entropy.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. /*
  2. * Entropy accumulator implementation
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  6. */
  7. #include "common.h"
  8. #if defined(MBEDTLS_ENTROPY_C)
  9. #if defined(MBEDTLS_TEST_NULL_ENTROPY)
  10. #warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! "
  11. #warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES "
  12. #warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE "
  13. #endif
  14. #include "mbedtls/entropy.h"
  15. #include "mbedtls/entropy_poll.h"
  16. #include "mbedtls/platform_util.h"
  17. #include "mbedtls/error.h"
  18. #include "mbedtls/sha256.h"
  19. #include "mbedtls/sha512.h"
  20. #include <string.h>
  21. #if defined(MBEDTLS_FS_IO)
  22. #include <stdio.h>
  23. #endif
  24. #include "mbedtls/platform.h"
  25. #include "mbedtls/platform.h"
  26. #if defined(MBEDTLS_HAVEGE_C)
  27. #include "mbedtls/havege.h"
  28. #endif
  29. #define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
  30. void mbedtls_entropy_init(mbedtls_entropy_context *ctx)
  31. {
  32. ctx->source_count = 0;
  33. memset(ctx->source, 0, sizeof(ctx->source));
  34. #if defined(MBEDTLS_THREADING_C)
  35. mbedtls_mutex_init(&ctx->mutex);
  36. #endif
  37. ctx->accumulator_started = 0;
  38. #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
  39. mbedtls_sha512_init(&ctx->accumulator);
  40. #else
  41. mbedtls_sha256_init(&ctx->accumulator);
  42. #endif
  43. #if defined(MBEDTLS_HAVEGE_C)
  44. mbedtls_havege_init(&ctx->havege_data);
  45. #endif
  46. /* Reminder: Update ENTROPY_HAVE_STRONG in the test files
  47. * when adding more strong entropy sources here. */
  48. #if defined(MBEDTLS_TEST_NULL_ENTROPY)
  49. mbedtls_entropy_add_source(ctx, mbedtls_null_entropy_poll, NULL,
  50. 1, MBEDTLS_ENTROPY_SOURCE_STRONG);
  51. #endif
  52. #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
  53. #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
  54. mbedtls_entropy_add_source(ctx, mbedtls_platform_entropy_poll, NULL,
  55. MBEDTLS_ENTROPY_MIN_PLATFORM,
  56. MBEDTLS_ENTROPY_SOURCE_STRONG);
  57. #endif
  58. #if defined(MBEDTLS_TIMING_C)
  59. mbedtls_entropy_add_source(ctx, mbedtls_hardclock_poll, NULL,
  60. MBEDTLS_ENTROPY_MIN_HARDCLOCK,
  61. MBEDTLS_ENTROPY_SOURCE_WEAK);
  62. #endif
  63. #if defined(MBEDTLS_HAVEGE_C)
  64. mbedtls_entropy_add_source(ctx, mbedtls_havege_poll, &ctx->havege_data,
  65. MBEDTLS_ENTROPY_MIN_HAVEGE,
  66. MBEDTLS_ENTROPY_SOURCE_STRONG);
  67. #endif
  68. #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
  69. mbedtls_entropy_add_source(ctx, mbedtls_hardware_poll, NULL,
  70. MBEDTLS_ENTROPY_MIN_HARDWARE,
  71. MBEDTLS_ENTROPY_SOURCE_STRONG);
  72. #endif
  73. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  74. mbedtls_entropy_add_source(ctx, mbedtls_nv_seed_poll, NULL,
  75. MBEDTLS_ENTROPY_BLOCK_SIZE,
  76. MBEDTLS_ENTROPY_SOURCE_STRONG);
  77. ctx->initial_entropy_run = 0;
  78. #endif
  79. #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
  80. }
  81. void mbedtls_entropy_free(mbedtls_entropy_context *ctx)
  82. {
  83. /* If the context was already free, don't call free() again.
  84. * This is important for mutexes which don't allow double-free. */
  85. if (ctx->accumulator_started == -1) {
  86. return;
  87. }
  88. #if defined(MBEDTLS_HAVEGE_C)
  89. mbedtls_havege_free(&ctx->havege_data);
  90. #endif
  91. #if defined(MBEDTLS_THREADING_C)
  92. mbedtls_mutex_free(&ctx->mutex);
  93. #endif
  94. #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
  95. mbedtls_sha512_free(&ctx->accumulator);
  96. #else
  97. mbedtls_sha256_free(&ctx->accumulator);
  98. #endif
  99. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  100. ctx->initial_entropy_run = 0;
  101. #endif
  102. ctx->source_count = 0;
  103. mbedtls_platform_zeroize(ctx->source, sizeof(ctx->source));
  104. ctx->accumulator_started = -1;
  105. }
  106. int mbedtls_entropy_add_source(mbedtls_entropy_context *ctx,
  107. mbedtls_entropy_f_source_ptr f_source, void *p_source,
  108. size_t threshold, int strong)
  109. {
  110. int idx, ret = 0;
  111. #if defined(MBEDTLS_THREADING_C)
  112. if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
  113. return ret;
  114. }
  115. #endif
  116. idx = ctx->source_count;
  117. if (idx >= MBEDTLS_ENTROPY_MAX_SOURCES) {
  118. ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES;
  119. goto exit;
  120. }
  121. ctx->source[idx].f_source = f_source;
  122. ctx->source[idx].p_source = p_source;
  123. ctx->source[idx].threshold = threshold;
  124. ctx->source[idx].strong = strong;
  125. ctx->source_count++;
  126. exit:
  127. #if defined(MBEDTLS_THREADING_C)
  128. if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
  129. return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
  130. }
  131. #endif
  132. return ret;
  133. }
  134. /*
  135. * Entropy accumulator update
  136. */
  137. static int entropy_update(mbedtls_entropy_context *ctx, unsigned char source_id,
  138. const unsigned char *data, size_t len)
  139. {
  140. unsigned char header[2];
  141. unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
  142. size_t use_len = len;
  143. const unsigned char *p = data;
  144. int ret = 0;
  145. if (use_len > MBEDTLS_ENTROPY_BLOCK_SIZE) {
  146. #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
  147. if ((ret = mbedtls_sha512_ret(data, len, tmp, 0)) != 0) {
  148. goto cleanup;
  149. }
  150. #else
  151. if ((ret = mbedtls_sha256_ret(data, len, tmp, 0)) != 0) {
  152. goto cleanup;
  153. }
  154. #endif
  155. p = tmp;
  156. use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
  157. }
  158. header[0] = source_id;
  159. header[1] = use_len & 0xFF;
  160. /*
  161. * Start the accumulator if this has not already happened. Note that
  162. * it is sufficient to start the accumulator here only because all calls to
  163. * gather entropy eventually execute this code.
  164. */
  165. #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
  166. if (ctx->accumulator_started == 0 &&
  167. (ret = mbedtls_sha512_starts_ret(&ctx->accumulator, 0)) != 0) {
  168. goto cleanup;
  169. } else {
  170. ctx->accumulator_started = 1;
  171. }
  172. if ((ret = mbedtls_sha512_update_ret(&ctx->accumulator, header, 2)) != 0) {
  173. goto cleanup;
  174. }
  175. ret = mbedtls_sha512_update_ret(&ctx->accumulator, p, use_len);
  176. #else
  177. if (ctx->accumulator_started == 0 &&
  178. (ret = mbedtls_sha256_starts_ret(&ctx->accumulator, 0)) != 0) {
  179. goto cleanup;
  180. } else {
  181. ctx->accumulator_started = 1;
  182. }
  183. if ((ret = mbedtls_sha256_update_ret(&ctx->accumulator, header, 2)) != 0) {
  184. goto cleanup;
  185. }
  186. ret = mbedtls_sha256_update_ret(&ctx->accumulator, p, use_len);
  187. #endif
  188. cleanup:
  189. mbedtls_platform_zeroize(tmp, sizeof(tmp));
  190. return ret;
  191. }
  192. int mbedtls_entropy_update_manual(mbedtls_entropy_context *ctx,
  193. const unsigned char *data, size_t len)
  194. {
  195. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  196. #if defined(MBEDTLS_THREADING_C)
  197. if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
  198. return ret;
  199. }
  200. #endif
  201. ret = entropy_update(ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len);
  202. #if defined(MBEDTLS_THREADING_C)
  203. if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
  204. return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
  205. }
  206. #endif
  207. return ret;
  208. }
  209. /*
  210. * Run through the different sources to add entropy to our accumulator
  211. */
  212. static int entropy_gather_internal(mbedtls_entropy_context *ctx)
  213. {
  214. int ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
  215. int i;
  216. int have_one_strong = 0;
  217. unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
  218. size_t olen;
  219. if (ctx->source_count == 0) {
  220. return MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED;
  221. }
  222. /*
  223. * Run through our entropy sources
  224. */
  225. for (i = 0; i < ctx->source_count; i++) {
  226. if (ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG) {
  227. have_one_strong = 1;
  228. }
  229. olen = 0;
  230. if ((ret = ctx->source[i].f_source(ctx->source[i].p_source,
  231. buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen)) != 0) {
  232. goto cleanup;
  233. }
  234. /*
  235. * Add if we actually gathered something
  236. */
  237. if (olen > 0) {
  238. if ((ret = entropy_update(ctx, (unsigned char) i,
  239. buf, olen)) != 0) {
  240. return ret;
  241. }
  242. ctx->source[i].size += olen;
  243. }
  244. }
  245. if (have_one_strong == 0) {
  246. ret = MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE;
  247. }
  248. cleanup:
  249. mbedtls_platform_zeroize(buf, sizeof(buf));
  250. return ret;
  251. }
  252. /*
  253. * Thread-safe wrapper for entropy_gather_internal()
  254. */
  255. int mbedtls_entropy_gather(mbedtls_entropy_context *ctx)
  256. {
  257. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  258. #if defined(MBEDTLS_THREADING_C)
  259. if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
  260. return ret;
  261. }
  262. #endif
  263. ret = entropy_gather_internal(ctx);
  264. #if defined(MBEDTLS_THREADING_C)
  265. if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
  266. return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
  267. }
  268. #endif
  269. return ret;
  270. }
  271. int mbedtls_entropy_func(void *data, unsigned char *output, size_t len)
  272. {
  273. int ret, count = 0, i, thresholds_reached;
  274. size_t strong_size;
  275. mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
  276. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
  277. if (len > MBEDTLS_ENTROPY_BLOCK_SIZE) {
  278. return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
  279. }
  280. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  281. /* Update the NV entropy seed before generating any entropy for outside
  282. * use.
  283. */
  284. if (ctx->initial_entropy_run == 0) {
  285. ctx->initial_entropy_run = 1;
  286. if ((ret = mbedtls_entropy_update_nv_seed(ctx)) != 0) {
  287. return ret;
  288. }
  289. }
  290. #endif
  291. #if defined(MBEDTLS_THREADING_C)
  292. if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
  293. return ret;
  294. }
  295. #endif
  296. /*
  297. * Always gather extra entropy before a call
  298. */
  299. do {
  300. if (count++ > ENTROPY_MAX_LOOP) {
  301. ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
  302. goto exit;
  303. }
  304. if ((ret = entropy_gather_internal(ctx)) != 0) {
  305. goto exit;
  306. }
  307. thresholds_reached = 1;
  308. strong_size = 0;
  309. for (i = 0; i < ctx->source_count; i++) {
  310. if (ctx->source[i].size < ctx->source[i].threshold) {
  311. thresholds_reached = 0;
  312. }
  313. if (ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG) {
  314. strong_size += ctx->source[i].size;
  315. }
  316. }
  317. } while (!thresholds_reached || strong_size < MBEDTLS_ENTROPY_BLOCK_SIZE);
  318. memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
  319. #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
  320. /*
  321. * Note that at this stage it is assumed that the accumulator was started
  322. * in a previous call to entropy_update(). If this is not guaranteed, the
  323. * code below will fail.
  324. */
  325. if ((ret = mbedtls_sha512_finish_ret(&ctx->accumulator, buf)) != 0) {
  326. goto exit;
  327. }
  328. /*
  329. * Reset accumulator and counters and recycle existing entropy
  330. */
  331. mbedtls_sha512_free(&ctx->accumulator);
  332. mbedtls_sha512_init(&ctx->accumulator);
  333. if ((ret = mbedtls_sha512_starts_ret(&ctx->accumulator, 0)) != 0) {
  334. goto exit;
  335. }
  336. if ((ret = mbedtls_sha512_update_ret(&ctx->accumulator, buf,
  337. MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0) {
  338. goto exit;
  339. }
  340. /*
  341. * Perform second SHA-512 on entropy
  342. */
  343. if ((ret = mbedtls_sha512_ret(buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
  344. buf, 0)) != 0) {
  345. goto exit;
  346. }
  347. #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
  348. if ((ret = mbedtls_sha256_finish_ret(&ctx->accumulator, buf)) != 0) {
  349. goto exit;
  350. }
  351. /*
  352. * Reset accumulator and counters and recycle existing entropy
  353. */
  354. mbedtls_sha256_free(&ctx->accumulator);
  355. mbedtls_sha256_init(&ctx->accumulator);
  356. if ((ret = mbedtls_sha256_starts_ret(&ctx->accumulator, 0)) != 0) {
  357. goto exit;
  358. }
  359. if ((ret = mbedtls_sha256_update_ret(&ctx->accumulator, buf,
  360. MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0) {
  361. goto exit;
  362. }
  363. /*
  364. * Perform second SHA-256 on entropy
  365. */
  366. if ((ret = mbedtls_sha256_ret(buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
  367. buf, 0)) != 0) {
  368. goto exit;
  369. }
  370. #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
  371. for (i = 0; i < ctx->source_count; i++) {
  372. ctx->source[i].size = 0;
  373. }
  374. memcpy(output, buf, len);
  375. ret = 0;
  376. exit:
  377. mbedtls_platform_zeroize(buf, sizeof(buf));
  378. #if defined(MBEDTLS_THREADING_C)
  379. if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
  380. return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
  381. }
  382. #endif
  383. return ret;
  384. }
  385. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  386. int mbedtls_entropy_update_nv_seed(mbedtls_entropy_context *ctx)
  387. {
  388. int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
  389. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
  390. /* Read new seed and write it to NV */
  391. if ((ret = mbedtls_entropy_func(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0) {
  392. return ret;
  393. }
  394. if (mbedtls_nv_seed_write(buf, MBEDTLS_ENTROPY_BLOCK_SIZE) < 0) {
  395. return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
  396. }
  397. /* Manually update the remaining stream with a separator value to diverge */
  398. memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE);
  399. ret = mbedtls_entropy_update_manual(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE);
  400. return ret;
  401. }
  402. #endif /* MBEDTLS_ENTROPY_NV_SEED */
  403. #if defined(MBEDTLS_FS_IO)
  404. int mbedtls_entropy_write_seed_file(mbedtls_entropy_context *ctx, const char *path)
  405. {
  406. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  407. FILE *f = NULL;
  408. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
  409. if ((ret = mbedtls_entropy_func(ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE)) != 0) {
  410. ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
  411. goto exit;
  412. }
  413. if ((f = fopen(path, "wb")) == NULL) {
  414. ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
  415. goto exit;
  416. }
  417. if (fwrite(buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f) != MBEDTLS_ENTROPY_BLOCK_SIZE) {
  418. ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
  419. goto exit;
  420. }
  421. ret = 0;
  422. exit:
  423. mbedtls_platform_zeroize(buf, sizeof(buf));
  424. if (f != NULL) {
  425. fclose(f);
  426. }
  427. return ret;
  428. }
  429. int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *path)
  430. {
  431. int ret = 0;
  432. FILE *f;
  433. size_t n;
  434. unsigned char buf[MBEDTLS_ENTROPY_MAX_SEED_SIZE];
  435. if ((f = fopen(path, "rb")) == NULL) {
  436. return MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
  437. }
  438. fseek(f, 0, SEEK_END);
  439. n = (size_t) ftell(f);
  440. fseek(f, 0, SEEK_SET);
  441. if (n > MBEDTLS_ENTROPY_MAX_SEED_SIZE) {
  442. n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
  443. }
  444. if (fread(buf, 1, n, f) != n) {
  445. ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
  446. } else {
  447. ret = mbedtls_entropy_update_manual(ctx, buf, n);
  448. }
  449. fclose(f);
  450. mbedtls_platform_zeroize(buf, sizeof(buf));
  451. if (ret != 0) {
  452. return ret;
  453. }
  454. return mbedtls_entropy_write_seed_file(ctx, path);
  455. }
  456. #endif /* MBEDTLS_FS_IO */
  457. #if defined(MBEDTLS_SELF_TEST)
  458. #if !defined(MBEDTLS_TEST_NULL_ENTROPY)
  459. /*
  460. * Dummy source function
  461. */
  462. static int entropy_dummy_source(void *data, unsigned char *output,
  463. size_t len, size_t *olen)
  464. {
  465. ((void) data);
  466. memset(output, 0x2a, len);
  467. *olen = len;
  468. return 0;
  469. }
  470. #endif /* !MBEDTLS_TEST_NULL_ENTROPY */
  471. #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
  472. static int mbedtls_entropy_source_self_test_gather(unsigned char *buf, size_t buf_len)
  473. {
  474. int ret = 0;
  475. size_t entropy_len = 0;
  476. size_t olen = 0;
  477. size_t attempts = buf_len;
  478. while (attempts > 0 && entropy_len < buf_len) {
  479. if ((ret = mbedtls_hardware_poll(NULL, buf + entropy_len,
  480. buf_len - entropy_len, &olen)) != 0) {
  481. return ret;
  482. }
  483. entropy_len += olen;
  484. attempts--;
  485. }
  486. if (entropy_len < buf_len) {
  487. ret = 1;
  488. }
  489. return ret;
  490. }
  491. static int mbedtls_entropy_source_self_test_check_bits(const unsigned char *buf,
  492. size_t buf_len)
  493. {
  494. unsigned char set = 0xFF;
  495. unsigned char unset = 0x00;
  496. size_t i;
  497. for (i = 0; i < buf_len; i++) {
  498. set &= buf[i];
  499. unset |= buf[i];
  500. }
  501. return set == 0xFF || unset == 0x00;
  502. }
  503. /*
  504. * A test to ensure that the entropy sources are functioning correctly
  505. * and there is no obvious failure. The test performs the following checks:
  506. * - The entropy source is not providing only 0s (all bits unset) or 1s (all
  507. * bits set).
  508. * - The entropy source is not providing values in a pattern. Because the
  509. * hardware could be providing data in an arbitrary length, this check polls
  510. * the hardware entropy source twice and compares the result to ensure they
  511. * are not equal.
  512. * - The error code returned by the entropy source is not an error.
  513. */
  514. int mbedtls_entropy_source_self_test(int verbose)
  515. {
  516. int ret = 0;
  517. unsigned char buf0[2 * sizeof(unsigned long long int)];
  518. unsigned char buf1[2 * sizeof(unsigned long long int)];
  519. if (verbose != 0) {
  520. mbedtls_printf(" ENTROPY_BIAS test: ");
  521. }
  522. memset(buf0, 0x00, sizeof(buf0));
  523. memset(buf1, 0x00, sizeof(buf1));
  524. if ((ret = mbedtls_entropy_source_self_test_gather(buf0, sizeof(buf0))) != 0) {
  525. goto cleanup;
  526. }
  527. if ((ret = mbedtls_entropy_source_self_test_gather(buf1, sizeof(buf1))) != 0) {
  528. goto cleanup;
  529. }
  530. /* Make sure that the returned values are not all 0 or 1 */
  531. if ((ret = mbedtls_entropy_source_self_test_check_bits(buf0, sizeof(buf0))) != 0) {
  532. goto cleanup;
  533. }
  534. if ((ret = mbedtls_entropy_source_self_test_check_bits(buf1, sizeof(buf1))) != 0) {
  535. goto cleanup;
  536. }
  537. /* Make sure that the entropy source is not returning values in a
  538. * pattern */
  539. ret = memcmp(buf0, buf1, sizeof(buf0)) == 0;
  540. cleanup:
  541. if (verbose != 0) {
  542. if (ret != 0) {
  543. mbedtls_printf("failed\n");
  544. } else {
  545. mbedtls_printf("passed\n");
  546. }
  547. mbedtls_printf("\n");
  548. }
  549. return ret != 0;
  550. }
  551. #endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
  552. /*
  553. * The actual entropy quality is hard to test, but we can at least
  554. * test that the functions don't cause errors and write the correct
  555. * amount of data to buffers.
  556. */
  557. int mbedtls_entropy_self_test(int verbose)
  558. {
  559. int ret = 1;
  560. #if !defined(MBEDTLS_TEST_NULL_ENTROPY)
  561. mbedtls_entropy_context ctx;
  562. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
  563. unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
  564. size_t i, j;
  565. #endif /* !MBEDTLS_TEST_NULL_ENTROPY */
  566. if (verbose != 0) {
  567. mbedtls_printf(" ENTROPY test: ");
  568. }
  569. #if !defined(MBEDTLS_TEST_NULL_ENTROPY)
  570. mbedtls_entropy_init(&ctx);
  571. /* First do a gather to make sure we have default sources */
  572. if ((ret = mbedtls_entropy_gather(&ctx)) != 0) {
  573. goto cleanup;
  574. }
  575. ret = mbedtls_entropy_add_source(&ctx, entropy_dummy_source, NULL, 16,
  576. MBEDTLS_ENTROPY_SOURCE_WEAK);
  577. if (ret != 0) {
  578. goto cleanup;
  579. }
  580. if ((ret = mbedtls_entropy_update_manual(&ctx, buf, sizeof(buf))) != 0) {
  581. goto cleanup;
  582. }
  583. /*
  584. * To test that mbedtls_entropy_func writes correct number of bytes:
  585. * - use the whole buffer and rely on ASan to detect overruns
  586. * - collect entropy 8 times and OR the result in an accumulator:
  587. * any byte should then be 0 with probably 2^(-64), so requiring
  588. * each of the 32 or 64 bytes to be non-zero has a false failure rate
  589. * of at most 2^(-58) which is acceptable.
  590. */
  591. for (i = 0; i < 8; i++) {
  592. if ((ret = mbedtls_entropy_func(&ctx, buf, sizeof(buf))) != 0) {
  593. goto cleanup;
  594. }
  595. for (j = 0; j < sizeof(buf); j++) {
  596. acc[j] |= buf[j];
  597. }
  598. }
  599. for (j = 0; j < sizeof(buf); j++) {
  600. if (acc[j] == 0) {
  601. ret = 1;
  602. goto cleanup;
  603. }
  604. }
  605. #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
  606. if ((ret = mbedtls_entropy_source_self_test(0)) != 0) {
  607. goto cleanup;
  608. }
  609. #endif
  610. cleanup:
  611. mbedtls_entropy_free(&ctx);
  612. #endif /* !MBEDTLS_TEST_NULL_ENTROPY */
  613. if (verbose != 0) {
  614. if (ret != 0) {
  615. mbedtls_printf("failed\n");
  616. } else {
  617. mbedtls_printf("passed\n");
  618. }
  619. mbedtls_printf("\n");
  620. }
  621. return ret != 0;
  622. }
  623. #endif /* MBEDTLS_SELF_TEST */
  624. #endif /* MBEDTLS_ENTROPY_C */