mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-31 11:17:29 +02:00
@@ -42,6 +42,9 @@
|
|||||||
#define WOLFSSL_VALIDATE_ECC_IMPORT
|
#define WOLFSSL_VALIDATE_ECC_IMPORT
|
||||||
#define WOLFSSL_VALIDATE_FFC_IMPORT
|
#define WOLFSSL_VALIDATE_FFC_IMPORT
|
||||||
#define HAVE_FFDHE_Q
|
#define HAVE_FFDHE_Q
|
||||||
|
#define WOLFSSL_AESNI
|
||||||
|
#define HAVE_INTEL_RDSEED
|
||||||
|
#define FORCE_FAILURE_RDSEED
|
||||||
#endif /* FIPS v2 */
|
#endif /* FIPS v2 */
|
||||||
#else
|
#else
|
||||||
/* Enables blinding mode, to prevent timing attacks */
|
/* Enables blinding mode, to prevent timing attacks */
|
||||||
|
@@ -161,6 +161,8 @@ linuxv2)
|
|||||||
CRYPT_VERSION=$LINUXV2_CRYPT_VERSION
|
CRYPT_VERSION=$LINUXV2_CRYPT_VERSION
|
||||||
CRYPT_INC_PATH=wolfssl/wolfcrypt
|
CRYPT_INC_PATH=wolfssl/wolfcrypt
|
||||||
CRYPT_SRC_PATH=wolfcrypt/src
|
CRYPT_SRC_PATH=wolfcrypt/src
|
||||||
|
# Replace the WC_MODS list for now. Do not want to copy over random.c yet.
|
||||||
|
WC_MODS=( aes des3 sha sha256 sha512 rsa hmac )
|
||||||
WC_MODS+=( cmac dh ecc )
|
WC_MODS+=( cmac dh ecc )
|
||||||
FIPS_SRCS+=( wolfcrypt_first.c wolfcrypt_last.c )
|
FIPS_SRCS+=( wolfcrypt_first.c wolfcrypt_last.c )
|
||||||
FIPS_INCS=( fips.h )
|
FIPS_INCS=( fips.h )
|
||||||
|
@@ -89,13 +89,12 @@ int wc_RNG_GenerateByte(WC_RNG* rng, byte* b)
|
|||||||
return FreeRng_fips(rng);
|
return FreeRng_fips(rng);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wc_RNG_HealthTest(int reseed,
|
int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz,
|
||||||
const byte* entropyA, word32 entropyASz,
|
const byte* seedB, word32 seedBSz,
|
||||||
const byte* entropyB, word32 entropyBSz,
|
byte* output, word32 outputSz)
|
||||||
byte* output, word32 outputSz)
|
|
||||||
{
|
{
|
||||||
return RNG_HealthTest_fips(reseed, entropyA, entropyASz,
|
return RNG_HealthTest_fips(reseed, seedA, seedASz,
|
||||||
entropyB, entropyBSz, output, outputSz);
|
seedB, seedBSz, output, outputSz);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_HASHDRBG */
|
#endif /* HAVE_HASHDRBG */
|
||||||
|
|
||||||
@@ -177,9 +176,68 @@ 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 (2048)
|
|
||||||
#define ENTROPY_SZ (SECURITY_STRENGTH/8)
|
|
||||||
#define MAX_ENTROPY_SZ (ENTROPY_SZ + ENTROPY_SZ/2)
|
/* For FIPS builds, the user should not be adjusting the values. */
|
||||||
|
#if defined(HAVE_FIPS) && \
|
||||||
|
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
|
||||||
|
#if defined(RNG_SECURITY_STRENGTH) \
|
||||||
|
|| defined(ENTROPY_SCALE_FACTOR) \
|
||||||
|
|| defined(SEED_BLOCK_SZ)
|
||||||
|
|
||||||
|
#error "Do not change the RNG parameters for FIPS builds."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* The security strength for the RNG is the target number of bits of
|
||||||
|
* entropy you are looking for in a seed. */
|
||||||
|
#ifndef RNG_SECURITY_STRENGTH
|
||||||
|
#if defined(HAVE_FIPS) && \
|
||||||
|
defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
|
||||||
|
/* SHA-256 requires a minimum of 256-bits of entropy. The goal
|
||||||
|
* of 1024 will provide 4 times that. */
|
||||||
|
#define RNG_SECURITY_STRENGTH (1024)
|
||||||
|
#else
|
||||||
|
/* If not using FIPS or using old FIPS, set the number down a bit.
|
||||||
|
* More is better, but more is also slower. */
|
||||||
|
#define RNG_SECURITY_STRENGTH (256)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ENTROPY_SCALE_FACTOR
|
||||||
|
/* The entropy scale factor should be the whole number inverse of the
|
||||||
|
* minimum bits of entropy per bit of NDRNG output. */
|
||||||
|
#if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
|
||||||
|
/* The value of 2 applies to Intel's RDSEED which provides about
|
||||||
|
* 0.5 bits minimum of entropy per bit. */
|
||||||
|
#define ENTROPY_SCALE_FACTOR 2
|
||||||
|
#else
|
||||||
|
/* Setting the default to 1. */
|
||||||
|
#define ENTROPY_SCALE_FACTOR 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEED_BLOCK_SZ
|
||||||
|
/* The seed block size, is the size of the output of the underlying NDRNG.
|
||||||
|
* This value is used for testing the output of the NDRNG. */
|
||||||
|
#if defined(HAVE_INTEL_RDSEED) || defined(HAVE_INTEL_RDRAND)
|
||||||
|
/* RDSEED outputs in blocks of 64-bits. */
|
||||||
|
#define SEED_BLOCK_SZ sizeof(word64)
|
||||||
|
#else
|
||||||
|
/* Setting the default to 4. */
|
||||||
|
#define SEED_BLOCK_SZ 4
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SEED_SZ (RNG_SECURITY_STRENGTH*ENTROPY_SCALE_FACTOR/8)
|
||||||
|
|
||||||
|
/* The maximum seed size will be the seed size plus a seed block for the
|
||||||
|
* test, and an additional half of the seed size. This additional half
|
||||||
|
* is in case the user does not supply a nonce. A nonce will be obtained
|
||||||
|
* from the NDRNG. */
|
||||||
|
#define MAX_SEED_SZ (SEED_SZ + SEED_SZ/2 + SEED_BLOCK_SZ)
|
||||||
|
|
||||||
|
|
||||||
/* Internal return codes */
|
/* Internal return codes */
|
||||||
#define DRBG_SUCCESS 0
|
#define DRBG_SUCCESS 0
|
||||||
@@ -310,19 +368,19 @@ static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
|
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
|
||||||
static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
|
static int Hash_DRBG_Reseed(DRBG* drbg, const byte* seed, word32 seedSz)
|
||||||
{
|
{
|
||||||
byte seed[DRBG_SEED_LEN];
|
byte newV[DRBG_SEED_LEN];
|
||||||
|
|
||||||
XMEMSET(seed, 0, DRBG_SEED_LEN);
|
XMEMSET(newV, 0, DRBG_SEED_LEN);
|
||||||
|
|
||||||
if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
|
if (Hash_df(drbg, newV, sizeof(newV), drbgReseed,
|
||||||
entropy, entropySz) != DRBG_SUCCESS) {
|
drbg->V, sizeof(drbg->V), seed, seedSz) != DRBG_SUCCESS) {
|
||||||
return DRBG_FAILURE;
|
return DRBG_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
XMEMCPY(drbg->V, seed, sizeof(drbg->V));
|
XMEMCPY(drbg->V, newV, sizeof(drbg->V));
|
||||||
ForceZero(seed, sizeof(seed));
|
ForceZero(newV, sizeof(newV));
|
||||||
|
|
||||||
if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
|
if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
|
||||||
sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
|
sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
|
||||||
@@ -336,13 +394,13 @@ static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */
|
/* Returns: DRBG_SUCCESS and DRBG_FAILURE or BAD_FUNC_ARG on fail */
|
||||||
int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy, word32 entropySz)
|
int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* seed, word32 seedSz)
|
||||||
{
|
{
|
||||||
if (rng == NULL || entropy == NULL) {
|
if (rng == NULL || seed == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Hash_DRBG_Reseed(rng->drbg, entropy, entropySz);
|
return Hash_DRBG_Reseed(rng->drbg, seed, seedSz);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WC_INLINE void array_add_one(byte* data, word32 dataSz)
|
static WC_INLINE void array_add_one(byte* data, word32 dataSz)
|
||||||
@@ -572,6 +630,29 @@ static int Hash_DRBG_Uninstantiate(DRBG* drbg)
|
|||||||
|
|
||||||
return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
|
return (compareSum == 0) ? DRBG_SUCCESS : DRBG_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wc_RNG_TestSeed(const byte* seed, word32 seedSz)
|
||||||
|
{
|
||||||
|
int ret = DRBG_SUCCESS;
|
||||||
|
|
||||||
|
/* Check the seed for duplicate words. */
|
||||||
|
word32 seedIdx = 0;
|
||||||
|
word32 scratchSz = min(SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ);
|
||||||
|
|
||||||
|
while (seedIdx < seedSz - SEED_BLOCK_SZ) {
|
||||||
|
if (ConstantCompare(seed + seedIdx,
|
||||||
|
seed + seedIdx + scratchSz,
|
||||||
|
scratchSz) == 0) {
|
||||||
|
|
||||||
|
ret = DRBG_CONT_FAILURE;
|
||||||
|
}
|
||||||
|
seedIdx += SEED_BLOCK_SZ;
|
||||||
|
scratchSz = min(SEED_BLOCK_SZ, (seedSz - seedIdx));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
#endif /* HAVE_HASHDRBG */
|
#endif /* HAVE_HASHDRBG */
|
||||||
/* End NIST DRBG Code */
|
/* End NIST DRBG Code */
|
||||||
|
|
||||||
@@ -581,7 +662,7 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
|
|||||||
{
|
{
|
||||||
int ret = RNG_FAILURE_E;
|
int ret = RNG_FAILURE_E;
|
||||||
#ifdef HAVE_HASHDRBG
|
#ifdef HAVE_HASHDRBG
|
||||||
word32 entropySz = ENTROPY_SZ;
|
word32 seedSz = SEED_SZ + SEED_BLOCK_SZ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
(void)nonce;
|
(void)nonce;
|
||||||
@@ -634,10 +715,10 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
|
|||||||
#else
|
#else
|
||||||
#ifdef HAVE_HASHDRBG
|
#ifdef HAVE_HASHDRBG
|
||||||
if (nonceSz == 0)
|
if (nonceSz == 0)
|
||||||
entropySz = MAX_ENTROPY_SZ;
|
seedSz = MAX_SEED_SZ;
|
||||||
|
|
||||||
if (wc_RNG_HealthTestLocal(0) == 0) {
|
if (wc_RNG_HealthTestLocal(0) == 0) {
|
||||||
DECLARE_VAR(entropy, byte, MAX_ENTROPY_SZ, rng->heap);
|
DECLARE_VAR(seed, byte, MAX_SEED_SZ, rng->heap);
|
||||||
|
|
||||||
rng->drbg =
|
rng->drbg =
|
||||||
(struct DRBG*)XMALLOC(sizeof(DRBG), rng->heap,
|
(struct DRBG*)XMALLOC(sizeof(DRBG), rng->heap,
|
||||||
@@ -645,16 +726,24 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
|
|||||||
if (rng->drbg == NULL) {
|
if (rng->drbg == NULL) {
|
||||||
ret = MEMORY_E;
|
ret = MEMORY_E;
|
||||||
}
|
}
|
||||||
else if (wc_GenerateSeed(&rng->seed, entropy, entropySz) == 0 &&
|
else {
|
||||||
Hash_DRBG_Instantiate(rng->drbg, entropy, entropySz,
|
ret = wc_GenerateSeed(&rng->seed, seed, seedSz);
|
||||||
nonce, nonceSz, rng->heap, devId) == DRBG_SUCCESS) {
|
if (ret != 0)
|
||||||
ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
|
ret = DRBG_FAILURE;
|
||||||
}
|
else
|
||||||
else
|
ret = wc_RNG_TestSeed(seed, seedSz);
|
||||||
ret = DRBG_FAILURE;
|
|
||||||
|
|
||||||
ForceZero(entropy, entropySz);
|
if (ret == DRBG_SUCCESS)
|
||||||
FREE_VAR(entropy, rng->heap);
|
ret = Hash_DRBG_Instantiate(rng->drbg,
|
||||||
|
seed + SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ,
|
||||||
|
nonce, nonceSz, rng->heap, devId);
|
||||||
|
|
||||||
|
if (ret == DRBG_SUCCESS)
|
||||||
|
ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ForceZero(seed, seedSz);
|
||||||
|
FREE_VAR(seed, rng->heap);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = DRBG_CONT_FAILURE;
|
ret = DRBG_CONT_FAILURE;
|
||||||
@@ -747,20 +836,24 @@ int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz)
|
|||||||
ret = Hash_DRBG_Generate(rng->drbg, output, sz);
|
ret = Hash_DRBG_Generate(rng->drbg, output, sz);
|
||||||
if (ret == DRBG_NEED_RESEED) {
|
if (ret == DRBG_NEED_RESEED) {
|
||||||
if (wc_RNG_HealthTestLocal(1) == 0) {
|
if (wc_RNG_HealthTestLocal(1) == 0) {
|
||||||
byte entropy[ENTROPY_SZ];
|
byte newSeed[SEED_SZ + SEED_BLOCK_SZ];
|
||||||
|
|
||||||
if (wc_GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
|
ret = wc_GenerateSeed(&rng->seed, newSeed,
|
||||||
Hash_DRBG_Reseed(rng->drbg, entropy, ENTROPY_SZ)
|
SEED_SZ + SEED_BLOCK_SZ);
|
||||||
== DRBG_SUCCESS) {
|
if (ret != 0)
|
||||||
|
|
||||||
ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
|
|
||||||
if (ret == DRBG_SUCCESS)
|
|
||||||
ret = Hash_DRBG_Generate(rng->drbg, output, sz);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = DRBG_FAILURE;
|
ret = DRBG_FAILURE;
|
||||||
|
else
|
||||||
|
ret = wc_RNG_TestSeed(newSeed, SEED_SZ + SEED_BLOCK_SZ);
|
||||||
|
|
||||||
ForceZero(entropy, ENTROPY_SZ);
|
if (ret == DRBG_SUCCESS)
|
||||||
|
ret = Hash_DRBG_Reseed(rng->drbg, newSeed + SEED_BLOCK_SZ,
|
||||||
|
SEED_SZ);
|
||||||
|
if (ret == DRBG_SUCCESS)
|
||||||
|
ret = Hash_DRBG_Generate(rng->drbg, NULL, 0);
|
||||||
|
if (ret == DRBG_SUCCESS)
|
||||||
|
ret = Hash_DRBG_Generate(rng->drbg, output, sz);
|
||||||
|
|
||||||
|
ForceZero(newSeed, sizeof(newSeed));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = DRBG_CONT_FAILURE;
|
ret = DRBG_CONT_FAILURE;
|
||||||
@@ -822,21 +915,20 @@ int wc_FreeRng(WC_RNG* rng)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_HASHDRBG
|
#ifdef HAVE_HASHDRBG
|
||||||
int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
|
int wc_RNG_HealthTest(int reseed, const byte* seedA, word32 seedASz,
|
||||||
const byte* entropyB, word32 entropyBSz,
|
const byte* seedB, word32 seedBSz,
|
||||||
byte* output, word32 outputSz)
|
byte* output, word32 outputSz)
|
||||||
{
|
{
|
||||||
return wc_RNG_HealthTest_ex(reseed, NULL, 0,
|
return wc_RNG_HealthTest_ex(reseed, NULL, 0,
|
||||||
entropyA, entropyASz,
|
seedA, seedASz, seedB, seedBSz,
|
||||||
entropyB, entropyBSz,
|
|
||||||
output, outputSz,
|
output, outputSz,
|
||||||
NULL, INVALID_DEVID);
|
NULL, INVALID_DEVID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,
|
int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,
|
||||||
const byte* entropyA, word32 entropyASz,
|
const byte* seedA, word32 seedASz,
|
||||||
const byte* entropyB, word32 entropyBSz,
|
const byte* seedB, word32 seedBSz,
|
||||||
byte* output, word32 outputSz,
|
byte* output, word32 outputSz,
|
||||||
void* heap, int devId)
|
void* heap, int devId)
|
||||||
{
|
{
|
||||||
@@ -846,11 +938,11 @@ int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,
|
|||||||
DRBG drbg_var;
|
DRBG drbg_var;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (entropyA == NULL || output == NULL) {
|
if (seedA == NULL || output == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reseed != 0 && entropyB == NULL) {
|
if (reseed != 0 && seedB == NULL) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -867,13 +959,13 @@ int wc_RNG_HealthTest_ex(int reseed, const byte* nonce, word32 nonceSz,
|
|||||||
drbg = &drbg_var;
|
drbg = &drbg_var;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Hash_DRBG_Instantiate(drbg, entropyA, entropyASz, nonce, nonceSz,
|
if (Hash_DRBG_Instantiate(drbg, seedA, seedASz, nonce, nonceSz,
|
||||||
heap, devId) != 0) {
|
heap, devId) != 0) {
|
||||||
goto exit_rng_ht;
|
goto exit_rng_ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reseed) {
|
if (reseed) {
|
||||||
if (Hash_DRBG_Reseed(drbg, entropyB, entropyBSz) != 0) {
|
if (Hash_DRBG_Reseed(drbg, seedB, seedBSz) != 0) {
|
||||||
goto exit_rng_ht;
|
goto exit_rng_ht;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -904,14 +996,14 @@ exit_rng_ht:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const byte entropyA[] = {
|
const byte seedA[] = {
|
||||||
0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
|
0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
|
||||||
0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
|
0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
|
||||||
0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,
|
0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,
|
||||||
0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68
|
0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68
|
||||||
};
|
};
|
||||||
|
|
||||||
const byte reseedEntropyA[] = {
|
const byte reseedSeedA[] = {
|
||||||
0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
|
0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
|
||||||
0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
|
0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
|
||||||
0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3
|
0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3
|
||||||
@@ -931,7 +1023,7 @@ const byte outputA[] = {
|
|||||||
0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17
|
0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17
|
||||||
};
|
};
|
||||||
|
|
||||||
const byte entropyB[] = {
|
const byte seedB[] = {
|
||||||
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, /* nonce next */
|
0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, /* nonce next */
|
||||||
@@ -972,8 +1064,8 @@ static int wc_RNG_HealthTestLocal(int reseed)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (reseed) {
|
if (reseed) {
|
||||||
ret = wc_RNG_HealthTest(1, entropyA, sizeof(entropyA),
|
ret = wc_RNG_HealthTest(1, seedA, sizeof(seedA),
|
||||||
reseedEntropyA, sizeof(reseedEntropyA),
|
reseedSeedA, sizeof(reseedSeedA),
|
||||||
check, RNG_HEALTH_TEST_CHECK_SIZE);
|
check, RNG_HEALTH_TEST_CHECK_SIZE);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (ConstantCompare(check, outputA,
|
if (ConstantCompare(check, outputA,
|
||||||
@@ -982,7 +1074,7 @@ static int wc_RNG_HealthTestLocal(int reseed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ret = wc_RNG_HealthTest(0, entropyB, sizeof(entropyB),
|
ret = wc_RNG_HealthTest(0, seedB, sizeof(seedB),
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
check, RNG_HEALTH_TEST_CHECK_SIZE);
|
check, RNG_HEALTH_TEST_CHECK_SIZE);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@@ -992,13 +1084,13 @@ static int wc_RNG_HealthTestLocal(int reseed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* The previous test cases use a large seed instead of a seed and nonce.
|
/* 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
|
* seedB is actually from a test case with a seed and nonce, and
|
||||||
* just concatenates them. The pivot point between seed and nonce is
|
* just concatenates them. The pivot point between seed and nonce is
|
||||||
* byte 32, feed them into the health test separately. */
|
* byte 32, feed them into the health test separately. */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
ret = wc_RNG_HealthTest_ex(0,
|
ret = wc_RNG_HealthTest_ex(0,
|
||||||
entropyB + 32, sizeof(entropyB) - 32,
|
seedB + 32, sizeof(seedB) - 32,
|
||||||
entropyB, 32,
|
seedB, 32,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
check, RNG_HEALTH_TEST_CHECK_SIZE,
|
check, RNG_HEALTH_TEST_CHECK_SIZE,
|
||||||
NULL, INVALID_DEVID);
|
NULL, INVALID_DEVID);
|
||||||
@@ -1350,6 +1442,19 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
|||||||
|
|
||||||
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_INTEL_RDSEED
|
||||||
|
if (IS_INTEL_RDSEED(intel_flags)) {
|
||||||
|
if (!wc_GenerateSeed_IntelRD(NULL, output, sz)) {
|
||||||
|
/* success, we're done */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#ifdef FORCE_FAILURE_RDSEED
|
||||||
|
/* don't fall back to CryptoAPI */
|
||||||
|
return READ_RAN_E;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* HAVE_INTEL_RDSEED */
|
||||||
|
|
||||||
if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
|
if(!CryptAcquireContext(&os->handle, 0, 0, PROV_RSA_FULL,
|
||||||
CRYPT_VERIFYCONTEXT))
|
CRYPT_VERIFYCONTEXT))
|
||||||
return WINCRYPT_E;
|
return WINCRYPT_E;
|
||||||
|
@@ -8276,6 +8276,36 @@ int random_test(void)
|
|||||||
if ((ret = random_rng_test()) != 0)
|
if ((ret = random_rng_test()) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/* Test the seed check function. */
|
||||||
|
#if !(defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) || \
|
||||||
|
(defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2))
|
||||||
|
{
|
||||||
|
word32 i, outputSz;
|
||||||
|
|
||||||
|
/* Repeat the same byte over and over. Should fail. */
|
||||||
|
outputSz = sizeof(output);
|
||||||
|
XMEMSET(output, 1, outputSz);
|
||||||
|
ret = wc_RNG_TestSeed(output, outputSz);
|
||||||
|
if (ret == 0)
|
||||||
|
return -6404;
|
||||||
|
|
||||||
|
/* Every byte of the entropy scratch is different,
|
||||||
|
* entropy is a single byte that shouldn't match. */
|
||||||
|
outputSz = (sizeof(word32) * 2) + 1;
|
||||||
|
for (i = 0; i < outputSz; i++)
|
||||||
|
output[i] = (byte)i;
|
||||||
|
ret = wc_RNG_TestSeed(output, outputSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return -6405;
|
||||||
|
|
||||||
|
outputSz = sizeof(output);
|
||||||
|
for (i = 0; i < outputSz; i++)
|
||||||
|
output[i] = (byte)i;
|
||||||
|
ret = wc_RNG_TestSeed(output, outputSz);
|
||||||
|
if (ret != 0)
|
||||||
|
return -6406;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -205,6 +205,7 @@ WOLFSSL_API int wc_FreeRng(WC_RNG*);
|
|||||||
#ifdef HAVE_HASHDRBG
|
#ifdef HAVE_HASHDRBG
|
||||||
WOLFSSL_LOCAL int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy,
|
WOLFSSL_LOCAL int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy,
|
||||||
word32 entropySz);
|
word32 entropySz);
|
||||||
|
WOLFSSL_API int wc_RNG_TestSeed(const byte* seed, word32 seedSz);
|
||||||
WOLFSSL_API int wc_RNG_HealthTest(int reseed,
|
WOLFSSL_API int wc_RNG_HealthTest(int reseed,
|
||||||
const byte* entropyA, word32 entropyASz,
|
const byte* entropyA, word32 entropyASz,
|
||||||
const byte* entropyB, word32 entropyBSz,
|
const byte* entropyB, word32 entropyBSz,
|
||||||
|
Reference in New Issue
Block a user