entropy.c 19 KB

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