1/* BEGIN_HEADER */ 2#include "mbedtls/ctr_drbg.h" 3 4int test_offset_idx; 5int mbedtls_entropy_func( void *data, unsigned char *buf, size_t len ) 6{ 7 const unsigned char *p = (unsigned char *) data; 8 memcpy( buf, p + test_offset_idx, len ); 9 test_offset_idx += len; 10 return( 0 ); 11} 12/* END_HEADER */ 13 14/* BEGIN_DEPENDENCIES 15 * depends_on:MBEDTLS_CTR_DRBG_C 16 * END_DEPENDENCIES 17 */ 18 19/* BEGIN_CASE */ 20void ctr_drbg_special_behaviours( ) 21{ 22 mbedtls_ctr_drbg_context ctx; 23 unsigned char output[512]; 24 unsigned char additional[512]; 25 26 mbedtls_ctr_drbg_init( &ctx ); 27 memset( output, 0, sizeof( output ) ); 28 memset( additional, 0, sizeof( additional ) ); 29 30 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, 31 output, MBEDTLS_CTR_DRBG_MAX_REQUEST + 1, 32 additional, 16 ) == 33 MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG ); 34 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, 35 output, 16, 36 additional, MBEDTLS_CTR_DRBG_MAX_INPUT + 1 ) == 37 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); 38 39 TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional, 40 MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 1 ) == 41 MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); 42exit: 43 mbedtls_ctr_drbg_free( &ctx ); 44} 45/* END_CASE */ 46 47/* BEGIN_CASE */ 48void ctr_drbg_validate_pr( char *add_init_string, char *entropy_string, 49 char *add1_string, char *add2_string, 50 char *result_str ) 51{ 52 unsigned char entropy[512]; 53 unsigned char add_init[512]; 54 unsigned char add1[512]; 55 unsigned char add2[512]; 56 mbedtls_ctr_drbg_context ctx; 57 unsigned char buf[512]; 58 unsigned char output_str[512]; 59 int add_init_len, add1_len, add2_len; 60 61 mbedtls_ctr_drbg_init( &ctx ); 62 memset( output_str, 0, 512 ); 63 64 unhexify( entropy, entropy_string ); 65 add_init_len = unhexify( add_init, add_init_string ); 66 add1_len = unhexify( add1, add1_string ); 67 add2_len = unhexify( add2, add2_string ); 68 69 test_offset_idx = 0; 70 TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_entropy_func, entropy, add_init, add_init_len, 32 ) == 0 ); 71 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); 72 73 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, 16, add1, add1_len ) == 0 ); 74 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, 16, add2, add2_len ) == 0 ); 75 hexify( output_str, buf, 16 ); 76 TEST_ASSERT( strcmp( (char *) output_str, result_str ) == 0 ); 77 78exit: 79 mbedtls_ctr_drbg_free( &ctx ); 80} 81/* END_CASE */ 82 83/* BEGIN_CASE */ 84void ctr_drbg_validate_nopr( char *add_init_string, char *entropy_string, 85 char *add1_string, char *add_reseed_string, 86 char *add2_string, char *result_str ) 87{ 88 unsigned char entropy[512]; 89 unsigned char add_init[512]; 90 unsigned char add1[512]; 91 unsigned char add_reseed[512]; 92 unsigned char add2[512]; 93 mbedtls_ctr_drbg_context ctx; 94 unsigned char buf[512]; 95 unsigned char output_str[512]; 96 int add_init_len, add1_len, add_reseed_len, add2_len; 97 98 mbedtls_ctr_drbg_init( &ctx ); 99 memset( output_str, 0, 512 ); 100 101 unhexify( entropy, entropy_string ); 102 add_init_len = unhexify( add_init, add_init_string ); 103 add1_len = unhexify( add1, add1_string ); 104 add_reseed_len = unhexify( add_reseed, add_reseed_string ); 105 add2_len = unhexify( add2, add2_string ); 106 107 test_offset_idx = 0; 108 TEST_ASSERT( mbedtls_ctr_drbg_seed_entropy_len( &ctx, mbedtls_entropy_func, entropy, add_init, add_init_len, 32 ) == 0 ); 109 110 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, 16, add1, add1_len ) == 0 ); 111 TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, add_reseed, add_reseed_len ) == 0 ); 112 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, buf, 16, add2, add2_len ) == 0 ); 113 hexify( output_str, buf, 16 ); 114 TEST_ASSERT( strcmp( (char *) output_str, result_str ) == 0 ); 115 116exit: 117 mbedtls_ctr_drbg_free( &ctx ); 118} 119/* END_CASE */ 120 121/* BEGIN_CASE */ 122void ctr_drbg_entropy_usage( ) 123{ 124 unsigned char out[16]; 125 unsigned char add[16]; 126 unsigned char entropy[1024]; 127 mbedtls_ctr_drbg_context ctx; 128 size_t i, reps = 10; 129 int last_idx; 130 131 mbedtls_ctr_drbg_init( &ctx ); 132 test_offset_idx = 0; 133 memset( entropy, 0, sizeof( entropy ) ); 134 memset( out, 0, sizeof( out ) ); 135 memset( add, 0, sizeof( add ) ); 136 137 /* Init must use entropy */ 138 last_idx = test_offset_idx; 139 TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, mbedtls_entropy_func, entropy, NULL, 0 ) == 0 ); 140 TEST_ASSERT( last_idx < test_offset_idx ); 141 142 /* By default, PR is off and reseed_interval is large, 143 * so the next few calls should not use entropy */ 144 last_idx = test_offset_idx; 145 for( i = 0; i < reps; i++ ) 146 { 147 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 ); 148 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) - 4, 149 add, sizeof( add ) ) == 0 ); 150 } 151 TEST_ASSERT( last_idx == test_offset_idx ); 152 153 /* While at it, make sure we didn't write past the requested length */ 154 TEST_ASSERT( out[sizeof( out ) - 4] == 0 ); 155 TEST_ASSERT( out[sizeof( out ) - 3] == 0 ); 156 TEST_ASSERT( out[sizeof( out ) - 2] == 0 ); 157 TEST_ASSERT( out[sizeof( out ) - 1] == 0 ); 158 159 /* Set reseed_interval to the number of calls done, 160 * so the next call should reseed */ 161 mbedtls_ctr_drbg_set_reseed_interval( &ctx, 2 * reps ); 162 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); 163 TEST_ASSERT( last_idx < test_offset_idx ); 164 165 /* The new few calls should not reseed */ 166 last_idx = test_offset_idx; 167 for( i = 0; i < reps / 2; i++ ) 168 { 169 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); 170 TEST_ASSERT( mbedtls_ctr_drbg_random_with_add( &ctx, out, sizeof( out ) , 171 add, sizeof( add ) ) == 0 ); 172 } 173 TEST_ASSERT( last_idx == test_offset_idx ); 174 175 /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT) 176 * (just make sure it doesn't cause memory corruption) */ 177 mbedtls_ctr_drbg_update( &ctx, entropy, sizeof( entropy ) ); 178 179 /* Now enable PR, so the next few calls should all reseed */ 180 mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); 181 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); 182 TEST_ASSERT( last_idx < test_offset_idx ); 183 184 /* Finally, check setting entropy_len */ 185 mbedtls_ctr_drbg_set_entropy_len( &ctx, 42 ); 186 last_idx = test_offset_idx; 187 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); 188 TEST_ASSERT( test_offset_idx - last_idx == 42 ); 189 190 mbedtls_ctr_drbg_set_entropy_len( &ctx, 13 ); 191 last_idx = test_offset_idx; 192 TEST_ASSERT( mbedtls_ctr_drbg_random( &ctx, out, sizeof( out ) ) == 0 ); 193 TEST_ASSERT( test_offset_idx - last_idx == 13 ); 194 195exit: 196 mbedtls_ctr_drbg_free( &ctx ); 197} 198/* END_CASE */ 199 200/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */ 201void ctr_drbg_seed_file( char *path, int ret ) 202{ 203 mbedtls_ctr_drbg_context ctx; 204 205 mbedtls_ctr_drbg_init( &ctx ); 206 207 TEST_ASSERT( mbedtls_ctr_drbg_seed( &ctx, rnd_std_rand, NULL, NULL, 0 ) == 0 ); 208 TEST_ASSERT( mbedtls_ctr_drbg_write_seed_file( &ctx, path ) == ret ); 209 TEST_ASSERT( mbedtls_ctr_drbg_update_seed_file( &ctx, path ) == ret ); 210 211exit: 212 mbedtls_ctr_drbg_free( &ctx ); 213} 214/* END_CASE */ 215 216/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ 217void ctr_drbg_selftest( ) 218{ 219 TEST_ASSERT( mbedtls_ctr_drbg_self_test( 1 ) == 0 ); 220} 221/* END_CASE */ 222