xref: /aosp_15_r20/external/mbedtls/tests/suites/test_suite_psa_crypto_init.function (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1/* BEGIN_HEADER */
2#include <stdint.h>
3
4/* Some tests in this module configure entropy sources. */
5#include "psa_crypto_invasive.h"
6
7#include "mbedtls/entropy.h"
8#include "entropy_poll.h"
9
10#define ENTROPY_MIN_NV_SEED_SIZE                                        \
11    MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
12
13#include "psa_crypto_random_impl.h"
14#if defined(MBEDTLS_PSA_HMAC_DRBG_MD_TYPE)
15/* PSA crypto uses the HMAC_DRBG module. It reads from the entropy source twice:
16 * once for the initial entropy and once for a nonce. The nonce length is
17 * half the entropy length. For SHA-256, SHA-384 or SHA-512, the
18 * entropy length is 256 per the documentation of mbedtls_hmac_drbg_seed(),
19 * and PSA crypto doesn't support other hashes for HMAC_DRBG. */
20#define ENTROPY_NONCE_LEN (256 / 2)
21#else
22/* PSA crypto uses the CTR_DRBG module. In some configurations, it needs
23 * to read from the entropy source twice: once for the initial entropy
24 * and once for a nonce. */
25#include "mbedtls/ctr_drbg.h"
26#define ENTROPY_NONCE_LEN MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN
27#endif
28
29#if !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG)
30
31typedef struct {
32    size_t threshold; /* Minimum bytes to make mbedtls_entropy_func happy */
33    size_t max_steps;
34    size_t *length_sequence;
35    size_t step;
36} fake_entropy_state_t;
37static int fake_entropy_source(void *state_arg,
38                               unsigned char *output, size_t len,
39                               size_t *olen)
40{
41    fake_entropy_state_t *state = state_arg;
42    size_t i;
43
44    if (state->step >= state->max_steps) {
45        return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
46    }
47
48    *olen = MIN(len, state->length_sequence[state->step]);
49    for (i = 0; i < *olen; i++) {
50        output[i] = i;
51    }
52    ++state->step;
53    return 0;
54}
55
56#define ENTROPY_SOURCE_PLATFORM                 0x00000001
57#define ENTROPY_SOURCE_TIMING                   0x00000002
58#define ENTROPY_SOURCE_HARDWARE                 0x00000004
59#define ENTROPY_SOURCE_NV_SEED                  0x00000008
60#define ENTROPY_SOURCE_FAKE                     0x40000000
61
62static uint32_t custom_entropy_sources_mask;
63static fake_entropy_state_t fake_entropy_state;
64
65/* This is a modified version of mbedtls_entropy_init() from entropy.c
66 * which chooses entropy sources dynamically. */
67static void custom_entropy_init(mbedtls_entropy_context *ctx)
68{
69    ctx->source_count = 0;
70    memset(ctx->source, 0, sizeof(ctx->source));
71
72#if defined(MBEDTLS_THREADING_C)
73    mbedtls_mutex_init(&ctx->mutex);
74#endif
75
76    ctx->accumulator_started = 0;
77    mbedtls_md_init(&ctx->accumulator);
78
79#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
80    if (custom_entropy_sources_mask & ENTROPY_SOURCE_PLATFORM) {
81        mbedtls_entropy_add_source(ctx, mbedtls_platform_entropy_poll, NULL,
82                                   MBEDTLS_ENTROPY_MIN_PLATFORM,
83                                   MBEDTLS_ENTROPY_SOURCE_STRONG);
84    }
85#endif
86#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
87    if (custom_entropy_sources_mask & ENTROPY_SOURCE_HARDWARE) {
88        mbedtls_entropy_add_source(ctx, mbedtls_hardware_poll, NULL,
89                                   MBEDTLS_ENTROPY_MIN_HARDWARE,
90                                   MBEDTLS_ENTROPY_SOURCE_STRONG);
91    }
92#endif
93#if defined(MBEDTLS_ENTROPY_NV_SEED)
94    if (custom_entropy_sources_mask & ENTROPY_SOURCE_NV_SEED) {
95        mbedtls_entropy_add_source(ctx, mbedtls_nv_seed_poll, NULL,
96                                   MBEDTLS_ENTROPY_BLOCK_SIZE,
97                                   MBEDTLS_ENTROPY_SOURCE_STRONG);
98        ctx->initial_entropy_run = 0;
99    } else {
100        /* Skip the NV seed even though it's compiled in. */
101        ctx->initial_entropy_run = 1;
102    }
103#endif
104
105    if (custom_entropy_sources_mask & ENTROPY_SOURCE_FAKE) {
106        mbedtls_entropy_add_source(ctx,
107                                   fake_entropy_source, &fake_entropy_state,
108                                   fake_entropy_state.threshold,
109                                   MBEDTLS_ENTROPY_SOURCE_STRONG);
110    }
111}
112
113#endif /* !defined(MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG) */
114
115/* END_HEADER */
116
117/* BEGIN_DEPENDENCIES
118 * depends_on:MBEDTLS_PSA_CRYPTO_C
119 * END_DEPENDENCIES
120 */
121
122/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
123void create_nv_seed()
124{
125    static unsigned char seed[ENTROPY_MIN_NV_SEED_SIZE];
126    TEST_ASSERT(mbedtls_nv_seed_write(seed, sizeof(seed)) >= 0);
127}
128/* END_CASE */
129
130/* BEGIN_CASE */
131void init_deinit(int count)
132{
133    psa_status_t status;
134    int i;
135    for (i = 0; i < count; i++) {
136        status = psa_crypto_init();
137        PSA_ASSERT(status);
138        status = psa_crypto_init();
139        PSA_ASSERT(status);
140        PSA_DONE();
141    }
142}
143/* END_CASE */
144
145/* BEGIN_CASE */
146void deinit_without_init(int count)
147{
148    int i;
149    for (i = 0; i < count; i++) {
150        PSA_ASSERT(psa_crypto_init());
151        PSA_DONE();
152    }
153    PSA_DONE();
154}
155/* END_CASE */
156
157/* BEGIN_CASE */
158void validate_module_init_generate_random(int count)
159{
160    psa_status_t status;
161    uint8_t random[10] = { 0 };
162    int i;
163    for (i = 0; i < count; i++) {
164        status = psa_crypto_init();
165        PSA_ASSERT(status);
166        PSA_DONE();
167    }
168    status = psa_generate_random(random, sizeof(random));
169    TEST_EQUAL(status, PSA_ERROR_BAD_STATE);
170}
171/* END_CASE */
172
173/* BEGIN_CASE */
174void validate_module_init_key_based(int count)
175{
176    psa_status_t status;
177    uint8_t data[10] = { 0 };
178    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
179    mbedtls_svc_key_id_t key = mbedtls_svc_key_id_make(0xdead, 0xdead);
180    int i;
181
182    for (i = 0; i < count; i++) {
183        status = psa_crypto_init();
184        PSA_ASSERT(status);
185        PSA_DONE();
186    }
187    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
188    status = psa_import_key(&attributes, data, sizeof(data), &key);
189    TEST_EQUAL(status, PSA_ERROR_BAD_STATE);
190    TEST_ASSERT(mbedtls_svc_key_id_is_null(key));
191}
192/* END_CASE */
193
194/* BEGIN_CASE depends_on:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
195void custom_entropy_sources(int sources_arg, int expected_init_status_arg)
196{
197    psa_status_t expected_init_status = expected_init_status_arg;
198    uint8_t random[10] = { 0 };
199
200    custom_entropy_sources_mask = sources_arg;
201    PSA_ASSERT(mbedtls_psa_crypto_configure_entropy_sources(
202                   custom_entropy_init, mbedtls_entropy_free));
203
204    TEST_EQUAL(psa_crypto_init(), expected_init_status);
205    if (expected_init_status != PSA_SUCCESS) {
206        goto exit;
207    }
208
209    PSA_ASSERT(psa_generate_random(random, sizeof(random)));
210
211exit:
212    PSA_DONE();
213}
214/* END_CASE */
215
216/* BEGIN_CASE depends_on:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
217void fake_entropy_source(int threshold,
218                         int amount1,
219                         int amount2,
220                         int amount3,
221                         int amount4,
222                         int expected_init_status_arg)
223{
224    psa_status_t expected_init_status = expected_init_status_arg;
225    uint8_t random[10] = { 0 };
226    size_t lengths[4];
227
228    fake_entropy_state.threshold = threshold;
229    fake_entropy_state.step = 0;
230    fake_entropy_state.max_steps = 0;
231    if (amount1 >= 0) {
232        lengths[fake_entropy_state.max_steps++] = amount1;
233    }
234    if (amount2 >= 0) {
235        lengths[fake_entropy_state.max_steps++] = amount2;
236    }
237    if (amount3 >= 0) {
238        lengths[fake_entropy_state.max_steps++] = amount3;
239    }
240    if (amount4 >= 0) {
241        lengths[fake_entropy_state.max_steps++] = amount4;
242    }
243    fake_entropy_state.length_sequence = lengths;
244
245    custom_entropy_sources_mask = ENTROPY_SOURCE_FAKE;
246    PSA_ASSERT(mbedtls_psa_crypto_configure_entropy_sources(
247                   custom_entropy_init, mbedtls_entropy_free));
248
249    TEST_EQUAL(psa_crypto_init(), expected_init_status);
250    if (expected_init_status != PSA_SUCCESS) {
251        goto exit;
252    }
253
254    PSA_ASSERT(psa_generate_random(random, sizeof(random)));
255
256exit:
257    PSA_DONE();
258}
259/* END_CASE */
260
261/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:!MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG */
262void entropy_from_nv_seed(int seed_size_arg,
263                          int expected_init_status_arg)
264{
265    psa_status_t expected_init_status = expected_init_status_arg;
266    uint8_t random[10] = { 0 };
267    uint8_t *seed = NULL;
268    size_t seed_size = seed_size_arg;
269
270    TEST_CALLOC(seed, seed_size);
271    TEST_ASSERT(mbedtls_nv_seed_write(seed, seed_size) >= 0);
272
273    custom_entropy_sources_mask = ENTROPY_SOURCE_NV_SEED;
274    PSA_ASSERT(mbedtls_psa_crypto_configure_entropy_sources(
275                   custom_entropy_init, mbedtls_entropy_free));
276
277    TEST_EQUAL(psa_crypto_init(), expected_init_status);
278    if (expected_init_status != PSA_SUCCESS) {
279        goto exit;
280    }
281
282    PSA_ASSERT(psa_generate_random(random, sizeof(random)));
283
284exit:
285    mbedtls_free(seed);
286    PSA_DONE();
287}
288/* END_CASE */
289