From 93d356cbe283b49c41581758bd39119de4c3041c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 9 Mar 2021 10:03:08 +0100 Subject: [PATCH 01/17] psa: Export "internally" mbedtls_cipher_info_from_psa Export "internally" mbedtls_cipher_info_from_psa to be able to use it in psa_crypto_cipher.c. Signed-off-by: Ronald Cron --- library/psa_crypto_core.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index ec7ac8049..f949c7188 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -212,6 +212,22 @@ psa_status_t psa_copy_key_material_into_slot( psa_key_slot_t *slot, */ psa_status_t mbedtls_to_psa_error( int ret ); +/** Get Mbed TLS cipher information given the cipher algorithm PSA identifier + * as well as the PSA type and size of the key to be used with the cipher + * algorithm. + * + * \param alg PSA cipher algorithm identifier + * \param key_type PSA key type + * \param key_bits Size of the key in bits + * \param[out] cipher_id Mbed TLS cipher algorithm identifier + * + * \return The Mbed TLS cipher information of the cipher algorithm. + * \c NULL if the PSA cipher algorithm is not supported. + */ +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_psa( + psa_algorithm_t alg, psa_key_type_t key_type, size_t key_bits, + mbedtls_cipher_id_t *cipher_id ); + /** Import a key in binary format. * * \note The signature of this function is that of a PSA driver From 004f917ee80711ba0539181313e48168816f7d41 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 16 Mar 2021 17:26:12 +0100 Subject: [PATCH 02/17] psa: aead: Fix status initialization Signed-off-by: Ronald Cron --- library/psa_crypto.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 9c8e108df..5de0f10a4 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3568,7 +3568,7 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, psa_key_usage_t usage, psa_algorithm_t alg ) { - psa_status_t status; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t key_bits; mbedtls_cipher_id_t cipher_id; @@ -3684,7 +3684,7 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, size_t ciphertext_size, size_t *ciphertext_length ) { - psa_status_t status; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; aead_operation_t operation = AEAD_OPERATION_INIT; uint8_t *tag; @@ -3799,7 +3799,7 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, size_t plaintext_size, size_t *plaintext_length ) { - psa_status_t status; + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; aead_operation_t operation = AEAD_OPERATION_INIT; const uint8_t *tag = NULL; From 197c2fd0a04a5a71156b9fb046d93f656916846c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 16 Mar 2021 14:50:33 +0100 Subject: [PATCH 03/17] psa: aead: Move key resolution As we want to do Mbed TLS aead operations as a driver does, aead operations should not access the key slot as key slots are not available to drivers. First step in this PR: move key resolution from aead operation setup to psa_aead_encrypt/decrypt APIs. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 5de0f10a4..b135b720e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3564,19 +3564,12 @@ static void psa_aead_abort_internal( aead_operation_t *operation ) } static psa_status_t psa_aead_setup( aead_operation_t *operation, - mbedtls_svc_key_id_t key, - psa_key_usage_t usage, psa_algorithm_t alg ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t key_bits; mbedtls_cipher_id_t cipher_id; - status = psa_get_and_lock_transparent_key_slot_with_policy( - key, &operation->slot, usage, alg ); - if( status != PSA_SUCCESS ) - return( status ); - key_bits = psa_get_key_slot_bits( operation->slot ); operation->cipher_info = @@ -3690,7 +3683,12 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, *ciphertext_length = 0; - status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_ENCRYPT, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &operation.slot, PSA_KEY_USAGE_ENCRYPT, alg ); + if( status != PSA_SUCCESS ) + return( status ); + + status = psa_aead_setup( &operation, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -3805,7 +3803,12 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, *plaintext_length = 0; - status = psa_aead_setup( &operation, key, PSA_KEY_USAGE_DECRYPT, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &operation.slot, PSA_KEY_USAGE_DECRYPT, alg ); + if( status != PSA_SUCCESS ) + return( status ); + + status = psa_aead_setup( &operation, alg ); if( status != PSA_SUCCESS ) return( status ); From 7dbd800f428246f711cbc0437b4c6267489c72c4 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 16 Mar 2021 16:30:42 +0100 Subject: [PATCH 04/17] psa: aead: Isolate key slot unlock from operation abort As we want to do Mbed TLS aead operations as a driver does, aead operations should not access the key slot as key slots are not available to drivers. Second step in this PR: do not unlock the key slot as part of operation abort. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 59 +++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index b135b720e..70d3d5e93 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3559,8 +3559,6 @@ static void psa_aead_abort_internal( aead_operation_t *operation ) break; #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ } - - psa_unlock_key_slot( operation->slot ); } static psa_status_t psa_aead_setup( aead_operation_t *operation, @@ -3576,10 +3574,7 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, mbedtls_cipher_info_from_psa( alg, operation->slot->attr.type, key_bits, &cipher_id ); if( operation->cipher_info == NULL ) - { - status = PSA_ERROR_NOT_SUPPORTED; - goto cleanup; - } + return( PSA_ERROR_NOT_SUPPORTED ); switch( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ) ) { @@ -3591,17 +3586,15 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, * The call to mbedtls_ccm_encrypt_and_tag or * mbedtls_ccm_auth_decrypt will validate the tag length. */ if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( operation->slot->attr.type ) != 16 ) - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto cleanup; - } + return( PSA_ERROR_INVALID_ARGUMENT ); + mbedtls_ccm_init( &operation->ctx.ccm ); status = mbedtls_to_psa_error( mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id, operation->slot->key.data, (unsigned int) key_bits ) ); - if( status != 0 ) - goto cleanup; + if( status != PSA_SUCCESS ) + return( status ); break; #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ @@ -3613,17 +3606,15 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, * The call to mbedtls_gcm_crypt_and_tag or * mbedtls_gcm_auth_decrypt will validate the tag length. */ if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( operation->slot->attr.type ) != 16 ) - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto cleanup; - } + return( PSA_ERROR_INVALID_ARGUMENT ); + mbedtls_gcm_init( &operation->ctx.gcm ); status = mbedtls_to_psa_error( mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id, operation->slot->key.data, (unsigned int) key_bits ) ); - if( status != 0 ) - goto cleanup; + if( status != PSA_SUCCESS ) + return( status ); break; #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ @@ -3633,36 +3624,27 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, operation->full_tag_length = 16; /* We only support the default tag length. */ if( alg != PSA_ALG_CHACHA20_POLY1305 ) - { - status = PSA_ERROR_NOT_SUPPORTED; - goto cleanup; - } + return( PSA_ERROR_NOT_SUPPORTED ); + mbedtls_chachapoly_init( &operation->ctx.chachapoly ); status = mbedtls_to_psa_error( mbedtls_chachapoly_setkey( &operation->ctx.chachapoly, operation->slot->key.data ) ); - if( status != 0 ) - goto cleanup; + if( status != PSA_SUCCESS ) + return( status ); break; #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ default: - status = PSA_ERROR_NOT_SUPPORTED; - goto cleanup; + return( PSA_ERROR_NOT_SUPPORTED ); } if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length ) - { - status = PSA_ERROR_INVALID_ARGUMENT; - goto cleanup; - } + return( PSA_ERROR_INVALID_ARGUMENT ); + operation->tag_length = PSA_AEAD_TAG_LENGTH( alg ); return( PSA_SUCCESS ); - -cleanup: - psa_aead_abort_internal( operation ); - return( status ); } psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, @@ -3690,7 +3672,7 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, status = psa_aead_setup( &operation, alg ); if( status != PSA_SUCCESS ) - return( status ); + goto exit; /* For all currently supported modes, the tag is at the end of the * ciphertext. */ @@ -3758,7 +3740,10 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, memset( ciphertext, 0, ciphertext_size ); exit: + psa_unlock_key_slot( operation.slot ); psa_aead_abort_internal( &operation ); + + if( status == PSA_SUCCESS ) *ciphertext_length = plaintext_length + operation.tag_length; return( status ); @@ -3810,7 +3795,7 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, status = psa_aead_setup( &operation, alg ); if( status != PSA_SUCCESS ) - return( status ); + goto exit; status = psa_aead_unpadded_locate_tag( operation.tag_length, ciphertext, ciphertext_length, @@ -3874,7 +3859,9 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, memset( plaintext, 0, plaintext_size ); exit: + psa_unlock_key_slot( operation.slot ); psa_aead_abort_internal( &operation ); + if( status == PSA_SUCCESS ) *plaintext_length = ciphertext_length - operation.tag_length; return( status ); From 9f310179563c29ec3ebc9b4c8e89b409ec3266d5 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 16 Mar 2021 16:36:37 +0100 Subject: [PATCH 05/17] psa: aead: Remove key slot from operation context Signed-off-by: Ronald Cron --- library/psa_crypto.c | 62 +++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 70d3d5e93..65d7fe5de 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -563,17 +563,6 @@ static psa_status_t validate_unstructured_key_bit_size( psa_key_type_t type, return( PSA_SUCCESS ); } -/** Return the size of the key in the given slot, in bits. - * - * \param[in] slot A key slot. - * - * \return The key size in bits, read from the metadata in the slot. - */ -static inline size_t psa_get_key_slot_bits( const psa_key_slot_t *slot ) -{ - return( slot->attr.bits ); -} - /** Check whether a given key type is valid for use with a given MAC algorithm * * Upon successful return of this function, the behavior of #PSA_MAC_LENGTH @@ -3522,7 +3511,6 @@ psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) typedef struct { - psa_key_slot_t *slot; const mbedtls_cipher_info_t *cipher_info; union { @@ -3542,7 +3530,7 @@ typedef struct uint8_t tag_length; } aead_operation_t; -#define AEAD_OPERATION_INIT {0, 0, {0}, 0, 0, 0} +#define AEAD_OPERATION_INIT {0, {0}, 0, 0, 0} static void psa_aead_abort_internal( aead_operation_t *operation ) { @@ -3561,17 +3549,20 @@ static void psa_aead_abort_internal( aead_operation_t *operation ) } } -static psa_status_t psa_aead_setup( aead_operation_t *operation, - psa_algorithm_t alg ) +static psa_status_t psa_aead_setup( + aead_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + psa_algorithm_t alg ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t key_bits; mbedtls_cipher_id_t cipher_id; - key_bits = psa_get_key_slot_bits( operation->slot ); + key_bits = attributes->core.bits; operation->cipher_info = - mbedtls_cipher_info_from_psa( alg, operation->slot->attr.type, key_bits, + mbedtls_cipher_info_from_psa( alg, attributes->core.type, key_bits, &cipher_id ); if( operation->cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); @@ -3585,14 +3576,13 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16. * The call to mbedtls_ccm_encrypt_and_tag or * mbedtls_ccm_auth_decrypt will validate the tag length. */ - if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( operation->slot->attr.type ) != 16 ) + if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( attributes->core.type ) != 16 ) return( PSA_ERROR_INVALID_ARGUMENT ); mbedtls_ccm_init( &operation->ctx.ccm ); status = mbedtls_to_psa_error( mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id, - operation->slot->key.data, - (unsigned int) key_bits ) ); + key_buffer, (unsigned int) key_bits ) ); if( status != PSA_SUCCESS ) return( status ); break; @@ -3605,14 +3595,13 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. * The call to mbedtls_gcm_crypt_and_tag or * mbedtls_gcm_auth_decrypt will validate the tag length. */ - if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( operation->slot->attr.type ) != 16 ) + if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( attributes->core.type ) != 16 ) return( PSA_ERROR_INVALID_ARGUMENT ); mbedtls_gcm_init( &operation->ctx.gcm ); status = mbedtls_to_psa_error( mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id, - operation->slot->key.data, - (unsigned int) key_bits ) ); + key_buffer, (unsigned int) key_bits ) ); if( status != PSA_SUCCESS ) return( status ); break; @@ -3629,7 +3618,7 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, mbedtls_chachapoly_init( &operation->ctx.chachapoly ); status = mbedtls_to_psa_error( mbedtls_chachapoly_setkey( &operation->ctx.chachapoly, - operation->slot->key.data ) ); + key_buffer ) ); if( status != PSA_SUCCESS ) return( status ); break; @@ -3660,17 +3649,22 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, size_t *ciphertext_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; aead_operation_t operation = AEAD_OPERATION_INIT; uint8_t *tag; *ciphertext_length = 0; status = psa_get_and_lock_transparent_key_slot_with_policy( - key, &operation.slot, PSA_KEY_USAGE_ENCRYPT, alg ); + key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); - status = psa_aead_setup( &operation, alg ); + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + status = psa_aead_setup( &operation, &attributes, slot->key.data, alg ); if( status != PSA_SUCCESS ) goto exit; @@ -3740,9 +3734,8 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, memset( ciphertext, 0, ciphertext_size ); exit: - psa_unlock_key_slot( operation.slot ); psa_aead_abort_internal( &operation ); - + psa_unlock_key_slot( slot ); if( status == PSA_SUCCESS ) *ciphertext_length = plaintext_length + operation.tag_length; @@ -3783,17 +3776,22 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, size_t *plaintext_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; aead_operation_t operation = AEAD_OPERATION_INIT; const uint8_t *tag = NULL; *plaintext_length = 0; status = psa_get_and_lock_transparent_key_slot_with_policy( - key, &operation.slot, PSA_KEY_USAGE_DECRYPT, alg ); + key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); - status = psa_aead_setup( &operation, alg ); + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + status = psa_aead_setup( &operation, &attributes, slot->key.data, alg ); if( status != PSA_SUCCESS ) goto exit; @@ -3859,9 +3857,9 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, memset( plaintext, 0, plaintext_size ); exit: - psa_unlock_key_slot( operation.slot ); psa_aead_abort_internal( &operation ); - + psa_unlock_key_slot( slot ); + if( status == PSA_SUCCESS ) *plaintext_length = ciphertext_length - operation.tag_length; return( status ); From 215633cea4dc4af1a2405161c6069774afbcee0b Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 16 Mar 2021 17:15:37 +0100 Subject: [PATCH 06/17] psa: aead: Implement aead operations as a driver entry point Signed-off-by: Ronald Cron --- library/psa_crypto.c | 162 ++++++++++++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 55 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 65d7fe5de..0863901f1 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3636,35 +3636,21 @@ static psa_status_t psa_aead_setup( return( PSA_SUCCESS ); } -psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *nonce, - size_t nonce_length, - const uint8_t *additional_data, - size_t additional_data_length, - const uint8_t *plaintext, - size_t plaintext_length, - uint8_t *ciphertext, - size_t ciphertext_size, - size_t *ciphertext_length ) +static psa_status_t psa_aead_encrypt_internal( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *plaintext, size_t plaintext_length, + uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; aead_operation_t operation = AEAD_OPERATION_INIT; uint8_t *tag; + (void) key_buffer_size; - *ciphertext_length = 0; - - status = psa_get_and_lock_transparent_key_slot_with_policy( - key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); - if( status != PSA_SUCCESS ) - return( status ); - - psa_key_attributes_t attributes = { - .core = slot->attr - }; - - status = psa_aead_setup( &operation, &attributes, slot->key.data, alg ); + status = psa_aead_setup( &operation, attributes, key_buffer, alg ); if( status != PSA_SUCCESS ) goto exit; @@ -3730,15 +3716,54 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, return( PSA_ERROR_NOT_SUPPORTED ); } - if( status != PSA_SUCCESS && ciphertext_size != 0 ) - memset( ciphertext, 0, ciphertext_size ); + if( status == PSA_SUCCESS ) + *ciphertext_length = plaintext_length + operation.tag_length; exit: psa_aead_abort_internal( &operation ); + + return( status ); +} + +psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *nonce, + size_t nonce_length, + const uint8_t *additional_data, + size_t additional_data_length, + const uint8_t *plaintext, + size_t plaintext_length, + uint8_t *ciphertext, + size_t ciphertext_size, + size_t *ciphertext_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; + + *ciphertext_length = 0; + + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); + if( status != PSA_SUCCESS ) + return( status ); + + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + status = psa_aead_encrypt_internal( + &attributes, slot->key.data, slot->key.bytes, + alg, + nonce, nonce_length, + additional_data, additional_data_length, + plaintext, plaintext_length, + ciphertext, ciphertext_size, ciphertext_length ); + + if( status != PSA_SUCCESS && ciphertext_size != 0 ) + memset( ciphertext, 0, ciphertext_size ); + psa_unlock_key_slot( slot ); - if( status == PSA_SUCCESS ) - *ciphertext_length = plaintext_length + operation.tag_length; return( status ); } @@ -3763,35 +3788,21 @@ static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length, return( PSA_SUCCESS ); } -psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, - psa_algorithm_t alg, - const uint8_t *nonce, - size_t nonce_length, - const uint8_t *additional_data, - size_t additional_data_length, - const uint8_t *ciphertext, - size_t ciphertext_length, - uint8_t *plaintext, - size_t plaintext_size, - size_t *plaintext_length ) +static psa_status_t psa_aead_decrypt_internal( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *ciphertext, size_t ciphertext_length, + uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_slot_t *slot; aead_operation_t operation = AEAD_OPERATION_INIT; const uint8_t *tag = NULL; + (void) key_buffer_size; - *plaintext_length = 0; - - status = psa_get_and_lock_transparent_key_slot_with_policy( - key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); - if( status != PSA_SUCCESS ) - return( status ); - - psa_key_attributes_t attributes = { - .core = slot->attr - }; - - status = psa_aead_setup( &operation, &attributes, slot->key.data, alg ); + status = psa_aead_setup( &operation, attributes, key_buffer, alg ); if( status != PSA_SUCCESS ) goto exit; @@ -3853,18 +3864,59 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, return( PSA_ERROR_NOT_SUPPORTED ); } - if( status != PSA_SUCCESS && plaintext_size != 0 ) - memset( plaintext, 0, plaintext_size ); + if( status == PSA_SUCCESS ) + *plaintext_length = ciphertext_length - operation.tag_length; exit: psa_aead_abort_internal( &operation ); - psa_unlock_key_slot( slot ); if( status == PSA_SUCCESS ) *plaintext_length = ciphertext_length - operation.tag_length; return( status ); } +psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, + psa_algorithm_t alg, + const uint8_t *nonce, + size_t nonce_length, + const uint8_t *additional_data, + size_t additional_data_length, + const uint8_t *ciphertext, + size_t ciphertext_length, + uint8_t *plaintext, + size_t plaintext_size, + size_t *plaintext_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_slot_t *slot; + + *plaintext_length = 0; + + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); + if( status != PSA_SUCCESS ) + return( status ); + + psa_key_attributes_t attributes = { + .core = slot->attr + }; + + status = psa_aead_decrypt_internal( + &attributes, slot->key.data, slot->key.bytes, + alg, + nonce, nonce_length, + additional_data, additional_data_length, + ciphertext, ciphertext_length, + plaintext, plaintext_size, plaintext_length ); + + if( status != PSA_SUCCESS && plaintext_size != 0 ) + memset( plaintext, 0, plaintext_size ); + + psa_unlock_key_slot( slot ); + + return( status ); +} + /****************************************************************/ From 7ceee8d30a00d0c23084286bf9e0bee668a62b61 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 17 Mar 2021 16:55:43 +0100 Subject: [PATCH 07/17] psa: Add psa_crypto_aead.[hc] Signed-off-by: Ronald Cron --- library/CMakeLists.txt | 1 + library/Makefile | 1 + library/psa_crypto_aead.c | 28 ++++++++++++++++++++++++++++ library/psa_crypto_aead.h | 26 ++++++++++++++++++++++++++ visualc/VS2010/mbedTLS.vcxproj | 2 ++ 5 files changed, 58 insertions(+) create mode 100644 library/psa_crypto_aead.c create mode 100644 library/psa_crypto_aead.h diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 220fbf92b..256feef53 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -63,6 +63,7 @@ set(src_crypto platform_util.c poly1305.c psa_crypto.c + psa_crypto_aead.c psa_crypto_cipher.c psa_crypto_client.c psa_crypto_driver_wrappers.c diff --git a/library/Makefile b/library/Makefile index 13b0b2934..f089e0b58 100644 --- a/library/Makefile +++ b/library/Makefile @@ -120,6 +120,7 @@ OBJS_CRYPTO= \ platform_util.o \ poly1305.o \ psa_crypto.o \ + psa_crypto_aead.o \ psa_crypto_cipher.o \ psa_crypto_client.o \ psa_crypto_driver_wrappers.o \ diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c new file mode 100644 index 000000000..f45353344 --- /dev/null +++ b/library/psa_crypto_aead.c @@ -0,0 +1,28 @@ +/* + * PSA AEAD entry points + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "common.h" + +#if defined(MBEDTLS_PSA_CRYPTO_C) + +#include "psa_crypto_aead.h" + +#endif /* MBEDTLS_PSA_CRYPTO_C */ + diff --git a/library/psa_crypto_aead.h b/library/psa_crypto_aead.h new file mode 100644 index 000000000..1219e7c88 --- /dev/null +++ b/library/psa_crypto_aead.h @@ -0,0 +1,26 @@ +/* + * PSA AEAD driver entry points + */ +/* + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PSA_CRYPTO_AEAD_H +#define PSA_CRYPTO_AEAD_H + +#include + +#endif /* PSA_CRYPTO_AEAD */ diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 09c5341fb..1ebbd4b80 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -255,6 +255,7 @@ + @@ -332,6 +333,7 @@ + From 46f9178d85c1d2593925f99de271d9bfa1a50aaf Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 17 Mar 2021 08:16:34 +0100 Subject: [PATCH 08/17] psa: aead: Move AEAD driver entry points to psa_crypto_aead.c Signed-off-by: Ronald Cron --- library/psa_crypto.c | 330 +------------------------------------- library/psa_crypto_aead.c | 330 ++++++++++++++++++++++++++++++++++++++ library/psa_crypto_aead.h | 125 +++++++++++++++ 3 files changed, 457 insertions(+), 328 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 0863901f1..eb6fae0c6 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3509,222 +3509,6 @@ psa_status_t psa_cipher_abort( psa_cipher_operation_t *operation ) /* AEAD */ /****************************************************************/ -typedef struct -{ - const mbedtls_cipher_info_t *cipher_info; - union - { - unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - mbedtls_ccm_context ccm; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - mbedtls_gcm_context gcm; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - mbedtls_chachapoly_context chachapoly; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - } ctx; - psa_algorithm_t core_alg; - uint8_t full_tag_length; - uint8_t tag_length; -} aead_operation_t; - -#define AEAD_OPERATION_INIT {0, {0}, 0, 0, 0} - -static void psa_aead_abort_internal( aead_operation_t *operation ) -{ - switch( operation->core_alg ) - { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - case PSA_ALG_CCM: - mbedtls_ccm_free( &operation->ctx.ccm ); - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - case PSA_ALG_GCM: - mbedtls_gcm_free( &operation->ctx.gcm ); - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ - } -} - -static psa_status_t psa_aead_setup( - aead_operation_t *operation, - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, - psa_algorithm_t alg ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - size_t key_bits; - mbedtls_cipher_id_t cipher_id; - - key_bits = attributes->core.bits; - - operation->cipher_info = - mbedtls_cipher_info_from_psa( alg, attributes->core.type, key_bits, - &cipher_id ); - if( operation->cipher_info == NULL ) - return( PSA_ERROR_NOT_SUPPORTED ); - - switch( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ) ) - { -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ): - operation->core_alg = PSA_ALG_CCM; - operation->full_tag_length = 16; - /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16. - * The call to mbedtls_ccm_encrypt_and_tag or - * mbedtls_ccm_auth_decrypt will validate the tag length. */ - if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( attributes->core.type ) != 16 ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - mbedtls_ccm_init( &operation->ctx.ccm ); - status = mbedtls_to_psa_error( - mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id, - key_buffer, (unsigned int) key_bits ) ); - if( status != PSA_SUCCESS ) - return( status ); - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ): - operation->core_alg = PSA_ALG_GCM; - operation->full_tag_length = 16; - /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. - * The call to mbedtls_gcm_crypt_and_tag or - * mbedtls_gcm_auth_decrypt will validate the tag length. */ - if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( attributes->core.type ) != 16 ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - mbedtls_gcm_init( &operation->ctx.gcm ); - status = mbedtls_to_psa_error( - mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id, - key_buffer, (unsigned int) key_bits ) ); - if( status != PSA_SUCCESS ) - return( status ); - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ): - operation->core_alg = PSA_ALG_CHACHA20_POLY1305; - operation->full_tag_length = 16; - /* We only support the default tag length. */ - if( alg != PSA_ALG_CHACHA20_POLY1305 ) - return( PSA_ERROR_NOT_SUPPORTED ); - - mbedtls_chachapoly_init( &operation->ctx.chachapoly ); - status = mbedtls_to_psa_error( - mbedtls_chachapoly_setkey( &operation->ctx.chachapoly, - key_buffer ) ); - if( status != PSA_SUCCESS ) - return( status ); - break; -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - - default: - return( PSA_ERROR_NOT_SUPPORTED ); - } - - if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length ) - return( PSA_ERROR_INVALID_ARGUMENT ); - - operation->tag_length = PSA_AEAD_TAG_LENGTH( alg ); - - return( PSA_SUCCESS ); -} - -static psa_status_t psa_aead_encrypt_internal( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *nonce, size_t nonce_length, - const uint8_t *additional_data, size_t additional_data_length, - const uint8_t *plaintext, size_t plaintext_length, - uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - aead_operation_t operation = AEAD_OPERATION_INIT; - uint8_t *tag; - (void) key_buffer_size; - - status = psa_aead_setup( &operation, attributes, key_buffer, alg ); - if( status != PSA_SUCCESS ) - goto exit; - - /* For all currently supported modes, the tag is at the end of the - * ciphertext. */ - if( ciphertext_size < ( plaintext_length + operation.tag_length ) ) - { - status = PSA_ERROR_BUFFER_TOO_SMALL; - goto exit; - } - tag = ciphertext + plaintext_length; - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - if( operation.core_alg == PSA_ALG_GCM ) - { - status = mbedtls_to_psa_error( - mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm, - MBEDTLS_GCM_ENCRYPT, - plaintext_length, - nonce, nonce_length, - additional_data, additional_data_length, - plaintext, ciphertext, - operation.tag_length, tag ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - if( operation.core_alg == PSA_ALG_CCM ) - { - status = mbedtls_to_psa_error( - mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm, - plaintext_length, - nonce, nonce_length, - additional_data, - additional_data_length, - plaintext, ciphertext, - tag, operation.tag_length ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 ) - { - if( nonce_length != 12 || operation.tag_length != 16 ) - { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - status = mbedtls_to_psa_error( - mbedtls_chachapoly_encrypt_and_tag( &operation.ctx.chachapoly, - plaintext_length, - nonce, - additional_data, - additional_data_length, - plaintext, - ciphertext, - tag ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - { - (void) tag; - return( PSA_ERROR_NOT_SUPPORTED ); - } - - if( status == PSA_SUCCESS ) - *ciphertext_length = plaintext_length + operation.tag_length; - -exit: - psa_aead_abort_internal( &operation ); - - return( status ); -} - psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *nonce, @@ -3751,7 +3535,7 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, .core = slot->attr }; - status = psa_aead_encrypt_internal( + status = mbedtls_psa_aead_encrypt( &attributes, slot->key.data, slot->key.bytes, alg, nonce, nonce_length, @@ -3767,114 +3551,6 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, return( status ); } -/* Locate the tag in a ciphertext buffer containing the encrypted data - * followed by the tag. Return the length of the part preceding the tag in - * *plaintext_length. This is the size of the plaintext in modes where - * the encrypted data has the same size as the plaintext, such as - * CCM and GCM. */ -static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length, - const uint8_t *ciphertext, - size_t ciphertext_length, - size_t plaintext_size, - const uint8_t **p_tag ) -{ - size_t payload_length; - if( tag_length > ciphertext_length ) - return( PSA_ERROR_INVALID_ARGUMENT ); - payload_length = ciphertext_length - tag_length; - if( payload_length > plaintext_size ) - return( PSA_ERROR_BUFFER_TOO_SMALL ); - *p_tag = ciphertext + payload_length; - return( PSA_SUCCESS ); -} - -static psa_status_t psa_aead_decrypt_internal( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - psa_algorithm_t alg, - const uint8_t *nonce, size_t nonce_length, - const uint8_t *additional_data, size_t additional_data_length, - const uint8_t *ciphertext, size_t ciphertext_length, - uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ) -{ - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - aead_operation_t operation = AEAD_OPERATION_INIT; - const uint8_t *tag = NULL; - (void) key_buffer_size; - - status = psa_aead_setup( &operation, attributes, key_buffer, alg ); - if( status != PSA_SUCCESS ) - goto exit; - - status = psa_aead_unpadded_locate_tag( operation.tag_length, - ciphertext, ciphertext_length, - plaintext_size, &tag ); - if( status != PSA_SUCCESS ) - goto exit; - -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - if( operation.core_alg == PSA_ALG_GCM ) - { - status = mbedtls_to_psa_error( - mbedtls_gcm_auth_decrypt( &operation.ctx.gcm, - ciphertext_length - operation.tag_length, - nonce, nonce_length, - additional_data, - additional_data_length, - tag, operation.tag_length, - ciphertext, plaintext ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) - if( operation.core_alg == PSA_ALG_CCM ) - { - status = mbedtls_to_psa_error( - mbedtls_ccm_auth_decrypt( &operation.ctx.ccm, - ciphertext_length - operation.tag_length, - nonce, nonce_length, - additional_data, - additional_data_length, - ciphertext, plaintext, - tag, operation.tag_length ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ -#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) - if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 ) - { - if( nonce_length != 12 || operation.tag_length != 16 ) - { - status = PSA_ERROR_NOT_SUPPORTED; - goto exit; - } - status = mbedtls_to_psa_error( - mbedtls_chachapoly_auth_decrypt( &operation.ctx.chachapoly, - ciphertext_length - operation.tag_length, - nonce, - additional_data, - additional_data_length, - tag, - ciphertext, - plaintext ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ - { - return( PSA_ERROR_NOT_SUPPORTED ); - } - - if( status == PSA_SUCCESS ) - *plaintext_length = ciphertext_length - operation.tag_length; - -exit: - psa_aead_abort_internal( &operation ); - - if( status == PSA_SUCCESS ) - *plaintext_length = ciphertext_length - operation.tag_length; - return( status ); -} - psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, psa_algorithm_t alg, const uint8_t *nonce, @@ -3901,7 +3577,7 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, .core = slot->attr }; - status = psa_aead_decrypt_internal( + status = mbedtls_psa_aead_decrypt( &attributes, slot->key.data, slot->key.bytes, alg, nonce, nonce_length, @@ -3917,8 +3593,6 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, return( status ); } - - /****************************************************************/ /* Generators */ /****************************************************************/ diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c index f45353344..18ea17667 100644 --- a/library/psa_crypto_aead.c +++ b/library/psa_crypto_aead.c @@ -23,6 +23,336 @@ #if defined(MBEDTLS_PSA_CRYPTO_C) #include "psa_crypto_aead.h" +#include "psa_crypto_core.h" + +#include "mbedtls/ccm.h" +#include "mbedtls/chachapoly.h" +#include "mbedtls/cipher.h" +#include "mbedtls/gcm.h" + +typedef struct +{ + const mbedtls_cipher_info_t *cipher_info; + union + { + unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) + mbedtls_ccm_context ccm; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) + mbedtls_gcm_context gcm; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) + mbedtls_chachapoly_context chachapoly; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ + } ctx; + psa_algorithm_t core_alg; + uint8_t full_tag_length; + uint8_t tag_length; +} aead_operation_t; + +#define AEAD_OPERATION_INIT {0, {0}, 0, 0, 0} + +static void psa_aead_abort_internal( aead_operation_t *operation ) +{ + switch( operation->core_alg ) + { +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) + case PSA_ALG_CCM: + mbedtls_ccm_free( &operation->ctx.ccm ); + break; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) + case PSA_ALG_GCM: + mbedtls_gcm_free( &operation->ctx.gcm ); + break; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ + } +} + +static psa_status_t psa_aead_setup( + aead_operation_t *operation, + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, + psa_algorithm_t alg ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + size_t key_bits; + mbedtls_cipher_id_t cipher_id; + + key_bits = attributes->core.bits; + + operation->cipher_info = + mbedtls_cipher_info_from_psa( alg, attributes->core.type, key_bits, + &cipher_id ); + if( operation->cipher_info == NULL ) + return( PSA_ERROR_NOT_SUPPORTED ); + + switch( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ) ) + { +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) + case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ): + operation->core_alg = PSA_ALG_CCM; + operation->full_tag_length = 16; + /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16. + * The call to mbedtls_ccm_encrypt_and_tag or + * mbedtls_ccm_auth_decrypt will validate the tag length. */ + if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( attributes->core.type ) != 16 ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + mbedtls_ccm_init( &operation->ctx.ccm ); + status = mbedtls_to_psa_error( + mbedtls_ccm_setkey( &operation->ctx.ccm, cipher_id, + key_buffer, (unsigned int) key_bits ) ); + if( status != PSA_SUCCESS ) + return( status ); + break; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) + case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ): + operation->core_alg = PSA_ALG_GCM; + operation->full_tag_length = 16; + /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. + * The call to mbedtls_gcm_crypt_and_tag or + * mbedtls_gcm_auth_decrypt will validate the tag length. */ + if( PSA_BLOCK_CIPHER_BLOCK_LENGTH( attributes->core.type ) != 16 ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + mbedtls_gcm_init( &operation->ctx.gcm ); + status = mbedtls_to_psa_error( + mbedtls_gcm_setkey( &operation->ctx.gcm, cipher_id, + key_buffer, (unsigned int) key_bits ) ); + if( status != PSA_SUCCESS ) + return( status ); + break; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) + case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ): + operation->core_alg = PSA_ALG_CHACHA20_POLY1305; + operation->full_tag_length = 16; + /* We only support the default tag length. */ + if( alg != PSA_ALG_CHACHA20_POLY1305 ) + return( PSA_ERROR_NOT_SUPPORTED ); + + mbedtls_chachapoly_init( &operation->ctx.chachapoly ); + status = mbedtls_to_psa_error( + mbedtls_chachapoly_setkey( &operation->ctx.chachapoly, + key_buffer ) ); + if( status != PSA_SUCCESS ) + return( status ); + break; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ + + default: + return( PSA_ERROR_NOT_SUPPORTED ); + } + + if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + operation->tag_length = PSA_AEAD_TAG_LENGTH( alg ); + + return( PSA_SUCCESS ); +} + +psa_status_t mbedtls_psa_aead_encrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *plaintext, size_t plaintext_length, + uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + aead_operation_t operation = AEAD_OPERATION_INIT; + uint8_t *tag; + (void) key_buffer_size; + + status = psa_aead_setup( &operation, attributes, key_buffer, alg ); + if( status != PSA_SUCCESS ) + goto exit; + + /* For all currently supported modes, the tag is at the end of the + * ciphertext. */ + if( ciphertext_size < ( plaintext_length + operation.tag_length ) ) + { + status = PSA_ERROR_BUFFER_TOO_SMALL; + goto exit; + } + tag = ciphertext + plaintext_length; + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) + if( operation.core_alg == PSA_ALG_GCM ) + { + status = mbedtls_to_psa_error( + mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm, + MBEDTLS_GCM_ENCRYPT, + plaintext_length, + nonce, nonce_length, + additional_data, additional_data_length, + plaintext, ciphertext, + operation.tag_length, tag ) ); + } + else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) + if( operation.core_alg == PSA_ALG_CCM ) + { + status = mbedtls_to_psa_error( + mbedtls_ccm_encrypt_and_tag( &operation.ctx.ccm, + plaintext_length, + nonce, nonce_length, + additional_data, + additional_data_length, + plaintext, ciphertext, + tag, operation.tag_length ) ); + } + else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) + if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 ) + { + if( nonce_length != 12 || operation.tag_length != 16 ) + { + status = PSA_ERROR_NOT_SUPPORTED; + goto exit; + } + status = mbedtls_to_psa_error( + mbedtls_chachapoly_encrypt_and_tag( &operation.ctx.chachapoly, + plaintext_length, + nonce, + additional_data, + additional_data_length, + plaintext, + ciphertext, + tag ) ); + } + else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ + { + (void) tag; + return( PSA_ERROR_NOT_SUPPORTED ); + } + + if( status == PSA_SUCCESS ) + *ciphertext_length = plaintext_length + operation.tag_length; + +exit: + psa_aead_abort_internal( &operation ); + + return( status ); +} + +/* Locate the tag in a ciphertext buffer containing the encrypted data + * followed by the tag. Return the length of the part preceding the tag in + * *plaintext_length. This is the size of the plaintext in modes where + * the encrypted data has the same size as the plaintext, such as + * CCM and GCM. */ +static psa_status_t psa_aead_unpadded_locate_tag( size_t tag_length, + const uint8_t *ciphertext, + size_t ciphertext_length, + size_t plaintext_size, + const uint8_t **p_tag ) +{ + size_t payload_length; + if( tag_length > ciphertext_length ) + return( PSA_ERROR_INVALID_ARGUMENT ); + payload_length = ciphertext_length - tag_length; + if( payload_length > plaintext_size ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + *p_tag = ciphertext + payload_length; + return( PSA_SUCCESS ); +} + +psa_status_t mbedtls_psa_aead_decrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *ciphertext, size_t ciphertext_length, + uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + aead_operation_t operation = AEAD_OPERATION_INIT; + const uint8_t *tag = NULL; + (void) key_buffer_size; + + status = psa_aead_setup( &operation, attributes, key_buffer, alg ); + if( status != PSA_SUCCESS ) + goto exit; + + status = psa_aead_unpadded_locate_tag( operation.tag_length, + ciphertext, ciphertext_length, + plaintext_size, &tag ); + if( status != PSA_SUCCESS ) + goto exit; + +#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) + if( operation.core_alg == PSA_ALG_GCM ) + { + status = mbedtls_to_psa_error( + mbedtls_gcm_auth_decrypt( &operation.ctx.gcm, + ciphertext_length - operation.tag_length, + nonce, nonce_length, + additional_data, + additional_data_length, + tag, operation.tag_length, + ciphertext, plaintext ) ); + } + else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) + if( operation.core_alg == PSA_ALG_CCM ) + { + status = mbedtls_to_psa_error( + mbedtls_ccm_auth_decrypt( &operation.ctx.ccm, + ciphertext_length - operation.tag_length, + nonce, nonce_length, + additional_data, + additional_data_length, + ciphertext, plaintext, + tag, operation.tag_length ) ); + } + else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) + if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 ) + { + if( nonce_length != 12 || operation.tag_length != 16 ) + { + status = PSA_ERROR_NOT_SUPPORTED; + goto exit; + } + status = mbedtls_to_psa_error( + mbedtls_chachapoly_auth_decrypt( &operation.ctx.chachapoly, + ciphertext_length - operation.tag_length, + nonce, + additional_data, + additional_data_length, + tag, + ciphertext, + plaintext ) ); + } + else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ + { + return( PSA_ERROR_NOT_SUPPORTED ); + } + + if( status == PSA_SUCCESS ) + *plaintext_length = ciphertext_length - operation.tag_length; + +exit: + psa_aead_abort_internal( &operation ); + + if( status == PSA_SUCCESS ) + *plaintext_length = ciphertext_length - operation.tag_length; + return( status ); +} #endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/psa_crypto_aead.h b/library/psa_crypto_aead.h index 1219e7c88..aab0f835c 100644 --- a/library/psa_crypto_aead.h +++ b/library/psa_crypto_aead.h @@ -23,4 +23,129 @@ #include +/** + * \brief Process an authenticated encryption operation. + * + * \note The signature of this function is that of a PSA driver + * aead_encrypt entry point. This function behaves as an aead_encrypt + * entry point as defined in the PSA driver interface specification for + * transparent drivers. + * + * \param[in] attributes The attributes of the key to use for the + * operation. + * \param[in] key_buffer The buffer containing the key context. + * \param key_buffer_size Size of the \p key_buffer buffer in bytes. + * \param alg The AEAD algorithm to compute. + * \param[in] nonce Nonce or IV to use. + * \param nonce_length Size of the nonce buffer in bytes. This must + * be appropriate for the selected algorithm. + * The default nonce size is + * PSA_AEAD_NONCE_LENGTH(key_type, alg) where + * key_type is the type of key. + * \param[in] additional_data Additional data that will be authenticated + * but not encrypted. + * \param additional_data_length Size of additional_data in bytes. + * \param[in] plaintext Data that will be authenticated and encrypted. + * \param plaintext_length Size of plaintext in bytes. + * \param[out] ciphertext Output buffer for the authenticated and + * encrypted data. The additional data is not + * part of this output. For algorithms where the + * encrypted data and the authentication tag are + * defined as separate outputs, the + * authentication tag is appended to the + * encrypted data. + * \param ciphertext_size Size of the ciphertext buffer in bytes. This + * must be appropriate for the selected algorithm + * and key: + * - A sufficient output size is + * PSA_AEAD_ENCRYPT_OUTPUT_SIZE(key_type, alg, + * plaintext_length) where key_type is the type + * of key. + * - PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( + * plaintext_length) evaluates to the maximum + * ciphertext size of any supported AEAD + * encryption. + * \param[out] ciphertext_length On success, the size of the output in the + * ciphertext buffer. + * + * \retval #PSA_SUCCESS Success. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * ciphertext_size is too small. + * \retval #PSA_ERROR_CORRUPTION_DETECTED + */ +psa_status_t mbedtls_psa_aead_encrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *plaintext, size_t plaintext_length, + uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length ); + +/** + * \brief Process an authenticated decryption operation. + * + * \note The signature of this function is that of a PSA driver + * aead_decrypt entry point. This function behaves as an aead_decrypt + * entry point as defined in the PSA driver interface specification for + * transparent drivers. + * + * \param[in] attributes The attributes of the key to use for the + * operation. + * \param[in] key_buffer The buffer containing the key context. + * \param key_buffer_size Size of the \p key_buffer buffer in bytes. + * \param alg The AEAD algorithm to compute. + * \param[in] nonce Nonce or IV to use. + * \param nonce_length Size of the nonce buffer in bytes. This must + * be appropriate for the selected algorithm. + * The default nonce size is + * PSA_AEAD_NONCE_LENGTH(key_type, alg) where + * key_type is the type of key. + * \param[in] additional_data Additional data that has been authenticated + * but not encrypted. + * \param additional_data_length Size of additional_data in bytes. + * \param[in] ciphertext Data that has been authenticated and + * encrypted. For algorithms where the encrypted + * data and the authentication tag are defined + * as separate inputs, the buffer contains + * encrypted data followed by the authentication + * tag. + * \param ciphertext_length Size of ciphertext in bytes. + * \param[out] plaintext Output buffer for the decrypted data. + * \param plaintext_size Size of the plaintext buffer in bytes. This + * must be appropriate for the selected algorithm + * and key: + * - A sufficient output size is + * PSA_AEAD_DECRYPT_OUTPUT_SIZE(key_type, alg, + * ciphertext_length) where key_type is the + * type of key. + * - PSA_AEAD_DECRYPT_OUTPUT_MAX_SIZE( + * ciphertext_length) evaluates to the maximum + * plaintext size of any supported AEAD + * decryption. + * \param[out] plaintext_length On success, the size of the output in the + * plaintext buffer. + * + * \retval #PSA_SUCCESS Success. + * \retval #PSA_ERROR_INVALID_SIGNATURE + * The cipher is not authentic. + * \retval #PSA_ERROR_NOT_SUPPORTED + * \p alg is not supported. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * plaintext_size is too small. + * \retval #PSA_ERROR_CORRUPTION_DETECTED + */ +psa_status_t mbedtls_psa_aead_decrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *ciphertext, size_t ciphertext_length, + uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ); + #endif /* PSA_CRYPTO_AEAD */ From de82281541289f0ecb0222f41e988c3cf41f851f Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Wed, 17 Mar 2021 16:08:20 +0100 Subject: [PATCH 09/17] psa: aead: Add driver delegation Signed-off-by: Ronald Cron --- library/psa_crypto.c | 4 +- library/psa_crypto_driver_wrappers.c | 104 +++++++++++++++++++++++ library/psa_crypto_driver_wrappers.h | 22 +++++ tests/include/test/drivers/aead.h | 51 +++++++++++ tests/include/test/drivers/test_driver.h | 1 + tests/src/drivers/aead.c | 67 +++++++++++++++ visualc/VS2010/mbedTLS.vcxproj | 1 + 7 files changed, 248 insertions(+), 2 deletions(-) create mode 100644 tests/include/test/drivers/aead.h create mode 100644 tests/src/drivers/aead.c diff --git a/library/psa_crypto.c b/library/psa_crypto.c index eb6fae0c6..d8de189da 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3535,7 +3535,7 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, .core = slot->attr }; - status = mbedtls_psa_aead_encrypt( + status = psa_driver_wrapper_aead_encrypt( &attributes, slot->key.data, slot->key.bytes, alg, nonce, nonce_length, @@ -3577,7 +3577,7 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, .core = slot->attr }; - status = mbedtls_psa_aead_decrypt( + status = psa_driver_wrapper_aead_decrypt( &attributes, slot->key.data, slot->key.bytes, alg, nonce, nonce_length, diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 9459c4636..536505ef4 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -19,6 +19,7 @@ * limitations under the License. */ +#include "psa_crypto_aead.h" #include "psa_crypto_cipher.h" #include "psa_crypto_core.h" #include "psa_crypto_driver_wrappers.h" @@ -1177,4 +1178,107 @@ psa_status_t psa_driver_wrapper_hash_abort( } } +psa_status_t psa_driver_wrapper_aead_encrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *plaintext, size_t plaintext_length, + uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_location_t location = + PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + + switch( location ) + { + case PSA_KEY_LOCATION_LOCAL_STORAGE: + /* Key is stored in the slot in export representation, so + * cycle through all known transparent accelerators */ + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + status = test_transparent_aead_encrypt( + attributes, key_buffer, key_buffer_size, + alg, + nonce, nonce_length, + additional_data, additional_data_length, + plaintext, plaintext_length, + ciphertext, ciphertext_size, ciphertext_length ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + + /* Fell through, meaning no accelerator supports this operation */ + return( mbedtls_psa_aead_encrypt( + attributes, key_buffer, key_buffer_size, + alg, + nonce, nonce_length, + additional_data, additional_data_length, + plaintext, plaintext_length, + ciphertext, ciphertext_size, ciphertext_length ) ); + + /* Add cases for opaque driver here */ + + default: + /* Key is declared with a lifetime not known to us */ + (void)status; + return( PSA_ERROR_INVALID_ARGUMENT ); + } +} + +psa_status_t psa_driver_wrapper_aead_decrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *ciphertext, size_t ciphertext_length, + uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_location_t location = + PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + + switch( location ) + { + case PSA_KEY_LOCATION_LOCAL_STORAGE: + /* Key is stored in the slot in export representation, so + * cycle through all known transparent accelerators */ + +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) +#if defined(PSA_CRYPTO_DRIVER_TEST) + status = test_transparent_aead_decrypt( + attributes, key_buffer, key_buffer_size, + alg, + nonce, nonce_length, + additional_data, additional_data_length, + ciphertext, ciphertext_length, + plaintext, plaintext_size, plaintext_length ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + return( status ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + + /* Fell through, meaning no accelerator supports this operation */ + return( mbedtls_psa_aead_decrypt( + attributes, key_buffer, key_buffer_size, + alg, + nonce, nonce_length, + additional_data, additional_data_length, + ciphertext, ciphertext_length, + plaintext, plaintext_size, plaintext_length ) ); + + /* Add cases for opaque driver here */ + + default: + /* Key is declared with a lifetime not known to us */ + (void)status; + return( PSA_ERROR_INVALID_ARGUMENT ); + } +} /* End of automatically generated file. */ diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index e33699656..e49941138 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -156,6 +156,28 @@ psa_status_t psa_driver_wrapper_hash_finish( psa_status_t psa_driver_wrapper_hash_abort( psa_hash_operation_t *operation ); +/* + * AEAD functions + */ + +psa_status_t psa_driver_wrapper_aead_encrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *plaintext, size_t plaintext_length, + uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length ); + +psa_status_t psa_driver_wrapper_aead_decrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *ciphertext, size_t ciphertext_length, + uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ); + #endif /* PSA_CRYPTO_DRIVER_WRAPPERS_H */ /* End of automatically generated file. */ diff --git a/tests/include/test/drivers/aead.h b/tests/include/test/drivers/aead.h new file mode 100644 index 000000000..928737704 --- /dev/null +++ b/tests/include/test/drivers/aead.h @@ -0,0 +1,51 @@ +/* + * Test driver for AEAD driver entry points. + */ +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PSA_CRYPTO_TEST_DRIVERS_AEAD_H +#define PSA_CRYPTO_TEST_DRIVERS_AEAD_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(PSA_CRYPTO_DRIVER_TEST) +#include + +psa_status_t test_transparent_aead_encrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *plaintext, size_t plaintext_length, + uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length ); + +psa_status_t test_transparent_aead_decrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *ciphertext, size_t ciphertext_length, + uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ); + +#endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_TEST_DRIVERS_AEAD_H */ diff --git a/tests/include/test/drivers/test_driver.h b/tests/include/test/drivers/test_driver.h index f26b795dd..2fdce5c79 100644 --- a/tests/include/test/drivers/test_driver.h +++ b/tests/include/test/drivers/test_driver.h @@ -22,6 +22,7 @@ #define PSA_CRYPTO_TEST_DRIVER_LIFETIME 0x7fffff +#include "test/drivers/aead.h" #include "test/drivers/signature.h" #include "test/drivers/key_management.h" #include "test/drivers/cipher.h" diff --git a/tests/src/drivers/aead.c b/tests/src/drivers/aead.c new file mode 100644 index 000000000..4a2d0424c --- /dev/null +++ b/tests/src/drivers/aead.c @@ -0,0 +1,67 @@ +/* + * Test driver for AEAD entry points. + */ +/* Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PSA_CRYPTO_DRIVERS) && defined(PSA_CRYPTO_DRIVER_TEST) +#include "psa_crypto_aead.h" + +#include "test/drivers/aead.h" + +psa_status_t test_transparent_aead_encrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *plaintext, size_t plaintext_length, + uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length ) +{ + return( mbedtls_psa_aead_encrypt( + attributes, key_buffer, key_buffer_size, + alg, + nonce, nonce_length, + additional_data, additional_data_length, + plaintext, plaintext_length, + ciphertext, ciphertext_size, ciphertext_length ) ); +} + +psa_status_t test_transparent_aead_decrypt( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + psa_algorithm_t alg, + const uint8_t *nonce, size_t nonce_length, + const uint8_t *additional_data, size_t additional_data_length, + const uint8_t *ciphertext, size_t ciphertext_length, + uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ) +{ + return( mbedtls_psa_aead_decrypt( + attributes, key_buffer, key_buffer_size, + alg, + nonce, nonce_length, + additional_data, additional_data_length, + ciphertext, ciphertext_length, + plaintext, plaintext_size, plaintext_length ) ); +} + +#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */ diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 1ebbd4b80..f9271f571 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -244,6 +244,7 @@ + From bfe551d15e7d00b6c40591afac1b66e344127471 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 23 Mar 2021 09:33:25 +0100 Subject: [PATCH 10/17] tests: Add AEAD transparent test driver hooks Signed-off-by: Ronald Cron --- tests/include/test/drivers/aead.h | 19 ++++++++++++++++ tests/src/drivers/aead.c | 36 +++++++++++++++++++++++++++---- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/tests/include/test/drivers/aead.h b/tests/include/test/drivers/aead.h index 928737704..1be8910a3 100644 --- a/tests/include/test/drivers/aead.h +++ b/tests/include/test/drivers/aead.h @@ -29,6 +29,25 @@ #if defined(PSA_CRYPTO_DRIVER_TEST) #include +typedef struct { + /* If not PSA_SUCCESS, return this error code instead of processing the + * function call. */ + psa_status_t forced_status; + /* Count the amount of times AEAD driver functions are called. */ + unsigned long hits; + /* Status returned by the last AEAD driver function call. */ + psa_status_t driver_status; +} test_driver_aead_hooks_t; + +#define TEST_DRIVER_AEAD_INIT { 0, 0, 0 } +static inline test_driver_aead_hooks_t test_driver_aead_hooks_init( void ) +{ + const test_driver_aead_hooks_t v = TEST_DRIVER_AEAD_INIT; + return( v ); +} + +extern test_driver_aead_hooks_t test_driver_aead_hooks; + psa_status_t test_transparent_aead_encrypt( const psa_key_attributes_t *attributes, const uint8_t *key_buffer, size_t key_buffer_size, diff --git a/tests/src/drivers/aead.c b/tests/src/drivers/aead.c index 4a2d0424c..c87752502 100644 --- a/tests/src/drivers/aead.c +++ b/tests/src/drivers/aead.c @@ -28,6 +28,8 @@ #include "test/drivers/aead.h" +test_driver_aead_hooks_t test_driver_aead_hooks = TEST_DRIVER_AEAD_INIT; + psa_status_t test_transparent_aead_encrypt( const psa_key_attributes_t *attributes, const uint8_t *key_buffer, size_t key_buffer_size, @@ -37,13 +39,26 @@ psa_status_t test_transparent_aead_encrypt( const uint8_t *plaintext, size_t plaintext_length, uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length ) { - return( mbedtls_psa_aead_encrypt( + test_driver_aead_hooks.hits++; + + if( test_driver_aead_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_aead_hooks.driver_status = + test_driver_aead_hooks.forced_status; + } + else + { + test_driver_aead_hooks.driver_status = + mbedtls_psa_aead_encrypt( attributes, key_buffer, key_buffer_size, alg, nonce, nonce_length, additional_data, additional_data_length, plaintext, plaintext_length, - ciphertext, ciphertext_size, ciphertext_length ) ); + ciphertext, ciphertext_size, ciphertext_length ); + } + + return( test_driver_aead_hooks.driver_status ); } psa_status_t test_transparent_aead_decrypt( @@ -55,13 +70,26 @@ psa_status_t test_transparent_aead_decrypt( const uint8_t *ciphertext, size_t ciphertext_length, uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length ) { - return( mbedtls_psa_aead_decrypt( + test_driver_aead_hooks.hits++; + + if( test_driver_aead_hooks.forced_status != PSA_SUCCESS ) + { + test_driver_aead_hooks.driver_status = + test_driver_aead_hooks.forced_status; + } + else + { + test_driver_aead_hooks.driver_status = + mbedtls_psa_aead_decrypt( attributes, key_buffer, key_buffer_size, alg, nonce, nonce_length, additional_data, additional_data_length, ciphertext, ciphertext_length, - plaintext, plaintext_size, plaintext_length ) ); + plaintext, plaintext_size, plaintext_length ); + } + + return( test_driver_aead_hooks.driver_status ); } #endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */ From d17dff38e9d9f1f75d3b4c5693bceb06e3a4b4c4 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 23 Mar 2021 09:33:39 +0100 Subject: [PATCH 11/17] tests: driver wrapper: Add AEAD dispatch testing The aead_encrypt and aead_decrypt are lightly simplified and tweaked versions of test_suite_psa_crypto test functions with the same names. Signed-off-by: Ronald Cron --- ...test_suite_psa_crypto_driver_wrappers.data | 48 +++++++ ..._suite_psa_crypto_driver_wrappers.function | 127 ++++++++++++++++++ 2 files changed, 175 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data index 07311e47a..455ecf075 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data @@ -195,3 +195,51 @@ cipher_decrypt_multipart:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf715880 Cipher driver: negative testing on all entry points depends_on:PSA_WANT_ALG_CTR:PSA_WANT_KEY_TYPE_AES cipher_entry_points:PSA_ALG_CTR:PSA_KEY_TYPE_AES:"2b7e151628aed2a6abf7158809cf4f3c":"2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a":"6bc1bee22e409f96e93d7e117393172a" + +PSA AEAD encrypt: AES-CCM, 24 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":PSA_SUCCESS + +PSA AEAD encrypt: AES-CCM, 24 bytes, fallback +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":PSA_ERROR_NOT_SUPPORTED + +PSA AEAD encrypt: AES-CCM, 24 bytes, INSUFFICIENT_MEMORY +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_encrypt:PSA_KEY_TYPE_AES:"4189351B5CAEA375A0299E81C621BF43":PSA_ALG_CCM:"48c0906930561e0ab0ef4cd972":"40a27c1d1e23ea3dbe8056b2774861a4a201cce49f19997d19206d8c8a343951":"4535d12b4377928a7c0a61c9f825a48671ea05910748c8ef":"26c56961c035a7e452cce61bc6ee220d77b3f94d18fd10b6d80e8bf80f4a46cab06d4313f0db9be9":PSA_ERROR_INSUFFICIENT_MEMORY + +PSA AEAD encrypt, AES-GCM, 128 bytes #1 +depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":PSA_SUCCESS + +PSA AEAD encrypt, AES-GCM, 128 bytes #1, fallback +depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":PSA_ERROR_NOT_SUPPORTED + +PSA AEAD encrypt, AES-GCM, 128 bytes #1, INSUFFICIENT_MEMORY +depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +aead_encrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":PSA_ERROR_INSUFFICIENT_MEMORY + +PSA AEAD decrypt: AES-CCM, 39 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"00412B4EA9CDBE3C9696766CFA":"0BE1A88BACE018B1":"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8":"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":PSA_SUCCESS + +PSA AEAD decrypt: AES-CCM, 39 bytes, fallback +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"00412B4EA9CDBE3C9696766CFA":"0BE1A88BACE018B1":"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8":"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":PSA_ERROR_NOT_SUPPORTED + +PSA AEAD decrypt: AES-CCM, 39 bytes, INSUFFICIENT_MEMORY +depends_on:MBEDTLS_AES_C:MBEDTLS_CCM_C +aead_decrypt:PSA_KEY_TYPE_AES:"D7828D13B2B0BDC325A76236DF93CC6B":PSA_ALG_CCM:"00412B4EA9CDBE3C9696766CFA":"0BE1A88BACE018B1":"4CB97F86A2A4689A877947AB8091EF5386A6FFBDD080F8120333D1FCB691F3406CBF531F83A4D8":"08E8CF97D820EA258460E96AD9CF5289054D895CEAC47C":PSA_ERROR_INSUFFICIENT_MEMORY + +PSA AEAD decrypt, AES-GCM, 144 bytes #1 +depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_SUCCESS + +PSA AEAD decrypt, AES-GCM, 144 bytes #1, fallback +depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_ERROR_NOT_SUPPORTED + +PSA AEAD decrypt, AES-GCM, 144 bytes #1, INSUFFICIENT_MEMORY +depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C +aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index dd01ab691..20452b70c 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -809,3 +809,130 @@ exit: test_driver_cipher_hooks = test_driver_cipher_hooks_init(); } /* END_CASE */ + +/* BEGIN_CASE */ +void aead_encrypt( int key_type_arg, data_t *key_data, + int alg_arg, + data_t *nonce, + data_t *additional_data, + data_t *input_data, + data_t *expected_result, + int forced_status_arg ) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + psa_status_t forced_status = forced_status_arg; + unsigned char *output_data = NULL; + size_t output_size = 0; + size_t output_length = 0; + size_t tag_length = PSA_AEAD_TAG_LENGTH( alg ); + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status = PSA_ERROR_GENERIC_ERROR; + test_driver_aead_hooks = test_driver_aead_hooks_init(); + + output_size = input_data->len + tag_length; + /* For all currently defined algorithms, PSA_AEAD_ENCRYPT_OUTPUT_SIZE + * should be exact. */ + TEST_EQUAL( output_size, + PSA_AEAD_ENCRYPT_OUTPUT_SIZE( alg, input_data->len ) ); + TEST_ASSERT( output_size <= + PSA_AEAD_ENCRYPT_OUTPUT_MAX_SIZE( input_data->len ) ); + ASSERT_ALLOC( output_data, output_size ); + + PSA_ASSERT( psa_crypto_init( ) ); + + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_ENCRYPT ); + psa_set_key_algorithm( &attributes, alg ); + psa_set_key_type( &attributes, key_type ); + + PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len, + &key ) ); + + test_driver_aead_hooks.forced_status = forced_status; + status = psa_aead_encrypt( key, alg, + nonce->x, nonce->len, + additional_data->x, additional_data->len, + input_data->x, input_data->len, + output_data, output_size, + &output_length ); + TEST_EQUAL( test_driver_aead_hooks.hits, 1 ); + TEST_EQUAL( test_driver_aead_hooks.driver_status, forced_status ); + + TEST_EQUAL( status, ( forced_status == PSA_ERROR_NOT_SUPPORTED ) ? + PSA_SUCCESS : forced_status ); + + if( status == PSA_SUCCESS ) + { + ASSERT_COMPARE( expected_result->x, expected_result->len, + output_data, output_length ); + } + +exit: + psa_destroy_key( key ); + mbedtls_free( output_data ); + PSA_DONE( ); + test_driver_aead_hooks = test_driver_aead_hooks_init(); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void aead_decrypt( int key_type_arg, data_t *key_data, + int alg_arg, + data_t *nonce, + data_t *additional_data, + data_t *input_data, + data_t *expected_data, + int forced_status_arg ) +{ + mbedtls_svc_key_id_t key = MBEDTLS_SVC_KEY_ID_INIT; + psa_key_type_t key_type = key_type_arg; + psa_algorithm_t alg = alg_arg; + psa_status_t forced_status = forced_status_arg; + unsigned char *output_data = NULL; + size_t output_size = 0; + size_t output_length = 0; + size_t tag_length = PSA_AEAD_TAG_LENGTH( alg ); + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status = PSA_ERROR_GENERIC_ERROR; + test_driver_aead_hooks = test_driver_aead_hooks_init(); + + output_size = input_data->len - tag_length; + ASSERT_ALLOC( output_data, output_size ); + + PSA_ASSERT( psa_crypto_init( ) ); + + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_DECRYPT ); + psa_set_key_algorithm( &attributes, alg ); + psa_set_key_type( &attributes, key_type ); + + PSA_ASSERT( psa_import_key( &attributes, key_data->x, key_data->len, + &key ) ); + + test_driver_aead_hooks.forced_status = forced_status; + status = psa_aead_decrypt( key, alg, + nonce->x, nonce->len, + additional_data->x, + additional_data->len, + input_data->x, input_data->len, + output_data, output_size, + &output_length ); + TEST_EQUAL( test_driver_aead_hooks.hits, 1 ); + TEST_EQUAL( test_driver_aead_hooks.driver_status, forced_status ); + + TEST_EQUAL( status, ( forced_status == PSA_ERROR_NOT_SUPPORTED ) ? + PSA_SUCCESS : forced_status ); + + if( status == PSA_SUCCESS ) + { + ASSERT_COMPARE( expected_data->x, expected_data->len, + output_data, output_length ); + } + +exit: + psa_destroy_key( key ); + mbedtls_free( output_data ); + PSA_DONE( ); + test_driver_aead_hooks = test_driver_aead_hooks_init(); +} +/* END_CASE */ From 9a986165bf06089ae362bcf7c7e7447ebfc3ee26 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 26 Mar 2021 12:40:07 +0100 Subject: [PATCH 12/17] psa: aead: Accept opaque keys for encryption/decryption Signed-off-by: Ronald Cron --- library/psa_crypto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index d8de189da..217e904dd 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3526,7 +3526,7 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, *ciphertext_length = 0; - status = psa_get_and_lock_transparent_key_slot_with_policy( + status = psa_get_and_lock_key_slot_with_policy( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -3568,7 +3568,7 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, *plaintext_length = 0; - status = psa_get_and_lock_transparent_key_slot_with_policy( + status = psa_get_and_lock_key_slot_with_policy( key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); From ea7ab139914320384dfec02cd11a184fcc2a3506 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Wed, 17 Mar 2021 16:28:00 +0100 Subject: [PATCH 13/17] Do validation on the algorithm argument in AEAD Corresponds better to the validation done in other modules of PSA Crypto. Signed-off-by: Steven Cooreman Signed-off-by: Ronald Cron --- library/psa_crypto.c | 6 ++++++ tests/suites/test_suite_psa_crypto.data | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 217e904dd..0a9abda1e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -3526,6 +3526,9 @@ psa_status_t psa_aead_encrypt( mbedtls_svc_key_id_t key, *ciphertext_length = 0; + if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) ) + return( PSA_ERROR_NOT_SUPPORTED ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); if( status != PSA_SUCCESS ) @@ -3568,6 +3571,9 @@ psa_status_t psa_aead_decrypt( mbedtls_svc_key_id_t key, *plaintext_length = 0; + if( !PSA_ALG_IS_AEAD( alg ) || PSA_ALG_IS_WILDCARD( alg ) ) + return( PSA_ERROR_NOT_SUPPORTED ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); if( status != PSA_SUCCESS ) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 0b7e31843..eac38c8a2 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -558,7 +558,7 @@ aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_WITH_ PSA key policy: AEAD, min-length policy used as algorithm depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES -aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:8:PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8):PSA_ERROR_INVALID_ARGUMENT +aead_key_policy:PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8):PSA_KEY_TYPE_AES:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":13:8:PSA_ALG_AEAD_WITH_AT_LEAST_THIS_LENGTH_TAG(PSA_ALG_CCM, 8):PSA_ERROR_NOT_SUPPORTED PSA key policy: AEAD, tag length > exact-length policy depends_on:PSA_WANT_ALG_CCM:PSA_WANT_KEY_TYPE_AES From ecbc06825214788190f1dddb984a068052d69ead Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 26 Mar 2021 13:25:17 +0100 Subject: [PATCH 14/17] psa: aead: Remove from operation ctx members only used in setup Signed-off-by: Ronald Cron --- library/psa_crypto_aead.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c index 18ea17667..57352c473 100644 --- a/library/psa_crypto_aead.c +++ b/library/psa_crypto_aead.c @@ -32,7 +32,6 @@ typedef struct { - const mbedtls_cipher_info_t *cipher_info; union { unsigned dummy; /* Make the union non-empty even with no supported algorithms. */ @@ -47,11 +46,10 @@ typedef struct #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ } ctx; psa_algorithm_t core_alg; - uint8_t full_tag_length; uint8_t tag_length; } aead_operation_t; -#define AEAD_OPERATION_INIT {0, {0}, 0, 0, 0} +#define AEAD_OPERATION_INIT {{0}, 0, 0} static void psa_aead_abort_internal( aead_operation_t *operation ) { @@ -78,14 +76,16 @@ static psa_status_t psa_aead_setup( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t key_bits; + const mbedtls_cipher_info_t *cipher_info; mbedtls_cipher_id_t cipher_id; + size_t full_tag_length = 0; key_bits = attributes->core.bits; - operation->cipher_info = - mbedtls_cipher_info_from_psa( alg, attributes->core.type, key_bits, - &cipher_id ); - if( operation->cipher_info == NULL ) + cipher_info = mbedtls_cipher_info_from_psa( alg, + attributes->core.type, key_bits, + &cipher_id ); + if( cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); switch( PSA_ALG_AEAD_WITH_SHORTENED_TAG( alg, 0 ) ) @@ -93,7 +93,7 @@ static psa_status_t psa_aead_setup( #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CCM, 0 ): operation->core_alg = PSA_ALG_CCM; - operation->full_tag_length = 16; + full_tag_length = 16; /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16. * The call to mbedtls_ccm_encrypt_and_tag or * mbedtls_ccm_auth_decrypt will validate the tag length. */ @@ -112,7 +112,7 @@ static psa_status_t psa_aead_setup( #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_GCM, 0 ): operation->core_alg = PSA_ALG_GCM; - operation->full_tag_length = 16; + full_tag_length = 16; /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. * The call to mbedtls_gcm_crypt_and_tag or * mbedtls_gcm_auth_decrypt will validate the tag length. */ @@ -131,7 +131,7 @@ static psa_status_t psa_aead_setup( #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) case PSA_ALG_AEAD_WITH_SHORTENED_TAG( PSA_ALG_CHACHA20_POLY1305, 0 ): operation->core_alg = PSA_ALG_CHACHA20_POLY1305; - operation->full_tag_length = 16; + full_tag_length = 16; /* We only support the default tag length. */ if( alg != PSA_ALG_CHACHA20_POLY1305 ) return( PSA_ERROR_NOT_SUPPORTED ); @@ -149,7 +149,7 @@ static psa_status_t psa_aead_setup( return( PSA_ERROR_NOT_SUPPORTED ); } - if( PSA_AEAD_TAG_LENGTH( alg ) > operation->full_tag_length ) + if( PSA_AEAD_TAG_LENGTH( alg ) > full_tag_length ) return( PSA_ERROR_INVALID_ARGUMENT ); operation->tag_length = PSA_AEAD_TAG_LENGTH( alg ); From b9349a67a937a07719928c8bae158d7d8bd7ecd8 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 26 Mar 2021 13:32:29 +0100 Subject: [PATCH 15/17] psa: aead: Add missing chachapoly context free Signed-off-by: Ronald Cron --- library/psa_crypto_aead.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c index 57352c473..005dd3320 100644 --- a/library/psa_crypto_aead.c +++ b/library/psa_crypto_aead.c @@ -65,6 +65,11 @@ static void psa_aead_abort_internal( aead_operation_t *operation ) mbedtls_gcm_free( &operation->ctx.gcm ); break; #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) + case PSA_ALG_CHACHA20_POLY1305: + mbedtls_chachapoly_free( &operation->ctx.chachapoly ); + break; +#endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */ } } From a1971c3b720a53372a539047b02adc0ab6da8e0c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 26 Mar 2021 13:35:11 +0100 Subject: [PATCH 16/17] tests: psa: aead: Fix forced error code Signed-off-by: Ronald Cron --- tests/suites/test_suite_psa_crypto_driver_wrappers.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data index 455ecf075..241d715b3 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data @@ -242,4 +242,4 @@ aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00 PSA AEAD decrypt, AES-GCM, 144 bytes #1, INSUFFICIENT_MEMORY depends_on:MBEDTLS_AES_C:MBEDTLS_GCM_C -aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_SUCCESS +aead_decrypt:PSA_KEY_TYPE_AES:"a0ec7b0052541d9e9c091fb7fc481409":PSA_ALG_GCM:"00e440846db73a490573deaf3728c94f":"a3cfcb832e935eb5bc3812583b3a1b2e82920c07fda3668a35d939d8f11379bb606d39e6416b2ef336fffb15aec3f47a71e191f4ff6c56ff15913562619765b26ae094713d60bab6ab82bfc36edaaf8c7ce2cf5906554dcc5933acdb9cb42c1d24718efdc4a09256020b024b224cfe602772bd688c6c8f1041a46f7ec7d51208":"3b6de52f6e582d317f904ee768895bd4d0790912efcf27b58651d0eb7eb0b2f07222c6ffe9f7e127d98ccb132025b098a67dc0ec0083235e9f83af1ae1297df4319547cbcb745cebed36abc1f32a059a05ede6c00e0da097521ead901ad6a73be20018bda4c323faa135169e21581e5106ac20853642e9d6b17f1dd925c872814365847fe0b7b7fbed325953df344a96":"5431d93278c35cfcd7ffa9ce2de5c6b922edffd5055a9eaa5b54cae088db007cf2d28efaf9edd1569341889073e87c0a88462d77016744be62132fd14a243ed6e30e12cd2f7d08a8daeec161691f3b27d4996df8745d74402ee208e4055615a8cb069d495cf5146226490ac615d7b17ab39fb4fdd098e4e7ee294d34c1312826":PSA_ERROR_INSUFFICIENT_MEMORY From 810eb1683132e0c078144bc430aa57e06d5675bb Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 6 Apr 2021 09:01:39 +0200 Subject: [PATCH 17/17] psa: aead: Make CCM/GCM ordering consistent Signed-off-by: Ronald Cron --- library/psa_crypto_aead.c | 56 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/library/psa_crypto_aead.c b/library/psa_crypto_aead.c index 005dd3320..2632830f8 100644 --- a/library/psa_crypto_aead.c +++ b/library/psa_crypto_aead.c @@ -189,20 +189,6 @@ psa_status_t mbedtls_psa_aead_encrypt( } tag = ciphertext + plaintext_length; -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - if( operation.core_alg == PSA_ALG_GCM ) - { - status = mbedtls_to_psa_error( - mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm, - MBEDTLS_GCM_ENCRYPT, - plaintext_length, - nonce, nonce_length, - additional_data, additional_data_length, - plaintext, ciphertext, - operation.tag_length, tag ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) if( operation.core_alg == PSA_ALG_CCM ) { @@ -217,6 +203,20 @@ psa_status_t mbedtls_psa_aead_encrypt( } else #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) + if( operation.core_alg == PSA_ALG_GCM ) + { + status = mbedtls_to_psa_error( + mbedtls_gcm_crypt_and_tag( &operation.ctx.gcm, + MBEDTLS_GCM_ENCRYPT, + plaintext_length, + nonce, nonce_length, + additional_data, additional_data_length, + plaintext, ciphertext, + operation.tag_length, tag ) ); + } + else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 ) { @@ -296,20 +296,6 @@ psa_status_t mbedtls_psa_aead_decrypt( if( status != PSA_SUCCESS ) goto exit; -#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) - if( operation.core_alg == PSA_ALG_GCM ) - { - status = mbedtls_to_psa_error( - mbedtls_gcm_auth_decrypt( &operation.ctx.gcm, - ciphertext_length - operation.tag_length, - nonce, nonce_length, - additional_data, - additional_data_length, - tag, operation.tag_length, - ciphertext, plaintext ) ); - } - else -#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM) if( operation.core_alg == PSA_ALG_CCM ) { @@ -324,6 +310,20 @@ psa_status_t mbedtls_psa_aead_decrypt( } else #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */ +#if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM) + if( operation.core_alg == PSA_ALG_GCM ) + { + status = mbedtls_to_psa_error( + mbedtls_gcm_auth_decrypt( &operation.ctx.gcm, + ciphertext_length - operation.tag_length, + nonce, nonce_length, + additional_data, + additional_data_length, + tag, operation.tag_length, + ciphertext, plaintext ) ); + } + else +#endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */ #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305) if( operation.core_alg == PSA_ALG_CHACHA20_POLY1305 ) {