mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
FIPS Revalidation
1. Add second RNG initialization API to let caller pass in a nonce.
This commit is contained in:
@ -175,10 +175,8 @@ int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
|
|||||||
#define OUTPUT_BLOCK_LEN (WC_SHA256_DIGEST_SIZE)
|
#define OUTPUT_BLOCK_LEN (WC_SHA256_DIGEST_SIZE)
|
||||||
#define MAX_REQUEST_LEN (0x10000)
|
#define MAX_REQUEST_LEN (0x10000)
|
||||||
#define RESEED_INTERVAL WC_RESEED_INTERVAL
|
#define RESEED_INTERVAL WC_RESEED_INTERVAL
|
||||||
#define SECURITY_STRENGTH (256)
|
#define SECURITY_STRENGTH (2048)
|
||||||
#define ENTROPY_SZ (SECURITY_STRENGTH/8)
|
#define ENTROPY_SZ (SECURITY_STRENGTH/8)
|
||||||
#define NONCE_SZ (ENTROPY_SZ/2)
|
|
||||||
#define ENTROPY_NONCE_SZ (ENTROPY_SZ+NONCE_SZ)
|
|
||||||
|
|
||||||
/* Internal return codes */
|
/* Internal return codes */
|
||||||
#define DRBG_SUCCESS 0
|
#define DRBG_SUCCESS 0
|
||||||
@ -532,12 +530,19 @@ static int Hash_DRBG_Uninstantiate(DRBG* drbg)
|
|||||||
/* End NIST DRBG Code */
|
/* End NIST DRBG Code */
|
||||||
|
|
||||||
|
|
||||||
int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
|
static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
|
||||||
|
void* heap, int devId)
|
||||||
{
|
{
|
||||||
int ret = RNG_FAILURE_E;
|
int ret = RNG_FAILURE_E;
|
||||||
|
word32 entropySz = ENTROPY_SZ;
|
||||||
|
|
||||||
|
(void)nonce;
|
||||||
|
(void)nonceSz;
|
||||||
|
|
||||||
if (rng == NULL)
|
if (rng == NULL)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
if (nonce == NULL && nonceSz != 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
#ifdef WOLFSSL_HEAP_TEST
|
#ifdef WOLFSSL_HEAP_TEST
|
||||||
rng->heap = (void*)WOLFSSL_HEAP_TEST;
|
rng->heap = (void*)WOLFSSL_HEAP_TEST;
|
||||||
@ -580,8 +585,11 @@ int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
|
|||||||
ret = 0; /* success */
|
ret = 0; /* success */
|
||||||
#else
|
#else
|
||||||
#ifdef HAVE_HASHDRBG
|
#ifdef HAVE_HASHDRBG
|
||||||
|
if (nonceSz == 0)
|
||||||
|
entropySz += (entropySz / 2);
|
||||||
|
|
||||||
if (wc_RNG_HealthTestLocal(0) == 0) {
|
if (wc_RNG_HealthTestLocal(0) == 0) {
|
||||||
DECLARE_VAR(entropy, byte, ENTROPY_NONCE_SZ, rng->heap);
|
DECLARE_VAR(entropy, byte, entropySz, rng->heap);
|
||||||
|
|
||||||
rng->drbg =
|
rng->drbg =
|
||||||
(struct DRBG*)XMALLOC(sizeof(DRBG), rng->heap,
|
(struct DRBG*)XMALLOC(sizeof(DRBG), rng->heap,
|
||||||
@ -589,18 +597,15 @@ int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
|
|||||||
if (rng->drbg == NULL) {
|
if (rng->drbg == NULL) {
|
||||||
ret = MEMORY_E;
|
ret = MEMORY_E;
|
||||||
}
|
}
|
||||||
/* This doesn't use a separate nonce. The entropy input will be
|
else if (wc_GenerateSeed(&rng->seed, entropy, entropySz) == 0 &&
|
||||||
* the default size plus the size of the nonce making the seed
|
Hash_DRBG_Instantiate(rng->drbg, entropy, entropySz,
|
||||||
* size. */
|
nonce, nonceSz, rng->heap, devId) == DRBG_SUCCESS) {
|
||||||
else if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 &&
|
|
||||||
Hash_DRBG_Instantiate(rng->drbg, entropy, ENTROPY_NONCE_SZ,
|
|
||||||
NULL, 0, rng->heap, devId) == DRBG_SUCCESS) {
|
|
||||||
ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
|
ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = DRBG_FAILURE;
|
ret = DRBG_FAILURE;
|
||||||
|
|
||||||
ForceZero(entropy, ENTROPY_NONCE_SZ);
|
ForceZero(entropy, entropySz);
|
||||||
FREE_VAR(entropy, rng->heap);
|
FREE_VAR(entropy, rng->heap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -627,9 +632,29 @@ int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int wc_InitRng(WC_RNG* rng)
|
int wc_InitRng(WC_RNG* rng)
|
||||||
{
|
{
|
||||||
return wc_InitRng_ex(rng, NULL, INVALID_DEVID);
|
return _InitRng(rng, NULL, 0, NULL, INVALID_DEVID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId)
|
||||||
|
{
|
||||||
|
return _InitRng(rng, NULL, 0, heap, devId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz)
|
||||||
|
{
|
||||||
|
return _InitRng(rng, nonce, nonceSz, NULL, INVALID_DEVID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz,
|
||||||
|
void* heap, int devId)
|
||||||
|
{
|
||||||
|
return _InitRng(rng, nonce, nonceSz, heap, devId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -752,6 +777,20 @@ int wc_FreeRng(WC_RNG* rng)
|
|||||||
int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
|
int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
|
||||||
const byte* entropyB, word32 entropyBSz,
|
const byte* entropyB, word32 entropyBSz,
|
||||||
byte* output, word32 outputSz)
|
byte* output, word32 outputSz)
|
||||||
|
{
|
||||||
|
return wc_RNG_HealthTest_ex(reseed, NULL, 0,
|
||||||
|
entropyA, entropyASz,
|
||||||
|
entropyB, entropyBSz,
|
||||||
|
output, outputSz,
|
||||||
|
NULL, INVALID_DEVID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,
|
||||||
|
const byte* entropyA, word32 entropyASz,
|
||||||
|
const byte* entropyB, word32 entropyBSz,
|
||||||
|
byte* output, word32 outputSz,
|
||||||
|
void* heap, int devId)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
DRBG* drbg;
|
DRBG* drbg;
|
||||||
@ -780,8 +819,8 @@ int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
|
|||||||
drbg = &drbg_var;
|
drbg = &drbg_var;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Hash_DRBG_Instantiate(drbg, entropyA, entropyASz, NULL, 0, NULL,
|
if (Hash_DRBG_Instantiate(drbg, entropyA, entropyASz, nonce, nonceSz,
|
||||||
INVALID_DEVID) != 0) {
|
heap, devId) != 0) {
|
||||||
goto exit_rng_ht;
|
goto exit_rng_ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -847,8 +886,9 @@ const byte outputA[] = {
|
|||||||
const byte entropyB[] = {
|
const byte entropyB[] = {
|
||||||
0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
|
0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
|
||||||
0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
|
0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
|
||||||
0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, 0x85, 0x81, 0xf9, 0x31,
|
0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, /* nonce next */
|
||||||
0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 0xdb, 0xcb, 0xcc, 0x2e
|
0x85, 0x81, 0xf9, 0x31, 0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d,
|
||||||
|
0xdb, 0xcb, 0xcc, 0x2e
|
||||||
};
|
};
|
||||||
|
|
||||||
const byte outputB[] = {
|
const byte outputB[] = {
|
||||||
@ -902,6 +942,23 @@ static int wc_RNG_HealthTestLocal(int reseed)
|
|||||||
RNG_HEALTH_TEST_CHECK_SIZE) != 0)
|
RNG_HEALTH_TEST_CHECK_SIZE) != 0)
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The previous test cases use a large seed instead of a seed and nonce.
|
||||||
|
* entropyB is actually from a test case with a seed and nonce, and
|
||||||
|
* just concatenates them. The pivot point between seed and nonce is
|
||||||
|
* byte 32, feed them into the health test separately. */
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_RNG_HealthTest_ex(0,
|
||||||
|
entropyB + 32, sizeof(entropyB) - 32,
|
||||||
|
entropyB, 32,
|
||||||
|
NULL, 0,
|
||||||
|
check, RNG_HEALTH_TEST_CHECK_SIZE,
|
||||||
|
NULL, INVALID_DEVID);
|
||||||
|
if (ret == 0) {
|
||||||
|
if (ConstantCompare(check, outputB, sizeof(outputB)) != 0)
|
||||||
|
ret = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSL_SMALL_STACK
|
#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
@ -181,6 +181,9 @@ int wc_GenerateSeed(OS_Seed* os, byte* seed, word32 sz);
|
|||||||
|
|
||||||
WOLFSSL_API int wc_InitRng(WC_RNG*);
|
WOLFSSL_API int wc_InitRng(WC_RNG*);
|
||||||
WOLFSSL_API int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId);
|
WOLFSSL_API int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId);
|
||||||
|
WOLFSSL_API int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz);
|
||||||
|
WOLFSSL_API int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz,
|
||||||
|
void* heap, int devId);
|
||||||
WOLFSSL_API int wc_RNG_GenerateBlock(WC_RNG*, byte*, word32 sz);
|
WOLFSSL_API int wc_RNG_GenerateBlock(WC_RNG*, byte*, word32 sz);
|
||||||
WOLFSSL_API int wc_RNG_GenerateByte(WC_RNG*, byte*);
|
WOLFSSL_API int wc_RNG_GenerateByte(WC_RNG*, byte*);
|
||||||
WOLFSSL_API int wc_FreeRng(WC_RNG*);
|
WOLFSSL_API int wc_FreeRng(WC_RNG*);
|
||||||
@ -193,6 +196,12 @@ WOLFSSL_API int wc_FreeRng(WC_RNG*);
|
|||||||
const byte* entropyA, word32 entropyASz,
|
const byte* entropyA, word32 entropyASz,
|
||||||
const byte* entropyB, word32 entropyBSz,
|
const byte* entropyB, word32 entropyBSz,
|
||||||
byte* output, word32 outputSz);
|
byte* output, word32 outputSz);
|
||||||
|
WOLFSSL_API int wc_RNG_HealthTest_ex(int reseed,
|
||||||
|
const byte* nonce, word32 nonceSz,
|
||||||
|
const byte* entropyA, word32 entropyASz,
|
||||||
|
const byte* entropyB, word32 entropyBSz,
|
||||||
|
byte* output, word32 outputSz,
|
||||||
|
void* heap, int devId);
|
||||||
#endif /* HAVE_HASHDRBG */
|
#endif /* HAVE_HASHDRBG */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
Reference in New Issue
Block a user