Merge branch 'master' into ti

This commit is contained in:
toddouska 2014-05-15 10:37:15 -07:00
commit e024c8af41
5 changed files with 275 additions and 106 deletions

View File

@ -274,6 +274,9 @@ const char* CTaoCryptGetErrorString(int error)
case ASN_NAME_INVALID_E: case ASN_NAME_INVALID_E:
return "Name Constraint error"; return "Name Constraint error";
case RNG_FAILURE_E:
return "Random Number Generator failed";
default: default:
return "unknown error number"; return "unknown error number";

View File

@ -30,10 +30,16 @@
*/ */
#ifdef HAVE_FIPS
/* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
#define FIPS_NO_WRAPPERS
#endif
#include <cyassl/ctaocrypt/random.h> #include <cyassl/ctaocrypt/random.h>
#include <cyassl/ctaocrypt/error-crypt.h> #include <cyassl/ctaocrypt/error-crypt.h>
#if defined(HAVE_HASHDRBG) || defined(NO_RC4) #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
#include <cyassl/ctaocrypt/sha256.h> #include <cyassl/ctaocrypt/sha256.h>
#ifdef NO_INLINE #ifdef NO_INLINE
@ -74,9 +80,16 @@
#define NONCE_SZ (ENTROPY_SZ/2) #define NONCE_SZ (ENTROPY_SZ/2)
#define ENTROPY_NONCE_SZ (ENTROPY_SZ+NONCE_SZ) #define ENTROPY_NONCE_SZ (ENTROPY_SZ+NONCE_SZ)
#define DRBG_SUCCESS 0 /* Internal return codes */
#define DRBG_ERROR 1 #define DRBG_SUCCESS 0
#define DRBG_NEED_RESEED 2 #define DRBG_ERROR 1
#define DRBG_FAILURE 2
#define DRBG_NEED_RESEED 3
/* RNG health states */
#define DRBG_NOT_INIT 0
#define DRBG_OK 1
#define DRBG_FAILED 2
enum { enum {
@ -88,10 +101,11 @@ enum {
}; };
/* Hash Derivation Function */
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type, static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type,
byte* inA, word32 inASz, const byte* inA, word32 inASz,
byte* inB, word32 inBSz, const byte* inB, word32 inBSz)
byte* inC, word32 inCSz)
{ {
byte ctr; byte ctr;
int i; int i;
@ -107,33 +121,29 @@ static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type,
for (i = 0, ctr = 1; i < len; i++, ctr++) for (i = 0, ctr = 1; i < len; i++, ctr++)
{ {
if (InitSha256(&rng->sha) != 0) if (InitSha256(&rng->sha) != 0)
return DRBG_ERROR; return DRBG_FAILURE;
if (Sha256Update(&rng->sha, &ctr, sizeof(ctr)) != 0) if (Sha256Update(&rng->sha, &ctr, sizeof(ctr)) != 0)
return DRBG_ERROR; return DRBG_FAILURE;
if (Sha256Update(&rng->sha, (byte*)&bits, sizeof(bits)) != 0) if (Sha256Update(&rng->sha, (byte*)&bits, sizeof(bits)) != 0)
return DRBG_ERROR; return DRBG_FAILURE;
/* churning V is the only string that doesn't have /* churning V is the only string that doesn't have
* the type added */ * the type added */
if (type != drbgInitV) if (type != drbgInitV)
if (Sha256Update(&rng->sha, &type, sizeof(type)) != 0) if (Sha256Update(&rng->sha, &type, sizeof(type)) != 0)
return DRBG_ERROR; return DRBG_FAILURE;
if (Sha256Update(&rng->sha, inA, inASz) != 0) if (Sha256Update(&rng->sha, inA, inASz) != 0)
return DRBG_ERROR; return DRBG_FAILURE;
if (inB != NULL && inBSz > 0) if (inB != NULL && inBSz > 0)
if (Sha256Update(&rng->sha, inB, inBSz) != 0) if (Sha256Update(&rng->sha, inB, inBSz) != 0)
return DRBG_ERROR; return DRBG_FAILURE;
if (inC != NULL && inCSz > 0)
if (Sha256Update(&rng->sha, inC, inCSz) != 0)
return DRBG_ERROR;
if (Sha256Final(&rng->sha, rng->digest) != 0) if (Sha256Final(&rng->sha, rng->digest) != 0)
return DRBG_ERROR; return DRBG_FAILURE;
if (outSz > OUTPUT_BLOCK_LEN) { if (outSz > OUTPUT_BLOCK_LEN) {
XMEMCPY(out, rng->digest, OUTPUT_BLOCK_LEN); XMEMCPY(out, rng->digest, OUTPUT_BLOCK_LEN);
@ -149,26 +159,26 @@ static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type,
} }
static int Hash_DRBG_Reseed(RNG* rng, byte* entropy, word32 entropySz) /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
static int Hash_DRBG_Reseed(RNG* rng, const byte* entropy, word32 entropySz)
{ {
int ret;
byte seed[DRBG_SEED_LEN]; byte seed[DRBG_SEED_LEN];
ret = Hash_df(rng, seed, sizeof(seed), drbgReseed, rng->V, sizeof(rng->V), if (Hash_df(rng, seed, sizeof(seed), drbgReseed, rng->V, sizeof(rng->V),
entropy, entropySz, NULL, 0); entropy, entropySz) != DRBG_SUCCESS) {
if (ret != 0) return DRBG_FAILURE;
return ret; }
XMEMCPY(rng->V, seed, sizeof(rng->V)); XMEMCPY(rng->V, seed, sizeof(rng->V));
XMEMSET(seed, 0, sizeof(seed)); XMEMSET(seed, 0, sizeof(seed));
ret = Hash_df(rng, rng->C, sizeof(rng->C), drbgInitC, rng->V, if (Hash_df(rng, rng->C, sizeof(rng->C), drbgInitC, rng->V,
sizeof(rng->V), NULL, 0, NULL, 0); sizeof(rng->V), NULL, 0) != DRBG_SUCCESS) {
if (ret != 0) return DRBG_FAILURE;
return ret; }
rng->reseedCtr = 1; rng->reseedCtr = 1;
return 0; return DRBG_SUCCESS;
} }
static INLINE void array_add_one(byte* data, word32 dataSz) static INLINE void array_add_one(byte* data, word32 dataSz)
@ -182,26 +192,23 @@ static INLINE void array_add_one(byte* data, word32 dataSz)
} }
} }
static int Hash_gen(RNG* rng, byte* out, word32 outSz, byte* V)
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */
static int Hash_gen(RNG* rng, byte* out, word32 outSz, const byte* V)
{ {
byte data[DRBG_SEED_LEN]; byte data[DRBG_SEED_LEN];
int i, ret; int i;
int len = (outSz / OUTPUT_BLOCK_LEN) int len = (outSz / OUTPUT_BLOCK_LEN)
+ ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0); + ((outSz % OUTPUT_BLOCK_LEN) ? 1 : 0);
XMEMCPY(data, V, sizeof(data)); XMEMCPY(data, V, sizeof(data));
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
ret = InitSha256(&rng->sha); if (InitSha256(&rng->sha) != 0 ||
if (ret != 0) Sha256Update(&rng->sha, data, sizeof(data)) != 0 ||
return ret; Sha256Final(&rng->sha, rng->digest) != 0) {
ret = Sha256Update(&rng->sha, data, sizeof(data)); return DRBG_FAILURE;
if (ret != 0) }
return ret;
ret = Sha256Final(&rng->sha, rng->digest);
if (ret != 0)
return ret;
if (outSz > OUTPUT_BLOCK_LEN) { if (outSz > OUTPUT_BLOCK_LEN) {
XMEMCPY(out, rng->digest, OUTPUT_BLOCK_LEN); XMEMCPY(out, rng->digest, OUTPUT_BLOCK_LEN);
@ -215,11 +222,11 @@ static int Hash_gen(RNG* rng, byte* out, word32 outSz, byte* V)
} }
XMEMSET(data, 0, sizeof(data)); XMEMSET(data, 0, sizeof(data));
return 0; return DRBG_SUCCESS;
} }
static INLINE void array_add(byte* d, word32 dLen, byte* s, word32 sLen) static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
{ {
word16 carry = 0; word16 carry = 0;
@ -238,74 +245,67 @@ static INLINE void array_add(byte* d, word32 dLen, byte* s, word32 sLen)
} }
/* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */
static int Hash_DRBG_Generate(RNG* rng, byte* out, word32 outSz) static int Hash_DRBG_Generate(RNG* rng, byte* out, word32 outSz)
{ {
int ret; int ret = DRBG_NEED_RESEED;
if (rng->reseedCtr != RESEED_INTERVAL) { if (rng->reseedCtr != RESEED_INTERVAL) {
byte type = drbgGenerateH; byte type = drbgGenerateH;
word32 reseedCtr = rng->reseedCtr; word32 reseedCtr = rng->reseedCtr;
rng->reseedCtr++; rng->reseedCtr++;
if (Hash_gen(rng, out, outSz, rng->V) != 0) if (Hash_gen(rng, out, outSz, rng->V) != 0 ||
return DRBG_ERROR; InitSha256(&rng->sha) != 0 ||
if (InitSha256(&rng->sha) != 0) Sha256Update(&rng->sha, &type, sizeof(type)) != 0 ||
return DRBG_ERROR; Sha256Update(&rng->sha, rng->V, sizeof(rng->V)) != 0 ||
if (Sha256Update(&rng->sha, &type, sizeof(type)) != 0) Sha256Final(&rng->sha, rng->digest) != 0) {
return DRBG_ERROR;
if (Sha256Update(&rng->sha, rng->V, sizeof(rng->V)) != 0)
return DRBG_ERROR;
if (Sha256Final(&rng->sha, rng->digest) != 0)
return DRBG_ERROR;
array_add(rng->V, sizeof(rng->V), rng->digest, sizeof(rng->digest)); ret = DRBG_FAILURE;
array_add(rng->V, sizeof(rng->V), rng->C, sizeof(rng->C)); }
#ifdef LITTLE_ENDIAN_ORDER else {
reseedCtr = ByteReverseWord32(reseedCtr); array_add(rng->V, sizeof(rng->V), rng->digest, sizeof(rng->digest));
#endif array_add(rng->V, sizeof(rng->V), rng->C, sizeof(rng->C));
array_add(rng->V, sizeof(rng->V), (byte*)&reseedCtr, sizeof(reseedCtr)); #ifdef LITTLE_ENDIAN_ORDER
ret = DRBG_SUCCESS; reseedCtr = ByteReverseWord32(reseedCtr);
} #endif
else { array_add(rng->V, sizeof(rng->V),
ret = DRBG_NEED_RESEED; (byte*)&reseedCtr, sizeof(reseedCtr));
ret = DRBG_SUCCESS;
}
} }
return ret; return ret;
} }
static int Hash_DRBG_Instantiate(RNG* rng, byte* seed, word32 seedSz, /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
byte* nonce, word32 nonceSz, byte* personal, word32 personalSz) static int Hash_DRBG_Instantiate(RNG* rng, const byte* seed, word32 seedSz,
const byte* nonce, word32 nonceSz)
{ {
int ret; int ret = DRBG_FAILURE;
XMEMSET(rng, 0, sizeof(*rng)); XMEMSET(rng, 0, sizeof(*rng));
ret = Hash_df(rng, rng->V, sizeof(rng->V), drbgInitV, seed, seedSz,
nonce, nonceSz, personal, personalSz);
if (ret != 0) if (Hash_df(rng, rng->V, sizeof(rng->V), drbgInitV, seed, seedSz,
return ret; nonce, nonceSz) == DRBG_SUCCESS &&
Hash_df(rng, rng->C, sizeof(rng->C), drbgInitC, rng->V,
sizeof(rng->V), NULL, 0) == DRBG_SUCCESS) {
ret = Hash_df(rng, rng->C, sizeof(rng->C), drbgInitC, rng->V, rng->reseedCtr = 1;
sizeof(rng->V), NULL, 0, NULL, 0); ret = DRBG_SUCCESS;
if (ret != 0) }
return ret;
rng->reseedCtr = 1; return ret;
return 0;
} }
/* Returns: DRBG_SUCCESS */
static int Hash_DRBG_Uninstantiate(RNG* rng) static int Hash_DRBG_Uninstantiate(RNG* rng)
{ {
int result = DRBG_ERROR; XMEMSET(rng, 0, sizeof(*rng));
if (rng != NULL) { return DRBG_SUCCESS;
XMEMSET(rng, 0, sizeof(*rng));
result = DRBG_SUCCESS;
}
return result;
} }
/* End NIST DRBG Code */ /* End NIST DRBG Code */
@ -314,17 +314,27 @@ static int Hash_DRBG_Uninstantiate(RNG* rng)
/* Get seed and key cipher */ /* Get seed and key cipher */
int InitRng(RNG* rng) int InitRng(RNG* rng)
{ {
byte entropy[ENTROPY_NONCE_SZ]; int ret = BAD_FUNC_ARG;
int ret = DRBG_ERROR;
/* This doesn't use a separate nonce. The entropy input will be if (rng != NULL) {
* the default size plus the size of the nonce making the seed byte entropy[ENTROPY_NONCE_SZ];
* size. */
if (GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0)
ret = Hash_DRBG_Instantiate(rng, entropy, ENTROPY_NONCE_SZ,
NULL, 0, NULL, 0);
XMEMSET(entropy, 0, ENTROPY_NONCE_SZ); /* This doesn't use a separate nonce. The entropy input will be
* the default size plus the size of the nonce making the seed
* size. */
if (GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 &&
Hash_DRBG_Instantiate(rng, entropy, ENTROPY_NONCE_SZ,
NULL, 0) == DRBG_SUCCESS) {
rng->status = DRBG_OK;
ret = 0;
}
else {
rng->status = DRBG_FAILED;
ret = RNG_FAILURE_E;
}
XMEMSET(entropy, 0, ENTROPY_NONCE_SZ);
}
return ret; return ret;
} }
@ -335,24 +345,36 @@ int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
{ {
int ret; int ret;
XMEMSET(output, 0, sz); if (rng == NULL || output == NULL || sz > MAX_REQUEST_LEN)
ret = Hash_DRBG_Generate(rng, output, sz); return BAD_FUNC_ARG;
if (ret == DRBG_NEED_RESEED) { if (rng->status != DRBG_OK)
return RNG_FAILURE_E;
ret = Hash_DRBG_Generate(rng, output, sz);
if (ret == DRBG_SUCCESS) {
ret = 0;
}
else if (ret == DRBG_NEED_RESEED) {
byte entropy[ENTROPY_SZ]; byte entropy[ENTROPY_SZ];
ret = GenerateSeed(&rng->seed, entropy, ENTROPY_SZ); if (GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
if (ret == 0) { Hash_DRBG_Reseed(rng, entropy, ENTROPY_SZ) == DRBG_SUCCESS &&
ret = Hash_DRBG_Reseed(rng, entropy, ENTROPY_SZ); Hash_DRBG_Generate(rng, output, sz) == DRBG_SUCCESS) {
if (ret == 0) ret = 0;
ret = Hash_DRBG_Generate(rng, output, sz); }
else {
ret = RNG_FAILURE_E;
rng->status = DRBG_FAILED;
} }
else
ret = DRBG_ERROR;
XMEMSET(entropy, 0, ENTROPY_SZ); XMEMSET(entropy, 0, ENTROPY_SZ);
} }
else {
ret = RNG_FAILURE_E;
rng->status = DRBG_FAILED;
}
return ret; return ret;
} }
@ -364,11 +386,59 @@ int RNG_GenerateByte(RNG* rng, byte* b)
} }
void FreeRng(RNG* rng) int FreeRng(RNG* rng)
{ {
Hash_DRBG_Uninstantiate(rng); int ret = BAD_FUNC_ARG;
if (rng != NULL) {
if (Hash_DRBG_Uninstantiate(rng) == DRBG_SUCCESS)
ret = 0;
else
ret = RNG_FAILURE_E;
}
return ret;
} }
int RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
const byte* entropyB, word32 entropyBSz,
const byte* output, word32 outputSz)
{
RNG rng;
byte check[SHA256_DIGEST_SIZE * 4];
if (Hash_DRBG_Instantiate(&rng, entropyA, entropyASz, NULL, 0) != 0)
return -1;
if (reseed) {
if (Hash_DRBG_Reseed(&rng, entropyB, entropyBSz) != 0) {
Hash_DRBG_Uninstantiate(&rng);
return -1;
}
}
if (Hash_DRBG_Generate(&rng, check, sizeof(check)) != 0) {
Hash_DRBG_Uninstantiate(&rng);
return -1;
}
if (Hash_DRBG_Generate(&rng, check, sizeof(check)) != 0) {
Hash_DRBG_Uninstantiate(&rng);
return -1;
}
if (outputSz != sizeof(check) || XMEMCMP(output, check, sizeof(check))) {
Hash_DRBG_Uninstantiate(&rng);
return -1;
}
Hash_DRBG_Uninstantiate(&rng);
return 0;
}
#else /* HAVE_HASHDRBG || NO_RC4 */ #else /* HAVE_HASHDRBG || NO_RC4 */
/* Get seed and key cipher */ /* Get seed and key cipher */

View File

@ -2581,6 +2581,74 @@ int camellia_test(void)
#endif /* HAVE_CAMELLIA */ #endif /* HAVE_CAMELLIA */
#if defined(HAVE_HASHDRBG) || defined(NO_RC4)
int random_test(void)
{
const byte test1Entropy[] =
{
0xa6, 0x5a, 0xd0, 0xf3, 0x45, 0xdb, 0x4e, 0x0e, 0xff, 0xe8, 0x75, 0xc3,
0xa2, 0xe7, 0x1f, 0x42, 0xc7, 0x12, 0x9d, 0x62, 0x0f, 0xf5, 0xc1, 0x19,
0xa9, 0xef, 0x55, 0xf0, 0x51, 0x85, 0xe0, 0xfb, 0x85, 0x81, 0xf9, 0x31,
0x75, 0x17, 0x27, 0x6e, 0x06, 0xe9, 0x60, 0x7d, 0xdb, 0xcb, 0xcc, 0x2e
};
const byte test1Output[] =
{
0xd3, 0xe1, 0x60, 0xc3, 0x5b, 0x99, 0xf3, 0x40, 0xb2, 0x62, 0x82, 0x64,
0xd1, 0x75, 0x10, 0x60, 0xe0, 0x04, 0x5d, 0xa3, 0x83, 0xff, 0x57, 0xa5,
0x7d, 0x73, 0xa6, 0x73, 0xd2, 0xb8, 0xd8, 0x0d, 0xaa, 0xf6, 0xa6, 0xc3,
0x5a, 0x91, 0xbb, 0x45, 0x79, 0xd7, 0x3f, 0xd0, 0xc8, 0xfe, 0xd1, 0x11,
0xb0, 0x39, 0x13, 0x06, 0x82, 0x8a, 0xdf, 0xed, 0x52, 0x8f, 0x01, 0x81,
0x21, 0xb3, 0xfe, 0xbd, 0xc3, 0x43, 0xe7, 0x97, 0xb8, 0x7d, 0xbb, 0x63,
0xdb, 0x13, 0x33, 0xde, 0xd9, 0xd1, 0xec, 0xe1, 0x77, 0xcf, 0xa6, 0xb7,
0x1f, 0xe8, 0xab, 0x1d, 0xa4, 0x66, 0x24, 0xed, 0x64, 0x15, 0xe5, 0x1c,
0xcd, 0xe2, 0xc7, 0xca, 0x86, 0xe2, 0x83, 0x99, 0x0e, 0xea, 0xeb, 0x91,
0x12, 0x04, 0x15, 0x52, 0x8b, 0x22, 0x95, 0x91, 0x02, 0x81, 0xb0, 0x2d,
0xd4, 0x31, 0xf4, 0xc9, 0xf7, 0x04, 0x27, 0xdf
};
const byte test2EntropyA[] =
{
0x63, 0x36, 0x33, 0x77, 0xe4, 0x1e, 0x86, 0x46, 0x8d, 0xeb, 0x0a, 0xb4,
0xa8, 0xed, 0x68, 0x3f, 0x6a, 0x13, 0x4e, 0x47, 0xe0, 0x14, 0xc7, 0x00,
0x45, 0x4e, 0x81, 0xe9, 0x53, 0x58, 0xa5, 0x69, 0x80, 0x8a, 0xa3, 0x8f,
0x2a, 0x72, 0xa6, 0x23, 0x59, 0x91, 0x5a, 0x9f, 0x8a, 0x04, 0xca, 0x68
};
const byte test2EntropyB[] =
{
0xe6, 0x2b, 0x8a, 0x8e, 0xe8, 0xf1, 0x41, 0xb6, 0x98, 0x05, 0x66, 0xe3,
0xbf, 0xe3, 0xc0, 0x49, 0x03, 0xda, 0xd4, 0xac, 0x2c, 0xdf, 0x9f, 0x22,
0x80, 0x01, 0x0a, 0x67, 0x39, 0xbc, 0x83, 0xd3
};
const byte test2Output[] =
{
0x04, 0xee, 0xc6, 0x3b, 0xb2, 0x31, 0xdf, 0x2c, 0x63, 0x0a, 0x1a, 0xfb,
0xe7, 0x24, 0x94, 0x9d, 0x00, 0x5a, 0x58, 0x78, 0x51, 0xe1, 0xaa, 0x79,
0x5e, 0x47, 0x73, 0x47, 0xc8, 0xb0, 0x56, 0x62, 0x1c, 0x18, 0xbd, 0xdc,
0xdd, 0x8d, 0x99, 0xfc, 0x5f, 0xc2, 0xb9, 0x20, 0x53, 0xd8, 0xcf, 0xac,
0xfb, 0x0b, 0xb8, 0x83, 0x12, 0x05, 0xfa, 0xd1, 0xdd, 0xd6, 0xc0, 0x71,
0x31, 0x8a, 0x60, 0x18, 0xf0, 0x3b, 0x73, 0xf5, 0xed, 0xe4, 0xd4, 0xd0,
0x71, 0xf9, 0xde, 0x03, 0xfd, 0x7a, 0xea, 0x10, 0x5d, 0x92, 0x99, 0xb8,
0xaf, 0x99, 0xaa, 0x07, 0x5b, 0xdb, 0x4d, 0xb9, 0xaa, 0x28, 0xc1, 0x8d,
0x17, 0x4b, 0x56, 0xee, 0x2a, 0x01, 0x4d, 0x09, 0x88, 0x96, 0xff, 0x22,
0x82, 0xc9, 0x55, 0xa8, 0x19, 0x69, 0xe0, 0x69, 0xfa, 0x8c, 0xe0, 0x07,
0xa1, 0x80, 0x18, 0x3a, 0x07, 0xdf, 0xae, 0x17
};
int ret;
ret = RNG_HealthTest(0, test1Entropy, sizeof(test1Entropy), NULL, 0,
test1Output, sizeof(test1Output));
if (ret != 0) return -39;
ret = RNG_HealthTest(1, test2EntropyA, sizeof(test2EntropyA),
test2EntropyB, sizeof(test2EntropyB),
test2Output, sizeof(test2Output));
if (ret != 0) return -40;
return 0;
}
#else /* HAVE_HASHDRBG || NO_RC4 */
int random_test(void) int random_test(void)
{ {
RNG rng; RNG rng;
@ -2600,6 +2668,8 @@ int random_test(void)
return 0; return 0;
} }
#endif /* HAVE_HASHDRBG || NO_RC4 */
#ifdef HAVE_NTRU #ifdef HAVE_NTRU

View File

@ -125,6 +125,8 @@ enum {
FIPS_NOT_ALLOWED_E = -197, /* FIPS not allowed error */ FIPS_NOT_ALLOWED_E = -197, /* FIPS not allowed error */
ASN_NAME_INVALID_E = -198, /* ASN name constraint error */ ASN_NAME_INVALID_E = -198, /* ASN name constraint error */
RNG_FAILURE_E = -199, /* RNG Failed, Reinitialize */
MIN_CODE_E = -200 /* errors -101 - -199 */ MIN_CODE_E = -200 /* errors -101 - -199 */
}; };

View File

@ -84,6 +84,7 @@ typedef struct RNG {
byte V[DRBG_SEED_LEN]; byte V[DRBG_SEED_LEN];
byte C[DRBG_SEED_LEN]; byte C[DRBG_SEED_LEN];
word32 reseedCtr; word32 reseedCtr;
byte status;
} RNG; } RNG;
@ -119,10 +120,33 @@ CYASSL_API int RNG_GenerateByte(RNG*, byte*);
#if defined(HAVE_HASHDRBG) || defined(NO_RC4) #if defined(HAVE_HASHDRBG) || defined(NO_RC4)
CYASSL_API void FreeRng(RNG*); CYASSL_API int FreeRng(RNG*);
CYASSL_API int RNG_HealthTest(int reseed,
const byte* entropyA, word32 entropyASz,
const byte* entropyB, word32 entropyBSz,
const byte* output, word32 outputSz);
#endif /* HAVE_HASHDRBG || NO_RC4 */ #endif /* HAVE_HASHDRBG || NO_RC4 */
#ifdef HAVE_FIPS
/* fips wrapper calls, user can call direct */
CYASSL_API int InitRng_fips(RNG* rng);
CYASSL_API int FreeRng_fips(RNG* rng);
CYASSL_API int RNG_GenerateBlock_fips(RNG* rng, byte* buf, word32 bufSz);
CYASSL_API int RNG_HealthTest_fips(int reseed,
const byte* entropyA, word32 entropyASz,
const byte* entropyB, word32 entropyBSz,
const byte* output, word32 outputSz);
#ifndef FIPS_NO_WRAPPERS
/* if not impl or fips.c impl wrapper force fips calls if fips build */
#define InitRng InitRng_fips
#define FreeRng FreeRng_fips
#define RNG_GenerateBlock RNG_GenerateBlock_fips
#define RNG_HealthTest RNG_HealthTest_fips
#endif /* FIPS_NO_WRAPPERS */
#endif /* HAVE_FIPS */
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif