diff --git a/ChangeLog.d/add-aes-ecb-to-psa.txt b/ChangeLog.d/add-aes-ecb-to-psa.txt index 2fa57ad8e..b0de67c4e 100644 --- a/ChangeLog.d/add-aes-ecb-to-psa.txt +++ b/ChangeLog.d/add-aes-ecb-to-psa.txt @@ -1,2 +1,2 @@ Features - * Added support for AES-ECB to the PSA Crypto cipher API. + * Add support for ECB to the PSA cipher API. diff --git a/include/mbedtls/psa_util.h b/include/mbedtls/psa_util.h index a8c15a03c..aa944b63b 100644 --- a/include/mbedtls/psa_util.h +++ b/include/mbedtls/psa_util.h @@ -86,7 +86,7 @@ static inline psa_algorithm_t mbedtls_psa_translate_cipher_mode( switch( mode ) { case MBEDTLS_MODE_ECB: - return ( PSA_ALG_ECB_NO_PADDING ); + return( PSA_ALG_ECB_NO_PADDING ); case MBEDTLS_MODE_GCM: return( PSA_ALG_AEAD_WITH_TAG_LENGTH( PSA_ALG_GCM, taglen ) ); case MBEDTLS_MODE_CCM: diff --git a/include/psa/crypto_values.h b/include/psa/crypto_values.h index 786a3bb17..db5188743 100644 --- a/include/psa/crypto_values.h +++ b/include/psa/crypto_values.h @@ -981,11 +981,22 @@ #define PSA_ALG_XTS ((psa_algorithm_t)0x044000ff) /** The Electronic Code Book (ECB) mode of a block cipher, with no padding. + * + * \warning ECB mode does not protect the confidentiality of the encrypted data + * except in extremely narrow circumstances. It is recommended that applications + * only use ECB if they need to construct an operating mode that the + * implementation does not provide. Implementations are encouraged to provide + * the modes that applications need in preference to supporting direct access + * to ECB. * * The underlying block cipher is determined by the key type. * - * This symmetric cipher mode can only be used with messages whose lengths - * are whole number of blocks for the chosen block cipher. + * This symmetric cipher mode can only be used with messages whose lengths are a + * multiple of the block size of the chosen block cipher. + * + * ECB mode does not accept an initialization vector (IV). When using a + * multi-part cipher operation with this algorithm, psa_cipher_generate_iv() + * and psa_cipher_set_iv() must not be called. */ #define PSA_ALG_ECB_NO_PADDING ((psa_algorithm_t)0x04404400) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 9362ef0ba..f3bd87693 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3749,9 +3749,12 @@ static psa_status_t psa_cipher_init( psa_cipher_operation_t *operation, operation->alg = alg; operation->key_set = 0; operation->iv_set = 0; - if( alg == PSA_ALG_ECB_NO_PADDING ) { + if( alg == PSA_ALG_ECB_NO_PADDING ) + { operation->iv_required = 0; - } else { + } + else + { operation->iv_required = 1; } operation->iv_size = 0; @@ -3844,7 +3847,8 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, operation->key_set = 1; operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 : PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) ); - if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG && alg != PSA_ALG_ECB_NO_PADDING ) + if( ( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) != 0 && + alg != PSA_ALG_ECB_NO_PADDING ) { operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ); } @@ -4002,7 +4006,8 @@ psa_status_t psa_cipher_finish( psa_cipher_operation_t *operation, { if( operation->alg == PSA_ALG_ECB_NO_PADDING || ( operation->alg == PSA_ALG_CBC_NO_PADDING && - operation->ctx.cipher.operation == MBEDTLS_ENCRYPT ) ) { + operation->ctx.cipher.operation == MBEDTLS_ENCRYPT ) ) + { status = PSA_ERROR_INVALID_ARGUMENT; goto error; } diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index e392ecc66..e75d6518e 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -3349,7 +3349,7 @@ void cipher_encrypt( int alg_arg, int key_type_arg, if( iv->len > 0 ) { - PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); + PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); } output_buffer_size = ( (size_t) input->len + @@ -3416,7 +3416,7 @@ void cipher_encrypt_multipart( int alg_arg, int key_type_arg, if( iv->len > 0 ) { - PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); + PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); } output_buffer_size = ( (size_t) input->len + @@ -3488,7 +3488,7 @@ void cipher_decrypt_multipart( int alg_arg, int key_type_arg, handle, alg ) ); if( iv->len > 0 ) { - PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); + PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); } output_buffer_size = ( (size_t) input->len + @@ -3557,7 +3557,7 @@ void cipher_decrypt( int alg_arg, int key_type_arg, handle, alg ) ); if( iv->len > 0 ) { - PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); + PSA_ASSERT( psa_cipher_set_iv( &operation, iv->x, iv->len ) ); } output_buffer_size = ( (size_t) input->len + @@ -3626,9 +3626,9 @@ void cipher_verify_output( int alg_arg, int key_type_arg, handle, alg ) ); if( alg != PSA_ALG_ECB_NO_PADDING ) { - PSA_ASSERT( psa_cipher_generate_iv( &operation1, - iv, iv_size, - &iv_length ) ); + PSA_ASSERT( psa_cipher_generate_iv( &operation1, + iv, iv_size, + &iv_length ) ); } output1_size = ( (size_t) input->len + PSA_BLOCK_CIPHER_BLOCK_SIZE( key_type ) ); @@ -3650,8 +3650,8 @@ void cipher_verify_output( int alg_arg, int key_type_arg, ASSERT_ALLOC( output2, output2_size ); if( iv_length > 0 ) { - PSA_ASSERT( psa_cipher_set_iv( &operation2, - iv, iv_length ) ); + PSA_ASSERT( psa_cipher_set_iv( &operation2, + iv, iv_length ) ); } PSA_ASSERT( psa_cipher_update( &operation2, output1, output1_length, @@ -3716,9 +3716,9 @@ void cipher_verify_output_multipart( int alg_arg, handle, alg ) ); if( alg != PSA_ALG_ECB_NO_PADDING ) { - PSA_ASSERT( psa_cipher_generate_iv( &operation1, - iv, iv_size, - &iv_length ) ); + PSA_ASSERT( psa_cipher_generate_iv( &operation1, + iv, iv_size, + &iv_length ) ); } output1_buffer_size = ( (size_t) input->len + @@ -3751,8 +3751,8 @@ void cipher_verify_output_multipart( int alg_arg, ASSERT_ALLOC( output2, output2_buffer_size ); if( iv_length > 0 ) { - PSA_ASSERT( psa_cipher_set_iv( &operation2, - iv, iv_length ) ); + PSA_ASSERT( psa_cipher_set_iv( &operation2, + iv, iv_length ) ); } PSA_ASSERT( psa_cipher_update( &operation2, output1, first_part_size,