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 /* 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"
#endif

View File

@ -32,7 +32,14 @@
#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"
#else
#include "psa/crypto.h"
#endif
#include "entropy.h"
#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
#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.
*/
@ -175,7 +189,11 @@ typedef struct mbedtls_ctr_drbg_context {
* This is the maximum number of requests
* that can be made between reseedings. */
#if defined(MBEDTLS_AES_C)
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)

View File

@ -2607,6 +2607,13 @@
* The CTR_DRBG generator uses AES-256 by default.
* 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 To achieve a 256-bit security strength with CTR_DRBG,
@ -2616,7 +2623,9 @@
* Module: library/ctr_drbg.c
* 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.
*/
@ -3155,8 +3164,7 @@
*
* Module: library/psa_crypto.c
*
* Requires: MBEDTLS_CIPHER_C,
* either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
* Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C,
* or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C,
* or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG.
*

View File

@ -24,15 +24,60 @@
#include <stdio.h>
#endif
/* Using error translation functions from PSA to MbedTLS */
#if !defined(MBEDTLS_AES_C)
#include "psa_util_internal.h"
#endif
#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
*/
void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
{
memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context));
#if defined(MBEDTLS_AES_C)
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.
* See mbedtls_ctr_drbg_set_nonce_len(). */
ctx->reseed_counter = -1;
@ -56,7 +101,11 @@ void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx)
mbedtls_mutex_free(&ctx->mutex);
}
#endif
#if defined(MBEDTLS_AES_C)
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));
ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
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 chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
unsigned char *p, *iv;
mbedtls_aes_context aes_ctx;
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;
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 +
MBEDTLS_CTR_DRBG_BLOCKSIZE + 16);
mbedtls_aes_init(&aes_ctx);
/*
* Construct IV (16 bytes) and S in buffer
@ -151,10 +208,20 @@ static int block_cipher_df(unsigned char *output,
key[i] = i;
}
#if defined(MBEDTLS_AES_C)
mbedtls_aes_init(&aes_ctx);
if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
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
@ -170,10 +237,19 @@ static int block_cipher_df(unsigned char *output,
use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
chain, chain)) != 0) {
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);
@ -187,23 +263,46 @@ static int block_cipher_df(unsigned char *output,
/*
* Do final encryption with reduced data
*/
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
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;
p = output;
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,
iv, iv)) != 0) {
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);
p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
}
exit:
#if defined(MBEDTLS_AES_C)
mbedtls_aes_free(&aes_ctx);
#else
ctr_drbg_destroy_psa_contex(&psa_ctx);
#endif
/*
* tidy up the stack
*/
@ -236,6 +335,10 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
unsigned char *p = tmp;
int i, j;
int ret = 0;
#if !defined(MBEDTLS_AES_C)
psa_status_t status;
size_t tmp_len;
#endif
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
*/
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
ctx->counter, p)) != 0) {
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;
}
@ -267,10 +379,20 @@ static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
/*
* Update key and counter
*/
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
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,
MBEDTLS_CTR_DRBG_BLOCKSIZE);
@ -447,10 +569,20 @@ int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
good_nonce_len(ctx->entropy_len));
/* Initialize with an empty key. */
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
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. */
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
*/
#if defined(MBEDTLS_AES_C)
if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
ctx->counter, tmp)) != 0) {
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)
? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;

View File

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

View File

@ -23,11 +23,17 @@ typedef struct {
/* If not PSA_SUCCESS, return this error code instead of processing the
* function call. */
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. */
unsigned long hits;
unsigned long hits_encrypt;
unsigned long hits_set_iv;
} 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
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
* is called. */
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. */
psa_key_location_t location;
} 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
* (stated first in version 1.0.1 of the specification) and that it is not
* 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
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)
#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 */

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_PKCS12_C
scripts/config.py unset MBEDTLS_CTR_DRBG_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)
{
mbedtls_test_driver_cipher_hooks.hits++;
mbedtls_test_driver_cipher_hooks.hits_encrypt++;
if (mbedtls_test_driver_cipher_hooks.forced_output != NULL) {
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) {
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) && \
defined(LIBTESTDRIVER1_MBEDTLS_PSA_BUILTIN_CIPHER)
@ -208,10 +212,14 @@ psa_status_t mbedtls_test_transparent_cipher_set_iv(
size_t iv_length)
{
mbedtls_test_driver_cipher_hooks.hits++;
mbedtls_test_driver_cipher_hooks.hits_set_iv++;
if (mbedtls_test_driver_cipher_hooks.forced_status != PSA_SUCCESS) {
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) && \
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)
{
++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) {
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);
#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) {
return "A volatile slot has not been closed properly.";
}
#endif
if (stats.persistent_slots != 0) {
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 empty = { 0, 0 };
AES_PSA_INIT();
ctr_drbg_validate_internal(RESEED_NEVER, add_init,
entropy->len, entropy,
&empty, add1, add2,
result_string);
AES_PSA_DONE();
goto exit; // goto is needed to avoid warning ( no test assertions in func)
}
/* END_CASE */
@ -151,10 +153,12 @@ void ctr_drbg_validate_pr(data_t *add_init, data_t *entropy,
data_t *result_string)
{
data_t empty = { 0, 0 };
AES_PSA_INIT();
ctr_drbg_validate_internal(RESEED_ALWAYS, add_init,
entropy->len / 3, entropy,
&empty, add1, add2,
result_string);
AES_PSA_DONE();
goto exit; // goto is needed to avoid warning ( no test assertions in func)
}
/* 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 *add2, data_t *result_string)
{
AES_PSA_INIT();
ctr_drbg_validate_internal(RESEED_SECOND, add_init,
entropy->len / 2, entropy,
add_reseed, add1, add2,
result_string);
AES_PSA_DONE();
goto exit; // goto is needed to avoid warning ( no test assertions in func)
}
/* 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 *add2, data_t *result_string)
{
AES_PSA_INIT();
ctr_drbg_validate_internal(RESEED_FIRST, add_init,
entropy->len / 2, entropy,
add_reseed, add1, add2,
result_string);
AES_PSA_DONE();
goto exit; // goto is needed to avoid warning ( no test assertions in func)
}
/* END_CASE */
@ -196,6 +204,8 @@ void ctr_drbg_entropy_strength(int expected_bit_strength)
size_t byte_strength = expected_bit_strength / 8;
mbedtls_ctr_drbg_init(&ctx);
AES_PSA_INIT();
test_offset_idx = 0;
test_max_idx = sizeof(entropy);
memset(entropy, 0, sizeof(entropy));
@ -214,6 +224,7 @@ void ctr_drbg_entropy_strength(int expected_bit_strength)
exit:
mbedtls_ctr_drbg_free(&ctx);
AES_PSA_DONE();
}
/* END_CASE */
@ -228,6 +239,9 @@ void ctr_drbg_entropy_usage(int entropy_nonce_len)
size_t expected_idx = 0;
mbedtls_ctr_drbg_init(&ctx);
AES_PSA_INIT();
test_offset_idx = 0;
test_max_idx = sizeof(entropy);
memset(entropy, 0, sizeof(entropy));
@ -307,6 +321,7 @@ void ctr_drbg_entropy_usage(int entropy_nonce_len)
exit:
mbedtls_ctr_drbg_free(&ctx);
AES_PSA_DONE();
}
/* END_CASE */
@ -317,6 +332,8 @@ void ctr_drbg_seed_file(char *path, int ret)
mbedtls_ctr_drbg_init(&ctx);
AES_PSA_INIT();
TEST_ASSERT(mbedtls_ctr_drbg_seed(&ctx, mbedtls_test_rnd_std_rand,
NULL, NULL, 0) == 0);
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:
mbedtls_ctr_drbg_free(&ctx);
AES_PSA_DONE();
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void ctr_drbg_selftest()
{
AES_PSA_INIT();
TEST_ASSERT(mbedtls_ctr_drbg_self_test(1) == 0);
AES_PSA_DONE();
}
/* END_CASE */

View File

@ -845,10 +845,10 @@ void validate_key(int force_status_arg,
psa_set_key_bits(&attributes, 0);
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());
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);
TEST_EQUAL(mbedtls_test_driver_key_management_hooks.hits, 1);
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_export_public_key = 0;
mbedtls_test_driver_key_management_hooks.forced_status = force_status;
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) &&
!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) {
@ -1059,9 +1060,11 @@ void cipher_encrypt_validation(int alg_arg,
PSA_ASSERT(psa_import_key(&attributes, key_data->x, key_data->len,
&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,
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;
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,
&key));
mbedtls_test_driver_cipher_hooks.hits = 0;
PSA_ASSERT(psa_cipher_encrypt_setup(&operation, key, alg));
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1);
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,
&key));
mbedtls_test_driver_cipher_hooks.hits = 0;
PSA_ASSERT(psa_cipher_decrypt_setup(&operation, key, alg));
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits, 1);
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.hits = 0;
status = psa_cipher_decrypt(key, alg, input, input_buffer_size, output,
output_buffer_size, &output_length);
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
* successful, then force driver error.
*/
mbedtls_test_driver_cipher_hooks.hits = 0;
mbedtls_test_driver_cipher_hooks.hits_encrypt = 0;
status = psa_cipher_encrypt(
key, alg, input->x, input->len,
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);
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. */
for (size_t i = 0; i < output_buffer_size; i++) {
output[i] = 0xa5;
}
mbedtls_test_driver_cipher_hooks.hits_encrypt = 0;
status = psa_cipher_encrypt(
key, alg, input->x, input->len,
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);
/*
* 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(status, mbedtls_test_driver_cipher_hooks.forced_status);
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. */
for (size_t i = 0; i < 16; i++) {
output[i] = 0xa5;
}
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, 2);
TEST_EQUAL(status, mbedtls_test_driver_cipher_hooks.forced_status);
TEST_EQUAL(mbedtls_test_driver_cipher_hooks.hits_set_iv, 1);
TEST_EQUAL(status, mbedtls_test_driver_cipher_hooks.forced_status_set_iv);
mbedtls_test_driver_cipher_hooks.forced_status_set_iv = PSA_SUCCESS;
/*
* 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

View File

@ -746,19 +746,12 @@ void invalid_handle(int handle_construction,
* MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) is a volatile
* key identifier as the imported key is a volatile key. Volatile
* key identifiers are in the range from PSA_KEY_ID_VOLATILE_MIN
* to PSA_KEY_ID_VOLATILE_MAX included. Thus pick a key identifier
* in the range from PSA_KEY_ID_VOLATILE_MIN to
* PSA_KEY_ID_VOLATILE_MAX different from
* MBEDTLS_SVC_KEY_ID_GET_KEY_ID( valid_handle ) to build an
* unopened and thus invalid identifier.
* to PSA_KEY_ID_VOLATILE_MAX included. It is very unlikely that
* all IDs are used up to the last one, so pick
* PSA_KEY_ID_VOLATILE_MAX to build an unopened and thus invalid
* identifier.
*/
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;
}
key_id = PSA_KEY_ID_VOLATILE_MAX;
invalid_handle =
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 returned_key_id = MBEDTLS_SVC_KEY_ID_INIT;
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_CALLOC(keys, MBEDTLS_PSA_KEY_SLOT_COUNT);
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_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));
/*
* 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);
for (i = 0; i < MBEDTLS_PSA_KEY_SLOT_COUNT; i++) {
for (i = 0; i < available_key_slots; i++) {
PSA_ASSERT(psa_import_key(&attributes,
(uint8_t *) &i, sizeof(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
* 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_length));
i = MBEDTLS_PSA_KEY_SLOT_COUNT - 1;
i = available_key_slots - 1;
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.
@ -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
* 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],
exported, sizeof(exported),
&exported_length));

View File

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