diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h index 9e38e53cea..3bace60885 100644 --- a/include/psa/crypto_struct.h +++ b/include/psa/crypto_struct.h @@ -322,6 +322,27 @@ typedef uint16_t psa_key_bits_t; * conditionals. */ #define PSA_MAX_KEY_BITS 0xfff8 +/** A mask of flags that can be stored in key attributes. + * + * This type is also used internally to store flags in slots. Internal + * flags are defined in library/psa_crypto_core.h. Internal flags may have + * the same value as external flags if they are properly handled during + * key creation and in psa_get_key_attributes. + */ +typedef uint16_t psa_key_attributes_flag_t; + +#define MBEDLTS_PSA_KA_FLAG_SLOT_NUMBER ( (psa_key_attributes_flag_t) 0x0001 ) + +/* A mask of key attribute flags used externally only. + * Only meant for internal checks inside the library. */ +#define MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ( \ + 0 ) + +/* A mask of key attribute flags used both internally and externally. + * Currently there aren't any. */ +#define MBEDTLS_PSA_KA_MASK_DUAL_USE ( \ + 0 ) + typedef struct { psa_key_type_t type; @@ -329,7 +350,7 @@ typedef struct psa_key_id_t id; psa_key_policy_t policy; psa_key_bits_t bits; - uint16_t flags; + psa_key_attributes_flag_t flags; } psa_core_key_attributes_t; #define PSA_CORE_KEY_ATTRIBUTES_INIT {0, 0, 0, {0, 0, 0}, 0, 0} diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 41289c607e..e043d7000e 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -1408,6 +1408,15 @@ psa_status_t psa_export_public_key( psa_key_handle_t handle, data_length, 1 ) ); } +#if defined(static_assert) +static_assert( ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0, + "One or more key attribute flag is listed as both external-only and dual-use" ); +static_assert( ( MBEDTLS_PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_DUAL_USE ) == 0, + "One or more key attribute flag is listed as both external-only and dual-use" ); +static_assert( ( MBEDTLS_PSA_KA_MASK_INTERNAL_ONLY & MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY ) == 0, + "One or more key attribute flag is listed as both internal-only and external-only" ); +#endif + /** Validate that a key policy is internally well-formed. * * This function only rejects invalid policies. It does not validate the @@ -1467,6 +1476,11 @@ static psa_status_t psa_validate_key_attributes( if( psa_get_key_bits( attributes ) > PSA_MAX_KEY_BITS ) return( PSA_ERROR_NOT_SUPPORTED ); + /* Reject invalid flags. These should not be reachable through the API. */ + if( attributes->core.flags & ~ ( MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY | + MBEDTLS_PSA_KA_MASK_DUAL_USE ) ) + return( PSA_ERROR_INVALID_ARGUMENT ); + return( PSA_SUCCESS ); } @@ -1523,6 +1537,10 @@ static psa_status_t psa_start_key_creation( slot->attr = attributes->core; + /* Erase external-only flags from the internal copy. To access + * external-only flags, query `attributes`. */ + slot->attr.flags |= ~MBEDTLS_PSA_KA_MASK_EXTERNAL_ONLY; + #if defined(MBEDTLS_PSA_CRYPTO_SE_C) /* For a key in a secure element, we need to do three things: * create the key file in internal storage, create the diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h index fbfb6daef5..e289dbeef8 100644 --- a/library/psa_crypto_core.h +++ b/library/psa_crypto_core.h @@ -64,6 +64,11 @@ typedef struct } data; } psa_key_slot_t; +/* A mask of key attribute flags used only internally. + * Currently there aren't any. */ +#define MBEDTLS_PSA_KA_MASK_INTERNAL_ONLY ( \ + 0 ) + /** Test whether a key slot is occupied. * * A key slot is occupied iff the key type is nonzero. This works because