Merge pull request #3995 from stevew817/feature/psa_configurable_static_ram_usage
Allow tweaking PSA_KEY_SLOT_COUNT
diff --git a/ChangeLog.d/psa_allow_tweaking_library_configuration.txt b/ChangeLog.d/psa_allow_tweaking_library_configuration.txt
new file mode 100644
index 0000000..78b082c
--- /dev/null
+++ b/ChangeLog.d/psa_allow_tweaking_library_configuration.txt
@@ -0,0 +1,5 @@
+Features
+ * The PSA crypto subsystem can now be configured to use less static RAM by
+ tweaking the setting for the maximum amount of keys simultaneously in RAM.
+ MBEDTLS_PSA_KEY_SLOT_COUNT sets the maximum number of volatile keys that
+ can exist simultaneously. It has a sensible default if not overridden.
diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
index c3132a5..d370dbf 100644
--- a/include/mbedtls/config.h
+++ b/include/mbedtls/config.h
@@ -3687,6 +3687,17 @@
*/
//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256
+/** \def MBEDTLS_PSA_KEY_SLOT_COUNT
+ * Restrict the PSA library to supporting a maximum amount of simultaneously
+ * loaded keys. A loaded key is a key stored by the PSA Crypto core as a
+ * volatile key, or a persistent key which is loaded temporarily by the
+ * library as part of a crypto operation in flight.
+ *
+ * If this option is unset, the library will fall back to a default value of
+ * 32 keys.
+ */
+//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
+
/* SSL Cache options */
//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */
//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
diff --git a/include/psa/crypto_extra.h b/include/psa/crypto_extra.h
index 1f3ff0d..d4a9ee4 100644
--- a/include/psa/crypto_extra.h
+++ b/include/psa/crypto_extra.h
@@ -39,6 +39,10 @@
/* UID for secure storage seed */
#define PSA_CRYPTO_ITS_RANDOM_SEED_UID 0xFFFFFF52
+/* See config.h for definition */
+#if !defined(MBEDTLS_PSA_KEY_SLOT_COUNT)
+#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
+#endif
/** \addtogroup attributes
* @{
diff --git a/library/psa_crypto_slot_management.c b/library/psa_crypto_slot_management.c
index 6dca0ef..dcbee31 100644
--- a/library/psa_crypto_slot_management.c
+++ b/library/psa_crypto_slot_management.c
@@ -45,7 +45,7 @@
typedef struct
{
- psa_key_slot_t key_slots[PSA_KEY_SLOT_COUNT];
+ psa_key_slot_t key_slots[MBEDTLS_PSA_KEY_SLOT_COUNT];
unsigned key_slots_initialized : 1;
} psa_global_data_t;
@@ -128,13 +128,13 @@
if( status != PSA_SUCCESS )
return( status );
- for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ )
+ for( slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++ )
{
slot = &global_data.key_slots[ slot_idx ];
if( mbedtls_svc_key_id_equal( key, slot->attr.id ) )
break;
}
- status = ( slot_idx < PSA_KEY_SLOT_COUNT ) ?
+ status = ( slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT ) ?
PSA_SUCCESS : PSA_ERROR_DOES_NOT_EXIST;
}
@@ -161,7 +161,7 @@
{
size_t slot_idx;
- for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ )
+ for( slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++ )
{
psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ];
slot->lock_count = 1;
@@ -184,7 +184,7 @@
}
selected_slot = unlocked_persistent_key_slot = NULL;
- for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ )
+ for( slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++ )
{
psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ];
if( ! psa_is_key_slot_occupied( slot ) )
@@ -453,7 +453,7 @@
memset( stats, 0, sizeof( *stats ) );
- for( slot_idx = 0; slot_idx < PSA_KEY_SLOT_COUNT; slot_idx++ )
+ for( slot_idx = 0; slot_idx < MBEDTLS_PSA_KEY_SLOT_COUNT; slot_idx++ )
{
const psa_key_slot_t *slot = &global_data.key_slots[ slot_idx ];
if( psa_is_key_slot_locked( slot ) )
diff --git a/library/psa_crypto_slot_management.h b/library/psa_crypto_slot_management.h
index ef0814a..3d1a852 100644
--- a/library/psa_crypto_slot_management.h
+++ b/library/psa_crypto_slot_management.h
@@ -25,14 +25,10 @@
#include "psa_crypto_core.h"
#include "psa_crypto_se.h"
-/* Number of key slots (plus one because 0 is not used).
- * The value is a compile-time constant for now, for simplicity. */
-#define PSA_KEY_SLOT_COUNT 32
-
/** Range of volatile key identifiers.
*
- * The last PSA_KEY_SLOT_COUNT identifiers of the implementation range
- * of key identifiers are reserved for volatile key identifiers.
+ * The last #MBEDTLS_PSA_KEY_SLOT_COUNT identifiers of the implementation
+ * range of key identifiers are reserved for volatile key identifiers.
* A volatile key identifier is equal to #PSA_KEY_ID_VOLATILE_MIN plus the
* index of the key slot containing the volatile key definition.
*/
@@ -40,7 +36,7 @@
/** The minimum value for a volatile key identifier.
*/
#define PSA_KEY_ID_VOLATILE_MIN ( PSA_KEY_ID_VENDOR_MAX - \
- PSA_KEY_SLOT_COUNT + 1 )
+ MBEDTLS_PSA_KEY_SLOT_COUNT + 1 )
/** The maximum value for a volatile key identifier.
*/
diff --git a/library/psa_crypto_storage.h b/library/psa_crypto_storage.h
index 8461691..970e108 100644
--- a/library/psa_crypto_storage.h
+++ b/library/psa_crypto_storage.h
@@ -49,7 +49,7 @@
* - Using the ITS backend, all key ids are ok except 0xFFFFFF52
* (#PSA_CRYPTO_ITS_RANDOM_SEED_UID) for which the file contains the
* device's random seed (if this feature is enabled).
- * - Only key ids from 1 to #PSA_KEY_SLOT_COUNT are actually used.
+ * - Only key ids from 1 to #MBEDTLS_PSA_KEY_SLOT_COUNT are actually used.
*
* Since we need to preserve the random seed, avoid using that key slot.
* Reserve a whole range of key slots just in case something else comes up.
diff --git a/programs/test/query_config.c b/programs/test/query_config.c
index 6962adf..b9105f8 100644
--- a/programs/test/query_config.c
+++ b/programs/test/query_config.c
@@ -2642,6 +2642,14 @@
}
#endif /* MBEDTLS_PSA_HMAC_DRBG_MD_TYPE */
+#if defined(MBEDTLS_PSA_KEY_SLOT_COUNT)
+ if( strcmp( "MBEDTLS_PSA_KEY_SLOT_COUNT", config ) == 0 )
+ {
+ MACRO_EXPANSION_TO_STR( MBEDTLS_PSA_KEY_SLOT_COUNT );
+ return( 0 );
+ }
+#endif /* MBEDTLS_PSA_KEY_SLOT_COUNT */
+
#if defined(MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT)
if( strcmp( "MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT", config ) == 0 )
{
diff --git a/tests/suites/test_suite_psa_crypto_slot_management.function b/tests/suites/test_suite_psa_crypto_slot_management.function
index d14dfbb..dbf05d2 100644
--- a/tests/suites/test_suite_psa_crypto_slot_management.function
+++ b/tests/suites/test_suite_psa_crypto_slot_management.function
@@ -933,9 +933,9 @@
psa_set_key_type( &attributes, PSA_KEY_TYPE_RAW_DATA );
/*
- * Create PSA_KEY_SLOT_COUNT persistent keys.
+ * Create MBEDTLS_PSA_KEY_SLOT_COUNT persistent keys.
*/
- for( i = 0; i < PSA_KEY_SLOT_COUNT; i++ )
+ for( i = 0; i < MBEDTLS_PSA_KEY_SLOT_COUNT; i++ )
{
key = mbedtls_svc_key_id_make( i, i + 1 );
psa_set_key_id( &attributes, key );
@@ -951,7 +951,7 @@
* is removed from the RAM key slots. This makes room to store its
* description in RAM.
*/
- i = PSA_KEY_SLOT_COUNT;
+ i = MBEDTLS_PSA_KEY_SLOT_COUNT;
key = mbedtls_svc_key_id_make( i, i + 1 );
psa_set_key_id( &attributes, key );
psa_set_key_lifetime( &attributes, lifetime );
@@ -966,15 +966,15 @@
MBEDTLS_SVC_KEY_ID_GET_KEY_ID( returned_key_id ) ) );
/*
- * Check that we can export all ( PSA_KEY_SLOT_COUNT + 1 ) keys,
+ * Check that we can export all ( MBEDTLS_PSA_KEY_SLOT_COUNT + 1 ) keys,
* that they have the expected value and destroy them. In that process,
* the description of the persistent key that was evicted from the RAM
* slots when creating the last key is restored in a RAM slot to export
* its value.
*/
- for( i = 0; i <= PSA_KEY_SLOT_COUNT; i++ )
+ for( i = 0; i <= MBEDTLS_PSA_KEY_SLOT_COUNT; i++ )
{
- if( i < PSA_KEY_SLOT_COUNT )
+ if( i < MBEDTLS_PSA_KEY_SLOT_COUNT )
key = mbedtls_svc_key_id_make( i, i + 1 );
else
key = returned_key_id;
@@ -1005,9 +1005,9 @@
mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
mbedtls_svc_key_id_t *keys = NULL;
- TEST_ASSERT( PSA_KEY_SLOT_COUNT >= 1 );
+ TEST_ASSERT( MBEDTLS_PSA_KEY_SLOT_COUNT >= 1 );
- ASSERT_ALLOC( keys, PSA_KEY_SLOT_COUNT );
+ ASSERT_ALLOC( keys, MBEDTLS_PSA_KEY_SLOT_COUNT );
PSA_ASSERT( psa_crypto_init( ) );
psa_set_key_usage_flags( &attributes,
@@ -1027,10 +1027,10 @@
TEST_ASSERT( mbedtls_svc_key_id_equal( returned_key_id, persistent_key ) );
/*
- * Create PSA_KEY_SLOT_COUNT volatile keys
+ * Create MBEDTLS_PSA_KEY_SLOT_COUNT volatile keys
*/
psa_set_key_lifetime( &attributes, PSA_KEY_LIFETIME_VOLATILE );
- for( i = 0; i < PSA_KEY_SLOT_COUNT; i++ )
+ for( i = 0; i < MBEDTLS_PSA_KEY_SLOT_COUNT; i++ )
{
PSA_ASSERT( psa_import_key( &attributes,
(uint8_t *) &i, sizeof( i ),
@@ -1050,12 +1050,12 @@
* Check we can export the volatile key created last and that it has the
* expected value. Then, destroy it.
*/
- PSA_ASSERT( psa_export_key( keys[PSA_KEY_SLOT_COUNT - 1],
+ PSA_ASSERT( psa_export_key( keys[MBEDTLS_PSA_KEY_SLOT_COUNT - 1],
exported, sizeof( exported ),
&exported_length ) );
- i = PSA_KEY_SLOT_COUNT - 1;
+ i = MBEDTLS_PSA_KEY_SLOT_COUNT - 1;
ASSERT_COMPARE( exported, exported_length, (uint8_t *) &i, sizeof( i ) );
- PSA_ASSERT( psa_destroy_key( keys[PSA_KEY_SLOT_COUNT - 1] ) );
+ PSA_ASSERT( psa_destroy_key( keys[MBEDTLS_PSA_KEY_SLOT_COUNT - 1] ) );
/*
* Check that we can now access the persistent key again.
@@ -1078,7 +1078,7 @@
* Check we can export the remaining volatile keys and that they have the
* expected values.
*/
- for( i = 0; i < ( PSA_KEY_SLOT_COUNT - 1 ); i++ )
+ for( i = 0; i < ( MBEDTLS_PSA_KEY_SLOT_COUNT - 1 ); i++ )
{
PSA_ASSERT( psa_export_key( keys[i],
exported, sizeof( exported ),