diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h index 7986eb23b7..0c90cb2d13 100644 --- a/include/psa/crypto_extra.h +++ b/include/psa/crypto_extra.h @@ -231,8 +231,8 @@ typedef struct mbedtls_psa_stats_s size_t cache_slots; /** Number of slots that are not used for anything. */ size_t empty_slots; - /** Number of slots that are not accessed. */ - size_t unaccessed_slots; + /** Number of slots that are not locked. */ + size_t unlocked_slots; /** Largest key id value among open keys in internal persistent storage. */ psa_key_id_t max_open_internal_key_id; /** Largest key id value among open keys in secure elements. */ diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 41a2263ee8..6a07cbd0b3 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1187,27 +1187,28 @@ static psa_status_t psa_restrict_key_policy( return( PSA_SUCCESS ); } -/** Retrieve a slot which must contain a key. The key must have allow all the - * usage flags set in \p usage. If \p alg is nonzero, the key must allow - * operations with this algorithm. +/** Get the description of a key given its identifier and policy constraints + * and lock it. * - * In case of a persistent key, the function loads the description of the key - * into a key slot if not already done. + * The key must have allow all the usage flags set in \p usage. If \p alg is + * nonzero, the key must allow operations with this algorithm. * - * On success, the access counter of the returned key slot is incremented by - * one. It is the responsibility of the caller to call - * psa_decrement_key_slot_access_count() when it does not access the key slot - * anymore. + * In case of a persistent key, the function loads the description of the key + * into a key slot if not already done. + * + * On success, the returned key slot is locked. It is the responsibility of + * the caller to unlock the key slot when it does not access it anymore. */ -static psa_status_t psa_get_key_from_slot( mbedtls_svc_key_id_t key, - psa_key_slot_t **p_slot, - psa_key_usage_t usage, - psa_algorithm_t alg ) +static psa_status_t psa_get_and_lock_key_slot_with_policy( + mbedtls_svc_key_id_t key, + psa_key_slot_t **p_slot, + psa_key_usage_t usage, + psa_algorithm_t alg ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - status = psa_get_key_slot( key, p_slot ); + status = psa_get_and_lock_key_slot( key, p_slot ); if( status != PSA_SUCCESS ) return( status ); slot = *p_slot; @@ -1231,37 +1232,38 @@ static psa_status_t psa_get_key_from_slot( mbedtls_svc_key_id_t key, error: *p_slot = NULL; - psa_decrement_key_slot_access_count( slot ); + psa_unlock_key_slot( slot ); return( status ); } -/** Retrieve a slot which must contain a transparent key. +/** Get a key slot containing a transparent key and lock it. * * A transparent key is a key for which the key material is directly * available, as opposed to a key in a secure element. * - * This is a temporary function to use instead of psa_get_key_from_slot() - * until secure element support is fully implemented. + * This is a temporary function to use instead of + * psa_get_and_lock_key_slot_with_policy() until secure element support is + * fully implemented. * - * On success, the access counter of the returned key slot is incremented by - * one. It is the responsibility of the caller to call - * psa_decrement_key_slot_access_count() when it does not access the key slot - * anymore. + * On success, the returned key slot is locked. It is the responsibility of the + * caller to unlock the key slot when it does not access it anymore. */ #if defined(MBEDTLS_PSA_CRYPTO_SE_C) -static psa_status_t psa_get_transparent_key( mbedtls_svc_key_id_t key, - psa_key_slot_t **p_slot, - psa_key_usage_t usage, - psa_algorithm_t alg ) +static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy( + mbedtls_svc_key_id_t key, + psa_key_slot_t **p_slot, + psa_key_usage_t usage, + psa_algorithm_t alg ) { - psa_status_t status = psa_get_key_from_slot( key, p_slot, usage, alg ); + psa_status_t status = psa_get_and_lock_key_slot_with_policy( key, p_slot, + usage, alg ); if( status != PSA_SUCCESS ) return( status ); if( psa_key_slot_is_external( *p_slot ) ) { - psa_decrement_key_slot_access_count( *p_slot ); + psa_unlock_key_slot( *p_slot ); *p_slot = NULL; return( PSA_ERROR_NOT_SUPPORTED ); } @@ -1270,8 +1272,8 @@ static psa_status_t psa_get_transparent_key( mbedtls_svc_key_id_t key, } #else /* MBEDTLS_PSA_CRYPTO_SE_C */ /* With no secure element support, all keys are transparent. */ -#define psa_get_transparent_key( key, p_slot, usage, alg ) \ - psa_get_key_from_slot( key, p_slot, usage, alg ) +#define psa_get_and_lock_transparent_key_slot_with_policy( key, p_slot, usage, alg ) \ + 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. */ @@ -1305,15 +1307,15 @@ psa_status_t psa_wipe_key_slot( psa_key_slot_t *slot ) /* * As the return error code may not be handled in case of multiple errors, - * do our best to report an unexpected access counter: if available + * do our best to report an unexpected lock counter: if available * call MBEDTLS_PARAM_FAILED that may terminate execution (if called as * part of the execution of a test suite this will stop the test suite * execution). */ - if( slot->access_count != 1 ) + if( slot->lock_count != 1 ) { #ifdef MBEDTLS_CHECK_PARAMS - MBEDTLS_PARAM_FAILED( slot->access_count == 1 ); + MBEDTLS_PARAM_FAILED( slot->lock_count == 1 ); #endif status = PSA_ERROR_CORRUPTION_DETECTED; } @@ -1349,7 +1351,7 @@ psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key ) * the key is operated by an SE or not and this information is needed by * the current implementation. */ - status = psa_get_key_slot( key, &slot ); + status = psa_get_and_lock_key_slot( key, &slot ); if( status != PSA_SUCCESS ) return( status ); @@ -1360,9 +1362,9 @@ psa_status_t psa_destroy_key( mbedtls_svc_key_id_t key ) * implemented), the key should be destroyed when all accesses have * stopped. */ - if( slot->access_count > 1 ) + if( slot->lock_count > 1 ) { - psa_decrement_key_slot_access_count( slot ); + psa_unlock_key_slot( slot ); return( PSA_ERROR_GENERIC_ERROR ); } @@ -1533,12 +1535,12 @@ psa_status_t psa_get_key_attributes( mbedtls_svc_key_id_t key, psa_key_attributes_t *attributes ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; psa_reset_key_attributes( attributes ); - status = psa_get_key_from_slot( key, &slot, 0, 0 ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 ); if( status != PSA_SUCCESS ) return( status ); @@ -1589,9 +1591,9 @@ psa_status_t psa_get_key_attributes( mbedtls_svc_key_id_t key, if( status != PSA_SUCCESS ) psa_reset_key_attributes( attributes ); - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } #if defined(MBEDTLS_PSA_CRYPTO_SE_C) @@ -1752,7 +1754,7 @@ psa_status_t psa_export_key( mbedtls_svc_key_id_t key, size_t *data_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; /* Set the key to empty now, so that even when there are errors, we always @@ -1762,16 +1764,18 @@ psa_status_t psa_export_key( mbedtls_svc_key_id_t key, *data_length = 0; /* Export requires the EXPORT flag. There is an exception for public keys, - * which don't require any flag, but psa_get_key_from_slot takes - * care of this. */ - status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_EXPORT, 0 ); + * which don't require any flag, but + * psa_get_and_lock_key_slot_with_policy() takes care of this. + */ + status = psa_get_and_lock_key_slot_with_policy( key, &slot, + PSA_KEY_USAGE_EXPORT, 0 ); if( status != PSA_SUCCESS ) return( status ); status = psa_internal_export_key( slot, data, data_size, data_length, 0 ); - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } psa_status_t psa_export_public_key( mbedtls_svc_key_id_t key, @@ -1780,7 +1784,7 @@ psa_status_t psa_export_public_key( mbedtls_svc_key_id_t key, size_t *data_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; /* Set the key to empty now, so that even when there are errors, we always @@ -1790,14 +1794,14 @@ psa_status_t psa_export_public_key( mbedtls_svc_key_id_t key, *data_length = 0; /* Exporting a public key doesn't require a usage flag. */ - status = psa_get_key_from_slot( key, &slot, 0, 0 ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, 0, 0 ); if( status != PSA_SUCCESS ) return( status ); status = psa_internal_export_key( slot, data, data_size, data_length, 1 ); - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } #if defined(static_assert) @@ -1904,10 +1908,8 @@ static psa_status_t psa_validate_key_attributes( * In case of failure at any step, stop the sequence and call * psa_fail_key_creation(). * - * On success, the access counter of the returned key slot is incremented by - * one. It is the responsibility of the caller to call - * psa_decrement_key_slot_access_count() when it does not access the key slot - * anymore. + * On success, the key slot is locked. It is the responsibility of the caller + * to unlock the key slot when it does not access it anymore. * * \param method An identification of the calling function. * \param[in] attributes Key attributes for the new key. @@ -2025,9 +2027,9 @@ static psa_status_t psa_start_key_creation( * See the documentation of psa_start_key_creation() for the intended use * of this function. * - * If the finalization succeeds, the function decreases the slot access - * counter (that was incremented as part of psa_start_key_creation()) and the - * slot cannot be accessed anymore as part of the key creation process. + * If the finalization succeeds, the function unlocks the key slot (it was + * locked by psa_start_key_creation()) and the key slot cannot be accessed + * anymore as part of the key creation process. * * \param[in,out] slot Pointer to the slot with key material. * \param[in] driver The secure element driver for the key, @@ -2101,7 +2103,7 @@ static psa_status_t psa_finish_key_creation( if( status == PSA_SUCCESS ) { *key = slot->attr.id; - status = psa_decrement_key_slot_access_count( slot ); + status = psa_unlock_key_slot( slot ); if( status != PSA_SUCCESS ) *key = MBEDTLS_SVC_KEY_ID_INIT; } @@ -2344,7 +2346,7 @@ psa_status_t psa_copy_key( mbedtls_svc_key_id_t source_key, mbedtls_svc_key_id_t *target_key ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *source_slot = NULL; psa_key_slot_t *target_slot = NULL; psa_key_attributes_t actual_attributes = *specified_attributes; @@ -2352,8 +2354,8 @@ psa_status_t psa_copy_key( mbedtls_svc_key_id_t source_key, *target_key = MBEDTLS_SVC_KEY_ID_INIT; - status = psa_get_transparent_key( source_key, &source_slot, - PSA_KEY_USAGE_COPY, 0 ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + source_key, &source_slot, PSA_KEY_USAGE_COPY, 0 ); if( status != PSA_SUCCESS ) goto exit; @@ -2390,9 +2392,9 @@ exit: if( status != PSA_SUCCESS ) psa_fail_key_creation( target_slot, driver ); - decrement_status = psa_decrement_key_slot_access_count( source_slot ); + unlock_status = psa_unlock_key_slot( source_slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } @@ -3179,7 +3181,7 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, int is_sign ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; size_t key_bits; psa_key_usage_t usage = @@ -3199,7 +3201,8 @@ static psa_status_t psa_mac_setup( psa_mac_operation_t *operation, if( is_sign ) operation->is_sign = 1; - status = psa_get_transparent_key( key, &slot, usage, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &slot, usage, alg ); if( status != PSA_SUCCESS ) goto exit; key_bits = psa_get_key_slot_bits( slot ); @@ -3289,9 +3292,9 @@ exit: operation->key_set = 1; } - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } psa_status_t psa_mac_sign_setup( psa_mac_operation_t *operation, @@ -3789,7 +3792,7 @@ psa_status_t psa_sign_hash( mbedtls_svc_key_id_t key, size_t *signature_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; *signature_length = signature_size; @@ -3800,7 +3803,9 @@ psa_status_t psa_sign_hash( mbedtls_svc_key_id_t key, if( signature_size == 0 ) return( PSA_ERROR_BUFFER_TOO_SMALL ); - status = psa_get_key_from_slot( key, &slot, PSA_KEY_USAGE_SIGN_HASH, alg ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, + PSA_KEY_USAGE_SIGN_HASH, + alg ); if( status != PSA_SUCCESS ) goto exit; if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) @@ -3897,9 +3902,9 @@ exit: /* If signature_size is 0 then we have nothing to do. We must not call * memset because signature may be NULL in this case. */ - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } psa_status_t psa_verify_hash( mbedtls_svc_key_id_t key, @@ -3910,11 +3915,12 @@ psa_status_t psa_verify_hash( mbedtls_svc_key_id_t key, size_t signature_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - status = psa_get_key_from_slot( key, &slot, - PSA_KEY_USAGE_VERIFY_HASH, alg ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, + PSA_KEY_USAGE_VERIFY_HASH, + alg ); if( status != PSA_SUCCESS ) return( status ); @@ -3985,9 +3991,9 @@ psa_status_t psa_verify_hash( mbedtls_svc_key_id_t key, } exit: - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } #if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) @@ -4012,7 +4018,7 @@ psa_status_t psa_asymmetric_encrypt( mbedtls_svc_key_id_t key, size_t *output_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; (void) input; @@ -4026,7 +4032,8 @@ psa_status_t psa_asymmetric_encrypt( mbedtls_svc_key_id_t key, if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_transparent_key( key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &slot, PSA_KEY_USAGE_ENCRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); if( ! ( PSA_KEY_TYPE_IS_PUBLIC_KEY( slot->attr.type ) || @@ -4100,9 +4107,9 @@ rsa_exit: } exit: - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } psa_status_t psa_asymmetric_decrypt( mbedtls_svc_key_id_t key, @@ -4116,7 +4123,7 @@ psa_status_t psa_asymmetric_decrypt( mbedtls_svc_key_id_t key, size_t *output_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; (void) input; @@ -4130,7 +4137,8 @@ psa_status_t psa_asymmetric_decrypt( mbedtls_svc_key_id_t key, if( ! PSA_ALG_IS_RSA_OAEP( alg ) && salt_length != 0 ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_transparent_key( key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &slot, PSA_KEY_USAGE_DECRYPT, alg ); if( status != PSA_SUCCESS ) return( status ); if( ! PSA_KEY_TYPE_IS_KEY_PAIR( slot->attr.type ) ) @@ -4203,9 +4211,9 @@ rsa_exit: } exit: - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } @@ -4220,7 +4228,7 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, mbedtls_operation_t cipher_operation ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; int ret = 0; psa_key_slot_t *slot; size_t key_bits; @@ -4238,7 +4246,7 @@ static psa_status_t psa_cipher_setup( psa_cipher_operation_t *operation, return( PSA_ERROR_INVALID_ARGUMENT ); /* Fetch key material from key storage. */ - status = psa_get_key_from_slot( key, &slot, usage, alg ); + status = psa_get_and_lock_key_slot_with_policy( key, &slot, usage, alg ); if( status != PSA_SUCCESS ) goto exit; @@ -4366,9 +4374,9 @@ exit: else psa_cipher_abort( operation ); - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } psa_status_t psa_cipher_encrypt_setup( psa_cipher_operation_t *operation, @@ -4768,7 +4776,7 @@ static void psa_aead_abort_internal( aead_operation_t *operation ) #endif /* MBEDTLS_GCM_C */ } - psa_decrement_key_slot_access_count( operation->slot ); + psa_unlock_key_slot( operation->slot ); } static psa_status_t psa_aead_setup( aead_operation_t *operation, @@ -4780,7 +4788,8 @@ static psa_status_t psa_aead_setup( aead_operation_t *operation, size_t key_bits; mbedtls_cipher_id_t cipher_id; - status = psa_get_transparent_key( key, &operation->slot, usage, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &operation->slot, usage, alg ); if( status != PSA_SUCCESS ) return( status ); @@ -5910,11 +5919,11 @@ psa_status_t psa_key_derivation_input_key( mbedtls_svc_key_id_t key ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; - status = psa_get_transparent_key( key, &slot, - PSA_KEY_USAGE_DERIVE, operation->alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg ); if( status != PSA_SUCCESS ) { psa_key_derivation_abort( operation ); @@ -5931,9 +5940,9 @@ psa_status_t psa_key_derivation_input_key( slot->data.key.data, slot->data.key.bytes ); - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } @@ -6082,13 +6091,13 @@ psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *o size_t peer_key_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot; if( ! PSA_ALG_IS_KEY_AGREEMENT( operation->alg ) ) return( PSA_ERROR_INVALID_ARGUMENT ); - status = psa_get_transparent_key( private_key, &slot, - PSA_KEY_USAGE_DERIVE, operation->alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + private_key, &slot, PSA_KEY_USAGE_DERIVE, operation->alg ); if( status != PSA_SUCCESS ) return( status ); status = psa_key_agreement_internal( operation, step, @@ -6104,9 +6113,9 @@ psa_status_t psa_key_derivation_key_agreement( psa_key_derivation_operation_t *o operation->can_output_key = 1; } - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } psa_status_t psa_raw_key_agreement( psa_algorithm_t alg, @@ -6118,7 +6127,7 @@ psa_status_t psa_raw_key_agreement( psa_algorithm_t alg, size_t *output_length ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; - psa_status_t decrement_status = PSA_ERROR_CORRUPTION_DETECTED; + psa_status_t unlock_status = PSA_ERROR_CORRUPTION_DETECTED; psa_key_slot_t *slot = NULL; if( ! PSA_ALG_IS_KEY_AGREEMENT( alg ) ) @@ -6126,8 +6135,8 @@ psa_status_t psa_raw_key_agreement( psa_algorithm_t alg, status = PSA_ERROR_INVALID_ARGUMENT; goto exit; } - status = psa_get_transparent_key( private_key, &slot, - PSA_KEY_USAGE_DERIVE, alg ); + status = psa_get_and_lock_transparent_key_slot_with_policy( + private_key, &slot, PSA_KEY_USAGE_DERIVE, alg ); if( status != PSA_SUCCESS ) goto exit; @@ -6150,9 +6159,9 @@ exit: *output_length = output_size; } - decrement_status = psa_decrement_key_slot_access_count( slot ); + unlock_status = psa_unlock_key_slot( slot ); - return( ( status == PSA_SUCCESS ) ? decrement_status : status ); + return( ( status == PSA_SUCCESS ) ? unlock_status : status ); } diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index 489be31e2f..1492d19436 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -38,8 +38,7 @@ typedef struct psa_core_key_attributes_t attr; /* - * Number of on-going accesses, read and/or write, to the key slot by the - * library. + * Number of locks, read and/or write, to the key slot by the library. * * This counter is incremented by one each time a library function * retrieves through one of the dedicated internal API a pointer to the @@ -47,7 +46,7 @@ typedef struct * * This counter is decremented by one each time a library function stops * accessing to the key slot and states it by calling the - * psa_decrement_key_slot_access_count() API. + * psa_unlock_key_slot() API. * * This counter is used to prevent resetting the key slot while the library * may access it. For example, such control is needed in the following @@ -61,7 +60,7 @@ typedef struct * or purge or destroy a key while it is in used by the library through * another thread. */ - size_t access_count; + size_t lock_count; union { @@ -101,18 +100,17 @@ static inline int psa_is_key_slot_occupied( const psa_key_slot_t *slot ) return( slot->attr.type != 0 ); } -/** Test whether a key slot is accessed. +/** Test whether a key slot is locked. * - * A key slot is accessed iff its access counter is strickly greater than - * 0. + * A key slot is locked iff its lock counter is strickly greater than 0. * * \param[in] slot The key slot to test. * - * \return 1 if the slot is accessed, 0 otherwise. + * \return 1 if the slot is locked, 0 otherwise. */ -static inline int psa_is_key_slot_accessed( const psa_key_slot_t *slot ) +static inline int psa_is_key_slot_locked( const psa_key_slot_t *slot ) { - return( slot->access_count > 0 ); + return( slot->lock_count > 0 ); } /** Retrieve flags from psa_key_slot_t::attr::core::flags. diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c index 943923f5db..3e18668715 100644 --- a/library/psa_crypto_slot_management.c +++ b/library/psa_crypto_slot_management.c @@ -68,25 +68,23 @@ psa_status_t psa_validate_key_id( return( PSA_ERROR_INVALID_HANDLE ); } -/** Search for the description of a key given its identifier. +/** Get the description in memory of a key given its identifier and lock it. * - * The descriptions of volatile keys and loaded persistent keys are - * stored in key slots. This function returns a pointer to the key slot - * containing the description of a key given its identifier. + * The descriptions of volatile keys and loaded persistent keys are + * stored in key slots. This function returns a pointer to the key slot + * containing the description of a key given its identifier. * - * The function searches the key slots containing the description of the key - * with \p key identifier. The function does only read accesses to the key - * slots. The function does not load any persistent key thus does not access - * any storage. + * The function searches the key slots containing the description of the key + * with \p key identifier. The function does only read accesses to the key + * slots. The function does not load any persistent key thus does not access + * any storage. * - * For volatile key identifiers, only one key slot is queried as a volatile - * key with identifier key_id can only be stored in slot of index - * ( key_id - #PSA_KEY_ID_VOLATILE_MIN ). + * For volatile key identifiers, only one key slot is queried as a volatile + * key with identifier key_id can only be stored in slot of index + * ( key_id - #PSA_KEY_ID_VOLATILE_MIN ). * - * On success, the access counter of the returned key slot is incremented by - * one. It is the responsibility of the caller to call - * psa_decrement_key_slot_access_count() when it does not access the key slot - * anymore. + * On success, the function locks the key slot. It is the responsibility of + * the caller to unlock the key slot when it does not access it anymore. * * \param key Key identifier to query. * \param[out] p_slot On success, `*p_slot` contains a pointer to the @@ -101,7 +99,7 @@ psa_status_t psa_validate_key_id( * \retval #PSA_ERROR_DOES_NOT_EXIST * There is no key with key identifier \p key in the key slots. */ -static psa_status_t psa_search_key_in_slots( +static psa_status_t psa_get_and_lock_key_slot_in_memory( mbedtls_svc_key_id_t key, psa_key_slot_t **p_slot ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -133,7 +131,7 @@ static psa_status_t psa_search_key_in_slots( if( status == PSA_SUCCESS ) { - status = psa_increment_key_slot_access_count( slot ); + status = psa_lock_key_slot( slot ); if( status == PSA_SUCCESS ) *p_slot = slot; } @@ -157,7 +155,7 @@ void psa_wipe_all_key_slots( void ) for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ ) { psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ]; - slot->access_count = 1; + slot->lock_count = 1; (void) psa_wipe_key_slot( slot ); } global_data.key_slots_initialized = 0; @@ -168,7 +166,7 @@ psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id, { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; size_t slot_idx; - psa_key_slot_t *selected_slot, *unaccessed_persistent_key_slot; + psa_key_slot_t *selected_slot, *unlocked_persistent_key_slot; if( ! global_data.key_slots_initialized ) { @@ -176,7 +174,7 @@ psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id, goto error; } - selected_slot = unaccessed_persistent_key_slot = NULL; + selected_slot = unlocked_persistent_key_slot = NULL; for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ ) { psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ]; @@ -186,30 +184,30 @@ psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id, break; } - if( ( unaccessed_persistent_key_slot == NULL ) && + if( ( unlocked_persistent_key_slot == NULL ) && ( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) ) && - ( ! psa_is_key_slot_accessed( slot ) ) ) - unaccessed_persistent_key_slot = slot; + ( ! psa_is_key_slot_locked( slot ) ) ) + unlocked_persistent_key_slot = slot; } /* - * If there is no unused key slot and there is at least one unaccessed key + * If there is no unused key slot and there is at least one unlocked key * slot containing the description of a permament key, recycle the first * such key slot we encountered. If we need later on to operate on the * persistent key we evict now, we will reload its description from * storage. */ if( ( selected_slot == NULL ) && - ( unaccessed_persistent_key_slot != NULL ) ) + ( unlocked_persistent_key_slot != NULL ) ) { - selected_slot = unaccessed_persistent_key_slot; - selected_slot->access_count = 1; + selected_slot = unlocked_persistent_key_slot; + selected_slot->lock_count = 1; psa_wipe_key_slot( selected_slot ); } if( selected_slot != NULL ) { - status = psa_increment_key_slot_access_count( selected_slot ); + status = psa_lock_key_slot( selected_slot ); if( status != PSA_SUCCESS ) goto error; @@ -267,8 +265,8 @@ exit: } #endif /* MBEDTLS_PSA_CRYPTO_STORAGE_C */ -psa_status_t psa_get_key_slot( mbedtls_svc_key_id_t key, - psa_key_slot_t **p_slot ) +psa_status_t psa_get_and_lock_key_slot( mbedtls_svc_key_id_t key, + psa_key_slot_t **p_slot ) { psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED; @@ -278,9 +276,9 @@ psa_status_t psa_get_key_slot( mbedtls_svc_key_id_t key, /* * On success, the pointer to the slot is passed directly to the caller - * thus no need to decrement the key slot access counter here. + * thus no need to unlock the key slot here. */ - status = psa_search_key_in_slots( key, p_slot ); + status = psa_get_and_lock_key_slot_in_memory( key, p_slot ); if( status != PSA_ERROR_DOES_NOT_EXIST ) return( status ); @@ -305,26 +303,26 @@ psa_status_t psa_get_key_slot( mbedtls_svc_key_id_t key, } -psa_status_t psa_decrement_key_slot_access_count( psa_key_slot_t *slot ) +psa_status_t psa_unlock_key_slot( psa_key_slot_t *slot ) { if( slot == NULL ) return( PSA_SUCCESS ); - if( slot->access_count > 0 ) + if( slot->lock_count > 0 ) { - slot->access_count--; + slot->lock_count--; return( PSA_SUCCESS ); } /* * As the return error code may not be handled in case of multiple errors, - * do our best to report if the access counter is equal to zero: if + * do our best to report if the lock counter is equal to zero: if * available call MBEDTLS_PARAM_FAILED that may terminate execution (if * called as part of the execution of a unit test suite this will stop the * test suite execution). */ #ifdef MBEDTLS_CHECK_PARAMS - MBEDTLS_PARAM_FAILED( slot->access_count > 0 ); + MBEDTLS_PARAM_FAILED( slot->lock_count > 0 ); #endif return( PSA_ERROR_CORRUPTION_DETECTED ); @@ -379,7 +377,7 @@ psa_status_t psa_open_key( mbedtls_svc_key_id_t key, psa_key_handle_t *handle ) psa_status_t status; psa_key_slot_t *slot; - status = psa_get_key_slot( key, &slot ); + status = psa_get_and_lock_key_slot( key, &slot ); if( status != PSA_SUCCESS ) { *handle = PSA_KEY_HANDLE_INIT; @@ -388,7 +386,7 @@ psa_status_t psa_open_key( mbedtls_svc_key_id_t key, psa_key_handle_t *handle ) *handle = key; - return( psa_decrement_key_slot_access_count( slot ) ); + return( psa_unlock_key_slot( slot ) ); #else /* defined(MBEDTLS_PSA_CRYPTO_STORAGE_C) */ (void) key; @@ -405,14 +403,14 @@ psa_status_t psa_close_key( psa_key_handle_t handle ) if( psa_key_handle_is_null( handle ) ) return( PSA_SUCCESS ); - status = psa_search_key_in_slots( handle, &slot ); + status = psa_get_and_lock_key_slot_in_memory( handle, &slot ); if( status != PSA_SUCCESS ) return( status ); - if( slot->access_count <= 1 ) + if( slot->lock_count <= 1 ) return( psa_wipe_key_slot( slot ) ); else - return( psa_decrement_key_slot_access_count( slot ) ); + return( psa_unlock_key_slot( slot ) ); } psa_status_t psa_purge_key( mbedtls_svc_key_id_t key ) @@ -420,15 +418,15 @@ psa_status_t psa_purge_key( mbedtls_svc_key_id_t key ) psa_status_t status; psa_key_slot_t *slot; - status = psa_search_key_in_slots( key, &slot ); + status = psa_get_and_lock_key_slot_in_memory( key, &slot ); if( status != PSA_SUCCESS ) return( status ); if( ( ! PSA_KEY_LIFETIME_IS_VOLATILE( slot->attr.lifetime ) ) && - ( slot->access_count <= 1 ) ) + ( slot->lock_count <= 1 ) ) return( psa_wipe_key_slot( slot ) ); else - return( psa_decrement_key_slot_access_count( slot ) ); + return( psa_unlock_key_slot( slot ) ); } void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats ) @@ -440,9 +438,9 @@ void mbedtls_psa_get_stats( mbedtls_psa_stats_t *stats ) for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ ) { const psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ]; - if( ! psa_is_key_slot_accessed( slot ) ) + if( ! psa_is_key_slot_locked( slot ) ) { - ++stats->unaccessed_slots; + ++stats->unlocked_slots; } if( ! psa_is_key_slot_occupied( slot ) ) { diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h index db5acba3bb..8b9d7463ac 100644 --- a/library/psa_crypto_slot_management.h +++ b/library/psa_crypto_slot_management.h @@ -61,19 +61,17 @@ static inline int psa_key_id_is_volatile( psa_key_id_t key_id ) ( key_id <= PSA_KEY_ID_VOLATILE_MAX ) ); } -/** Retrieve the description of a key given its identifier. +/** Get the description of a key given its identifier and lock it. * - * The descriptions of volatile keys and loaded persistent keys are - * stored in key slots. This function returns a pointer to the key slot - * containing the description of a key given its identifier. + * The descriptions of volatile keys and loaded persistent keys are stored in + * key slots. This function returns a pointer to the key slot containing the + * description of a key given its identifier. * - * In case of a persistent key, the function loads the description of the key - * into a key slot if not already done. + * In case of a persistent key, the function loads the description of the key + * into a key slot if not already done. * - * On success, the access counter of the returned key slot is incremented by - * one. It is the responsibility of the caller to call - * psa_decrement_key_slot_access_count() when it does not access the slot - * anymore. + * On success, the returned key slot is locked. It is the responsibility of + * the caller to unlock the key slot when it does not access it anymore. * * \param key Key identifier to query. * \param[out] p_slot On success, `*p_slot` contains a pointer to the @@ -98,8 +96,8 @@ static inline int psa_key_id_is_volatile( psa_key_id_t key_id ) * \retval #PSA_ERROR_STORAGE_FAILURE * \retval #PSA_ERROR_DATA_CORRUPT */ -psa_status_t psa_get_key_slot( mbedtls_svc_key_id_t key, - psa_key_slot_t **p_slot ); +psa_status_t psa_get_and_lock_key_slot( mbedtls_svc_key_id_t key, + psa_key_slot_t **p_slot ); /** Initialize the key slot structures. * @@ -116,10 +114,9 @@ void psa_wipe_all_key_slots( void ); /** 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). On success, the access counter of the - * returned key slot is incremented by one. It is the responsibility of the - * caller to call psa_decrement_key_slot_access_count() when it does not access - * the key slot anymore. + * ground state (all-bits-zero). On success, the key slot is locked. It is + * the responsibility of the caller to unlock the key slot when it does not + * access it anymore. * * \param[out] volatile_key_id On success, volatile key identifier * associated to the returned slot. @@ -132,31 +129,31 @@ void psa_wipe_all_key_slots( void ); psa_status_t psa_get_empty_key_slot( psa_key_id_t *volatile_key_id, psa_key_slot_t **p_slot ); -/** Increment slot access counter. +/** Lock a key slot. * - * This function increments the slot access counter by one. + * This function increments the key slot lock counter by one. * * \param[in] slot The key slot. * * \retval #PSA_SUCCESS - The access count was incremented. + The key slot lock counter was incremented. * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The access count already reached its maximum value and was not + * The lock counter already reached its maximum value and was not * increased. */ -static inline psa_status_t psa_increment_key_slot_access_count( psa_key_slot_t *slot ) +static inline psa_status_t psa_lock_key_slot( psa_key_slot_t *slot ) { - if( slot->access_count >= SIZE_MAX ) + if( slot->lock_count >= SIZE_MAX ) return( PSA_ERROR_CORRUPTION_DETECTED ); - slot->access_count++; + slot->lock_count++; return( PSA_SUCCESS ); } -/** Decrement slot access counter. +/** Unlock a key slot. * - * This function decrements the slot access counter by one. + * This function decrements the key slot lock counter by one. * * \note To ease the handling of errors in retrieving a key slot * a NULL input pointer is valid, and the function returns @@ -164,13 +161,13 @@ static inline psa_status_t psa_increment_key_slot_access_count( psa_key_slot_t * * * \param[in] slot The key slot. * \retval #PSA_SUCCESS - * \p slot is NULL or the key slot access pointer has been + * \p slot is NULL or the key slot lock counter has been * decremented successfully. * \retval #PSA_ERROR_CORRUPTION_DETECTED - * The access counter was equal to 0. + * The lock counter was equal to 0. * */ -psa_status_t psa_decrement_key_slot_access_count( psa_key_slot_t *slot ); +psa_status_t psa_unlock_key_slot( psa_key_slot_t *slot ); /** Test whether a lifetime designates a key in an external cryptoprocessor. * diff --git a/tests/include/test/psa_crypto_helpers.h b/tests/include/test/psa_crypto_helpers.h index 214ee87f3b..09171ae767 100644 --- a/tests/include/test/psa_crypto_helpers.h +++ b/tests/include/test/psa_crypto_helpers.h @@ -41,9 +41,9 @@ static int test_helper_is_psa_pristine( int line, const char *file ) msg = "An external slot has not been closed properly."; else if( stats.half_filled_slots != 0 ) msg = "A half-filled slot has not been cleared properly."; - else if( stats.unaccessed_slots != PSA_KEY_SLOT_COUNT ) + else if( stats.unlocked_slots != PSA_KEY_SLOT_COUNT ) { - msg = "Some slots are still marked as accessed."; + msg = "Some slots are still marked as locked."; } /* If the test has already failed, don't overwrite the failure