Add infrastructure for key attribute flags
Add infrastructure for internal, external and dual-use flags, with a
compile-time check (if static_assert is available) to ensure that the
same numerical value doesn't get declared for two different purposes
in crypto_struct.h (external or dual-use) and
psa_crypto_core.h (internal).
diff --git a/include/psa/crypto_struct.h b/include/psa/crypto_struct.h
index 9e38e53..3bace60 100644
--- a/include/psa/crypto_struct.h
+++ b/include/psa/crypto_struct.h
@@ -322,6 +322,27 @@
* 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 @@
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 41289c6..e043d70 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -1408,6 +1408,15 @@
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 @@
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 @@
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 fbfb6da..e289dbe 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -64,6 +64,11 @@
} 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