entropy.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. /*
  2. * Entropy accumulator implementation
  3. *
  4. * Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
  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. * This file is part of mbed TLS (https://tls.mbed.org)
  20. */
  21. #if !defined(MBEDTLS_CONFIG_FILE)
  22. #include "mbedtls/config.h"
  23. #else
  24. #include MBEDTLS_CONFIG_FILE
  25. #endif
  26. #if defined(MBEDTLS_ENTROPY_C)
  27. #if defined(MBEDTLS_TEST_NULL_ENTROPY)
  28. #warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! "
  29. #warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES "
  30. #warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE "
  31. #endif
  32. #include "mbedtls/entropy.h"
  33. #include "mbedtls/entropy_poll.h"
  34. #include <string.h>
  35. #if defined(MBEDTLS_FS_IO)
  36. #include <stdio.h>
  37. #endif
  38. #if defined(MBEDTLS_SELF_TEST)
  39. #if defined(MBEDTLS_PLATFORM_C)
  40. #include "mbedtls/platform.h"
  41. #else
  42. #include <stdio.h>
  43. #define mbedtls_printf printf
  44. #endif /* MBEDTLS_PLATFORM_C */
  45. #endif /* MBEDTLS_SELF_TEST */
  46. #if defined(MBEDTLS_HAVEGE_C)
  47. #include "mbedtls/havege.h"
  48. #endif
  49. /* Implementation that should never be optimized out by the compiler */
  50. static void mbedtls_zeroize( void *v, size_t n ) {
  51. volatile unsigned char *p = v; while( n-- ) *p++ = 0;
  52. }
  53. #define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */
  54. void mbedtls_entropy_init( mbedtls_entropy_context *ctx )
  55. {
  56. memset( ctx, 0, sizeof(mbedtls_entropy_context) );
  57. #if defined(MBEDTLS_THREADING_C)
  58. mbedtls_mutex_init( &ctx->mutex );
  59. #endif
  60. #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
  61. mbedtls_sha512_starts( &ctx->accumulator, 0 );
  62. #else
  63. mbedtls_sha256_starts( &ctx->accumulator, 0 );
  64. #endif
  65. #if defined(MBEDTLS_HAVEGE_C)
  66. mbedtls_havege_init( &ctx->havege_data );
  67. #endif
  68. #if defined(MBEDTLS_TEST_NULL_ENTROPY)
  69. mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL,
  70. 1, MBEDTLS_ENTROPY_SOURCE_STRONG );
  71. #endif
  72. #if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES)
  73. #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
  74. mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL,
  75. MBEDTLS_ENTROPY_MIN_PLATFORM,
  76. MBEDTLS_ENTROPY_SOURCE_STRONG );
  77. #endif
  78. #if defined(MBEDTLS_TIMING_C)
  79. mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL,
  80. MBEDTLS_ENTROPY_MIN_HARDCLOCK,
  81. MBEDTLS_ENTROPY_SOURCE_WEAK );
  82. #endif
  83. #if defined(MBEDTLS_HAVEGE_C)
  84. mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data,
  85. MBEDTLS_ENTROPY_MIN_HAVEGE,
  86. MBEDTLS_ENTROPY_SOURCE_STRONG );
  87. #endif
  88. #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
  89. mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL,
  90. MBEDTLS_ENTROPY_MIN_HARDWARE,
  91. MBEDTLS_ENTROPY_SOURCE_STRONG );
  92. #endif
  93. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  94. mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL,
  95. MBEDTLS_ENTROPY_BLOCK_SIZE,
  96. MBEDTLS_ENTROPY_SOURCE_STRONG );
  97. #endif
  98. #endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */
  99. }
  100. void mbedtls_entropy_free( mbedtls_entropy_context *ctx )
  101. {
  102. #if defined(MBEDTLS_HAVEGE_C)
  103. mbedtls_havege_free( &ctx->havege_data );
  104. #endif
  105. #if defined(MBEDTLS_THREADING_C)
  106. mbedtls_mutex_free( &ctx->mutex );
  107. #endif
  108. mbedtls_zeroize( ctx, sizeof( mbedtls_entropy_context ) );
  109. }
  110. int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx,
  111. mbedtls_entropy_f_source_ptr f_source, void *p_source,
  112. size_t threshold, int strong )
  113. {
  114. int index, ret = 0;
  115. #if defined(MBEDTLS_THREADING_C)
  116. if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
  117. return( ret );
  118. #endif
  119. index = ctx->source_count;
  120. if( index >= MBEDTLS_ENTROPY_MAX_SOURCES )
  121. {
  122. ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES;
  123. goto exit;
  124. }
  125. ctx->source[index].f_source = f_source;
  126. ctx->source[index].p_source = p_source;
  127. ctx->source[index].threshold = threshold;
  128. ctx->source[index].strong = strong;
  129. ctx->source_count++;
  130. exit:
  131. #if defined(MBEDTLS_THREADING_C)
  132. if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
  133. return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
  134. #endif
  135. return( ret );
  136. }
  137. /*
  138. * Entropy accumulator update
  139. */
  140. static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id,
  141. const unsigned char *data, size_t len )
  142. {
  143. unsigned char header[2];
  144. unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE];
  145. size_t use_len = len;
  146. const unsigned char *p = data;
  147. if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE )
  148. {
  149. #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
  150. mbedtls_sha512( data, len, tmp, 0 );
  151. #else
  152. mbedtls_sha256( data, len, tmp, 0 );
  153. #endif
  154. p = tmp;
  155. use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
  156. }
  157. header[0] = source_id;
  158. header[1] = use_len & 0xFF;
  159. #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
  160. mbedtls_sha512_update( &ctx->accumulator, header, 2 );
  161. mbedtls_sha512_update( &ctx->accumulator, p, use_len );
  162. #else
  163. mbedtls_sha256_update( &ctx->accumulator, header, 2 );
  164. mbedtls_sha256_update( &ctx->accumulator, p, use_len );
  165. #endif
  166. return( 0 );
  167. }
  168. int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx,
  169. const unsigned char *data, size_t len )
  170. {
  171. int ret;
  172. #if defined(MBEDTLS_THREADING_C)
  173. if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
  174. return( ret );
  175. #endif
  176. ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len );
  177. #if defined(MBEDTLS_THREADING_C)
  178. if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
  179. return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
  180. #endif
  181. return( ret );
  182. }
  183. /*
  184. * Run through the different sources to add entropy to our accumulator
  185. */
  186. static int entropy_gather_internal( mbedtls_entropy_context *ctx )
  187. {
  188. int ret, i, have_one_strong = 0;
  189. unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER];
  190. size_t olen;
  191. if( ctx->source_count == 0 )
  192. return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED );
  193. /*
  194. * Run through our entropy sources
  195. */
  196. for( i = 0; i < ctx->source_count; i++ )
  197. {
  198. if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG )
  199. have_one_strong = 1;
  200. olen = 0;
  201. if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source,
  202. buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 )
  203. {
  204. return( ret );
  205. }
  206. /*
  207. * Add if we actually gathered something
  208. */
  209. if( olen > 0 )
  210. {
  211. entropy_update( ctx, (unsigned char) i, buf, olen );
  212. ctx->source[i].size += olen;
  213. }
  214. }
  215. if( have_one_strong == 0 )
  216. return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE );
  217. return( 0 );
  218. }
  219. /*
  220. * Thread-safe wrapper for entropy_gather_internal()
  221. */
  222. int mbedtls_entropy_gather( mbedtls_entropy_context *ctx )
  223. {
  224. int ret;
  225. #if defined(MBEDTLS_THREADING_C)
  226. if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
  227. return( ret );
  228. #endif
  229. ret = entropy_gather_internal( ctx );
  230. #if defined(MBEDTLS_THREADING_C)
  231. if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
  232. return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
  233. #endif
  234. return( ret );
  235. }
  236. int mbedtls_entropy_func( void *data, unsigned char *output, size_t len )
  237. {
  238. int ret, count = 0, i, done;
  239. mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data;
  240. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
  241. if( len > MBEDTLS_ENTROPY_BLOCK_SIZE )
  242. return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  243. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  244. /* Update the NV entropy seed before generating any entropy for outside
  245. * use.
  246. */
  247. if( ctx->initial_entropy_run == 0 )
  248. {
  249. ctx->initial_entropy_run = 1;
  250. if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 )
  251. return( ret );
  252. }
  253. #endif
  254. #if defined(MBEDTLS_THREADING_C)
  255. if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
  256. return( ret );
  257. #endif
  258. /*
  259. * Always gather extra entropy before a call
  260. */
  261. do
  262. {
  263. if( count++ > ENTROPY_MAX_LOOP )
  264. {
  265. ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
  266. goto exit;
  267. }
  268. if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
  269. goto exit;
  270. done = 1;
  271. for( i = 0; i < ctx->source_count; i++ )
  272. if( ctx->source[i].size < ctx->source[i].threshold )
  273. done = 0;
  274. }
  275. while( ! done );
  276. memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
  277. #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
  278. mbedtls_sha512_finish( &ctx->accumulator, buf );
  279. /*
  280. * Reset accumulator and counters and recycle existing entropy
  281. */
  282. memset( &ctx->accumulator, 0, sizeof( mbedtls_sha512_context ) );
  283. mbedtls_sha512_starts( &ctx->accumulator, 0 );
  284. mbedtls_sha512_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
  285. /*
  286. * Perform second SHA-512 on entropy
  287. */
  288. mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 );
  289. #else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
  290. mbedtls_sha256_finish( &ctx->accumulator, buf );
  291. /*
  292. * Reset accumulator and counters and recycle existing entropy
  293. */
  294. memset( &ctx->accumulator, 0, sizeof( mbedtls_sha256_context ) );
  295. mbedtls_sha256_starts( &ctx->accumulator, 0 );
  296. mbedtls_sha256_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
  297. /*
  298. * Perform second SHA-256 on entropy
  299. */
  300. mbedtls_sha256( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 );
  301. #endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */
  302. for( i = 0; i < ctx->source_count; i++ )
  303. ctx->source[i].size = 0;
  304. memcpy( output, buf, len );
  305. ret = 0;
  306. exit:
  307. #if defined(MBEDTLS_THREADING_C)
  308. if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
  309. return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
  310. #endif
  311. return( ret );
  312. }
  313. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  314. int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx )
  315. {
  316. int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
  317. unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
  318. /* Read new seed and write it to NV */
  319. if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
  320. return( ret );
  321. if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
  322. return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
  323. /* Manually update the remaining stream with a separator value to diverge */
  324. memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
  325. mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
  326. return( 0 );
  327. }
  328. #endif /* MBEDTLS_ENTROPY_NV_SEED */
  329. #if defined(MBEDTLS_FS_IO)
  330. int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path )
  331. {
  332. int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
  333. FILE *f;
  334. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
  335. if( ( f = fopen( path, "wb" ) ) == NULL )
  336. return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
  337. if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 )
  338. goto exit;
  339. if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE )
  340. {
  341. ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR;
  342. goto exit;
  343. }
  344. ret = 0;
  345. exit:
  346. fclose( f );
  347. return( ret );
  348. }
  349. int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path )
  350. {
  351. FILE *f;
  352. size_t n;
  353. unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ];
  354. if( ( f = fopen( path, "rb" ) ) == NULL )
  355. return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
  356. fseek( f, 0, SEEK_END );
  357. n = (size_t) ftell( f );
  358. fseek( f, 0, SEEK_SET );
  359. if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE )
  360. n = MBEDTLS_ENTROPY_MAX_SEED_SIZE;
  361. if( fread( buf, 1, n, f ) != n )
  362. {
  363. fclose( f );
  364. return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR );
  365. }
  366. fclose( f );
  367. mbedtls_entropy_update_manual( ctx, buf, n );
  368. return( mbedtls_entropy_write_seed_file( ctx, path ) );
  369. }
  370. #endif /* MBEDTLS_FS_IO */
  371. #if defined(MBEDTLS_SELF_TEST)
  372. /*
  373. * Dummy source function
  374. */
  375. static int entropy_dummy_source( void *data, unsigned char *output,
  376. size_t len, size_t *olen )
  377. {
  378. ((void) data);
  379. memset( output, 0x2a, len );
  380. *olen = len;
  381. return( 0 );
  382. }
  383. /*
  384. * The actual entropy quality is hard to test, but we can at least
  385. * test that the functions don't cause errors and write the correct
  386. * amount of data to buffers.
  387. */
  388. int mbedtls_entropy_self_test( int verbose )
  389. {
  390. int ret = 0;
  391. mbedtls_entropy_context ctx;
  392. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
  393. unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
  394. size_t i, j;
  395. if( verbose != 0 )
  396. mbedtls_printf( " ENTROPY test: " );
  397. mbedtls_entropy_init( &ctx );
  398. /* First do a gather to make sure we have default sources */
  399. if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 )
  400. goto cleanup;
  401. ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16,
  402. MBEDTLS_ENTROPY_SOURCE_WEAK );
  403. if( ret != 0 )
  404. goto cleanup;
  405. if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 )
  406. goto cleanup;
  407. /*
  408. * To test that mbedtls_entropy_func writes correct number of bytes:
  409. * - use the whole buffer and rely on ASan to detect overruns
  410. * - collect entropy 8 times and OR the result in an accumulator:
  411. * any byte should then be 0 with probably 2^(-64), so requiring
  412. * each of the 32 or 64 bytes to be non-zero has a false failure rate
  413. * of at most 2^(-58) which is acceptable.
  414. */
  415. for( i = 0; i < 8; i++ )
  416. {
  417. if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 )
  418. goto cleanup;
  419. for( j = 0; j < sizeof( buf ); j++ )
  420. acc[j] |= buf[j];
  421. }
  422. for( j = 0; j < sizeof( buf ); j++ )
  423. {
  424. if( acc[j] == 0 )
  425. {
  426. ret = 1;
  427. goto cleanup;
  428. }
  429. }
  430. cleanup:
  431. mbedtls_entropy_free( &ctx );
  432. if( verbose != 0 )
  433. {
  434. if( ret != 0 )
  435. mbedtls_printf( "failed\n" );
  436. else
  437. mbedtls_printf( "passed\n" );
  438. mbedtls_printf( "\n" );
  439. }
  440. return( ret != 0 );
  441. }
  442. #endif /* MBEDTLS_SELF_TEST */
  443. #endif /* MBEDTLS_ENTROPY_C */