1*62c56f98SSadaf Ebrahimi/* BEGIN_HEADER */ 2*62c56f98SSadaf Ebrahimi#include "mbedtls/entropy.h" 3*62c56f98SSadaf Ebrahimi#include "entropy_poll.h" 4*62c56f98SSadaf Ebrahimi#include "mbedtls/md.h" 5*62c56f98SSadaf Ebrahimi#include "string.h" 6*62c56f98SSadaf Ebrahimi 7*62c56f98SSadaf Ebrahimitypedef enum { 8*62c56f98SSadaf Ebrahimi DUMMY_CONSTANT_LENGTH, /* Output context->length bytes */ 9*62c56f98SSadaf Ebrahimi DUMMY_REQUESTED_LENGTH, /* Output whatever length was requested */ 10*62c56f98SSadaf Ebrahimi DUMMY_FAIL, /* Return an error code */ 11*62c56f98SSadaf Ebrahimi} entropy_dummy_instruction; 12*62c56f98SSadaf Ebrahimi 13*62c56f98SSadaf Ebrahimitypedef struct { 14*62c56f98SSadaf Ebrahimi entropy_dummy_instruction instruction; 15*62c56f98SSadaf Ebrahimi size_t length; /* Length to return for DUMMY_CONSTANT_LENGTH */ 16*62c56f98SSadaf Ebrahimi size_t calls; /* Incremented at each call */ 17*62c56f98SSadaf Ebrahimi} entropy_dummy_context; 18*62c56f98SSadaf Ebrahimi 19*62c56f98SSadaf Ebrahimi/* 20*62c56f98SSadaf Ebrahimi * Dummy entropy source 21*62c56f98SSadaf Ebrahimi * 22*62c56f98SSadaf Ebrahimi * If data is NULL, write exactly the requested length. 23*62c56f98SSadaf Ebrahimi * Otherwise, write the length indicated by data or error if negative 24*62c56f98SSadaf Ebrahimi */ 25*62c56f98SSadaf Ebrahimistatic int entropy_dummy_source(void *arg, unsigned char *output, 26*62c56f98SSadaf Ebrahimi size_t len, size_t *olen) 27*62c56f98SSadaf Ebrahimi{ 28*62c56f98SSadaf Ebrahimi entropy_dummy_context *context = arg; 29*62c56f98SSadaf Ebrahimi ++context->calls; 30*62c56f98SSadaf Ebrahimi 31*62c56f98SSadaf Ebrahimi switch (context->instruction) { 32*62c56f98SSadaf Ebrahimi case DUMMY_CONSTANT_LENGTH: 33*62c56f98SSadaf Ebrahimi *olen = context->length; 34*62c56f98SSadaf Ebrahimi break; 35*62c56f98SSadaf Ebrahimi case DUMMY_REQUESTED_LENGTH: 36*62c56f98SSadaf Ebrahimi *olen = len; 37*62c56f98SSadaf Ebrahimi break; 38*62c56f98SSadaf Ebrahimi case DUMMY_FAIL: 39*62c56f98SSadaf Ebrahimi return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; 40*62c56f98SSadaf Ebrahimi } 41*62c56f98SSadaf Ebrahimi 42*62c56f98SSadaf Ebrahimi memset(output, 0x2a, *olen); 43*62c56f98SSadaf Ebrahimi return 0; 44*62c56f98SSadaf Ebrahimi} 45*62c56f98SSadaf Ebrahimi 46*62c56f98SSadaf Ebrahimi/* 47*62c56f98SSadaf Ebrahimi * Ability to clear entropy sources to allow testing with just predefined 48*62c56f98SSadaf Ebrahimi * entropy sources. This function or tests depending on it might break if there 49*62c56f98SSadaf Ebrahimi * are internal changes to how entropy sources are registered. 50*62c56f98SSadaf Ebrahimi * 51*62c56f98SSadaf Ebrahimi * To be called immediately after mbedtls_entropy_init(). 52*62c56f98SSadaf Ebrahimi * 53*62c56f98SSadaf Ebrahimi * Just resetting the counter. New sources will overwrite existing ones. 54*62c56f98SSadaf Ebrahimi * This might break memory checks in the future if sources need 'free-ing' then 55*62c56f98SSadaf Ebrahimi * as well. 56*62c56f98SSadaf Ebrahimi */ 57*62c56f98SSadaf Ebrahimistatic void entropy_clear_sources(mbedtls_entropy_context *ctx) 58*62c56f98SSadaf Ebrahimi{ 59*62c56f98SSadaf Ebrahimi ctx->source_count = 0; 60*62c56f98SSadaf Ebrahimi} 61*62c56f98SSadaf Ebrahimi 62*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ENTROPY_NV_SEED) 63*62c56f98SSadaf Ebrahimi/* 64*62c56f98SSadaf Ebrahimi * NV seed read/write functions that use a buffer instead of a file 65*62c56f98SSadaf Ebrahimi */ 66*62c56f98SSadaf Ebrahimistatic unsigned char buffer_seed[MBEDTLS_ENTROPY_BLOCK_SIZE]; 67*62c56f98SSadaf Ebrahimi 68*62c56f98SSadaf Ebrahimiint buffer_nv_seed_read(unsigned char *buf, size_t buf_len) 69*62c56f98SSadaf Ebrahimi{ 70*62c56f98SSadaf Ebrahimi if (buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE) { 71*62c56f98SSadaf Ebrahimi return -1; 72*62c56f98SSadaf Ebrahimi } 73*62c56f98SSadaf Ebrahimi 74*62c56f98SSadaf Ebrahimi memcpy(buf, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE); 75*62c56f98SSadaf Ebrahimi return 0; 76*62c56f98SSadaf Ebrahimi} 77*62c56f98SSadaf Ebrahimi 78*62c56f98SSadaf Ebrahimiint buffer_nv_seed_write(unsigned char *buf, size_t buf_len) 79*62c56f98SSadaf Ebrahimi{ 80*62c56f98SSadaf Ebrahimi if (buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE) { 81*62c56f98SSadaf Ebrahimi return -1; 82*62c56f98SSadaf Ebrahimi } 83*62c56f98SSadaf Ebrahimi 84*62c56f98SSadaf Ebrahimi memcpy(buffer_seed, buf, MBEDTLS_ENTROPY_BLOCK_SIZE); 85*62c56f98SSadaf Ebrahimi return 0; 86*62c56f98SSadaf Ebrahimi} 87*62c56f98SSadaf Ebrahimi 88*62c56f98SSadaf Ebrahimi/* 89*62c56f98SSadaf Ebrahimi * NV seed read/write helpers that fill the base seedfile 90*62c56f98SSadaf Ebrahimi */ 91*62c56f98SSadaf Ebrahimistatic int write_nv_seed(unsigned char *buf, size_t buf_len) 92*62c56f98SSadaf Ebrahimi{ 93*62c56f98SSadaf Ebrahimi FILE *f; 94*62c56f98SSadaf Ebrahimi 95*62c56f98SSadaf Ebrahimi if (buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE) { 96*62c56f98SSadaf Ebrahimi return -1; 97*62c56f98SSadaf Ebrahimi } 98*62c56f98SSadaf Ebrahimi 99*62c56f98SSadaf Ebrahimi if ((f = fopen(MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w")) == NULL) { 100*62c56f98SSadaf Ebrahimi return -1; 101*62c56f98SSadaf Ebrahimi } 102*62c56f98SSadaf Ebrahimi 103*62c56f98SSadaf Ebrahimi if (fwrite(buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f) != 104*62c56f98SSadaf Ebrahimi MBEDTLS_ENTROPY_BLOCK_SIZE) { 105*62c56f98SSadaf Ebrahimi return -1; 106*62c56f98SSadaf Ebrahimi } 107*62c56f98SSadaf Ebrahimi 108*62c56f98SSadaf Ebrahimi fclose(f); 109*62c56f98SSadaf Ebrahimi 110*62c56f98SSadaf Ebrahimi return 0; 111*62c56f98SSadaf Ebrahimi} 112*62c56f98SSadaf Ebrahimi 113*62c56f98SSadaf Ebrahimiint read_nv_seed(unsigned char *buf, size_t buf_len) 114*62c56f98SSadaf Ebrahimi{ 115*62c56f98SSadaf Ebrahimi FILE *f; 116*62c56f98SSadaf Ebrahimi 117*62c56f98SSadaf Ebrahimi if (buf_len != MBEDTLS_ENTROPY_BLOCK_SIZE) { 118*62c56f98SSadaf Ebrahimi return -1; 119*62c56f98SSadaf Ebrahimi } 120*62c56f98SSadaf Ebrahimi 121*62c56f98SSadaf Ebrahimi if ((f = fopen(MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb")) == NULL) { 122*62c56f98SSadaf Ebrahimi return -1; 123*62c56f98SSadaf Ebrahimi } 124*62c56f98SSadaf Ebrahimi 125*62c56f98SSadaf Ebrahimi if (fread(buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f) != 126*62c56f98SSadaf Ebrahimi MBEDTLS_ENTROPY_BLOCK_SIZE) { 127*62c56f98SSadaf Ebrahimi return -1; 128*62c56f98SSadaf Ebrahimi } 129*62c56f98SSadaf Ebrahimi 130*62c56f98SSadaf Ebrahimi fclose(f); 131*62c56f98SSadaf Ebrahimi 132*62c56f98SSadaf Ebrahimi return 0; 133*62c56f98SSadaf Ebrahimi} 134*62c56f98SSadaf Ebrahimi#endif /* MBEDTLS_ENTROPY_NV_SEED */ 135*62c56f98SSadaf Ebrahimi/* END_HEADER */ 136*62c56f98SSadaf Ebrahimi 137*62c56f98SSadaf Ebrahimi/* BEGIN_DEPENDENCIES 138*62c56f98SSadaf Ebrahimi * depends_on:MBEDTLS_ENTROPY_C:!MBEDTLS_PSA_INJECT_ENTROPY 139*62c56f98SSadaf Ebrahimi * END_DEPENDENCIES 140*62c56f98SSadaf Ebrahimi */ 141*62c56f98SSadaf Ebrahimi 142*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 143*62c56f98SSadaf Ebrahimivoid entropy_init_free(int reinit) 144*62c56f98SSadaf Ebrahimi{ 145*62c56f98SSadaf Ebrahimi mbedtls_entropy_context ctx; 146*62c56f98SSadaf Ebrahimi 147*62c56f98SSadaf Ebrahimi /* Double free is not explicitly documented to work, but it is convenient 148*62c56f98SSadaf Ebrahimi * to call mbedtls_entropy_free() unconditionally on an error path without 149*62c56f98SSadaf Ebrahimi * checking whether it has already been called in the success path. */ 150*62c56f98SSadaf Ebrahimi 151*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 152*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 153*62c56f98SSadaf Ebrahimi 154*62c56f98SSadaf Ebrahimi if (reinit) { 155*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 156*62c56f98SSadaf Ebrahimi } 157*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 158*62c56f98SSadaf Ebrahimi 159*62c56f98SSadaf Ebrahimi /* This test case always succeeds, functionally speaking. A plausible 160*62c56f98SSadaf Ebrahimi * bug might trigger an invalid pointer dereference or a memory leak. */ 161*62c56f98SSadaf Ebrahimi goto exit; 162*62c56f98SSadaf Ebrahimi} 163*62c56f98SSadaf Ebrahimi/* END_CASE */ 164*62c56f98SSadaf Ebrahimi 165*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */ 166*62c56f98SSadaf Ebrahimivoid entropy_seed_file(char *path, int ret) 167*62c56f98SSadaf Ebrahimi{ 168*62c56f98SSadaf Ebrahimi mbedtls_entropy_context ctx; 169*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 170*62c56f98SSadaf Ebrahimi 171*62c56f98SSadaf Ebrahimi MD_PSA_INIT(); 172*62c56f98SSadaf Ebrahimi 173*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_write_seed_file(&ctx, path) == ret); 174*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_update_seed_file(&ctx, path) == ret); 175*62c56f98SSadaf Ebrahimi 176*62c56f98SSadaf Ebrahimiexit: 177*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 178*62c56f98SSadaf Ebrahimi MD_PSA_DONE(); 179*62c56f98SSadaf Ebrahimi} 180*62c56f98SSadaf Ebrahimi/* END_CASE */ 181*62c56f98SSadaf Ebrahimi 182*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */ 183*62c56f98SSadaf Ebrahimivoid entropy_write_base_seed_file(int ret) 184*62c56f98SSadaf Ebrahimi{ 185*62c56f98SSadaf Ebrahimi mbedtls_entropy_context ctx; 186*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 187*62c56f98SSadaf Ebrahimi 188*62c56f98SSadaf Ebrahimi MD_PSA_INIT(); 189*62c56f98SSadaf Ebrahimi 190*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_write_seed_file(&ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE) == ret); 191*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_update_seed_file(&ctx, MBEDTLS_PLATFORM_STD_NV_SEED_FILE) == ret); 192*62c56f98SSadaf Ebrahimi 193*62c56f98SSadaf Ebrahimiexit: 194*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 195*62c56f98SSadaf Ebrahimi MD_PSA_DONE(); 196*62c56f98SSadaf Ebrahimi} 197*62c56f98SSadaf Ebrahimi/* END_CASE */ 198*62c56f98SSadaf Ebrahimi 199*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 200*62c56f98SSadaf Ebrahimivoid entropy_no_sources() 201*62c56f98SSadaf Ebrahimi{ 202*62c56f98SSadaf Ebrahimi mbedtls_entropy_context ctx; 203*62c56f98SSadaf Ebrahimi unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; 204*62c56f98SSadaf Ebrahimi 205*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 206*62c56f98SSadaf Ebrahimi entropy_clear_sources(&ctx); 207*62c56f98SSadaf Ebrahimi TEST_EQUAL(mbedtls_entropy_func(&ctx, buf, sizeof(buf)), 208*62c56f98SSadaf Ebrahimi MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED); 209*62c56f98SSadaf Ebrahimi 210*62c56f98SSadaf Ebrahimiexit: 211*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 212*62c56f98SSadaf Ebrahimi} 213*62c56f98SSadaf Ebrahimi/* END_CASE */ 214*62c56f98SSadaf Ebrahimi 215*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 216*62c56f98SSadaf Ebrahimivoid entropy_too_many_sources() 217*62c56f98SSadaf Ebrahimi{ 218*62c56f98SSadaf Ebrahimi mbedtls_entropy_context ctx; 219*62c56f98SSadaf Ebrahimi size_t i; 220*62c56f98SSadaf Ebrahimi entropy_dummy_context dummy = { DUMMY_REQUESTED_LENGTH, 0, 0 }; 221*62c56f98SSadaf Ebrahimi 222*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 223*62c56f98SSadaf Ebrahimi 224*62c56f98SSadaf Ebrahimi /* 225*62c56f98SSadaf Ebrahimi * It's hard to tell precisely when the error will occur, 226*62c56f98SSadaf Ebrahimi * since we don't know how many sources were automatically added. 227*62c56f98SSadaf Ebrahimi */ 228*62c56f98SSadaf Ebrahimi for (i = 0; i < MBEDTLS_ENTROPY_MAX_SOURCES; i++) { 229*62c56f98SSadaf Ebrahimi (void) mbedtls_entropy_add_source(&ctx, entropy_dummy_source, &dummy, 230*62c56f98SSadaf Ebrahimi 16, MBEDTLS_ENTROPY_SOURCE_WEAK); 231*62c56f98SSadaf Ebrahimi } 232*62c56f98SSadaf Ebrahimi 233*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, &dummy, 234*62c56f98SSadaf Ebrahimi 16, MBEDTLS_ENTROPY_SOURCE_WEAK) 235*62c56f98SSadaf Ebrahimi == MBEDTLS_ERR_ENTROPY_MAX_SOURCES); 236*62c56f98SSadaf Ebrahimi 237*62c56f98SSadaf Ebrahimiexit: 238*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 239*62c56f98SSadaf Ebrahimi} 240*62c56f98SSadaf Ebrahimi/* END_CASE */ 241*62c56f98SSadaf Ebrahimi 242*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG */ 243*62c56f98SSadaf Ebrahimivoid entropy_func_len(int len, int ret) 244*62c56f98SSadaf Ebrahimi{ 245*62c56f98SSadaf Ebrahimi mbedtls_entropy_context ctx; 246*62c56f98SSadaf Ebrahimi unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 }; 247*62c56f98SSadaf Ebrahimi unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE + 10] = { 0 }; 248*62c56f98SSadaf Ebrahimi size_t i, j; 249*62c56f98SSadaf Ebrahimi 250*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 251*62c56f98SSadaf Ebrahimi 252*62c56f98SSadaf Ebrahimi MD_PSA_INIT(); 253*62c56f98SSadaf Ebrahimi 254*62c56f98SSadaf Ebrahimi /* 255*62c56f98SSadaf Ebrahimi * See comments in mbedtls_entropy_self_test() 256*62c56f98SSadaf Ebrahimi */ 257*62c56f98SSadaf Ebrahimi for (i = 0; i < 8; i++) { 258*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_func(&ctx, buf, len) == ret); 259*62c56f98SSadaf Ebrahimi for (j = 0; j < sizeof(buf); j++) { 260*62c56f98SSadaf Ebrahimi acc[j] |= buf[j]; 261*62c56f98SSadaf Ebrahimi } 262*62c56f98SSadaf Ebrahimi } 263*62c56f98SSadaf Ebrahimi 264*62c56f98SSadaf Ebrahimi if (ret == 0) { 265*62c56f98SSadaf Ebrahimi for (j = 0; j < (size_t) len; j++) { 266*62c56f98SSadaf Ebrahimi TEST_ASSERT(acc[j] != 0); 267*62c56f98SSadaf Ebrahimi } 268*62c56f98SSadaf Ebrahimi } 269*62c56f98SSadaf Ebrahimi 270*62c56f98SSadaf Ebrahimi for (j = len; j < sizeof(buf); j++) { 271*62c56f98SSadaf Ebrahimi TEST_ASSERT(acc[j] == 0); 272*62c56f98SSadaf Ebrahimi } 273*62c56f98SSadaf Ebrahimi 274*62c56f98SSadaf Ebrahimiexit: 275*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 276*62c56f98SSadaf Ebrahimi MD_PSA_DONE(); 277*62c56f98SSadaf Ebrahimi} 278*62c56f98SSadaf Ebrahimi/* END_CASE */ 279*62c56f98SSadaf Ebrahimi 280*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 281*62c56f98SSadaf Ebrahimivoid entropy_source_fail(char *path) 282*62c56f98SSadaf Ebrahimi{ 283*62c56f98SSadaf Ebrahimi mbedtls_entropy_context ctx; 284*62c56f98SSadaf Ebrahimi unsigned char buf[16]; 285*62c56f98SSadaf Ebrahimi entropy_dummy_context dummy = { DUMMY_FAIL, 0, 0 }; 286*62c56f98SSadaf Ebrahimi 287*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 288*62c56f98SSadaf Ebrahimi 289*62c56f98SSadaf Ebrahimi MD_PSA_INIT(); 290*62c56f98SSadaf Ebrahimi 291*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, 292*62c56f98SSadaf Ebrahimi &dummy, 16, 293*62c56f98SSadaf Ebrahimi MBEDTLS_ENTROPY_SOURCE_WEAK) 294*62c56f98SSadaf Ebrahimi == 0); 295*62c56f98SSadaf Ebrahimi 296*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_func(&ctx, buf, sizeof(buf)) 297*62c56f98SSadaf Ebrahimi == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED); 298*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_gather(&ctx) 299*62c56f98SSadaf Ebrahimi == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED); 300*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_FS_IO) && defined(MBEDTLS_ENTROPY_NV_SEED) 301*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_write_seed_file(&ctx, path) 302*62c56f98SSadaf Ebrahimi == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED); 303*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_update_seed_file(&ctx, path) 304*62c56f98SSadaf Ebrahimi == MBEDTLS_ERR_ENTROPY_SOURCE_FAILED); 305*62c56f98SSadaf Ebrahimi#else 306*62c56f98SSadaf Ebrahimi ((void) path); 307*62c56f98SSadaf Ebrahimi#endif 308*62c56f98SSadaf Ebrahimi 309*62c56f98SSadaf Ebrahimiexit: 310*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 311*62c56f98SSadaf Ebrahimi MD_PSA_DONE(); 312*62c56f98SSadaf Ebrahimi} 313*62c56f98SSadaf Ebrahimi/* END_CASE */ 314*62c56f98SSadaf Ebrahimi 315*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 316*62c56f98SSadaf Ebrahimivoid entropy_threshold(int threshold, int chunk_size, int result) 317*62c56f98SSadaf Ebrahimi{ 318*62c56f98SSadaf Ebrahimi mbedtls_entropy_context ctx; 319*62c56f98SSadaf Ebrahimi entropy_dummy_context strong = 320*62c56f98SSadaf Ebrahimi { DUMMY_CONSTANT_LENGTH, MBEDTLS_ENTROPY_BLOCK_SIZE, 0 }; 321*62c56f98SSadaf Ebrahimi entropy_dummy_context weak = { DUMMY_CONSTANT_LENGTH, chunk_size, 0 }; 322*62c56f98SSadaf Ebrahimi unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; 323*62c56f98SSadaf Ebrahimi int ret; 324*62c56f98SSadaf Ebrahimi 325*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 326*62c56f98SSadaf Ebrahimi entropy_clear_sources(&ctx); 327*62c56f98SSadaf Ebrahimi 328*62c56f98SSadaf Ebrahimi MD_PSA_INIT(); 329*62c56f98SSadaf Ebrahimi 330*62c56f98SSadaf Ebrahimi /* Set strong source that reaches its threshold immediately and 331*62c56f98SSadaf Ebrahimi * a weak source whose threshold is a test parameter. */ 332*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, 333*62c56f98SSadaf Ebrahimi &strong, 1, 334*62c56f98SSadaf Ebrahimi MBEDTLS_ENTROPY_SOURCE_STRONG) == 0); 335*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, 336*62c56f98SSadaf Ebrahimi &weak, threshold, 337*62c56f98SSadaf Ebrahimi MBEDTLS_ENTROPY_SOURCE_WEAK) == 0); 338*62c56f98SSadaf Ebrahimi 339*62c56f98SSadaf Ebrahimi ret = mbedtls_entropy_func(&ctx, buf, sizeof(buf)); 340*62c56f98SSadaf Ebrahimi 341*62c56f98SSadaf Ebrahimi if (result >= 0) { 342*62c56f98SSadaf Ebrahimi TEST_ASSERT(ret == 0); 343*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ENTROPY_NV_SEED) 344*62c56f98SSadaf Ebrahimi /* If the NV seed functionality is enabled, there are two entropy 345*62c56f98SSadaf Ebrahimi * updates: before and after updating the NV seed. */ 346*62c56f98SSadaf Ebrahimi result *= 2; 347*62c56f98SSadaf Ebrahimi#endif 348*62c56f98SSadaf Ebrahimi TEST_ASSERT(weak.calls == (size_t) result); 349*62c56f98SSadaf Ebrahimi } else { 350*62c56f98SSadaf Ebrahimi TEST_ASSERT(ret == result); 351*62c56f98SSadaf Ebrahimi } 352*62c56f98SSadaf Ebrahimi 353*62c56f98SSadaf Ebrahimiexit: 354*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 355*62c56f98SSadaf Ebrahimi MD_PSA_DONE(); 356*62c56f98SSadaf Ebrahimi} 357*62c56f98SSadaf Ebrahimi/* END_CASE */ 358*62c56f98SSadaf Ebrahimi 359*62c56f98SSadaf Ebrahimi/* BEGIN_CASE */ 360*62c56f98SSadaf Ebrahimivoid entropy_calls(int strength1, int strength2, 361*62c56f98SSadaf Ebrahimi int threshold, int chunk_size, 362*62c56f98SSadaf Ebrahimi int result) 363*62c56f98SSadaf Ebrahimi{ 364*62c56f98SSadaf Ebrahimi /* 365*62c56f98SSadaf Ebrahimi * if result >= 0: result = expected number of calls to source 1 366*62c56f98SSadaf Ebrahimi * if result < 0: result = expected return code from mbedtls_entropy_func() 367*62c56f98SSadaf Ebrahimi */ 368*62c56f98SSadaf Ebrahimi 369*62c56f98SSadaf Ebrahimi mbedtls_entropy_context ctx; 370*62c56f98SSadaf Ebrahimi entropy_dummy_context dummy1 = { DUMMY_CONSTANT_LENGTH, chunk_size, 0 }; 371*62c56f98SSadaf Ebrahimi entropy_dummy_context dummy2 = { DUMMY_CONSTANT_LENGTH, chunk_size, 0 }; 372*62c56f98SSadaf Ebrahimi unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; 373*62c56f98SSadaf Ebrahimi int ret; 374*62c56f98SSadaf Ebrahimi 375*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 376*62c56f98SSadaf Ebrahimi entropy_clear_sources(&ctx); 377*62c56f98SSadaf Ebrahimi 378*62c56f98SSadaf Ebrahimi MD_PSA_INIT(); 379*62c56f98SSadaf Ebrahimi 380*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, 381*62c56f98SSadaf Ebrahimi &dummy1, threshold, 382*62c56f98SSadaf Ebrahimi strength1) == 0); 383*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_add_source(&ctx, entropy_dummy_source, 384*62c56f98SSadaf Ebrahimi &dummy2, threshold, 385*62c56f98SSadaf Ebrahimi strength2) == 0); 386*62c56f98SSadaf Ebrahimi 387*62c56f98SSadaf Ebrahimi ret = mbedtls_entropy_func(&ctx, buf, sizeof(buf)); 388*62c56f98SSadaf Ebrahimi 389*62c56f98SSadaf Ebrahimi if (result >= 0) { 390*62c56f98SSadaf Ebrahimi TEST_ASSERT(ret == 0); 391*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ENTROPY_NV_SEED) 392*62c56f98SSadaf Ebrahimi /* If the NV seed functionality is enabled, there are two entropy 393*62c56f98SSadaf Ebrahimi * updates: before and after updating the NV seed. */ 394*62c56f98SSadaf Ebrahimi result *= 2; 395*62c56f98SSadaf Ebrahimi#endif 396*62c56f98SSadaf Ebrahimi TEST_ASSERT(dummy1.calls == (size_t) result); 397*62c56f98SSadaf Ebrahimi } else { 398*62c56f98SSadaf Ebrahimi TEST_ASSERT(ret == result); 399*62c56f98SSadaf Ebrahimi } 400*62c56f98SSadaf Ebrahimi 401*62c56f98SSadaf Ebrahimiexit: 402*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 403*62c56f98SSadaf Ebrahimi MD_PSA_DONE(); 404*62c56f98SSadaf Ebrahimi} 405*62c56f98SSadaf Ebrahimi/* END_CASE */ 406*62c56f98SSadaf Ebrahimi 407*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO */ 408*62c56f98SSadaf Ebrahimivoid nv_seed_file_create() 409*62c56f98SSadaf Ebrahimi{ 410*62c56f98SSadaf Ebrahimi unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; 411*62c56f98SSadaf Ebrahimi 412*62c56f98SSadaf Ebrahimi memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE); 413*62c56f98SSadaf Ebrahimi 414*62c56f98SSadaf Ebrahimi TEST_ASSERT(write_nv_seed(buf, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 415*62c56f98SSadaf Ebrahimi} 416*62c56f98SSadaf Ebrahimi/* END_CASE */ 417*62c56f98SSadaf Ebrahimi 418*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_FS_IO:MBEDTLS_PLATFORM_NV_SEED_ALT */ 419*62c56f98SSadaf Ebrahimivoid entropy_nv_seed_std_io() 420*62c56f98SSadaf Ebrahimi{ 421*62c56f98SSadaf Ebrahimi unsigned char io_seed[MBEDTLS_ENTROPY_BLOCK_SIZE]; 422*62c56f98SSadaf Ebrahimi unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE]; 423*62c56f98SSadaf Ebrahimi 424*62c56f98SSadaf Ebrahimi memset(io_seed, 1, MBEDTLS_ENTROPY_BLOCK_SIZE); 425*62c56f98SSadaf Ebrahimi memset(check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE); 426*62c56f98SSadaf Ebrahimi 427*62c56f98SSadaf Ebrahimi mbedtls_platform_set_nv_seed(mbedtls_platform_std_nv_seed_read, 428*62c56f98SSadaf Ebrahimi mbedtls_platform_std_nv_seed_write); 429*62c56f98SSadaf Ebrahimi 430*62c56f98SSadaf Ebrahimi /* Check if platform NV read and write manipulate the same data */ 431*62c56f98SSadaf Ebrahimi TEST_ASSERT(write_nv_seed(io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 432*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_nv_seed_read(check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 433*62c56f98SSadaf Ebrahimi MBEDTLS_ENTROPY_BLOCK_SIZE); 434*62c56f98SSadaf Ebrahimi 435*62c56f98SSadaf Ebrahimi TEST_ASSERT(memcmp(io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 436*62c56f98SSadaf Ebrahimi 437*62c56f98SSadaf Ebrahimi memset(check_seed, 0, MBEDTLS_ENTROPY_BLOCK_SIZE); 438*62c56f98SSadaf Ebrahimi 439*62c56f98SSadaf Ebrahimi /* Check if platform NV write and raw read manipulate the same data */ 440*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_nv_seed_write(io_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 441*62c56f98SSadaf Ebrahimi MBEDTLS_ENTROPY_BLOCK_SIZE); 442*62c56f98SSadaf Ebrahimi TEST_ASSERT(read_nv_seed(check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 443*62c56f98SSadaf Ebrahimi 444*62c56f98SSadaf Ebrahimi TEST_ASSERT(memcmp(io_seed, check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 445*62c56f98SSadaf Ebrahimi} 446*62c56f98SSadaf Ebrahimi/* END_CASE */ 447*62c56f98SSadaf Ebrahimi 448*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:MBEDTLS_MD_C:MBEDTLS_ENTROPY_NV_SEED:MBEDTLS_PLATFORM_NV_SEED_ALT */ 449*62c56f98SSadaf Ebrahimivoid entropy_nv_seed(data_t *read_seed) 450*62c56f98SSadaf Ebrahimi{ 451*62c56f98SSadaf Ebrahimi#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) 452*62c56f98SSadaf Ebrahimi const mbedtls_md_info_t *md_info = 453*62c56f98SSadaf Ebrahimi mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); 454*62c56f98SSadaf Ebrahimi#elif defined(MBEDTLS_ENTROPY_SHA256_ACCUMULATOR) 455*62c56f98SSadaf Ebrahimi const mbedtls_md_info_t *md_info = 456*62c56f98SSadaf Ebrahimi mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); 457*62c56f98SSadaf Ebrahimi#else 458*62c56f98SSadaf Ebrahimi#error "Unsupported entropy accumulator" 459*62c56f98SSadaf Ebrahimi#endif 460*62c56f98SSadaf Ebrahimi mbedtls_md_context_t accumulator; 461*62c56f98SSadaf Ebrahimi mbedtls_entropy_context ctx; 462*62c56f98SSadaf Ebrahimi int (*original_mbedtls_nv_seed_read)(unsigned char *buf, size_t buf_len) = 463*62c56f98SSadaf Ebrahimi mbedtls_nv_seed_read; 464*62c56f98SSadaf Ebrahimi int (*original_mbedtls_nv_seed_write)(unsigned char *buf, size_t buf_len) = 465*62c56f98SSadaf Ebrahimi mbedtls_nv_seed_write; 466*62c56f98SSadaf Ebrahimi 467*62c56f98SSadaf Ebrahimi unsigned char header[2]; 468*62c56f98SSadaf Ebrahimi unsigned char entropy[MBEDTLS_ENTROPY_BLOCK_SIZE]; 469*62c56f98SSadaf Ebrahimi unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; 470*62c56f98SSadaf Ebrahimi unsigned char empty[MBEDTLS_ENTROPY_BLOCK_SIZE]; 471*62c56f98SSadaf Ebrahimi unsigned char check_seed[MBEDTLS_ENTROPY_BLOCK_SIZE]; 472*62c56f98SSadaf Ebrahimi unsigned char check_entropy[MBEDTLS_ENTROPY_BLOCK_SIZE]; 473*62c56f98SSadaf Ebrahimi 474*62c56f98SSadaf Ebrahimi memset(entropy, 0, MBEDTLS_ENTROPY_BLOCK_SIZE); 475*62c56f98SSadaf Ebrahimi memset(buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE); 476*62c56f98SSadaf Ebrahimi memset(empty, 0, MBEDTLS_ENTROPY_BLOCK_SIZE); 477*62c56f98SSadaf Ebrahimi memset(check_seed, 2, MBEDTLS_ENTROPY_BLOCK_SIZE); 478*62c56f98SSadaf Ebrahimi memset(check_entropy, 3, MBEDTLS_ENTROPY_BLOCK_SIZE); 479*62c56f98SSadaf Ebrahimi 480*62c56f98SSadaf Ebrahimi // Make sure we read/write NV seed from our buffers 481*62c56f98SSadaf Ebrahimi mbedtls_platform_set_nv_seed(buffer_nv_seed_read, buffer_nv_seed_write); 482*62c56f98SSadaf Ebrahimi 483*62c56f98SSadaf Ebrahimi mbedtls_md_init(&accumulator); 484*62c56f98SSadaf Ebrahimi mbedtls_entropy_init(&ctx); 485*62c56f98SSadaf Ebrahimi entropy_clear_sources(&ctx); 486*62c56f98SSadaf Ebrahimi 487*62c56f98SSadaf Ebrahimi MD_PSA_INIT(); 488*62c56f98SSadaf Ebrahimi 489*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_add_source(&ctx, mbedtls_nv_seed_poll, NULL, 490*62c56f98SSadaf Ebrahimi MBEDTLS_ENTROPY_BLOCK_SIZE, 491*62c56f98SSadaf Ebrahimi MBEDTLS_ENTROPY_SOURCE_STRONG) == 0); 492*62c56f98SSadaf Ebrahimi 493*62c56f98SSadaf Ebrahimi // Set the initial NV seed to read 494*62c56f98SSadaf Ebrahimi TEST_ASSERT(read_seed->len >= MBEDTLS_ENTROPY_BLOCK_SIZE); 495*62c56f98SSadaf Ebrahimi memcpy(buffer_seed, read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE); 496*62c56f98SSadaf Ebrahimi 497*62c56f98SSadaf Ebrahimi // Do an entropy run 498*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_func(&ctx, entropy, sizeof(entropy)) == 0); 499*62c56f98SSadaf Ebrahimi // Determine what should have happened with manual entropy internal logic 500*62c56f98SSadaf Ebrahimi 501*62c56f98SSadaf Ebrahimi // Init accumulator 502*62c56f98SSadaf Ebrahimi header[1] = MBEDTLS_ENTROPY_BLOCK_SIZE; 503*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_setup(&accumulator, md_info, 0) == 0); 504*62c56f98SSadaf Ebrahimi 505*62c56f98SSadaf Ebrahimi // First run for updating write_seed 506*62c56f98SSadaf Ebrahimi header[0] = 0; 507*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_starts(&accumulator) == 0); 508*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_update(&accumulator, header, 2) == 0); 509*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_update(&accumulator, 510*62c56f98SSadaf Ebrahimi read_seed->x, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 511*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_finish(&accumulator, buf) == 0); 512*62c56f98SSadaf Ebrahimi 513*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_starts(&accumulator) == 0); 514*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_update(&accumulator, 515*62c56f98SSadaf Ebrahimi buf, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 516*62c56f98SSadaf Ebrahimi 517*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md(md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE, 518*62c56f98SSadaf Ebrahimi check_seed) == 0); 519*62c56f98SSadaf Ebrahimi 520*62c56f98SSadaf Ebrahimi // Second run for actual entropy (triggers mbedtls_entropy_update_nv_seed) 521*62c56f98SSadaf Ebrahimi header[0] = MBEDTLS_ENTROPY_SOURCE_MANUAL; 522*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_update(&accumulator, header, 2) == 0); 523*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_update(&accumulator, 524*62c56f98SSadaf Ebrahimi empty, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 525*62c56f98SSadaf Ebrahimi 526*62c56f98SSadaf Ebrahimi header[0] = 0; 527*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_update(&accumulator, header, 2) == 0); 528*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_update(&accumulator, 529*62c56f98SSadaf Ebrahimi check_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 530*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md_finish(&accumulator, buf) == 0); 531*62c56f98SSadaf Ebrahimi 532*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_md(md_info, buf, MBEDTLS_ENTROPY_BLOCK_SIZE, 533*62c56f98SSadaf Ebrahimi check_entropy) == 0); 534*62c56f98SSadaf Ebrahimi 535*62c56f98SSadaf Ebrahimi // Check result of both NV file and entropy received with the manual calculations 536*62c56f98SSadaf Ebrahimi TEST_ASSERT(memcmp(check_seed, buffer_seed, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 537*62c56f98SSadaf Ebrahimi TEST_ASSERT(memcmp(check_entropy, entropy, MBEDTLS_ENTROPY_BLOCK_SIZE) == 0); 538*62c56f98SSadaf Ebrahimi 539*62c56f98SSadaf Ebrahimiexit: 540*62c56f98SSadaf Ebrahimi mbedtls_md_free(&accumulator); 541*62c56f98SSadaf Ebrahimi mbedtls_entropy_free(&ctx); 542*62c56f98SSadaf Ebrahimi mbedtls_nv_seed_read = original_mbedtls_nv_seed_read; 543*62c56f98SSadaf Ebrahimi mbedtls_nv_seed_write = original_mbedtls_nv_seed_write; 544*62c56f98SSadaf Ebrahimi MD_PSA_DONE(); 545*62c56f98SSadaf Ebrahimi} 546*62c56f98SSadaf Ebrahimi/* END_CASE */ 547*62c56f98SSadaf Ebrahimi 548*62c56f98SSadaf Ebrahimi/* BEGIN_CASE depends_on:ENTROPY_HAVE_STRONG:MBEDTLS_SELF_TEST */ 549*62c56f98SSadaf Ebrahimivoid entropy_selftest(int result) 550*62c56f98SSadaf Ebrahimi{ 551*62c56f98SSadaf Ebrahimi MD_PSA_INIT(); 552*62c56f98SSadaf Ebrahimi 553*62c56f98SSadaf Ebrahimi TEST_ASSERT(mbedtls_entropy_self_test(1) == result); 554*62c56f98SSadaf Ebrahimi 555*62c56f98SSadaf Ebrahimiexit: 556*62c56f98SSadaf Ebrahimi MD_PSA_DONE(); 557*62c56f98SSadaf Ebrahimi} 558*62c56f98SSadaf Ebrahimi/* END_CASE */ 559