diff --git a/core/c/base64.c b/core/c/base64.c index f801cc75..a37767a9 100644 --- a/core/c/base64.c +++ b/core/c/base64.c @@ -57,7 +57,7 @@ #include "base64.h" /* aaaack but it's fast and const should make it shared text page. */ -static const unsigned char pr2six[256] = +static const unsigned char b64ToBits[256] = { /* ASCII table */ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, @@ -80,58 +80,39 @@ static const unsigned char pr2six[256] = size_t mpw_base64_decode_max(const char *b64Text) { - register const uint8_t *bufin; - register int nprbytes; + register const uint8_t *b64Cursor = (uint8_t *)b64Text; + while (b64ToBits[*(b64Cursor++)] <= 63); + int b64Size = (int)(b64Cursor - (uint8_t *)b64Text) - 1; - bufin = (uint8_t *)b64Text; - while (pr2six[*(bufin++)] <= 63); - - nprbytes = (int)(bufin - (uint8_t *)b64Text) - 1; - return (size_t)(((nprbytes + 3) / 4) * 3); + // Every 4 b64 chars yield 3 plain bytes => len = 3 * ceil(b64Size / 4) + return (size_t)(3 /*bytes*/ * ((b64Size + 4 /*chars*/ - 1) / 4 /*chars*/)); } -int mpw_base64_decode(uint8_t *plainBuf, size_t plainMax, const char *b64Text) { +int mpw_base64_decode(uint8_t *plainBuf, const char *b64Text) { - register const uint8_t *bufin; - register uint8_t *bufout; - register int nprbytes; + register const uint8_t *b64Cursor = (uint8_t *)b64Text; + while (b64ToBits[*(b64Cursor++)] <= 63); + int b64Remaining = (int)(b64Cursor - (uint8_t *)b64Text) - 1; - bufin = (uint8_t *)b64Text; - while (pr2six[*(bufin++)] <= 63); - nprbytes = (int)(bufin - (uint8_t *)b64Text) - 1; - - bufout = plainBuf; - bufin = (uint8_t *)b64Text; - - while (nprbytes > 4) { - if (bufout + 2 >= plainBuf + plainMax) - return -1; - - *(bufout++) = (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); - *(bufout++) = (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); - *(bufout++) = (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); - bufin += 4; - nprbytes -= 4; + b64Cursor = (uint8_t *)b64Text; + register uint8_t *plainCursor = plainBuf; + while (b64Remaining > 4) { + *(plainCursor++) = (b64ToBits[b64Cursor[0]] << 2 | b64ToBits[b64Cursor[1]] >> 4); + *(plainCursor++) = (b64ToBits[b64Cursor[1]] << 4 | b64ToBits[b64Cursor[2]] >> 2); + *(plainCursor++) = (b64ToBits[b64Cursor[2]] << 6 | b64ToBits[b64Cursor[3]]); + b64Cursor += 4; + b64Remaining -= 4; } - /* Note: (nprbytes == 1) would be an error, so just ingore that case */ - if (nprbytes > 1) { - if (bufout >= plainBuf + plainMax) - return -1; - *(bufout++) = (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); - } - if (nprbytes > 2) { - if (bufout >= plainBuf + plainMax) - return -1; - *(bufout++) = (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); - } - if (nprbytes > 3) { - if (bufout >= plainBuf + plainMax) - return -1; - *(bufout++) = (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); - } + /* Note: (b64Size == 1) would be an error, so just ingore that case */ + if (b64Remaining > 1) + *(plainCursor++) = (b64ToBits[b64Cursor[0]] << 2 | b64ToBits[b64Cursor[1]] >> 4); + if (b64Remaining > 2) + *(plainCursor++) = (b64ToBits[b64Cursor[1]] << 4 | b64ToBits[b64Cursor[2]] >> 2); + if (b64Remaining > 3) + *(plainCursor++) = (b64ToBits[b64Cursor[2]] << 6 | b64ToBits[b64Cursor[3]]); - return (int)(bufout - plainBuf); + return (int)(plainCursor - plainBuf); } static const char basis_64[] = @@ -143,40 +124,32 @@ size_t mpw_base64_encode_max(size_t plainSize) { return 4 /*chars*/ * (plainSize + 3 /*bytes*/ - 1) / 3 /*bytes*/; } -int mpw_base64_encode(char *b64Text, size_t b64Max, const uint8_t *plainBuf, size_t plainSize) { +int mpw_base64_encode(char *b64Text, const uint8_t *plainBuf, size_t plainSize) { - int i; - char *p; - - p = b64Text; - for (i = 0; i < plainSize - 2; i += 3) { - if (p >= b64Text + b64Max) - return -1; - - *p++ = basis_64[(plainBuf[i] >> 2) & 0x3F]; - *p++ = basis_64[((plainBuf[i] & 0x3) << 4) | - ((plainBuf[i + 1] & 0xF0) >> 4)]; - *p++ = basis_64[((plainBuf[i + 1] & 0xF) << 2) | - ((plainBuf[i + 2] & 0xC0) >> 6)]; - *p++ = basis_64[plainBuf[i + 2] & 0x3F]; + int plainCursor = 0; + char *b64Cursor = b64Text; + for (; plainCursor < plainSize - 2; plainCursor += 3) { + *b64Cursor++ = basis_64[((plainBuf[plainCursor] >> 2)) & 0x3F]; + *b64Cursor++ = basis_64[((plainBuf[plainCursor] & 0x3) << 4) | + ((plainBuf[plainCursor + 1] & 0xF0) >> 4)]; + *b64Cursor++ = basis_64[((plainBuf[plainCursor + 1] & 0xF) << 2) | + ((plainBuf[plainCursor + 2] & 0xC0) >> 6)]; + *b64Cursor++ = basis_64[plainBuf[plainCursor + 2] & 0x3F]; } - if (i < plainSize) { - if (p + 3 >= b64Text + b64Max) - return -1; - - *p++ = basis_64[(plainBuf[i] >> 2) & 0x3F]; - if (i == (plainSize - 1)) { - *p++ = basis_64[((plainBuf[i] & 0x3) << 4)]; - *p++ = '='; + if (plainCursor < plainSize) { + *b64Cursor++ = basis_64[(plainBuf[plainCursor] >> 2) & 0x3F]; + if (plainCursor == (plainSize - 1)) { + *b64Cursor++ = basis_64[((plainBuf[plainCursor] & 0x3) << 4)]; + *b64Cursor++ = '='; } else { - *p++ = basis_64[((plainBuf[i] & 0x3) << 4) | - ((plainBuf[i + 1] & 0xF0) >> 4)]; - *p++ = basis_64[((plainBuf[i + 1] & 0xF) << 2)]; + *b64Cursor++ = basis_64[((plainBuf[plainCursor] & 0x3) << 4) | + ((plainBuf[plainCursor + 1] & 0xF0) >> 4)]; + *b64Cursor++ = basis_64[((plainBuf[plainCursor + 1] & 0xF) << 2)]; } - *p++ = '='; + *b64Cursor++ = '='; } - *p = '\0'; - return (int)(p - b64Text); + *b64Cursor = '\0'; + return (int)(b64Cursor - b64Text); } diff --git a/core/c/base64.h b/core/c/base64.h index defa8017..fdbfc58a 100644 --- a/core/c/base64.h +++ b/core/c/base64.h @@ -62,18 +62,17 @@ */ size_t mpw_base64_decode_max(const char *b64Text); /** Decodes a base-64 encoded string into a plain byte buffer. - * @param plainMax the maximum amount of bytes to write to plainBuf. - * @return The amount of bytes that were written to plainBuf or -1 if this amount would have exceeded plainMax. + * @param plainBuf a byte buffer, size should be at least mpw_base64_decode_max(b64Text) + * @return The amount of bytes that were written to plainBuf. */ -int mpw_base64_decode(uint8_t *plainBuf, size_t plainMax, const char *b64Text); +int mpw_base64_decode(uint8_t *plainBuf, const char *b64Text); /** * @return The amount of characters needed to encode a plainBuf of the given size as base-64 (excluding the terminating NUL). */ size_t mpw_base64_encode_max(size_t plainSize); /** Encodes a plain byte buffer into a base-64 encoded string. - * @param b64Max the maximum amount of characters to write to b64Text, excluding the terminating NUL. - * @return The amount of characters that were written to b64Text, excluding the terminating NUL - * or -1 if this amount would have exceeded b64Max. + * @param b64Text a character buffer, size should be at least mpw_base64_encode_max(plainSize) + 1 + * @return The amount of characters that were written to b64Text, excluding the terminating NUL. */ -int mpw_base64_encode(char *b64Text, size_t b64Max, const uint8_t *plainBuf, size_t plainSize); +int mpw_base64_encode(char *b64Text, const uint8_t *plainBuf, size_t plainSize); diff --git a/core/c/mpw-algorithm_v0.c b/core/c/mpw-algorithm_v0.c index fdcbee92..5fe465e6 100644 --- a/core/c/mpw-algorithm_v0.c +++ b/core/c/mpw-algorithm_v0.c @@ -163,7 +163,7 @@ const char *mpw_encrypt_v0( // Base64-encode size_t b64Max = mpw_base64_encode_max( bufSize ); char *cipherText = calloc( 1, b64Max + 1 ); - if (mpw_base64_encode( cipherText, b64Max, cipherBuf, bufSize ) < 0) { + if (mpw_base64_encode( cipherText, cipherBuf, bufSize ) < 0) { err( "Base64 encoding error." ); mpw_free_string( cipherText ); cipherText = NULL; @@ -178,14 +178,14 @@ const char *mpw_decrypt_v0( MPMasterKey masterKey, const char *cipherText) { // Base64-decode - size_t bufSize = mpw_base64_decode_max( cipherText ); - uint8_t *cipherBuf = calloc( 1, bufSize ); - if ((bufSize = (size_t)mpw_base64_decode( cipherBuf, bufSize, cipherText )) < 0) { + uint8_t *cipherBuf = calloc( 1, mpw_base64_decode_max( cipherText ) ); + size_t bufSize = (size_t)mpw_base64_decode( cipherBuf, cipherText ); + if ((int)bufSize < 0) { err( "Base64 decoding error." ); mpw_free( cipherBuf, mpw_base64_decode_max( cipherText ) ); return NULL; } - trc( "b64 decoded: %lu bytes = %s\n", bufSize, mpw_hex( cipherBuf, bufSize ) ); + trc( "b64 decoded: %zu bytes = %s\n", bufSize, mpw_hex( cipherBuf, bufSize ) ); // Decrypt const uint8_t *plainBytes = mpw_aes_decrypt( masterKey, MPMasterKeySize, cipherBuf, bufSize ); diff --git a/core/c/mpw-util.c b/core/c/mpw-util.c index f014f38c..53d155ee 100644 --- a/core/c/mpw-util.c +++ b/core/c/mpw-util.c @@ -91,7 +91,7 @@ bool mpw_push_int(uint8_t **const buffer, size_t *const bufferSize, const uint32 return mpw_push_buf( buffer, bufferSize, &pushInt, sizeof( pushInt ) ); } -bool mpw_realloc(void **buffer, size_t *bufferSize, const size_t deltaSize) { +bool __mpw_realloc(void **buffer, size_t *bufferSize, const size_t deltaSize) { if (!buffer) return false; @@ -188,6 +188,10 @@ static uint8_t const *mpw_aes(bool encrypt, const uint8_t *key, const size_t key uint8_t nonce[crypto_stream_NONCEBYTES]; bzero( (void *)nonce, sizeof( nonce ) ); +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" if (encrypt) { uint8_t *const cipherBuf = malloc( bufSize ); if (crypto_stream_aes128ctr_xor( cipherBuf, buf, bufSize, nonce, key ) != 0) { @@ -195,7 +199,8 @@ static uint8_t const *mpw_aes(bool encrypt, const uint8_t *key, const size_t key return NULL; } return cipherBuf; - } else { + } + else { uint8_t *const plainBuf = malloc( bufSize ); if (crypto_stream_aes128ctr( plainBuf, bufSize, nonce, key ) != 0) { mpw_free( plainBuf, bufSize ); @@ -205,6 +210,8 @@ static uint8_t const *mpw_aes(bool encrypt, const uint8_t *key, const size_t key plainBuf[c] = buf[c] ^ plainBuf[c]; return plainBuf; } +#pragma clang diagnostic pop +#pragma GCC diagnostic pop #else #error No crypto support for mpw_aes. #endif @@ -274,8 +281,8 @@ const char *mpw_hex(const void *buf, size_t length) { mpw_hex_buf_i = (mpw_hex_buf_i + 1) % 10; if (mpw_realloc( &mpw_hex_buf[mpw_hex_buf_i], NULL, length * 2 + 1 )) - for (size_t kH = 0; kH < length; kH++) - sprintf( &(mpw_hex_buf[mpw_hex_buf_i][kH * 2]), "%02X", ((const uint8_t *)buf)[kH] ); + for (size_t kH = 0; kH < length; kH++) + sprintf( &(mpw_hex_buf[mpw_hex_buf_i][kH * 2]), "%02X", ((const uint8_t *)buf)[kH] ); return mpw_hex_buf[mpw_hex_buf_i]; } diff --git a/core/c/mpw-util.h b/core/c/mpw-util.h index 6059a8d8..19dbc29e 100644 --- a/core/c/mpw-util.h +++ b/core/c/mpw-util.h @@ -121,8 +121,9 @@ bool mpw_push_int( * @param deltaSize The amount to increase the buffer's size by. * @return true if successful, false if reallocation failed. */ -bool mpw_realloc( - void **buffer, size_t *bufferSize, const size_t deltaSize); +#define mpw_realloc(buffer, bufferSize, deltaSize) \ + __mpw_realloc( (void **)buffer, bufferSize, deltaSize ) +bool __mpw_realloc(void **buffer, size_t *bufferSize, const size_t deltaSize); /** Free a buffer after zero'ing its contents. */ bool mpw_free( const void *buffer, const size_t bufferSize);