2 * Entropy accumulator implementation
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 #if defined(MBEDTLS_ENTROPY_C)
24 #if defined(MBEDTLS_TEST_NULL_ENTROPY)
25 #warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! "
26 #warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES "
27 #warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE "
30 #include "mbedtls/entropy.h"
31 #include "mbedtls/entropy_poll.h"
32 #include "mbedtls/platform_util.h"
33 #include "mbedtls/error.h"
37 #if defined(MBEDTLS_FS_IO)
41 #if defined(MBEDTLS_ENTROPY_NV_SEED)
42 #include "mbedtls/platform.h"
45 #if defined(MBEDTLS_SELF_TEST)
46 #if defined(MBEDTLS_PLATFORM_C)
47 #include "mbedtls/platform.h"
50 #define mbedtls_printf printf
51 #endif /* MBEDTLS_PLATFORM_C */
52 #endif /* MBEDTLS_SELF_TEST */
54 #if defined(MBEDTLS_HAVEGE_C)
55 #include "mbedtls/havege.h"
58 #define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
60 void mbedtls_entropy_init(mbedtls_entropy_context
*ctx
) {
61 ctx
->source_count
= 0;
62 memset(ctx
->source
, 0, sizeof(ctx
->source
));
64 #if defined(MBEDTLS_THREADING_C)
65 mbedtls_mutex_init(&ctx
->mutex
);
68 ctx
->accumulator_started
= 0;
69 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
70 mbedtls_sha512_init(&ctx
->accumulator
);
72 mbedtls_sha256_init(&ctx
->accumulator
);
74 #if defined(MBEDTLS_HAVEGE_C)
75 mbedtls_havege_init(&ctx
->havege_data
);
78 /* Reminder: Update ENTROPY_HAVE_STRONG in the test files
79 * when adding more strong entropy sources here. */
81 #if defined(MBEDTLS_TEST_NULL_ENTROPY)
82 mbedtls_entropy_add_source(ctx
, mbedtls_null_entropy_poll
, NULL
,
83 1, MBEDTLS_ENTROPY_SOURCE_STRONG
);
86 #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
87 #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
88 mbedtls_entropy_add_source(ctx
, mbedtls_platform_entropy_poll
, NULL
,
89 MBEDTLS_ENTROPY_MIN_PLATFORM
,
90 MBEDTLS_ENTROPY_SOURCE_STRONG
);
92 #if defined(MBEDTLS_TIMING_C)
93 mbedtls_entropy_add_source(ctx
, mbedtls_hardclock_poll
, NULL
,
94 MBEDTLS_ENTROPY_MIN_HARDCLOCK
,
95 MBEDTLS_ENTROPY_SOURCE_WEAK
);
97 #if defined(MBEDTLS_HAVEGE_C)
98 mbedtls_entropy_add_source(ctx
, mbedtls_havege_poll
, &ctx
->havege_data
,
99 MBEDTLS_ENTROPY_MIN_HAVEGE
,
100 MBEDTLS_ENTROPY_SOURCE_STRONG
);
102 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
103 mbedtls_entropy_add_source(ctx
, mbedtls_hardware_poll
, NULL
,
104 MBEDTLS_ENTROPY_MIN_HARDWARE
,
105 MBEDTLS_ENTROPY_SOURCE_STRONG
);
107 #if defined(MBEDTLS_ENTROPY_NV_SEED)
108 mbedtls_entropy_add_source(ctx
, mbedtls_nv_seed_poll
, NULL
,
109 MBEDTLS_ENTROPY_BLOCK_SIZE
,
110 MBEDTLS_ENTROPY_SOURCE_STRONG
);
111 ctx
->initial_entropy_run
= 0;
113 #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
116 void mbedtls_entropy_free(mbedtls_entropy_context
*ctx
) {
117 /* If the context was already free, don't call free() again.
118 * This is important for mutexes which don't allow double-free. */
119 if (ctx
->accumulator_started
== -1)
122 #if defined(MBEDTLS_HAVEGE_C)
123 mbedtls_havege_free(&ctx
->havege_data
);
125 #if defined(MBEDTLS_THREADING_C)
126 mbedtls_mutex_free(&ctx
->mutex
);
128 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
129 mbedtls_sha512_free(&ctx
->accumulator
);
131 mbedtls_sha256_free(&ctx
->accumulator
);
133 #if defined(MBEDTLS_ENTROPY_NV_SEED)
134 ctx
->initial_entropy_run
= 0;
136 ctx
->source_count
= 0;
137 mbedtls_platform_zeroize(ctx
->source
, sizeof(ctx
->source
));
138 ctx
->accumulator_started
= -1;
141 int mbedtls_entropy_add_source(mbedtls_entropy_context
*ctx
,
142 mbedtls_entropy_f_source_ptr f_source
, void *p_source
,
143 size_t threshold
, int strong
) {
146 #if defined(MBEDTLS_THREADING_C)
147 if ((ret
= mbedtls_mutex_lock(&ctx
->mutex
)) != 0)
151 idx
= ctx
->source_count
;
152 if (idx
>= MBEDTLS_ENTROPY_MAX_SOURCES
) {
153 ret
= MBEDTLS_ERR_ENTROPY_MAX_SOURCES
;
157 ctx
->source
[idx
].f_source
= f_source
;
158 ctx
->source
[idx
].p_source
= p_source
;
159 ctx
->source
[idx
].threshold
= threshold
;
160 ctx
->source
[idx
].strong
= strong
;
165 #if defined(MBEDTLS_THREADING_C)
166 if (mbedtls_mutex_unlock(&ctx
->mutex
) != 0)
167 return (MBEDTLS_ERR_THREADING_MUTEX_ERROR
);
174 * Entropy accumulator update
176 static int entropy_update(mbedtls_entropy_context
*ctx
, unsigned char source_id
,
177 const unsigned char *data
, size_t len
) {
178 unsigned char header
[2];
179 unsigned char tmp
[MBEDTLS_ENTROPY_BLOCK_SIZE
];
180 size_t use_len
= len
;
181 const unsigned char *p
= data
;
184 if (use_len
> MBEDTLS_ENTROPY_BLOCK_SIZE
) {
185 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
186 if ((ret
= mbedtls_sha512_ret(data
, len
, tmp
, 0)) != 0)
189 if ((ret
= mbedtls_sha256_ret(data
, len
, tmp
, 0)) != 0)
193 use_len
= MBEDTLS_ENTROPY_BLOCK_SIZE
;
196 header
[0] = source_id
;
197 header
[1] = use_len
& 0xFF;
200 * Start the accumulator if this has not already happened. Note that
201 * it is sufficient to start the accumulator here only because all calls to
202 * gather entropy eventually execute this code.
204 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
205 if (ctx
->accumulator_started
== 0 &&
206 (ret
= mbedtls_sha512_starts_ret(&ctx
->accumulator
, 0)) != 0)
209 ctx
->accumulator_started
= 1;
210 if ((ret
= mbedtls_sha512_update_ret(&ctx
->accumulator
, header
, 2)) != 0)
212 ret
= mbedtls_sha512_update_ret(&ctx
->accumulator
, p
, use_len
);
214 if (ctx
->accumulator_started
== 0 &&
215 (ret
= mbedtls_sha256_starts_ret(&ctx
->accumulator
, 0)) != 0)
218 ctx
->accumulator_started
= 1;
219 if ((ret
= mbedtls_sha256_update_ret(&ctx
->accumulator
, header
, 2)) != 0)
221 ret
= mbedtls_sha256_update_ret(&ctx
->accumulator
, p
, use_len
);
225 mbedtls_platform_zeroize(tmp
, sizeof(tmp
));
230 int mbedtls_entropy_update_manual(mbedtls_entropy_context
*ctx
,
231 const unsigned char *data
, size_t len
) {
232 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
234 #if defined(MBEDTLS_THREADING_C)
235 if ((ret
= mbedtls_mutex_lock(&ctx
->mutex
)) != 0)
239 ret
= entropy_update(ctx
, MBEDTLS_ENTROPY_SOURCE_MANUAL
, data
, len
);
241 #if defined(MBEDTLS_THREADING_C)
242 if (mbedtls_mutex_unlock(&ctx
->mutex
) != 0)
243 return (MBEDTLS_ERR_THREADING_MUTEX_ERROR
);
250 * Run through the different sources to add entropy to our accumulator
252 static int entropy_gather_internal(mbedtls_entropy_context
*ctx
) {
253 int ret
= MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
;
255 int have_one_strong
= 0;
256 unsigned char buf
[MBEDTLS_ENTROPY_MAX_GATHER
];
259 if (ctx
->source_count
== 0)
260 return (MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED
);
263 * Run through our entropy sources
265 for (i
= 0; i
< ctx
->source_count
; i
++) {
266 if (ctx
->source
[i
].strong
== MBEDTLS_ENTROPY_SOURCE_STRONG
)
270 if ((ret
= ctx
->source
[i
].f_source(ctx
->source
[i
].p_source
,
271 buf
, MBEDTLS_ENTROPY_MAX_GATHER
, &olen
)) != 0) {
276 * Add if we actually gathered something
279 if ((ret
= entropy_update(ctx
, (unsigned char) i
,
282 ctx
->source
[i
].size
+= olen
;
286 if (have_one_strong
== 0)
287 ret
= MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE
;
290 mbedtls_platform_zeroize(buf
, sizeof(buf
));
296 * Thread-safe wrapper for entropy_gather_internal()
298 int mbedtls_entropy_gather(mbedtls_entropy_context
*ctx
) {
299 int ret
= MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
;
301 #if defined(MBEDTLS_THREADING_C)
302 if ((ret
= mbedtls_mutex_lock(&ctx
->mutex
)) != 0)
306 ret
= entropy_gather_internal(ctx
);
308 #if defined(MBEDTLS_THREADING_C)
309 if (mbedtls_mutex_unlock(&ctx
->mutex
) != 0)
310 return (MBEDTLS_ERR_THREADING_MUTEX_ERROR
);
316 int mbedtls_entropy_func(void *data
, unsigned char *output
, size_t len
) {
317 int ret
, count
= 0, i
, thresholds_reached
;
319 mbedtls_entropy_context
*ctx
= (mbedtls_entropy_context
*) data
;
320 unsigned char buf
[MBEDTLS_ENTROPY_BLOCK_SIZE
];
322 if (len
> MBEDTLS_ENTROPY_BLOCK_SIZE
)
323 return (MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
);
325 #if defined(MBEDTLS_ENTROPY_NV_SEED)
326 /* Update the NV entropy seed before generating any entropy for outside
329 if (ctx
->initial_entropy_run
== 0) {
330 ctx
->initial_entropy_run
= 1;
331 if ((ret
= mbedtls_entropy_update_nv_seed(ctx
)) != 0)
336 #if defined(MBEDTLS_THREADING_C)
337 if ((ret
= mbedtls_mutex_lock(&ctx
->mutex
)) != 0)
342 * Always gather extra entropy before a call
345 if (count
++ > ENTROPY_MAX_LOOP
) {
346 ret
= MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
;
350 if ((ret
= entropy_gather_internal(ctx
)) != 0)
353 thresholds_reached
= 1;
355 for (i
= 0; i
< ctx
->source_count
; i
++) {
356 if (ctx
->source
[i
].size
< ctx
->source
[i
].threshold
)
357 thresholds_reached
= 0;
358 if (ctx
->source
[i
].strong
== MBEDTLS_ENTROPY_SOURCE_STRONG
)
359 strong_size
+= ctx
->source
[i
].size
;
361 } while (! thresholds_reached
|| strong_size
< MBEDTLS_ENTROPY_BLOCK_SIZE
);
363 memset(buf
, 0, MBEDTLS_ENTROPY_BLOCK_SIZE
);
365 #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
367 * Note that at this stage it is assumed that the accumulator was started
368 * in a previous call to entropy_update(). If this is not guaranteed, the
369 * code below will fail.
371 if ((ret
= mbedtls_sha512_finish_ret(&ctx
->accumulator
, buf
)) != 0)
375 * Reset accumulator and counters and recycle existing entropy
377 mbedtls_sha512_free(&ctx
->accumulator
);
378 mbedtls_sha512_init(&ctx
->accumulator
);
379 if ((ret
= mbedtls_sha512_starts_ret(&ctx
->accumulator
, 0)) != 0)
381 if ((ret
= mbedtls_sha512_update_ret(&ctx
->accumulator
, buf
,
382 MBEDTLS_ENTROPY_BLOCK_SIZE
)) != 0)
386 * Perform second SHA-512 on entropy
388 if ((ret
= mbedtls_sha512_ret(buf
, MBEDTLS_ENTROPY_BLOCK_SIZE
,
391 #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
392 if ((ret
= mbedtls_sha256_finish_ret(&ctx
->accumulator
, buf
)) != 0)
396 * Reset accumulator and counters and recycle existing entropy
398 mbedtls_sha256_free(&ctx
->accumulator
);
399 mbedtls_sha256_init(&ctx
->accumulator
);
400 if ((ret
= mbedtls_sha256_starts_ret(&ctx
->accumulator
, 0)) != 0)
402 if ((ret
= mbedtls_sha256_update_ret(&ctx
->accumulator
, buf
,
403 MBEDTLS_ENTROPY_BLOCK_SIZE
)) != 0)
407 * Perform second SHA-256 on entropy
409 if ((ret
= mbedtls_sha256_ret(buf
, MBEDTLS_ENTROPY_BLOCK_SIZE
,
412 #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
414 for (i
= 0; i
< ctx
->source_count
; i
++)
415 ctx
->source
[i
].size
= 0;
417 memcpy(output
, buf
, len
);
422 mbedtls_platform_zeroize(buf
, sizeof(buf
));
424 #if defined(MBEDTLS_THREADING_C)
425 if (mbedtls_mutex_unlock(&ctx
->mutex
) != 0)
426 return (MBEDTLS_ERR_THREADING_MUTEX_ERROR
);
432 #if defined(MBEDTLS_ENTROPY_NV_SEED)
433 int mbedtls_entropy_update_nv_seed(mbedtls_entropy_context
*ctx
) {
434 int ret
= MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR
;
435 unsigned char buf
[MBEDTLS_ENTROPY_BLOCK_SIZE
];
437 /* Read new seed and write it to NV */
438 if ((ret
= mbedtls_entropy_func(ctx
, buf
, MBEDTLS_ENTROPY_BLOCK_SIZE
)) != 0)
441 if (mbedtls_nv_seed_write(buf
, MBEDTLS_ENTROPY_BLOCK_SIZE
) < 0)
442 return (MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR
);
444 /* Manually update the remaining stream with a separator value to diverge */
445 memset(buf
, 0, MBEDTLS_ENTROPY_BLOCK_SIZE
);
446 ret
= mbedtls_entropy_update_manual(ctx
, buf
, MBEDTLS_ENTROPY_BLOCK_SIZE
);
450 #endif /* MBEDTLS_ENTROPY_NV_SEED */
452 #if defined(MBEDTLS_FS_IO)
453 int mbedtls_entropy_write_seed_file(mbedtls_entropy_context
*ctx
, const char *path
) {
454 int ret
= MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR
;
456 unsigned char buf
[MBEDTLS_ENTROPY_BLOCK_SIZE
];
458 if ((f
= fopen(path
, "wb")) == NULL
)
459 return (MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR
);
461 if ((ret
= mbedtls_entropy_func(ctx
, buf
, MBEDTLS_ENTROPY_BLOCK_SIZE
)) != 0)
464 if (fwrite(buf
, 1, MBEDTLS_ENTROPY_BLOCK_SIZE
, f
) != MBEDTLS_ENTROPY_BLOCK_SIZE
) {
465 ret
= MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR
;
472 mbedtls_platform_zeroize(buf
, sizeof(buf
));
478 int mbedtls_entropy_update_seed_file(mbedtls_entropy_context
*ctx
, const char *path
) {
482 unsigned char buf
[ MBEDTLS_ENTROPY_MAX_SEED_SIZE
];
484 if ((f
= fopen(path
, "rb")) == NULL
)
485 return (MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR
);
487 fseek(f
, 0, SEEK_END
);
488 n
= (size_t) ftell(f
);
489 fseek(f
, 0, SEEK_SET
);
491 if (n
> MBEDTLS_ENTROPY_MAX_SEED_SIZE
)
492 n
= MBEDTLS_ENTROPY_MAX_SEED_SIZE
;
494 if (fread(buf
, 1, n
, f
) != n
)
495 ret
= MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR
;
497 ret
= mbedtls_entropy_update_manual(ctx
, buf
, n
);
501 mbedtls_platform_zeroize(buf
, sizeof(buf
));
506 return (mbedtls_entropy_write_seed_file(ctx
, path
));
508 #endif /* MBEDTLS_FS_IO */
510 #if defined(MBEDTLS_SELF_TEST)
511 #if !defined(MBEDTLS_TEST_NULL_ENTROPY)
513 * Dummy source function
515 static int entropy_dummy_source(void *data
, unsigned char *output
,
516 size_t len
, size_t *olen
) {
519 memset(output
, 0x2a, len
);
524 #endif /* !MBEDTLS_TEST_NULL_ENTROPY */
526 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
528 static int mbedtls_entropy_source_self_test_gather(unsigned char *buf
, size_t buf_len
) {
530 size_t entropy_len
= 0;
532 size_t attempts
= buf_len
;
534 while (attempts
> 0 && entropy_len
< buf_len
) {
535 if ((ret
= mbedtls_hardware_poll(NULL
, buf
+ entropy_len
,
536 buf_len
- entropy_len
, &olen
)) != 0)
543 if (entropy_len
< buf_len
) {
551 static int mbedtls_entropy_source_self_test_check_bits(const unsigned char *buf
,
553 unsigned char set
= 0xFF;
554 unsigned char unset
= 0x00;
557 for (i
= 0; i
< buf_len
; i
++) {
562 return (set
== 0xFF || unset
== 0x00);
566 * A test to ensure hat the entropy sources are functioning correctly
567 * and there is no obvious failure. The test performs the following checks:
568 * - The entropy source is not providing only 0s (all bits unset) or 1s (all
570 * - The entropy source is not providing values in a pattern. Because the
571 * hardware could be providing data in an arbitrary length, this check polls
572 * the hardware entropy source twice and compares the result to ensure they
574 * - The error code returned by the entropy source is not an error.
576 int mbedtls_entropy_source_self_test(int verbose
) {
578 unsigned char buf0
[2 * sizeof(unsigned long long int)];
579 unsigned char buf1
[2 * sizeof(unsigned long long int)];
582 mbedtls_printf(" ENTROPY_BIAS test: ");
584 memset(buf0
, 0x00, sizeof(buf0
));
585 memset(buf1
, 0x00, sizeof(buf1
));
587 if ((ret
= mbedtls_entropy_source_self_test_gather(buf0
, sizeof(buf0
))) != 0)
589 if ((ret
= mbedtls_entropy_source_self_test_gather(buf1
, sizeof(buf1
))) != 0)
592 /* Make sure that the returned values are not all 0 or 1 */
593 if ((ret
= mbedtls_entropy_source_self_test_check_bits(buf0
, sizeof(buf0
))) != 0)
595 if ((ret
= mbedtls_entropy_source_self_test_check_bits(buf1
, sizeof(buf1
))) != 0)
598 /* Make sure that the entropy source is not returning values in a
600 ret
= memcmp(buf0
, buf1
, sizeof(buf0
)) == 0;
605 mbedtls_printf("failed\n");
607 mbedtls_printf("passed\n");
609 mbedtls_printf("\n");
615 #endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
618 * The actual entropy quality is hard to test, but we can at least
619 * test that the functions don't cause errors and write the correct
620 * amount of data to buffers.
622 int mbedtls_entropy_self_test(int verbose
) {
624 #if !defined(MBEDTLS_TEST_NULL_ENTROPY)
625 mbedtls_entropy_context ctx
;
626 unsigned char buf
[MBEDTLS_ENTROPY_BLOCK_SIZE
] = { 0 };
627 unsigned char acc
[MBEDTLS_ENTROPY_BLOCK_SIZE
] = { 0 };
629 #endif /* !MBEDTLS_TEST_NULL_ENTROPY */
632 mbedtls_printf(" ENTROPY test: ");
634 #if !defined(MBEDTLS_TEST_NULL_ENTROPY)
635 mbedtls_entropy_init(&ctx
);
637 /* First do a gather to make sure we have default sources */
638 if ((ret
= mbedtls_entropy_gather(&ctx
)) != 0)
641 ret
= mbedtls_entropy_add_source(&ctx
, entropy_dummy_source
, NULL
, 16,
642 MBEDTLS_ENTROPY_SOURCE_WEAK
);
646 if ((ret
= mbedtls_entropy_update_manual(&ctx
, buf
, sizeof buf
)) != 0)
650 * To test that mbedtls_entropy_func writes correct number of bytes:
651 * - use the whole buffer and rely on ASan to detect overruns
652 * - collect entropy 8 times and OR the result in an accumulator:
653 * any byte should then be 0 with probably 2^(-64), so requiring
654 * each of the 32 or 64 bytes to be non-zero has a false failure rate
655 * of at most 2^(-58) which is acceptable.
657 for (i
= 0; i
< 8; i
++) {
658 if ((ret
= mbedtls_entropy_func(&ctx
, buf
, sizeof(buf
))) != 0)
661 for (j
= 0; j
< sizeof(buf
); j
++)
665 for (j
= 0; j
< sizeof(buf
); j
++) {
672 #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
673 if ((ret
= mbedtls_entropy_source_self_test(0)) != 0)
678 mbedtls_entropy_free(&ctx
);
679 #endif /* !MBEDTLS_TEST_NULL_ENTROPY */
683 mbedtls_printf("failed\n");
685 mbedtls_printf("passed\n");
687 mbedtls_printf("\n");
692 #endif /* MBEDTLS_SELF_TEST */
694 #endif /* MBEDTLS_ENTROPY_C */