diff --git a/include/polarssl/cipher.h b/include/polarssl/cipher.h index cc692089a..aad488fc8 100644 --- a/include/polarssl/cipher.h +++ b/include/polarssl/cipher.h @@ -512,6 +512,10 @@ int cipher_update_ad( cipher_context_t *ctx, * POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE on an * unsupported mode for a cipher or a cipher specific * error code. + * + * \note If the underlying cipher is GCM, all calls to this + * function, except the last one before cipher_finish(), + * must have ilen a multiple of the block size. */ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ilen, unsigned char *output, size_t *olen ); diff --git a/library/cipher.c b/library/cipher.c index 280124d6d..8d90a646b 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -467,14 +467,21 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; } +#if defined(POLARSSL_GCM_C) + if( ctx->cipher_info->mode == POLARSSL_MODE_GCM) + { + *olen = ilen; + return gcm_update( ctx->cipher_ctx, ilen, input, output ); + } +#endif + if( input == output && ( ctx->unprocessed_len != 0 || ilen % cipher_get_block_size( ctx ) ) ) { return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA; } - if( ctx->cipher_info->mode == POLARSSL_MODE_CBC || - ctx->cipher_info->mode == POLARSSL_MODE_GCM ) + if( ctx->cipher_info->mode == POLARSSL_MODE_CBC ) { /* * If there is not enough data for a full block, cache it. @@ -501,18 +508,6 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, copy_len ); -#if defined(POLARSSL_GCM_C) - if( ctx->cipher_info->mode == POLARSSL_MODE_GCM ) - { - if( 0 != ( ret = gcm_update( ctx->cipher_ctx, - cipher_get_block_size( ctx ), - ctx->unprocessed_data, output ) ) ) - { - return ret; - } - } - else -#endif if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, ctx->operation, cipher_get_block_size( ctx ), ctx->iv, ctx->unprocessed_data, output ) ) ) @@ -549,17 +544,6 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ile */ if( ilen ) { -#if defined(POLARSSL_GCM_C) - if( ctx->cipher_info->mode == POLARSSL_MODE_GCM ) - { - if( 0 != ( ret = gcm_update( ctx->cipher_ctx, - ilen, input, output ) ) ) - { - return ret; - } - } - else -#endif if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, ctx->operation, ilen, ctx->iv, input, output ) ) ) { @@ -790,27 +774,12 @@ int cipher_finish( cipher_context_t *ctx, if( POLARSSL_MODE_CFB == ctx->cipher_info->mode || POLARSSL_MODE_CTR == ctx->cipher_info->mode || + POLARSSL_MODE_GCM == ctx->cipher_info->mode || POLARSSL_MODE_STREAM == ctx->cipher_info->mode ) { return 0; } -#if defined(POLARSSL_GCM_C) - if( POLARSSL_MODE_GCM == ctx->cipher_info->mode ) - { - if( 0 != ( ret = gcm_update( ctx->cipher_ctx, - ctx->unprocessed_len, ctx->unprocessed_data, - output ) ) ) - { - return( ret ); - } - - *olen += ctx->unprocessed_len; - - return( 0 ); - } -#endif - if( POLARSSL_MODE_CBC == ctx->cipher_info->mode ) { if( POLARSSL_ENCRYPT == ctx->operation ) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index cddaec668..7e7ddd713 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -690,16 +690,6 @@ int ssl_derive_keys( ssl_context *ssl ) } break; -#if defined(POLARSSL_GCM_C) - case POLARSSL_CIPHER_AES_128_GCM: - case POLARSSL_CIPHER_AES_256_GCM: - gcm_init( (gcm_context *) transform->ctx_enc, key1, - cipher_info->key_length ); - gcm_init( (gcm_context *) transform->ctx_dec, key2, - cipher_info->key_length ); - break; -#endif - case POLARSSL_CIPHER_NULL: break; @@ -1046,7 +1036,7 @@ static int ssl_encrypt_buf( ssl_context *ssl ) */ ssl->out_msglen += 16; - gcm_crypt_and_tag( ssl->transform_out->cipher_ctx_enc->cipher_ctx, + gcm_crypt_and_tag( ssl->transform_out->cipher_ctx_enc.cipher_ctx, GCM_ENCRYPT, enc_msglen, ssl->transform_out->iv_enc, ssl->transform_out->ivlen, add_data, 13, @@ -1285,7 +1275,7 @@ static int ssl_decrypt_buf( ssl_context *ssl ) ssl->transform_in->ivlen ); SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, 16 ); - ret = gcm_auth_decrypt( ssl->transform_in->cipher_ctx_dec->cipher_ctx, + ret = gcm_auth_decrypt( ssl->transform_in->cipher_ctx_dec.cipher_ctx, dec_msglen, ssl->transform_in->iv_dec, ssl->transform_in->ivlen, diff --git a/tests/suites/test_suite_cipher.gcm.data b/tests/suites/test_suite_cipher.gcm.data index 7a83dc5dd..7681d1878 100644 --- a/tests/suites/test_suite_cipher.gcm.data +++ b/tests/suites/test_suite_cipher.gcm.data @@ -85,25 +85,13 @@ AES 128 GCM Encrypt and decrypt 16 bytes in multiple parts 2 depends_on:POLARSSL_AES_C:POLARSSL_GCM_C enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:0:16 -AES 128 GCM Encrypt and decrypt 16 bytes in multiple parts 3 -depends_on:POLARSSL_AES_C:POLARSSL_GCM_C -enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:1:15 - -AES 128 GCM Encrypt and decrypt 16 bytes in multiple parts 4 -depends_on:POLARSSL_AES_C:POLARSSL_GCM_C -enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:15:1 - -AES 128 GCM Encrypt and decrypt 22 bytes in multiple parts 1 -depends_on:POLARSSL_AES_C:POLARSSL_GCM_C -enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:15:7 - AES 128 GCM Encrypt and decrypt 22 bytes in multiple parts 1 depends_on:POLARSSL_AES_C:POLARSSL_GCM_C enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:16:6 -AES 128 GCM Encrypt and decrypt 22 bytes in multiple parts 1 +AES 128 GCM Encrypt and decrypt 22 bytes in multiple parts 2 depends_on:POLARSSL_AES_C:POLARSSL_GCM_C -enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:17:6 +enc_dec_buf_multipart:POLARSSL_CIPHER_AES_128_GCM:128:0:22 AES 128 GCM Encrypt and decrypt 32 bytes in multiple parts 1 depends_on:POLARSSL_AES_C:POLARSSL_GCM_C