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