diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h index b3adecc4f..2b9909e1a 100644 --- a/include/mbedtls/ccm.h +++ b/include/mbedtls/ccm.h @@ -77,6 +77,16 @@ extern "C" { typedef struct mbedtls_ccm_context { mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */ + unsigned char MBEDTLS_PRIVATE(b)[16]; /*!< The B working buffer */ + unsigned char MBEDTLS_PRIVATE(y)[16]; /*!< The Y working buffer */ + unsigned char MBEDTLS_PRIVATE(ctr)[16]; /*!< The counter buffer */ + unsigned char MBEDTLS_PRIVATE(q); /*!< The Q working value */ + size_t MBEDTLS_PRIVATE(plaintext_len); /*!< The counter buffer */ + int MBEDTLS_PRIVATE(mode); /*!< The operation to perform: + #MBEDTLS_CCM_ENCRYPT or + #MBEDTLS_CCM_DECRYPT or + #MBEDTLS_CCM_STAR_ENCRYPT or + #MBEDTLS_CCM_STAR_DECRYPT. */ } mbedtls_ccm_context; diff --git a/library/ccm.c b/library/ccm.c index 424ee77b6..686eda543 100644 --- a/library/ccm.c +++ b/library/ccm.c @@ -117,11 +117,11 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) * Update the CBC-MAC state in y using a block in b * (Always using b as the source helps the compiler optimise a bit better.) */ -#define UPDATE_CBC_MAC \ - for( i = 0; i < 16; i++ ) \ - y[i] ^= b[i]; \ - \ - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ +#define UPDATE_CBC_MAC \ + for( i = 0; i < 16; i++ ) \ + ctx->y[i] ^= ctx->b[i]; \ + \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen ) ) != 0 ) \ return( ret ); /* @@ -130,16 +130,16 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) * This avoids allocating one more 16 bytes buffer while allowing src == dst. */ #define CTR_CRYPT( dst, src, len ) \ - do \ - { \ - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, \ - 16, b, &olen ) ) != 0 ) \ - { \ - return( ret ); \ - } \ - \ - for( i = 0; i < (len); i++ ) \ - (dst)[i] = (src)[i] ^ b[i]; \ + do \ + { \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->ctr, \ + 16, ctx->b, &olen ) ) != 0 ) \ + { \ + return( ret ); \ + } \ + \ + for( i = 0; i < (len); i++ ) \ + (dst)[i] = (src)[i] ^ ctx->b[i]; \ } while( 0 ) /* @@ -153,14 +153,12 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, { int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; unsigned char i; - unsigned char q; size_t len_left, olen; - unsigned char b[16]; - unsigned char y[16]; - unsigned char ctr[16]; const unsigned char *src; unsigned char *dst; + ctx->mode = mode; + /* * Check length requirements: SP800-38C A.1 * Additional requirement: a < 2^16 - 2^8 to simplify the code. @@ -178,7 +176,7 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, if( add_len >= 0xFF00 ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); - q = 16 - 1 - (unsigned char) iv_len; + ctx->q = 16 - 1 - (unsigned char) iv_len; /* * First block B_0: @@ -192,22 +190,22 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, * 5 .. 3 (t - 2) / 2 * 2 .. 0 q - 1 */ - b[0] = 0; - b[0] |= ( add_len > 0 ) << 6; - b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; - b[0] |= q - 1; + ctx->b[0] = 0; + ctx->b[0] |= ( add_len > 0 ) << 6; + ctx->b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; + ctx->b[0] |= ctx->q - 1; - memcpy( b + 1, iv, iv_len ); + memcpy( ctx->b + 1, iv, iv_len ); - for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) - b[15-i] = (unsigned char)( len_left & 0xFF ); + for( i = 0, len_left = length; i < ctx->q; i++, len_left >>= 8 ) + ctx->b[15-i] = (unsigned char)( len_left & 0xFF ); if( len_left > 0 ) return( MBEDTLS_ERR_CCM_BAD_INPUT ); /* Start CBC-MAC with first block */ - memset( y, 0, 16 ); + memset( ctx->y, 0, 16 ); UPDATE_CBC_MAC; /* @@ -220,12 +218,12 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, len_left = add_len; src = add; - memset( b, 0, 16 ); - b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); - b[1] = (unsigned char)( ( add_len ) & 0xFF ); + memset( ctx->b, 0, 16 ); + ctx->b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); + ctx->b[1] = (unsigned char)( ( add_len ) & 0xFF ); use_len = len_left < 16 - 2 ? len_left : 16 - 2; - memcpy( b + 2, src, use_len ); + memcpy( ctx->b + 2, src, use_len ); len_left -= use_len; src += use_len; @@ -235,8 +233,8 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, { use_len = len_left > 16 ? 16 : len_left; - memset( b, 0, 16 ); - memcpy( b, src, use_len ); + memset( ctx->b, 0, 16 ); + memcpy( ctx->b, src, use_len ); UPDATE_CBC_MAC; len_left -= use_len; @@ -254,10 +252,10 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, * 7 .. 3 0 * 2 .. 0 q - 1 */ - ctr[0] = q - 1; - memcpy( ctr + 1, iv, iv_len ); - memset( ctr + 1 + iv_len, 0, q ); - ctr[15] = 1; + ctx->ctr[0] = ctx->q - 1; + memcpy( ctx->ctr + 1, iv, iv_len ); + memset( ctx->ctr + 1 + iv_len, 0, ctx->q ); + ctx->ctr[15] = 1; /* * Authenticate and {en,de}crypt the message. @@ -273,19 +271,19 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, { size_t use_len = len_left > 16 ? 16 : len_left; - if( mode == CCM_ENCRYPT ) + if( ctx->mode == CCM_ENCRYPT ) { - memset( b, 0, 16 ); - memcpy( b, src, use_len ); + memset( ctx->b, 0, 16 ); + memcpy( ctx->b, src, use_len ); UPDATE_CBC_MAC; } CTR_CRYPT( dst, src, use_len ); - if( mode == CCM_DECRYPT ) + if( ctx->mode == CCM_DECRYPT ) { - memset( b, 0, 16 ); - memcpy( b, dst, use_len ); + memset( ctx->b, 0, 16 ); + memcpy( ctx->b, dst, use_len ); UPDATE_CBC_MAC; } @@ -297,19 +295,19 @@ static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, * Increment counter. * No need to check for overflow thanks to the length check above. */ - for( i = 0; i < q; i++ ) - if( ++ctr[15-i] != 0 ) + for( i = 0; i < ctx->q; i++ ) + if( ++(ctx->ctr)[15-i] != 0 ) break; } /* * Authentication: reset counter and crypt/mask internal tag */ - for( i = 0; i < q; i++ ) - ctr[15-i] = 0; + for( i = 0; i < ctx->q; i++ ) + ctx->ctr[15-i] = 0; - CTR_CRYPT( y, y, 16 ); - memcpy( tag, y, tag_len ); + CTR_CRYPT( ctx->y, ctx->y, 16 ); + memcpy( tag, ctx->y, tag_len ); return( 0 ); }