diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index b2d4633de..6dfaa1300 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -89,7 +89,7 @@ static inline void psa_set_key_enrollment_algorithm( psa_key_attributes_t *attributes, psa_algorithm_t alg2) { - attributes->policy.alg2 = alg2; + attributes->core.policy.alg2 = alg2; } /** Retrieve the enrollment algorithm policy from key attributes. @@ -101,7 +101,7 @@ static inline void psa_set_key_enrollment_algorithm( static inline psa_algorithm_t psa_get_key_enrollment_algorithm( const psa_key_attributes_t *attributes) { - return( attributes->policy.alg2 ); + return( attributes->core.policy.alg2 ); } /**@}*/ diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 0ddc7a3eb..453c83565 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -309,18 +309,39 @@ static inline struct psa_key_policy_s psa_key_policy_init( void ) return( v ); } +/* The type used internally for key sizes. + * Public interfaces use size_t, but internally we use a smaller type. */ +typedef uint16_t psa_key_bits_t; +/* The maximum value of the type used to represent bit-sizes. + * This is used to mark an invalid key size. */ +#define PSA_KEY_BITS_TOO_LARGE ( (psa_key_bits_t) ( -1 ) ) +/* The maximum size of a key in bits. + * Currently defined as the maximum that can be represented, rounded down + * to a whole number of bytes. + * This is an uncast value so that it can be used in preprocessor + * conditionals. */ +#define PSA_MAX_KEY_BITS 0xfff8 + +typedef struct +{ + psa_key_type_t type; + psa_key_lifetime_t lifetime; + psa_key_id_t id; + psa_key_policy_t policy; + psa_key_bits_t bits; + uint16_t flags; +} psa_core_key_attributes_t; + +#define PSA_CORE_KEY_ATTRIBUTES_INIT {0, 0, 0, {0, 0, 0}, 0, 0} + struct psa_key_attributes_s { - psa_key_id_t id; - psa_key_lifetime_t lifetime; - psa_key_policy_t policy; - psa_key_type_t type; - size_t bits; + psa_core_key_attributes_t core; void *domain_parameters; size_t domain_parameters_size; }; -#define PSA_KEY_ATTRIBUTES_INIT {0, 0, {0, 0, 0}, 0, 0, NULL, 0} +#define PSA_KEY_ATTRIBUTES_INIT {PSA_CORE_KEY_ATTRIBUTES_INIT, NULL, 0} static inline struct psa_key_attributes_s psa_key_attributes_init( void ) { const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT; @@ -330,53 +351,53 @@ static inline struct psa_key_attributes_s psa_key_attributes_init( void ) static inline void psa_set_key_id(psa_key_attributes_t *attributes, psa_key_id_t id) { - attributes->id = id; - if( attributes->lifetime == PSA_KEY_LIFETIME_VOLATILE ) - attributes->lifetime = PSA_KEY_LIFETIME_PERSISTENT; + attributes->core.id = id; + if( attributes->core.lifetime == PSA_KEY_LIFETIME_VOLATILE ) + attributes->core.lifetime = PSA_KEY_LIFETIME_PERSISTENT; } static inline psa_key_id_t psa_get_key_id( const psa_key_attributes_t *attributes) { - return( attributes->id ); + return( attributes->core.id ); } static inline void psa_set_key_lifetime(psa_key_attributes_t *attributes, psa_key_lifetime_t lifetime) { - attributes->lifetime = lifetime; + attributes->core.lifetime = lifetime; if( lifetime == PSA_KEY_LIFETIME_VOLATILE ) - attributes->id = 0; + attributes->core.id = 0; } static inline psa_key_lifetime_t psa_get_key_lifetime( const psa_key_attributes_t *attributes) { - return( attributes->lifetime ); + return( attributes->core.lifetime ); } static inline void psa_set_key_usage_flags(psa_key_attributes_t *attributes, psa_key_usage_t usage_flags) { - attributes->policy.usage = usage_flags; + attributes->core.policy.usage = usage_flags; } static inline psa_key_usage_t psa_get_key_usage_flags( const psa_key_attributes_t *attributes) { - return( attributes->policy.usage ); + return( attributes->core.policy.usage ); } static inline void psa_set_key_algorithm(psa_key_attributes_t *attributes, psa_algorithm_t alg) { - attributes->policy.alg = alg; + attributes->core.policy.alg = alg; } static inline psa_algorithm_t psa_get_key_algorithm( const psa_key_attributes_t *attributes) { - return( attributes->policy.alg ); + return( attributes->core.policy.alg ); } /* This function is declared in crypto_extra.h, which comes after this @@ -392,7 +413,7 @@ static inline void psa_set_key_type(psa_key_attributes_t *attributes, if( attributes->domain_parameters == NULL ) { /* Common case: quick path */ - attributes->type = type; + attributes->core.type = type; } else { @@ -407,19 +428,22 @@ static inline void psa_set_key_type(psa_key_attributes_t *attributes, static inline psa_key_type_t psa_get_key_type( const psa_key_attributes_t *attributes) { - return( attributes->type ); + return( attributes->core.type ); } static inline void psa_set_key_bits(psa_key_attributes_t *attributes, size_t bits) { - attributes->bits = bits; + if( bits > PSA_MAX_KEY_BITS ) + attributes->core.bits = PSA_KEY_BITS_TOO_LARGE; + else + attributes->core.bits = (psa_key_bits_t) bits; } static inline size_t psa_get_key_bits( const psa_key_attributes_t *attributes) { - return( attributes->bits ); + return( attributes->core.bits ); } #endif /* PSA_CRYPTO_STRUCT_H */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 875252803..b602f1961 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -40,6 +40,7 @@ * stored keys. */ #include "psa_crypto_storage.h" +#include #include #include #include "mbedtls/platform.h" @@ -366,7 +367,7 @@ static psa_status_t mbedtls_to_psa_error( int ret ) #if defined(MBEDTLS_PSA_CRYPTO_SE_C) static inline int psa_key_slot_is_external( const psa_key_slot_t *slot ) { - return( psa_key_lifetime_is_external( slot->lifetime ) ); + return( psa_key_lifetime_is_external( slot->attr.lifetime ) ); } #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ @@ -695,7 +696,45 @@ exit: } #endif /* defined(MBEDTLS_ECP_C) */ -/** Import key data into a slot. `slot->type` must have been set + +/** Return the size of the key in the given slot, in bits. + * + * \param[in] slot A key slot. + * + * \return The key size in bits, read from the metadata in the slot. + */ +static inline size_t psa_get_key_slot_bits( const psa_key_slot_t *slot ) +{ + return( slot->attr.bits ); +} + +/** Calculate the size of the key in the given slot, in bits. + * + * \param[in] slot A key slot containing a transparent key. + * + * \return The key size in bits, calculated from the key data. + */ +static psa_key_bits_t psa_calculate_key_bits( const psa_key_slot_t *slot ) +{ + size_t bits = 0; /* return 0 on an empty slot */ + + if( key_type_is_raw_bytes( slot->attr.type ) ) + bits = PSA_BYTES_TO_BITS( slot->data.raw.bytes ); +#if defined(MBEDTLS_RSA_C) + else if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) + bits = PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ); +#endif /* defined(MBEDTLS_RSA_C) */ +#if defined(MBEDTLS_ECP_C) + else if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) ) + bits = slot->data.ecp->grp.pbits; +#endif /* defined(MBEDTLS_ECP_C) */ + + /* We know that the size fits in psa_key_bits_t thanks to checks + * when the key was created. */ + return( (psa_key_bits_t) bits ); +} + +/** Import key data into a slot. `slot->attr.type` must have been set * previously. This function assumes that the slot does not contain * any key material yet. On failure, the slot content is unchanged. */ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, @@ -704,13 +743,17 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, { psa_status_t status = PSA_SUCCESS; - if( key_type_is_raw_bytes( slot->type ) ) + if( key_type_is_raw_bytes( slot->attr.type ) ) { - /* Ensure that a bytes-to-bit conversion won't overflow. */ + size_t bit_size = PSA_BYTES_TO_BITS( data_length ); + /* Ensure that the bytes-to-bit conversion didn't overflow. */ if( data_length > SIZE_MAX / 8 ) return( PSA_ERROR_NOT_SUPPORTED ); - status = prepare_raw_data_slot( slot->type, - PSA_BYTES_TO_BITS( data_length ), + /* Enforce a size limit, and in particular ensure that the bit + * size fits in its representation type. */ + if( bit_size > PSA_MAX_KEY_BITS ) + return( PSA_ERROR_NOT_SUPPORTED ); + status = prepare_raw_data_slot( slot->attr.type, bit_size, &slot->data.raw ); if( status != PSA_SUCCESS ) return( status ); @@ -719,25 +762,25 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, } else #if defined(MBEDTLS_ECP_C) - if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->type ) ) + if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->attr.type ) ) { - status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->type ), + status = psa_import_ec_private_key( PSA_KEY_TYPE_GET_CURVE( slot->attr.type ), data, data_length, &slot->data.ecp ); } - else if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( slot->type ) ) + else if( PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY( slot->attr.type ) ) { status = psa_import_ec_public_key( - PSA_KEY_TYPE_GET_CURVE( slot->type ), + PSA_KEY_TYPE_GET_CURVE( slot->attr.type ), data, data_length, &slot->data.ecp ); } else #endif /* MBEDTLS_ECP_C */ #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PK_PARSE_C) - if( PSA_KEY_TYPE_IS_RSA( slot->type ) ) + if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) { - status = psa_import_rsa_key( slot->type, + status = psa_import_rsa_key( slot->attr.type, data, data_length, &slot->data.rsa ); } @@ -746,6 +789,14 @@ psa_status_t psa_import_key_into_slot( psa_key_slot_t *slot, { return( PSA_ERROR_NOT_SUPPORTED ); } + + if( status == PSA_SUCCESS ) + { + /* Write the actual key size to the slot. + * psa_start_key_creation() wrote the size declared by the + * caller, which may be 0 (meaning unspecified) or wrong. */ + slot->attr.bits = psa_calculate_key_bits( slot ); + } return( status ); } @@ -851,20 +902,18 @@ static psa_status_t psa_get_key_from_slot( psa_key_handle_t handle, status = psa_get_key_slot( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); - if( slot->type == PSA_KEY_TYPE_NONE ) - return( PSA_ERROR_DOES_NOT_EXIST ); /* Enforce that usage policy for the key slot contains all the flags * required by the usage parameter. There is one exception: public * keys can always be exported, so we treat public key objects as * if they had the export flag. */ - if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ) + if( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) ) usage &= ~PSA_KEY_USAGE_EXPORT; - if( ( slot->policy.usage & usage ) != usage ) + if( ( slot->attr.policy.usage & usage ) != usage ) return( PSA_ERROR_NOT_PERMITTED ); /* Enforce that the usage policy permits the requested algortihm. */ - if( alg != 0 && ! psa_key_policy_permits( &slot->policy, alg ) ) + if( alg != 0 && ! psa_key_policy_permits( &slot->attr.policy, alg ) ) return( PSA_ERROR_NOT_PERMITTED ); *p_slot = slot; @@ -911,17 +960,17 @@ static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot ) } else #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - if( slot->type == PSA_KEY_TYPE_NONE ) + if( slot->attr.type == PSA_KEY_TYPE_NONE ) { /* No key material to clean. */ } - else if( key_type_is_raw_bytes( slot->type ) ) + else if( key_type_is_raw_bytes( slot->attr.type ) ) { mbedtls_free( slot->data.raw.data ); } else #if defined(MBEDTLS_RSA_C) - if( PSA_KEY_TYPE_IS_RSA( slot->type ) ) + if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) { mbedtls_rsa_free( slot->data.rsa ); mbedtls_free( slot->data.rsa ); @@ -929,7 +978,7 @@ static psa_status_t psa_remove_key_data_from_memory( psa_key_slot_t *slot ) else #endif /* defined(MBEDTLS_RSA_C) */ #if defined(MBEDTLS_ECP_C) - if( PSA_KEY_TYPE_IS_ECC( slot->type ) ) + if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) ) { mbedtls_ecp_keypair_free( slot->data.ecp ); mbedtls_free( slot->data.ecp ); @@ -978,7 +1027,7 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle ) return( status ); #if defined(MBEDTLS_PSA_CRYPTO_SE_C) - driver = psa_get_se_driver_entry( slot->lifetime ); + driver = psa_get_se_driver_entry( slot->attr.lifetime ); if( driver != NULL ) { /* For a key in a secure element, we need to do three things: @@ -987,9 +1036,9 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle ) * persistent data. Start a transaction that will encompass these * three actions. */ psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_DESTROY_KEY ); - psa_crypto_transaction.key.lifetime = slot->lifetime; + psa_crypto_transaction.key.lifetime = slot->attr.lifetime; psa_crypto_transaction.key.slot = slot->data.se.slot_number; - psa_crypto_transaction.key.id = slot->persistent_storage_id; + psa_crypto_transaction.key.id = slot->attr.id; status = psa_crypto_save_transaction( ); if( status != PSA_SUCCESS ) { @@ -1003,10 +1052,10 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle ) #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT ) + if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT ) { storage_status = - psa_destroy_persistent_key( slot->persistent_storage_id ); + psa_destroy_persistent_key( slot->attr.id ); } #endif /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ @@ -1032,28 +1081,6 @@ psa_status_t psa_destroy_key( psa_key_handle_t handle ) return( storage_status ); } -/* Return the size of the key in the given slot, in bits. */ -static size_t psa_get_key_slot_bits( const psa_key_slot_t *slot ) -{ -#if defined(MBEDTLS_PSA_CRYPTO_SE_C) - if( psa_get_se_driver( slot->lifetime, NULL, NULL ) ) - return( slot->data.se.bits ); -#endif /* defined(MBEDTLS_PSA_CRYPTO_SE_C) */ - - if( key_type_is_raw_bytes( slot->type ) ) - return( slot->data.raw.bytes * 8 ); -#if defined(MBEDTLS_RSA_C) - if( PSA_KEY_TYPE_IS_RSA( slot->type ) ) - return( PSA_BYTES_TO_BITS( mbedtls_rsa_get_len( slot->data.rsa ) ) ); -#endif /* defined(MBEDTLS_RSA_C) */ -#if defined(MBEDTLS_ECP_C) - if( PSA_KEY_TYPE_IS_ECC( slot->type ) ) - return( slot->data.ecp->grp.pbits ); -#endif /* defined(MBEDTLS_ECP_C) */ - /* Shouldn't happen except on an empty slot. */ - return( 0 ); -} - void psa_reset_key_attributes( psa_key_attributes_t *attributes ) { mbedtls_free( attributes->domain_parameters ); @@ -1086,7 +1113,7 @@ psa_status_t psa_set_key_domain_parameters( psa_key_attributes_t *attributes, attributes->domain_parameters = copy; attributes->domain_parameters_size = data_length; - attributes->type = type; + attributes->core.type = type; return( PSA_SUCCESS ); } @@ -1145,21 +1172,6 @@ exit: } #endif /* MBEDTLS_RSA_C */ -/** Retrieve the generic attributes of a key in a slot. - * - * This function does not retrieve domain parameters, which require - * additional memory management. - */ -static void psa_get_key_slot_attributes( psa_key_slot_t *slot, - psa_key_attributes_t *attributes ) -{ - attributes->id = slot->persistent_storage_id; - attributes->lifetime = slot->lifetime; - attributes->policy = slot->policy; - attributes->type = slot->type; - attributes->bits = psa_get_key_slot_bits( slot ); -} - /** Retrieve all the publicly-accessible attributes of a key. */ psa_status_t psa_get_key_attributes( psa_key_handle_t handle, @@ -1174,9 +1186,9 @@ psa_status_t psa_get_key_attributes( psa_key_handle_t handle, if( status != PSA_SUCCESS ) return( status ); - psa_get_key_slot_attributes( slot, attributes ); + attributes->core = slot->attr; - switch( slot->type ) + switch( slot->attr.type ) { #if defined(MBEDTLS_RSA_C) case PSA_KEY_TYPE_RSA_KEY_PAIR: @@ -1184,7 +1196,7 @@ psa_status_t psa_get_key_attributes( psa_key_handle_t handle, #if defined(MBEDTLS_PSA_CRYPTO_SE_C) /* TOnogrepDO: reporting the public exponent for opaque keys * is not yet implemented. */ - if( psa_get_se_driver( slot->lifetime, NULL, NULL ) ) + if( psa_get_se_driver( slot->attr.lifetime, NULL, NULL ) ) break; #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ status = psa_get_rsa_public_exponent( slot->data.rsa, attributes ); @@ -1229,11 +1241,11 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, *data_length = 0; - if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->type ) ) + if( export_public_key && ! PSA_KEY_TYPE_IS_ASYMMETRIC( slot->attr.type ) ) return( PSA_ERROR_INVALID_ARGUMENT ); #if defined(MBEDTLS_PSA_CRYPTO_SE_C) - if( psa_get_se_driver( slot->lifetime, &drv, &drv_context ) ) + if( psa_get_se_driver( slot->attr.lifetime, &drv, &drv_context ) ) { psa_drv_se_export_key_t method; if( drv->key_management == NULL ) @@ -1249,7 +1261,7 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, } #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ - if( key_type_is_raw_bytes( slot->type ) ) + if( key_type_is_raw_bytes( slot->attr.type ) ) { if( slot->data.raw.bytes > data_size ) return( PSA_ERROR_BUFFER_TOO_SMALL ); @@ -1263,11 +1275,11 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, return( PSA_SUCCESS ); } #if defined(MBEDTLS_ECP_C) - if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->type ) && !export_public_key ) + if( PSA_KEY_TYPE_IS_ECC_KEY_PAIR( slot->attr.type ) && !export_public_key ) { psa_status_t status; - size_t bytes = PSA_BITS_TO_BYTES( psa_get_key_slot_bits( slot ) ); + size_t bytes = PSA_BITS_TO_BYTES( slot->attr.bits ); if( bytes > data_size ) return( PSA_ERROR_BUFFER_TOO_SMALL ); status = mbedtls_to_psa_error( @@ -1282,12 +1294,12 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, else { #if defined(MBEDTLS_PK_WRITE_C) - if( PSA_KEY_TYPE_IS_RSA( slot->type ) || - PSA_KEY_TYPE_IS_ECC( slot->type ) ) + if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) || + PSA_KEY_TYPE_IS_ECC( slot->attr.type ) ) { mbedtls_pk_context pk; int ret; - if( PSA_KEY_TYPE_IS_RSA( slot->type ) ) + if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) { #if defined(MBEDTLS_RSA_C) mbedtls_pk_init( &pk ); @@ -1307,7 +1319,7 @@ static psa_status_t psa_internal_export_key( const psa_key_slot_t *slot, return( PSA_ERROR_NOT_SUPPORTED ); #endif } - if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) ) + if( export_public_key || PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) ) { ret = pk_write_pubkey_simple( &pk, data, data_size ); } @@ -1396,9 +1408,13 @@ psa_status_t psa_export_public_key( psa_key_handle_t handle, data_length, 1 ) ); } -static psa_status_t psa_set_key_policy_internal( - psa_key_slot_t *slot, - const psa_key_policy_t *policy ) +/** Validate that a key policy is internally well-formed. + * + * This function only rejects invalid policies. It does not validate the + * consistency of the policy with respect to other attributes of the key + * such as the key type. + */ +static psa_status_t psa_validate_key_policy( const psa_key_policy_t *policy ) { if( ( policy->usage & ~( PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY | @@ -1409,7 +1425,48 @@ static psa_status_t psa_set_key_policy_internal( PSA_KEY_USAGE_DERIVE ) ) != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); - slot->policy = *policy; + return( PSA_SUCCESS ); +} + +/** Validate the internal consistency of key attributes. + * + * This function only rejects invalid attribute values. If does not + * validate the consistency of the attributes with any key data that may + * be involved in the creation of the key. + * + * Call this function early in the key creation process. + * + * \param[in] attributes Key attributes for the new key. + * \param[out] p_drv On any return, the driver for the key, if any. + * NULL for a transparent key. + * + */ +static psa_status_t psa_validate_key_attributes( + const psa_key_attributes_t *attributes, + psa_se_drv_table_entry_t **p_drv ) +{ + psa_status_t status; + + if( attributes->core.lifetime != PSA_KEY_LIFETIME_VOLATILE ) + { + status = psa_validate_persistent_key_parameters( + attributes->core.lifetime, attributes->core.id, + p_drv, 1 ); + if( status != PSA_SUCCESS ) + return( status ); + } + + status = psa_validate_key_policy( &attributes->core.policy ); + if( status != PSA_SUCCESS ) + return( status ); + + /* Refuse to create overly large keys. + * Note that this doesn't trigger on import if the attributes don't + * explicitly specify a size (so psa_get_key_bits returns 0), so + * psa_import_key() needs its own checks. */ + if( psa_get_key_bits( attributes ) > PSA_MAX_KEY_BITS ) + return( PSA_ERROR_NOT_SUPPORTED ); + return( PSA_SUCCESS ); } @@ -1449,26 +1506,22 @@ static psa_status_t psa_start_key_creation( *p_drv = NULL; + status = psa_validate_key_attributes( attributes, p_drv ); + if( status != PSA_SUCCESS ) + return( status ); + status = psa_internal_allocate_key_slot( handle, p_slot ); if( status != PSA_SUCCESS ) return( status ); slot = *p_slot; - status = psa_set_key_policy_internal( slot, &attributes->policy ); - if( status != PSA_SUCCESS ) - return( status ); - slot->lifetime = attributes->lifetime; + /* We're storing the declared bit-size of the key. It's up to each + * creation mechanism to verify that this information is correct. + * It's automatically correct for mechanisms that use the bit-size as + * an input (generate, device) but not for those where the bit-size + * is optional (import, copy). */ - if( attributes->lifetime != PSA_KEY_LIFETIME_VOLATILE ) - { - status = psa_validate_persistent_key_parameters( attributes->lifetime, - attributes->id, - p_drv, 1 ); - if( status != PSA_SUCCESS ) - return( status ); - slot->persistent_storage_id = attributes->id; - } - slot->type = attributes->type; + slot->attr = attributes->core; #if defined(MBEDTLS_PSA_CRYPTO_SE_C) /* For a key in a secure element, we need to do three things: @@ -1491,19 +1544,15 @@ static psa_status_t psa_start_key_creation( if( status != PSA_SUCCESS ) return( status ); psa_crypto_prepare_transaction( PSA_CRYPTO_TRANSACTION_CREATE_KEY ); - psa_crypto_transaction.key.lifetime = slot->lifetime; + psa_crypto_transaction.key.lifetime = slot->attr.lifetime; psa_crypto_transaction.key.slot = slot->data.se.slot_number; - psa_crypto_transaction.key.id = slot->persistent_storage_id; + psa_crypto_transaction.key.id = slot->attr.id; status = psa_crypto_save_transaction( ); if( status != PSA_SUCCESS ) { (void) psa_crypto_stop_transaction( ); return( status ); } - - /* TOnogrepDO: validate bits. How to do this depends on the key - * creation method, so setting bits might not belong here. */ - slot->data.se.bits = psa_get_key_bits( attributes ); } #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ @@ -1536,24 +1585,33 @@ static psa_status_t psa_finish_key_creation( (void) driver; #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) - if( slot->lifetime != PSA_KEY_LIFETIME_VOLATILE ) + if( slot->attr.lifetime != PSA_KEY_LIFETIME_VOLATILE ) { - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_get_key_slot_attributes( slot, &attributes ); - #if defined(MBEDTLS_PSA_CRYPTO_SE_C) if( driver != NULL ) { - status = psa_save_persistent_key( &attributes, - (uint8_t*) &slot->data.se, - sizeof( slot->data.se ) ); + psa_se_key_data_storage_t data; +#if defined(static_assert) + static_assert( sizeof( slot->data.se.slot_number ) == + sizeof( data.slot_number ), + "Slot number size does not match psa_se_key_data_storage_t" ); + static_assert( sizeof( slot->attr.bits ) == sizeof( data.bits ), + "Bit-size size does not match psa_se_key_data_storage_t" ); +#endif + memcpy( &data.slot_number, &slot->data.se.slot_number, + sizeof( slot->data.se.slot_number ) ); + memcpy( &data.bits, &slot->attr.bits, + sizeof( slot->attr.bits ) ); + status = psa_save_persistent_key( &slot->attr, + (uint8_t*) &data, + sizeof( data ) ); } else #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ { size_t buffer_size = - PSA_KEY_EXPORT_MAX_SIZE( slot->type, - psa_get_key_bits( &attributes ) ); + PSA_KEY_EXPORT_MAX_SIZE( slot->attr.type, + slot->attr.bits ); uint8_t *buffer = mbedtls_calloc( 1, buffer_size ); size_t length = 0; if( buffer == NULL && buffer_size != 0 ) @@ -1562,7 +1620,8 @@ static psa_status_t psa_finish_key_creation( buffer, buffer_size, &length, 0 ); if( status == PSA_SUCCESS ) - status = psa_save_persistent_key( &attributes, buffer, length ); + status = psa_save_persistent_key( &slot->attr, + buffer, length ); if( buffer_size != 0 ) mbedtls_platform_zeroize( buffer, buffer_size ); @@ -1577,7 +1636,7 @@ static psa_status_t psa_finish_key_creation( status = psa_save_se_persistent_data( driver ); if( status != PSA_SUCCESS ) { - psa_destroy_persistent_key( slot->persistent_storage_id ); + psa_destroy_persistent_key( slot->attr.id ); return( status ); } status = psa_crypto_stop_transaction( ); @@ -1624,20 +1683,29 @@ static void psa_fail_key_creation( psa_key_slot_t *slot, psa_wipe_key_slot( slot ); } -static psa_status_t psa_check_key_slot_attributes( +/** Validate optional attributes during key creation. + * + * Some key attributes are optional during key creation. If they are + * specified in the attributes structure, check that they are consistent + * with the data in the slot. + * + * This function should be called near the end of key creation, after + * the slot in memory is fully populated but before saving persistent data. + */ +static psa_status_t psa_validate_optional_attributes( const psa_key_slot_t *slot, const psa_key_attributes_t *attributes ) { - if( attributes->type != 0 ) + if( attributes->core.type != 0 ) { - if( attributes->type != slot->type ) + if( attributes->core.type != slot->attr.type ) return( PSA_ERROR_INVALID_ARGUMENT ); } if( attributes->domain_parameters_size != 0 ) { #if defined(MBEDTLS_RSA_C) - if( PSA_KEY_TYPE_IS_RSA( slot->type ) ) + if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) { mbedtls_mpi actual, required; int ret; @@ -1667,9 +1735,9 @@ static psa_status_t psa_check_key_slot_attributes( } } - if( attributes->bits != 0 ) + if( attributes->core.bits != 0 ) { - if( attributes->bits != psa_get_key_slot_bits( slot ) ) + if( attributes->core.bits != slot->attr.bits ) return( PSA_ERROR_INVALID_ARGUMENT ); } @@ -1693,6 +1761,7 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes, if( driver != NULL ) { const psa_drv_se_t *drv = psa_get_se_driver_methods( driver ); + size_t bits; if( drv->key_management == NULL || drv->key_management->p_import == NULL ) { @@ -1702,9 +1771,18 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes, status = drv->key_management->p_import( psa_get_se_driver_context( driver ), slot->data.se.slot_number, - slot->lifetime, slot->type, slot->policy.alg, slot->policy.usage, + slot->attr.lifetime, slot->attr.type, + slot->attr.policy.alg, slot->attr.policy.usage, data, data_length, - &slot->data.se.bits ); + &bits ); + if( status != PSA_SUCCESS ) + goto exit; + if( bits > PSA_MAX_KEY_BITS ) + { + status = PSA_ERROR_NOT_SUPPORTED; + goto exit; + } + slot->attr.bits = (psa_key_bits_t) bits; } else #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ @@ -1713,7 +1791,7 @@ psa_status_t psa_import_key( const psa_key_attributes_t *attributes, if( status != PSA_SUCCESS ) goto exit; } - status = psa_check_key_slot_attributes( slot, attributes ); + status = psa_validate_optional_attributes( slot, attributes ); if( status != PSA_SUCCESS ) goto exit; @@ -1735,7 +1813,7 @@ static psa_status_t psa_copy_key_material( const psa_key_slot_t *source, size_t buffer_size = 0; size_t length; - buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->type, + buffer_size = PSA_KEY_EXPORT_MAX_SIZE( source->attr.type, psa_get_key_slot_bits( source ) ); buffer = mbedtls_calloc( 1, buffer_size ); if( buffer == NULL && buffer_size != 0 ) @@ -1743,7 +1821,7 @@ static psa_status_t psa_copy_key_material( const psa_key_slot_t *source, status = psa_internal_export_key( source, buffer, buffer_size, &length, 0 ); if( status != PSA_SUCCESS ) goto exit; - target->type = source->type; + target->attr.type = source->attr.type; status = psa_import_key_into_slot( target, buffer, length ); exit: @@ -1768,12 +1846,13 @@ psa_status_t psa_copy_key( psa_key_handle_t source_handle, if( status != PSA_SUCCESS ) goto exit; - status = psa_check_key_slot_attributes( source_slot, specified_attributes ); + status = psa_validate_optional_attributes( source_slot, + specified_attributes ); if( status != PSA_SUCCESS ) goto exit; - status = psa_restrict_key_policy( &actual_attributes.policy, - &source_slot->policy ); + status = psa_restrict_key_policy( &actual_attributes.core.policy, + &source_slot->attr.policy ); if( status != PSA_SUCCESS ) goto exit; @@ -2563,7 +2642,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, { const mbedtls_cipher_info_t *cipher_info = mbedtls_cipher_info_from_psa( full_length_alg, - slot->type, key_bits, NULL ); + slot->attr.type, key_bits, NULL ); int ret; if( cipher_info == NULL ) { @@ -2595,7 +2674,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, goto exit; } - if( slot->type != PSA_KEY_TYPE_HMAC ) + if( slot->attr.type != PSA_KEY_TYPE_HMAC ) { status = PSA_ERROR_INVALID_ARGUMENT; goto exit; @@ -3135,14 +3214,14 @@ psa_status_t psa_asymmetric_sign( psa_key_handle_t handle, status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_SIGN, alg ); if( status != PSA_SUCCESS ) goto exit; - if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->type ) ) + if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) { status = PSA_ERROR_INVALID_ARGUMENT; goto exit; } #if defined(MBEDTLS_RSA_C) - if( slot->type == PSA_KEY_TYPE_RSA_KEY_PAIR ) + if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR ) { status = psa_rsa_sign( slot->data.rsa, alg, @@ -3153,7 +3232,7 @@ psa_status_t psa_asymmetric_sign( psa_key_handle_t handle, else #endif /* defined(MBEDTLS_RSA_C) */ #if defined(MBEDTLS_ECP_C) - if( PSA_KEY_TYPE_IS_ECC( slot->type ) ) + if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) ) { #if defined(MBEDTLS_ECDSA_C) if( @@ -3210,7 +3289,7 @@ psa_status_t psa_asymmetric_verify( psa_key_handle_t handle, return( status ); #if defined(MBEDTLS_RSA_C) - if( PSA_KEY_TYPE_IS_RSA( slot->type ) ) + if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) { return( psa_rsa_verify( slot->data.rsa, alg, @@ -3220,7 +3299,7 @@ psa_status_t psa_asymmetric_verify( psa_key_handle_t handle, else #endif /* defined(MBEDTLS_RSA_C) */ #if defined(MBEDTLS_ECP_C) - if( PSA_KEY_TYPE_IS_ECC( slot->type ) ) + if( PSA_KEY_TYPE_IS_ECC( slot->attr.type ) ) { #if defined(MBEDTLS_ECDSA_C) if( PSA_ALG_IS_ECDSA( alg ) ) @@ -3278,12 +3357,12 @@ psa_status_t psa_asymmetric_encrypt( psa_key_handle_t handle, status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); - if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->type ) || - PSA_KEY_TYPE_IS_KEY_PAIR( slot->type ) ) ) + if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) || + PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) ) return( PSA_ERROR_INVALID_ARGUMENT ); #if defined(MBEDTLS_RSA_C) - if( PSA_KEY_TYPE_IS_RSA( slot->type ) ) + if( PSA_KEY_TYPE_IS_RSA( slot->attr.type ) ) { mbedtls_rsa_context *rsa = slot->data.rsa; int ret; @@ -3358,11 +3437,11 @@ psa_status_t psa_asymmetric_decrypt( psa_key_handle_t handle, status = psa_get_transparent_key( handle, &slot, PSA_KEY_USAGE_DECRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); - if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->type ) ) + if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) return( PSA_ERROR_INVALID_ARGUMENT ); #if defined(MBEDTLS_RSA_C) - if( slot->type == PSA_KEY_TYPE_RSA_KEY_PAIR ) + if( slot->attr.type == PSA_KEY_TYPE_RSA_KEY_PAIR ) { mbedtls_rsa_context *rsa = slot->data.rsa; int ret; @@ -3469,7 +3548,7 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, goto exit; key_bits = psa_get_key_slot_bits( slot ); - cipher_info = mbedtls_cipher_info_from_psa( alg, slot->type, key_bits, NULL ); + cipher_info = mbedtls_cipher_info_from_psa( alg, slot->attr.type, key_bits, NULL ); if( cipher_info == NULL ) { status = PSA_ERROR_NOT_SUPPORTED; @@ -3481,7 +3560,7 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, goto exit; #if defined(MBEDTLS_DES_C) - if( slot->type == PSA_KEY_TYPE_DES && key_bits == 128 ) + if( slot->attr.type == PSA_KEY_TYPE_DES && key_bits == 128 ) { /* Two-key Triple-DES is 3-key Triple-DES with K1=K3 */ uint8_t keys[24]; @@ -3523,10 +3602,10 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, operation->key_set = 1; operation->block_size = ( PSA_ALG_IS_STREAM_CIPHER( alg ) ? 1 : - PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ) ); + PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ) ); if( alg & PSA_ALG_CIPHER_FROM_BLOCK_FLAG ) { - operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->type ); + operation->iv_size = PSA_BLOCK_CIPHER_BLOCK_SIZE( slot->attr.type ); } #if defined(MBEDTLS_CHACHA20_C) else @@ -3808,7 +3887,7 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, key_bits = psa_get_key_slot_bits( operation->slot ); operation->cipher_info = - mbedtls_cipher_info_from_psa( alg, operation->slot->type, key_bits, + mbedtls_cipher_info_from_psa( alg, operation->slot->attr.type, key_bits, &cipher_id ); if( operation->cipher_info == NULL ) return( PSA_ERROR_NOT_SUPPORTED ); @@ -3822,7 +3901,7 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16. * The call to mbedtls_ccm_encrypt_and_tag or * mbedtls_ccm_auth_decrypt will validate the tag length. */ - if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 ) + if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 ) return( PSA_ERROR_INVALID_ARGUMENT ); mbedtls_ccm_init( &operation->ctx.ccm ); status = mbedtls_to_psa_error( @@ -3841,7 +3920,7 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16. * The call to mbedtls_gcm_crypt_and_tag or * mbedtls_gcm_auth_decrypt will validate the tag length. */ - if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->type ) != 16 ) + if( PSA_BLOCK_CIPHER_BLOCK_SIZE( operation->slot->attr.type ) != 16 ) return( PSA_ERROR_INVALID_ARGUMENT ); mbedtls_gcm_init( &operation->ctx.gcm ); status = mbedtls_to_psa_error( @@ -4666,7 +4745,7 @@ static psa_status_t psa_generate_derived_key_internal( size_t bytes = PSA_BITS_TO_BYTES( bits ); psa_status_t status; - if( ! key_type_is_raw_bytes( slot->type ) ) + if( ! key_type_is_raw_bytes( slot->attr.type ) ) return( PSA_ERROR_INVALID_ARGUMENT ); if( bits % 8 != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); @@ -4678,7 +4757,7 @@ static psa_status_t psa_generate_derived_key_internal( if( status != PSA_SUCCESS ) goto exit; #if defined(MBEDTLS_DES_C) - if( slot->type == PSA_KEY_TYPE_DES ) + if( slot->attr.type == PSA_KEY_TYPE_DES ) psa_des_set_key_parity( data, bytes ); #endif /* MBEDTLS_DES_C */ status = psa_import_key_into_slot( slot, data, bytes ); @@ -4706,7 +4785,7 @@ psa_status_t psa_key_derivation_output_key( const psa_key_attributes_t *attribut if( status == PSA_SUCCESS ) { status = psa_generate_derived_key_internal( slot, - attributes->bits, + attributes->core.bits, operation ); } if( status == PSA_SUCCESS ) @@ -4987,7 +5066,7 @@ psa_status_t psa_key_derivation( psa_key_derivation_operation_t *operation, if( status != PSA_SUCCESS ) return( status ); - if( slot->type != PSA_KEY_TYPE_DERIVE ) + if( slot->attr.type != PSA_KEY_TYPE_DERIVE ) return( PSA_ERROR_INVALID_ARGUMENT ); status = psa_key_derivation_internal( operation, @@ -5362,7 +5441,7 @@ psa_status_t psa_key_derivation_input_key( operation->alg ); if( status != PSA_SUCCESS ) return( status ); - if( slot->type != PSA_KEY_TYPE_DERIVE ) + if( slot->attr.type != PSA_KEY_TYPE_DERIVE ) return( PSA_ERROR_INVALID_ARGUMENT ); /* Don't allow a key to be used as an input that is usually public. * This is debatable. It's ok from a cryptographic perspective to @@ -5442,7 +5521,7 @@ static psa_status_t psa_key_agreement_raw_internal( psa_algorithm_t alg, { #if defined(MBEDTLS_ECDH_C) case PSA_ALG_ECDH: - if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->type ) ) + if( ! PSA_KEY_TYPE_IS_ECC_KEY_PAIR( private_key->attr.type ) ) return( PSA_ERROR_INVALID_ARGUMENT ); return( psa_key_agreement_ecdh( peer_key, peer_key_length, private_key->data.ecp, @@ -5571,6 +5650,17 @@ psa_status_t psa_generate_random( uint8_t *output, int ret; GUARD_MODULE_INITIALIZED; + while( output_size > MBEDTLS_CTR_DRBG_MAX_REQUEST ) + { + ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, + output, + MBEDTLS_CTR_DRBG_MAX_REQUEST ); + if( ret != 0 ) + return( mbedtls_to_psa_error( ret ) ); + output += MBEDTLS_CTR_DRBG_MAX_REQUEST; + output_size -= MBEDTLS_CTR_DRBG_MAX_REQUEST; + } + ret = mbedtls_ctr_drbg_random( &global_data.ctr_drbg, output, output_size ); return( mbedtls_to_psa_error( ret ) ); } @@ -5625,7 +5715,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_key_type_t type = slot->type; + psa_key_type_t type = slot->attr.type; if( domain_parameters == NULL && domain_parameters_size != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); @@ -5639,10 +5729,7 @@ static psa_status_t psa_generate_key_internal( status = psa_generate_random( slot->data.raw.data, slot->data.raw.bytes ); if( status != PSA_SUCCESS ) - { - mbedtls_free( slot->data.raw.data ); return( status ); - } #if defined(MBEDTLS_DES_C) if( type == PSA_KEY_TYPE_DES ) psa_des_set_key_parity( slot->data.raw.data, @@ -5744,7 +5831,7 @@ psa_status_t psa_generate_key( const psa_key_attributes_t *attributes, if( status == PSA_SUCCESS ) { status = psa_generate_key_internal( - slot, attributes->bits, + slot, attributes->core.bits, attributes->domain_parameters, attributes->domain_parameters_size ); } if( status == PSA_SUCCESS ) diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 86584907c..fbfb6daef 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -39,11 +39,7 @@ */ typedef struct { - psa_key_type_t type; - psa_key_policy_t policy; - psa_key_lifetime_t lifetime; - psa_key_file_id_t persistent_storage_id; - unsigned allocated : 1; + psa_core_key_attributes_t attr; union { /* Raw-data key (key_type_is_raw_bytes() in psa_crypto.c) */ @@ -64,11 +60,74 @@ typedef struct struct se { psa_key_slot_number_t slot_number; - size_t bits; } se; } data; } psa_key_slot_t; +/** Test whether a key slot is occupied. + * + * A key slot is occupied iff the key type is nonzero. This works because + * no valid key can have 0 as its key type. + * + * \param[in] slot The key slot to test. + * + * \return 1 if the slot is occupied, 0 otherwise. + */ +static inline int psa_is_key_slot_occupied( const psa_key_slot_t *slot ) +{ + return( slot->attr.type != 0 ); +} + +/** Retrieve flags from psa_key_slot_t::attr::core::flags. + * + * \param[in] slot The key slot to query. + * \param mask The mask of bits to extract. + * + * \return The key attribute flags in the given slot, + * bitwise-anded with \p mask. + */ +static inline uint16_t psa_key_slot_get_flags( const psa_key_slot_t *slot, + uint16_t mask ) +{ + return( slot->attr.flags & mask ); +} + +/** Set flags in psa_key_slot_t::attr::core::flags. + * + * \param[in,out] slot The key slot to modify. + * \param mask The mask of bits to modify. + * \param value The new value of the selected bits. + */ +static inline void psa_key_slot_set_flags( psa_key_slot_t *slot, + uint16_t mask, + uint16_t value ) +{ + slot->attr.flags = ( ( ~mask & slot->attr.flags ) | + ( mask & value ) ); +} + +/** Turn on flags in psa_key_slot_t::attr::core::flags. + * + * \param[in,out] slot The key slot to modify. + * \param mask The mask of bits to set. + */ +static inline void psa_key_slot_set_bits_in_flags( psa_key_slot_t *slot, + uint16_t mask ) +{ + slot->attr.flags |= mask; +} + +/** Turn off flags in psa_key_slot_t::attr::core::flags. + * + * \param[in,out] slot The key slot to modify. + * \param mask The mask of bits to clear. + */ +static inline void psa_key_slot_clear_bits( psa_key_slot_t *slot, + uint16_t mask ) +{ + slot->attr.flags &= ~mask; +} + /** Completely wipe a slot in memory, including its policy. * * Persistent storage is not affected. diff --git a/library/psa_crypto_se.c b/library/psa_crypto_se.c index aece47d01..58b0f3807 100644 --- a/library/psa_crypto_se.c +++ b/library/psa_crypto_se.c @@ -198,7 +198,7 @@ psa_status_t psa_find_se_slot_for_key( psa_drv_se_allocate_key_t p_allocate = NULL; /* If the lifetime is wrong, it's a bug in the library. */ - if( driver->lifetime != attributes->lifetime ) + if( driver->lifetime != psa_get_key_lifetime( attributes ) ) return( PSA_ERROR_CORRUPTION_DETECTED ); /* If the driver doesn't support key creation in any way, give up now. */ diff --git a/library/psa_crypto_se.h b/library/psa_crypto_se.h index 08e658cdd..378c78ffe 100644 --- a/library/psa_crypto_se.h +++ b/library/psa_crypto_se.h @@ -171,4 +171,13 @@ psa_status_t psa_save_se_persistent_data( */ psa_status_t psa_destroy_se_persistent_data( psa_key_lifetime_t lifetime ); + +/** The storage representation of a key whose data is in a secure element. + */ +typedef struct +{ + uint8_t slot_number[sizeof( psa_key_slot_number_t )]; + uint8_t bits[sizeof( psa_key_bits_t )]; +} psa_se_key_data_storage_t; + #endif /* PSA_CRYPTO_SE_H */ diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index e63dcdae6..073400988 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -33,6 +33,9 @@ #include "psa_crypto_core.h" #include "psa_crypto_slot_management.h" #include "psa_crypto_storage.h" +#if defined(MBEDTLS_PSA_CRYPTO_SE_C) +#include "psa_crypto_se.h" +#endif #include #include @@ -71,8 +74,8 @@ psa_status_t psa_get_key_slot( psa_key_handle_t handle, return( PSA_ERROR_INVALID_HANDLE ); slot = &global_data.key_slots[handle - 1]; - /* If the slot hasn't been allocated, the handle is invalid. */ - if( ! slot->allocated ) + /* If the slot isn't occupied, the handle is invalid. */ + if( ! psa_is_key_slot_occupied( slot ) ) return( PSA_ERROR_INVALID_HANDLE ); *p_slot = slot; @@ -108,48 +111,44 @@ psa_status_t psa_internal_allocate_key_slot( psa_key_handle_t *handle, for( *handle = PSA_KEY_SLOT_COUNT; *handle != 0; --( *handle ) ) { *p_slot = &global_data.key_slots[*handle - 1]; - if( ! ( *p_slot )->allocated ) - { - ( *p_slot )->allocated = 1; + if( ! psa_is_key_slot_occupied( *p_slot ) ) return( PSA_SUCCESS ); - } } *p_slot = NULL; return( PSA_ERROR_INSUFFICIENT_MEMORY ); } #if defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) -static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *p_slot ) +static psa_status_t psa_load_persistent_key_into_slot( psa_key_slot_t *slot ) { psa_status_t status = PSA_SUCCESS; uint8_t *key_data = NULL; size_t key_data_length = 0; - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_set_key_id( &attributes, p_slot->persistent_storage_id ); - status = psa_load_persistent_key( &attributes, + status = psa_load_persistent_key( &slot->attr, &key_data, &key_data_length ); if( status != PSA_SUCCESS ) goto exit; - p_slot->lifetime = psa_get_key_lifetime( &attributes ); - p_slot->type = psa_get_key_type( &attributes ); - p_slot->policy = attributes.policy; #if defined(MBEDTLS_PSA_CRYPTO_SE_C) - if( psa_key_lifetime_is_external( p_slot->lifetime ) ) + if( psa_key_lifetime_is_external( slot->attr.lifetime ) ) { - if( key_data_length != sizeof( p_slot->data.se ) ) + psa_se_key_data_storage_t *data; + if( key_data_length != sizeof( *data ) ) { status = PSA_ERROR_STORAGE_FAILURE; goto exit; } - memcpy( &p_slot->data.se, key_data, sizeof( p_slot->data.se ) ); + data = (psa_se_key_data_storage_t *) key_data; + memcpy( &slot->data.se.slot_number, &data->slot_number, + sizeof( slot->data.se.slot_number ) ); + memcpy( &slot->attr.bits, &data->bits, + sizeof( slot->attr.bits ) ); } else #endif /* MBEDTLS_PSA_CRYPTO_SE_C */ { - status = psa_import_key_into_slot( p_slot, - key_data, key_data_length ); + status = psa_import_key_into_slot( slot, key_data, key_data_length ); } exit: @@ -233,8 +232,8 @@ psa_status_t psa_open_key( psa_key_file_id_t id, psa_key_handle_t *handle ) if( status != PSA_SUCCESS ) return( status ); - slot->lifetime = PSA_KEY_LIFETIME_PERSISTENT; - slot->persistent_storage_id = id; + slot->attr.lifetime = PSA_KEY_LIFETIME_PERSISTENT; + slot->attr.id = id; status = psa_load_persistent_key_into_slot( slot ); if( status != PSA_SUCCESS ) @@ -269,28 +268,25 @@ void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats ) memset( stats, 0, sizeof( *stats ) ); for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ ) { - psa_key_slot_t *slot = &global_data.key_slots[key - 1]; - if( slot->type == PSA_KEY_TYPE_NONE ) + const psa_key_slot_t *slot = &global_data.key_slots[key - 1]; + if( ! psa_is_key_slot_occupied( slot ) ) { - if( slot->allocated ) - ++stats->half_filled_slots; - else - ++stats->empty_slots; + ++stats->empty_slots; continue; } - if( slot->lifetime == PSA_KEY_LIFETIME_VOLATILE ) + if( slot->attr.lifetime == PSA_KEY_LIFETIME_VOLATILE ) ++stats->volatile_slots; - else if( slot->lifetime == PSA_KEY_LIFETIME_PERSISTENT ) + else if( slot->attr.lifetime == PSA_KEY_LIFETIME_PERSISTENT ) { ++stats->persistent_slots; - if( slot->persistent_storage_id > stats->max_open_internal_key_id ) - stats->max_open_internal_key_id = slot->persistent_storage_id; + if( slot->attr.id > stats->max_open_internal_key_id ) + stats->max_open_internal_key_id = slot->attr.id; } else { ++stats->external_slots; - if( slot->persistent_storage_id > stats->max_open_external_key_id ) - stats->max_open_external_key_id = slot->persistent_storage_id; + if( slot->attr.id > stats->max_open_external_key_id ) + stats->max_open_external_key_id = slot->attr.id; } } } diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index 049520d4b..cde590fc5 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -58,13 +58,13 @@ psa_status_t psa_initialize_key_slots( void ); * This does not affect persistent storage. */ void psa_wipe_all_key_slots( void ); -/** Find a free key slot and mark it as in use. +/** Find a free key slot. + * + * This function returns a key slot that is available for use and is in its + * ground state (all-bits-zero). * * \param[out] handle On success, a slot number that can be used as a - * handle to the slot. The selected slot was not - * in use before. This function marks it as in use - * and otherwise leaves it in a freshly-initialized - * state. + * handle to the slot. * \param[out] p_slot On success, a pointer to the slot. * * \retval #PSA_SUCCESS diff --git a/library/psa_crypto_storage.c b/library/psa_crypto_storage.c index b8569beb8..55fd65af9 100644 --- a/library/psa_crypto_storage.c +++ b/library/psa_crypto_storage.c @@ -264,7 +264,7 @@ typedef struct { void psa_format_key_data_for_storage( const uint8_t *data, const size_t data_length, - const psa_key_attributes_t *attributes, + const psa_core_key_attributes_t *attr, uint8_t *storage_data ) { psa_persistent_key_storage_format *storage_format = @@ -272,11 +272,11 @@ void psa_format_key_data_for_storage( const uint8_t *data, memcpy( storage_format->magic, PSA_KEY_STORAGE_MAGIC_HEADER, PSA_KEY_STORAGE_MAGIC_HEADER_LENGTH ); PUT_UINT32_LE( 0, storage_format->version, 0 ); - PUT_UINT32_LE( psa_get_key_lifetime( attributes ), storage_format->lifetime, 0 ); - PUT_UINT32_LE( psa_get_key_type( attributes ), storage_format->type, 0 ); - PUT_UINT32_LE( psa_get_key_usage_flags( attributes ), storage_format->policy, 0 ); - PUT_UINT32_LE( psa_get_key_algorithm( attributes ), storage_format->policy, sizeof( uint32_t ) ); - PUT_UINT32_LE( psa_get_key_enrollment_algorithm( attributes ), storage_format->policy, 2 * sizeof( uint32_t ) ); + PUT_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 ); + PUT_UINT32_LE( attr->type, storage_format->type, 0 ); + PUT_UINT32_LE( attr->policy.usage, storage_format->policy, 0 ); + PUT_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) ); + PUT_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) ); PUT_UINT32_LE( data_length, storage_format->data_len, 0 ); memcpy( storage_format->key_data, data, data_length ); } @@ -293,7 +293,7 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data, size_t storage_data_length, uint8_t **key_data, size_t *key_data_length, - psa_key_attributes_t *attributes ) + psa_core_key_attributes_t *attr ) { psa_status_t status; const psa_persistent_key_storage_format *storage_format = @@ -328,16 +328,16 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data, memcpy( *key_data, storage_format->key_data, *key_data_length ); } - GET_UINT32_LE( attributes->lifetime, storage_format->lifetime, 0 ); - GET_UINT32_LE( attributes->type, storage_format->type, 0 ); - GET_UINT32_LE( attributes->policy.usage, storage_format->policy, 0 ); - GET_UINT32_LE( attributes->policy.alg, storage_format->policy, sizeof( uint32_t ) ); - GET_UINT32_LE( attributes->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) ); + GET_UINT32_LE( attr->lifetime, storage_format->lifetime, 0 ); + GET_UINT32_LE( attr->type, storage_format->type, 0 ); + GET_UINT32_LE( attr->policy.usage, storage_format->policy, 0 ); + GET_UINT32_LE( attr->policy.alg, storage_format->policy, sizeof( uint32_t ) ); + GET_UINT32_LE( attr->policy.alg2, storage_format->policy, 2 * sizeof( uint32_t ) ); return( PSA_SUCCESS ); } -psa_status_t psa_save_persistent_key( const psa_key_attributes_t *attributes, +psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr, const uint8_t *data, const size_t data_length ) { @@ -353,10 +353,9 @@ psa_status_t psa_save_persistent_key( const psa_key_attributes_t *attributes, if( storage_data == NULL ) return( PSA_ERROR_INSUFFICIENT_MEMORY ); - psa_format_key_data_for_storage( data, data_length, attributes, - storage_data ); + psa_format_key_data_for_storage( data, data_length, attr, storage_data ); - status = psa_crypto_storage_store( psa_get_key_id( attributes ), + status = psa_crypto_storage_store( attr->id, storage_data, storage_data_length ); mbedtls_free( storage_data ); @@ -373,14 +372,14 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length ) mbedtls_free( key_data ); } -psa_status_t psa_load_persistent_key( psa_key_attributes_t *attributes, +psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr, uint8_t **data, size_t *data_length ) { psa_status_t status = PSA_SUCCESS; uint8_t *loaded_data; size_t storage_data_length = 0; - psa_key_id_t key = psa_get_key_id( attributes ); + psa_key_id_t key = attr->id; status = psa_crypto_storage_get_data_length( key, &storage_data_length ); if( status != PSA_SUCCESS ) @@ -396,7 +395,7 @@ psa_status_t psa_load_persistent_key( psa_key_attributes_t *attributes, goto exit; status = psa_parse_key_data_from_storage( loaded_data, storage_data_length, - data, data_length, attributes ); + data, data_length, attr ); exit: mbedtls_free( loaded_data ); diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h index 8fe20ac32..1b7dbd67c 100644 --- a/library/psa_crypto_storage.h +++ b/library/psa_crypto_storage.h @@ -35,9 +35,14 @@ extern "C" { #include #include -/* Limit the maximum key size to 30kB (just in case someone tries to - * inadvertently store an obscene amount of data) */ -#define PSA_CRYPTO_MAX_STORAGE_SIZE ( 30 * 1024 ) +/* Limit the maximum key size in storage. This should have no effect + * since the key size is limited in memory. */ +#define PSA_CRYPTO_MAX_STORAGE_SIZE ( PSA_BITS_TO_BYTES( PSA_MAX_KEY_BITS ) ) +/* Sanity check: a file size must fit in 32 bits. Allow a generous + * 64kB of metadata. */ +#if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000 +#error PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000 +#endif /** The maximum permitted persistent slot number. * @@ -83,7 +88,7 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key ); * already occupied non-persistent key, as well as validating the key data. * * - * \param[in] attributes The attributes of the key to save. + * \param[in] attr The attributes of the key to save. * The key identifier field in the attributes * determines the key's location. * \param[in] data Buffer containing the key data. @@ -95,7 +100,7 @@ int psa_is_key_present_in_storage( const psa_key_file_id_t key ); * \retval PSA_ERROR_STORAGE_FAILURE * \retval PSA_ERROR_ALREADY_EXISTS */ -psa_status_t psa_save_persistent_key( const psa_key_attributes_t *attributes, +psa_status_t psa_save_persistent_key( const psa_core_key_attributes_t *attr, const uint8_t *data, const size_t data_length ); @@ -111,8 +116,7 @@ psa_status_t psa_save_persistent_key( const psa_key_attributes_t *attributes, * this function to zeroize and free this buffer, regardless of whether this * function succeeds or fails. * - * \param[in,out] attributes - * On input, the key identifier field identifies + * \param[in,out] attr On input, the key identifier field identifies * the key to load. Other fields are ignored. * On success, the attribute structure contains * the key metadata that was loaded from storage. @@ -124,7 +128,7 @@ psa_status_t psa_save_persistent_key( const psa_key_attributes_t *attributes, * \retval PSA_ERROR_STORAGE_FAILURE * \retval PSA_ERROR_DOES_NOT_EXIST */ -psa_status_t psa_load_persistent_key( psa_key_attributes_t *attributes, +psa_status_t psa_load_persistent_key( psa_core_key_attributes_t *attr, uint8_t **data, size_t *data_length ); @@ -158,13 +162,13 @@ void psa_free_persistent_key_data( uint8_t *key_data, size_t key_data_length ); * * \param[in] data Buffer containing the key data. * \param data_length Length of the key data buffer. - * \param[in] attributes The attributes of the key. + * \param[in] attr The core attributes of the key. * \param[out] storage_data Output buffer for the formatted data. * */ void psa_format_key_data_for_storage( const uint8_t *data, const size_t data_length, - const psa_key_attributes_t *attributes, + const psa_core_key_attributes_t *attr, uint8_t *storage_data ); /** @@ -176,7 +180,7 @@ void psa_format_key_data_for_storage( const uint8_t *data, * containing the key data. This must be freed * using psa_free_persistent_key_data() * \param[out] key_data_length Length of the key data buffer - * \param[out] attributes On success, the attribute structure is filled + * \param[out] attr On success, the attribute structure is filled * with the loaded key metadata. * * \retval PSA_SUCCESS @@ -188,7 +192,7 @@ psa_status_t psa_parse_key_data_from_storage( const uint8_t *storage_data, size_t storage_data_length, uint8_t **key_data, size_t *key_data_length, - psa_key_attributes_t *attributes ); + psa_core_key_attributes_t *attr ); #if defined(MBEDTLS_PSA_CRYPTO_SE_C) /** This symbol is defined if transaction support is required. */ diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 53f842201..b04984024 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -52,9 +52,18 @@ invalid_handle:1 PSA invalid handle (largest plausible handle) invalid_handle:-1 +PSA import: bad usage flag +import_with_policy:PSA_KEY_TYPE_RAW_DATA:0x40000000:0:PSA_ERROR_INVALID_ARGUMENT + +PSA import: invalid type (0) +import_with_policy:PSA_KEY_TYPE_NONE:0:0:PSA_ERROR_NOT_SUPPORTED + +PSA import: invalid type (PSA_KEY_TYPE_CATEGORY_MASK) +import_with_policy:PSA_KEY_TYPE_CATEGORY_MASK:0:0:PSA_ERROR_NOT_SUPPORTED + PSA import AES: bad key size depends_on:MBEDTLS_AES_C -import:"0123456789abcdef":PSA_KEY_TYPE_AES:0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"0123456789abcdef":PSA_KEY_TYPE_AES:0:PSA_ERROR_INVALID_ARGUMENT PSA import/export RSA public key: good, 1024-bit depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C @@ -110,19 +119,19 @@ import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa24 PSA import RSA keypair: truncated depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C -import:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT PSA import RSA keypair: public key depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C -import:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"30818902818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc30203010001":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT PSA import RSA public key: key pair depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C -import:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa2470b541ee1feb0b12d25c79711531249e1129628042dbbb6c120d1443524ef4c0e6e1d8956eeb2077af12349ddeee54483bc06c2c61948cd02b202e796aebd94d3a7cbf859c2c1819c324cb82b9cd34ede263a2abffe4733f077869e8660f7d6834da53d690ef7985f6bc3020301000102818100874bf0ffc2f2a71d14671ddd0171c954d7fdbf50281e4f6d99ea0e1ebcf82faa58e7b595ffb293d1abe17f110b37c48cc0f36c37e84d876621d327f64bbe08457d3ec4098ba2fa0a319fba411c2841ed7be83196a8cdf9daa5d00694bc335fc4c32217fe0488bce9cb7202e59468b1ead119000477db2ca797fac19eda3f58c1024100e2ab760841bb9d30a81d222de1eb7381d82214407f1b975cbbfe4e1a9467fd98adbd78f607836ca5be1928b9d160d97fd45c12d6b52e2c9871a174c66b488113024100c5ab27602159ae7d6f20c3c2ee851e46dc112e689e28d5fcbbf990a99ef8a90b8bb44fd36467e7fc1789ceb663abda338652c3c73f111774902e840565927091024100b6cdbd354f7df579a63b48b3643e353b84898777b48b15f94e0bfc0567a6ae5911d57ad6409cf7647bf96264e9bd87eb95e263b7110b9a1f9f94acced0fafa4d024071195eec37e8d257decfc672b07ae639f10cbb9b0c739d0c809968d644a94e3fd6ed9287077a14583f379058f76a8aecd43c62dc8c0f41766650d725275ac4a1024100bb32d133edc2e048d463388b7be9cb4be29f4b6250be603e70e3647501c97ddde20a4e71be95fd5e71784e25aca4baf25be5738aae59bbfe1c997781447a2b":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_INVALID_ARGUMENT PSA import RSA keypair: valid key but EC depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C -import:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_INVALID_ARGUMENT PSA import/export-public RSA public key: good, 1024-bit depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C @@ -150,19 +159,19 @@ import_export:"3082025802010002818000cde684f1aee96917b89c8a0a72523cfce4686ed5a5f PSA import RSA public key: 1022-bit (not supported) depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C -import:"30818802818036e4b95f847dcd7a91b0972b7ba096e040ec04e42d59f733029fb2600b8ae9e4fd8ea76f3d7ec576288102285b612db7abc53770006046fef321172a6ad84053710d48528a8d51b6481db53c09e1524d6704b58bd30313016535eefe9bcff89eb599608daaa0a72ab7720af31486b51020421fdd3c6974cc445a78dd134450230203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_NOT_SUPPORTED +import_with_data:"30818802818036e4b95f847dcd7a91b0972b7ba096e040ec04e42d59f733029fb2600b8ae9e4fd8ea76f3d7ec576288102285b612db7abc53770006046fef321172a6ad84053710d48528a8d51b6481db53c09e1524d6704b58bd30313016535eefe9bcff89eb599608daaa0a72ab7720af31486b51020421fdd3c6974cc445a78dd134450230203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_NOT_SUPPORTED PSA import RSA keypair: 1022-bit (not supported) depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C -import:"3082025802010002818036e4b95f847dcd7a91b0972b7ba096e040ec04e42d59f733029fb2600b8ae9e4fd8ea76f3d7ec576288102285b612db7abc53770006046fef321172a6ad84053710d48528a8d51b6481db53c09e1524d6704b58bd30313016535eefe9bcff89eb599608daaa0a72ab7720af31486b51020421fdd3c6974cc445a78dd1344502302030100010281800ad9700e01e8bf68ff4c90c4465dfa13fea0e76295d817349ccb257d382acf89b3d7b31e18606af4ac92baf3710426fe0b54225ddfa527c31218b3346e03a9cae5395a780ade880b996f4061fad65689393fc8e77f46a4c1a29b0450cdaaef0710e523cd1028abe1653d23f0d5ec805a629bdf1fc4c1c00737760e1714f6b7f102407d5e545484b546bd61972b446a04af0cf17b126a8872b977da5035ca82dd0e4fef1381a6480f60db07628348602f86ba89a271563d9a3fb613b9b39703498f9902407017641093065eed178ff848b5f8a2b502a187511db28549ea7646f3e7b3ea171f4c34c0ecf0566adc4d172c057be077a45fcf8019a36a4588c4de3b8c0a631b02407cc7fccbbae2eb2be80c9c8615b7dfbbd4469907ec13b44274cacd1f69ad38679b2021352e18106131327e54f5579893e6160714bd6fdfe60c30136e45595c51024055250f779f96f94873db82a808c24325e847b6b8212cd81e9ba118a8715ab2f8b96773b310c8477c88b76e609c11cb22569408d4afa4f836b57b85ac09e661fd02400e5fc5df9614c95d77e9bc2df63d48e7a08a0034174f0f745eef4413ee36d929f194557e6990e148b7438e949a41e92bc9d9136c3e6563904151a578a2f4fc1b":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_NOT_SUPPORTED +import_with_data:"3082025802010002818036e4b95f847dcd7a91b0972b7ba096e040ec04e42d59f733029fb2600b8ae9e4fd8ea76f3d7ec576288102285b612db7abc53770006046fef321172a6ad84053710d48528a8d51b6481db53c09e1524d6704b58bd30313016535eefe9bcff89eb599608daaa0a72ab7720af31486b51020421fdd3c6974cc445a78dd1344502302030100010281800ad9700e01e8bf68ff4c90c4465dfa13fea0e76295d817349ccb257d382acf89b3d7b31e18606af4ac92baf3710426fe0b54225ddfa527c31218b3346e03a9cae5395a780ade880b996f4061fad65689393fc8e77f46a4c1a29b0450cdaaef0710e523cd1028abe1653d23f0d5ec805a629bdf1fc4c1c00737760e1714f6b7f102407d5e545484b546bd61972b446a04af0cf17b126a8872b977da5035ca82dd0e4fef1381a6480f60db07628348602f86ba89a271563d9a3fb613b9b39703498f9902407017641093065eed178ff848b5f8a2b502a187511db28549ea7646f3e7b3ea171f4c34c0ecf0566adc4d172c057be077a45fcf8019a36a4588c4de3b8c0a631b02407cc7fccbbae2eb2be80c9c8615b7dfbbd4469907ec13b44274cacd1f69ad38679b2021352e18106131327e54f5579893e6160714bd6fdfe60c30136e45595c51024055250f779f96f94873db82a808c24325e847b6b8212cd81e9ba118a8715ab2f8b96773b310c8477c88b76e609c11cb22569408d4afa4f836b57b85ac09e661fd02400e5fc5df9614c95d77e9bc2df63d48e7a08a0034174f0f745eef4413ee36d929f194557e6990e148b7438e949a41e92bc9d9136c3e6563904151a578a2f4fc1b":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_NOT_SUPPORTED PSA import RSA public key: 1023-bit (not supported) depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C -import:"3081880281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_NOT_SUPPORTED +import_with_data:"3081880281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001":PSA_KEY_TYPE_RSA_PUBLIC_KEY:0:PSA_ERROR_NOT_SUPPORTED PSA import RSA keypair: 1023-bit (not supported) depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_RSA_C -import:"3082025a0201000281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001028180491b277413fb35efe82dace68b544a9dd6aa8917d329731955ec66ec3b0178fcf5a29196e1a6c093bf6c8064b36a8f0d9840a78003d11392754a70a77788975515a1442a6c806cafa2f07fe99cac78a86fa868888d654cec4baf205352cf8255acaa47e2455f23b58c0e5ae43fa297bbffe5b970caa80f71e82084fd35425479024100ef27f3fb2df90ac4910ed95fdde4877d09b0dc4e95079f12a7e2041300a8884a39372a1c79691338cd5c3965bcf3a24f2ce9e10de19d4cb87c7546d60ca0aa0d024073e9e1283475e9ab3075da0b005ca7c7b05e76325f8deb648238831c8353041d594307f784cd527cfee9187b997713d71c0ff98f01beac4d1a85583be52e90e302402f0c801e311c2677274671933f96fee4a56c6adaf6ccaa09c4875d5fd3a8542fadf3e14ffabea62e6d90302688b6b17ebc0a42e1353a79e66d6db102d9371e5d02406731ef3c8607fbf266806590a9cfd3a79a435ee355e2d9906fc6b4236c5f3a288ed178844a7d295512f49ed15b3d82325e4f729478af3262aa9bd083f273d49502410090a32c0e8ca3bcd4c66f092cdc369cd1abb4a05b9a6f0e65e5a51da1d96d5aca8c1525b3f11322c0588062fc8592ebf25b7950f918d39018e82b8acccc8f7e7a":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_NOT_SUPPORTED +import_with_data:"3082025a0201000281806c49704e91f3df44fc99e9b3c0fee5025cc04d09529a1dd05754f2da2751d7a9aa5a79f7070132f2c47b31963e37cd74675f9c93ee7c85a143fefe303e94d1ee0e4d30898d17ab3a229e8457ef21fd179039f748305babe7f134f6d58ce5d721a1a5da98f63503d2466c6a515e53494a41180a91e535bd5b55d4dce2c17419870203010001028180491b277413fb35efe82dace68b544a9dd6aa8917d329731955ec66ec3b0178fcf5a29196e1a6c093bf6c8064b36a8f0d9840a78003d11392754a70a77788975515a1442a6c806cafa2f07fe99cac78a86fa868888d654cec4baf205352cf8255acaa47e2455f23b58c0e5ae43fa297bbffe5b970caa80f71e82084fd35425479024100ef27f3fb2df90ac4910ed95fdde4877d09b0dc4e95079f12a7e2041300a8884a39372a1c79691338cd5c3965bcf3a24f2ce9e10de19d4cb87c7546d60ca0aa0d024073e9e1283475e9ab3075da0b005ca7c7b05e76325f8deb648238831c8353041d594307f784cd527cfee9187b997713d71c0ff98f01beac4d1a85583be52e90e302402f0c801e311c2677274671933f96fee4a56c6adaf6ccaa09c4875d5fd3a8542fadf3e14ffabea62e6d90302688b6b17ebc0a42e1353a79e66d6db102d9371e5d02406731ef3c8607fbf266806590a9cfd3a79a435ee355e2d9906fc6b4236c5f3a288ed178844a7d295512f49ed15b3d82325e4f729478af3262aa9bd083f273d49502410090a32c0e8ca3bcd4c66f092cdc369cd1abb4a05b9a6f0e65e5a51da1d96d5aca8c1525b3f11322c0588062fc8592ebf25b7950f918d39018e82b8acccc8f7e7a":PSA_KEY_TYPE_RSA_KEY_PAIR:0:PSA_ERROR_NOT_SUPPORTED PSA import/export EC secp224r1 key pair: good depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_PK_WRITE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP224R1_ENABLED @@ -256,31 +265,31 @@ import_export:"3082025e02010002818100af057d396ee84fb75fdbb5c2b13c7fe5a654aa8aa24 PSA import EC keypair: DER format depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED -import:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"3077020101042049c9a8c18c4b885638c431cf1df1c994131609b580d4fd43a0cab17db2f13eeea00a06082a8648ce3d030107a144034200047772656f814b399279d5e1f1781fac6f099a3c5ca1b0e35351834b08b65e0b572590cdaf8f769361bcf34acfc11e5e074e8426bdde04be6e653945449617de45":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT PSA import EC keypair: too short depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED -import:"0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"0123456789abcdef0123456789abcdef":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT PSA import EC keypair: public key depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED -import:"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"04dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT PSA import EC keypair: secp256r1, all-bits-zero (bad) depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED -import:"0000000000000000000000000000000000000000000000000000000000000000":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"0000000000000000000000000000000000000000000000000000000000000000":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT PSA import EC keypair: secp256r1, d == n - 1 (good) depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED -import:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_SUCCESS +import_with_data:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632550":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_SUCCESS PSA import EC keypair: secp256r1, d == n (bad) depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED -import:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT PSA import EC keypair: secp256r1, d > n (bad) depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED -import:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632552":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_INVALID_ARGUMENT PSA import EC public key: key pair depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED @@ -288,31 +297,39 @@ depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED # one would expect the status to be PSA_ERROR_INVALID_ARGUMENT. But the # Mbed TLS pkparse module returns MBEDTLS_ERR_PK_INVALID_ALG, I think because # it's looking for an OID where there is no OID. -import:"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_NOT_SUPPORTED +import_with_data:"3078020101042100ab45435712649cb30bbddac49197eebf2740ffc7f874d9244c3460f54f322d3aa00a06082a8648ce3d030107a14403420004dea5e45d0ea37fc566232a508f4ad20ea13d47e4bf5fa4d54a57a0ba012042087097496efc583fed8b24a5b9be9a51de063f5a00a8b698a16fd7f29b5485f320":PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_CURVE_SECP256R1):0:PSA_ERROR_NOT_SUPPORTED PSA import EC keypair: valid key but RSA depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_BP512R1_ENABLED:MBEDTLS_RSA_C -import:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_BRAINPOOL_P512R1):0:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"3082013b020100024100ee2b131d6b1818a94ca8e91c42387eb15a7c271f57b89e7336b144d4535b16c83097ecdefbbb92d1b5313b5a37214d0e8f25922dca778b424b25295fc8a1a7070203010001024100978ac8eadb0dc6035347d6aba8671215ff21283385396f7897c04baf5e2a835f3b53ef80a82ed36ae687a925380b55a0c73eb85656e989dcf0ed7fb4887024e1022100fdad8e1c6853563f8b921d2d112462ae7d6b176082d2ba43e87e1a37fc1a8b33022100f0592cf4c55ba44307b18981bcdbda376c51e590ffa5345ba866f6962dca94dd02201995f1a967d44ff4a4cd1de837bc65bf97a2bf7eda730a9a62cea53254591105022027f96cf4b8ee68ff8d04062ec1ce7f18c0b74e4b3379b29f9bfea3fc8e592731022100cefa6d220496b43feb83194255d8fb930afcf46f36606e3aa0eb7a93ad88c10c":PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_BRAINPOOL_P512R1):0:PSA_ERROR_INVALID_ARGUMENT PSA import AES: bits=0 ok depends_on:MBEDTLS_AES_C -import:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:0:PSA_SUCCESS +import_with_data:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:0:PSA_SUCCESS PSA import AES: bits=128 ok depends_on:MBEDTLS_AES_C -import:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:128:PSA_SUCCESS +import_with_data:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:128:PSA_SUCCESS PSA import AES: bits=256 wrong depends_on:MBEDTLS_AES_C -import:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:256:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:256:PSA_ERROR_INVALID_ARGUMENT PSA import AES: bits=256 ok depends_on:MBEDTLS_AES_C -import:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:256:PSA_SUCCESS +import_with_data:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:256:PSA_SUCCESS PSA import AES: bits=128 wrong depends_on:MBEDTLS_AES_C -import:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:128:PSA_ERROR_INVALID_ARGUMENT +import_with_data:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa":PSA_KEY_TYPE_AES:128:PSA_ERROR_INVALID_ARGUMENT + +PSA import large key: raw, 65528 bits (ok) +depends_on:HAVE_RAM_AVAILABLE_128K +import_large_key:PSA_KEY_TYPE_RAW_DATA:8191:PSA_SUCCESS + +PSA import large key: raw, 65536 bits (not supported) +depends_on:HAVE_RAM_AVAILABLE_128K +import_large_key:PSA_KEY_TYPE_RAW_DATA:8192:PSA_ERROR_NOT_SUPPORTED PSA import RSA key pair: maximum size exceeded depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C @@ -2075,6 +2092,25 @@ PSA key derivation: TLS 1.2 PRF SHA-256, derive key export, 1+41 depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION derive_key_export:PSA_ALG_TLS12_PRF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":1:41 +PSA key derivation: invalid type (0) +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION +derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_NONE:128:PSA_ERROR_NOT_SUPPORTED + +PSA key derivation: invalid type (PSA_KEY_TYPE_CATEGORY_MASK) +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA256_C:!PSA_PRE_1_0_KEY_DERIVATION +derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_256):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_CATEGORY_MASK:128:PSA_ERROR_NOT_SUPPORTED + +# This test assumes that PSA_MAX_KEY_BITS (currently 65536-8 bits = 8191 bytes +# and not expected to be raised any time soon) is less than the maximum +# output from HKDF-SHA512 (255*64 = 16320 bytes). +PSA key derivation: largest possible key +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION +derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_512):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_RAW_DATA:PSA_MAX_KEY_BITS:PSA_SUCCESS + +PSA key derivation: key too large +depends_on:MBEDTLS_MD_C:MBEDTLS_SHA512_C:!PSA_PRE_1_0_KEY_DERIVATION +derive_key:PSA_ALG_HKDF(PSA_ALG_SHA_512):"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b":"000102030405060708090a0b0c":"f0f1f2f3f4f5f6f7f8f9":PSA_KEY_TYPE_RAW_DATA:PSA_MAX_KEY_BITS + 1:PSA_ERROR_NOT_SUPPORTED + PSA key agreement setup: ECDH + HKDF-SHA-256: good depends_on:MBEDTLS_PK_PARSE_C:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDH_C:MBEDTLS_MD_C:MBEDTLS_SHA256_C key_agreement_setup:PSA_ALG_KEY_AGREEMENT(PSA_ALG_ECDH, PSA_ALG_HKDF(PSA_ALG_SHA_256)):PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_CURVE_SECP256R1):"c88f01f510d9ac3f70a292daa2316de544e9aab8afe84049c62a9c57862d1433":"04d12dfb5289c8d4f81208b70270398c342296970a0bccb74c736fc7554494bf6356fbf3ca366cc23e8157854c13c58d6aac23f046ada30f8353e74f33039872ab":PSA_SUCCESS @@ -2173,6 +2209,18 @@ generate_random:19 PSA generate random: 260 bytes generate_random:260 +PSA generate random: MBEDTLS_CTR_DRBG_MAX_REQUEST bytes +generate_random:MBEDTLS_CTR_DRBG_MAX_REQUEST + +PSA generate random: MBEDTLS_CTR_DRBG_MAX_REQUEST+1 bytes +generate_random:MBEDTLS_CTR_DRBG_MAX_REQUEST + 1 + +PSA generate random: 2*MBEDTLS_CTR_DRBG_MAX_REQUEST+1 bytes +generate_random:2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1 + +PSA generate key: bad type (0) +generate_key:PSA_KEY_TYPE_NONE:128:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED + PSA generate key: bad type (PSA_KEY_TYPE_CATEGORY_MASK) generate_key:PSA_KEY_TYPE_CATEGORY_MASK:128:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED @@ -2188,6 +2236,19 @@ generate_key:PSA_KEY_TYPE_RAW_DATA:7:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_INVALID_AR PSA generate key: raw data, 8 bits generate_key:PSA_KEY_TYPE_RAW_DATA:8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS +PSA generate key: raw data, (MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits +generate_key:PSA_KEY_TYPE_RAW_DATA:(MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS + +PSA generate key: raw data, (2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8 bits +generate_key:PSA_KEY_TYPE_RAW_DATA:(2 * MBEDTLS_CTR_DRBG_MAX_REQUEST + 1) * 8:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS + +PSA generate key: raw data, 65528 bits (ok) +depends_on:HAVE_RAM_AVAILABLE_128K +generate_key:PSA_KEY_TYPE_RAW_DATA:65528:PSA_KEY_USAGE_EXPORT:0:PSA_SUCCESS + +PSA generate key: raw data, 65536 bits (not supported) +generate_key:PSA_KEY_TYPE_RAW_DATA:65536:PSA_KEY_USAGE_EXPORT:0:PSA_ERROR_NOT_SUPPORTED + PSA generate key: AES, 128 bits, CTR depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR generate_key:PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT:PSA_ALG_CTR:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 1d06d62e7..81ccb4ce3 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -5,8 +5,21 @@ #include "mbedtls/asn1write.h" #include "mbedtls/oid.h" +/* For MBEDTLS_CTR_DRBG_MAX_REQUEST, knowing that psa_generate_random() + * uses mbedtls_ctr_drbg internally. */ +#include "mbedtls/ctr_drbg.h" + #include "psa_crypto_helpers.h" +/* Tests that require more than 128kB of RAM plus change have this symbol + * as a dependency. Currently we always define this symbol, so the tests + * are always executed. In the future we should make this conditional + * so that tests that require a lot of memory are skipped on constrained + * platforms. */ +#define HAVE_RAM_AVAILABLE_128K + +#include "psa/crypto.h" + /** An invalid export length that will never be set by psa_export_key(). */ static const size_t INVALID_EXPORT_LENGTH = ~0U; @@ -556,7 +569,8 @@ static int setup_key_derivation_wrap( psa_key_derivation_operation_t* operation, TEST_ASSERT( ! "Key derivation algorithm not supported" ); } - PSA_ASSERT( psa_key_derivation_set_capacity( operation, capacity ) ); + if( capacity != SIZE_MAX ) + PSA_ASSERT( psa_key_derivation_set_capacity( operation, capacity ) ); return( 1 ); @@ -1201,9 +1215,52 @@ void persistence_attributes( int id1_arg, int lifetime_arg, int id2_arg, /* END_CASE */ /* BEGIN_CASE */ -void import( data_t *data, int type_arg, - int attr_bits_arg, - int expected_status_arg ) +void import_with_policy( int type_arg, + int usage_arg, int alg_arg, + int expected_status_arg ) +{ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_handle_t handle = 0; + psa_key_type_t type = type_arg; + psa_key_usage_t usage = usage_arg; + psa_algorithm_t alg = alg_arg; + psa_status_t expected_status = expected_status_arg; + const uint8_t key_material[16] = {0}; + psa_status_t status; + + PSA_ASSERT( psa_crypto_init( ) ); + + psa_set_key_type( &attributes, type ); + psa_set_key_usage_flags( &attributes, usage ); + psa_set_key_algorithm( &attributes, alg ); + + status = psa_import_key( &attributes, + key_material, sizeof( key_material ), + &handle ); + TEST_EQUAL( status, expected_status ); + if( status != PSA_SUCCESS ) + goto exit; + + PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) ); + TEST_EQUAL( psa_get_key_type( &got_attributes ), type ); + TEST_EQUAL( psa_get_key_usage_flags( &got_attributes ), usage ); + TEST_EQUAL( psa_get_key_algorithm( &got_attributes ), alg ); + + PSA_ASSERT( psa_destroy_key( handle ) ); + test_operations_on_invalid_handle( handle ); + +exit: + psa_destroy_key( handle ); + psa_reset_key_attributes( &got_attributes ); + PSA_DONE( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void import_with_data( data_t *data, int type_arg, + int attr_bits_arg, + int expected_status_arg ) { psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; psa_key_attributes_t got_attributes = PSA_KEY_ATTRIBUTES_INIT; @@ -1217,6 +1274,7 @@ void import( data_t *data, int type_arg, psa_set_key_type( &attributes, type ); psa_set_key_bits( &attributes, attr_bits ); + status = psa_import_key( &attributes, data->x, data->len, &handle ); TEST_EQUAL( status, expected_status ); if( status != PSA_SUCCESS ) @@ -1225,7 +1283,7 @@ void import( data_t *data, int type_arg, PSA_ASSERT( psa_get_key_attributes( handle, &got_attributes ) ); TEST_EQUAL( psa_get_key_type( &got_attributes ), type ); if( attr_bits != 0 ) - TEST_EQUAL( attr_bits, got_attributes.bits ); + TEST_EQUAL( attr_bits, psa_get_key_bits( &got_attributes ) ); PSA_ASSERT( psa_destroy_key( handle ) ); test_operations_on_invalid_handle( handle ); @@ -1237,6 +1295,54 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void import_large_key( int type_arg, int byte_size_arg, + int expected_status_arg ) +{ + psa_key_type_t type = type_arg; + size_t byte_size = byte_size_arg; + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t expected_status = expected_status_arg; + psa_key_handle_t handle = 0; + psa_status_t status; + uint8_t *buffer = NULL; + size_t buffer_size = byte_size + 1; + size_t n; + + /* It would be better to skip the test than fail it if the allocation + * fails, but the test framework doesn't support this yet. */ + ASSERT_ALLOC( buffer, buffer_size ); + memset( buffer, 'K', byte_size ); + + PSA_ASSERT( psa_crypto_init( ) ); + + /* Try importing the key */ + psa_set_key_usage_flags( &attributes, PSA_KEY_USAGE_EXPORT ); + psa_set_key_type( &attributes, type ); + status = psa_import_key( &attributes, buffer, byte_size, &handle ); + TEST_EQUAL( status, expected_status ); + + if( status == PSA_SUCCESS ) + { + PSA_ASSERT( psa_get_key_attributes( handle, &attributes ) ); + TEST_EQUAL( psa_get_key_type( &attributes ), type ); + TEST_EQUAL( psa_get_key_bits( &attributes ), + PSA_BYTES_TO_BITS( byte_size ) ); + memset( buffer, 0, byte_size + 1 ); + PSA_ASSERT( psa_export_key( handle, buffer, byte_size, &n ) ); + for( n = 0; n < byte_size; n++ ) + TEST_EQUAL( buffer[n], 'K' ); + for( n = byte_size; n < buffer_size; n++ ) + TEST_EQUAL( buffer[n], 0 ); + } + +exit: + psa_destroy_key( handle ); + PSA_DONE( ); + mbedtls_free( buffer ); +} +/* END_CASE */ + /* BEGIN_CASE */ void import_rsa_made_up( int bits_arg, int keypair, int expected_status_arg ) { @@ -4563,6 +4669,51 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void derive_key( int alg_arg, + data_t *key_data, data_t *input1, data_t *input2, + int type_arg, int bits_arg, + int expected_status_arg ) +{ + psa_key_handle_t base_handle = 0; + psa_key_handle_t derived_handle = 0; + psa_algorithm_t alg = alg_arg; + psa_key_type_t type = type_arg; + size_t bits = bits_arg; + psa_status_t expected_status = expected_status_arg; + psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT; + psa_key_attributes_t base_attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_key_attributes_t derived_attributes = PSA_KEY_ATTRIBUTES_INIT; + + PSA_ASSERT( psa_crypto_init( ) ); + + psa_set_key_usage_flags( &base_attributes, PSA_KEY_USAGE_DERIVE ); + psa_set_key_algorithm( &base_attributes, alg ); + psa_set_key_type( &base_attributes, PSA_KEY_TYPE_DERIVE ); + PSA_ASSERT( psa_import_key( &base_attributes, key_data->x, key_data->len, + &base_handle ) ); + + if( !setup_key_derivation_wrap( &operation, base_handle, alg, + input1->x, input1->len, + input2->x, input2->len, SIZE_MAX ) ) + goto exit; + + psa_set_key_usage_flags( &derived_attributes, PSA_KEY_USAGE_EXPORT ); + psa_set_key_algorithm( &derived_attributes, 0 ); + psa_set_key_type( &derived_attributes, type ); + psa_set_key_bits( &derived_attributes, bits ); + TEST_EQUAL( psa_key_derivation_output_key( &derived_attributes, &operation, + &derived_handle ), + expected_status ); + +exit: + psa_key_derivation_abort( &operation ); + psa_destroy_key( base_handle ); + psa_destroy_key( derived_handle ); + PSA_DONE( ); +} +/* END_CASE */ + /* BEGIN_CASE */ void key_agreement_setup( int alg_arg, int our_key_type_arg, data_t *our_key_data, diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.data b/tests/suites/test_suite_psa_crypto_persistent_key.data index 925c0f54a..3f40d35c7 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.data +++ b/tests/suites/test_suite_psa_crypto_persistent_key.data @@ -19,10 +19,10 @@ parse_storage_data_check:"505341004b4559":"":PSA_KEY_LIFETIME_PERSISTENT:PSA_KEY # Not specific to files, but only run this test in an environment where the maximum size could be reached. Save maximum size persistent raw key depends_on:MBEDTLS_PSA_ITS_FILE_C -save_large_persistent_key:0:PSA_SUCCESS +save_large_persistent_key:PSA_CRYPTO_MAX_STORAGE_SIZE:PSA_SUCCESS Save larger than maximum size persistent raw key, should fail -save_large_persistent_key:1:PSA_ERROR_INSUFFICIENT_STORAGE +save_large_persistent_key:PSA_CRYPTO_MAX_STORAGE_SIZE + 1:PSA_ERROR_NOT_SUPPORTED Persistent key destroy depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C diff --git a/tests/suites/test_suite_psa_crypto_persistent_key.function b/tests/suites/test_suite_psa_crypto_persistent_key.function index b76c7330a..115bfea5d 100644 --- a/tests/suites/test_suite_psa_crypto_persistent_key.function +++ b/tests/suites/test_suite_psa_crypto_persistent_key.function @@ -45,7 +45,7 @@ void format_storage_data_check( data_t *key_data, file_data_length = key_data->len + sizeof( psa_persistent_key_storage_format ); file_data = mbedtls_calloc( 1, file_data_length ); psa_format_key_data_for_storage( key_data->x, key_data->len, - &attributes, + &attributes.core, file_data ); ASSERT_COMPARE( expected_file_data->x, expected_file_data->len, @@ -71,7 +71,7 @@ void parse_storage_data_check( data_t *file_data, status = psa_parse_key_data_from_storage( file_data->x, file_data->len, &key_data, &key_data_length, - &attributes ); + &attributes.core ); TEST_EQUAL( status, expected_status ); if( status != PSA_SUCCESS ) @@ -96,17 +96,14 @@ exit: /* END_CASE */ /* BEGIN_CASE */ -void save_large_persistent_key( int data_too_large, int expected_status ) +void save_large_persistent_key( int data_length_arg, int expected_status ) { psa_key_id_t key_id = 42; psa_key_handle_t handle = 0; uint8_t *data = NULL; - size_t data_length = PSA_CRYPTO_MAX_STORAGE_SIZE; + size_t data_length = data_length_arg; psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - if( data_too_large ) - data_length += 1; - ASSERT_ALLOC( data, data_length ); PSA_ASSERT( psa_crypto_init() );