test_suite_entropy.function 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. /* BEGIN_HEADER */
  2. #include "mbedtls/entropy.h"
  3. #include "mbedtls/entropy_poll.h"
  4. #include "mbedtls/md.h"
  5. #include "string.h"
  6. /*
  7. * Number of calls made to entropy_dummy_source()
  8. */
  9. static size_t entropy_dummy_calls;
  10. /*
  11. * Dummy entropy source
  12. *
  13. * If data is NULL, write exactly the requested length.
  14. * Otherwise, write the length indicated by data or error if negative
  15. */
  16. static int entropy_dummy_source( void *data, unsigned char *output,
  17. size_t len, size_t *olen )
  18. {
  19. entropy_dummy_calls++;
  20. if( data == NULL )
  21. *olen = len;
  22. else
  23. {
  24. int *d = (int *) data;
  25. if( *d < 0 )
  26. return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  27. else
  28. *olen = *d;
  29. }
  30. memset( output, 0x2a, *olen );
  31. return( 0 );
  32. }
  33. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  34. /*
  35. * Ability to clear entropy sources to allow testing with just predefined
  36. * entropy sources. This function or tests depending on it might break if there
  37. * are internal changes to how entropy sources are registered.
  38. *
  39. * To be called immediately after mbedtls_entropy_init().
  40. *
  41. * Just resetting the counter. New sources will overwrite existing ones.
  42. * This might break memory checks in the future if sources need 'free-ing' then
  43. * as well.
  44. */
  45. void entropy_clear_sources( mbedtls_entropy_context *ctx )
  46. {
  47. ctx->source_count = 0;
  48. }
  49. /*
  50. * NV seed read/write functions that use a buffer instead of a file
  51. */
  52. static unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
  53. int buffer_nv_seed_read( unsigned char *buf, size_t buf_len )
  54. {
  55. if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
  56. return( -1 );
  57. memcpy( buf, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE );
  58. return( 0 );
  59. }
  60. int buffer_nv_seed_write( unsigned char *buf, size_t buf_len )
  61. {
  62. if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
  63. return( -1 );
  64. memcpy( buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE );
  65. return( 0 );
  66. }
  67. /*
  68. * NV seed read/write helpers that fill the base seedfile
  69. */
  70. int write_nv_seed( unsigned char *buf, size_t buf_len )
  71. {
  72. FILE *f;
  73. if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
  74. return( -1 );
  75. if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL )
  76. return( -1 );
  77. if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
  78. MBEDTLS_ENTROPY_BLOCK_SIZE )
  79. return( -1 );
  80. fclose( f );
  81. return( 0 );
  82. }
  83. int read_nv_seed( unsigned char *buf, size_t buf_len )
  84. {
  85. FILE *f;
  86. if( buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE )
  87. return( -1 );
  88. if( ( f = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL )
  89. return( -1 );
  90. if( fread( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) !=
  91. MBEDTLS_ENTROPY_BLOCK_SIZE )
  92. return( -1 );
  93. fclose( f );
  94. return( 0 );
  95. }
  96. #endif /* MBEDTLS_ENTROPY_NV_SEED */
  97. /* END_HEADER */
  98. /* BEGIN_DEPENDENCIES
  99. * depends_on:MBEDTLS_ENTROPY_C
  100. * END_DEPENDENCIES
  101. */
  102. /* BEGIN_CASE */
  103. void entropy_init_free( int reinit )
  104. {
  105. mbedtls_entropy_context ctx;
  106. /* Double free is not explicitly documented to work, but it is convenient
  107. * to call mbedtls_entropy_free() unconditionally on an error path without
  108. * checking whether it has already been called in the success path. */
  109. mbedtls_entropy_init( &ctx );
  110. mbedtls_entropy_free( &ctx );
  111. if( reinit )
  112. mbedtls_entropy_init( &ctx );
  113. mbedtls_entropy_free( &ctx );
  114. /* This test case always succeeds, functionally speaking. A plausible
  115. * bug might trigger an invalid pointer dereference or a memory leak. */
  116. goto exit;
  117. }
  118. /* END_CASE */
  119. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  120. void entropy_seed_file( char * path, int ret )
  121. {
  122. mbedtls_entropy_context ctx;
  123. mbedtls_entropy_init( &ctx );
  124. TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path ) == ret );
  125. TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path ) == ret );
  126. exit:
  127. mbedtls_entropy_free( &ctx );
  128. }
  129. /* END_CASE */
  130. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  131. void entropy_write_base_seed_file( int ret )
  132. {
  133. mbedtls_entropy_context ctx;
  134. mbedtls_entropy_init( &ctx );
  135. TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE ) == ret );
  136. TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE ) == ret );
  137. exit:
  138. mbedtls_entropy_free( &ctx );
  139. }
  140. /* END_CASE */
  141. /* BEGIN_CASE */
  142. void entropy_too_many_sources( )
  143. {
  144. mbedtls_entropy_context ctx;
  145. size_t i;
  146. mbedtls_entropy_init( &ctx );
  147. /*
  148. * It's hard to tell precisely when the error will occur,
  149. * since we don't know how many sources were automatically added.
  150. */
  151. for( i = 0; i < MBEDTLS_ENTROPY_MAX_SOURCES; i++ )
  152. (void) mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL,
  153. 16, MBEDTLS_ENTROPY_SOURCE_WEAK );
  154. TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL,
  155. 16, MBEDTLS_ENTROPY_SOURCE_WEAK )
  156. == MBEDTLS_ERR_ENTROPY_MAX_SOURCES );
  157. exit:
  158. mbedtls_entropy_free( &ctx );
  159. }
  160. /* END_CASE */
  161. /* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
  162. void entropy_func_len( int len, int ret )
  163. {
  164. mbedtls_entropy_context ctx;
  165. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
  166. unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 };
  167. size_t i, j;
  168. mbedtls_entropy_init( &ctx );
  169. /*
  170. * See comments in mbedtls_entropy_self_test()
  171. */
  172. for( i = 0; i < 8; i++ )
  173. {
  174. TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, len ) == ret );
  175. for( j = 0; j < sizeof( buf ); j++ )
  176. acc[j] |= buf[j];
  177. }
  178. if( ret == 0 )
  179. for( j = 0; j < (size_t) len; j++ )
  180. TEST_ASSERT( acc[j] != 0 );
  181. for( j = len; j < sizeof( buf ); j++ )
  182. TEST_ASSERT( acc[j] == 0 );
  183. exit:
  184. mbedtls_entropy_free( &ctx );
  185. }
  186. /* END_CASE */
  187. /* BEGIN_CASE */
  188. void entropy_source_fail( char * path )
  189. {
  190. mbedtls_entropy_context ctx;
  191. int fail = -1;
  192. unsigned char buf[16];
  193. mbedtls_entropy_init( &ctx );
  194. TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
  195. &fail, 16,
  196. MBEDTLS_ENTROPY_SOURCE_WEAK )
  197. == 0 );
  198. TEST_ASSERT( mbedtls_entropy_func( &ctx, buf, sizeof( buf ) )
  199. == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  200. TEST_ASSERT( mbedtls_entropy_gather( &ctx )
  201. == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  202. #if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_ENTROPY_NV_SEED)
  203. TEST_ASSERT( mbedtls_entropy_write_seed_file( &ctx, path )
  204. == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  205. TEST_ASSERT( mbedtls_entropy_update_seed_file( &ctx, path )
  206. == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  207. #else
  208. ((void) path);
  209. #endif
  210. exit:
  211. mbedtls_entropy_free( &ctx );
  212. }
  213. /* END_CASE */
  214. /* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */
  215. void entropy_threshold( int threshold, int chunk_size, int result )
  216. {
  217. mbedtls_entropy_context ctx;
  218. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 };
  219. int ret;
  220. mbedtls_entropy_init( &ctx );
  221. TEST_ASSERT( mbedtls_entropy_add_source( &ctx, entropy_dummy_source,
  222. &chunk_size, threshold,
  223. MBEDTLS_ENTROPY_SOURCE_WEAK ) == 0 );
  224. entropy_dummy_calls = 0;
  225. ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) );
  226. if( result >= 0 )
  227. {
  228. TEST_ASSERT( ret == 0 );
  229. #if defined(MBEDTLS_ENTROPY_NV_SEED)
  230. // Two times as much calls due to the NV seed update
  231. result *= 2;
  232. #endif
  233. TEST_ASSERT( entropy_dummy_calls == (size_t) result );
  234. }
  235. else
  236. {
  237. TEST_ASSERT( ret == result );
  238. }
  239. exit:
  240. mbedtls_entropy_free( &ctx );
  241. }
  242. /* END_CASE */
  243. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */
  244. void nv_seed_file_create( )
  245. {
  246. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
  247. memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
  248. TEST_ASSERT( write_nv_seed( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  249. }
  250. /* END_CASE */
  251. /* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO:MBEDTLS_PLATFORM_NV_SEED_ALT */
  252. void entropy_nv_seed_std_io( )
  253. {
  254. unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
  255. unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
  256. memset( io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE );
  257. memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
  258. mbedtls_platform_set_nv_seed( mbedtls_platform_std_nv_seed_read,
  259. mbedtls_platform_std_nv_seed_write );
  260. /* Check if platform NV read and write manipulate the same data */
  261. TEST_ASSERT( write_nv_seed( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  262. TEST_ASSERT( mbedtls_nv_seed_read( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
  263. MBEDTLS_ENTROPY_BLOCK_SIZE );
  264. TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  265. memset( check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
  266. /* Check if platform NV write and raw read manipulate the same data */
  267. TEST_ASSERT( mbedtls_nv_seed_write( io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) ==
  268. MBEDTLS_ENTROPY_BLOCK_SIZE );
  269. TEST_ASSERT( read_nv_seed( check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  270. TEST_ASSERT( memcmp( io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  271. }
  272. /* END_CASE */
  273. /* BEGIN_CASE depends_on:MBEDTLS_MD_C:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT */
  274. void entropy_nv_seed( data_t * read_seed )
  275. {
  276. #if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR)
  277. const mbedtls_md_info_t *md_info =
  278. mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 );
  279. #elif defined(MBEDTLS_ENTROPY_SHA256_ACCUMULATOR)
  280. const mbedtls_md_info_t *md_info =
  281. mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
  282. #else
  283. #error "Unsupported entropy accumulator"
  284. #endif
  285. mbedtls_md_context_t accumulator;
  286. mbedtls_entropy_context ctx;
  287. int (*original_mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) =
  288. mbedtls_nv_seed_read;
  289. int (*original_mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) =
  290. mbedtls_nv_seed_write;
  291. unsigned char header[2];
  292. unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
  293. unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
  294. unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE];
  295. unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE];
  296. unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE];
  297. memset( entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
  298. memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
  299. memset( empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
  300. memset( check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE );
  301. memset( check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE );
  302. // Make sure we read/write NV seed from our buffers
  303. mbedtls_platform_set_nv_seed( buffer_nv_seed_read, buffer_nv_seed_write );
  304. mbedtls_md_init( &accumulator );
  305. mbedtls_entropy_init( &ctx );
  306. entropy_clear_sources( &ctx );
  307. TEST_ASSERT( mbedtls_entropy_add_source( &ctx, mbedtls_nv_seed_poll, NULL,
  308. MBEDTLS_ENTROPY_BLOCK_SIZE,
  309. MBEDTLS_ENTROPY_SOURCE_STRONG ) == 0 );
  310. // Set the initial NV seed to read
  311. TEST_ASSERT( read_seed->len >= MBEDTLS_ENTROPY_BLOCK_SIZE );
  312. memcpy( buffer_seed, read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE );
  313. // Do an entropy run
  314. TEST_ASSERT( mbedtls_entropy_func( &ctx, entropy, sizeof( entropy ) ) == 0 );
  315. // Determine what should have happened with manual entropy internal logic
  316. // Init accumulator
  317. header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE;
  318. TEST_ASSERT( mbedtls_md_setup( &accumulator, md_info, 0 ) == 0 );
  319. // First run for updating write_seed
  320. header[0] = 0;
  321. TEST_ASSERT( mbedtls_md_starts( &accumulator ) == 0 );
  322. TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
  323. TEST_ASSERT( mbedtls_md_update( &accumulator,
  324. read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  325. TEST_ASSERT( mbedtls_md_finish( &accumulator, buf ) == 0 );
  326. TEST_ASSERT( mbedtls_md_starts( &accumulator ) == 0 );
  327. TEST_ASSERT( mbedtls_md_update( &accumulator,
  328. buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  329. TEST_ASSERT( mbedtls_md( md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
  330. check_seed ) == 0 );
  331. // Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed)
  332. header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL;
  333. TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
  334. TEST_ASSERT( mbedtls_md_update( &accumulator,
  335. empty, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  336. header[0] = 0;
  337. TEST_ASSERT( mbedtls_md_update( &accumulator, header, 2 ) == 0 );
  338. TEST_ASSERT( mbedtls_md_update( &accumulator,
  339. check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  340. TEST_ASSERT( mbedtls_md_finish( &accumulator, buf ) == 0 );
  341. TEST_ASSERT( mbedtls_md( md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE,
  342. check_entropy ) == 0 );
  343. // Check result of both NV file and entropy received with the manual calculations
  344. TEST_ASSERT( memcmp( check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  345. TEST_ASSERT( memcmp( check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE ) == 0 );
  346. exit:
  347. mbedtls_md_free( &accumulator );
  348. mbedtls_entropy_free( &ctx );
  349. mbedtls_nv_seed_read = original_mbedtls_nv_seed_read;
  350. mbedtls_nv_seed_write = original_mbedtls_nv_seed_write;
  351. }
  352. /* END_CASE */
  353. /* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG:MBEDTLS_SELF_TEST */
  354. void entropy_selftest( int result )
  355. {
  356. TEST_ASSERT( mbedtls_entropy_self_test( 1 ) == result );
  357. }
  358. /* END_CASE */