Merge pull request #8521 from valeriosetti/issue8441

[G4] Make CTR-DRBG fall back on PSA when AES not built in
This commit is contained in:
Gilles Peskine 2023-12-06 18:25:44 +00:00 committed by GitHub
commit 57e401b39f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 303 additions and 44 deletions

View file

@ -153,7 +153,9 @@
#endif /* not all curves accelerated */ #endif /* not all curves accelerated */
#endif /* some curve accelerated */ #endif /* some curve accelerated */
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) #if defined(MBEDTLS_CTR_DRBG_C) && !(defined(MBEDTLS_AES_C) || \
(defined(MBEDTLS_PSA_CRYPTO_C) && defined(PSA_WANT_KEY_TYPE_AES) && \
defined(PSA_WANT_ALG_ECB_NO_PADDING)))
#error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites" #error "MBEDTLS_CTR_DRBG_C defined, but not all prerequisites"
#endif #endif

View file

@ -32,7 +32,14 @@
#include "mbedtls/build_info.h" #include "mbedtls/build_info.h"
/* In case AES_C is defined then it is the primary option for backward
* compatibility purposes. If that's not available, PSA is used instead */
#if defined(MBEDTLS_AES_C)
#include "mbedtls/aes.h" #include "mbedtls/aes.h"
#else
#include "psa/crypto.h"
#endif
#include "entropy.h" #include "entropy.h"
#if defined(MBEDTLS_THREADING_C) #if defined(MBEDTLS_THREADING_C)
@ -150,6 +157,13 @@ extern "C" {
#define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN (MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1) / 2 #define MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN (MBEDTLS_CTR_DRBG_ENTROPY_LEN + 1) / 2
#endif #endif
#if !defined(MBEDTLS_AES_C)
typedef struct mbedtls_ctr_drbg_psa_context {
mbedtls_svc_key_id_t key_id;
psa_cipher_operation_t operation;
} mbedtls_ctr_drbg_psa_context;
#endif
/** /**
* \brief The CTR_DRBG context structure. * \brief The CTR_DRBG context structure.
*/ */
@ -175,7 +189,11 @@ typedef struct mbedtls_ctr_drbg_context {
* This is the maximum number of requests * This is the maximum number of requests
* that can be made between reseedings. */ * that can be made between reseedings. */
#if defined(MBEDTLS_AES_C)
mbedtls_aes_context MBEDTLS_PRIVATE(aes_ctx); /*!< The AES context. */ mbedtls_aes_context MBEDTLS_PRIVATE(aes_ctx); /*!< The AES context. */
#else
mbedtls_ctr_drbg_psa_context MBEDTLS_PRIVATE(psa_ctx); /*!< The PSA context. */
#endif
/* /*
* Callbacks (Entropy) * Callbacks (Entropy)

View file

@ -2607,6 +2607,13 @@
* The CTR_DRBG generator uses AES-256 by default. * The CTR_DRBG generator uses AES-256 by default.
* To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above.
* *
* AES support can either be achived through builtin (MBEDTLS_AES_C) or PSA.
* Builtin is the default option when MBEDTLS_AES_C is defined otherwise PSA
* is used.
*
* \warning When using PSA, the user should call `psa_crypto_init()` before
* using any CTR_DRBG operation (except `mbedtls_ctr_drbg_init()`).
*
* \note AES-128 will be used if \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set. * \note AES-128 will be used if \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set.
* *
* \note To achieve a 256-bit security strength with CTR_DRBG, * \note To achieve a 256-bit security strength with CTR_DRBG,
@ -2616,7 +2623,9 @@
* Module: library/ctr_drbg.c * Module: library/ctr_drbg.c
* Caller: * Caller:
* *
* Requires: MBEDTLS_AES_C * Requires: MBEDTLS_AES_C or
* (PSA_WANT_KEY_TYPE_AES and PSA_WANT_ALG_ECB_NO_PADDING and
* MBEDTLS_PSA_CRYPTO_C)
* *
* This module provides the CTR_DRBG AES random number generator. * This module provides the CTR_DRBG AES random number generator.
*/ */
@ -3155,8 +3164,7 @@
* *
* Module: library/psa_crypto.c * Module: library/psa_crypto.c
* *
* Requires: MBEDTLS_CIPHER_C, * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
* either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
* or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C, * or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C,
* or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
* *

View file

@ -24,15 +24,60 @@
#include <stdio.h> #include <stdio.h>
#endif #endif
/* Using error translation functions from PSA to MbedTLS */
#if !defined(MBEDTLS_AES_C)
#include "psa_util_internal.h"
#endif
#include "mbedtls/platform.h" #include "mbedtls/platform.h"
#if !defined(MBEDTLS_AES_C)
static psa_status_t ctr_drbg_setup_psa_context(mbedtls_ctr_drbg_psa_context *psa_ctx,
unsigned char *key, size_t key_len)
{
psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
psa_status_t status;
psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT);
psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
status = psa_import_key(&key_attr, key, key_len, &psa_ctx->key_id);
if (status != PSA_SUCCESS) {
goto exit;
}
status = psa_cipher_encrypt_setup(&psa_ctx->operation, psa_ctx->key_id, PSA_ALG_ECB_NO_PADDING);
if (status != PSA_SUCCESS) {
goto exit;
}
exit:
psa_reset_key_attributes(&key_attr);
return status;
}
static void ctr_drbg_destroy_psa_contex(mbedtls_ctr_drbg_psa_context *psa_ctx)
{
psa_cipher_abort(&psa_ctx->operation);
psa_destroy_key(psa_ctx->key_id);
psa_ctx->operation = psa_cipher_operation_init();
psa_ctx->key_id = MBEDTLS_SVC_KEY_ID_INIT;
}
#endif
/* /*
* CTR_DRBG context initialization * CTR_DRBG context initialization
*/ */
void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx) void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
{ {
memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context)); memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context));
#if defined(MBEDTLS_AES_C)
mbedtls_aes_init(&ctx->aes_ctx); mbedtls_aes_init(&ctx->aes_ctx);
#else
ctx->psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
ctx->psa_ctx.operation = psa_cipher_operation_init();
#endif
/* Indicate that the entropy nonce length is not set explicitly. /* Indicate that the entropy nonce length is not set explicitly.
* See mbedtls_ctr_drbg_set_nonce_len(). */ * See mbedtls_ctr_drbg_set_nonce_len(). */
ctx->reseed_counter = -1; ctx->reseed_counter = -1;
@ -56,7 +101,11 @@ void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx)
mbedtls_mutex_free(&ctx->mutex); mbedtls_mutex_free(&ctx->mutex);
} }
#endif #endif
#if defined(MBEDTLS_AES_C)
mbedtls_aes_free(&ctx->aes_ctx); mbedtls_aes_free(&ctx->aes_ctx);
#else
ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
#endif
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context)); mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
ctx->reseed_counter = -1; ctx->reseed_counter = -1;
@ -117,8 +166,17 @@ static int block_cipher_df(unsigned char *output,
unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
unsigned char *p, *iv; unsigned char *p, *iv;
mbedtls_aes_context aes_ctx;
int ret = 0; int ret = 0;
#if defined(MBEDTLS_AES_C)
mbedtls_aes_context aes_ctx;
#else
psa_status_t status;
size_t tmp_len;
mbedtls_ctr_drbg_psa_context psa_ctx;
psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
psa_ctx.operation = psa_cipher_operation_init();
#endif
int i, j; int i, j;
size_t buf_len, use_len; size_t buf_len, use_len;
@ -129,7 +187,6 @@ static int block_cipher_df(unsigned char *output,
memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
MBEDTLS_CTR_DRBG_BLOCKSIZE + 16); MBEDTLS_CTR_DRBG_BLOCKSIZE + 16);
mbedtls_aes_init(&aes_ctx);
/* /*
* Construct IV (16 bytes) and S in buffer * Construct IV (16 bytes) and S in buffer
@ -151,10 +208,20 @@ static int block_cipher_df(unsigned char *output,
key[i] = i; key[i] = i;
} }
#if defined(MBEDTLS_AES_C)
mbedtls_aes_init(&aes_ctx);
if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key, if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
goto exit; goto exit;
} }
#else
status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key));
if (status != PSA_SUCCESS) {
ret = psa_generic_status_to_mbedtls(status);
goto exit;
}
#endif
/* /*
* Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
@ -170,10 +237,19 @@ static int block_cipher_df(unsigned char *output,
use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ? use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
chain, chain)) != 0) { chain, chain)) != 0) {
goto exit; goto exit;
} }
#else
status = psa_cipher_update(&psa_ctx.operation, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE,
chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
if (status != PSA_SUCCESS) {
ret = psa_generic_status_to_mbedtls(status);
goto exit;
}
#endif
} }
memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE); memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE);
@ -187,23 +263,46 @@ static int block_cipher_df(unsigned char *output,
/* /*
* Do final encryption with reduced data * Do final encryption with reduced data
*/ */
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp, if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
goto exit; goto exit;
} }
#else
ctr_drbg_destroy_psa_contex(&psa_ctx);
status = ctr_drbg_setup_psa_context(&psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
if (status != PSA_SUCCESS) {
ret = psa_generic_status_to_mbedtls(status);
goto exit;
}
#endif
iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
p = output; p = output;
for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) { for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT, if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
iv, iv)) != 0) { iv, iv)) != 0) {
goto exit; goto exit;
} }
#else
status = psa_cipher_update(&psa_ctx.operation, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE,
iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
if (status != PSA_SUCCESS) {
ret = psa_generic_status_to_mbedtls(status);
goto exit;
}
#endif
memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE); memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
p += MBEDTLS_CTR_DRBG_BLOCKSIZE; p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
} }
exit: exit:
#if defined(MBEDTLS_AES_C)
mbedtls_aes_free(&aes_ctx); mbedtls_aes_free(&aes_ctx);
#else
ctr_drbg_destroy_psa_contex(&psa_ctx);
#endif
/* /*
* tidy up the stack * tidy up the stack
*/ */
@ -236,6 +335,10 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
unsigned char *p = tmp; unsigned char *p = tmp;
int i, j; int i, j;
int ret = 0; int ret = 0;
#if !defined(MBEDTLS_AES_C)
psa_status_t status;
size_t tmp_len;
#endif
memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN); memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
@ -252,10 +355,19 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
/* /*
* Crypt counter block * Crypt counter block
*/ */
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
ctx->counter, p)) != 0) { ctx->counter, p)) != 0) {
goto exit; goto exit;
} }
#else
status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
p, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
if (status != PSA_SUCCESS) {
ret = psa_generic_status_to_mbedtls(status);
goto exit;
}
#endif
p += MBEDTLS_CTR_DRBG_BLOCKSIZE; p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
} }
@ -267,10 +379,20 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
/* /*
* Update key and counter * Update key and counter
*/ */
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp, if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
goto exit; goto exit;
} }
#else
ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
if (status != PSA_SUCCESS) {
ret = psa_generic_status_to_mbedtls(status);
goto exit;
}
#endif
memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
MBEDTLS_CTR_DRBG_BLOCKSIZE); MBEDTLS_CTR_DRBG_BLOCKSIZE);
@ -447,10 +569,20 @@ int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
good_nonce_len(ctx->entropy_len)); good_nonce_len(ctx->entropy_len));
/* Initialize with an empty key. */ /* Initialize with an empty key. */
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key, if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) { MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
return ret; return ret;
} }
#else
psa_status_t status;
status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, key, MBEDTLS_CTR_DRBG_KEYSIZE);
if (status != PSA_SUCCESS) {
ret = psa_generic_status_to_mbedtls(status);
return status;
}
#endif
/* Do the initial seeding. */ /* Do the initial seeding. */
if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len, if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len,
@ -531,10 +663,22 @@ int mbedtls_ctr_drbg_random_with_add(void *p_rng,
/* /*
* Crypt counter block * Crypt counter block
*/ */
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
ctx->counter, tmp)) != 0) { ctx->counter, tmp)) != 0) {
goto exit; goto exit;
} }
#else
psa_status_t status;
size_t tmp_len;
status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
if (status != PSA_SUCCESS) {
ret = psa_generic_status_to_mbedtls(status);
goto exit;
}
#endif
use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE) use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE)
? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len; ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;

View file

@ -7714,6 +7714,11 @@ psa_status_t psa_crypto_init(void)
} }
global_data.drivers_initialized = 1; global_data.drivers_initialized = 1;
status = psa_initialize_key_slots();
if (status != PSA_SUCCESS) {
goto exit;
}
/* Initialize and seed the random generator. */ /* Initialize and seed the random generator. */
mbedtls_psa_random_init(&global_data.rng); mbedtls_psa_random_init(&global_data.rng);
global_data.rng_state = RNG_INITIALIZED; global_data.rng_state = RNG_INITIALIZED;
@ -7723,11 +7728,6 @@ psa_status_t psa_crypto_init(void)
} }
global_data.rng_state = RNG_SEEDED; global_data.rng_state = RNG_SEEDED;
status = psa_initialize_key_slots();
if (status != PSA_SUCCESS) {
goto exit;
}
#if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS) #if defined(PSA_CRYPTO_STORAGE_HAS_TRANSACTIONS)
status = psa_crypto_load_transaction(); status = psa_crypto_load_transaction();
if (status == PSA_SUCCESS) { if (status == PSA_SUCCESS) {

View file

@ -23,11 +23,17 @@ typedef struct {
/* If not PSA_SUCCESS, return this error code instead of processing the /* If not PSA_SUCCESS, return this error code instead of processing the
* function call. */ * function call. */
psa_status_t forced_status; psa_status_t forced_status;
psa_status_t forced_status_encrypt;
psa_status_t forced_status_set_iv;
/* Count the amount of times one of the cipher driver functions is called. */ /* Count the amount of times one of the cipher driver functions is called. */
unsigned long hits; unsigned long hits;
unsigned long hits_encrypt;
unsigned long hits_set_iv;
} mbedtls_test_driver_cipher_hooks_t; } mbedtls_test_driver_cipher_hooks_t;
#define MBEDTLS_TEST_DRIVER_CIPHER_INIT { NULL, 0, PSA_SUCCESS, 0 } #define MBEDTLS_TEST_DRIVER_CIPHER_INIT { NULL, 0, \
PSA_SUCCESS, PSA_SUCCESS, PSA_SUCCESS, \
0, 0, 0 }
static inline mbedtls_test_driver_cipher_hooks_t static inline mbedtls_test_driver_cipher_hooks_t
mbedtls_test_driver_cipher_hooks_init(void) mbedtls_test_driver_cipher_hooks_init(void)
{ {

View file

@ -26,6 +26,8 @@ typedef struct {
/* Count the amount of times one of the key management driver functions /* Count the amount of times one of the key management driver functions
* is called. */ * is called. */
unsigned long hits; unsigned long hits;
/* Subset of hits which only counts key operations with EC key */
unsigned long hits_export_public_key;
/* Location of the last key management driver called to import a key. */ /* Location of the last key management driver called to import a key. */
psa_key_location_t location; psa_key_location_t location;
} mbedtls_test_driver_key_management_hooks_t; } mbedtls_test_driver_key_management_hooks_t;
@ -34,7 +36,7 @@ typedef struct {
* sense that no PSA specification will assign a meaning to this location * sense that no PSA specification will assign a meaning to this location
* (stated first in version 1.0.1 of the specification) and that it is not * (stated first in version 1.0.1 of the specification) and that it is not
* used as a location of an opaque test drivers. */ * used as a location of an opaque test drivers. */
#define MBEDTLS_TEST_DRIVER_KEY_MANAGEMENT_INIT { NULL, 0, PSA_SUCCESS, 0, 0x800000 } #define MBEDTLS_TEST_DRIVER_KEY_MANAGEMENT_INIT { NULL, 0, PSA_SUCCESS, 0, 0, 0x800000 }
static inline mbedtls_test_driver_key_management_hooks_t static inline mbedtls_test_driver_key_management_hooks_t
mbedtls_test_driver_key_management_hooks_init(void) mbedtls_test_driver_key_management_hooks_init(void)
{ {

View file

@ -392,4 +392,27 @@ uint64_t mbedtls_test_parse_binary_string(data_t *bin_string);
#define MD_OR_USE_PSA_DONE() ((void) 0) #define MD_OR_USE_PSA_DONE() ((void) 0)
#endif #endif
/** \def AES_PSA_INIT
*
* Call this macro to initialize the PSA subsystem if AES_C is not defined,
* so that CTR_DRBG uses PSA implementation to get AES-ECB.
*
* If the initialization fails, mark the test case as failed and jump to the
* \p exit label.
*/
/** \def AES_PSA_DONE
*
* Call this macro at the end of a test case if you called #AES_PSA_INIT.
*
* This is like #PSA_DONE except it does nothing under the same conditions as
* #AES_PSA_INIT.
*/
#if defined(MBEDTLS_AES_C)
#define AES_PSA_INIT() ((void) 0)
#define AES_PSA_DONE() ((void) 0)
#else /* MBEDTLS_AES_C */
#define AES_PSA_INIT() PSA_INIT()
#define AES_PSA_DONE() PSA_DONE()
#endif /* MBEDTLS_AES_C */
#endif /* PSA_CRYPTO_HELPERS_H */ #endif /* PSA_CRYPTO_HELPERS_H */

View file

@ -3729,7 +3729,6 @@ common_psa_crypto_config_accel_cipher_aead() {
scripts/config.py unset MBEDTLS_PKCS5_C scripts/config.py unset MBEDTLS_PKCS5_C
scripts/config.py unset MBEDTLS_PKCS12_C scripts/config.py unset MBEDTLS_PKCS12_C
scripts/config.py unset MBEDTLS_CTR_DRBG_C
scripts/config.py unset MBEDTLS_NIST_KW_C scripts/config.py unset MBEDTLS_NIST_KW_C
} }

View file

@ -41,6 +41,7 @@ psa_status_t mbedtls_test_transparent_cipher_encrypt(
size_t *output_length) size_t *output_length)
{ {
mbedtls_test_driver_cipher_hooks.hits++; mbedtls_test_driver_cipher_hooks.hits++;
mbedtls_test_driver_cipher_hooks.hits_encrypt++;
if (mbedtls_test_driver_cipher_hooks.forced_output != NULL) { if (mbedtls_test_driver_cipher_hooks.forced_output != NULL) {
if (output_size < mbedtls_test_driver_cipher_hooks.forced_output_length) { if (output_size < mbedtls_test_driver_cipher_hooks.forced_output_length) {
@ -58,6 +59,9 @@ psa_status_t mbedtls_test_transparent_cipher_encrypt(
if (mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS) { if (mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS) {
return mbedtls_test_driver_cipher_hooks.forced_status; return mbedtls_test_driver_cipher_hooks.forced_status;
} }
if (mbedtls_test_driver_cipher_hooks.forced_status_encrypt != PSA_SUCCESS) {
return mbedtls_test_driver_cipher_hooks.forced_status_encrypt;
}
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ #if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_CIPHER) defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_CIPHER)
@ -208,10 +212,14 @@ psa_status_t mbedtls_test_transparent_cipher_set_iv(
size_t iv_length) size_t iv_length)
{ {
mbedtls_test_driver_cipher_hooks.hits++; mbedtls_test_driver_cipher_hooks.hits++;
mbedtls_test_driver_cipher_hooks.hits_set_iv++;
if (mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS) { if (mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS) {
return mbedtls_test_driver_cipher_hooks.forced_status; return mbedtls_test_driver_cipher_hooks.forced_status;
} }
if (mbedtls_test_driver_cipher_hooks.forced_status_set_iv != PSA_SUCCESS) {
return mbedtls_test_driver_cipher_hooks.forced_status_set_iv;
}
#if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \ #if defined(MBEDTLS_TEST_LIBTESTDRIVER1) && \
defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_CIPHER) defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_CIPHER)

View file

@ -529,6 +529,7 @@ psa_status_t mbedtls_test_transparent_export_public_key(
uint8_t *data, size_t data_size, size_t *data_length) uint8_t *data, size_t data_size, size_t *data_length)
{ {
++mbedtls_test_driver_key_management_hooks.hits; ++mbedtls_test_driver_key_management_hooks.hits;
++mbedtls_test_driver_key_management_hooks.hits_export_public_key;
if (mbedtls_test_driver_key_management_hooks.forced_status != PSA_SUCCESS) { if (mbedtls_test_driver_key_management_hooks.forced_status != PSA_SUCCESS) {
return mbedtls_test_driver_key_management_hooks.forced_status; return mbedtls_test_driver_key_management_hooks.forced_status;

View file

@ -70,9 +70,20 @@ const char *mbedtls_test_helper_is_psa_leaking(void)
mbedtls_psa_get_stats(&stats); mbedtls_psa_get_stats(&stats);
#if defined(MBEDTLS_CTR_DRBG_C) && !defined(MBEDTLS_AES_C) && \
!defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
/* When AES_C is not defined and PSA does not have an external RNG,
* then CTR_DRBG uses PSA to perform AES-ECB. In this scenario 1 key
* slot is used internally from PSA to hold the AES key and it should
* not be taken into account when evaluating remaining open slots. */
if (stats.volatile_slots > 1) {
return "A volatile slot has not been closed properly.";
}
#else
if (stats.volatile_slots != 0) { if (stats.volatile_slots != 0) {
return "A volatile slot has not been closed properly."; return "A volatile slot has not been closed properly.";
} }
#endif
if (stats.persistent_slots != 0) { if (stats.persistent_slots != 0) {
return "A persistent slot has not been closed properly."; return "A persistent slot has not been closed properly.";
} }

View file

@ -137,10 +137,12 @@ void ctr_drbg_validate_no_reseed(data_t *add_init, data_t *entropy,
data_t *result_string) data_t *result_string)
{ {
data_t empty = { 0, 0 }; data_t empty = { 0, 0 };
AES_PSA_INIT();
ctr_drbg_validate_internal(RESEED_NEVER, add_init, ctr_drbg_validate_internal(RESEED_NEVER, add_init,
entropy->len, entropy, entropy->len, entropy,
&empty, add1, add2, &empty, add1, add2,
result_string); result_string);
AES_PSA_DONE();
goto exit; // goto is needed to avoid warning ( no test assertions in func) goto exit; // goto is needed to avoid warning ( no test assertions in func)
} }
/* END_CASE */ /* END_CASE */
@ -151,10 +153,12 @@ void ctr_drbg_validate_pr(data_t *add_init, data_t *entropy,
data_t *result_string) data_t *result_string)
{ {
data_t empty = { 0, 0 }; data_t empty = { 0, 0 };
AES_PSA_INIT();
ctr_drbg_validate_internal(RESEED_ALWAYS, add_init, ctr_drbg_validate_internal(RESEED_ALWAYS, add_init,
entropy->len / 3, entropy, entropy->len / 3, entropy,
&empty, add1, add2, &empty, add1, add2,
result_string); result_string);
AES_PSA_DONE();
goto exit; // goto is needed to avoid warning ( no test assertions in func) goto exit; // goto is needed to avoid warning ( no test assertions in func)
} }
/* END_CASE */ /* END_CASE */
@ -164,10 +168,12 @@ void ctr_drbg_validate_reseed_between(data_t *add_init, data_t *entropy,
data_t *add1, data_t *add_reseed, data_t *add1, data_t *add_reseed,
data_t *add2, data_t *result_string) data_t *add2, data_t *result_string)
{ {
AES_PSA_INIT();
ctr_drbg_validate_internal(RESEED_SECOND, add_init, ctr_drbg_validate_internal(RESEED_SECOND, add_init,
entropy->len / 2, entropy, entropy->len / 2, entropy,
add_reseed, add1, add2, add_reseed, add1, add2,
result_string); result_string);
AES_PSA_DONE();
goto exit; // goto is needed to avoid warning ( no test assertions in func) goto exit; // goto is needed to avoid warning ( no test assertions in func)
} }
/* END_CASE */ /* END_CASE */
@ -177,10 +183,12 @@ void ctr_drbg_validate_reseed_first(data_t *add_init, data_t *entropy,
data_t *add1, data_t *add_reseed, data_t *add1, data_t *add_reseed,
data_t *add2, data_t *result_string) data_t *add2, data_t *result_string)
{ {
AES_PSA_INIT();
ctr_drbg_validate_internal(RESEED_FIRST, add_init, ctr_drbg_validate_internal(RESEED_FIRST, add_init,
entropy->len / 2, entropy, entropy->len / 2, entropy,
add_reseed, add1, add2, add_reseed, add1, add2,
result_string); result_string);
AES_PSA_DONE();
goto exit; // goto is needed to avoid warning ( no test assertions in func) goto exit; // goto is needed to avoid warning ( no test assertions in func)
} }
/* END_CASE */ /* END_CASE */
@ -196,6 +204,8 @@ void ctr_drbg_entropy_strength(int expected_bit_strength)
size_t byte_strength = expected_bit_strength / 8; size_t byte_strength = expected_bit_strength / 8;
mbedtls_ctr_drbg_init(&ctx); mbedtls_ctr_drbg_init(&ctx);
AES_PSA_INIT();
test_offset_idx = 0; test_offset_idx = 0;
test_max_idx = sizeof(entropy); test_max_idx = sizeof(entropy);
memset(entropy, 0, sizeof(entropy)); memset(entropy, 0, sizeof(entropy));
@ -214,6 +224,7 @@ void ctr_drbg_entropy_strength(int expected_bit_strength)
exit: exit:
mbedtls_ctr_drbg_free(&ctx); mbedtls_ctr_drbg_free(&ctx);
AES_PSA_DONE();
} }
/* END_CASE */ /* END_CASE */
@ -228,6 +239,9 @@ void ctr_drbg_entropy_usage(int entropy_nonce_len)
size_t expected_idx = 0; size_t expected_idx = 0;
mbedtls_ctr_drbg_init(&ctx); mbedtls_ctr_drbg_init(&ctx);
AES_PSA_INIT();
test_offset_idx = 0; test_offset_idx = 0;
test_max_idx = sizeof(entropy); test_max_idx = sizeof(entropy);
memset(entropy, 0, sizeof(entropy)); memset(entropy, 0, sizeof(entropy));
@ -307,6 +321,7 @@ void ctr_drbg_entropy_usage(int entropy_nonce_len)
exit: exit:
mbedtls_ctr_drbg_free(&ctx); mbedtls_ctr_drbg_free(&ctx);
AES_PSA_DONE();
} }
/* END_CASE */ /* END_CASE */
@ -317,6 +332,8 @@ void ctr_drbg_seed_file(char *path, int ret)
mbedtls_ctr_drbg_init(&ctx); mbedtls_ctr_drbg_init(&ctx);
AES_PSA_INIT();
TEST_ASSERT(mbedtls_ctr_drbg_seed(&ctx, mbedtls_test_rnd_std_rand, TEST_ASSERT(mbedtls_ctr_drbg_seed(&ctx, mbedtls_test_rnd_std_rand,
NULL, NULL, 0) == 0); NULL, NULL, 0) == 0);
TEST_ASSERT(mbedtls_ctr_drbg_write_seed_file(&ctx, path) == ret); TEST_ASSERT(mbedtls_ctr_drbg_write_seed_file(&ctx, path) == ret);
@ -324,12 +341,15 @@ void ctr_drbg_seed_file(char *path, int ret)
exit: exit:
mbedtls_ctr_drbg_free(&ctx); mbedtls_ctr_drbg_free(&ctx);
AES_PSA_DONE();
} }
/* END_CASE */ /* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void ctr_drbg_selftest() void ctr_drbg_selftest()
{ {
AES_PSA_INIT();
TEST_ASSERT(mbedtls_ctr_drbg_self_test(1) == 0); TEST_ASSERT(mbedtls_ctr_drbg_self_test(1) == 0);
AES_PSA_DONE();
} }
/* END_CASE */ /* END_CASE */

View file

@ -845,10 +845,10 @@ void validate_key(int force_status_arg,
psa_set_key_bits(&attributes, 0); psa_set_key_bits(&attributes, 0);
psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT); psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
mbedtls_test_driver_key_management_hooks.forced_status = force_status;
PSA_ASSERT(psa_crypto_init()); PSA_ASSERT(psa_crypto_init());
mbedtls_test_driver_key_management_hooks.hits = 0;
mbedtls_test_driver_key_management_hooks.forced_status = force_status;
actual_status = psa_import_key(&attributes, key_input->x, key_input->len, &key); actual_status = psa_import_key(&attributes, key_input->x, key_input->len, &key);
TEST_EQUAL(mbedtls_test_driver_key_management_hooks.hits, 1); TEST_EQUAL(mbedtls_test_driver_key_management_hooks.hits, 1);
TEST_EQUAL(actual_status, expected_status); TEST_EQUAL(actual_status, expected_status);
@ -906,6 +906,7 @@ void export_key(int force_status_arg,
} }
mbedtls_test_driver_key_management_hooks.hits = 0; mbedtls_test_driver_key_management_hooks.hits = 0;
mbedtls_test_driver_key_management_hooks.hits_export_public_key = 0;
mbedtls_test_driver_key_management_hooks.forced_status = force_status; mbedtls_test_driver_key_management_hooks.forced_status = force_status;
if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(output_key_type)) { if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(output_key_type)) {
@ -923,7 +924,7 @@ void export_key(int force_status_arg,
if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(output_key_type) && if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(output_key_type) &&
!PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(input_key_type)) { !PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(input_key_type)) {
TEST_EQUAL(mbedtls_test_driver_key_management_hooks.hits, 1); TEST_EQUAL(mbedtls_test_driver_key_management_hooks.hits_export_public_key, 1);
} }
if (actual_status == PSA_SUCCESS) { if (actual_status == PSA_SUCCESS) {
@ -1059,9 +1060,11 @@ void cipher_encrypt_validation(int alg_arg,
PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len,
&key)); &key));
mbedtls_test_driver_cipher_hooks.hits = 0;
mbedtls_test_driver_cipher_hooks.hits_encrypt = 0;
PSA_ASSERT(psa_cipher_encrypt(key, alg, input->x, input->len, output1, PSA_ASSERT(psa_cipher_encrypt(key, alg, input->x, input->len, output1,
output1_buffer_size, &output1_length)); output1_buffer_size, &output1_length));
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1); TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits_encrypt, 1);
mbedtls_test_driver_cipher_hooks.hits = 0; mbedtls_test_driver_cipher_hooks.hits = 0;
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg)); PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
@ -1161,6 +1164,7 @@ void cipher_encrypt_multipart(int alg_arg,
PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len,
&key)); &key));
mbedtls_test_driver_cipher_hooks.hits = 0;
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg)); PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1); TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1);
mbedtls_test_driver_cipher_hooks.hits = 0; mbedtls_test_driver_cipher_hooks.hits = 0;
@ -1289,6 +1293,7 @@ void cipher_decrypt_multipart(int alg_arg,
PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len, PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len,
&key)); &key));
mbedtls_test_driver_cipher_hooks.hits = 0;
PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg)); PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1); TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1);
mbedtls_test_driver_cipher_hooks.hits = 0; mbedtls_test_driver_cipher_hooks.hits = 0;
@ -1414,6 +1419,7 @@ void cipher_decrypt(int alg_arg,
mbedtls_test_driver_cipher_hooks.forced_output_length = expected_output->len; mbedtls_test_driver_cipher_hooks.forced_output_length = expected_output->len;
} }
mbedtls_test_driver_cipher_hooks.hits = 0;
status = psa_cipher_decrypt(key, alg, input, input_buffer_size, output, status = psa_cipher_decrypt(key, alg, input, input_buffer_size, output,
output_buffer_size, &output_length); output_buffer_size, &output_length);
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1); TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1);
@ -1468,23 +1474,26 @@ void cipher_entry_points(int alg_arg, int key_type_arg,
* First test that if we don't force a driver error, encryption is * First test that if we don't force a driver error, encryption is
* successful, then force driver error. * successful, then force driver error.
*/ */
mbedtls_test_driver_cipher_hooks.hits = 0;
mbedtls_test_driver_cipher_hooks.hits_encrypt = 0;
status = psa_cipher_encrypt( status = psa_cipher_encrypt(
key, alg, input->x, input->len, key, alg, input->x, input->len,
output, output_buffer_size, &function_output_length); output, output_buffer_size, &function_output_length);
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1); TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits_encrypt, 1);
TEST_EQUAL(status, PSA_SUCCESS); TEST_EQUAL(status, PSA_SUCCESS);
mbedtls_test_driver_cipher_hooks.hits = 0; mbedtls_test_driver_cipher_hooks.hits = 0;
mbedtls_test_driver_cipher_hooks.forced_status = PSA_ERROR_GENERIC_ERROR; mbedtls_test_driver_cipher_hooks.forced_status_encrypt = PSA_ERROR_GENERIC_ERROR;
/* Set the output buffer in a given state. */ /* Set the output buffer in a given state. */
for (size_t i = 0; i < output_buffer_size; i++) { for (size_t i = 0; i < output_buffer_size; i++) {
output[i] = 0xa5; output[i] = 0xa5;
} }
mbedtls_test_driver_cipher_hooks.hits_encrypt = 0;
status = psa_cipher_encrypt( status = psa_cipher_encrypt(
key, alg, input->x, input->len, key, alg, input->x, input->len,
output, output_buffer_size, &function_output_length); output, output_buffer_size, &function_output_length);
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1); TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits_encrypt, 1);
TEST_EQUAL(status, PSA_ERROR_GENERIC_ERROR); TEST_EQUAL(status, PSA_ERROR_GENERIC_ERROR);
/* /*
* Check that the output buffer is still in the same state. * Check that the output buffer is still in the same state.
@ -1545,17 +1554,18 @@ void cipher_entry_points(int alg_arg, int key_type_arg,
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1); TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1);
TEST_EQUAL(status, mbedtls_test_driver_cipher_hooks.forced_status); TEST_EQUAL(status, mbedtls_test_driver_cipher_hooks.forced_status);
mbedtls_test_driver_cipher_hooks.hits = 0; mbedtls_test_driver_cipher_hooks.hits = 0;
mbedtls_test_driver_cipher_hooks.hits_set_iv = 0;
mbedtls_test_driver_cipher_hooks.forced_status = PSA_ERROR_GENERIC_ERROR; mbedtls_test_driver_cipher_hooks.forced_status_set_iv = PSA_ERROR_GENERIC_ERROR;
/* Set the output buffer in a given state. */ /* Set the output buffer in a given state. */
for (size_t i = 0; i < 16; i++) { for (size_t i = 0; i < 16; i++) {
output[i] = 0xa5; output[i] = 0xa5;
} }
status = psa_cipher_generate_iv(&operation, output, 16, &function_output_length); status = psa_cipher_generate_iv(&operation, output, 16, &function_output_length);
/* When generating the IV fails, it should call abort too */ TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits_set_iv, 1);
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 2); TEST_EQUAL(status, mbedtls_test_driver_cipher_hooks.forced_status_set_iv);
TEST_EQUAL(status, mbedtls_test_driver_cipher_hooks.forced_status); mbedtls_test_driver_cipher_hooks.forced_status_set_iv = PSA_SUCCESS;
/* /*
* Check that the output buffer is still in the same state. * Check that the output buffer is still in the same state.
* This will fail if the output buffer is used by the core to pass the IV * This will fail if the output buffer is used by the core to pass the IV

View file

@ -746,19 +746,12 @@ void invalid_handle(int handle_construction,
* MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) is a volatile * MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) is a volatile
* key identifier as the imported key is a volatile key. Volatile * key identifier as the imported key is a volatile key. Volatile
* key identifiers are in the range from PSA_KEY_ID_VOLATILE_MIN * key identifiers are in the range from PSA_KEY_ID_VOLATILE_MIN
* to PSA_KEY_ID_VOLATILE_MAX included. Thus pick a key identifier * to PSA_KEY_ID_VOLATILE_MAX included. It is very unlikely that
* in the range from PSA_KEY_ID_VOLATILE_MIN to * all IDs are used up to the last one, so pick
* PSA_KEY_ID_VOLATILE_MAX different from * PSA_KEY_ID_VOLATILE_MAX to build an unopened and thus invalid
* MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) to build an * identifier.
* unopened and thus invalid identifier.
*/ */
key_id = PSA_KEY_ID_VOLATILE_MAX;
if (MBEDTLS_SVC_KEY_ID_GET_KEY_ID(valid_handle) ==
PSA_KEY_ID_VOLATILE_MIN) {
key_id = PSA_KEY_ID_VOLATILE_MIN + 1;
} else {
key_id = MBEDTLS_SVC_KEY_ID_GET_KEY_ID(valid_handle) - 1;
}
invalid_handle = invalid_handle =
mbedtls_svc_key_id_make(0, key_id); mbedtls_svc_key_id_make(0, key_id);
@ -938,11 +931,16 @@ void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation()
mbedtls_svc_key_id_t persistent_key2 = MBEDTLS_SVC_KEY_ID_INIT; mbedtls_svc_key_id_t persistent_key2 = MBEDTLS_SVC_KEY_ID_INIT;
mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT; mbedtls_svc_key_id_t returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
mbedtls_svc_key_id_t *keys = NULL; mbedtls_svc_key_id_t *keys = NULL;
mbedtls_psa_stats_t psa_key_slots_stats;
size_t available_key_slots = 0;
TEST_ASSERT(MBEDTLS_PSA_KEY_SLOT_COUNT >= 1); TEST_ASSERT(MBEDTLS_PSA_KEY_SLOT_COUNT >= 1);
TEST_CALLOC(keys, MBEDTLS_PSA_KEY_SLOT_COUNT);
PSA_ASSERT(psa_crypto_init()); PSA_ASSERT(psa_crypto_init());
mbedtls_psa_get_stats(&psa_key_slots_stats);
available_key_slots = psa_key_slots_stats.empty_slots;
TEST_CALLOC(keys, available_key_slots);
psa_set_key_usage_flags(&attributes, psa_set_key_usage_flags(&attributes,
PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY); PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_COPY);
@ -961,10 +959,10 @@ void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation()
TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, persistent_key)); TEST_ASSERT(mbedtls_svc_key_id_equal(returned_key_id, persistent_key));
/* /*
* Create MBEDTLS_PSA_KEY_SLOT_COUNT volatile keys * Create the maximum available number of volatile keys
*/ */
psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE); psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
for (i = 0; i < MBEDTLS_PSA_KEY_SLOT_COUNT; i++) { for (i = 0; i < available_key_slots; i++) {
PSA_ASSERT(psa_import_key(&attributes, PSA_ASSERT(psa_import_key(&attributes,
(uint8_t *) &i, sizeof(i), (uint8_t *) &i, sizeof(i),
&keys[i])); &keys[i]));
@ -983,12 +981,12 @@ void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation()
* Check we can export the volatile key created last and that it has the * Check we can export the volatile key created last and that it has the
* expected value. Then, destroy it. * expected value. Then, destroy it.
*/ */
PSA_ASSERT(psa_export_key(keys[MBEDTLS_PSA_KEY_SLOT_COUNT - 1], PSA_ASSERT(psa_export_key(keys[available_key_slots - 1],
exported, sizeof(exported), exported, sizeof(exported),
&exported_length)); &exported_length));
i = MBEDTLS_PSA_KEY_SLOT_COUNT - 1; i = available_key_slots - 1;
TEST_MEMORY_COMPARE(exported, exported_length, (uint8_t *) &i, sizeof(i)); TEST_MEMORY_COMPARE(exported, exported_length, (uint8_t *) &i, sizeof(i));
PSA_ASSERT(psa_destroy_key(keys[MBEDTLS_PSA_KEY_SLOT_COUNT - 1])); PSA_ASSERT(psa_destroy_key(keys[available_key_slots - 1]));
/* /*
* Check that we can now access the persistent key again. * Check that we can now access the persistent key again.
@ -1011,7 +1009,7 @@ void non_reusable_key_slots_integrity_in_case_of_key_slot_starvation()
* Check we can export the remaining volatile keys and that they have the * Check we can export the remaining volatile keys and that they have the
* expected values. * expected values.
*/ */
for (i = 0; i < (MBEDTLS_PSA_KEY_SLOT_COUNT - 1); i++) { for (i = 0; i < (available_key_slots - 1); i++) {
PSA_ASSERT(psa_export_key(keys[i], PSA_ASSERT(psa_export_key(keys[i],
exported, sizeof(exported), exported, sizeof(exported),
&exported_length)); &exported_length));

View file

@ -26,7 +26,12 @@ void random_twice_with_ctr_drbg()
unsigned char output1[OUTPUT_SIZE]; unsigned char output1[OUTPUT_SIZE];
unsigned char output2[OUTPUT_SIZE]; unsigned char output2[OUTPUT_SIZE];
#if defined(MBEDTLS_AES_C)
MD_PSA_INIT(); MD_PSA_INIT();
#else
USE_PSA_INIT();
#endif
/* First round */ /* First round */
mbedtls_entropy_init(&entropy); mbedtls_entropy_init(&entropy);
@ -56,7 +61,11 @@ void random_twice_with_ctr_drbg()
exit: exit:
mbedtls_ctr_drbg_free(&drbg); mbedtls_ctr_drbg_free(&drbg);
mbedtls_entropy_free(&entropy); mbedtls_entropy_free(&entropy);
#if defined(MBEDTLS_AES_C)
MD_PSA_DONE(); MD_PSA_DONE();
#else
USE_PSA_DONE();
#endif
} }
/* END_CASE */ /* END_CASE */