test_suite_ctr_drbg.function 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /* BEGIN_HEADER */
  2. #include "mbedtls/entropy.h"
  3. #include "mbedtls/ctr_drbg.h"
  4. #include "string.h"
  5. /* Modes for ctr_drbg_validate */
  6. enum reseed_mode
  7. {
  8. RESEED_NEVER, /* never reseed */
  9. RESEED_FIRST, /* instantiate, reseed, generate, generate */
  10. RESEED_SECOND, /* instantiate, generate, reseed, generate */
  11. RESEED_ALWAYS /* prediction resistance, no explicit reseed */
  12. };
  13. static size_t test_offset_idx = 0;
  14. static size_t test_max_idx = 0;
  15. static int mbedtls_test_entropy_func( void *data, unsigned char *buf, size_t len )
  16. {
  17. const unsigned char *p = (unsigned char *) data;
  18. if( test_offset_idx + len > test_max_idx )
  19. return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
  20. memcpy( buf, p + test_offset_idx, len );
  21. test_offset_idx += len;
  22. return( 0 );
  23. }
  24. static void ctr_drbg_validate_internal( int reseed_mode, data_t * nonce,
  25. int entropy_len_arg, data_t * entropy,
  26. data_t * reseed,
  27. data_t * add1, data_t * add2,
  28. data_t * result )
  29. {
  30. mbedtls_ctr_drbg_context ctx;
  31. unsigned char buf[64];
  32. size_t entropy_chunk_len = (size_t) entropy_len_arg;
  33. TEST_ASSERT( entropy_chunk_len <= sizeof( buf ) );
  34. test_offset_idx = 0;
  35. mbedtls_ctr_drbg_init( &ctx );
  36. test_max_idx = entropy->len;
  37. /* CTR_DRBG_Instantiate(entropy[:entropy->len], nonce, perso, <ignored>)
  38. * where nonce||perso = nonce[nonce->len] */
  39. mbedtls_ctr_drbg_set_entropy_len( &ctx, entropy_chunk_len );
  40. mbedtls_ctr_drbg_set_nonce_len( &ctx, 0 );
  41. TEST_ASSERT( mbedtls_ctr_drbg_seed(
  42. &ctx,
  43. mbedtls_test_entropy_func, entropy->x,
  44. nonce->x, nonce->len ) == 0 );
  45. if( reseed_mode == RESEED_ALWAYS )
  46. mbedtls_ctr_drbg_set_prediction_resistance(
  47. &ctx,
  48. MBEDTLS_CTR_DRBG_PR_ON );
  49. if( reseed_mode == RESEED_FIRST )
  50. {
  51. /* CTR_DRBG_Reseed(entropy[idx:idx+entropy->len],
  52. * reseed[:reseed->len]) */
  53. TEST_ASSERT( mbedtls_ctr_drbg_reseed(
  54. &ctx,
  55. reseed->x, reseed->len ) == 0 );
  56. }
  57. /* CTR_DRBG_Generate(result->len * 8 bits, add1[:add1->len]) -> buf */
  58. /* Then reseed if prediction resistance is enabled. */
  59. TEST_ASSERT( mbedtls_ctr_drbg_random_with_add(
  60. &ctx,
  61. buf, result->len,
  62. add1->x, add1->len ) == 0 );
  63. if( reseed_mode == RESEED_SECOND )
  64. {
  65. /* CTR_DRBG_Reseed(entropy[idx:idx+entropy->len],
  66. * reseed[:reseed->len]) */
  67. TEST_ASSERT( mbedtls_ctr_drbg_reseed(
  68. &ctx,
  69. reseed->x, reseed->len ) == 0 );
  70. }
  71. /* CTR_DRBG_Generate(result->len * 8 bits, add2->x[:add2->len]) -> buf */
  72. /* Then reseed if prediction resistance is enabled. */
  73. TEST_ASSERT( mbedtls_ctr_drbg_random_with_add(
  74. &ctx,
  75. buf, result->len,
  76. add2->x, add2->len ) == 0 );
  77. TEST_ASSERT( memcmp( buf, result->x, result->len ) == 0 );
  78. exit:
  79. mbedtls_ctr_drbg_free( &ctx );
  80. }
  81. /* END_HEADER */
  82. /* BEGIN_DEPENDENCIES
  83. * depends_on:MBEDTLS_CTR_DRBG_C
  84. * END_DEPENDENCIES
  85. */
  86. /* BEGIN_CASE */
  87. void ctr_drbg_special_behaviours( )
  88. {
  89. mbedtls_ctr_drbg_context ctx;
  90. unsigned char output[512];
  91. unsigned char additional[512];
  92. mbedtls_ctr_drbg_init( &ctx );
  93. memset( output, 0, sizeof( output ) );
  94. memset( additional, 0, sizeof( additional ) );
  95. TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx,
  96. output, MBEDTLS_CTR_DRBG_MAX_REQUEST + 1,
  97. additional, 16 ) ==
  98. MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG );
  99. TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx,
  100. output, 16,
  101. additional, MBEDTLS_CTR_DRBG_MAX_INPUT + 1 ) ==
  102. MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
  103. TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
  104. MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 1 ) ==
  105. MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
  106. mbedtls_ctr_drbg_set_entropy_len( &ctx, ~0 );
  107. TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
  108. MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) ==
  109. MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
  110. exit:
  111. mbedtls_ctr_drbg_free( &ctx );
  112. }
  113. /* END_CASE */
  114. /* BEGIN_CASE */
  115. void ctr_drbg_validate_no_reseed( data_t * add_init, data_t * entropy,
  116. data_t * add1, data_t * add2,
  117. data_t * result_string )
  118. {
  119. data_t empty = { 0, 0 };
  120. ctr_drbg_validate_internal( RESEED_NEVER, add_init,
  121. entropy->len, entropy,
  122. &empty, add1, add2,
  123. result_string );
  124. goto exit; // goto is needed to avoid warning ( no test assertions in func)
  125. }
  126. /* END_CASE */
  127. /* BEGIN_CASE */
  128. void ctr_drbg_validate_pr( data_t * add_init, data_t * entropy,
  129. data_t * add1, data_t * add2,
  130. data_t * result_string )
  131. {
  132. data_t empty = { 0, 0 };
  133. ctr_drbg_validate_internal( RESEED_ALWAYS, add_init,
  134. entropy->len / 3, entropy,
  135. &empty, add1, add2,
  136. result_string );
  137. goto exit; // goto is needed to avoid warning ( no test assertions in func)
  138. }
  139. /* END_CASE */
  140. /* BEGIN_CASE */
  141. void ctr_drbg_validate_reseed_between( data_t * add_init, data_t * entropy,
  142. data_t * add1, data_t * add_reseed,
  143. data_t * add2, data_t * result_string )
  144. {
  145. ctr_drbg_validate_internal( RESEED_SECOND, add_init,
  146. entropy->len / 2, entropy,
  147. add_reseed, add1, add2,
  148. result_string );
  149. goto exit; // goto is needed to avoid warning ( no test assertions in func)
  150. }
  151. /* END_CASE */
  152. /* BEGIN_CASE */
  153. void ctr_drbg_validate_reseed_first( data_t * add_init, data_t * entropy,
  154. data_t * add1, data_t * add_reseed,
  155. data_t * add2, data_t * result_string )
  156. {
  157. ctr_drbg_validate_internal( RESEED_FIRST, add_init,
  158. entropy->len / 2, entropy,
  159. add_reseed, add1, add2,
  160. result_string );
  161. goto exit; // goto is needed to avoid warning ( no test assertions in func)
  162. }
  163. /* END_CASE */
  164. /* BEGIN_CASE */
  165. void ctr_drbg_entropy_strength( int expected_bit_strength )
  166. {
  167. unsigned char entropy[/*initial entropy*/ MBEDTLS_CTR_DRBG_ENTROPY_LEN +
  168. /*nonce*/ MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN +
  169. /*reseed*/ MBEDTLS_CTR_DRBG_ENTROPY_LEN];
  170. mbedtls_ctr_drbg_context ctx;
  171. size_t last_idx;
  172. size_t byte_strength = expected_bit_strength / 8;
  173. mbedtls_ctr_drbg_init( &ctx );
  174. test_offset_idx = 0;
  175. test_max_idx = sizeof( entropy );
  176. memset( entropy, 0, sizeof( entropy ) );
  177. /* The initial seeding must grab at least byte_strength bytes of entropy
  178. * for the entropy input and byte_strength/2 bytes for a nonce. */
  179. TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx,
  180. mbedtls_test_entropy_func, entropy,
  181. NULL, 0 ) == 0 );
  182. TEST_ASSERT( test_offset_idx >= ( byte_strength * 3 + 1 ) / 2 );
  183. last_idx = test_offset_idx;
  184. /* A reseed must grab at least byte_strength bytes of entropy. */
  185. TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) == 0 );
  186. TEST_ASSERT( test_offset_idx - last_idx >= byte_strength );
  187. exit:
  188. mbedtls_ctr_drbg_free( &ctx );
  189. }
  190. /* END_CASE */
  191. /* BEGIN_CASE */
  192. void ctr_drbg_entropy_usage( int entropy_nonce_len )
  193. {
  194. unsigned char out[16];
  195. unsigned char add[16];
  196. unsigned char entropy[1024];
  197. mbedtls_ctr_drbg_context ctx;
  198. size_t i, reps = 10;
  199. size_t expected_idx = 0;
  200. mbedtls_ctr_drbg_init( &ctx );
  201. test_offset_idx = 0;
  202. test_max_idx = sizeof( entropy );
  203. memset( entropy, 0, sizeof( entropy ) );
  204. memset( out, 0, sizeof( out ) );
  205. memset( add, 0, sizeof( add ) );
  206. if( entropy_nonce_len >= 0 )
  207. TEST_ASSERT( mbedtls_ctr_drbg_set_nonce_len( &ctx, entropy_nonce_len ) == 0 );
  208. /* Set reseed interval before seed */
  209. mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps );
  210. /* Init must use entropy */
  211. TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_test_entropy_func, entropy, NULL, 0 ) == 0 );
  212. expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
  213. if( entropy_nonce_len >= 0 )
  214. expected_idx += entropy_nonce_len;
  215. else
  216. expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_NONCE_LEN;
  217. TEST_EQUAL( test_offset_idx, expected_idx );
  218. /* By default, PR is off, and reseed interval was set to
  219. * 2 * reps so the next few calls should not use entropy */
  220. for( i = 0; i < reps; i++ )
  221. {
  222. TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
  223. TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) - 4,
  224. add, sizeof( add ) ) == 0 );
  225. }
  226. TEST_EQUAL( test_offset_idx, expected_idx );
  227. /* While at it, make sure we didn't write past the requested length */
  228. TEST_ASSERT( out[sizeof( out ) - 4] == 0 );
  229. TEST_ASSERT( out[sizeof( out ) - 3] == 0 );
  230. TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
  231. TEST_ASSERT( out[sizeof( out ) - 1] == 0 );
  232. /* There have been 2 * reps calls to random. The next call should reseed */
  233. TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
  234. expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
  235. TEST_EQUAL( test_offset_idx, expected_idx );
  236. /* Set reseed interval after seed */
  237. mbedtls_ctr_drbg_set_reseed_interval( &ctx, 4 * reps + 1 );
  238. /* The next few calls should not reseed */
  239. for( i = 0; i < (2 * reps); i++ )
  240. {
  241. TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
  242. TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) ,
  243. add, sizeof( add ) ) == 0 );
  244. }
  245. TEST_EQUAL( test_offset_idx, expected_idx );
  246. /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT).
  247. * Make sure it's detected as an error and doesn't cause memory
  248. * corruption. */
  249. TEST_ASSERT( mbedtls_ctr_drbg_update_ret(
  250. &ctx, entropy, sizeof( entropy ) ) != 0 );
  251. /* Now enable PR, so the next few calls should all reseed */
  252. mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
  253. TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
  254. expected_idx += MBEDTLS_CTR_DRBG_ENTROPY_LEN;
  255. TEST_EQUAL( test_offset_idx, expected_idx );
  256. /* Finally, check setting entropy_len */
  257. mbedtls_ctr_drbg_set_entropy_len( &ctx, 42 );
  258. TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
  259. expected_idx += 42;
  260. TEST_EQUAL( test_offset_idx, expected_idx );
  261. mbedtls_ctr_drbg_set_entropy_len( &ctx, 13 );
  262. TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
  263. expected_idx += 13;
  264. TEST_EQUAL( test_offset_idx, expected_idx );
  265. exit:
  266. mbedtls_ctr_drbg_free( &ctx );
  267. }
  268. /* END_CASE */
  269. /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
  270. void ctr_drbg_seed_file( char * path, int ret )
  271. {
  272. mbedtls_ctr_drbg_context ctx;
  273. mbedtls_ctr_drbg_init( &ctx );
  274. TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_test_rnd_std_rand,
  275. NULL, NULL, 0 ) == 0 );
  276. TEST_ASSERT( mbedtls_ctr_drbg_write_seed_file( &ctx, path ) == ret );
  277. TEST_ASSERT( mbedtls_ctr_drbg_update_seed_file( &ctx, path ) == ret );
  278. exit:
  279. mbedtls_ctr_drbg_free( &ctx );
  280. }
  281. /* END_CASE */
  282. /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
  283. void ctr_drbg_selftest( )
  284. {
  285. TEST_ASSERT( mbedtls_ctr_drbg_self_test( 1 ) == 0 );
  286. }
  287. /* END_CASE */