diff --git a/library/psa_crypto.c b/library/psa_crypto.c index 910de1f03..233a19ede 100644 --- a/library/psa_crypto.c +++ b/library/psa_crypto.c @@ -43,6 +43,7 @@ #include "psa/crypto.h" +#include "psa_crypto_invasive.h" /* Include internal declarations that are useful for implementing persistently * stored keys. */ #include "psa_crypto_storage.h" @@ -146,12 +147,23 @@ static int key_type_is_raw_bytes( psa_key_type_t type ) return( PSA_KEY_TYPE_IS_UNSTRUCTURED( type ) ); } +enum rng_state +{ + RNG_NOT_INITIALIZED = 0, + RNG_INITIALIZED, + RNG_SEEDED, +}; + typedef struct { - int initialized; + void (* entropy_init )( mbedtls_entropy_context *ctx ); + void (* entropy_free )( mbedtls_entropy_context *ctx ); mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; key_slot_t key_slots[PSA_KEY_SLOT_COUNT]; + unsigned initialized : 1; + enum rng_state rng_state : 2; + unsigned key_slots_initialized : 1; } psa_global_data_t; static psa_global_data_t global_data; @@ -4439,23 +4451,42 @@ psa_status_t psa_generate_key( psa_key_slot_t key, /* Module setup */ /****************************************************************/ +psa_status_t mbedtls_psa_crypto_configure_entropy_sources( + void (* entropy_init )( mbedtls_entropy_context *ctx ), + void (* entropy_free )( mbedtls_entropy_context *ctx ) ) +{ + if( global_data.rng_state != RNG_NOT_INITIALIZED ) + return( PSA_ERROR_BAD_STATE ); + global_data.entropy_init = entropy_init; + global_data.entropy_free = entropy_free; + return( PSA_SUCCESS ); +} + void mbedtls_psa_crypto_free( void ) { psa_key_slot_t key; key_slot_t *slot; psa_status_t status; - - for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ ) + if( global_data.key_slots_initialized ) { - status = psa_get_key_slot( key, &slot ); - if( status != PSA_SUCCESS ) - continue; - psa_remove_key_data_from_memory( slot ); - /* Zeroize the slot to wipe metadata such as policies. */ - mbedtls_zeroize( slot, sizeof( *slot ) ); + for( key = 1; key <= PSA_KEY_SLOT_COUNT; key++ ) + { + status = psa_get_key_slot( key, &slot ); + if( status != PSA_SUCCESS ) + continue; + psa_remove_key_data_from_memory( slot ); + /* Zeroize the slot to wipe metadata such as policies. */ + mbedtls_zeroize( slot, sizeof( *slot ) ); + } } - mbedtls_ctr_drbg_free( &global_data.ctr_drbg ); - mbedtls_entropy_free( &global_data.entropy ); + if( global_data.rng_state != RNG_NOT_INITIALIZED ) + { + mbedtls_ctr_drbg_free( &global_data.ctr_drbg ); + global_data.entropy_free( &global_data.entropy ); + } + /* Wipe all remaining data, including configuration. + * In particular, this sets all state indicator to the value + * indicating "uninitialized". */ mbedtls_zeroize( &global_data, sizeof( global_data ) ); } @@ -4464,20 +4495,35 @@ psa_status_t psa_crypto_init( void ) int ret; const unsigned char drbg_seed[] = "PSA"; + /* Double initialization is explicitly allowed. */ if( global_data.initialized != 0 ) return( PSA_SUCCESS ); - mbedtls_zeroize( &global_data, sizeof( global_data ) ); - mbedtls_entropy_init( &global_data.entropy ); - mbedtls_ctr_drbg_init( &global_data.ctr_drbg ); + /* Set default configuration if + * mbedtls_psa_crypto_configure_entropy_sources() hasn't been called. */ + if( global_data.entropy_init == NULL ) + global_data.entropy_init = mbedtls_entropy_init; + if( global_data.entropy_free == NULL ) + global_data.entropy_free = mbedtls_entropy_free; + /* Initialize the random generator. */ + global_data.entropy_init( &global_data.entropy ); + mbedtls_ctr_drbg_init( &global_data.ctr_drbg ); + global_data.rng_state = RNG_INITIALIZED; ret = mbedtls_ctr_drbg_seed( &global_data.ctr_drbg, mbedtls_entropy_func, &global_data.entropy, drbg_seed, sizeof( drbg_seed ) - 1 ); if( ret != 0 ) goto exit; + global_data.rng_state = RNG_SEEDED; + /* Initialize the key slots. Zero-initialization has made all key + * slots empty, so there is nothing to do. In a future version we will + * load data from storage. */ + global_data.key_slots_initialized = 1; + + /* All done. */ global_data.initialized = 1; exit: diff --git a/library/psa_crypto_invasive.h b/library/psa_crypto_invasive.h new file mode 100644 index 000000000..642652a47 --- /dev/null +++ b/library/psa_crypto_invasive.h @@ -0,0 +1,79 @@ +/** + * \file psa_crypto_invasive.h + * + * \brief PSA cryptography module: invasive interfaces for test only. + * + * The interfaces in this file are intended for testing purposes only. + * They MUST NOT be made available to clients over IPC in integrations + * with isolation, and they SHOULD NOT be made available in library + * integrations except when building the library for testing. + */ +/* + * Copyright (C) 2018, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#ifndef PSA_CRYPTO_INVASIVE_H +#define PSA_CRYPTO_INVASIVE_H + +#if defined(MBEDTLS_CONFIG_FILE) +#include MBEDTLS_CONFIG_FILE +#else +#include "mbedtls/config.h" +#endif + +#include "psa/crypto.h" + +#include "mbedtls/entropy.h" + +/** \brief Configure entropy sources. + * + * This function may only be called before a call to psa_crypto_init(), + * or after a call to mbedtls_psa_crypto_free() and before any + * subsequent call to psa_crypto_init(). + * + * This function is only intended for test purposes. The functionality + * it provides is also useful for system integrators, but + * system integrators should configure entropy drivers instead of + * breaking through to the Mbed TLS API. + * + * \param entropy_init Function to initialize the entropy context + * and set up the desired entropy sources. + * It is called by psa_crypto_init(). + * By default this is mbedtls_entropy_init(). + * This function cannot report failures directly. + * To indicate a failure, set the entropy context + * to a state where mbedtls_entropy_func() will + * return an error. + * \param entropy_free Function to free the entropy context + * and associated resources. + * It is called by mbedtls_psa_crypto_free(). + * By default this is mbedtls_entropy_free(). + * + * \retval PSA_SUCCESS + * Success. + * \retval PSA_ERROR_NOT_PERMITTED + * The caller does not have the permission to configure + * entropy sources. + * \retval PSA_ERROR_BAD_STATE + * The library has already been initialized. + */ +psa_status_t mbedtls_psa_crypto_configure_entropy_sources( + void (* entropy_init )( mbedtls_entropy_context *ctx ), + void (* entropy_free )( mbedtls_entropy_context *ctx ) ); + +#endif /* PSA_CRYPTO_INVASIVE_H */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 95d60ff31..56ce9338a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -113,6 +113,7 @@ add_test_suite(poly1305) add_test_suite(psa_crypto) add_test_suite(psa_crypto_entropy) add_test_suite(psa_crypto_hash) +add_test_suite(psa_crypto_init) add_test_suite(psa_crypto_metadata) add_test_suite(psa_crypto_persistent_key) add_test_suite(psa_crypto_storage_file) diff --git a/tests/suites/test_suite_psa_crypto.data b/tests/suites/test_suite_psa_crypto.data index 6087412be..91739f55e 100644 --- a/tests/suites/test_suite_psa_crypto.data +++ b/tests/suites/test_suite_psa_crypto.data @@ -1,9 +1,6 @@ PSA compile-time sanity checks static_checks: -PSA init/deinit -init_deinit: - PSA fill 250 slots fill_slots:250 @@ -1829,12 +1826,6 @@ PSA generate key: ECC, SECP256R1, incorrect bit size depends_on:MBEDTLS_ECP_C:MBEDTLS_ECP_DP_SECP256R1_ENABLED:MBEDTLS_ECDSA_C generate_key:PSA_KEY_TYPE_ECC_KEYPAIR(PSA_ECC_CURVE_SECP256R1):128:PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN | PSA_KEY_USAGE_VERIFY:PSA_ALG_ECDSA_ANY:PSA_ERROR_INVALID_ARGUMENT -PSA validate module initialization: random -validate_module_init_generate_random: - -PSA validate module initialization: key based -validate_module_init_key_based: - persistent key can be accessed after in-memory deletion: AES, 128 bits, CTR depends_on:MBEDTLS_PK_C:MBEDTLS_PK_PARSE_C:MBEDTLS_RSA_C:MBEDTLS_PSA_CRYPTO_STORAGE_C persistent_key_load_key_from_storage:"2b7e151628aed2a6abf7158809cf4f3c":PSA_KEY_TYPE_AES:128:PSA_KEY_USAGE_EXPORT:PSA_ALG_CTR:IMPORT_KEY:PSA_SUCCESS diff --git a/tests/suites/test_suite_psa_crypto.function b/tests/suites/test_suite_psa_crypto.function index 53295befa..2fa060b25 100644 --- a/tests/suites/test_suite_psa_crypto.function +++ b/tests/suites/test_suite_psa_crypto.function @@ -871,22 +871,6 @@ void static_checks( ) } /* END_CASE */ -/* BEGIN_CASE */ -void init_deinit( ) -{ - psa_status_t status; - int i; - for( i = 0; i <= 1; i++ ) - { - status = psa_crypto_init( ); - TEST_ASSERT( status == PSA_SUCCESS ); - status = psa_crypto_init( ); - TEST_ASSERT( status == PSA_SUCCESS ); - mbedtls_psa_crypto_free( ); - } -} -/* END_CASE */ - /* BEGIN_CASE */ void fill_slots( int max_arg ) { @@ -4018,26 +4002,6 @@ exit: } /* END_CASE */ -/* BEGIN_CASE */ -void validate_module_init_generate_random( ) -{ - psa_status_t status; - uint8_t random[10] = { 0 }; - status = psa_generate_random( random, sizeof( random ) ); - TEST_ASSERT( status == PSA_ERROR_BAD_STATE ); -} -/* END_CASE */ - -/* BEGIN_CASE */ -void validate_module_init_key_based( ) -{ - psa_status_t status; - uint8_t data[10] = { 0 }; - status = psa_import_key( 1, PSA_KEY_TYPE_RAW_DATA, data, sizeof( data ) ); - TEST_ASSERT( status == PSA_ERROR_BAD_STATE ); -} -/* END_CASE */ - /* BEGIN_CASE depends_on:MBEDTLS_PSA_CRYPTO_STORAGE_C */ void persistent_key_load_key_from_storage( data_t *data, int type_arg, int bits, int usage_arg, diff --git a/tests/suites/test_suite_psa_crypto_init.data b/tests/suites/test_suite_psa_crypto_init.data new file mode 100644 index 000000000..c57a764ef --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_init.data @@ -0,0 +1,56 @@ +Create NV seed file +create_nv_seed: + +PSA init/deinit +init_deinit:2 + +PSA deinit without init +deinit_without_init:0 + +PSA deinit twice +deinit_without_init:1 + +No random without init +validate_module_init_generate_random:0 + +No key slot access without init +validate_module_init_key_based:0 + +No random after deinit +validate_module_init_generate_random:1 + +No key slot access after deinit +validate_module_init_key_based:1 + +Custom entropy sources: all standard +custom_entropy_sources:0x0000ffff:PSA_SUCCESS + +Custom entropy sources: none +custom_entropy_sources:0:PSA_ERROR_INSUFFICIENT_ENTROPY + +Fake entropy: never returns anything +fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:0:0:0:0:PSA_ERROR_INSUFFICIENT_ENTROPY + +Fake entropy: less than the block size +fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:-1:-1:-1:PSA_ERROR_INSUFFICIENT_ENTROPY + +Fake entropy: one block eventually +fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:0:0:0:MBEDTLS_ENTROPY_BLOCK_SIZE:PSA_SUCCESS + +Fake entropy: one block in two steps +fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:1:-1:-1:PSA_SUCCESS + +Fake entropy: more than one block in two steps +fake_entropy_source:MBEDTLS_ENTROPY_BLOCK_SIZE:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:-1:-1:PSA_SUCCESS + +NV seed only: less than minimum +entropy_from_nv_seed:MBEDTLS_ENTROPY_MIN_PLATFORM - 1:PSA_ERROR_INSUFFICIENT_ENTROPY + +NV seed only: less than one block +entropy_from_nv_seed:MBEDTLS_ENTROPY_BLOCK_SIZE - 1:PSA_ERROR_INSUFFICIENT_ENTROPY + +NV seed only: just enough +entropy_from_nv_seed:ENTROPY_MIN_NV_SEED_SIZE:PSA_SUCCESS + +Recreate NV seed file +create_nv_seed: diff --git a/tests/suites/test_suite_psa_crypto_init.function b/tests/suites/test_suite_psa_crypto_init.function new file mode 100644 index 000000000..359650429 --- /dev/null +++ b/tests/suites/test_suite_psa_crypto_init.function @@ -0,0 +1,294 @@ +/* BEGIN_HEADER */ +#include + +#if defined(MBEDTLS_PSA_CRYPTO_SPM) +#include "spm/psa_defs.h" +#endif +#include "psa/crypto.h" + +/* Some tests in this module configure entropy sources. */ +#include "psa_crypto_invasive.h" + +#include "mbedtls/entropy.h" +#include "mbedtls/entropy_poll.h" +#include "mbedtls/platform.h" + +#define MIN( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#define MAX( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) + +#define ENTROPY_MIN_NV_SEED_SIZE \ + MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE) + +typedef struct +{ + size_t threshold; /* Minimum bytes to make mbedtls_entropy_func happy */ + size_t max_steps; + size_t *length_sequence; + size_t step; +} fake_entropy_state_t; +static int fake_entropy_source( void *state_arg, + unsigned char *output, size_t len, + size_t *olen ) +{ + fake_entropy_state_t *state = state_arg; + size_t i; + + if( state->step >= state->max_steps ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + *olen = MIN( len, state->length_sequence[state->step] ); + for( i = 0; i < *olen; i++ ) + output[i] = i; + ++state->step; + return( 0 ); +}; + +#define ENTROPY_SOURCE_PLATFORM 0x00000001 +#define ENTROPY_SOURCE_TIMING 0x00000002 +#define ENTROPY_SOURCE_HAVEGE 0x00000004 +#define ENTROPY_SOURCE_HARDWARE 0x00000008 +#define ENTROPY_SOURCE_NV_SEED 0x00000010 +#define ENTROPY_SOURCE_FAKE 0x40000000 + +static uint32_t custom_entropy_sources_mask; +static fake_entropy_state_t fake_entropy_state; + +/* This is a modified version of mbedtls_entropy_init() from entropy.c + * which chooses entropy sources dynamically. */ +static void custom_entropy_init( mbedtls_entropy_context *ctx ) +{ + ctx->source_count = 0; + memset( ctx->source, 0, sizeof( ctx->source ) ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif + + ctx->accumulator_started = 0; +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) + mbedtls_sha512_init( &ctx->accumulator ); +#else + mbedtls_sha256_init( &ctx->accumulator ); +#endif +#if defined(MBEDTLS_HAVEGE_C) + mbedtls_havege_init( &ctx->havege_data ); +#endif + +#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) + if( custom_entropy_sources_mask & ENTROPY_SOURCE_PLATFORM ) + mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL, + MBEDTLS_ENTROPY_MIN_PLATFORM, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif +#if defined(MBEDTLS_TIMING_C) + if( custom_entropy_sources_mask & ENTROPY_SOURCE_TIMING ) + mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL, + MBEDTLS_ENTROPY_MIN_HARDCLOCK, + MBEDTLS_ENTROPY_SOURCE_WEAK ); +#endif +#if defined(MBEDTLS_HAVEGE_C) + if( custom_entropy_sources_mask & ENTROPY_SOURCE_HAVEGE ) + mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data, + MBEDTLS_ENTROPY_MIN_HAVEGE, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + if( custom_entropy_sources_mask & ENTROPY_SOURCE_HARDWARE ) + mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL, + MBEDTLS_ENTROPY_MIN_HARDWARE, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) + if( custom_entropy_sources_mask & ENTROPY_SOURCE_NV_SEED ) + { + mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL, + MBEDTLS_ENTROPY_BLOCK_SIZE, + MBEDTLS_ENTROPY_SOURCE_STRONG ); + ctx->initial_entropy_run = 0; + } + else + { + /* Skip the NV seed even though it's compiled in. */ + ctx->initial_entropy_run = 1; + } +#endif + + if( custom_entropy_sources_mask & ENTROPY_SOURCE_FAKE ) + mbedtls_entropy_add_source( ctx, + fake_entropy_source, &fake_entropy_state, + fake_entropy_state.threshold, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +} + +/* END_HEADER */ + +/* BEGIN_DEPENDENCIES + * depends_on:MBEDTLS_PSA_CRYPTO_C + * END_DEPENDENCIES + */ + +/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED */ +void create_nv_seed( ) +{ + static unsigned char seed[ENTROPY_MIN_NV_SEED_SIZE]; + TEST_ASSERT( mbedtls_nv_seed_write( seed, sizeof( seed ) ) >= 0 ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void init_deinit( int count ) +{ + psa_status_t status; + int i; + for( i = 0; i < count; i++ ) + { + status = psa_crypto_init( ); + TEST_ASSERT( status == PSA_SUCCESS ); + status = psa_crypto_init( ); + TEST_ASSERT( status == PSA_SUCCESS ); + mbedtls_psa_crypto_free( ); + } +} +/* END_CASE */ + +/* BEGIN_CASE */ +void deinit_without_init( int count ) +{ + int i; + for( i = 0; i < count; i++ ) + { + TEST_ASSERT( psa_crypto_init( ) == PSA_SUCCESS ); + mbedtls_psa_crypto_free( ); + } + mbedtls_psa_crypto_free( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void validate_module_init_generate_random( int count ) +{ + psa_status_t status; + uint8_t random[10] = { 0 }; + int i; + for( i = 0; i < count; i++ ) + { + status = psa_crypto_init( ); + TEST_ASSERT( status == PSA_SUCCESS ); + mbedtls_psa_crypto_free( ); + } + status = psa_generate_random( random, sizeof( random ) ); + TEST_ASSERT( status == PSA_ERROR_BAD_STATE ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void validate_module_init_key_based( int count ) +{ + psa_status_t status; + uint8_t data[10] = { 0 }; + int i; + for( i = 0; i < count; i++ ) + { + status = psa_crypto_init( ); + TEST_ASSERT( status == PSA_SUCCESS ); + mbedtls_psa_crypto_free( ); + } + status = psa_import_key( 1, PSA_KEY_TYPE_RAW_DATA, data, sizeof( data ) ); + TEST_ASSERT( status == PSA_ERROR_BAD_STATE ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void custom_entropy_sources( int sources_arg, int expected_init_status_arg ) +{ + psa_status_t expected_init_status = expected_init_status_arg; + uint8_t random[10] = { 0 }; + + custom_entropy_sources_mask = sources_arg; + TEST_ASSERT( mbedtls_psa_crypto_configure_entropy_sources( + custom_entropy_init, mbedtls_entropy_free ) == + PSA_SUCCESS ); + + TEST_ASSERT( psa_crypto_init( ) == expected_init_status ); + if( expected_init_status != PSA_SUCCESS ) + goto exit; + + TEST_ASSERT( psa_generate_random( random, sizeof( random ) ) == + PSA_SUCCESS ); + +exit: + mbedtls_psa_crypto_free( ); +} +/* END_CASE */ + +/* BEGIN_CASE */ +void fake_entropy_source( int threshold, + int amount1, + int amount2, + int amount3, + int amount4, + int expected_init_status_arg ) +{ + psa_status_t expected_init_status = expected_init_status_arg; + uint8_t random[10] = { 0 }; + size_t lengths[4]; + + fake_entropy_state.threshold = threshold; + fake_entropy_state.step = 0; + fake_entropy_state.max_steps = 0; + if( amount1 >= 0 ) + lengths[fake_entropy_state.max_steps++] = amount1; + if( amount2 >= 0 ) + lengths[fake_entropy_state.max_steps++] = amount2; + if( amount3 >= 0 ) + lengths[fake_entropy_state.max_steps++] = amount3; + if( amount4 >= 0 ) + lengths[fake_entropy_state.max_steps++] = amount4; + fake_entropy_state.length_sequence = lengths; + + custom_entropy_sources_mask = ENTROPY_SOURCE_FAKE; + TEST_ASSERT( mbedtls_psa_crypto_configure_entropy_sources( + custom_entropy_init, mbedtls_entropy_free ) == + PSA_SUCCESS ); + + TEST_ASSERT( psa_crypto_init( ) == expected_init_status ); + if( expected_init_status != PSA_SUCCESS ) + goto exit; + + TEST_ASSERT( psa_generate_random( random, sizeof( random ) ) == + PSA_SUCCESS ); + +exit: + mbedtls_psa_crypto_free( ); +} +/* END_CASE */ + +/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED */ +void entropy_from_nv_seed( int seed_size_arg, + int expected_init_status_arg ) +{ + psa_status_t expected_init_status = expected_init_status_arg; + uint8_t random[10] = { 0 }; + uint8_t *seed = NULL; + size_t seed_size = seed_size_arg; + + ASSERT_ALLOC( seed, seed_size ); + TEST_ASSERT( mbedtls_nv_seed_write( seed, seed_size ) >= 0 ); + + custom_entropy_sources_mask = ENTROPY_SOURCE_NV_SEED; + TEST_ASSERT( mbedtls_psa_crypto_configure_entropy_sources( + custom_entropy_init, mbedtls_entropy_free ) == + PSA_SUCCESS ); + + TEST_ASSERT( psa_crypto_init( ) == expected_init_status ); + if( expected_init_status != PSA_SUCCESS ) + goto exit; + + TEST_ASSERT( psa_generate_random( random, sizeof( random ) ) == + PSA_SUCCESS ); + +exit: + mbedtls_free( seed ); + mbedtls_psa_crypto_free( ); +} +/* END_CASE */