psa: allow to use static key buffers instead of dynamic ones
This helps reducing heap memory usage and, if heap memory is
not used anywhere else in an embedded device, it also reduces
code footprint since there is no need for heap management code
in this case.
A new build symbol is added for this purpose, named
MBEDTLS_PSA_STATIC_KEY_SLOTS. It's disabled by default so that
normal usage of Mbed TLS library is not affected.
Signed-off-by: Valerio Setti <valerio.setti@nordicsemi.no>
diff --git a/library/pk.c b/library/pk.c
index 3fe51ea..51f0c24 100644
--- a/library/pk.c
+++ b/library/pk.c
@@ -35,10 +35,6 @@
#include <limits.h>
#include <stdint.h>
-#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \
- (PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \
- PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
-
/*
* Initialise a mbedtls_pk_context
*/
diff --git a/library/psa_crypto.c b/library/psa_crypto.c
index c4f41db..696e830 100644
--- a/library/psa_crypto.c
+++ b/library/psa_crypto.c
@@ -705,6 +705,17 @@
psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot,
size_t buffer_length)
{
+#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
+ if (slot->key.in_use) {
+ return PSA_ERROR_ALREADY_EXISTS;
+ }
+
+ if (buffer_length > ((size_t) MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE)) {
+ return PSA_ERROR_NOT_SUPPORTED;
+ }
+
+ slot->key.in_use = 1;
+#else
if (slot->key.data != NULL) {
return PSA_ERROR_ALREADY_EXISTS;
}
@@ -713,6 +724,7 @@
if (slot->key.data == NULL) {
return PSA_ERROR_INSUFFICIENT_MEMORY;
}
+#endif
slot->key.bytes = buffer_length;
return PSA_SUCCESS;
@@ -1177,11 +1189,16 @@
psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot)
{
+#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
+ slot->key.in_use = 0;
+#else /* MBEDTLS_PSA_STATIC_KEY_SLOTS */
if (slot->key.data != NULL) {
mbedtls_zeroize_and_free(slot->key.data, slot->key.bytes);
}
slot->key.data = NULL;
+#endif /* MBEDTLS_PSA_STATIC_KEY_SLOTS */
+
slot->key.bytes = 0;
return PSA_SUCCESS;
@@ -2096,7 +2113,13 @@
* storage ( thus not in the case of importing a key in a secure element
* with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
* buffer to hold the imported key material. */
- if (slot->key.data == NULL) {
+#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
+ int is_slot_unused = (slot->key.in_use == 0);
+#else
+ int is_slot_unused = (slot->key.data == NULL);
+#endif
+
+ if (is_slot_unused) {
if (psa_key_lifetime_is_external(attributes->lifetime)) {
status = psa_driver_wrapper_get_key_buffer_size_from_key_data(
attributes, data, data_length, &storage_size);
@@ -8013,7 +8036,13 @@
* storage ( thus not in the case of generating a key in a secure element
* with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
* buffer to hold the generated key material. */
- if (slot->key.data == NULL) {
+#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
+ int is_slot_unused = (slot->key.in_use == 0);
+#else
+ int is_slot_unused = (slot->key.data == NULL);
+#endif
+
+ if (is_slot_unused) {
if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime) ==
PSA_KEY_LOCATION_LOCAL_STORAGE) {
status = psa_validate_key_type_and_size_for_key_generation(
diff --git a/library/psa_crypto_core.h b/library/psa_crypto_core.h
index 21e7559..5f59697 100644
--- a/library/psa_crypto_core.h
+++ b/library/psa_crypto_core.h
@@ -55,6 +55,12 @@
PSA_SLOT_PENDING_DELETION,
} psa_key_slot_state_t;
+/* If the size of static key slots is not explicitly defined by the user, then
+ * set it to PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE. */
+#if !defined(MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE)
+#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE (PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE)
+#endif /* !MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE*/
+
/** The data structure representing a key slot, containing key material
* and metadata for one key.
*/
@@ -155,7 +161,12 @@
/* Dynamically allocated key data buffer.
* Format as specified in psa_export_key(). */
struct key_data {
+#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
+ int in_use;
+ uint8_t data[MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE];
+#else /* MBEDTLS_PSA_STATIC_KEY_SLOTS */
uint8_t *data;
+#endif /* MBEDTLS_PSA_STATIC_KEY_SLOTS */
size_t bytes;
} key;
} psa_key_slot_t;