blob: 31823ef2828e9ee5cb3dc2b2f7d7bc6a59febe05 [file] [log] [blame]
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/entropy.h"
Chris Jonesea0a8652021-03-09 19:11:19 +00003#include "entropy_poll.h"
Gilles Peskine72d40fc2020-04-14 21:28:42 +02004#include "mbedtls/md.h"
Mohammad Azim Khan67735d52017-04-06 11:55:43 +01005#include "string.h"
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +02006
Gilles Peskineed04a672019-10-08 14:37:27 +02007typedef enum
8{
9 DUMMY_CONSTANT_LENGTH, /* Output context->length bytes */
10 DUMMY_REQUESTED_LENGTH, /* Output whatever length was requested */
11 DUMMY_FAIL, /* Return an error code */
12} entropy_dummy_instruction;
13
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020014typedef struct {
Gilles Peskineed04a672019-10-08 14:37:27 +020015 entropy_dummy_instruction instruction;
16 size_t length; /* Length to return for DUMMY_CONSTANT_LENGTH */
17 size_t calls; /* Incremented at each call */
18} entropy_dummy_context;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020019
20/*
21 * Dummy entropy source
22 *
23 * If data is NULL, write exactly the requested length.
24 * Otherwise, write the length indicated by data or error if negative
25 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020026static int
27entropy_dummy_source(void *arg, unsigned char *output, size_t len, size_t *olen)
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020028{
Gilles Peskineed04a672019-10-08 14:37:27 +020029 entropy_dummy_context *context = arg;
30 ++context->calls;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020031
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020032 switch (context->instruction) {
Gilles Peskineed04a672019-10-08 14:37:27 +020033 case DUMMY_CONSTANT_LENGTH:
34 *olen = context->length;
35 break;
36 case DUMMY_REQUESTED_LENGTH:
37 *olen = len;
38 break;
39 case DUMMY_FAIL:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020040 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020041 }
42
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020043 memset(output, 0x2a, *olen);
44 return 0;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +020045}
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010046
47/*
48 * Ability to clear entropy sources to allow testing with just predefined
49 * entropy sources. This function or tests depending on it might break if there
50 * are internal changes to how entropy sources are registered.
51 *
52 * To be called immediately after mbedtls_entropy_init().
53 *
54 * Just resetting the counter. New sources will overwrite existing ones.
55 * This might break memory checks in the future if sources need 'free-ing' then
56 * as well.
57 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020058static void entropy_clear_sources(mbedtls_entropy_context *ctx)
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010059{
60 ctx->source_count = 0;
61}
62
Gilles Peskine7f246512019-10-08 14:51:49 +020063#if defined(MBEDTLS_ENTROPY_NV_SEED)
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010064/*
65 * NV seed read/write functions that use a buffer instead of a file
66 */
67static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
68
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020069int buffer_nv_seed_read(unsigned char *buf, size_t buf_len)
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010070{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020071 if (buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE)
72 return -1;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010073
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020074 memcpy(buf, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE);
75 return 0;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010076}
77
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020078int buffer_nv_seed_write(unsigned char *buf, size_t buf_len)
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010079{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020080 if (buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE)
81 return -1;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010082
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020083 memcpy(buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE);
84 return 0;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010085}
86
87/*
88 * NV seed read/write helpers that fill the base seedfile
89 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020090static int write_nv_seed(unsigned char *buf, size_t buf_len)
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010091{
92 FILE *f;
93
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020094 if (buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE)
95 return -1;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010096
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020097 if ((f = fopen(MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w")) == NULL)
98 return -1;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +010099
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200100 if (fwrite(buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f) !=
101 MBEDTLS_ENTROPY_BLOCK_SIZE)
102 return -1;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100103
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200104 fclose(f);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100105
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200106 return 0;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100107}
108
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200109int read_nv_seed(unsigned char *buf, size_t buf_len)
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100110{
111 FILE *f;
112
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200113 if (buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE)
114 return -1;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100115
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200116 if ((f = fopen(MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb")) == NULL)
117 return -1;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100118
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200119 if (fread(buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f) !=
120 MBEDTLS_ENTROPY_BLOCK_SIZE)
121 return -1;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100122
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200123 fclose(f);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100124
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200125 return 0;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100126}
Paul Bakker4a6c6fc2016-06-01 16:34:25 +0100127#endif /* MBEDTLS_ENTROPY_NV_SEED */
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200128/* END_HEADER */
129
130/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131 * depends_on:MBEDTLS_ENTROPY_C
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200132 * END_DEPENDENCIES
133 */
134
Gilles Peskine3d979f72021-02-22 21:24:02 +0100135/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200136void entropy_init_free(int reinit)
Gilles Peskine3d979f72021-02-22 21:24:02 +0100137{
138 mbedtls_entropy_context ctx;
139
140 /* Double free is not explicitly documented to work, but it is convenient
141 * to call mbedtls_entropy_free() unconditionally on an error path without
142 * checking whether it has already been called in the success path. */
143
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200144 mbedtls_entropy_init(&ctx);
145 mbedtls_entropy_free(&ctx);
Gilles Peskine3d979f72021-02-22 21:24:02 +0100146
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200147 if (reinit)
148 mbedtls_entropy_init(&ctx);
149 mbedtls_entropy_free(&ctx);
Gilles Peskine3d979f72021-02-22 21:24:02 +0100150
151 /* This test case always succeeds, functionally speaking. A plausible
152 * bug might trigger an invalid pointer dereference or a memory leak. */
153 goto exit;
154}
155/* END_CASE */
156
Simon Butcherb7f45c52016-09-15 18:42:26 +0100157/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200158void entropy_seed_file(char *path, int ret)
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200159{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200161
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200162 mbedtls_entropy_init(&ctx);
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200163
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200164 TEST_ASSERT(mbedtls_entropy_write_seed_file(&ctx, path) == ret);
165 TEST_ASSERT(mbedtls_entropy_update_seed_file(&ctx, path) == ret);
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200166
Paul Bakkerbd51b262014-07-10 15:26:12 +0200167exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200168 mbedtls_entropy_free(&ctx);
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200169}
170/* END_CASE */
171
Victor Krasnoshchokb3129ba2020-08-29 22:54:37 +0300172/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200173void entropy_write_base_seed_file(int ret)
Victor Krasnoshchokb3129ba2020-08-29 22:54:37 +0300174{
175 mbedtls_entropy_context ctx;
176
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200177 mbedtls_entropy_init(&ctx);
Victor Krasnoshchokb3129ba2020-08-29 22:54:37 +0300178
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200179 TEST_ASSERT(mbedtls_entropy_write_seed_file(
180 &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE) == ret);
181 TEST_ASSERT(mbedtls_entropy_update_seed_file(
182 &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE) == ret);
Victor Krasnoshchokb3129ba2020-08-29 22:54:37 +0300183
184exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200185 mbedtls_entropy_free(&ctx);
Victor Krasnoshchokb3129ba2020-08-29 22:54:37 +0300186}
187/* END_CASE */
188
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200189/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200190void entropy_no_sources()
Gilles Peskine7f246512019-10-08 14:51:49 +0200191{
192 mbedtls_entropy_context ctx;
193 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
194
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200195 mbedtls_entropy_init(&ctx);
196 entropy_clear_sources(&ctx);
197 TEST_EQUAL(mbedtls_entropy_func(&ctx, buf, sizeof(buf)),
198 MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED);
Gilles Peskine7f246512019-10-08 14:51:49 +0200199
200exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200201 mbedtls_entropy_free(&ctx);
Gilles Peskine7f246512019-10-08 14:51:49 +0200202}
203/* END_CASE */
204
205/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200206void entropy_too_many_sources()
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200207{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200209 size_t i;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200210 entropy_dummy_context dummy = { DUMMY_REQUESTED_LENGTH, 0, 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200211
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200212 mbedtls_entropy_init(&ctx);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200213
214 /*
215 * It's hard to tell precisely when the error will occur,
216 * since we don't know how many sources were automatically added.
217 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200218 for (i = 0; i < MBEDTLS_ENTROPY_MAX_SOURCES; i++)
219 (void)mbedtls_entropy_add_source(&ctx, entropy_dummy_source, &dummy, 16,
220 MBEDTLS_ENTROPY_SOURCE_WEAK);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200221
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200222 TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, &dummy,
223 16, MBEDTLS_ENTROPY_SOURCE_WEAK) ==
224 MBEDTLS_ERR_ENTROPY_MAX_SOURCES);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200225
Paul Bakkerbd51b262014-07-10 15:26:12 +0200226exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200227 mbedtls_entropy_free(&ctx);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200228}
229/* END_CASE */
230
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100231/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200232void entropy_func_len(int len, int ret)
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200233{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234 mbedtls_entropy_context ctx;
235 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
236 unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200237 size_t i, j;
238
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200239 mbedtls_entropy_init(&ctx);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200240
241 /*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242 * See comments in mbedtls_entropy_self_test()
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200243 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200244 for (i = 0; i < 8; i++) {
245 TEST_ASSERT(mbedtls_entropy_func(&ctx, buf, len) == ret);
246 for (j = 0; j < sizeof(buf); j++)
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200247 acc[j] |= buf[j];
248 }
249
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200250 if (ret == 0)
251 for (j = 0; j < (size_t)len; j++)
252 TEST_ASSERT(acc[j] != 0);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200253
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200254 for (j = len; j < sizeof(buf); j++)
255 TEST_ASSERT(acc[j] == 0);
Gilles Peskine7aba0362021-01-31 00:07:11 +0100256
257exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200258 mbedtls_entropy_free(&ctx);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200259}
260/* END_CASE */
261
262/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200263void entropy_source_fail(char *path)
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200264{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200265 mbedtls_entropy_context ctx;
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200266 unsigned char buf[16];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200267 entropy_dummy_context dummy = { DUMMY_FAIL, 0, 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200268
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200269 mbedtls_entropy_init(&ctx);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200270
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200271 TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, &dummy,
272 16,
273 MBEDTLS_ENTROPY_SOURCE_WEAK) == 0);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200274
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200275 TEST_ASSERT(mbedtls_entropy_func(&ctx, buf, sizeof(buf)) ==
276 MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
277 TEST_ASSERT(mbedtls_entropy_gather(&ctx) ==
278 MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
Simon Butcherb7f45c52016-09-15 18:42:26 +0100279#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_ENTROPY_NV_SEED)
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200280 TEST_ASSERT(mbedtls_entropy_write_seed_file(&ctx, path) ==
281 MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
282 TEST_ASSERT(mbedtls_entropy_update_seed_file(&ctx, path) ==
283 MBEDTLS_ERR_ENTROPY_SOURCE_FAILED);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200284#else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200285 ((void)path);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200286#endif
287
Paul Bakkerbd51b262014-07-10 15:26:12 +0200288exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200289 mbedtls_entropy_free(&ctx);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200290}
291/* END_CASE */
292
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100293/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200294void entropy_threshold(int threshold, int chunk_size, int result)
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200295{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200296 mbedtls_entropy_context ctx;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200297 entropy_dummy_context strong = { DUMMY_CONSTANT_LENGTH,
298 MBEDTLS_ENTROPY_BLOCK_SIZE, 0 };
299 entropy_dummy_context weak = { DUMMY_CONSTANT_LENGTH, chunk_size, 0 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200300 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200301 int ret;
302
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200303 mbedtls_entropy_init(&ctx);
304 entropy_clear_sources(&ctx);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200305
Gilles Peskinecbd91e02019-11-25 19:50:54 +0100306 /* Set strong source that reaches its threshold immediately and
307 * a weak source whose threshold is a test parameter. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200308 TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, &strong,
309 1,
310 MBEDTLS_ENTROPY_SOURCE_STRONG) == 0);
311 TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, &weak,
312 threshold,
313 MBEDTLS_ENTROPY_SOURCE_WEAK) == 0);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200314
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200315 ret = mbedtls_entropy_func(&ctx, buf, sizeof(buf));
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200316
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200317 if (result >= 0) {
318 TEST_ASSERT(ret == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100319#if defined(MBEDTLS_ENTROPY_NV_SEED)
Gilles Peskineae679392019-11-25 18:26:23 +0100320 /* If the NV seed functionality is enabled, there are two entropy
321 * updates: before and after updating the NV seed. */
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100322 result *= 2;
323#endif
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200324 TEST_ASSERT(weak.calls == (size_t)result);
325 } else {
326 TEST_ASSERT(ret == result);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200327 }
328
Paul Bakkerbd51b262014-07-10 15:26:12 +0200329exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200330 mbedtls_entropy_free(&ctx);
Manuel Pégourié-Gonnardc7c56b22014-05-30 11:42:01 +0200331}
332/* END_CASE */
333
Gilles Peskine65fc0682019-10-08 15:01:34 +0200334/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200335void entropy_calls(int strength1,
336 int strength2,
337 int threshold,
338 int chunk_size,
339 int result)
Gilles Peskine65fc0682019-10-08 15:01:34 +0200340{
341 /*
342 * if result >= 0: result = expected number of calls to source 1
343 * if result < 0: result = expected return code from mbedtls_entropy_func()
344 */
345
346 mbedtls_entropy_context ctx;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200347 entropy_dummy_context dummy1 = { DUMMY_CONSTANT_LENGTH, chunk_size, 0 };
348 entropy_dummy_context dummy2 = { DUMMY_CONSTANT_LENGTH, chunk_size, 0 };
Gilles Peskine65fc0682019-10-08 15:01:34 +0200349 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
350 int ret;
351
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200352 mbedtls_entropy_init(&ctx);
353 entropy_clear_sources(&ctx);
Gilles Peskine65fc0682019-10-08 15:01:34 +0200354
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200355 TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, &dummy1,
356 threshold, strength1) == 0);
357 TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, &dummy2,
358 threshold, strength2) == 0);
Gilles Peskine65fc0682019-10-08 15:01:34 +0200359
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200360 ret = mbedtls_entropy_func(&ctx, buf, sizeof(buf));
Gilles Peskine65fc0682019-10-08 15:01:34 +0200361
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200362 if (result >= 0) {
363 TEST_ASSERT(ret == 0);
Gilles Peskineae679392019-11-25 18:26:23 +0100364#if defined(MBEDTLS_ENTROPY_NV_SEED)
365 /* If the NV seed functionality is enabled, there are two entropy
366 * updates: before and after updating the NV seed. */
367 result *= 2;
368#endif
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200369 TEST_ASSERT(dummy1.calls == (size_t)result);
370 } else {
371 TEST_ASSERT(ret == result);
Gilles Peskine65fc0682019-10-08 15:01:34 +0200372 }
373
374exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200375 mbedtls_entropy_free(&ctx);
Gilles Peskine65fc0682019-10-08 15:01:34 +0200376}
377/* END_CASE */
378
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100379/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200380void nv_seed_file_create()
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100381{
382 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
383
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200384 memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100385
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200386 TEST_ASSERT(write_nv_seed(buf, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100387}
388/* END_CASE */
389
Paul Bakkerb598c292016-06-01 16:57:11 +0100390/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO:MBEDTLS_PLATFORM_NV_SEED_ALT */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200391void entropy_nv_seed_std_io()
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100392{
393 unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
394 unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
395
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200396 memset(io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE);
397 memset(check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100398
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200399 mbedtls_platform_set_nv_seed(mbedtls_platform_std_nv_seed_read,
400 mbedtls_platform_std_nv_seed_write);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100401
402 /* Check if platform NV read and write manipulate the same data */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200403 TEST_ASSERT(write_nv_seed(io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0);
404 TEST_ASSERT(mbedtls_nv_seed_read(check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) ==
405 MBEDTLS_ENTROPY_BLOCK_SIZE);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100406
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200407 TEST_ASSERT(memcmp(io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100408
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200409 memset(check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100410
411 /* Check if platform NV write and raw read manipulate the same data */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200412 TEST_ASSERT(mbedtls_nv_seed_write(io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) ==
413 MBEDTLS_ENTROPY_BLOCK_SIZE);
414 TEST_ASSERT(read_nv_seed(check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100415
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200416 TEST_ASSERT(memcmp(io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100417}
418/* END_CASE */
419
Gilles Peskine66afcca2019-06-12 19:33:42 +0200420/* BEGIN_CASE depends_on:MBEDTLS_MD_C:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200421void entropy_nv_seed(data_t *read_seed)
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100422{
Gilles Peskine66afcca2019-06-12 19:33:42 +0200423#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
424 const mbedtls_md_info_t *md_info =
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200425 mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
Gilles Peskine66afcca2019-06-12 19:33:42 +0200426#elif defined(MBEDTLS_ENTROPY_SHA256_ACCUMULATOR)
427 const mbedtls_md_info_t *md_info =
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200428 mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
Gilles Peskine66afcca2019-06-12 19:33:42 +0200429#else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200430# error "Unsupported entropy accumulator"
Gilles Peskine66afcca2019-06-12 19:33:42 +0200431#endif
432 mbedtls_md_context_t accumulator;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100433 mbedtls_entropy_context ctx;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200434 int (*original_mbedtls_nv_seed_read)(unsigned char *buf, size_t buf_len) =
Gilles Peskinee39b9032019-06-12 19:31:29 +0200435 mbedtls_nv_seed_read;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200436 int (*original_mbedtls_nv_seed_write)(unsigned char *buf, size_t buf_len) =
Gilles Peskinee39b9032019-06-12 19:31:29 +0200437 mbedtls_nv_seed_write;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100438
439 unsigned char header[2];
440 unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
441 unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
442 unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE];
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100443 unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
444 unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
445
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200446 memset(entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
447 memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
448 memset(empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
449 memset(check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE);
450 memset(check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100451
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100452 // Make sure we read/write NV seed from our buffers
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200453 mbedtls_platform_set_nv_seed(buffer_nv_seed_read, buffer_nv_seed_write);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100454
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200455 mbedtls_md_init(&accumulator);
456 mbedtls_entropy_init(&ctx);
457 entropy_clear_sources(&ctx);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100458
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200459 TEST_ASSERT(mbedtls_entropy_add_source(&ctx, mbedtls_nv_seed_poll, NULL,
460 MBEDTLS_ENTROPY_BLOCK_SIZE,
461 MBEDTLS_ENTROPY_SOURCE_STRONG) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100462
Gilles Peskine66afcca2019-06-12 19:33:42 +0200463 // Set the initial NV seed to read
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200464 TEST_ASSERT(read_seed->len >= MBEDTLS_ENTROPY_BLOCK_SIZE);
465 memcpy(buffer_seed, read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE);
Gilles Peskine66afcca2019-06-12 19:33:42 +0200466
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100467 // Do an entropy run
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200468 TEST_ASSERT(mbedtls_entropy_func(&ctx, entropy, sizeof(entropy)) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100469 // Determine what should have happened with manual entropy internal logic
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100470
471 // Init accumulator
472 header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200473 TEST_ASSERT(mbedtls_md_setup(&accumulator, md_info, 0) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100474
475 // First run for updating write_seed
476 header[0] = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200477 TEST_ASSERT(mbedtls_md_starts(&accumulator) == 0);
478 TEST_ASSERT(mbedtls_md_update(&accumulator, header, 2) == 0);
479 TEST_ASSERT(mbedtls_md_update(&accumulator, read_seed->x,
480 MBEDTLS_ENTROPY_BLOCK_SIZE) == 0);
481 TEST_ASSERT(mbedtls_md_finish(&accumulator, buf) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100482
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200483 TEST_ASSERT(mbedtls_md_starts(&accumulator) == 0);
484 TEST_ASSERT(
485 mbedtls_md_update(&accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100486
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200487 TEST_ASSERT(
488 mbedtls_md(md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE, check_seed) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100489
490 // Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed)
491 header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200492 TEST_ASSERT(mbedtls_md_update(&accumulator, header, 2) == 0);
493 TEST_ASSERT(mbedtls_md_update(&accumulator, empty,
494 MBEDTLS_ENTROPY_BLOCK_SIZE) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100495
496 header[0] = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200497 TEST_ASSERT(mbedtls_md_update(&accumulator, header, 2) == 0);
498 TEST_ASSERT(mbedtls_md_update(&accumulator, check_seed,
499 MBEDTLS_ENTROPY_BLOCK_SIZE) == 0);
500 TEST_ASSERT(mbedtls_md_finish(&accumulator, buf) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100501
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200502 TEST_ASSERT(mbedtls_md(md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
503 check_entropy) == 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100504
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200505 // Check result of both NV file and entropy received with the manual
506 // calculations
507 TEST_ASSERT(memcmp(check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) ==
508 0);
509 TEST_ASSERT(memcmp(check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE) ==
510 0);
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100511
Gilles Peskinee39b9032019-06-12 19:31:29 +0200512exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200513 mbedtls_md_free(&accumulator);
514 mbedtls_entropy_free(&ctx);
Gilles Peskinee39b9032019-06-12 19:31:29 +0200515 mbedtls_nv_seed_read = original_mbedtls_nv_seed_read;
516 mbedtls_nv_seed_write = original_mbedtls_nv_seed_write;
Paul Bakkerffbfb4c2016-06-01 15:36:18 +0100517}
518/* END_CASE */
519
Hanno Beckerd4a872e2017-09-07 08:09:33 +0100520/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG:MBEDTLS_SELF_TEST */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200521void entropy_selftest(int result)
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200522{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200523 TEST_ASSERT(mbedtls_entropy_self_test(1) == result);
Manuel Pégourié-Gonnard2c25eb02014-05-30 10:38:18 +0200524}
525/* END_CASE */