From d8a83dc17235b13a3ed1bd7db8afde1d3111fc73 Mon Sep 17 00:00:00 2001 From: Archana Date: Mon, 14 Jun 2021 10:04:16 +0530 Subject: [PATCH] Sizing of key buffer for opaque keys Create a new sizing function for determining the size required for key storage based on the input key data. This is required for key imports where the key length might need to be derived from the data. Signed-off-by: Archana --- library/psa_crypto.c | 30 ++++++++++++----- library/psa_crypto_driver_wrappers.c | 49 +++++++++++++++++++++++++--- library/psa_crypto_driver_wrappers.h | 6 ++++ 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index e962e29cb4..d70dccbf7d 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1891,6 +1891,7 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes, psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; size_t bits; + size_t storage_size = data_length; *key = MBEDTLS_SVC_KEY_ID_INIT; @@ -1906,12 +1907,18 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes, goto exit; /* In the case of a transparent key or an opaque key stored in local - * storage (thus not in the case of generating a key in a secure element - * or cryptoprocessor with storage), we have to allocate a buffer to - * hold the generated key material. */ + * storage, we have to allocate a buffer to hold the generated key + * material. */ if( slot->key.data == NULL ) { - status = psa_allocate_buffer_to_slot( slot, data_length ); + if( psa_key_lifetime_is_external( attributes->core.lifetime ) ) + { + status = psa_driver_wrapper_get_key_buffer_size_from_key_data( attributes, data, + data_length , &storage_size ); + if( status != PSA_SUCCESS ) + goto exit; + } + status = psa_allocate_buffer_to_slot( slot, storage_size ); if( status != PSA_SUCCESS ) goto exit; } @@ -4142,6 +4149,7 @@ static psa_status_t psa_generate_derived_key_internal( { uint8_t *data = NULL; size_t bytes = PSA_BITS_TO_BYTES( bits ); + size_t storage_size = bytes; psa_status_t status; if( ! key_type_is_raw_bytes( slot->attr.type ) ) @@ -4160,15 +4168,21 @@ static psa_status_t psa_generate_derived_key_internal( psa_des_set_key_parity( data, bytes ); #endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_DES */ - status = psa_allocate_buffer_to_slot( slot, bytes ); - if( status != PSA_SUCCESS ) - goto exit; - slot->attr.bits = (psa_key_bits_t) bits; psa_key_attributes_t attributes = { .core = slot->attr }; + if( psa_key_lifetime_is_external( attributes.core.lifetime ) ) + { + status = psa_driver_wrapper_get_key_buffer_size( &attributes, &storage_size ); + if( status != PSA_SUCCESS ) + goto exit; + } + status = psa_allocate_buffer_to_slot( slot, storage_size ); + if( status != PSA_SUCCESS ) + goto exit; + status = psa_driver_wrapper_import_key( &attributes, data, bytes, slot->key.data, diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 38d0e300e2..2974d6f93d 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -380,8 +380,49 @@ psa_status_t psa_driver_wrapper_verify_hash( } } +/** calculate the key buffer size required to store the key material of a key + * associated with an opaque driver from input key data. + * + * + * \param[in] attributes The key attributes + * \param[in] data The input key data. + * \param[in] data_length The input data length. + * \param[out] key_buffer_size Minimum buffer size to contain the key material. + * + * \retval #PSA_SUCCESS + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_NOT_SUPPORTED + */ +psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data( + const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + size_t *key_buffer_size ) +{ + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + psa_key_type_t key_type = attributes->core.type; + + *key_buffer_size = 0; + switch( location ) + { +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LOCATION: + *key_buffer_size = mbedtls_test_opaque_size_function( key_type, + PSA_BYTES_TO_BITS( data_length ) ); + return( ( *key_buffer_size != 0 ) ? + PSA_SUCCESS : PSA_ERROR_NOT_SUPPORTED ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + + default: + (void)key_type; + (void)data; + (void)data_length; + return( PSA_ERROR_INVALID_ARGUMENT ); + } +} + /** Get the key buffer size required to store the key material of a key - * associated with an opaque driver without storage. + * associated with an opaque driver. * * \param[in] attributes The key attributes. * \param[out] key_buffer_size Minimum buffer size to contain the key material @@ -389,11 +430,11 @@ psa_status_t psa_driver_wrapper_verify_hash( * \retval #PSA_SUCCESS * The minimum size for a buffer to contain the key material has been * returned successfully. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * The size in bits of the key is not valid. * \retval #PSA_ERROR_NOT_SUPPORTED * The type and/or the size in bits of the key or the combination of * the two is not supported. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * The key is declared with a lifetime not known to us. */ psa_status_t psa_driver_wrapper_get_key_buffer_size( const psa_key_attributes_t *attributes, @@ -426,7 +467,7 @@ psa_status_t psa_driver_wrapper_get_key_buffer_size( default: (void)key_type; (void)key_bits; - return( PSA_ERROR_NOT_SUPPORTED ); + return( PSA_ERROR_INVALID_ARGUMENT ); } } diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index 38a6ee82a7..99455a8a6c 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -85,6 +85,12 @@ psa_status_t psa_driver_wrapper_get_key_buffer_size( const psa_key_attributes_t *attributes, size_t *key_buffer_size ); +psa_status_t psa_driver_wrapper_get_key_buffer_size_from_key_data( + const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + size_t *key_buffer_size ); + psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length );