test_suite_hmac_drbg.function (10365B)
1 /* BEGIN_HEADER */ 2 #include "mbedtls/hmac_drbg.h" 3 #include "string.h" 4 5 typedef struct { 6 unsigned char *p; 7 size_t len; 8 } entropy_ctx; 9 10 static int mbedtls_test_entropy_func(void *data, unsigned char *buf, size_t len) 11 { 12 entropy_ctx *ctx = (entropy_ctx *) data; 13 14 if (len > ctx->len) { 15 return -1; 16 } 17 18 memcpy(buf, ctx->p, len); 19 20 ctx->p += len; 21 ctx->len -= len; 22 23 return 0; 24 } 25 /* END_HEADER */ 26 27 /* BEGIN_DEPENDENCIES 28 * depends_on:MBEDTLS_HMAC_DRBG_C 29 * END_DEPENDENCIES 30 */ 31 32 /* BEGIN_CASE */ 33 void hmac_drbg_entropy_usage(int md_alg) 34 { 35 unsigned char out[16]; 36 unsigned char buf[1024]; 37 const mbedtls_md_info_t *md_info; 38 mbedtls_hmac_drbg_context ctx; 39 entropy_ctx entropy; 40 size_t i, reps = 10; 41 size_t default_entropy_len; 42 size_t expected_consumed_entropy = 0; 43 44 mbedtls_hmac_drbg_init(&ctx); 45 memset(buf, 0, sizeof(buf)); 46 memset(out, 0, sizeof(out)); 47 48 entropy.len = sizeof(buf); 49 entropy.p = buf; 50 51 MD_PSA_INIT(); 52 53 md_info = mbedtls_md_info_from_type(md_alg); 54 TEST_ASSERT(md_info != NULL); 55 if (mbedtls_md_get_size(md_info) <= 20) { 56 default_entropy_len = 16; 57 } else if (mbedtls_md_get_size(md_info) <= 28) { 58 default_entropy_len = 24; 59 } else { 60 default_entropy_len = 32; 61 } 62 63 /* Set reseed interval before seed */ 64 mbedtls_hmac_drbg_set_reseed_interval(&ctx, 2 * reps); 65 66 /* Init must use entropy */ 67 TEST_ASSERT(mbedtls_hmac_drbg_seed(&ctx, md_info, mbedtls_test_entropy_func, &entropy, 68 NULL, 0) == 0); 69 /* default_entropy_len of entropy, plus half as much for the nonce */ 70 expected_consumed_entropy += default_entropy_len * 3 / 2; 71 TEST_EQUAL(sizeof(buf) - entropy.len, expected_consumed_entropy); 72 73 /* By default, PR is off, and reseed interval was set to 74 * 2 * reps so the next few calls should not use entropy */ 75 for (i = 0; i < reps; i++) { 76 TEST_ASSERT(mbedtls_hmac_drbg_random(&ctx, out, sizeof(out) - 4) == 0); 77 TEST_ASSERT(mbedtls_hmac_drbg_random_with_add(&ctx, out, sizeof(out) - 4, 78 buf, 16) == 0); 79 } 80 TEST_EQUAL(sizeof(buf) - entropy.len, expected_consumed_entropy); 81 82 /* While at it, make sure we didn't write past the requested length */ 83 TEST_ASSERT(out[sizeof(out) - 4] == 0); 84 TEST_ASSERT(out[sizeof(out) - 3] == 0); 85 TEST_ASSERT(out[sizeof(out) - 2] == 0); 86 TEST_ASSERT(out[sizeof(out) - 1] == 0); 87 88 /* There have been 2 * reps calls to random. The next call should reseed */ 89 TEST_ASSERT(mbedtls_hmac_drbg_random(&ctx, out, sizeof(out)) == 0); 90 expected_consumed_entropy += default_entropy_len; 91 TEST_EQUAL(sizeof(buf) - entropy.len, expected_consumed_entropy); 92 93 /* Set reseed interval after seed */ 94 mbedtls_hmac_drbg_set_reseed_interval(&ctx, 4 * reps + 1); 95 96 /* The new few calls should not reseed */ 97 for (i = 0; i < (2 * reps); i++) { 98 TEST_ASSERT(mbedtls_hmac_drbg_random(&ctx, out, sizeof(out)) == 0); 99 TEST_ASSERT(mbedtls_hmac_drbg_random_with_add(&ctx, out, sizeof(out), 100 buf, 16) == 0); 101 } 102 TEST_EQUAL(sizeof(buf) - entropy.len, expected_consumed_entropy); 103 104 /* Now enable PR, so the next few calls should all reseed */ 105 mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON); 106 TEST_ASSERT(mbedtls_hmac_drbg_random(&ctx, out, sizeof(out)) == 0); 107 expected_consumed_entropy += default_entropy_len; 108 TEST_EQUAL(sizeof(buf) - entropy.len, expected_consumed_entropy); 109 110 /* Finally, check setting entropy_len */ 111 mbedtls_hmac_drbg_set_entropy_len(&ctx, 42); 112 TEST_ASSERT(mbedtls_hmac_drbg_random(&ctx, out, sizeof(out)) == 0); 113 expected_consumed_entropy += 42; 114 TEST_EQUAL(sizeof(buf) - entropy.len, expected_consumed_entropy); 115 116 mbedtls_hmac_drbg_set_entropy_len(&ctx, 13); 117 TEST_ASSERT(mbedtls_hmac_drbg_random(&ctx, out, sizeof(out)) == 0); 118 expected_consumed_entropy += 13; 119 TEST_EQUAL(sizeof(buf) - entropy.len, expected_consumed_entropy); 120 121 exit: 122 mbedtls_hmac_drbg_free(&ctx); 123 MD_PSA_DONE(); 124 } 125 /* END_CASE */ 126 127 /* BEGIN_CASE depends_on:MBEDTLS_FS_IO */ 128 void hmac_drbg_seed_file(int md_alg, char *path, int ret) 129 { 130 const mbedtls_md_info_t *md_info; 131 mbedtls_hmac_drbg_context ctx; 132 mbedtls_hmac_drbg_init(&ctx); 133 134 MD_PSA_INIT(); 135 136 md_info = mbedtls_md_info_from_type(md_alg); 137 TEST_ASSERT(md_info != NULL); 138 139 TEST_ASSERT(mbedtls_hmac_drbg_seed(&ctx, md_info, 140 mbedtls_test_rnd_std_rand, NULL, 141 NULL, 0) == 0); 142 143 TEST_ASSERT(mbedtls_hmac_drbg_write_seed_file(&ctx, path) == ret); 144 TEST_ASSERT(mbedtls_hmac_drbg_update_seed_file(&ctx, path) == ret); 145 146 exit: 147 mbedtls_hmac_drbg_free(&ctx); 148 MD_PSA_DONE(); 149 } 150 /* END_CASE */ 151 152 /* BEGIN_CASE */ 153 void hmac_drbg_buf(int md_alg) 154 { 155 unsigned char out[16]; 156 unsigned char buf[100]; 157 const mbedtls_md_info_t *md_info; 158 mbedtls_hmac_drbg_context ctx; 159 size_t i; 160 161 mbedtls_hmac_drbg_init(&ctx); 162 memset(buf, 0, sizeof(buf)); 163 memset(out, 0, sizeof(out)); 164 165 MD_PSA_INIT(); 166 167 md_info = mbedtls_md_info_from_type(md_alg); 168 TEST_ASSERT(md_info != NULL); 169 TEST_ASSERT(mbedtls_hmac_drbg_seed_buf(&ctx, md_info, buf, sizeof(buf)) == 0); 170 171 /* Make sure it never tries to reseed (would segfault otherwise) */ 172 mbedtls_hmac_drbg_set_reseed_interval(&ctx, 3); 173 mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON); 174 175 for (i = 0; i < 30; i++) { 176 TEST_ASSERT(mbedtls_hmac_drbg_random(&ctx, out, sizeof(out)) == 0); 177 } 178 179 exit: 180 mbedtls_hmac_drbg_free(&ctx); 181 MD_PSA_DONE(); 182 } 183 /* END_CASE */ 184 185 /* BEGIN_CASE */ 186 void hmac_drbg_no_reseed(int md_alg, data_t *entropy, 187 data_t *custom, data_t *add1, 188 data_t *add2, data_t *output) 189 { 190 unsigned char data[1024]; 191 unsigned char my_output[512]; 192 entropy_ctx p_entropy; 193 const mbedtls_md_info_t *md_info; 194 mbedtls_hmac_drbg_context ctx; 195 196 mbedtls_hmac_drbg_init(&ctx); 197 198 p_entropy.p = entropy->x; 199 p_entropy.len = entropy->len; 200 201 MD_PSA_INIT(); 202 203 md_info = mbedtls_md_info_from_type(md_alg); 204 TEST_ASSERT(md_info != NULL); 205 206 /* Test the simplified buffer-based variant */ 207 memcpy(data, entropy->x, p_entropy.len); 208 memcpy(data + p_entropy.len, custom->x, custom->len); 209 TEST_ASSERT(mbedtls_hmac_drbg_seed_buf(&ctx, md_info, 210 data, p_entropy.len + custom->len) == 0); 211 TEST_ASSERT(mbedtls_hmac_drbg_random_with_add(&ctx, my_output, output->len, 212 add1->x, add1->len) == 0); 213 TEST_ASSERT(mbedtls_hmac_drbg_random_with_add(&ctx, my_output, output->len, 214 add2->x, add2->len) == 0); 215 216 /* Reset context for second run */ 217 mbedtls_hmac_drbg_free(&ctx); 218 219 TEST_ASSERT(memcmp(my_output, output->x, output->len) == 0); 220 221 /* And now the normal entropy-based variant */ 222 TEST_ASSERT(mbedtls_hmac_drbg_seed(&ctx, md_info, mbedtls_test_entropy_func, &p_entropy, 223 custom->x, custom->len) == 0); 224 TEST_ASSERT(mbedtls_hmac_drbg_random_with_add(&ctx, my_output, output->len, 225 add1->x, add1->len) == 0); 226 TEST_ASSERT(mbedtls_hmac_drbg_random_with_add(&ctx, my_output, output->len, 227 add2->x, add2->len) == 0); 228 TEST_ASSERT(memcmp(my_output, output->x, output->len) == 0); 229 230 exit: 231 mbedtls_hmac_drbg_free(&ctx); 232 MD_PSA_DONE(); 233 } 234 /* END_CASE */ 235 236 /* BEGIN_CASE */ 237 void hmac_drbg_nopr(int md_alg, data_t *entropy, data_t *custom, 238 data_t *add1, data_t *add2, data_t *add3, 239 data_t *output) 240 { 241 unsigned char my_output[512]; 242 entropy_ctx p_entropy; 243 const mbedtls_md_info_t *md_info; 244 mbedtls_hmac_drbg_context ctx; 245 246 mbedtls_hmac_drbg_init(&ctx); 247 248 p_entropy.p = entropy->x; 249 p_entropy.len = entropy->len; 250 251 MD_PSA_INIT(); 252 253 md_info = mbedtls_md_info_from_type(md_alg); 254 TEST_ASSERT(md_info != NULL); 255 256 TEST_ASSERT(mbedtls_hmac_drbg_seed(&ctx, md_info, mbedtls_test_entropy_func, &p_entropy, 257 custom->x, custom->len) == 0); 258 TEST_ASSERT(mbedtls_hmac_drbg_reseed(&ctx, add1->x, add1->len) == 0); 259 TEST_ASSERT(mbedtls_hmac_drbg_random_with_add(&ctx, my_output, output->len, 260 add2->x, add2->len) == 0); 261 TEST_ASSERT(mbedtls_hmac_drbg_random_with_add(&ctx, my_output, output->len, 262 add3->x, add3->len) == 0); 263 264 TEST_ASSERT(memcmp(my_output, output->x, output->len) == 0); 265 266 exit: 267 mbedtls_hmac_drbg_free(&ctx); 268 MD_PSA_DONE(); 269 } 270 /* END_CASE */ 271 272 /* BEGIN_CASE */ 273 void hmac_drbg_pr(int md_alg, data_t *entropy, data_t *custom, 274 data_t *add1, data_t *add2, data_t *output) 275 { 276 unsigned char my_output[512]; 277 entropy_ctx p_entropy; 278 const mbedtls_md_info_t *md_info; 279 mbedtls_hmac_drbg_context ctx; 280 281 mbedtls_hmac_drbg_init(&ctx); 282 283 p_entropy.p = entropy->x; 284 p_entropy.len = entropy->len; 285 286 MD_PSA_INIT(); 287 288 md_info = mbedtls_md_info_from_type(md_alg); 289 TEST_ASSERT(md_info != NULL); 290 291 TEST_ASSERT(mbedtls_hmac_drbg_seed(&ctx, md_info, mbedtls_test_entropy_func, &p_entropy, 292 custom->x, custom->len) == 0); 293 mbedtls_hmac_drbg_set_prediction_resistance(&ctx, MBEDTLS_HMAC_DRBG_PR_ON); 294 TEST_ASSERT(mbedtls_hmac_drbg_random_with_add(&ctx, my_output, output->len, 295 add1->x, add1->len) == 0); 296 TEST_ASSERT(mbedtls_hmac_drbg_random_with_add(&ctx, my_output, output->len, 297 add2->x, add2->len) == 0); 298 299 TEST_ASSERT(memcmp(my_output, output->x, output->len) == 0); 300 301 exit: 302 mbedtls_hmac_drbg_free(&ctx); 303 MD_PSA_DONE(); 304 } 305 /* END_CASE */ 306 307 /* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */ 308 void hmac_drbg_selftest() 309 { 310 MD_PSA_INIT(); 311 312 TEST_ASSERT(mbedtls_hmac_drbg_self_test(1) == 0); 313 314 exit: 315 MD_PSA_DONE(); 316 } 317 /* END_CASE */