1a8e1175bSopenharmony_ci/* BEGIN_HEADER */
2a8e1175bSopenharmony_ci#include <stdint.h>
3a8e1175bSopenharmony_ci
4a8e1175bSopenharmony_ci#include "psa_crypto_core.h"
5a8e1175bSopenharmony_ci/* Some tests in this module configure entropy sources. */
6a8e1175bSopenharmony_ci#include "psa_crypto_invasive.h"
7a8e1175bSopenharmony_ci
8a8e1175bSopenharmony_ci#include "mbedtls/entropy.h"
9a8e1175bSopenharmony_ci#include "entropy_poll.h"
10a8e1175bSopenharmony_ci
11a8e1175bSopenharmony_ci#define ENTROPY_MIN_NV_SEED_SIZE                                        \
12a8e1175bSopenharmony_ci    MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
13a8e1175bSopenharmony_ci
14a8e1175bSopenharmony_ci#include "psa_crypto_random_impl.h"
15a8e1175bSopenharmony_ci#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
16a8e1175bSopenharmony_ci/* PSA crypto uses the HMAC_DRBG module. It reads from the entropy source twice:
17a8e1175bSopenharmony_ci * once for the initial entropy and once for a nonce. The nonce length is
18a8e1175bSopenharmony_ci * half the entropy length. For SHA-256, SHA-384 or SHA-512, the
19a8e1175bSopenharmony_ci * entropy length is 256 per the documentation of mbedtls_hmac_drbg_seed(),
20a8e1175bSopenharmony_ci * and PSA crypto doesn't support other hashes for HMAC_DRBG. */
21a8e1175bSopenharmony_ci#define ENTROPY_NONCE_LEN (256 / 2)
22a8e1175bSopenharmony_ci#else
23a8e1175bSopenharmony_ci/* PSA crypto uses the CTR_DRBG module. In some configurations, it needs
24a8e1175bSopenharmony_ci * to read from the entropy source twice: once for the initial entropy
25a8e1175bSopenharmony_ci * and once for a nonce. */
26a8e1175bSopenharmony_ci#include "mbedtls/ctr_drbg.h"
27a8e1175bSopenharmony_ci#define ENTROPY_NONCE_LEN MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN
28a8e1175bSopenharmony_ci#endif
29a8e1175bSopenharmony_ci
30a8e1175bSopenharmony_ci#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
31a8e1175bSopenharmony_ci
32a8e1175bSopenharmony_citypedef struct {
33a8e1175bSopenharmony_ci    size_t threshold; /* Minimum bytes to make mbedtls_entropy_func happy */
34a8e1175bSopenharmony_ci    size_t max_steps;
35a8e1175bSopenharmony_ci    size_t *length_sequence;
36a8e1175bSopenharmony_ci    size_t step;
37a8e1175bSopenharmony_ci} fake_entropy_state_t;
38a8e1175bSopenharmony_cistatic int fake_entropy_source(void *state_arg,
39a8e1175bSopenharmony_ci                               unsigned char *output, size_t len,
40a8e1175bSopenharmony_ci                               size_t *olen)
41a8e1175bSopenharmony_ci{
42a8e1175bSopenharmony_ci    fake_entropy_state_t *state = state_arg;
43a8e1175bSopenharmony_ci    size_t i;
44a8e1175bSopenharmony_ci
45a8e1175bSopenharmony_ci    if (state->step >= state->max_steps) {
46a8e1175bSopenharmony_ci        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
47a8e1175bSopenharmony_ci    }
48a8e1175bSopenharmony_ci
49a8e1175bSopenharmony_ci    *olen = MIN(len, state->length_sequence[state->step]);
50a8e1175bSopenharmony_ci    for (i = 0; i < *olen; i++) {
51a8e1175bSopenharmony_ci        output[i] = i;
52a8e1175bSopenharmony_ci    }
53a8e1175bSopenharmony_ci    ++state->step;
54a8e1175bSopenharmony_ci    return 0;
55a8e1175bSopenharmony_ci}
56a8e1175bSopenharmony_ci
57a8e1175bSopenharmony_ci#define ENTROPY_SOURCE_PLATFORM                 0x00000001
58a8e1175bSopenharmony_ci#define ENTROPY_SOURCE_TIMING                   0x00000002
59a8e1175bSopenharmony_ci#define ENTROPY_SOURCE_HARDWARE                 0x00000004
60a8e1175bSopenharmony_ci#define ENTROPY_SOURCE_NV_SEED                  0x00000008
61a8e1175bSopenharmony_ci#define ENTROPY_SOURCE_FAKE                     0x40000000
62a8e1175bSopenharmony_ci
63a8e1175bSopenharmony_cistatic uint32_t custom_entropy_sources_mask;
64a8e1175bSopenharmony_cistatic fake_entropy_state_t fake_entropy_state;
65a8e1175bSopenharmony_ci
66a8e1175bSopenharmony_ci/* This is a modified version of mbedtls_entropy_init() from entropy.c
67a8e1175bSopenharmony_ci * which chooses entropy sources dynamically. */
68a8e1175bSopenharmony_cistatic void custom_entropy_init(mbedtls_entropy_context *ctx)
69a8e1175bSopenharmony_ci{
70a8e1175bSopenharmony_ci    ctx->source_count = 0;
71a8e1175bSopenharmony_ci    memset(ctx->source, 0, sizeof(ctx->source));
72a8e1175bSopenharmony_ci
73a8e1175bSopenharmony_ci#if defined(MBEDTLS_THREADING_C)
74a8e1175bSopenharmony_ci    mbedtls_mutex_init(&ctx->mutex);
75a8e1175bSopenharmony_ci#endif
76a8e1175bSopenharmony_ci
77a8e1175bSopenharmony_ci    ctx->accumulator_started = 0;
78a8e1175bSopenharmony_ci    mbedtls_md_init(&ctx->accumulator);
79a8e1175bSopenharmony_ci
80a8e1175bSopenharmony_ci#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
81a8e1175bSopenharmony_ci    if (custom_entropy_sources_mask & ENTROPY_SOURCE_PLATFORM) {
82a8e1175bSopenharmony_ci        mbedtls_entropy_add_source(ctx, mbedtls_platform_entropy_poll, NULL,
83a8e1175bSopenharmony_ci                                   MBEDTLS_ENTROPY_MIN_PLATFORM,
84a8e1175bSopenharmony_ci                                   MBEDTLS_ENTROPY_SOURCE_STRONG);
85a8e1175bSopenharmony_ci    }
86a8e1175bSopenharmony_ci#endif
87a8e1175bSopenharmony_ci#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
88a8e1175bSopenharmony_ci    if (custom_entropy_sources_mask & ENTROPY_SOURCE_HARDWARE) {
89a8e1175bSopenharmony_ci        mbedtls_entropy_add_source(ctx, mbedtls_hardware_poll, NULL,
90a8e1175bSopenharmony_ci                                   MBEDTLS_ENTROPY_MIN_HARDWARE,
91a8e1175bSopenharmony_ci                                   MBEDTLS_ENTROPY_SOURCE_STRONG);
92a8e1175bSopenharmony_ci    }
93a8e1175bSopenharmony_ci#endif
94a8e1175bSopenharmony_ci#if defined(MBEDTLS_ENTROPY_NV_SEED)
95a8e1175bSopenharmony_ci    if (custom_entropy_sources_mask & ENTROPY_SOURCE_NV_SEED) {
96a8e1175bSopenharmony_ci        mbedtls_entropy_add_source(ctx, mbedtls_nv_seed_poll, NULL,
97a8e1175bSopenharmony_ci                                   MBEDTLS_ENTROPY_BLOCK_SIZE,
98a8e1175bSopenharmony_ci                                   MBEDTLS_ENTROPY_SOURCE_STRONG);
99a8e1175bSopenharmony_ci        ctx->initial_entropy_run = 0;
100a8e1175bSopenharmony_ci    } else {
101a8e1175bSopenharmony_ci        /* Skip the NV seed even though it's compiled in. */
102a8e1175bSopenharmony_ci        ctx->initial_entropy_run = 1;
103a8e1175bSopenharmony_ci    }
104a8e1175bSopenharmony_ci#endif
105a8e1175bSopenharmony_ci
106a8e1175bSopenharmony_ci    if (custom_entropy_sources_mask & ENTROPY_SOURCE_FAKE) {
107a8e1175bSopenharmony_ci        mbedtls_entropy_add_source(ctx,
108a8e1175bSopenharmony_ci                                   fake_entropy_source, &fake_entropy_state,
109a8e1175bSopenharmony_ci                                   fake_entropy_state.threshold,
110a8e1175bSopenharmony_ci                                   MBEDTLS_ENTROPY_SOURCE_STRONG);
111a8e1175bSopenharmony_ci    }
112a8e1175bSopenharmony_ci}
113a8e1175bSopenharmony_ci
114a8e1175bSopenharmony_ci#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
115a8e1175bSopenharmony_ci
116a8e1175bSopenharmony_ci#if defined MBEDTLS_THREADING_PTHREAD
117a8e1175bSopenharmony_ci
118a8e1175bSopenharmony_citypedef struct {
119a8e1175bSopenharmony_ci    int do_init;
120a8e1175bSopenharmony_ci} thread_psa_init_ctx_t;
121a8e1175bSopenharmony_ci
122a8e1175bSopenharmony_cistatic void *thread_psa_init_function(void *ctx)
123a8e1175bSopenharmony_ci{
124a8e1175bSopenharmony_ci    thread_psa_init_ctx_t *init_context = (thread_psa_init_ctx_t *) ctx;
125a8e1175bSopenharmony_ci    psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
126a8e1175bSopenharmony_ci    uint8_t random[10] = { 0 };
127a8e1175bSopenharmony_ci
128a8e1175bSopenharmony_ci    if (init_context->do_init) {
129a8e1175bSopenharmony_ci        PSA_ASSERT(psa_crypto_init());
130a8e1175bSopenharmony_ci    }
131a8e1175bSopenharmony_ci
132a8e1175bSopenharmony_ci    /* If this is a test only thread, then we can assume PSA is being started
133a8e1175bSopenharmony_ci     * up on another thread and thus we cannot know whether the following tests
134a8e1175bSopenharmony_ci     * will be successful or not. These checks are still useful, however even
135a8e1175bSopenharmony_ci     * without checking the return codes as they may show up race conditions on
136a8e1175bSopenharmony_ci     * the flags they check under TSAN.*/
137a8e1175bSopenharmony_ci
138a8e1175bSopenharmony_ci    /* Test getting if drivers are initialised. */
139a8e1175bSopenharmony_ci    int can_do = psa_can_do_hash(PSA_ALG_NONE);
140a8e1175bSopenharmony_ci
141a8e1175bSopenharmony_ci    if (init_context->do_init) {
142a8e1175bSopenharmony_ci        TEST_ASSERT(can_do == 1);
143a8e1175bSopenharmony_ci    }
144a8e1175bSopenharmony_ci
145a8e1175bSopenharmony_ci#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
146a8e1175bSopenharmony_ci
147a8e1175bSopenharmony_ci    /* Test getting global_data.rng_state. */
148a8e1175bSopenharmony_ci    status = mbedtls_psa_crypto_configure_entropy_sources(NULL, NULL);
149a8e1175bSopenharmony_ci
150a8e1175bSopenharmony_ci    if (init_context->do_init) {
151a8e1175bSopenharmony_ci        /* Bad state due to entropy sources already being setup in
152a8e1175bSopenharmony_ci         * psa_crypto_init() */
153a8e1175bSopenharmony_ci        TEST_EQUAL(status, PSA_ERROR_BAD_STATE);
154a8e1175bSopenharmony_ci    }
155a8e1175bSopenharmony_ci#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
156a8e1175bSopenharmony_ci
157a8e1175bSopenharmony_ci    /* Test using the PSA RNG ony if we know PSA is up and running. */
158a8e1175bSopenharmony_ci    if (init_context->do_init) {
159a8e1175bSopenharmony_ci        status = psa_generate_random(random, sizeof(random));
160a8e1175bSopenharmony_ci
161a8e1175bSopenharmony_ci        TEST_EQUAL(status, PSA_SUCCESS);
162a8e1175bSopenharmony_ci    }
163a8e1175bSopenharmony_ci
164a8e1175bSopenharmony_ciexit:
165a8e1175bSopenharmony_ci    return NULL;
166a8e1175bSopenharmony_ci}
167a8e1175bSopenharmony_ci#endif /* defined MBEDTLS_THREADING_PTHREAD */
168a8e1175bSopenharmony_ci
169a8e1175bSopenharmony_ci/* END_HEADER */
170a8e1175bSopenharmony_ci
171a8e1175bSopenharmony_ci/* BEGIN_DEPENDENCIES
172a8e1175bSopenharmony_ci * depends_on:MBEDTLS_PSA_CRYPTO_C
173a8e1175bSopenharmony_ci * END_DEPENDENCIES
174a8e1175bSopenharmony_ci */
175a8e1175bSopenharmony_ci
176a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
177a8e1175bSopenharmony_civoid create_nv_seed()
178a8e1175bSopenharmony_ci{
179a8e1175bSopenharmony_ci    static unsigned char seed[ENTROPY_MIN_NV_SEED_SIZE];
180a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_nv_seed_write(seed, sizeof(seed)) >= 0);
181a8e1175bSopenharmony_ci}
182a8e1175bSopenharmony_ci/* END_CASE */
183a8e1175bSopenharmony_ci
184a8e1175bSopenharmony_ci/* BEGIN_CASE */
185a8e1175bSopenharmony_civoid init_deinit(int count)
186a8e1175bSopenharmony_ci{
187a8e1175bSopenharmony_ci    psa_status_t status;
188a8e1175bSopenharmony_ci    int i;
189a8e1175bSopenharmony_ci    for (i = 0; i < count; i++) {
190a8e1175bSopenharmony_ci        status = psa_crypto_init();
191a8e1175bSopenharmony_ci        PSA_ASSERT(status);
192a8e1175bSopenharmony_ci        status = psa_crypto_init();
193a8e1175bSopenharmony_ci        PSA_ASSERT(status);
194a8e1175bSopenharmony_ci        PSA_DONE();
195a8e1175bSopenharmony_ci    }
196a8e1175bSopenharmony_ci}
197a8e1175bSopenharmony_ci/* END_CASE */
198a8e1175bSopenharmony_ci
199a8e1175bSopenharmony_ci/* BEGIN_CASE */
200a8e1175bSopenharmony_civoid deinit_without_init(int count)
201a8e1175bSopenharmony_ci{
202a8e1175bSopenharmony_ci    int i;
203a8e1175bSopenharmony_ci    for (i = 0; i < count; i++) {
204a8e1175bSopenharmony_ci        PSA_ASSERT(psa_crypto_init());
205a8e1175bSopenharmony_ci        PSA_DONE();
206a8e1175bSopenharmony_ci    }
207a8e1175bSopenharmony_ci    PSA_DONE();
208a8e1175bSopenharmony_ci}
209a8e1175bSopenharmony_ci/* END_CASE */
210a8e1175bSopenharmony_ci
211a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_THREADING_PTHREAD */
212a8e1175bSopenharmony_civoid psa_threaded_init(int arg_thread_count)
213a8e1175bSopenharmony_ci{
214a8e1175bSopenharmony_ci    thread_psa_init_ctx_t init_context;
215a8e1175bSopenharmony_ci    thread_psa_init_ctx_t init_context_2;
216a8e1175bSopenharmony_ci
217a8e1175bSopenharmony_ci    size_t thread_count = (size_t) arg_thread_count;
218a8e1175bSopenharmony_ci    mbedtls_test_thread_t *threads = NULL;
219a8e1175bSopenharmony_ci
220a8e1175bSopenharmony_ci    TEST_CALLOC(threads, sizeof(mbedtls_test_thread_t) * thread_count);
221a8e1175bSopenharmony_ci
222a8e1175bSopenharmony_ci    init_context.do_init = 1;
223a8e1175bSopenharmony_ci
224a8e1175bSopenharmony_ci    /* Test initialising PSA and testing certain protected globals on multiple
225a8e1175bSopenharmony_ci     * threads. */
226a8e1175bSopenharmony_ci    for (size_t i = 0; i < thread_count; i++) {
227a8e1175bSopenharmony_ci        TEST_EQUAL(
228a8e1175bSopenharmony_ci            mbedtls_test_thread_create(&threads[i],
229a8e1175bSopenharmony_ci                                       thread_psa_init_function,
230a8e1175bSopenharmony_ci                                       (void *) &init_context),
231a8e1175bSopenharmony_ci            0);
232a8e1175bSopenharmony_ci    }
233a8e1175bSopenharmony_ci
234a8e1175bSopenharmony_ci    for (size_t i = 0; i < thread_count; i++) {
235a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
236a8e1175bSopenharmony_ci    }
237a8e1175bSopenharmony_ci
238a8e1175bSopenharmony_ci    PSA_DONE();
239a8e1175bSopenharmony_ci
240a8e1175bSopenharmony_ci    init_context_2.do_init = 0;
241a8e1175bSopenharmony_ci
242a8e1175bSopenharmony_ci    /* Test initialising PSA whilst also testing flags on other threads. */
243a8e1175bSopenharmony_ci    for (size_t i = 0; i < thread_count; i++) {
244a8e1175bSopenharmony_ci
245a8e1175bSopenharmony_ci        if (i & 1) {
246a8e1175bSopenharmony_ci
247a8e1175bSopenharmony_ci            TEST_EQUAL(
248a8e1175bSopenharmony_ci                mbedtls_test_thread_create(&threads[i],
249a8e1175bSopenharmony_ci                                           thread_psa_init_function,
250a8e1175bSopenharmony_ci                                           (void *) &init_context),
251a8e1175bSopenharmony_ci                0);
252a8e1175bSopenharmony_ci        } else {
253a8e1175bSopenharmony_ci            TEST_EQUAL(
254a8e1175bSopenharmony_ci                mbedtls_test_thread_create(&threads[i],
255a8e1175bSopenharmony_ci                                           thread_psa_init_function,
256a8e1175bSopenharmony_ci                                           (void *) &init_context_2),
257a8e1175bSopenharmony_ci                0);
258a8e1175bSopenharmony_ci        }
259a8e1175bSopenharmony_ci    }
260a8e1175bSopenharmony_ci
261a8e1175bSopenharmony_ci    for (size_t i = 0; i < thread_count; i++) {
262a8e1175bSopenharmony_ci        TEST_EQUAL(mbedtls_test_thread_join(&threads[i]), 0);
263a8e1175bSopenharmony_ci    }
264a8e1175bSopenharmony_ciexit:
265a8e1175bSopenharmony_ci
266a8e1175bSopenharmony_ci    PSA_DONE();
267a8e1175bSopenharmony_ci
268a8e1175bSopenharmony_ci    mbedtls_free(threads);
269a8e1175bSopenharmony_ci}
270a8e1175bSopenharmony_ci/* END_CASE */
271a8e1175bSopenharmony_ci
272a8e1175bSopenharmony_ci/* BEGIN_CASE */
273a8e1175bSopenharmony_civoid validate_module_init_generate_random(int count)
274a8e1175bSopenharmony_ci{
275a8e1175bSopenharmony_ci    psa_status_t status;
276a8e1175bSopenharmony_ci    uint8_t random[10] = { 0 };
277a8e1175bSopenharmony_ci    int i;
278a8e1175bSopenharmony_ci    for (i = 0; i < count; i++) {
279a8e1175bSopenharmony_ci        status = psa_crypto_init();
280a8e1175bSopenharmony_ci        PSA_ASSERT(status);
281a8e1175bSopenharmony_ci        PSA_DONE();
282a8e1175bSopenharmony_ci    }
283a8e1175bSopenharmony_ci    status = psa_generate_random(random, sizeof(random));
284a8e1175bSopenharmony_ci    TEST_EQUAL(status, PSA_ERROR_BAD_STATE);
285a8e1175bSopenharmony_ci}
286a8e1175bSopenharmony_ci/* END_CASE */
287a8e1175bSopenharmony_ci
288a8e1175bSopenharmony_ci/* BEGIN_CASE */
289a8e1175bSopenharmony_civoid validate_module_init_key_based(int count)
290a8e1175bSopenharmony_ci{
291a8e1175bSopenharmony_ci    psa_status_t status;
292a8e1175bSopenharmony_ci    uint8_t data[10] = { 0 };
293a8e1175bSopenharmony_ci    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
294a8e1175bSopenharmony_ci    mbedtls_svc_key_id_t key = mbedtls_svc_key_id_make(0xdead, 0xdead);
295a8e1175bSopenharmony_ci    int i;
296a8e1175bSopenharmony_ci
297a8e1175bSopenharmony_ci    for (i = 0; i < count; i++) {
298a8e1175bSopenharmony_ci        status = psa_crypto_init();
299a8e1175bSopenharmony_ci        PSA_ASSERT(status);
300a8e1175bSopenharmony_ci        PSA_DONE();
301a8e1175bSopenharmony_ci    }
302a8e1175bSopenharmony_ci    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
303a8e1175bSopenharmony_ci    status = psa_import_key(&attributes, data, sizeof(data), &key);
304a8e1175bSopenharmony_ci    TEST_EQUAL(status, PSA_ERROR_BAD_STATE);
305a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_svc_key_id_is_null(key));
306a8e1175bSopenharmony_ci}
307a8e1175bSopenharmony_ci/* END_CASE */
308a8e1175bSopenharmony_ci
309a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
310a8e1175bSopenharmony_civoid custom_entropy_sources(int sources_arg, int expected_init_status_arg)
311a8e1175bSopenharmony_ci{
312a8e1175bSopenharmony_ci    psa_status_t expected_init_status = expected_init_status_arg;
313a8e1175bSopenharmony_ci    uint8_t random[10] = { 0 };
314a8e1175bSopenharmony_ci
315a8e1175bSopenharmony_ci    custom_entropy_sources_mask = sources_arg;
316a8e1175bSopenharmony_ci    PSA_ASSERT(mbedtls_psa_crypto_configure_entropy_sources(
317a8e1175bSopenharmony_ci                   custom_entropy_init, mbedtls_entropy_free));
318a8e1175bSopenharmony_ci
319a8e1175bSopenharmony_ci    TEST_EQUAL(psa_crypto_init(), expected_init_status);
320a8e1175bSopenharmony_ci    if (expected_init_status != PSA_SUCCESS) {
321a8e1175bSopenharmony_ci        goto exit;
322a8e1175bSopenharmony_ci    }
323a8e1175bSopenharmony_ci
324a8e1175bSopenharmony_ci    PSA_ASSERT(psa_generate_random(random, sizeof(random)));
325a8e1175bSopenharmony_ci
326a8e1175bSopenharmony_ciexit:
327a8e1175bSopenharmony_ci    PSA_DONE();
328a8e1175bSopenharmony_ci}
329a8e1175bSopenharmony_ci/* END_CASE */
330a8e1175bSopenharmony_ci
331a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
332a8e1175bSopenharmony_civoid fake_entropy_source(int threshold,
333a8e1175bSopenharmony_ci                         int amount1,
334a8e1175bSopenharmony_ci                         int amount2,
335a8e1175bSopenharmony_ci                         int amount3,
336a8e1175bSopenharmony_ci                         int amount4,
337a8e1175bSopenharmony_ci                         int expected_init_status_arg)
338a8e1175bSopenharmony_ci{
339a8e1175bSopenharmony_ci    psa_status_t expected_init_status = expected_init_status_arg;
340a8e1175bSopenharmony_ci    uint8_t random[10] = { 0 };
341a8e1175bSopenharmony_ci    size_t lengths[4];
342a8e1175bSopenharmony_ci
343a8e1175bSopenharmony_ci    fake_entropy_state.threshold = threshold;
344a8e1175bSopenharmony_ci    fake_entropy_state.step = 0;
345a8e1175bSopenharmony_ci    fake_entropy_state.max_steps = 0;
346a8e1175bSopenharmony_ci    if (amount1 >= 0) {
347a8e1175bSopenharmony_ci        lengths[fake_entropy_state.max_steps++] = amount1;
348a8e1175bSopenharmony_ci    }
349a8e1175bSopenharmony_ci    if (amount2 >= 0) {
350a8e1175bSopenharmony_ci        lengths[fake_entropy_state.max_steps++] = amount2;
351a8e1175bSopenharmony_ci    }
352a8e1175bSopenharmony_ci    if (amount3 >= 0) {
353a8e1175bSopenharmony_ci        lengths[fake_entropy_state.max_steps++] = amount3;
354a8e1175bSopenharmony_ci    }
355a8e1175bSopenharmony_ci    if (amount4 >= 0) {
356a8e1175bSopenharmony_ci        lengths[fake_entropy_state.max_steps++] = amount4;
357a8e1175bSopenharmony_ci    }
358a8e1175bSopenharmony_ci    fake_entropy_state.length_sequence = lengths;
359a8e1175bSopenharmony_ci
360a8e1175bSopenharmony_ci    custom_entropy_sources_mask = ENTROPY_SOURCE_FAKE;
361a8e1175bSopenharmony_ci    PSA_ASSERT(mbedtls_psa_crypto_configure_entropy_sources(
362a8e1175bSopenharmony_ci                   custom_entropy_init, mbedtls_entropy_free));
363a8e1175bSopenharmony_ci
364a8e1175bSopenharmony_ci    TEST_EQUAL(psa_crypto_init(), expected_init_status);
365a8e1175bSopenharmony_ci    if (expected_init_status != PSA_SUCCESS) {
366a8e1175bSopenharmony_ci        goto exit;
367a8e1175bSopenharmony_ci    }
368a8e1175bSopenharmony_ci
369a8e1175bSopenharmony_ci    PSA_ASSERT(psa_generate_random(random, sizeof(random)));
370a8e1175bSopenharmony_ci
371a8e1175bSopenharmony_ciexit:
372a8e1175bSopenharmony_ci    PSA_DONE();
373a8e1175bSopenharmony_ci}
374a8e1175bSopenharmony_ci/* END_CASE */
375a8e1175bSopenharmony_ci
376a8e1175bSopenharmony_ci/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
377a8e1175bSopenharmony_civoid entropy_from_nv_seed(int seed_size_arg,
378a8e1175bSopenharmony_ci                          int expected_init_status_arg)
379a8e1175bSopenharmony_ci{
380a8e1175bSopenharmony_ci    psa_status_t expected_init_status = expected_init_status_arg;
381a8e1175bSopenharmony_ci    uint8_t random[10] = { 0 };
382a8e1175bSopenharmony_ci    uint8_t *seed = NULL;
383a8e1175bSopenharmony_ci    size_t seed_size = seed_size_arg;
384a8e1175bSopenharmony_ci
385a8e1175bSopenharmony_ci    TEST_CALLOC(seed, seed_size);
386a8e1175bSopenharmony_ci    TEST_ASSERT(mbedtls_nv_seed_write(seed, seed_size) >= 0);
387a8e1175bSopenharmony_ci
388a8e1175bSopenharmony_ci    custom_entropy_sources_mask = ENTROPY_SOURCE_NV_SEED;
389a8e1175bSopenharmony_ci    PSA_ASSERT(mbedtls_psa_crypto_configure_entropy_sources(
390a8e1175bSopenharmony_ci                   custom_entropy_init, mbedtls_entropy_free));
391a8e1175bSopenharmony_ci
392a8e1175bSopenharmony_ci    TEST_EQUAL(psa_crypto_init(), expected_init_status);
393a8e1175bSopenharmony_ci    if (expected_init_status != PSA_SUCCESS) {
394a8e1175bSopenharmony_ci        goto exit;
395a8e1175bSopenharmony_ci    }
396a8e1175bSopenharmony_ci
397a8e1175bSopenharmony_ci    PSA_ASSERT(psa_generate_random(random, sizeof(random)));
398a8e1175bSopenharmony_ci
399a8e1175bSopenharmony_ciexit:
400a8e1175bSopenharmony_ci    mbedtls_free(seed);
401a8e1175bSopenharmony_ci    PSA_DONE();
402a8e1175bSopenharmony_ci}
403a8e1175bSopenharmony_ci/* END_CASE */
404