diff --git a/ChangeLog.d/psa-builtin-keys-implementation.txt b/ChangeLog.d/psa-builtin-keys-implementation.txt new file mode 100644 index 000000000..66ba77d07 --- /dev/null +++ b/ChangeLog.d/psa-builtin-keys-implementation.txt @@ -0,0 +1,4 @@ +Features + * Added support for built-in driver keys through the PSA opaque crypto + driver interface. Refer to the documentation of + MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS for more information. diff --git a/docs/proposed/psa-driver-interface.md b/docs/proposed/psa-driver-interface.md index 47d7271e6..2bdbff4e1 100644 --- a/docs/proposed/psa-driver-interface.md +++ b/docs/proposed/psa-driver-interface.md @@ -810,7 +810,7 @@ psa_status_t acme_get_builtin_key(psa_drv_slot_number_t slot_number, If this function returns `PSA_SUCCESS` or `PSA_ERROR_BUFFER_TOO_SMALL`, it must fill `attributes` with the attributes of the key (except for the key identifier). On success, this function must also fill `key_buffer` with the key context. -On entry, `psa_get_key_lifetime(attributes)` is the location at which the driver was declared and the persistence level `#PSA_KEY_LIFETIME_PERSISTENT`. The driver entry point may change the lifetime to one with the same location but a different persistence level. The standard attributes other than the key identifier and lifetime have the value conveyed by `PSA_KEY_ATTRIBUTES_INIT`. +On entry, `psa_get_key_lifetime(attributes)` is the location at which the driver was declared and a persistence level with which the platform is attempting to register the key. The driver entry point may choose to change the lifetime (`psa_set_key_lifetime(attributes, lifetime)`) of the reported key attributes to one with the same location but a different persistence level, in case the driver has more specific knowledge about the actual persistence level of the key which is being retrieved. For example, if a driver knows it cannot delete a key, it may override the persistence level in the lifetime to `PSA_KEY_PERSISTENCE_READ_ONLY`. The standard attributes other than the key identifier and lifetime have the value conveyed by `PSA_KEY_ATTRIBUTES_INIT`. The output parameter `key_buffer` points to a writable buffer of `key_buffer_size` bytes. If the driver has a [`"builtin_key_size"` property](#key-format-for-opaque-drivers) property, `key_buffer_size` has this value, otherwise `key_buffer_size` has the value determined from the key type and size. diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h index d370dbff5..62d89c977 100644 --- a/include/mbedtls/config.h +++ b/include/mbedtls/config.h @@ -1338,6 +1338,22 @@ */ #define MBEDTLS_PKCS1_V21 +/** \def MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS + * + * Enable support for platform built-in keys. If you enable this feature, + * you must implement the function mbedtls_psa_platform_get_builtin_key(). + * See the documentation of that function for more information. + * + * Built-in keys are typically derived from a hardware unique key or + * stored in a secure element. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + * + * \warning This interface is experimental and may change or be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS + /** \def MBEDTLS_PSA_CRYPTO_CLIENT * * Enable support for PSA crypto client. diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index e01d827e8..1310bb576 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -713,6 +713,104 @@ psa_status_t mbedtls_psa_external_get_random( /**@}*/ +/** \defgroup psa_builtin_keys Built-in keys + * @{ + */ + +/** The minimum value for a key identifier that is built into the + * implementation. + * + * The range of key identifiers from #MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + * to #MBEDTLS_PSA_KEY_ID_BUILTIN_MAX within the range from + * #PSA_KEY_ID_VENDOR_MIN and #PSA_KEY_ID_VENDOR_MAX and must not intersect + * with any other set of implementation-chosen key identifiers. + * + * This value is part of the library's ABI since changing it would invalidate + * the values of built-in key identifiers in applications. + */ +#define MBEDTLS_PSA_KEY_ID_BUILTIN_MIN ((psa_key_id_t)0x7fff0000) + +/** The maximum value for a key identifier that is built into the + * implementation. + * + * See #MBEDTLS_PSA_KEY_ID_BUILTIN_MIN for more information. + */ +#define MBEDTLS_PSA_KEY_ID_BUILTIN_MAX ((psa_key_id_t)0x7fffefff) + +/** A slot number identifying a key in a driver. + * + * Values of this type are used to identify built-in keys. + */ +typedef uint64_t psa_drv_slot_number_t; + +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) +/** Test whether a key identifier belongs to the builtin key range. + * + * \param key_id Key identifier to test. + * + * \retval 1 + * The key identifier is a builtin key identifier. + * \retval 0 + * The key identifier is not a builtin key identifier. + */ +static inline int psa_key_id_is_builtin( psa_key_id_t key_id ) +{ + return( ( key_id >= MBEDTLS_PSA_KEY_ID_BUILTIN_MIN ) && + ( key_id <= MBEDTLS_PSA_KEY_ID_BUILTIN_MAX ) ); +} + +/** Platform function to obtain the location and slot number of a built-in key. + * + * An application-specific implementation of this function must be provided if + * #MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS is enabled. This would typically be provided + * as part of a platform's system image. + * + * #MBEDTLS_SVC_KEY_ID_GET_KEY_ID(\p key_id) needs to be in the range from + * #MBEDTLS_PSA_KEY_ID_BUILTIN_MIN to #MBEDTLS_PSA_KEY_ID_BUILTIN_MAX. + * + * In a multi-application configuration + * (\c MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER is defined), + * this function should check that #MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(\p key_id) + * is allowed to use the given key. + * + * \param key_id The key ID for which to retrieve the + * location and slot attributes. + * \param[out] lifetime On success, the lifetime associated with the key + * corresponding to \p key_id. Lifetime is a + * combination of which driver contains the key, + * and with what persistence level the key is + * intended to be used. If the platform + * implementation does not contain specific + * information about the intended key persistence + * level, the persistence level may be reported as + * #PSA_KEY_PERSISTENCE_DEFAULT. + * \param[out] slot_number On success, the slot number known to the driver + * registered at the lifetime location reported + * through \p lifetime which corresponds to the + * requested built-in key. + * + * \retval #PSA_SUCCESS + * The requested key identifier designates a built-in key. + * In a multi-application configuration, the requested owner + * is allowed to access it. + * \retval #PSA_ERROR_DOES_NOT_EXIST + * The requested key identifier is not a built-in key which is known + * to this function. If a key exists in the key storage with this + * identifier, the data from the storage will be used. + * \return (any other error) + * Any other error is propagated to the function that requested the key. + * Common errors include: + * - #PSA_ERROR_NOT_PERMITTED: the key exists but the requested owner + * is not allowed to access it. + */ +psa_status_t mbedtls_psa_platform_get_builtin_key( + mbedtls_svc_key_id_t key_id, + psa_key_lifetime_t *lifetime, + psa_drv_slot_number_t *slot_number ); +#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ + +/** @} */ + #ifdef __cplusplus } #endif diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 32568b322..f58df4aef 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -604,20 +604,8 @@ MBEDTLS_STATIC_TESTABLE psa_status_t psa_mac_key_can_do( return( PSA_ERROR_INVALID_ARGUMENT ); } -/** Try to allocate a buffer to an empty key slot. - * - * \param[in,out] slot Key slot to attach buffer to. - * \param[in] buffer_length Requested size of the buffer. - * - * \retval #PSA_SUCCESS - * The buffer has been successfully allocated. - * \retval #PSA_ERROR_INSUFFICIENT_MEMORY - * Not enough memory was available for allocation. - * \retval #PSA_ERROR_ALREADY_EXISTS - * Trying to allocate a buffer to a non-empty key slot. - */ -static psa_status_t psa_allocate_buffer_to_slot( psa_key_slot_t *slot, - size_t buffer_length ) +psa_status_t psa_allocate_buffer_to_slot( psa_key_slot_t *slot, + size_t buffer_length ) { if( slot->key.data != NULL ) return( PSA_ERROR_ALREADY_EXISTS ); @@ -1075,8 +1063,7 @@ static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy( psa_get_and_lock_key_slot_with_policy( key, p_slot, usage, alg ) #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ -/** Wipe key data from a slot. Preserve metadata such as the policy. */ -static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot ) +psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot ) { /* Data pointer will always be either a valid pointer or NULL in an * initialized slot, so we can just free it. */ diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index f949c7188..90f9d1863 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -180,6 +180,24 @@ static inline psa_key_slot_number_t psa_key_slot_get_slot_number( */ psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot ); +/** Try to allocate a buffer to an empty key slot. + * + * \param[in,out] slot Key slot to attach buffer to. + * \param[in] buffer_length Requested size of the buffer. + * + * \retval #PSA_SUCCESS + * The buffer has been successfully allocated. + * \retval #PSA_ERROR_INSUFFICIENT_MEMORY + * Not enough memory was available for allocation. + * \retval #PSA_ERROR_ALREADY_EXISTS + * Trying to allocate a buffer to a non-empty key slot. + */ +psa_status_t psa_allocate_buffer_to_slot( psa_key_slot_t *slot, + size_t buffer_length ); + +/** Wipe key data from a slot. Preserves metadata such as the policy. */ +psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot ); + /** Copy key data (in export format) into an empty key slot. * * This function assumes that the slot does not contain diff --git a/library/psa_crypto_driver_wrappers.c b/library/psa_crypto_driver_wrappers.c index 536505ef4..11160d82d 100644 --- a/library/psa_crypto_driver_wrappers.c +++ b/library/psa_crypto_driver_wrappers.c @@ -129,7 +129,7 @@ psa_status_t psa_driver_wrapper_sign_hash( /* 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: + case PSA_CRYPTO_TEST_DRIVER_LOCATION: return( test_opaque_signature_sign_hash( attributes, key_buffer, key_buffer_size, @@ -211,7 +211,7 @@ psa_status_t psa_driver_wrapper_verify_hash( /* 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: + case PSA_CRYPTO_TEST_DRIVER_LOCATION: return( test_opaque_signature_verify_hash( attributes, key_buffer, key_buffer_size, @@ -229,8 +229,8 @@ psa_status_t psa_driver_wrapper_verify_hash( } } -/** Get the key buffer size for the key material of a generated key in the - * case of an opaque driver without storage. +/** Get the key buffer size required to store the key material of a key + * associated with an opaque driver without storage. * * \param[in] attributes The key attributes. * \param[out] key_buffer_size Minimum buffer size to contain the key material @@ -256,7 +256,17 @@ psa_status_t psa_driver_wrapper_get_key_buffer_size( switch( location ) { #if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + case PSA_CRYPTO_TEST_DRIVER_LOCATION: +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) + /* Emulate property 'builtin_key_size' */ + if( psa_key_id_is_builtin( + MBEDTLS_SVC_KEY_ID_GET_KEY_ID( + psa_get_key_id( attributes ) ) ) ) + { + *key_buffer_size = sizeof( psa_drv_slot_number_t ); + return( PSA_SUCCESS ); + } +#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ #ifdef TEST_DRIVER_KEY_CONTEXT_SIZE_FUNCTION *key_buffer_size = test_size_function( key_type, key_bits ); return( PSA_SUCCESS ); @@ -353,7 +363,7 @@ psa_status_t psa_driver_wrapper_generate_key( /* 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: + case PSA_CRYPTO_TEST_DRIVER_LOCATION: status = test_opaque_generate_key( attributes, key_buffer, key_buffer_size, key_buffer_length ); break; @@ -485,7 +495,7 @@ psa_status_t psa_driver_wrapper_export_key( /* 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: + case PSA_CRYPTO_TEST_DRIVER_LOCATION: return( test_opaque_export_key( attributes, key_buffer, key_buffer_size, @@ -559,7 +569,7 @@ psa_status_t psa_driver_wrapper_export_public_key( /* 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: + case PSA_CRYPTO_TEST_DRIVER_LOCATION: return( test_opaque_export_public_key( attributes, key_buffer, key_buffer_size, @@ -574,6 +584,30 @@ psa_status_t psa_driver_wrapper_export_public_key( } } +psa_status_t psa_driver_wrapper_get_builtin_key( + psa_drv_slot_number_t slot_number, + psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) +{ + psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION( attributes->core.lifetime ); + switch( location ) + { +#if defined(PSA_CRYPTO_DRIVER_TEST) + case PSA_CRYPTO_TEST_DRIVER_LOCATION: + return( test_opaque_get_builtin_key( + slot_number, + attributes, + key_buffer, key_buffer_size, key_buffer_length ) ); +#endif /* PSA_CRYPTO_DRIVER_TEST */ + default: + (void) slot_number; + (void) key_buffer; + (void) key_buffer_size; + (void) key_buffer_length; + return( PSA_ERROR_DOES_NOT_EXIST ); + } +} + /* * Cipher functions */ @@ -616,7 +650,7 @@ psa_status_t psa_driver_wrapper_cipher_encrypt( return( PSA_ERROR_NOT_SUPPORTED ); /* Add cases for opaque driver here */ #if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + case PSA_CRYPTO_TEST_DRIVER_LOCATION: return( test_opaque_cipher_encrypt( &attributes, slot->key.data, slot->key.bytes, @@ -683,7 +717,7 @@ psa_status_t psa_driver_wrapper_cipher_decrypt( return( PSA_ERROR_NOT_SUPPORTED ); /* Add cases for opaque driver here */ #if defined(PSA_CRYPTO_DRIVER_TEST) - case PSA_CRYPTO_TEST_DRIVER_LIFETIME: + case PSA_CRYPTO_TEST_DRIVER_LOCATION: return( test_opaque_cipher_decrypt( &attributes, slot->key.data, slot->key.bytes, @@ -760,7 +794,7 @@ psa_status_t psa_driver_wrapper_cipher_encrypt_setup( /* 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: + case PSA_CRYPTO_TEST_DRIVER_LOCATION: status = test_opaque_cipher_encrypt_setup( &operation->ctx.opaque_test_driver_ctx, attributes, @@ -831,7 +865,7 @@ psa_status_t psa_driver_wrapper_cipher_decrypt_setup( /* 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: + case PSA_CRYPTO_TEST_DRIVER_LOCATION: status = test_opaque_cipher_decrypt_setup( &operation->ctx.opaque_test_driver_ctx, attributes, diff --git a/library/psa_crypto_driver_wrappers.h b/library/psa_crypto_driver_wrappers.h index e49941138..e82d0931b 100644 --- a/library/psa_crypto_driver_wrappers.h +++ b/library/psa_crypto_driver_wrappers.h @@ -68,6 +68,11 @@ 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 ); +psa_status_t psa_driver_wrapper_get_builtin_key( + psa_drv_slot_number_t slot_number, + psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ); + /* * Cipher functions */ diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index cf07a3693..0b1a3c166 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -26,6 +26,7 @@ #include "psa/crypto.h" #include "psa_crypto_core.h" +#include "psa_crypto_driver_wrappers.h" #include "psa_crypto_slot_management.h" #include "psa_crypto_storage.h" #if defined(MBEDTLS_PSA_CRYPTO_SE_C) @@ -274,6 +275,77 @@ exit: } #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) + +static psa_status_t psa_load_builtin_key_into_slot( psa_key_slot_t *slot ) +{ + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_VOLATILE; + psa_drv_slot_number_t slot_number = 0; + size_t key_buffer_size = 0; + size_t key_buffer_length = 0; + + if( ! psa_key_id_is_builtin( + MBEDTLS_SVC_KEY_ID_GET_KEY_ID( slot->attr.id ) ) ) + { + return( PSA_ERROR_DOES_NOT_EXIST ); + } + + /* Check the platform function to see whether this key actually exists */ + status = mbedtls_psa_platform_get_builtin_key( + slot->attr.id, &lifetime, &slot_number ); + if( status != PSA_SUCCESS ) + return( status ); + + /* Set required key attributes to ensure get_builtin_key can retrieve the + * full attributes. */ + psa_set_key_id( &attributes, slot->attr.id ); + psa_set_key_lifetime( &attributes, lifetime ); + + /* Get the full key attributes from the driver in order to be able to + * calculate the required buffer size. */ + status = psa_driver_wrapper_get_builtin_key( + slot_number, &attributes, + NULL, 0, NULL ); + if( status != PSA_ERROR_BUFFER_TOO_SMALL ) + { + /* Builtin keys cannot be defined by the attributes alone */ + if( status == PSA_SUCCESS ) + status = PSA_ERROR_CORRUPTION_DETECTED; + return( status ); + } + + /* If the key should exist according to the platform, then ask the driver + * what its expected size is. */ + status = psa_driver_wrapper_get_key_buffer_size( &attributes, + &key_buffer_size ); + if( status != PSA_SUCCESS ) + return( status ); + + /* Allocate a buffer of the required size and load the builtin key directly + * into the (now properly sized) slot buffer. */ + status = psa_allocate_buffer_to_slot( slot, key_buffer_size ); + if( status != PSA_SUCCESS ) + return( status ); + + status = psa_driver_wrapper_get_builtin_key( + slot_number, &attributes, + slot->key.data, slot->key.bytes, &key_buffer_length ); + if( status != PSA_SUCCESS ) + goto exit; + + /* Copy actual key length and core attributes into the slot on success */ + slot->key.bytes = key_buffer_length; + slot->attr = attributes.core; + +exit: + if( status != PSA_SUCCESS ) + psa_remove_key_data_from_memory( slot ); + return( status ); +} +#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ + psa_status_t psa_get_and_lock_key_slot( mbedtls_svc_key_id_t key, psa_key_slot_t **p_slot ) { @@ -291,17 +363,29 @@ psa_status_t psa_get_and_lock_key_slot( mbedtls_svc_key_id_t key, if( status != PSA_ERROR_DOES_NOT_EXIST ) return( status ); -#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) + /* Loading keys from storage requires support for such a mechanism */ +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) || \ + defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) psa_key_id_t volatile_key_id; status = psa_get_empty_key_slot( &volatile_key_id, p_slot ); if( status != PSA_SUCCESS ) return( status ); - (*p_slot)->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT; (*p_slot)->attr.id = key; + (*p_slot)->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT; + + status = PSA_ERROR_DOES_NOT_EXIST; +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) + /* Load keys in the 'builtin' range through their own interface */ + status = psa_load_builtin_key_into_slot( *p_slot ); +#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ + +#if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) + if( status == PSA_ERROR_DOES_NOT_EXIST ) + status = psa_load_persistent_key_into_slot( *p_slot ); +#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ - status = psa_load_persistent_key_into_slot( *p_slot ); if( status != PSA_SUCCESS ) { psa_wipe_key_slot( *p_slot ); @@ -309,9 +393,9 @@ psa_status_t psa_get_and_lock_key_slot( mbedtls_svc_key_id_t key, status = PSA_ERROR_INVALID_HANDLE; } return( status ); -#else +#else /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ return( PSA_ERROR_INVALID_HANDLE ); -#endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ +#endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C || MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ } psa_status_t psa_unlock_key_slot( psa_key_slot_t *slot ) diff --git a/library/version_features.c b/library/version_features.c index 93329879a..f665a2375 100644 --- a/library/version_features.c +++ b/library/version_features.c @@ -438,6 +438,9 @@ static const char * const features[] = { #if defined(MBEDTLS_PKCS1_V21) "MBEDTLS_PKCS1_V21", #endif /* MBEDTLS_PKCS1_V21 */ +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) + "MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS", +#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ #if defined(MBEDTLS_PSA_CRYPTO_CLIENT) "MBEDTLS_PSA_CRYPTO_CLIENT", #endif /* MBEDTLS_PSA_CRYPTO_CLIENT */ diff --git a/programs/test/query_config.c b/programs/test/query_config.c index b9105f812..9760f626c 100644 --- a/programs/test/query_config.c +++ b/programs/test/query_config.c @@ -1226,6 +1226,14 @@ int query_config( const char *config ) } #endif /* MBEDTLS_PKCS1_V21 */ +#if defined(MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS) + if( strcmp( "MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS", config ) == 0 ) + { + MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS ); + return( 0 ); + } +#endif /* MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ + #if defined(MBEDTLS_PSA_CRYPTO_CLIENT) if( strcmp( "MBEDTLS_PSA_CRYPTO_CLIENT", config ) == 0 ) { diff --git a/scripts/generate_visualc_files.pl b/scripts/generate_visualc_files.pl index df5d66e81..d11041c31 100755 --- a/scripts/generate_visualc_files.pl +++ b/scripts/generate_visualc_files.pl @@ -40,6 +40,7 @@ my $source_dir = 'library'; my $test_source_dir = 'tests/src'; my $test_header_dir = 'tests/include/test'; my $test_drivers_header_dir = 'tests/include/test/drivers'; +my $test_drivers_source_dir = 'tests/src/drivers'; my @thirdparty_header_dirs = qw( 3rdparty/everest/include/everest @@ -116,6 +117,7 @@ sub check_dirs { && -d $psa_header_dir && -d $source_dir && -d $test_source_dir + && -d $test_drivers_source_dir && -d $test_header_dir && -d $test_drivers_header_dir && -d $programs_dir; @@ -275,6 +277,7 @@ sub main { my @source_dirs = ( $source_dir, $test_source_dir, + $test_drivers_source_dir, @thirdparty_source_dirs, ); my @sources = (map { <$_/*.c> } @source_dirs); diff --git a/tests/include/test/drivers/key_management.h b/tests/include/test/drivers/key_management.h index b30baa205..100fc18d3 100644 --- a/tests/include/test/drivers/key_management.h +++ b/tests/include/test/drivers/key_management.h @@ -29,6 +29,9 @@ #if defined(PSA_CRYPTO_DRIVER_TEST) #include +#define PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT 0 +#define PSA_CRYPTO_TEST_DRIVER_BUILTIN_ECDSA_KEY_SLOT 1 + typedef struct { /* If non-null, on success, copy this to the output. */ void *forced_output; @@ -82,5 +85,10 @@ psa_status_t test_transparent_import_key( size_t *key_buffer_length, size_t *bits); +psa_status_t test_opaque_get_builtin_key( + psa_drv_slot_number_t slot_number, + 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_TEST_DRIVERS_KEY_MANAGEMENT_H */ diff --git a/tests/include/test/drivers/test_driver.h b/tests/include/test/drivers/test_driver.h index 2fdce5c79..84d0caa5e 100644 --- a/tests/include/test/drivers/test_driver.h +++ b/tests/include/test/drivers/test_driver.h @@ -20,7 +20,7 @@ #ifndef PSA_CRYPTO_TEST_DRIVER_H #define PSA_CRYPTO_TEST_DRIVER_H -#define PSA_CRYPTO_TEST_DRIVER_LIFETIME 0x7fffff +#define PSA_CRYPTO_TEST_DRIVER_LOCATION 0x7fffff #include "test/drivers/aead.h" #include "test/drivers/signature.h" diff --git a/tests/scripts/all.sh b/tests/scripts/all.sh index f768e1e5e..a85c7ce00 100755 --- a/tests/scripts/all.sh +++ b/tests/scripts/all.sh @@ -2267,6 +2267,7 @@ component_test_psa_crypto_drivers () { msg "build: MBEDTLS_PSA_CRYPTO_DRIVERS w/ driver hooks" scripts/config.py full scripts/config.py set MBEDTLS_PSA_CRYPTO_DRIVERS + scripts/config.py set MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS # Need to define the correct symbol and include the test driver header path in order to build with the test driver loc_cflags="$ASAN_CFLAGS -DPSA_CRYPTO_DRIVER_TEST" loc_cflags="${loc_cflags} -DMBEDTLS_PSA_ACCEL_KEY_TYPE_AES" diff --git a/tests/src/drivers/key_management.c b/tests/src/drivers/key_management.c deleted file mode 100644 index 10a40c37d..000000000 --- a/tests/src/drivers/key_management.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Test driver for generating and verifying keys. - * Currently only supports generating and verifying ECC keys. - */ -/* 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.h" -#include "psa_crypto_core.h" -#include "psa_crypto_ecp.h" -#include "psa_crypto_rsa.h" -#include "mbedtls/ecp.h" -#include "mbedtls/error.h" - -#include "test/drivers/key_management.h" - -#include "test/random.h" - -#include - -test_driver_key_management_hooks_t test_driver_key_management_hooks = - TEST_DRIVER_KEY_MANAGEMENT_INIT; - -psa_status_t test_transparent_generate_key( - const psa_key_attributes_t *attributes, - uint8_t *key, size_t key_size, size_t *key_length ) -{ - ++test_driver_key_management_hooks.hits; - - if( test_driver_key_management_hooks.forced_status != PSA_SUCCESS ) - return( test_driver_key_management_hooks.forced_status ); - - if( test_driver_key_management_hooks.forced_output != NULL ) - { - if( test_driver_key_management_hooks.forced_output_length > key_size ) - return( PSA_ERROR_BUFFER_TOO_SMALL ); - memcpy( key, test_driver_key_management_hooks.forced_output, - test_driver_key_management_hooks.forced_output_length ); - *key_length = test_driver_key_management_hooks.forced_output_length; - return( PSA_SUCCESS ); - } - - /* Copied from psa_crypto.c */ -#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 ) ) ) - { - return( mbedtls_transparent_test_driver_ecp_generate_key( - attributes, key, key_size, key_length ) ); - } - else -#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 ) - 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( - const psa_key_attributes_t *attributes, - uint8_t *key, size_t key_size, size_t *key_length ) -{ - (void) attributes; - (void) key; - (void) key_size; - (void) key_length; - return( PSA_ERROR_NOT_SUPPORTED ); -} - -psa_status_t test_transparent_import_key( - const psa_key_attributes_t *attributes, - const uint8_t *data, - size_t data_length, - uint8_t *key_buffer, - size_t key_buffer_size, - size_t *key_buffer_length, - size_t *bits) -{ - ++test_driver_key_management_hooks.hits; - - if( test_driver_key_management_hooks.forced_status != PSA_SUCCESS ) - return( test_driver_key_management_hooks.forced_status ); - - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_type_t type = psa_get_key_type( attributes ); - -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \ - defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) - if( PSA_KEY_TYPE_IS_ECC( type ) ) - { - status = mbedtls_transparent_test_driver_ecp_import_key( - attributes, - data, data_length, - key_buffer, key_buffer_size, - key_buffer_length, bits ); - } - else -#endif -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) || \ - defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) - if( PSA_KEY_TYPE_IS_RSA( type ) ) - { - status = mbedtls_transparent_test_driver_rsa_import_key( - attributes, - data, data_length, - key_buffer, key_buffer_size, - key_buffer_length, bits ); - } - else -#endif - { - status = PSA_ERROR_NOT_SUPPORTED; - (void)data; - (void)data_length; - (void)key_buffer; - (void)key_buffer_size; - (void)key_buffer_length; - (void)bits; - (void)type; - } - - return( status ); -} - -psa_status_t test_opaque_export_key( - const psa_key_attributes_t *attributes, - const uint8_t *key, size_t key_length, - uint8_t *data, size_t data_size, size_t *data_length ) -{ - (void) attributes; - (void) key; - (void) key_length; - (void) data; - (void) data_size; - (void) data_length; - return( PSA_ERROR_NOT_SUPPORTED ); -} - -psa_status_t test_transparent_export_public_key( - const psa_key_attributes_t *attributes, - const uint8_t *key_buffer, size_t key_buffer_size, - uint8_t *data, size_t data_size, size_t *data_length ) -{ - ++test_driver_key_management_hooks.hits; - - if( test_driver_key_management_hooks.forced_status != PSA_SUCCESS ) - return( test_driver_key_management_hooks.forced_status ); - - if( test_driver_key_management_hooks.forced_output != NULL ) - { - if( test_driver_key_management_hooks.forced_output_length > data_size ) - return( PSA_ERROR_BUFFER_TOO_SMALL ); - memcpy( data, test_driver_key_management_hooks.forced_output, - test_driver_key_management_hooks.forced_output_length ); - *data_length = test_driver_key_management_hooks.forced_output_length; - return( PSA_SUCCESS ); - } - - psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_key_type_t key_type = psa_get_key_type( attributes ); - -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \ - defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) - if( PSA_KEY_TYPE_IS_ECC( key_type ) ) - { - status = mbedtls_transparent_test_driver_ecp_export_public_key( - attributes, - key_buffer, key_buffer_size, - data, data_size, data_length ); - } - else -#endif -#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) || \ - defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) - if( PSA_KEY_TYPE_IS_RSA( key_type ) ) - { - status = mbedtls_transparent_test_driver_rsa_export_public_key( - attributes, - key_buffer, key_buffer_size, - data, data_size, data_length ); - } - else -#endif - { - status = PSA_ERROR_NOT_SUPPORTED; - (void)key_buffer; - (void)key_buffer_size; - (void)key_type; - } - - return( status ); -} - -psa_status_t test_opaque_export_public_key( - const psa_key_attributes_t *attributes, - const uint8_t *key, size_t key_length, - uint8_t *data, size_t data_size, size_t *data_length ) -{ - (void) attributes; - (void) key; - (void) key_length; - (void) data; - (void) data_size; - (void) data_length; - return( PSA_ERROR_NOT_SUPPORTED ); -} - -#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */ diff --git a/tests/src/drivers/platform_builtin_keys.c b/tests/src/drivers/platform_builtin_keys.c new file mode 100644 index 000000000..759fa7830 --- /dev/null +++ b/tests/src/drivers/platform_builtin_keys.c @@ -0,0 +1,91 @@ +/** \file platform_builtin_keys.c + * + * \brief Test driver implementation of the builtin key support + */ + +/* + * 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 +#include + +#if defined(PSA_CRYPTO_DRIVER_TEST) +#include +#endif + +typedef struct +{ + psa_key_id_t builtin_key_id; + psa_key_lifetime_t lifetime; + psa_drv_slot_number_t slot_number; +} mbedtls_psa_builtin_key_description_t; + +static const mbedtls_psa_builtin_key_description_t builtin_keys[] = { +#if defined(PSA_CRYPTO_DRIVER_TEST) + /* For testing, assign the AES builtin key slot to the boundary values. + * ECDSA can be exercised on key ID MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 1. */ + { MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1, + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_PERSISTENCE_READ_ONLY, PSA_CRYPTO_TEST_DRIVER_LOCATION ), + PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT }, + { MBEDTLS_PSA_KEY_ID_BUILTIN_MIN, + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_PERSISTENCE_READ_ONLY, PSA_CRYPTO_TEST_DRIVER_LOCATION ), + PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT }, + { MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 1, + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_PERSISTENCE_READ_ONLY, PSA_CRYPTO_TEST_DRIVER_LOCATION ), + PSA_CRYPTO_TEST_DRIVER_BUILTIN_ECDSA_KEY_SLOT}, + { MBEDTLS_PSA_KEY_ID_BUILTIN_MAX - 1, + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_PERSISTENCE_READ_ONLY, PSA_CRYPTO_TEST_DRIVER_LOCATION ), + PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT}, + { MBEDTLS_PSA_KEY_ID_BUILTIN_MAX, + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_PERSISTENCE_READ_ONLY, PSA_CRYPTO_TEST_DRIVER_LOCATION ), + PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT}, + { MBEDTLS_PSA_KEY_ID_BUILTIN_MAX + 1, + PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION( + PSA_KEY_PERSISTENCE_READ_ONLY, PSA_CRYPTO_TEST_DRIVER_LOCATION ), + PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT}, +#else + {0, 0, 0} +#endif +}; + +psa_status_t mbedtls_psa_platform_get_builtin_key( + mbedtls_svc_key_id_t key_id, + psa_key_lifetime_t *lifetime, + psa_drv_slot_number_t *slot_number ) +{ + psa_key_id_t app_key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID( key_id ); + const mbedtls_psa_builtin_key_description_t *builtin_key; + + for( size_t i = 0; + i < ( sizeof( builtin_keys ) / sizeof( builtin_keys[0] ) ); i++ ) + { + builtin_key = &builtin_keys[i]; + if( builtin_key->builtin_key_id == app_key_id ) + { + *lifetime = builtin_key->lifetime; + *slot_number = builtin_key->slot_number; + return( PSA_SUCCESS ); + } + } + + return( PSA_ERROR_DOES_NOT_EXIST ); +} diff --git a/tests/src/drivers/aead.c b/tests/src/drivers/test_driver_aead.c similarity index 100% rename from tests/src/drivers/aead.c rename to tests/src/drivers/test_driver_aead.c diff --git a/tests/src/drivers/cipher.c b/tests/src/drivers/test_driver_cipher.c similarity index 100% rename from tests/src/drivers/cipher.c rename to tests/src/drivers/test_driver_cipher.c diff --git a/tests/src/drivers/test_driver_key_management.c b/tests/src/drivers/test_driver_key_management.c new file mode 100644 index 000000000..a0626fbf4 --- /dev/null +++ b/tests/src/drivers/test_driver_key_management.c @@ -0,0 +1,390 @@ +/* + * Test driver for generating and verifying keys. + * Currently only supports generating and verifying ECC keys. + */ +/* 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.h" +#include "psa_crypto_core.h" +#include "psa_crypto_ecp.h" +#include "psa_crypto_rsa.h" +#include "mbedtls/ecp.h" +#include "mbedtls/error.h" + +#include "test/drivers/key_management.h" + +#include "test/random.h" + +#include + +test_driver_key_management_hooks_t test_driver_key_management_hooks = + TEST_DRIVER_KEY_MANAGEMENT_INIT; + +const uint8_t test_driver_aes_key[16] = + { 0x36, 0x77, 0x39, 0x7A, 0x24, 0x43, 0x26, 0x46, + 0x29, 0x4A, 0x40, 0x4E, 0x63, 0x52, 0x66, 0x55 }; +const uint8_t test_driver_ecdsa_key[32] = + { 0xdc, 0x7d, 0x9d, 0x26, 0xd6, 0x7a, 0x4f, 0x63, + 0x2c, 0x34, 0xc2, 0xdc, 0x0b, 0x69, 0x86, 0x18, + 0x38, 0x82, 0xc2, 0x06, 0xdf, 0x04, 0xcd, 0xb7, + 0xd6, 0x9a, 0xab, 0xe2, 0x8b, 0xe4, 0xf8, 0x1a }; +const uint8_t test_driver_ecdsa_pubkey[65] = + { 0x04, + 0x85, 0xf6, 0x4d, 0x89, 0xf0, 0x0b, 0xe6, 0x6c, + 0x88, 0xdd, 0x93, 0x7e, 0xfd, 0x6d, 0x7c, 0x44, + 0x56, 0x48, 0xdc, 0xb7, 0x01, 0x15, 0x0b, 0x8a, + 0x95, 0x09, 0x29, 0x58, 0x50, 0xf4, 0x1c, 0x19, + 0x31, 0xe5, 0x71, 0xfb, 0x8f, 0x8c, 0x78, 0x31, + 0x7a, 0x20, 0xb3, 0x80, 0xe8, 0x66, 0x58, 0x4b, + 0xbc, 0x25, 0x16, 0xc3, 0xd2, 0x70, 0x2d, 0x79, + 0x2f, 0x13, 0x1a, 0x92, 0x20, 0x95, 0xfd, 0x6c }; + +psa_status_t test_transparent_generate_key( + const psa_key_attributes_t *attributes, + uint8_t *key, size_t key_size, size_t *key_length ) +{ + ++test_driver_key_management_hooks.hits; + + if( test_driver_key_management_hooks.forced_status != PSA_SUCCESS ) + return( test_driver_key_management_hooks.forced_status ); + + if( test_driver_key_management_hooks.forced_output != NULL ) + { + if( test_driver_key_management_hooks.forced_output_length > key_size ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + memcpy( key, test_driver_key_management_hooks.forced_output, + test_driver_key_management_hooks.forced_output_length ); + *key_length = test_driver_key_management_hooks.forced_output_length; + return( PSA_SUCCESS ); + } + + /* Copied from psa_crypto.c */ +#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 ) ) ) + { + return( mbedtls_transparent_test_driver_ecp_generate_key( + attributes, key, key_size, key_length ) ); + } + else +#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 ) + 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( + const psa_key_attributes_t *attributes, + uint8_t *key, size_t key_size, size_t *key_length ) +{ + (void) attributes; + (void) key; + (void) key_size; + (void) key_length; + return( PSA_ERROR_NOT_SUPPORTED ); +} + +psa_status_t test_transparent_import_key( + const psa_key_attributes_t *attributes, + const uint8_t *data, + size_t data_length, + uint8_t *key_buffer, + size_t key_buffer_size, + size_t *key_buffer_length, + size_t *bits) +{ + ++test_driver_key_management_hooks.hits; + + if( test_driver_key_management_hooks.forced_status != PSA_SUCCESS ) + return( test_driver_key_management_hooks.forced_status ); + + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_type_t type = psa_get_key_type( attributes ); + +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) + if( PSA_KEY_TYPE_IS_ECC( type ) ) + { + status = mbedtls_transparent_test_driver_ecp_import_key( + attributes, + data, data_length, + key_buffer, key_buffer_size, + key_buffer_length, bits ); + } + else +#endif +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) + if( PSA_KEY_TYPE_IS_RSA( type ) ) + { + status = mbedtls_transparent_test_driver_rsa_import_key( + attributes, + data, data_length, + key_buffer, key_buffer_size, + key_buffer_length, bits ); + } + else +#endif + { + status = PSA_ERROR_NOT_SUPPORTED; + (void)data; + (void)data_length; + (void)key_buffer; + (void)key_buffer_size; + (void)key_buffer_length; + (void)bits; + (void)type; + } + + return( status ); +} + +psa_status_t test_opaque_export_key( + const psa_key_attributes_t *attributes, + const uint8_t *key, size_t key_length, + uint8_t *data, size_t data_size, size_t *data_length ) +{ + if( key_length != sizeof( psa_drv_slot_number_t ) ) + { + /* Test driver does not support generic opaque key handling yet. */ + return( PSA_ERROR_NOT_SUPPORTED ); + } + + /* Assume this is a builtin key based on the key material length. */ + psa_drv_slot_number_t slot_number = *( ( psa_drv_slot_number_t* ) key ); + + switch( slot_number ) + { + case PSA_CRYPTO_TEST_DRIVER_BUILTIN_ECDSA_KEY_SLOT: + /* This is the ECDSA slot. Verify the key's attributes before + * returning the private key. */ + if( psa_get_key_type( attributes ) != + PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ) ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + if( psa_get_key_bits( attributes ) != 256 ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + if( psa_get_key_algorithm( attributes ) != + PSA_ALG_ECDSA( PSA_ALG_ANY_HASH ) ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + if( ( psa_get_key_usage_flags( attributes ) & + PSA_KEY_USAGE_EXPORT ) == 0 ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + + if( data_size < sizeof( test_driver_ecdsa_key ) ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + + memcpy( data, test_driver_ecdsa_key, + sizeof( test_driver_ecdsa_key ) ); + *data_length = sizeof( test_driver_ecdsa_key ); + return( PSA_SUCCESS ); + + case PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT: + /* This is the AES slot. Verify the key's attributes before + * returning the key. */ + if( psa_get_key_type( attributes ) != PSA_KEY_TYPE_AES ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + if( psa_get_key_bits( attributes ) != 128 ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + if( psa_get_key_algorithm( attributes ) != PSA_ALG_CTR ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + if( ( psa_get_key_usage_flags( attributes ) & + PSA_KEY_USAGE_EXPORT ) == 0 ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + + if( data_size < sizeof( test_driver_aes_key ) ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + + memcpy( data, test_driver_aes_key, + sizeof( test_driver_aes_key ) ); + *data_length = sizeof( test_driver_aes_key ); + return( PSA_SUCCESS ); + + default: + return( PSA_ERROR_DOES_NOT_EXIST ); + } +} + +psa_status_t test_transparent_export_public_key( + const psa_key_attributes_t *attributes, + const uint8_t *key_buffer, size_t key_buffer_size, + uint8_t *data, size_t data_size, size_t *data_length ) +{ + ++test_driver_key_management_hooks.hits; + + if( test_driver_key_management_hooks.forced_status != PSA_SUCCESS ) + return( test_driver_key_management_hooks.forced_status ); + + if( test_driver_key_management_hooks.forced_output != NULL ) + { + if( test_driver_key_management_hooks.forced_output_length > data_size ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + memcpy( data, test_driver_key_management_hooks.forced_output, + test_driver_key_management_hooks.forced_output_length ); + *data_length = test_driver_key_management_hooks.forced_output_length; + return( PSA_SUCCESS ); + } + + psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; + psa_key_type_t key_type = psa_get_key_type( attributes ); + +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_KEY_PAIR) || \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_ECC_PUBLIC_KEY) + if( PSA_KEY_TYPE_IS_ECC( key_type ) ) + { + status = mbedtls_transparent_test_driver_ecp_export_public_key( + attributes, + key_buffer, key_buffer_size, + data, data_size, data_length ); + } + else +#endif +#if defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_KEY_PAIR) || \ + defined(MBEDTLS_PSA_ACCEL_KEY_TYPE_RSA_PUBLIC_KEY) + if( PSA_KEY_TYPE_IS_RSA( key_type ) ) + { + status = mbedtls_transparent_test_driver_rsa_export_public_key( + attributes, + key_buffer, key_buffer_size, + data, data_size, data_length ); + } + else +#endif + { + status = PSA_ERROR_NOT_SUPPORTED; + (void)key_buffer; + (void)key_buffer_size; + (void)key_type; + } + + return( status ); +} + +psa_status_t test_opaque_export_public_key( + const psa_key_attributes_t *attributes, + const uint8_t *key, size_t key_length, + uint8_t *data, size_t data_size, size_t *data_length ) +{ + if( key_length != sizeof( psa_drv_slot_number_t ) ) + { + /* Test driver does not support generic opaque key handling yet. */ + return( PSA_ERROR_NOT_SUPPORTED ); + } + + /* Assume this is a builtin key based on the key material length. */ + psa_drv_slot_number_t slot_number = *( ( psa_drv_slot_number_t* ) key ); + switch( slot_number ) + { + case PSA_CRYPTO_TEST_DRIVER_BUILTIN_ECDSA_KEY_SLOT: + /* This is the ECDSA slot. Verify the key's attributes before + * returning the public key. */ + if( psa_get_key_type( attributes ) != + PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ) ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + if( psa_get_key_bits( attributes ) != 256 ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + if( psa_get_key_algorithm( attributes ) != + PSA_ALG_ECDSA( PSA_ALG_ANY_HASH ) ) + return( PSA_ERROR_CORRUPTION_DETECTED ); + + if( data_size < sizeof( test_driver_ecdsa_pubkey ) ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + + memcpy( data, test_driver_ecdsa_pubkey, + sizeof( test_driver_ecdsa_pubkey ) ); + *data_length = sizeof( test_driver_ecdsa_pubkey ); + return( PSA_SUCCESS ); + + default: + return( PSA_ERROR_DOES_NOT_EXIST ); + } +} + +/* The opaque test driver exposes two built-in keys when builtin key support is + * compiled in. + * The key in slot #PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT is an AES-128 + * key which allows CTR mode. + * The key in slot #PSA_CRYPTO_TEST_DRIVER_BUILTIN_ECDSA_KEY_SLOT is a secp256r1 + * private key which allows ECDSA sign & verify. + * The key buffer format for these is the raw format of psa_drv_slot_number_t + * (i.e. for an actual driver this would mean 'builtin_key_size' = + * sizeof(psa_drv_slot_number_t)). + */ +psa_status_t test_opaque_get_builtin_key( + psa_drv_slot_number_t slot_number, + psa_key_attributes_t *attributes, + uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length ) +{ + switch( slot_number ) + { + case PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT: + psa_set_key_type( attributes, PSA_KEY_TYPE_AES ); + psa_set_key_bits( attributes, 128 ); + psa_set_key_usage_flags( + attributes, + PSA_KEY_USAGE_ENCRYPT | + PSA_KEY_USAGE_DECRYPT | + PSA_KEY_USAGE_EXPORT ); + psa_set_key_algorithm( attributes, PSA_ALG_CTR ); + + if( key_buffer_size < sizeof( psa_drv_slot_number_t ) ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + + *( (psa_drv_slot_number_t*) key_buffer ) = + PSA_CRYPTO_TEST_DRIVER_BUILTIN_AES_KEY_SLOT; + *key_buffer_length = sizeof( psa_drv_slot_number_t ); + return( PSA_SUCCESS ); + case PSA_CRYPTO_TEST_DRIVER_BUILTIN_ECDSA_KEY_SLOT: + psa_set_key_type( + attributes, + PSA_KEY_TYPE_ECC_KEY_PAIR( PSA_ECC_FAMILY_SECP_R1 ) ); + psa_set_key_bits( attributes, 256 ); + psa_set_key_usage_flags( + attributes, + PSA_KEY_USAGE_SIGN_HASH | + PSA_KEY_USAGE_VERIFY_HASH | + PSA_KEY_USAGE_EXPORT ); + psa_set_key_algorithm( + attributes, PSA_ALG_ECDSA( PSA_ALG_ANY_HASH ) ); + + if( key_buffer_size < sizeof( psa_drv_slot_number_t ) ) + return( PSA_ERROR_BUFFER_TOO_SMALL ); + + *( (psa_drv_slot_number_t*) key_buffer ) = + PSA_CRYPTO_TEST_DRIVER_BUILTIN_ECDSA_KEY_SLOT; + *key_buffer_length = sizeof( psa_drv_slot_number_t ); + return( PSA_SUCCESS ); + default: + return( PSA_ERROR_DOES_NOT_EXIST ); + } +} + +#endif /* MBEDTLS_PSA_CRYPTO_DRIVERS && PSA_CRYPTO_DRIVER_TEST */ diff --git a/tests/src/drivers/signature.c b/tests/src/drivers/test_driver_signature.c similarity index 100% rename from tests/src/drivers/signature.c rename to tests/src/drivers/test_driver_signature.c diff --git a/tests/src/drivers/size.c b/tests/src/drivers/test_driver_size.c similarity index 100% rename from tests/src/drivers/size.c rename to tests/src/drivers/test_driver_size.c diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.data b/tests/suites/test_suite_psa_crypto_driver_wrappers.data index 241d715b3..251388378 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.data +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.data @@ -243,3 +243,27 @@ 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_ERROR_INSUFFICIENT_MEMORY + +PSA opaque driver builtin key export: AES +builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_SUCCESS + +PSA opaque driver builtin key export: AES (registered to ID_MAX-1) +builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MAX - 1:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_SUCCESS + +PSA opaque driver builtin key export: AES (registered to ID_MAX) +builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MAX:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_SUCCESS + +PSA opaque driver builtin key export: key ID out of range (ID_MIN - 1) +builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN - 1:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_ERROR_INVALID_HANDLE + +PSA opaque driver builtin key export: key ID out of range (ID_MAX + 1) +builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MAX + 1:PSA_KEY_TYPE_AES:128:PSA_ALG_CTR:"3677397A24432646294A404E63526655":PSA_ERROR_INVALID_HANDLE + +PSA opaque driver builtin key export: secp256r1 +builtin_key_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):"dc7d9d26d67a4f632c34c2dc0b6986183882c206df04cdb7d69aabe28be4f81a":PSA_SUCCESS + +PSA opaque driver builtin pubkey export: secp256r1 +builtin_pubkey_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN + 1:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):"0485f64d89f00be66c88dd937efd6d7c445648dcb701150b8a9509295850f41c1931e571fb8f8c78317a20b380e866584bbc2516c3d2702d792f131a922095fd6c":PSA_SUCCESS + +PSA opaque driver builtin pubkey export: not a public key +builtin_pubkey_export:MBEDTLS_PSA_KEY_ID_BUILTIN_MIN:PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1):256:PSA_ALG_ECDSA(PSA_ALG_ANY_HASH):"0485f64d89f00be66c88dd937efd6d7c445648dcb701150b8a9509295850f41c1931e571fb8f8c78317a20b380e866584bbc2516c3d2702d792f131a922095fd6c":PSA_ERROR_INVALID_ARGUMENT diff --git a/tests/suites/test_suite_psa_crypto_driver_wrappers.function b/tests/suites/test_suite_psa_crypto_driver_wrappers.function index 20452b70c..ad5b6c5fa 100644 --- a/tests/suites/test_suite_psa_crypto_driver_wrappers.function +++ b/tests/suites/test_suite_psa_crypto_driver_wrappers.function @@ -936,3 +936,107 @@ exit: test_driver_aead_hooks = test_driver_aead_hooks_init(); } /* END_CASE */ + +/* BEGIN_CASE depends_on:PSA_CRYPTO_DRIVER_TEST:MBEDTLS_PSA_CRYPTO_DRIVERS:MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ +void builtin_key_export( int builtin_key_id_arg, + int builtin_key_type_arg, + int builtin_key_bits_arg, + int builtin_key_algorithm_arg, + data_t *expected_output, + int expected_status_arg ) +{ + psa_key_id_t builtin_key_id = (psa_key_id_t) builtin_key_id_arg; + psa_key_type_t builtin_key_type = (psa_key_type_t) builtin_key_type_arg; + psa_algorithm_t builtin_key_alg = (psa_algorithm_t) builtin_key_algorithm_arg; + size_t builtin_key_bits = (size_t) builtin_key_bits_arg; + psa_status_t expected_status = expected_status_arg; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + mbedtls_svc_key_id_t key = mbedtls_svc_key_id_make( 0, builtin_key_id ); + uint8_t* output_buffer = NULL; + size_t output_size = 0; + psa_status_t actual_status; + + PSA_ASSERT( psa_crypto_init( ) ); + ASSERT_ALLOC( output_buffer, expected_output->len ); + + actual_status = psa_export_key( key, output_buffer, expected_output->len, &output_size ); + + if( expected_status == PSA_SUCCESS ) + { + PSA_ASSERT( actual_status ); + TEST_EQUAL( output_size, expected_output->len ); + ASSERT_COMPARE( output_buffer, output_size, + expected_output->x, expected_output->len ); + + PSA_ASSERT( psa_get_key_attributes( key, &attributes ) ); + TEST_EQUAL( psa_get_key_bits( &attributes ), builtin_key_bits ); + TEST_EQUAL( psa_get_key_type( &attributes ), builtin_key_type ); + TEST_EQUAL( psa_get_key_algorithm( &attributes ), builtin_key_alg ); + } + else + { + if( actual_status != expected_status ) + fprintf( stderr, "Expected %d but got %d\n", expected_status, actual_status ); + TEST_EQUAL( actual_status, expected_status ); + TEST_EQUAL( output_size, 0 ); + } + +exit: + mbedtls_free( output_buffer ); + psa_reset_key_attributes( &attributes ); + psa_destroy_key( key ); + PSA_DONE( ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:PSA_CRYPTO_DRIVER_TEST:MBEDTLS_PSA_CRYPTO_DRIVERS:MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS */ +void builtin_pubkey_export( int builtin_key_id_arg, + int builtin_key_type_arg, + int builtin_key_bits_arg, + int builtin_key_algorithm_arg, + data_t *expected_output, + int expected_status_arg ) +{ + psa_key_id_t builtin_key_id = (psa_key_id_t) builtin_key_id_arg; + psa_key_type_t builtin_key_type = (psa_key_type_t) builtin_key_type_arg; + psa_algorithm_t builtin_key_alg = (psa_algorithm_t) builtin_key_algorithm_arg; + size_t builtin_key_bits = (size_t) builtin_key_bits_arg; + psa_status_t expected_status = expected_status_arg; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + + mbedtls_svc_key_id_t key = mbedtls_svc_key_id_make( 0, builtin_key_id ); + uint8_t* output_buffer = NULL; + size_t output_size = 0; + psa_status_t actual_status; + + PSA_ASSERT( psa_crypto_init( ) ); + ASSERT_ALLOC( output_buffer, expected_output->len ); + + actual_status = psa_export_public_key( key, output_buffer, expected_output->len, &output_size ); + + if( expected_status == PSA_SUCCESS ) + { + PSA_ASSERT( actual_status ); + TEST_EQUAL( output_size, expected_output->len ); + ASSERT_COMPARE( output_buffer, output_size, + expected_output->x, expected_output->len ); + + PSA_ASSERT( psa_get_key_attributes( key, &attributes ) ); + TEST_EQUAL( psa_get_key_bits( &attributes ), builtin_key_bits ); + TEST_EQUAL( psa_get_key_type( &attributes ), builtin_key_type ); + TEST_EQUAL( psa_get_key_algorithm( &attributes ), builtin_key_alg ); + } + else + { + TEST_EQUAL( actual_status, expected_status ); + TEST_EQUAL( output_size, 0 ); + } + +exit: + mbedtls_free( output_buffer ); + psa_reset_key_attributes( &attributes ); + psa_destroy_key( key ); + PSA_DONE( ); +} +/* END_CASE */ diff --git a/visualc/VS2010/mbedTLS.vcxproj b/visualc/VS2010/mbedTLS.vcxproj index 832d42862..5277193f9 100644 --- a/visualc/VS2010/mbedTLS.vcxproj +++ b/visualc/VS2010/mbedTLS.vcxproj @@ -379,6 +379,12 @@ + + + + + +