test_suite_entropy.function 11 KB

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