From f3bb761c0063f442935682326fb221a00b656379 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 2 Oct 2020 20:11:59 +0200 Subject: [PATCH 01/21] Improve psa_generate_key_internal() Small improvements to psa_generate_key_internal() implementation: . declare only once the status local variable and initialize it to PSA_ERROR_CORRUPTION_DETECTED to improve robustness against FI attacks. . remove an unnecessary assignment. . use type local variable instead of its global variable equivalent. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index e3ba1d38b..b673d5935 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5988,6 +5988,7 @@ static psa_status_t psa_generate_key_internal( psa_key_slot_t *slot, size_t bits, const uint8_t *domain_parameters, size_t domain_parameters_size ) { + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_type_t type = slot->attr.type; if( domain_parameters == NULL && domain_parameters_size != 0 ) @@ -5995,9 +5996,7 @@ static psa_status_t psa_generate_key_internal( if( key_type_is_raw_bytes( type ) ) { - psa_status_t status; - - status = validate_unstructured_key_bit_size( slot->attr.type, bits ); + status = validate_unstructured_key_bit_size( type, bits ); if( status != PSA_SUCCESS ) return( status ); @@ -6011,7 +6010,6 @@ static psa_status_t psa_generate_key_internal( if( status != PSA_SUCCESS ) return( status ); - slot->attr.bits = (psa_key_bits_t) bits; #if defined(MBEDTLS_DES_C) if( type == PSA_KEY_TYPE_DES ) psa_des_set_key_parity( slot->key.data, @@ -6026,7 +6024,6 @@ static psa_status_t psa_generate_key_internal( mbedtls_rsa_context rsa; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int exponent; - psa_status_t status; if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS ) return( PSA_ERROR_NOT_SUPPORTED ); /* Accept only byte-aligned keys, for the same reasons as @@ -6097,7 +6094,7 @@ static psa_status_t psa_generate_key_internal( /* Make sure to always have an export representation available */ size_t bytes = PSA_BITS_TO_BYTES( bits ); - psa_status_t status = psa_allocate_buffer_to_slot( slot, bytes ); + status = psa_allocate_buffer_to_slot( slot, bytes ); if( status != PSA_SUCCESS ) { mbedtls_ecp_keypair_free( &ecp ); From 01b2aba924c8250867493bbccfddd7d219b1e32f Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 5 Oct 2020 09:42:02 +0200 Subject: [PATCH 02/21] Move key buffer size computation out of psa_generate_key_internal() Preparatory commit to eventually change psa_generate_key_internal() signature to that of a PSA driver generate_key entry point. To be able to change the signature, the buffer to store the key has to be allocated before the call to psa_generate_key_internal() thus its size has to be calculed beforehand as well. This is the purpose of this commit: to move the computation of the key size in bytes out of psa_generate_key_internal(). Signed-off-by: Ronald Cron --- library/psa_crypto.c | 98 +++++++++++++++++++++++++++++++++----------- 1 file changed, 74 insertions(+), 24 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index b673d5935..ab50d533c 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5984,24 +5984,83 @@ static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters, } #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ -static psa_status_t psa_generate_key_internal( - psa_key_slot_t *slot, size_t bits, - const uint8_t *domain_parameters, size_t domain_parameters_size ) +/** Get the key buffer size for the key material in export format + * + * \param[in] type The key type + * \param[in] bits The number of bits of the key + * \param[out] key_buffer_size Minimum buffer size to contain the key material + * in export format + * + * \retval #PSA_SUCCESS + * The minimum size for a buffer to contain the key material in export + * format 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. + */ +static psa_status_t psa_get_key_buffer_size( + psa_key_type_t type, size_t bits, size_t *key_buffer_size ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_type_t type = slot->attr.type; - - if( domain_parameters == NULL && domain_parameters_size != 0 ) - return( PSA_ERROR_INVALID_ARGUMENT ); if( key_type_is_raw_bytes( type ) ) { status = validate_unstructured_key_bit_size( type, bits ); if( status != PSA_SUCCESS ) return( status ); + *key_buffer_size = PSA_BITS_TO_BYTES( bits ); + } + else +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) + if( PSA_KEY_TYPE_IS_RSA( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) + { + if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS ) + return( PSA_ERROR_NOT_SUPPORTED ); - /* Allocate memory for the key */ - status = psa_allocate_buffer_to_slot( slot, PSA_BITS_TO_BYTES( bits ) ); + /* Accept only byte-aligned keys, for the same reasons as + * in psa_import_rsa_key(). */ + if( bits % 8 != 0 ) + return( PSA_ERROR_NOT_SUPPORTED ); + + *key_buffer_size = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE( bits ); + } + else +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ + +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) + if( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) + { + *key_buffer_size = PSA_BITS_TO_BYTES( bits ); + } + else +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */ + { + return( PSA_ERROR_NOT_SUPPORTED ); + } + + return( PSA_SUCCESS ); +} + +static psa_status_t psa_generate_key_internal( + psa_key_slot_t *slot, size_t bits, + const uint8_t *domain_parameters, size_t domain_parameters_size ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_type_t type = slot->attr.type; + size_t key_buffer_size; + + if( domain_parameters == NULL && domain_parameters_size != 0 ) + return( PSA_ERROR_INVALID_ARGUMENT ); + + status = psa_get_key_buffer_size( slot->attr.type, bits, &key_buffer_size ); + if( status != PSA_SUCCESS ) + return( status ); + + if( key_type_is_raw_bytes( type ) ) + { + status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); if( status != PSA_SUCCESS ) return( status ); @@ -6024,12 +6083,7 @@ static psa_status_t psa_generate_key_internal( mbedtls_rsa_context rsa; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int exponent; - if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS ) - return( PSA_ERROR_NOT_SUPPORTED ); - /* Accept only byte-aligned keys, for the same reasons as - * in mbedtls_psa_rsa_import_key(). */ - if( bits % 8 != 0 ) - return( PSA_ERROR_NOT_SUPPORTED ); + status = psa_read_rsa_exponent( domain_parameters, domain_parameters_size, &exponent ); @@ -6044,10 +6098,7 @@ static psa_status_t psa_generate_key_internal( if( ret != 0 ) return( mbedtls_to_psa_error( ret ) ); - /* Make sure to always have an export representation available */ - size_t bytes = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE( bits ); - - status = psa_allocate_buffer_to_slot( slot, bytes ); + status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); if( status != PSA_SUCCESS ) { mbedtls_rsa_free( &rsa ); @@ -6057,7 +6108,7 @@ static psa_status_t psa_generate_key_internal( status = mbedtls_psa_rsa_export_key( type, &rsa, slot->key.data, - bytes, + slot->key.bytes, &slot->key.bytes ); mbedtls_rsa_free( &rsa ); if( status != PSA_SUCCESS ) @@ -6093,8 +6144,7 @@ static psa_status_t psa_generate_key_internal( /* Make sure to always have an export representation available */ - size_t bytes = PSA_BITS_TO_BYTES( bits ); - status = psa_allocate_buffer_to_slot( slot, bytes ); + status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); if( status != PSA_SUCCESS ) { mbedtls_ecp_keypair_free( &ecp ); @@ -6102,11 +6152,11 @@ static psa_status_t psa_generate_key_internal( } status = mbedtls_to_psa_error( - mbedtls_ecp_write_key( &ecp, slot->key.data, bytes ) ); + mbedtls_ecp_write_key( &ecp, slot->key.data, slot->key.bytes ) ); mbedtls_ecp_keypair_free( &ecp ); if( status != PSA_SUCCESS ) { - memset( slot->key.data, 0, bytes ); + memset( slot->key.data, 0, slot->key.bytes ); psa_remove_key_data_from_memory( slot ); } return( status ); From 2b56bc84f5d02a9feb2dd7ec0b4200123833f7ba Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 5 Oct 2020 10:02:26 +0200 Subject: [PATCH 03/21] Move key buffer allocation out of psa_generate_key_internal() Preparatory commit to eventually change psa_generate_key_internal() signature to that of a PSA driver generate_key entry point. To be able to change the signature, the buffer to store the generated key has to be allocated before the call to psa_generate_key_internal(). This commit moves the allocation and clean-up in case of error of the buffer to store the generated key from psa_generate_key_internal() to psa_generate_key(). This has the nice benefit of factorizing the key buffer allocation and clean-up. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 48 ++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index ab50d533c..4fca808ab 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -6049,21 +6049,12 @@ static psa_status_t psa_generate_key_internal( { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_type_t type = slot->attr.type; - size_t key_buffer_size; if( domain_parameters == NULL && domain_parameters_size != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_key_buffer_size( slot->attr.type, bits, &key_buffer_size ); - if( status != PSA_SUCCESS ) - return( status ); - if( key_type_is_raw_bytes( type ) ) { - status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); - if( status != PSA_SUCCESS ) - return( status ); - status = psa_generate_random( slot->key.data, slot->key.bytes ); if( status != PSA_SUCCESS ) @@ -6089,6 +6080,7 @@ static psa_status_t psa_generate_key_internal( &exponent ); if( status != PSA_SUCCESS ) return( status ); + mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE ); ret = mbedtls_rsa_gen_key( &rsa, mbedtls_psa_get_random, @@ -6098,21 +6090,13 @@ static psa_status_t psa_generate_key_internal( if( ret != 0 ) return( mbedtls_to_psa_error( ret ) ); - status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); - if( status != PSA_SUCCESS ) - { - mbedtls_rsa_free( &rsa ); - return( status ); - } - status = mbedtls_psa_rsa_export_key( type, &rsa, slot->key.data, slot->key.bytes, &slot->key.bytes ); mbedtls_rsa_free( &rsa ); - if( status != PSA_SUCCESS ) - psa_remove_key_data_from_memory( slot ); + return( status ); } else @@ -6142,23 +6126,11 @@ static psa_status_t psa_generate_key_internal( return( mbedtls_to_psa_error( ret ) ); } - - /* Make sure to always have an export representation available */ - status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); - if( status != PSA_SUCCESS ) - { - mbedtls_ecp_keypair_free( &ecp ); - return( status ); - } - status = mbedtls_to_psa_error( mbedtls_ecp_write_key( &ecp, slot->key.data, slot->key.bytes ) ); mbedtls_ecp_keypair_free( &ecp ); - if( status != PSA_SUCCESS ) { - memset( slot->key.data, 0, slot->key.bytes ); - psa_remove_key_data_from_memory( slot ); - } + return( status ); } else @@ -6176,6 +6148,7 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, psa_status_t status; psa_key_slot_t *slot = NULL; psa_se_drv_table_entry_t *driver = NULL; + size_t key_buffer_size; *key = MBEDTLS_SVC_KEY_ID_INIT; @@ -6195,10 +6168,23 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, psa_key_lifetime_is_external( attributes->core.lifetime ) ) goto exit; + status = psa_get_key_buffer_size( attributes->core.type, + attributes->core.bits, + &key_buffer_size ); + if( status != PSA_SUCCESS ) + goto exit; + + status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); + if( status != PSA_SUCCESS ) + goto exit; + status = psa_generate_key_internal( slot, attributes->core.bits, attributes->domain_parameters, attributes->domain_parameters_size ); + if( status != PSA_SUCCESS ) + psa_remove_key_data_from_memory( slot ); + exit: if( status == PSA_SUCCESS ) status = psa_finish_key_creation( slot, driver, key ); From 9cca31654c6be3d34710bb4684225966b0b6f575 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sat, 5 Dec 2020 19:07:47 +0100 Subject: [PATCH 04/21] psa: driver wrapper: Fix buffer allocation in case of key generation In case of a secure element or cryptoprocessor with storage, when generating a key, the key material is not exported from the secure element or cryptoprocessor thus there is no need to allocate a buffer in that case. Signed-off-by: Ronald Cron --- library/psa_crypto_driver_wrappers.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 1eb9ebe80..9440195cc 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -341,14 +341,19 @@ psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attrib psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); size_t export_size = 0; - status = get_expected_key_size( attributes, &export_size ); - if( status != PSA_SUCCESS ) - return( status ); - - slot->key.data = mbedtls_calloc(1, export_size); + /* If this is not to generate a key in a secure element or cryptoprocessor + * with storage. */ if( slot->key.data == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - slot->key.bytes = export_size; + { + status = get_expected_key_size( attributes, &export_size ); + if( status != PSA_SUCCESS ) + return( status ); + + slot->key.data = mbedtls_calloc(1, export_size); + if( slot->key.data == NULL ) + return( PSA_ERROR_INSUFFICIENT_MEMORY ); + slot->key.bytes = export_size; + } switch( location ) { From 31216284e1dde0e4d4e3bdec55833b7df728ddb7 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sat, 5 Dec 2020 18:47:56 +0100 Subject: [PATCH 05/21] psa: driver wrapper: Clarify the scope of and rename get_expected_key_size Restrict the scope of get_expected_key_size to generation of key in a secure element or cryptoprocessor without storage. For transparent driver, the key buffer size calculation is for the time being moved to psa_driver_wrapper_generate_key and will eventually be done by psa_get_key_buffer_size. Rename the function to get_key_buffer_size to align its naming with that of psa_get_key_buffer_size. Signed-off-by: Ronald Cron --- library/psa_crypto_driver_wrappers.c | 68 +++++++++++++++------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 9440195cc..07888f1de 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -239,61 +239,56 @@ psa_status_t psa_driver_wrapper_verify_hash( psa_key_slot_t *slot, } #if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) -/** Calculate the size to allocate for buffering a key with given attributes. +/** Get the key buffer size for the key material of a generated key in the + * case of an opaque driver without storage. * - * This function provides a way to get the expected size for storing a key with - * the given attributes. This will be the size of the export representation for - * cleartext keys, and a driver-defined size for keys stored by opaque drivers. - * - * \param[in] attributes The key attribute structure of the key to store. - * \param[out] expected_size On success, a byte size large enough to contain - * the declared key. + * \param[in] attributes The key attributes. + * \param[out] key_buffer_size Minimum buffer size to contain the key material * * \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. */ -static psa_status_t get_expected_key_size( const psa_key_attributes_t *attributes, - size_t *expected_size ) +static psa_status_t get_key_buffer_size( + const psa_key_attributes_t *attributes, + size_t *key_buffer_size ) { - size_t buffer_size = 0; psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); psa_key_type_t key_type = attributes->core.type; size_t key_bits = attributes->core.bits; + *key_buffer_size = 0; switch( location ) { - case PSA_KEY_LOCATION_LOCAL_STORAGE: - buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits ); - - if( buffer_size == 0 ) - return( PSA_ERROR_NOT_SUPPORTED ); - - *expected_size = buffer_size; - return( PSA_SUCCESS ); - #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TEST_DRIVER_LIFETIME: #ifdef TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION - *expected_size = test_size_function( key_type, key_bits ); + *key_buffer_size = test_size_function( key_type, key_bits ); return( PSA_SUCCESS ); #else /* TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION */ if( PSA_KEY_TYPE_IS_KEY_PAIR( key_type ) ) { - int public_key_overhead = ( ( TEST_DRIVER_KEY_CONTEXT_STORE_PUBLIC_KEY == 1 ) ? - PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits ) : 0 ); - *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE + int public_key_overhead = + ( ( TEST_DRIVER_KEY_CONTEXT_STORE_PUBLIC_KEY == 1 ) ? + PSA_EXPORT_KEY_OUTPUT_SIZE( key_type, key_bits ) : 0 ); + *key_buffer_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE + TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE + public_key_overhead; } - else if( PSA_KEY_TYPE_IS_PUBLIC_KEY( attributes->core.type ) ) + else if( PSA_KEY_TYPE_IS_PUBLIC_KEY( key_type ) ) { - *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE + *key_buffer_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE + TEST_DRIVER_KEY_CONTEXT_PUBLIC_KEY_SIZE; } else if ( !PSA_KEY_TYPE_IS_KEY_PAIR( key_type ) && - !PSA_KEY_TYPE_IS_PUBLIC_KEY ( attributes->core.type ) ) + !PSA_KEY_TYPE_IS_PUBLIC_KEY ( key_type ) ) { - *expected_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE + *key_buffer_size = TEST_DRIVER_KEY_CONTEXT_BASE_SIZE + TEST_DRIVER_KEY_CONTEXT_SYMMETRIC_FACTOR * ( ( key_bits + 7 ) / 8 ); } @@ -345,10 +340,21 @@ psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attrib * with storage. */ if( slot->key.data == NULL ) { - status = get_expected_key_size( attributes, &export_size ); - if( status != PSA_SUCCESS ) - return( status ); + if( location == PSA_KEY_LOCATION_LOCAL_STORAGE ) + { + export_size = PSA_KEY_EXPORT_MAX_SIZE( attributes->core.type, + attributes->core.bits ); + if( export_size == 0 ) + return( PSA_ERROR_NOT_SUPPORTED ); + } + else + { + status = get_key_buffer_size( attributes, &export_size ); + if( status != PSA_SUCCESS ) + return( status ); + } + slot->key.data = mbedtls_calloc(1, export_size); if( slot->key.data == NULL ) return( PSA_ERROR_INSUFFICIENT_MEMORY ); From 9df74beea71a29c22a8eef5ec3f641945d5f8048 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Sat, 5 Dec 2020 19:15:23 +0100 Subject: [PATCH 06/21] psa: driver wrapper: Rename and export get_key_buffer_size Rename and export get_key_buffer_size to be able to call it from psa_crypto.c to compute the size of buffers to contain keys generated by an opaque driver without storage. Signed-off-by: Ronald Cron --- library/psa_crypto_driver_wrappers.c | 9 +++++---- library/psa_crypto_driver_wrappers.h | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 07888f1de..e0c86cf75 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -238,7 +238,6 @@ psa_status_t psa_driver_wrapper_verify_hash( psa_key_slot_t *slot, #endif /* PSA_CRYPTO_DRIVER_PRESENT */ } -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) /** Get the key buffer size for the key material of a generated key in the * case of an opaque driver without storage. * @@ -254,7 +253,7 @@ psa_status_t psa_driver_wrapper_verify_hash( psa_key_slot_t *slot, * The type and/or the size in bits of the key or the combination of * the two is not supported. */ -static psa_status_t get_key_buffer_size( +psa_status_t psa_driver_wrapper_get_key_buffer_size( const psa_key_attributes_t *attributes, size_t *key_buffer_size ) { @@ -301,10 +300,11 @@ static psa_status_t get_key_buffer_size( #endif /* PSA_CRYPTO_DRIVER_TEST */ default: + (void)key_type; + (void)key_bits; return( PSA_ERROR_NOT_SUPPORTED ); } } -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes, psa_key_slot_t *slot ) @@ -350,7 +350,8 @@ psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attrib } else { - status = get_key_buffer_size( attributes, &export_size ); + status = psa_driver_wrapper_get_key_buffer_size( attributes, + &export_size ); if( status != PSA_SUCCESS ) return( status ); } diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index 27d8b64ea..b9bb53e21 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -63,6 +63,10 @@ psa_status_t psa_driver_wrapper_export_public_key( const uint8_t *key_buffer, size_t key_buffer_size, uint8_t *data, size_t data_size, size_t *data_length ); +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_generate_key( const psa_key_attributes_t *attributes, psa_key_slot_t *slot ); From 2a38a6b98f28c9cc828c7a4e2a139bedfbcb8ffd Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 2 Oct 2020 20:02:04 +0200 Subject: [PATCH 07/21] Change psa_generate_key_internal() signature Change psa_generate_key_internal() signature to that of a PSA driver generate_key entry point. That way, this function can be called by the driver wrapper when a software fallback is necessary. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 64 +++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 4fca808ab..c4b091357 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -6043,27 +6043,46 @@ static psa_status_t psa_get_key_buffer_size( return( PSA_SUCCESS ); } +/** + * \brief Generate a key. + * + * \note The signature of the function is that of a PSA driver generate_key + * entry point. + * + * \param[in] attributes The attributes for the key to generate. + * \param[out] key_buffer Buffer where the key data is to be written. + * \param[in] key_buffer_size Size of \p key_buffer in bytes. + * \param[out] key_buffer_length On success, the number of bytes written in + * \p key_buffer. + * + * \retval #PSA_SUCCESS + * The key was generated successfully. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_NOT_SUPPORTED + * Key size in bits or type not supported. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of \p key_buffer is too small. + */ static psa_status_t psa_generate_key_internal( - psa_key_slot_t *slot, size_t bits, - const uint8_t *domain_parameters, size_t domain_parameters_size ) + const psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_type_t type = slot->attr.type; + psa_key_type_t type = attributes->core.type; - if( domain_parameters == NULL && domain_parameters_size != 0 ) + if( ( attributes->domain_parameters == NULL ) && + ( attributes->domain_parameters_size != 0 ) ) return( PSA_ERROR_INVALID_ARGUMENT ); if( key_type_is_raw_bytes( type ) ) { - status = psa_generate_random( slot->key.data, - slot->key.bytes ); + status = psa_generate_random( key_buffer, key_buffer_size ); if( status != PSA_SUCCESS ) return( status ); #if defined(MBEDTLS_DES_C) if( type == PSA_KEY_TYPE_DES ) - psa_des_set_key_parity( slot->key.data, - slot->key.bytes ); + psa_des_set_key_parity( key_buffer, key_buffer_size ); #endif /* MBEDTLS_DES_C */ } else @@ -6075,8 +6094,8 @@ static psa_status_t psa_generate_key_internal( int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int exponent; - status = psa_read_rsa_exponent( domain_parameters, - domain_parameters_size, + status = psa_read_rsa_exponent( attributes->domain_parameters, + attributes->domain_parameters_size, &exponent ); if( status != PSA_SUCCESS ) return( status ); @@ -6085,16 +6104,16 @@ static psa_status_t psa_generate_key_internal( ret = mbedtls_rsa_gen_key( &rsa, mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE, - (unsigned int) bits, + (unsigned int) attributes->core.bits, exponent ); if( ret != 0 ) return( mbedtls_to_psa_error( ret ) ); status = mbedtls_psa_rsa_export_key( type, &rsa, - slot->key.data, - slot->key.bytes, - &slot->key.bytes ); + key_buffer, + key_buffer_size, + key_buffer_length ); mbedtls_rsa_free( &rsa ); return( status ); @@ -6107,15 +6126,17 @@ static psa_status_t psa_generate_key_internal( { psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( type ); mbedtls_ecp_group_id grp_id = - mbedtls_ecc_group_of_psa( curve, bits, 0 ); + mbedtls_ecc_group_of_psa( curve, attributes->core.bits, 0 ); + const mbedtls_ecp_curve_info *curve_info = mbedtls_ecp_curve_info_from_grp_id( grp_id ); mbedtls_ecp_keypair ecp; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - if( domain_parameters_size != 0 ) + if( attributes->domain_parameters_size != 0 ) return( PSA_ERROR_NOT_SUPPORTED ); if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); + mbedtls_ecp_keypair_init( &ecp ); ret = mbedtls_ecp_gen_key( grp_id, &ecp, mbedtls_psa_get_random, @@ -6127,15 +6148,19 @@ static psa_status_t psa_generate_key_internal( } status = mbedtls_to_psa_error( - mbedtls_ecp_write_key( &ecp, slot->key.data, slot->key.bytes ) ); + mbedtls_ecp_write_key( &ecp, key_buffer, key_buffer_size ) ); mbedtls_ecp_keypair_free( &ecp ); + if( status == PSA_SUCCESS ) + *key_buffer_length = key_buffer_size; + return( status ); } else #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */ { + (void)key_buffer_length; return( PSA_ERROR_NOT_SUPPORTED ); } @@ -6179,8 +6204,7 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, goto exit; status = psa_generate_key_internal( - slot, attributes->core.bits, - attributes->domain_parameters, attributes->domain_parameters_size ); + attributes, slot->key.data, slot->key.bytes, &slot->key.bytes ); if( status != PSA_SUCCESS ) psa_remove_key_data_from_memory( slot ); @@ -6194,8 +6218,6 @@ exit: return( status ); } - - /****************************************************************/ /* Module setup */ /****************************************************************/ From 55ed0591c861d3c1ebda7bbf43cc1fe3cdb43650 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 5 Oct 2020 10:30:40 +0200 Subject: [PATCH 08/21] Export "internally" psa_generate_key_internal() Export psa_generate_key_internal() to make it available to the driver wrapper. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 22 +--------------------- library/psa_crypto_core.h | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index c4b091357..67fdd5c6d 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -6043,27 +6043,7 @@ static psa_status_t psa_get_key_buffer_size( return( PSA_SUCCESS ); } -/** - * \brief Generate a key. - * - * \note The signature of the function is that of a PSA driver generate_key - * entry point. - * - * \param[in] attributes The attributes for the key to generate. - * \param[out] key_buffer Buffer where the key data is to be written. - * \param[in] key_buffer_size Size of \p key_buffer in bytes. - * \param[out] key_buffer_length On success, the number of bytes written in - * \p key_buffer. - * - * \retval #PSA_SUCCESS - * The key was generated successfully. - * \retval #PSA_ERROR_INVALID_ARGUMENT - * \retval #PSA_ERROR_NOT_SUPPORTED - * Key size in bits or type not supported. - * \retval #PSA_ERROR_BUFFER_TOO_SMALL - * The size of \p key_buffer is too small. - */ -static psa_status_t psa_generate_key_internal( +psa_status_t psa_generate_key_internal( const psa_key_attributes_t *attributes, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) { diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index cf9d6d0eb..9f108681a 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -299,4 +299,29 @@ psa_status_t psa_export_public_key_internal( const uint8_t *key_buffer, size_t key_buffer_size, uint8_t *data, size_t data_size, size_t *data_length ); +/** + * \brief Generate a key. + * + * \note The signature of the function is that of a PSA driver generate_key + * entry point. + * + * \param[in] attributes The attributes for the key to generate. + * \param[out] key_buffer Buffer where the key data is to be written. + * \param[in] key_buffer_size Size of \p key_buffer in bytes. + * \param[out] key_buffer_length On success, the number of bytes written in + * \p key_buffer. + * + * \retval #PSA_SUCCESS + * The key was generated successfully. + * \retval #PSA_ERROR_INVALID_ARGUMENT + * \retval #PSA_ERROR_NOT_SUPPORTED + * Key size in bits or type not supported. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of \p key_buffer is too small. + */ +psa_status_t psa_generate_key_internal( const psa_key_attributes_t *attributes, + uint8_t *key_buffer, + size_t key_buffer_size, + size_t *key_buffer_length ); + #endif /* PSA_CRYPTO_CORE_H */ From 5c4d38639db1be6324f448991314f0276179c196 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 7 Dec 2020 11:07:24 +0100 Subject: [PATCH 09/21] psa: Extend psa_get_key_buffer_size scope When generating transparent keys, we need to be able to compute the size of the key buffer whether the key is generated by the Mbed TLS library or by an accelerator. Thus, change the RSA/ECP MBEDTLS_PSA_BUILTIN_... compilation guards with their PSA_WANT_... counterparts. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 67fdd5c6d..0f7d4bdcb 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -6013,7 +6013,7 @@ static psa_status_t psa_get_key_buffer_size( *key_buffer_size = PSA_BITS_TO_BYTES( bits ); } else -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) +#if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) if( PSA_KEY_TYPE_IS_RSA( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) { if( bits > PSA_VENDOR_RSA_MAX_KEY_BITS ) @@ -6027,15 +6027,15 @@ static psa_status_t psa_get_key_buffer_size( *key_buffer_size = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE( bits ); } else -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ +#endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) */ -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) +#if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) if( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) { *key_buffer_size = PSA_BITS_TO_BYTES( bits ); } else -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */ +#endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) */ { return( PSA_ERROR_NOT_SUPPORTED ); } From 977c24704888ec5a330b918d1225202b8e852f1c Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 13 Oct 2020 08:32:21 +0200 Subject: [PATCH 10/21] Call software implementation as a driver Signed-off-by: Ronald Cron --- library/psa_crypto.c | 44 ++++++----- library/psa_crypto_driver_wrappers.c | 105 ++++++++------------------- library/psa_crypto_driver_wrappers.h | 2 +- 3 files changed, 59 insertions(+), 92 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 0f7d4bdcb..cbec9dda0 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -6167,24 +6167,34 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, if( status != PSA_SUCCESS ) 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. */ + if( slot->key.data == NULL ) + { + if ( PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ) == + PSA_KEY_LOCATION_LOCAL_STORAGE ) + { + status = psa_get_key_buffer_size( attributes->core.type, + attributes->core.bits, + &key_buffer_size ); + } + else + { + status = psa_driver_wrapper_get_key_buffer_size( + attributes, &key_buffer_size ); + } + if( status != PSA_SUCCESS ) + goto exit; + + status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); + if( status != PSA_SUCCESS ) + goto exit; + } + status = psa_driver_wrapper_generate_key( attributes, - slot ); - if( status != PSA_ERROR_NOT_SUPPORTED || - psa_key_lifetime_is_external( attributes->core.lifetime ) ) - goto exit; - - status = psa_get_key_buffer_size( attributes->core.type, - attributes->core.bits, - &key_buffer_size ); - if( status != PSA_SUCCESS ) - goto exit; - - status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); - if( status != PSA_SUCCESS ) - goto exit; - - status = psa_generate_key_internal( - attributes, slot->key.data, slot->key.bytes, &slot->key.bytes ); + slot->key.data, slot->key.bytes, &slot->key.bytes ); if( status != PSA_SUCCESS ) psa_remove_key_data_from_memory( slot ); diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index e0c86cf75..3cb75576e 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -306,16 +306,20 @@ psa_status_t psa_driver_wrapper_get_key_buffer_size( } } -psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes, - psa_key_slot_t *slot ) +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 ) { -#if defined(PSA_CRYPTO_DRIVER_PRESENT) + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_location_t location = + PSA_KEY_LIFETIME_GET_LOCATION(attributes->core.lifetime); + /* Try dynamically-registered SE interface first */ #if defined(MBEDTLS_PSA_CRYPTO_SE_C) const psa_drv_se_t *drv; psa_drv_se_context_t *drv_context; - if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) ) + if( psa_get_se_driver( attributes->core.lifetime, &drv, &drv_context ) ) { size_t pubkey_length = 0; /* We don't support this feature yet */ if( drv->key_management == NULL || @@ -325,100 +329,53 @@ psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attrib return( PSA_ERROR_NOT_SUPPORTED ); } return( drv->key_management->p_generate( - drv_context, psa_key_slot_get_slot_number( slot ), + drv_context, + *( (psa_key_slot_number_t *)key_buffer ), attributes, NULL, 0, &pubkey_length ) ); } #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - /* Then try accelerator API */ -#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) - psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; - psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(slot->attr.lifetime); - size_t export_size = 0; - - /* If this is not to generate a key in a secure element or cryptoprocessor - * with storage. */ - if( slot->key.data == NULL ) - { - if( location == PSA_KEY_LOCATION_LOCAL_STORAGE ) - { - export_size = PSA_KEY_EXPORT_MAX_SIZE( attributes->core.type, - attributes->core.bits ); - - if( export_size == 0 ) - return( PSA_ERROR_NOT_SUPPORTED ); - } - else - { - status = psa_driver_wrapper_get_key_buffer_size( attributes, - &export_size ); - if( status != PSA_SUCCESS ) - return( status ); - } - - slot->key.data = mbedtls_calloc(1, export_size); - if( slot->key.data == NULL ) - return( PSA_ERROR_INSUFFICIENT_MEMORY ); - slot->key.bytes = export_size; - } - 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) /* Transparent drivers are limited to generating asymmetric keys */ - if( ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) ) + if( PSA_KEY_TYPE_IS_ASYMMETRIC( attributes->core.type ) ) { - status = PSA_ERROR_NOT_SUPPORTED; - break; - } + /* Cycle through all known transparent accelerators */ #if defined(PSA_CRYPTO_DRIVER_TEST) - status = test_transparent_generate_key( attributes, - slot->key.data, - slot->key.bytes, - &slot->key.bytes ); - /* Declared with fallback == true */ - if( status != PSA_ERROR_NOT_SUPPORTED ) - break; + status = test_transparent_generate_key( + attributes, key_buffer, key_buffer_size, + key_buffer_length ); + /* Declared with fallback == true */ + if( status != PSA_ERROR_NOT_SUPPORTED ) + break; #endif /* PSA_CRYPTO_DRIVER_TEST */ - /* Fell through, meaning no accelerator supports this operation */ - status = PSA_ERROR_NOT_SUPPORTED; + } +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + + /* Software fallback */ + status = psa_generate_key_internal( + attributes, key_buffer, key_buffer_size, key_buffer_length ); break; + /* Add cases for opaque driver here */ +#if defined(PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT) #if defined(PSA_CRYPTO_DRIVER_TEST) case PSA_CRYPTO_TEST_DRIVER_LIFETIME: - status = test_opaque_generate_key( attributes, - slot->key.data, - slot->key.bytes, - &slot->key.bytes ); + status = test_opaque_generate_key( + attributes, key_buffer, key_buffer_size, key_buffer_length ); break; #endif /* PSA_CRYPTO_DRIVER_TEST */ +#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ + default: /* Key is declared with a lifetime not known to us */ status = PSA_ERROR_INVALID_ARGUMENT; break; } - if( status != PSA_SUCCESS ) - { - /* free allocated buffer */ - mbedtls_free( slot->key.data ); - slot->key.data = NULL; - slot->key.bytes = 0; - } - return( status ); -#else /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_ACCELERATOR_DRIVER_PRESENT */ -#else /* PSA_CRYPTO_DRIVER_PRESENT */ - (void) attributes; - (void) slot; - - return( PSA_ERROR_NOT_SUPPORTED ); -#endif /* PSA_CRYPTO_DRIVER_PRESENT */ } psa_status_t psa_driver_wrapper_import_key( diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index b9bb53e21..ad16cddea 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -69,7 +69,7 @@ psa_status_t psa_driver_wrapper_get_key_buffer_size( psa_status_t psa_driver_wrapper_generate_key( const psa_key_attributes_t *attributes, - psa_key_slot_t *slot ); + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ); /* * Cipher functions From 9e18fc1cf9427ec71a42a7dea5cc3e1f81b562ed Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Thu, 5 Nov 2020 17:36:40 +0100 Subject: [PATCH 11/21] Move RSA key generation code to the PSA RSA specific C file Signed-off-by: Ronald Cron --- library/psa_crypto.c | 59 +++----------------------------------- library/psa_crypto_rsa.c | 61 ++++++++++++++++++++++++++++++++++++++++ library/psa_crypto_rsa.h | 23 +++++++++++++++ 3 files changed, 88 insertions(+), 55 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index cbec9dda0..152651996 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5956,34 +5956,6 @@ psa_status_t mbedtls_psa_inject_entropy( const uint8_t *seed, } #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ -#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) -static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters, - size_t domain_parameters_size, - int *exponent ) -{ - size_t i; - uint32_t acc = 0; - - if( domain_parameters_size == 0 ) - { - *exponent = 65537; - return( PSA_SUCCESS ); - } - - /* Mbed TLS encodes the public exponent as an int. For simplicity, only - * support values that fit in a 32-bit integer, which is larger than - * int on just about every platform anyway. */ - if( domain_parameters_size > sizeof( acc ) ) - return( PSA_ERROR_NOT_SUPPORTED ); - for( i = 0; i < domain_parameters_size; i++ ) - acc = ( acc << 8 ) | domain_parameters[i]; - if( acc > INT_MAX ) - return( PSA_ERROR_NOT_SUPPORTED ); - *exponent = acc; - return( PSA_SUCCESS ); -} -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ - /** Get the key buffer size for the key material in export format * * \param[in] type The key type @@ -6070,33 +6042,10 @@ psa_status_t psa_generate_key_internal( #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) if ( type == PSA_KEY_TYPE_RSA_KEY_PAIR ) { - mbedtls_rsa_context rsa; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - int exponent; - - status = psa_read_rsa_exponent( attributes->domain_parameters, - attributes->domain_parameters_size, - &exponent ); - if( status != PSA_SUCCESS ) - return( status ); - - mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE ); - ret = mbedtls_rsa_gen_key( &rsa, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE, - (unsigned int) attributes->core.bits, - exponent ); - if( ret != 0 ) - return( mbedtls_to_psa_error( ret ) ); - - status = mbedtls_psa_rsa_export_key( type, - &rsa, - key_buffer, - key_buffer_size, - key_buffer_length ); - mbedtls_rsa_free( &rsa ); - - return( status ); + return( mbedtls_psa_rsa_generate_key( attributes, + key_buffer, + key_buffer_size, + key_buffer_length ) ); } else #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c index aae1d056a..157f08471 100644 --- a/library/psa_crypto_rsa.c +++ b/library/psa_crypto_rsa.c @@ -24,6 +24,7 @@ #include #include "psa_crypto_core.h" +#include "psa_crypto_random_impl.h" #include "psa_crypto_rsa.h" #include @@ -258,6 +259,66 @@ static psa_status_t rsa_export_public_key( #endif /* defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || * defined(BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ +#if defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) +static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters, + size_t domain_parameters_size, + int *exponent ) +{ + size_t i; + uint32_t acc = 0; + + if( domain_parameters_size == 0 ) + { + *exponent = 65537; + return( PSA_SUCCESS ); + } + + /* Mbed TLS encodes the public exponent as an int. For simplicity, only + * support values that fit in a 32-bit integer, which is larger than + * int on just about every platform anyway. */ + if( domain_parameters_size > sizeof( acc ) ) + return( PSA_ERROR_NOT_SUPPORTED ); + for( i = 0; i < domain_parameters_size; i++ ) + acc = ( acc << 8 ) | domain_parameters[i]; + if( acc > INT_MAX ) + return( PSA_ERROR_NOT_SUPPORTED ); + *exponent = acc; + return( PSA_SUCCESS ); +} + +psa_status_t mbedtls_psa_rsa_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) +{ + psa_status_t status; + mbedtls_rsa_context rsa; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + int exponent; + + status = psa_read_rsa_exponent( attributes->domain_parameters, + attributes->domain_parameters_size, + &exponent ); + if( status != PSA_SUCCESS ) + return( status ); + + mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE ); + ret = mbedtls_rsa_gen_key( &rsa, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE, + (unsigned int)attributes->core.bits, + exponent ); + if( ret != 0 ) + return( mbedtls_to_psa_error( ret ) ); + + status = mbedtls_psa_rsa_export_key( attributes->core.type, + &rsa, key_buffer, key_buffer_size, + key_buffer_length ); + mbedtls_rsa_free( &rsa ); + + return( status ); +} +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ + #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) diff --git a/library/psa_crypto_rsa.h b/library/psa_crypto_rsa.h index 64013df73..87e0a61d1 100644 --- a/library/psa_crypto_rsa.h +++ b/library/psa_crypto_rsa.h @@ -114,6 +114,29 @@ psa_status_t mbedtls_psa_rsa_export_public_key( const uint8_t *key_buffer, size_t key_buffer_size, uint8_t *data, size_t data_size, size_t *data_length ); +/** + * \brief Generate an RSA key. + * + * \note The signature of the function is that of a PSA driver generate_key + * entry point. + * + * \param[in] attributes The attributes for the RSA key to generate. + * \param[out] key_buffer Buffer where the key data is to be written. + * \param[in] key_buffer_size Size of \p key_buffer in bytes. + * \param[out] key_buffer_length On success, the number of bytes written in + * \p key_buffer. + * + * \retval #PSA_SUCCESS + * The key was successfully generated. + * \retval #PSA_ERROR_NOT_SUPPORTED + * Key length or type not supported. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of \p key_buffer is too small. + */ +psa_status_t mbedtls_psa_rsa_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ); + /* * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY. */ From 3a9c46b1849b18508331d36e5582a09a5658679d Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 6 Nov 2020 09:38:35 +0100 Subject: [PATCH 12/21] Add RSA key generation support to the transparent test driver Signed-off-by: Ronald Cron --- library/psa_crypto_rsa.c | 24 ++++++++++++++++++++++-- library/psa_crypto_rsa.h | 4 ++++ tests/src/drivers/key_management.c | 17 +++++++++++------ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c index 157f08471..8cdaa7b77 100644 --- a/library/psa_crypto_rsa.c +++ b/library/psa_crypto_rsa.c @@ -286,7 +286,7 @@ static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters, return( PSA_SUCCESS ); } -psa_status_t mbedtls_psa_rsa_generate_key( +static psa_status_t rsa_generate_key( const psa_key_attributes_t *attributes, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) { @@ -317,7 +317,7 @@ psa_status_t mbedtls_psa_rsa_generate_key( return( status ); } -#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ +#endif /* defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || \ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) @@ -345,6 +345,16 @@ psa_status_t mbedtls_psa_rsa_export_public_key( #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) || * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) +psa_status_t mbedtls_psa_rsa_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) +{ + return( rsa_generate_key( attributes, key_buffer, key_buffer_size, + key_buffer_length ) ); +} +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_RSA_KEY_PAIR) */ + /* * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY. */ @@ -377,6 +387,16 @@ psa_status_t mbedtls_transparent_test_driver_rsa_export_public_key( #endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) || defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) */ +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) +psa_status_t mbedtls_transparent_test_driver_rsa_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) +{ + return( rsa_generate_key( attributes, key_buffer, key_buffer_size, + key_buffer_length ) ); +} +#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) */ + #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/psa_crypto_rsa.h b/library/psa_crypto_rsa.h index 87e0a61d1..08182a7f2 100644 --- a/library/psa_crypto_rsa.h +++ b/library/psa_crypto_rsa.h @@ -154,6 +154,10 @@ psa_status_t mbedtls_transparent_test_driver_rsa_export_public_key( const uint8_t *key_buffer, size_t key_buffer_size, uint8_t *data, size_t data_size, size_t *data_length ); +psa_status_t mbedtls_transparent_test_driver_rsa_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key, size_t key_size, size_t *key_length ); + #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_RSA_H */ diff --git a/tests/src/drivers/key_management.c b/tests/src/drivers/key_management.c index be6a81492..46af648f8 100644 --- a/tests/src/drivers/key_management.c +++ b/tests/src/drivers/key_management.c @@ -45,11 +45,6 @@ psa_status_t test_transparent_generate_key( const psa_key_attributes_t *attributes, uint8_t *key, size_t key_size, size_t *key_length ) { -#if !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) && \ - !defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) - (void)attributes; -#endif /* !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR && - * !MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY */ ++test_driver_key_management_hooks.hits; if( test_driver_key_management_hooks.forced_status != PSA_SUCCESS ) @@ -125,7 +120,17 @@ psa_status_t test_transparent_generate_key( else #endif /* MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR || * MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY */ - return( PSA_ERROR_NOT_SUPPORTED ); + +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) + if ( psa_get_key_type( attributes ) == PSA_KEY_TYPE_RSA_KEY_PAIR ) + return( mbedtls_transparent_test_driver_rsa_generate_key( + attributes, key, key_size, key_length ) ); + else +#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) */ + { + (void)attributes; + return( PSA_ERROR_NOT_SUPPORTED ); + } } psa_status_t test_opaque_generate_key( From 7023db52736aa12a8036aee22ace3e1e188bf5a5 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 20 Nov 2020 18:17:42 +0100 Subject: [PATCH 13/21] Move ECP key generation code to the PSA ECP specific C file Signed-off-by: Ronald Cron --- library/psa_crypto.c | 37 +++++--------------------------- library/psa_crypto_ecp.c | 46 ++++++++++++++++++++++++++++++++++++++++ library/psa_crypto_ecp.h | 23 ++++++++++++++++++++ 3 files changed, 74 insertions(+), 32 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 152651996..0fd24691f 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -34,6 +34,7 @@ #include "psa_crypto_driver_wrappers.h" #include "psa_crypto_ecp.h" #include "psa_crypto_rsa.h" +#include "psa_crypto_ecp.h" #if defined(MBEDTLS_PSA_CRYPTO_SE_C) #include "psa_crypto_se.h" #endif @@ -6053,38 +6054,10 @@ psa_status_t psa_generate_key_internal( #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) if ( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) { - psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( type ); - mbedtls_ecp_group_id grp_id = - mbedtls_ecc_group_of_psa( curve, attributes->core.bits, 0 ); - - const mbedtls_ecp_curve_info *curve_info = - mbedtls_ecp_curve_info_from_grp_id( grp_id ); - mbedtls_ecp_keypair ecp; - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - if( attributes->domain_parameters_size != 0 ) - return( PSA_ERROR_NOT_SUPPORTED ); - if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL ) - return( PSA_ERROR_NOT_SUPPORTED ); - - mbedtls_ecp_keypair_init( &ecp ); - ret = mbedtls_ecp_gen_key( grp_id, &ecp, - mbedtls_psa_get_random, - MBEDTLS_PSA_RANDOM_STATE ); - if( ret != 0 ) - { - mbedtls_ecp_keypair_free( &ecp ); - return( mbedtls_to_psa_error( ret ) ); - } - - status = mbedtls_to_psa_error( - mbedtls_ecp_write_key( &ecp, key_buffer, key_buffer_size ) ); - - mbedtls_ecp_keypair_free( &ecp ); - - if( status == PSA_SUCCESS ) - *key_buffer_length = key_buffer_size; - - return( status ); + return( mbedtls_psa_ecp_generate_key( attributes, + key_buffer, + key_buffer_size, + key_buffer_length ) ); } else #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */ diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index 1a8f15ede..95bb7282c 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -292,6 +292,52 @@ static psa_status_t ecp_export_public_key( #endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || * defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ +#if defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) +psa_status_t mbedtls_psa_ecp_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; + + psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( + attributes->core.type ); + mbedtls_ecp_group_id grp_id = + mbedtls_ecc_group_of_psa( curve, attributes->core.bits, 0 ); + + const mbedtls_ecp_curve_info *curve_info = + mbedtls_ecp_curve_info_from_grp_id( grp_id ); + mbedtls_ecp_keypair ecp; + + if( attributes->domain_parameters_size != 0 ) + return( PSA_ERROR_NOT_SUPPORTED ); + + if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL ) + return( PSA_ERROR_NOT_SUPPORTED ); + + mbedtls_ecp_keypair_init( &ecp ); + ret = mbedtls_ecp_gen_key( grp_id, &ecp, + mbedtls_psa_get_random, + MBEDTLS_PSA_RANDOM_STATE ); + if( ret != 0 ) + { + mbedtls_ecp_keypair_free( &ecp ); + return( mbedtls_to_psa_error( ret ) ); + } + + status = mbedtls_to_psa_error( + mbedtls_ecp_write_key( &ecp, key_buffer, key_buffer_size ) ); + + mbedtls_ecp_keypair_free( &ecp ); + + if( status == PSA_SUCCESS ) + *key_buffer_length = key_buffer_size; + + return( status ); +} +#endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */ + + #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) diff --git a/library/psa_crypto_ecp.h b/library/psa_crypto_ecp.h index 59b61b9e5..b5ccc86b9 100644 --- a/library/psa_crypto_ecp.h +++ b/library/psa_crypto_ecp.h @@ -123,6 +123,29 @@ psa_status_t mbedtls_psa_ecp_export_public_key( const uint8_t *key_buffer, size_t key_buffer_size, uint8_t *data, size_t data_size, size_t *data_length ); +/** + * \brief Generate an ECP key. + * + * \note The signature of the function is that of a PSA driver generate_key + * entry point. + * + * \param[in] attributes The attributes for the ECP key to generate. + * \param[out] key_buffer Buffer where the key data is to be written. + * \param[in] key_buffer_size Size of \p key_buffer in bytes. + * \param[out] key_buffer_length On success, the number of bytes written in + * \p key_buffer. + * + * \retval #PSA_SUCCESS + * The key was successfully generated. + * \retval #PSA_ERROR_NOT_SUPPORTED + * Key length or type not supported. + * \retval #PSA_ERROR_BUFFER_TOO_SMALL + * The size of \p key_buffer is too small. + */ +psa_status_t mbedtls_psa_ecp_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ); + /* * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY. */ From bbe5cbb0c84709766a5cc9da8287a9375e345027 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Fri, 20 Nov 2020 19:42:24 +0100 Subject: [PATCH 14/21] Add ECP transparent test driver generate_key entry point Add ECP transparent test driver generate_key entry point and use it in the transparent test driver. Signed-off-by: Ronald Cron --- library/psa_crypto_ecp.c | 25 +++++++++++-- library/psa_crypto_ecp.h | 5 +++ tests/src/drivers/key_management.c | 58 +++--------------------------- 3 files changed, 32 insertions(+), 56 deletions(-) diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index 95bb7282c..67bb0f11e 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -293,7 +293,7 @@ static psa_status_t ecp_export_public_key( * defined(BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ #if defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) -psa_status_t mbedtls_psa_ecp_generate_key( +static psa_status_t ecp_generate_key( const psa_key_attributes_t *attributes, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) { @@ -337,7 +337,6 @@ psa_status_t mbedtls_psa_ecp_generate_key( } #endif /* defined(BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */ - #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \ defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) @@ -364,6 +363,16 @@ psa_status_t mbedtls_psa_ecp_export_public_key( #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */ +#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) +psa_status_t mbedtls_psa_ecp_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) +{ + return( ecp_generate_key( attributes, key_buffer, key_buffer_size, + key_buffer_length ) ); +} +#endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */ + /* * BEYOND THIS POINT, TEST DRIVER ENTRY POINTS ONLY. */ @@ -396,6 +405,18 @@ psa_status_t mbedtls_transparent_test_driver_ecp_export_public_key( #endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */ +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) \ + && defined(MBEDTLS_GENPRIME) +psa_status_t mbedtls_transparent_test_driver_ecp_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) +{ + return( ecp_generate_key( attributes, key_buffer, key_buffer_size, + key_buffer_length ) ); +} +#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || + defined(MBEDTLS_GENPRIME) */ + #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* MBEDTLS_PSA_CRYPTO_C */ diff --git a/library/psa_crypto_ecp.h b/library/psa_crypto_ecp.h index b5ccc86b9..5c9b63c39 100644 --- a/library/psa_crypto_ecp.h +++ b/library/psa_crypto_ecp.h @@ -151,6 +151,7 @@ psa_status_t mbedtls_psa_ecp_generate_key( */ #if defined(PSA_CRYPTO_DRIVER_TEST) + psa_status_t mbedtls_transparent_test_driver_ecp_import_key( const psa_key_attributes_t *attributes, const uint8_t *data, size_t data_length, @@ -162,6 +163,10 @@ psa_status_t mbedtls_transparent_test_driver_ecp_export_public_key( const uint8_t *key_buffer, size_t key_buffer_size, uint8_t *data, size_t data_size, size_t *data_length ); +psa_status_t mbedtls_transparent_test_driver_ecp_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ); + #endif /* PSA_CRYPTO_DRIVER_TEST */ #endif /* PSA_CRYPTO_ECP_H */ diff --git a/tests/src/drivers/key_management.c b/tests/src/drivers/key_management.c index 46af648f8..10a40c37d 100644 --- a/tests/src/drivers/key_management.c +++ b/tests/src/drivers/key_management.c @@ -61,65 +61,15 @@ psa_status_t test_transparent_generate_key( } /* Copied from psa_crypto.c */ -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \ - defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) if ( PSA_KEY_TYPE_IS_ECC( psa_get_key_type( attributes ) ) && PSA_KEY_TYPE_IS_KEY_PAIR( psa_get_key_type( attributes ) ) ) { - psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY( - psa_get_key_type( attributes ) ); - mbedtls_ecp_group_id grp_id = - mbedtls_ecc_group_of_psa( - curve, - psa_get_key_bits( attributes ), 0 ); - const mbedtls_ecp_curve_info *curve_info = - mbedtls_ecp_curve_info_from_grp_id( grp_id ); - mbedtls_ecp_keypair ecp; - mbedtls_test_rnd_pseudo_info rnd_info; - memset( &rnd_info, 0x5A, sizeof( mbedtls_test_rnd_pseudo_info ) ); - - int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; - if( attributes->domain_parameters_size != 0 ) - return( PSA_ERROR_NOT_SUPPORTED ); - if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL ) - return( PSA_ERROR_NOT_SUPPORTED ); - if( curve_info->bit_size != psa_get_key_bits( attributes ) ) - return( PSA_ERROR_INVALID_ARGUMENT ); - mbedtls_ecp_keypair_init( &ecp ); - ret = mbedtls_ecp_gen_key( grp_id, &ecp, - &mbedtls_test_rnd_pseudo_rand, - &rnd_info ); - if( ret != 0 ) - { - mbedtls_ecp_keypair_free( &ecp ); - return( mbedtls_to_psa_error( ret ) ); - } - - /* Make sure to use export representation */ - size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_bits( attributes ) ); - if( key_size < bytes ) - { - mbedtls_ecp_keypair_free( &ecp ); - return( PSA_ERROR_BUFFER_TOO_SMALL ); - } - psa_status_t status = mbedtls_to_psa_error( - mbedtls_mpi_write_binary( &ecp.d, key, bytes ) ); - - if( status == PSA_SUCCESS ) - { - *key_length = bytes; - } - else - { - memset( key, 0, bytes ); - } - - mbedtls_ecp_keypair_free( &ecp ); - return( status ); + return( mbedtls_transparent_test_driver_ecp_generate_key( + attributes, key, key_size, key_length ) ); } else -#endif /* MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR || - * MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY */ +#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) */ #if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) if ( psa_get_key_type( attributes ) == PSA_KEY_TYPE_RSA_KEY_PAIR ) From f619c68be930e6c97261cd4ae3d0d92ce079511e Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 7 Dec 2020 16:26:09 +0100 Subject: [PATCH 15/21] psa: driver wrappers: Add generate key unit test with no fallback Add a test in test_suite_psa_crypto_driver_wrappers that when accelerators do not support the generation of a key and there is no software fallback, the key generation fails with the PSA_ERROR_NOT_SUPPORTED error code. Signed-off-by: Ronald Cron --- tests/suites/test_suite_psa_crypto_driver_wrappers.data | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data index 1fd449fb8..14f84c023 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data @@ -38,6 +38,10 @@ generate_key through transparent driver: fallback depends_on:MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR generate_key:PSA_ERROR_NOT_SUPPORTED:"":PSA_SUCCESS +generate_key through transparent driver: fallback not available +depends_on:!MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR +generate_key:PSA_ERROR_NOT_SUPPORTED:"":PSA_ERROR_NOT_SUPPORTED + generate_key through transparent driver: error generate_key:PSA_ERROR_GENERIC_ERROR:"":PSA_ERROR_GENERIC_ERROR From d00f5e188ae55bccf9ec7a6fc1695f05a6bb1cea Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 7 Dec 2020 16:36:09 +0100 Subject: [PATCH 16/21] tests: psa: Remove generate key test case restriction Now that the support for key generation in the transparent test driver is at the same level as the support in the Mbed TLS library, remove the restriction on the generate key test case that was introduced by the work on key import and export through the PSA driver interface. Signed-off-by: Ronald Cron --- tests/suites/test_suite_psa_crypto.data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index c37bdceda..c981e98a8 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -2915,7 +2915,7 @@ depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDSA_C generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH:PSA_ALG_ECDSA_ANY:PSA_ERROR_NOT_SUPPORTED:0 PSA generate key: ECC, Curve25519, good -depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_ECP_DP_CURVE25519_ENABLED:!MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR +depends_on:PSA_WANT_ALG_ECDH:PSA_WANT_KEY_TYPE_ECC_KEY_PAIR:MBEDTLS_ECP_DP_CURVE25519_ENABLED generate_key:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_MONTGOMERY):255:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_DERIVE:PSA_ALG_ECDH:PSA_SUCCESS:0 PSA generate key: RSA, default e From 761905e7a32438e1c67ef49fcb9152a82ede4dd8 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 7 Dec 2020 16:41:54 +0100 Subject: [PATCH 17/21] tests: psa config: Extend tests to RSA keys Extend import/export/generate key through a PSA transparent driver without software fallback testing to RSA keys. Signed-off-by: Ronald Cron --- tests/scripts/all.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index e9d15e4ed..1036a7cfd 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -1371,7 +1371,7 @@ component_test_psa_crypto_config_basic() { scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO # Need to define the correct symbol and include the test driver header path in order to build with the test driver - make CC=gcc CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR -I../tests/include -O2" LDFLAGS="$ASAN_CFLAGS" + make CC=gcc CFLAGS="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST -DMBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR -DMBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR -I../tests/include -O2" LDFLAGS="$ASAN_CFLAGS" msg "test: full + MBEDTLS_PSA_CRYPTO_CONFIG" make test From 2365fde15385433890dc551e3f9b40ecc43b0a7e Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 8 Feb 2021 09:52:24 +0100 Subject: [PATCH 18/21] psa: rsa: Rename psa_read_rsa_exponent Rename psa_read_rsa_exponent to psa_rsa_read_exponent for consistency in function naming. Signed-off-by: Ronald Cron --- library/psa_crypto_rsa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/psa_crypto_rsa.c b/library/psa_crypto_rsa.c index 8cdaa7b77..fa64001ed 100644 --- a/library/psa_crypto_rsa.c +++ b/library/psa_crypto_rsa.c @@ -260,7 +260,7 @@ static psa_status_t rsa_export_public_key( * defined(BUILTIN_KEY_TYPE_RSA_PUBLIC_KEY) */ #if defined(BUILTIN_KEY_TYPE_RSA_KEY_PAIR) -static psa_status_t psa_read_rsa_exponent( const uint8_t *domain_parameters, +static psa_status_t psa_rsa_read_exponent( const uint8_t *domain_parameters, size_t domain_parameters_size, int *exponent ) { @@ -295,7 +295,7 @@ static psa_status_t rsa_generate_key( int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int exponent; - status = psa_read_rsa_exponent( attributes->domain_parameters, + status = psa_rsa_read_exponent( attributes->domain_parameters, attributes->domain_parameters_size, &exponent ); if( status != PSA_SUCCESS ) From 9539126549dbe3e100149b66426b960aa0bcfc28 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 8 Feb 2021 09:54:03 +0100 Subject: [PATCH 19/21] psa: ecp: Improve pre-processor condition and its comment Signed-off-by: Ronald Cron --- library/psa_crypto_ecp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/psa_crypto_ecp.c b/library/psa_crypto_ecp.c index 67bb0f11e..23ec6acef 100644 --- a/library/psa_crypto_ecp.c +++ b/library/psa_crypto_ecp.c @@ -405,8 +405,8 @@ psa_status_t mbedtls_transparent_test_driver_ecp_export_public_key( #endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) */ -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) \ - && defined(MBEDTLS_GENPRIME) +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) && \ + defined(MBEDTLS_GENPRIME) psa_status_t mbedtls_transparent_test_driver_ecp_generate_key( const psa_key_attributes_t *attributes, uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) @@ -414,7 +414,7 @@ psa_status_t mbedtls_transparent_test_driver_ecp_generate_key( return( ecp_generate_key( attributes, key_buffer, key_buffer_size, key_buffer_length ) ); } -#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || +#endif /* defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) && defined(MBEDTLS_GENPRIME) */ #endif /* PSA_CRYPTO_DRIVER_TEST */ From 3772afef0f4e3c83d913b52b9a21be530235dc97 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Mon, 8 Feb 2021 16:10:05 +0100 Subject: [PATCH 20/21] psa: key generation: Use PSA_EXPORT_KEY_OUTPUT_SIZE Use PSA_EXPORT_KEY_OUTPUT_SIZE macro to compute the size of the buffer to contain the generated key instead of computing it alongside the key type and size validation. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 0fd24691f..782e26140 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5957,24 +5957,21 @@ psa_status_t mbedtls_psa_inject_entropy( const uint8_t *seed, } #endif /* MBEDTLS_PSA_INJECT_ENTROPY */ -/** Get the key buffer size for the key material in export format +/** Validate the key type and size for key generation * - * \param[in] type The key type - * \param[in] bits The number of bits of the key - * \param[out] key_buffer_size Minimum buffer size to contain the key material - * in export format + * \param type The key type + * \param bits The number of bits of the key * * \retval #PSA_SUCCESS - * The minimum size for a buffer to contain the key material in export - * format has been returned successfully. + * The key type and size are valid. * \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. */ -static psa_status_t psa_get_key_buffer_size( - psa_key_type_t type, size_t bits, size_t *key_buffer_size ) +static psa_status_t psa_validate_key_type_and_size_for_key_generation( + psa_key_type_t type, size_t bits ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -5983,7 +5980,6 @@ static psa_status_t psa_get_key_buffer_size( status = validate_unstructured_key_bit_size( type, bits ); if( status != PSA_SUCCESS ) return( status ); - *key_buffer_size = PSA_BITS_TO_BYTES( bits ); } else #if defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) @@ -5996,8 +5992,6 @@ static psa_status_t psa_get_key_buffer_size( * in psa_import_rsa_key(). */ if( bits % 8 != 0 ) return( PSA_ERROR_NOT_SUPPORTED ); - - *key_buffer_size = PSA_KEY_EXPORT_RSA_KEY_PAIR_MAX_SIZE( bits ); } else #endif /* defined(PSA_WANT_KEY_TYPE_RSA_KEY_PAIR) */ @@ -6005,7 +5999,6 @@ static psa_status_t psa_get_key_buffer_size( #if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) if( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) { - *key_buffer_size = PSA_BITS_TO_BYTES( bits ); } else #endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) */ @@ -6098,17 +6091,22 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, if ( PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ) == PSA_KEY_LOCATION_LOCAL_STORAGE ) { - status = psa_get_key_buffer_size( attributes->core.type, - attributes->core.bits, - &key_buffer_size ); + status = psa_validate_key_type_and_size_for_key_generation( + attributes->core.type, attributes->core.bits ); + if( status != PSA_SUCCESS ) + goto exit; + + key_buffer_size = PSA_EXPORT_KEY_OUTPUT_SIZE( + attributes->core.type, + attributes->core.bits ); } else { status = psa_driver_wrapper_get_key_buffer_size( attributes, &key_buffer_size ); + if( status != PSA_SUCCESS ) + goto exit; } - if( status != PSA_SUCCESS ) - goto exit; status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); if( status != PSA_SUCCESS ) From d81ab56c84ef2d4bda931158fc3d618718f32855 Mon Sep 17 00:00:00 2001 From: Ronald Cron Date: Tue, 16 Feb 2021 09:01:16 +0100 Subject: [PATCH 21/21] psa: Avoid empty block Avoid empty block to ease maintenance. Signed-off-by: Ronald Cron --- library/psa_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 782e26140..f304950e0 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -5999,6 +5999,8 @@ static psa_status_t psa_validate_key_type_and_size_for_key_generation( #if defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) if( PSA_KEY_TYPE_IS_ECC( type ) && PSA_KEY_TYPE_IS_KEY_PAIR( type ) ) { + /* To avoid empty block, return successfully here. */ + return( PSA_SUCCESS ); } else #endif /* defined(PSA_WANT_KEY_TYPE_ECC_KEY_PAIR) */