Skip to content

Commit 325d390

Browse files
valeriosettifrkv
authored andcommitted
[nrf fromtree] psa: use static key slot buffers to store key material
This commit takes only relevant changes of PR Mbed-TLS/mbedtls#9448 that was merged in upstream Mbed TLS in the LTS branch "mbedtls-3.6". Since the original PR was made of several commits, but most of them were only affecting tests cases (not used in Zephyr), only changes belonging to the "include" and "library" folders were included here. == IMPORTANT == Changes introduced in this commit will be automatically part of Mbed TLS release 3.6.3, so by the time Zephyr's Mbed TLS fork repo is bumbed to that official release, this commit MUST be discarded. This commit introduces the possibility to use static key slot buffers in the PSA core instead of dynamically allocating them when needed. This helps reducing heap memory usage as well as potentially removing heap management ROM code if heap is not used anywhere else in the Zephyr application. Signed-off-by: Valerio Setti <vsetti@baylibre.com> Signed-off-by: Frank Audun Kvamtrø <frank.kvamtro@nordicsemi.no> (Cherry-picked from commit 4952e1328529ee549d412b498ea71c54f30aa3b1)
1 parent 98603a8 commit 325d390

9 files changed

+104
-10
lines changed

include/library/psa_crypto_core.h

+4
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,11 @@ typedef struct {
155155
/* Dynamically allocated key data buffer.
156156
* Format as specified in psa_export_key(). */
157157
struct key_data {
158+
#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
159+
uint8_t data[MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE];
160+
#else
158161
uint8_t *data;
162+
#endif
159163
size_t bytes;
160164
} key;
161165
} psa_key_slot_t;

include/library/psa_crypto_storage.h

+9-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,16 @@ extern "C" {
2121
#include <stdint.h>
2222
#include <string.h>
2323

24-
/* Limit the maximum key size in storage. This should have no effect
25-
* since the key size is limited in memory. */
24+
/* Limit the maximum key size in storage. */
25+
#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
26+
/* Reflect the maximum size for the key buffer. */
27+
#define PSA_CRYPTO_MAX_STORAGE_SIZE (MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE)
28+
#else
29+
/* Just set an upper boundary but it should have no effect since the key size
30+
* is limited in memory. */
2631
#define PSA_CRYPTO_MAX_STORAGE_SIZE (PSA_BITS_TO_BYTES(PSA_MAX_KEY_BITS))
32+
#endif
33+
2734
/* Sanity check: a file size must fit in 32 bits. Allow a generous
2835
* 64kB of metadata. */
2936
#if PSA_CRYPTO_MAX_STORAGE_SIZE > 0xffff0000

include/mbedtls/check_config.h

+5
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,11 @@
741741
#error "MBEDTLS_PSA_INJECT_ENTROPY is not compatible with MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG"
742742
#endif
743743

744+
#if defined(MBEDTLS_PSA_KEY_STORE_DYNAMIC) && \
745+
defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
746+
#error "MBEDTLS_PSA_KEY_STORE_DYNAMIC and MBEDTLS_PSA_STATIC_KEY_SLOTS cannot be defined simultaneously"
747+
#endif
748+
744749
#if defined(MBEDTLS_PSA_ITS_FILE_C) && \
745750
!defined(MBEDTLS_FS_IO)
746751
#error "MBEDTLS_PSA_ITS_FILE_C defined, but not all prerequisites"

include/mbedtls/entropy.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717

1818
#include "md.h"
1919

20-
#if defined(MBEDTLS_MD_CAN_SHA512) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256)
20+
#if (defined(MBEDTLS_MD_CAN_SHA512) || defined(PSA_WANT_ALG_SHA_512)) && \
21+
!defined(MBEDTLS_ENTROPY_FORCE_SHA256)
2122
#define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
2223
#define MBEDTLS_ENTROPY_MD MBEDTLS_MD_SHA512
2324
#define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */
2425
#else
25-
#if defined(MBEDTLS_MD_CAN_SHA256)
26+
#if (defined(MBEDTLS_MD_CAN_SHA256) || defined(PSA_WANT_ALG_SHA_256))
2627
#define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR
2728
#define MBEDTLS_ENTROPY_MD MBEDTLS_MD_SHA256
2829
#define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */

include/mbedtls/mbedtls_config.h

+33
Original file line numberDiff line numberDiff line change
@@ -3268,6 +3268,26 @@
32683268
*/
32693269
#define MBEDTLS_PSA_ITS_FILE_C
32703270

3271+
/**
3272+
* \def MBEDTLS_PSA_STATIC_KEY_SLOTS
3273+
*
3274+
* Statically preallocate memory to store keys' material in PSA instead
3275+
* of allocating it dynamically when required. This allows builds without a
3276+
* heap, if none of the enabled cryptographic implementations or other features
3277+
* require it.
3278+
* This feature affects both volatile and persistent keys which means that
3279+
* it's not possible to persistently store a key which is larger than
3280+
* #MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE.
3281+
*
3282+
* \note This feature comes with a (potentially) higher RAM usage since:
3283+
* - All the key slots are allocated no matter if they are used or not.
3284+
* - Each key buffer's length is #MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE bytes.
3285+
*
3286+
* Requires: MBEDTLS_PSA_CRYPTO_C
3287+
*
3288+
*/
3289+
//#define MBEDTLS_PSA_STATIC_KEY_SLOTS
3290+
32713291
/**
32723292
* \def MBEDTLS_RIPEMD160_C
32733293
*
@@ -4069,6 +4089,19 @@
40694089
*/
40704090
//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
40714091

4092+
/**
4093+
* \def MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE
4094+
*
4095+
* Define the size (in bytes) of each static key buffer when
4096+
* #MBEDTLS_PSA_STATIC_KEY_SLOTS is set. If not
4097+
* explicitly defined then it's automatically guessed from available PSA keys
4098+
* enabled in the build through PSA_WANT_xxx symbols.
4099+
* If required by the application this parameter can be set to higher values
4100+
* in order to store larger objects (ex: raw keys), but please note that this
4101+
* will increase RAM usage.
4102+
*/
4103+
//#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE 256
4104+
40724105
/* RSA OPTIONS */
40734106
//#define MBEDTLS_RSA_GEN_KEY_MIN_BITS 1024 /**< Minimum RSA key size that can be generated in bits (Minimum possible value is 128 bits) */
40744107

include/psa/crypto_extra.h

+10
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ extern "C" {
3232
#define MBEDTLS_PSA_KEY_SLOT_COUNT 32
3333
#endif
3434

35+
/* If the size of static key slots is not explicitly defined by the user, then
36+
* set it to the maximum between PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE and
37+
* PSA_CIPHER_MAX_KEY_LENGTH.
38+
* See mbedtls_config.h for the definition. */
39+
#if !defined(MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE)
40+
#define MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE \
41+
((PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE > PSA_CIPHER_MAX_KEY_LENGTH) ? \
42+
PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE : PSA_CIPHER_MAX_KEY_LENGTH)
43+
#endif /* !MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE*/
44+
3545
/** \addtogroup attributes
3646
* @{
3747
*/

include/psa/crypto_sizes.h

+25
Original file line numberDiff line numberDiff line change
@@ -1038,6 +1038,10 @@
10381038
PSA_KEY_EXPORT_FFDH_PUBLIC_KEY_MAX_SIZE(PSA_VENDOR_FFDH_MAX_KEY_BITS)
10391039
#endif
10401040

1041+
#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \
1042+
((PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \
1043+
PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE)
1044+
10411045
/** Sufficient output buffer size for psa_raw_key_agreement().
10421046
*
10431047
* This macro returns a compile-time constant if its arguments are
@@ -1085,6 +1089,27 @@
10851089
#define PSA_RAW_KEY_AGREEMENT_OUTPUT_MAX_SIZE PSA_BITS_TO_BYTES(PSA_VENDOR_FFDH_MAX_KEY_BITS)
10861090
#endif
10871091

1092+
/** Maximum key length for ciphers.
1093+
*
1094+
* Since there is no additional PSA_WANT_xxx symbol to specifiy the size of
1095+
* the key once a cipher is enabled (as it happens for asymmetric keys for
1096+
* example), the maximum key length is taken into account for each cipher.
1097+
* The resulting value will be the maximum cipher's key length given depending
1098+
* on which ciphers are enabled.
1099+
*
1100+
* Note: max value for AES used below would be doubled if XTS were enabled, but
1101+
* this mode is currently not supported in Mbed TLS implementation of PSA
1102+
* APIs.
1103+
*/
1104+
#if (defined(PSA_WANT_KEY_TYPE_AES) || defined(PSA_WANT_KEY_TYPE_ARIA) || \
1105+
defined(PSA_WANT_KEY_TYPE_CAMELLIA) || defined(PSA_WANT_KEY_TYPE_CHACHA20))
1106+
#define PSA_CIPHER_MAX_KEY_LENGTH 32u
1107+
#elif defined(PSA_WANT_KEY_TYPE_DES)
1108+
#define PSA_CIPHER_MAX_KEY_LENGTH 24u
1109+
#else
1110+
#define PSA_CIPHER_MAX_KEY_LENGTH 0u
1111+
#endif
1112+
10881113
/** The default IV size for a cipher algorithm, in bytes.
10891114
*
10901115
* The IV that is generated as part of a call to #psa_cipher_encrypt() is always

library/pk.c

-4
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@
3535
#include <limits.h>
3636
#include <stdint.h>
3737

38-
#define PSA_EXPORT_KEY_PAIR_OR_PUBLIC_MAX_SIZE \
39-
(PSA_EXPORT_KEY_PAIR_MAX_SIZE > PSA_EXPORT_PUBLIC_KEY_MAX_SIZE) ? \
40-
PSA_EXPORT_KEY_PAIR_MAX_SIZE : PSA_EXPORT_PUBLIC_KEY_MAX_SIZE
41-
4238
/*
4339
* Initialise a mbedtls_pk_context
4440
*/

library/psa_crypto.c

+15-2
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,11 @@ MBEDTLS_STATIC_TESTABLE psa_status_t psa_mac_key_can_do(
710710
psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot,
711711
size_t buffer_length)
712712
{
713+
#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
714+
if (buffer_length > ((size_t) MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE)) {
715+
return PSA_ERROR_NOT_SUPPORTED;
716+
}
717+
#else
713718
if (slot->key.data != NULL) {
714719
return PSA_ERROR_ALREADY_EXISTS;
715720
}
@@ -718,6 +723,7 @@ psa_status_t psa_allocate_buffer_to_slot(psa_key_slot_t *slot,
718723
if (slot->key.data == NULL) {
719724
return PSA_ERROR_INSUFFICIENT_MEMORY;
720725
}
726+
#endif
721727

722728
slot->key.bytes = buffer_length;
723729
return PSA_SUCCESS;
@@ -1186,11 +1192,18 @@ static psa_status_t psa_get_and_lock_transparent_key_slot_with_policy(
11861192

11871193
psa_status_t psa_remove_key_data_from_memory(psa_key_slot_t *slot)
11881194
{
1195+
#if defined(MBEDTLS_PSA_STATIC_KEY_SLOTS)
1196+
if (slot->key.bytes > 0) {
1197+
mbedtls_platform_zeroize(slot->key.data, MBEDTLS_PSA_STATIC_KEY_SLOT_BUFFER_SIZE);
1198+
}
1199+
#else
11891200
if (slot->key.data != NULL) {
11901201
mbedtls_zeroize_and_free(slot->key.data, slot->key.bytes);
11911202
}
11921203

11931204
slot->key.data = NULL;
1205+
#endif /* MBEDTLS_PSA_STATIC_KEY_SLOTS */
1206+
11941207
slot->key.bytes = 0;
11951208

11961209
return PSA_SUCCESS;
@@ -2109,7 +2122,7 @@ psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
21092122
* storage ( thus not in the case of importing a key in a secure element
21102123
* with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
21112124
* buffer to hold the imported key material. */
2112-
if (slot->key.data == NULL) {
2125+
if (slot->key.bytes == 0) {
21132126
if (psa_key_lifetime_is_external(attributes->lifetime)) {
21142127
status = psa_driver_wrapper_get_key_buffer_size_from_key_data(
21152128
attributes, data, data_length, &storage_size);
@@ -8026,7 +8039,7 @@ psa_status_t psa_generate_key_custom(const psa_key_attributes_t *attributes,
80268039
* storage ( thus not in the case of generating a key in a secure element
80278040
* with storage ( MBEDTLS_PSA_CRYPTO_SE_C ) ),we have to allocate a
80288041
* buffer to hold the generated key material. */
8029-
if (slot->key.data == NULL) {
8042+
if (slot->key.bytes == 0) {
80308043
if (PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime) ==
80318044
PSA_KEY_LOCATION_LOCAL_STORAGE) {
80328045
status = psa_validate_key_type_and_size_for_key_generation(

0 commit comments

Comments
 (0)