static int test_robustness(void) { u8_t entropy[32] = {0}; /* value not important */ u8_t output[32]; TCCtrPrng_t ctx; int rc; /* show that the CTR PRNG is robust to invalid inputs */ tc_ctr_prng_uninstantiate(0); rc = tc_ctr_prng_generate(&ctx, 0, 0, 0, 0); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } rc = tc_ctr_prng_generate(0, 0, 0, output, sizeof(output)); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } rc = tc_ctr_prng_generate(0, 0, 0, 0, 0); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } rc = tc_ctr_prng_reseed(&ctx, 0, 0, 0, 0); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } /* too little entropy */ rc = tc_ctr_prng_reseed(&ctx, entropy, sizeof(entropy) - 1, 0, 0); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } rc = tc_ctr_prng_reseed(0, entropy, sizeof(entropy), 0, 0); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } rc = tc_ctr_prng_reseed(0, 0, 0, 0, 0); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } rc = tc_ctr_prng_init(&ctx, 0, 0, 0, 0); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } /* too little entropy */ rc = tc_ctr_prng_init(&ctx, entropy, sizeof(entropy) - 1, 0, 0); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } rc = tc_ctr_prng_init(0, entropy, sizeof(entropy), 0, 0); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } rc = tc_ctr_prng_init(0, 0, 0, 0, 0); if (rc != TC_CRYPTO_FAIL) { rc = TC_FAIL; goto exit_test; } rc = TC_PASS; exit_test: return rc; }
static int32_t test_robustness(void) { int32_t result = TC_PASS; int32_t ret; uint8_t entropy[32U] = {0U}; /* value not important */ uint8_t output[32]; TCCtrPrng_t ctx; /* show that the CTR PRNG is robust to invalid inputs */ tc_ctr_prng_uninstantiate(0); ret = tc_ctr_prng_generate(&ctx, 0, 0, 0, 0); if (0 != ret) { result = TC_FAIL; goto exitTest; } ret = tc_ctr_prng_generate(0, 0, 0, output, sizeof output); if (0 != ret) { result = TC_FAIL; goto exitTest; } ret = tc_ctr_prng_generate(0, 0, 0, 0, 0); if (0 != ret) { result = TC_FAIL; goto exitTest; } ret = tc_ctr_prng_reseed(&ctx, 0, 0, 0, 0); if (0 != ret) { result = TC_FAIL; goto exitTest; } /* too little entropy */ ret = tc_ctr_prng_reseed(&ctx, entropy, (sizeof entropy) - 1U, 0, 0); if (0 != ret) { result = TC_FAIL; goto exitTest; } ret = tc_ctr_prng_reseed(0, entropy, sizeof entropy, 0, 0); if (0 != ret) { result = TC_FAIL; goto exitTest; } ret = tc_ctr_prng_reseed(0, 0, 0, 0, 0); if (0 != ret) { result = TC_FAIL; goto exitTest; } ret = tc_ctr_prng_init(&ctx, 0, 0, 0, 0); if (0 != ret) { result = TC_FAIL; goto exitTest; } /* too little entropy */ ret = tc_ctr_prng_init(&ctx, entropy, (sizeof entropy) - 1U, 0, 0); if (0 != ret) { result = TC_FAIL; goto exitTest; } ret = tc_ctr_prng_init(0, entropy, sizeof entropy, 0, 0); if (0 != ret) { result = TC_FAIL; goto exitTest; } ret = tc_ctr_prng_init(0, 0, 0, 0, 0); if (0 != ret) { result = TC_FAIL; goto exitTest; } exitTest: if (TC_FAIL == result) { TC_ERROR("CTR PRNG reseed tests failed\n"); } return result; }
static int test_reseed(void) { u8_t expectedV1[] = {0x7E, 0xE3, 0xA0, 0xCB, 0x6D, 0x5C, 0x4B, 0xC2, 0x4B, 0x7E, 0x3C, 0x48, 0x88, 0xC3, 0x69, 0x70}; u8_t expectedV2[] = {0x5E, 0xC1, 0x84, 0xED, 0x45, 0x76, 0x67, 0xEC, 0x7B, 0x4C, 0x08, 0x7E, 0xB0, 0xF9, 0x55, 0x4E}; u8_t extra_input[32] = {0}; u8_t entropy[32] = {0}; /* value not important */ u8_t output[32]; TCCtrPrng_t ctx; u32_t i; int rc; rc = tc_ctr_prng_init(&ctx, entropy, sizeof(entropy), 0, 0U); if (rc != TC_CRYPTO_SUCCESS) { rc = TC_FAIL; goto exit_test; } /* force internal state to max allowed count */ ctx.reseedCount = 0x1000000000000ULL; rc = tc_ctr_prng_generate(&ctx, 0, 0, output, sizeof(output)); if (rc != TC_CRYPTO_SUCCESS) { rc = TC_FAIL; goto exit_test; } /* expect further attempts to fail due to reaching reseed threshold */ rc = tc_ctr_prng_generate(&ctx, 0, 0, output, sizeof(output)); if (rc != TC_CTR_PRNG_RESEED_REQ) { rc = TC_FAIL; goto exit_test; } /* reseed and confirm generate works again * make entropy different from original value - not really important * for the purpose of this test */ memset(entropy, 0xFF, sizeof(entropy)); rc = tc_ctr_prng_reseed(&ctx, entropy, sizeof(entropy), extra_input, sizeof(extra_input)); if (rc != TC_CRYPTO_SUCCESS) { rc = TC_FAIL; goto exit_test; } rc = tc_ctr_prng_generate(&ctx, 0, 0, output, sizeof(output)); if (rc != TC_CRYPTO_SUCCESS) { rc = TC_FAIL; goto exit_test; } /* confirm entropy and additional_input are being used correctly * first, entropy only */ memset(&ctx, 0x0, sizeof(ctx)); for (i = 0; i < sizeof(entropy); i++) { entropy[i] = i; } rc = tc_ctr_prng_reseed(&ctx, entropy, sizeof(entropy), 0, 0); if (rc != 1) { rc = TC_FAIL; goto exit_test; } if (memcmp(ctx.V, expectedV1, sizeof(expectedV1))) { rc = TC_FAIL; goto exit_test; } /* now, entropy and additional_input */ memset(&ctx, 0x00, sizeof(ctx)); for (i = 0; i < sizeof(extra_input); i++) { extra_input[i] = i * 2; } rc = tc_ctr_prng_reseed(&ctx, entropy, sizeof(entropy), extra_input, sizeof(extra_input)); if (rc != 1) { rc = TC_FAIL; goto exit_test; } if (memcmp(ctx.V, expectedV2, sizeof(expectedV2))) { rc = TC_FAIL; goto exit_test; } rc = TC_PASS; exit_test: return rc; }
static int32_t test_reseed(void) { int32_t result = TC_PASS; uint8_t entropy[32U] = {0U}; /* value not important */ uint8_t additional_input[32] = {0U}; uint8_t output[32]; TCCtrPrng_t ctx; int32_t ret; uint32_t i; (void)tc_ctr_prng_init(&ctx, entropy, sizeof entropy, 0, 0U); /* force internal state to max allowed count */ ctx.reseedCount = 0x1000000000000ULL; ret = tc_ctr_prng_generate(&ctx, 0, 0, output, sizeof output); if (1 != ret) { result = TC_FAIL; goto exitTest; } /* expect further attempts to fail due to reaching reseed threshold */ ret = tc_ctr_prng_generate(&ctx, 0, 0, output, sizeof output); if (-1 != ret) { result = TC_FAIL; goto exitTest; } /* reseed and confirm generate works again */ /* make entropy different from original value - not really important for the purpose of this test */ memset(entropy, 0xFF, sizeof entropy); ret = tc_ctr_prng_reseed(&ctx, entropy, sizeof entropy, additional_input, sizeof additional_input); if (1 != ret) { result = TC_FAIL; goto exitTest; } ret = tc_ctr_prng_generate(&ctx, 0, 0, output, sizeof output); if (1 != ret) { result = TC_FAIL; goto exitTest; } /* confirm entropy and additional_input are being used correctly */ /* first, entropy only */ memset(&ctx, 0x0, sizeof ctx); for (i = 0U; i < sizeof entropy; i++) { entropy[i] = i; } ret = tc_ctr_prng_reseed(&ctx, entropy, sizeof entropy, 0, 0U); if (1 != ret) { result = TC_FAIL; goto exitTest; } { uint8_t expectedV[] = {0x7EU, 0xE3U, 0xA0U, 0xCBU, 0x6DU, 0x5CU, 0x4BU, 0xC2U, 0x4BU, 0x7EU, 0x3CU, 0x48U, 0x88U, 0xC3U, 0x69U, 0x70U}; for (i = 0U; i < sizeof expectedV; i++) { if (ctx.V[i] != expectedV[i]) { result = TC_FAIL; goto exitTest; } } } /* now, entropy and additional_input */ memset(&ctx, 0x0, sizeof ctx); for (i = 0U; i < sizeof additional_input; i++) { additional_input[i] = i * 2U; } ret = tc_ctr_prng_reseed(&ctx, entropy, sizeof entropy, additional_input, sizeof additional_input); if (1 != ret) { result = TC_FAIL; goto exitTest; } { uint8_t expectedV[] = {0x5EU, 0xC1U, 0x84U, 0xEDU, 0x45U, 0x76U, 0x67U, 0xECU, 0x7BU, 0x4CU, 0x08U, 0x7EU, 0xB0U, 0xF9U, 0x55U, 0x4EU}; for (i = 0U; i < sizeof expectedV; i++) { if (ctx.V[i] != expectedV[i]) { result = TC_FAIL; goto exitTest; } } } exitTest: if (TC_FAIL == result) { TC_ERROR("CTR PRNG reseed tests failed\n"); } return result; }