Merge branch 'master' into ti

This commit is contained in:
toddouska
2014-07-29 16:20:57 -07:00
3 changed files with 91 additions and 65 deletions

View File

@ -101,9 +101,18 @@ enum {
}; };
typedef struct DRBG {
Sha256 sha;
byte digest[SHA256_DIGEST_SIZE];
byte V[DRBG_SEED_LEN];
byte C[DRBG_SEED_LEN];
word32 reseedCtr;
} DRBG;
/* Hash Derivation Function */ /* Hash Derivation Function */
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type, static int Hash_df(DRBG* drbg, byte* out, word32 outSz, byte type,
const byte* inA, word32 inASz, const byte* inA, word32 inASz,
const byte* inB, word32 inBSz) const byte* inB, word32 inBSz)
{ {
@ -120,38 +129,38 @@ 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(&drbg->sha) != 0)
return DRBG_FAILURE; return DRBG_FAILURE;
if (Sha256Update(&rng->sha, &ctr, sizeof(ctr)) != 0) if (Sha256Update(&drbg->sha, &ctr, sizeof(ctr)) != 0)
return DRBG_FAILURE; return DRBG_FAILURE;
if (Sha256Update(&rng->sha, (byte*)&bits, sizeof(bits)) != 0) if (Sha256Update(&drbg->sha, (byte*)&bits, sizeof(bits)) != 0)
return DRBG_FAILURE; 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(&drbg->sha, &type, sizeof(type)) != 0)
return DRBG_FAILURE; return DRBG_FAILURE;
if (Sha256Update(&rng->sha, inA, inASz) != 0) if (Sha256Update(&drbg->sha, inA, inASz) != 0)
return DRBG_FAILURE; return DRBG_FAILURE;
if (inB != NULL && inBSz > 0) if (inB != NULL && inBSz > 0)
if (Sha256Update(&rng->sha, inB, inBSz) != 0) if (Sha256Update(&drbg->sha, inB, inBSz) != 0)
return DRBG_FAILURE; return DRBG_FAILURE;
if (Sha256Final(&rng->sha, rng->digest) != 0) if (Sha256Final(&drbg->sha, drbg->digest) != 0)
return DRBG_FAILURE; return DRBG_FAILURE;
if (outSz > OUTPUT_BLOCK_LEN) { if (outSz > OUTPUT_BLOCK_LEN) {
XMEMCPY(out, rng->digest, OUTPUT_BLOCK_LEN); XMEMCPY(out, drbg->digest, OUTPUT_BLOCK_LEN);
outSz -= OUTPUT_BLOCK_LEN; outSz -= OUTPUT_BLOCK_LEN;
out += OUTPUT_BLOCK_LEN; out += OUTPUT_BLOCK_LEN;
} }
else { else {
XMEMCPY(out, rng->digest, outSz); XMEMCPY(out, drbg->digest, outSz);
} }
} }
@ -160,24 +169,24 @@ static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type,
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
static int Hash_DRBG_Reseed(RNG* rng, const byte* entropy, word32 entropySz) static int Hash_DRBG_Reseed(DRBG* drbg, const byte* entropy, word32 entropySz)
{ {
byte seed[DRBG_SEED_LEN]; byte seed[DRBG_SEED_LEN];
if (Hash_df(rng, seed, sizeof(seed), drbgReseed, rng->V, sizeof(rng->V), if (Hash_df(drbg, seed, sizeof(seed), drbgReseed, drbg->V, sizeof(drbg->V),
entropy, entropySz) != DRBG_SUCCESS) { entropy, entropySz) != DRBG_SUCCESS) {
return DRBG_FAILURE; return DRBG_FAILURE;
} }
XMEMCPY(rng->V, seed, sizeof(rng->V)); XMEMCPY(drbg->V, seed, sizeof(drbg->V));
XMEMSET(seed, 0, sizeof(seed)); XMEMSET(seed, 0, sizeof(seed));
if (Hash_df(rng, rng->C, sizeof(rng->C), drbgInitC, rng->V, if (Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
sizeof(rng->V), NULL, 0) != DRBG_SUCCESS) { sizeof(drbg->V), NULL, 0) != DRBG_SUCCESS) {
return DRBG_FAILURE; return DRBG_FAILURE;
} }
rng->reseedCtr = 1; drbg->reseedCtr = 1;
return DRBG_SUCCESS; return DRBG_SUCCESS;
} }
@ -194,7 +203,7 @@ static INLINE void array_add_one(byte* data, word32 dataSz)
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
static int Hash_gen(RNG* rng, byte* out, word32 outSz, const byte* V) static int Hash_gen(DRBG* drbg, byte* out, word32 outSz, const byte* V)
{ {
byte data[DRBG_SEED_LEN]; byte data[DRBG_SEED_LEN];
int i; int i;
@ -203,21 +212,21 @@ static int Hash_gen(RNG* rng, byte* out, word32 outSz, const byte* V)
XMEMCPY(data, V, sizeof(data)); XMEMCPY(data, V, sizeof(data));
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (InitSha256(&rng->sha) != 0 || if (InitSha256(&drbg->sha) != 0 ||
Sha256Update(&rng->sha, data, sizeof(data)) != 0 || Sha256Update(&drbg->sha, data, sizeof(data)) != 0 ||
Sha256Final(&rng->sha, rng->digest) != 0) { Sha256Final(&drbg->sha, drbg->digest) != 0) {
return DRBG_FAILURE; return DRBG_FAILURE;
} }
if (outSz > OUTPUT_BLOCK_LEN) { if (outSz > OUTPUT_BLOCK_LEN) {
XMEMCPY(out, rng->digest, OUTPUT_BLOCK_LEN); XMEMCPY(out, drbg->digest, OUTPUT_BLOCK_LEN);
outSz -= OUTPUT_BLOCK_LEN; outSz -= OUTPUT_BLOCK_LEN;
out += OUTPUT_BLOCK_LEN; out += OUTPUT_BLOCK_LEN;
array_add_one(data, DRBG_SEED_LEN); array_add_one(data, DRBG_SEED_LEN);
} }
else { else {
XMEMCPY(out, rng->digest, outSz); XMEMCPY(out, drbg->digest, outSz);
} }
} }
XMEMSET(data, 0, sizeof(data)); XMEMSET(data, 0, sizeof(data));
@ -246,30 +255,31 @@ static INLINE void array_add(byte* d, word32 dLen, const byte* s, word32 sLen)
/* Returns: DRBG_SUCCESS, DRBG_NEED_RESEED, or DRBG_FAILURE */ /* 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(DRBG* drbg, byte* out, word32 outSz)
{ {
int ret = DRBG_NEED_RESEED; int ret = DRBG_NEED_RESEED;
if (rng->reseedCtr != RESEED_INTERVAL) { if (drbg->reseedCtr != RESEED_INTERVAL) {
byte type = drbgGenerateH; byte type = drbgGenerateH;
word32 reseedCtr = rng->reseedCtr; word32 reseedCtr = drbg->reseedCtr;
rng->reseedCtr++; drbg->reseedCtr++;
if (Hash_gen(rng, out, outSz, rng->V) != 0 || if (Hash_gen(drbg, out, outSz, drbg->V) != 0 ||
InitSha256(&rng->sha) != 0 || InitSha256(&drbg->sha) != 0 ||
Sha256Update(&rng->sha, &type, sizeof(type)) != 0 || Sha256Update(&drbg->sha, &type, sizeof(type)) != 0 ||
Sha256Update(&rng->sha, rng->V, sizeof(rng->V)) != 0 || Sha256Update(&drbg->sha, drbg->V, sizeof(drbg->V)) != 0 ||
Sha256Final(&rng->sha, rng->digest) != 0) { Sha256Final(&drbg->sha, drbg->digest) != 0) {
ret = DRBG_FAILURE; ret = DRBG_FAILURE;
} }
else { else {
array_add(rng->V, sizeof(rng->V), rng->digest, sizeof(rng->digest)); array_add(drbg->V, sizeof(drbg->V),
array_add(rng->V, sizeof(rng->V), rng->C, sizeof(rng->C)); drbg->digest, sizeof(drbg->digest));
array_add(drbg->V, sizeof(drbg->V), drbg->C, sizeof(drbg->C));
#ifdef LITTLE_ENDIAN_ORDER #ifdef LITTLE_ENDIAN_ORDER
reseedCtr = ByteReverseWord32(reseedCtr); reseedCtr = ByteReverseWord32(reseedCtr);
#endif #endif
array_add(rng->V, sizeof(rng->V), array_add(drbg->V, sizeof(drbg->V),
(byte*)&reseedCtr, sizeof(reseedCtr)); (byte*)&reseedCtr, sizeof(reseedCtr));
ret = DRBG_SUCCESS; ret = DRBG_SUCCESS;
} }
@ -280,19 +290,19 @@ static int Hash_DRBG_Generate(RNG* rng, byte* out, word32 outSz)
/* Returns: DRBG_SUCCESS or DRBG_FAILURE */ /* Returns: DRBG_SUCCESS or DRBG_FAILURE */
static int Hash_DRBG_Instantiate(RNG* rng, const byte* seed, word32 seedSz, static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz,
const byte* nonce, word32 nonceSz) const byte* nonce, word32 nonceSz)
{ {
int ret = DRBG_FAILURE; int ret = DRBG_FAILURE;
XMEMSET(rng, 0, sizeof(*rng)); XMEMSET(drbg, 0, sizeof(DRBG));
if (Hash_df(rng, rng->V, sizeof(rng->V), drbgInitV, seed, seedSz, if (Hash_df(drbg, drbg->V, sizeof(drbg->V), drbgInitV, seed, seedSz,
nonce, nonceSz) == DRBG_SUCCESS && nonce, nonceSz) == DRBG_SUCCESS &&
Hash_df(rng, rng->C, sizeof(rng->C), drbgInitC, rng->V, Hash_df(drbg, drbg->C, sizeof(drbg->C), drbgInitC, drbg->V,
sizeof(rng->V), NULL, 0) == DRBG_SUCCESS) { sizeof(drbg->V), NULL, 0) == DRBG_SUCCESS) {
rng->reseedCtr = 1; drbg->reseedCtr = 1;
ret = DRBG_SUCCESS; ret = DRBG_SUCCESS;
} }
@ -301,9 +311,9 @@ static int Hash_DRBG_Instantiate(RNG* rng, const byte* seed, word32 seedSz,
/* Returns: DRBG_SUCCESS */ /* Returns: DRBG_SUCCESS */
static int Hash_DRBG_Uninstantiate(RNG* rng) static int Hash_DRBG_Uninstantiate(DRBG* drbg)
{ {
XMEMSET(rng, 0, sizeof(*rng)); XMEMSET(drbg, 0, sizeof(DRBG));
return DRBG_SUCCESS; return DRBG_SUCCESS;
} }
@ -319,11 +329,16 @@ int InitRng(RNG* rng)
if (rng != NULL) { if (rng != NULL) {
byte entropy[ENTROPY_NONCE_SZ]; byte entropy[ENTROPY_NONCE_SZ];
rng->drbg = XMALLOC(sizeof(DRBG), NULL, DYNAMIC_TYPE_RNG);
if (rng->drbg == NULL) {
rng->status = DRBG_FAILED;
ret = MEMORY_E;
}
/* This doesn't use a separate nonce. The entropy input will be /* This doesn't use a separate nonce. The entropy input will be
* the default size plus the size of the nonce making the seed * the default size plus the size of the nonce making the seed
* size. */ * size. */
if (GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 && else if (GenerateSeed(&rng->seed, entropy, ENTROPY_NONCE_SZ) == 0 &&
Hash_DRBG_Instantiate(rng, entropy, ENTROPY_NONCE_SZ, Hash_DRBG_Instantiate(rng->drbg, entropy, ENTROPY_NONCE_SZ,
NULL, 0) == DRBG_SUCCESS) { NULL, 0) == DRBG_SUCCESS) {
rng->status = DRBG_OK; rng->status = DRBG_OK;
ret = 0; ret = 0;
@ -351,7 +366,7 @@ int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
if (rng->status != DRBG_OK) if (rng->status != DRBG_OK)
return RNG_FAILURE_E; return RNG_FAILURE_E;
ret = Hash_DRBG_Generate(rng, output, sz); ret = Hash_DRBG_Generate(rng->drbg, output, sz);
if (ret == DRBG_SUCCESS) { if (ret == DRBG_SUCCESS) {
ret = 0; ret = 0;
} }
@ -359,8 +374,9 @@ int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz)
byte entropy[ENTROPY_SZ]; byte entropy[ENTROPY_SZ];
if (GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 && if (GenerateSeed(&rng->seed, entropy, ENTROPY_SZ) == 0 &&
Hash_DRBG_Reseed(rng, entropy, ENTROPY_SZ) == DRBG_SUCCESS && Hash_DRBG_Reseed(rng->drbg,
Hash_DRBG_Generate(rng, output, sz) == DRBG_SUCCESS) { entropy, ENTROPY_SZ) == DRBG_SUCCESS &&
Hash_DRBG_Generate(rng->drbg, output, sz) == DRBG_SUCCESS) {
ret = 0; ret = 0;
} }
@ -391,10 +407,14 @@ int FreeRng(RNG* rng)
int ret = BAD_FUNC_ARG; int ret = BAD_FUNC_ARG;
if (rng != NULL) { if (rng != NULL) {
if (Hash_DRBG_Uninstantiate(rng) == DRBG_SUCCESS) if (Hash_DRBG_Uninstantiate(rng->drbg) == DRBG_SUCCESS)
ret = 0; ret = 0;
else else
ret = RNG_FAILURE_E; ret = RNG_FAILURE_E;
XFREE(rng->drbg, NULL, DYNAMIC_TYPE_RNG);
rng->drbg = NULL;
rng->status = DRBG_NOT_INIT;
} }
return ret; return ret;
@ -405,35 +425,35 @@ int RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz,
const byte* entropyB, word32 entropyBSz, const byte* entropyB, word32 entropyBSz,
const byte* output, word32 outputSz) const byte* output, word32 outputSz)
{ {
RNG rng; DRBG drbg;
byte check[SHA256_DIGEST_SIZE * 4]; byte check[SHA256_DIGEST_SIZE * 4];
if (Hash_DRBG_Instantiate(&rng, entropyA, entropyASz, NULL, 0) != 0) if (Hash_DRBG_Instantiate(&drbg, entropyA, entropyASz, NULL, 0) != 0)
return -1; return -1;
if (reseed) { if (reseed) {
if (Hash_DRBG_Reseed(&rng, entropyB, entropyBSz) != 0) { if (Hash_DRBG_Reseed(&drbg, entropyB, entropyBSz) != 0) {
Hash_DRBG_Uninstantiate(&rng); Hash_DRBG_Uninstantiate(&drbg);
return -1; return -1;
} }
} }
if (Hash_DRBG_Generate(&rng, check, sizeof(check)) != 0) { if (Hash_DRBG_Generate(&drbg, check, sizeof(check)) != 0) {
Hash_DRBG_Uninstantiate(&rng); Hash_DRBG_Uninstantiate(&drbg);
return -1; return -1;
} }
if (Hash_DRBG_Generate(&rng, check, sizeof(check)) != 0) { if (Hash_DRBG_Generate(&drbg, check, sizeof(check)) != 0) {
Hash_DRBG_Uninstantiate(&rng); Hash_DRBG_Uninstantiate(&drbg);
return -1; return -1;
} }
if (outputSz != sizeof(check) || XMEMCMP(output, check, sizeof(check))) { if (outputSz != sizeof(check) || XMEMCMP(output, check, sizeof(check))) {
Hash_DRBG_Uninstantiate(&rng); Hash_DRBG_Uninstantiate(&drbg);
return -1; return -1;
} }
Hash_DRBG_Uninstantiate(&rng); Hash_DRBG_Uninstantiate(&drbg);
return 0; return 0;
} }

View File

@ -75,15 +75,13 @@ int GenerateSeed(OS_Seed* os, byte* seed, word32 sz);
#define DRBG_SEED_LEN (440/8) #define DRBG_SEED_LEN (440/8)
struct DRBG; /* Private DRBG state */
/* Hash-based Deterministic Random Bit Generator */ /* Hash-based Deterministic Random Bit Generator */
typedef struct RNG { typedef struct RNG {
OS_Seed seed; OS_Seed seed;
struct DRBG* drbg;
Sha256 sha;
byte digest[SHA256_DIGEST_SIZE];
byte V[DRBG_SEED_LEN];
byte C[DRBG_SEED_LEN];
word32 reseedCtr;
byte status; byte status;
} RNG; } RNG;

View File

@ -4746,6 +4746,14 @@ static int DoDtlsHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx,
|| defined(HAVE_AESGCM) || defined(HAVE_AESGCM)
static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify) static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify)
{ {
#ifdef CYASSL_DTLS
if (ssl->options.dtls) {
if (verify)
return ssl->keys.dtls_state.curSeq; /* explicit from peer */
else
return ssl->keys.dtls_sequence_number - 1; /* already incremented */
}
#endif
if (verify) if (verify)
return ssl->keys.peer_sequence_number++; return ssl->keys.peer_sequence_number++;
else else