From 8d8fca67c3043874f5fa0f43d037f4d2d938a6e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Guimar=C3=A3es?= Date: Mon, 14 Apr 2014 16:28:43 -0300 Subject: [PATCH] SHA256, SHA384 and SHA512 error propagation. Major impact on random functions with error propagation. --- ctaocrypt/src/asn.c | 16 +++-- ctaocrypt/src/dh.c | 15 +++-- ctaocrypt/src/dsa.c | 15 +++-- ctaocrypt/src/ecc.c | 8 ++- ctaocrypt/src/pkcs7.c | 17 +++-- ctaocrypt/src/random.c | 127 ++++++++++++++++++++++++++------------ ctaocrypt/src/rsa.c | 26 ++++++-- ctaocrypt/test/test.c | 36 +++++------ cyassl/ctaocrypt/random.h | 4 +- cyassl/test.h | 15 ++++- mcapi/crypto.c | 8 +-- src/internal.c | 71 ++++++++++++++------- src/keys.c | 17 +++-- src/ssl.c | 12 +++- 14 files changed, 259 insertions(+), 128 deletions(-) diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index c331a2239..80c11c0c7 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -4621,6 +4621,8 @@ static int SetName(byte* output, CertName* name) static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, RNG* rng, const byte* ntruKey, word16 ntruSz) { + int ret; + (void)eccKey; (void)ntruKey; (void)ntruSz; @@ -4632,7 +4634,10 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, der->versionSz = SetMyVersion(cert->version, der->version, TRUE); /* serial number */ - RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE); + ret = RNG_GenerateBlock(rng, cert->serial, CTC_SERIAL_SIZE); + if (ret != 0) + return ret; + cert->serial[0] = 0x01; /* ensure positive */ der->serialSz = SetSerial(cert->serial, der->serial); @@ -6167,10 +6172,13 @@ int EncodeOcspRequest(OcspRequest* req) if (InitRng(&rng) != 0) { CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce."); } else { - req->nonceSz = MAX_OCSP_NONCE_SZ; - RNG_GenerateBlock(&rng, req->nonce, req->nonceSz); - extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray, + if (RNG_GenerateBlock(&rng, req->nonce, MAX_OCSP_NONCE_SZ) != 0) + CYASSL_MSG("\tCannot run RNG. Skipping the OSCP Nonce."); + else { + req->nonceSz = MAX_OCSP_NONCE_SZ; + extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray, req->nonce, req->nonceSz); + } } } diff --git a/ctaocrypt/src/dh.c b/ctaocrypt/src/dh.c index 8fa32600d..1e1dd704e 100644 --- a/ctaocrypt/src/dh.c +++ b/ctaocrypt/src/dh.c @@ -82,15 +82,22 @@ static word32 DiscreteLogWorkFactor(word32 n) } -static void GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz) +static int GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz) { + int ret; word32 sz = mp_unsigned_bin_size(&key->p); sz = min(sz, 2 * DiscreteLogWorkFactor(sz * CYASSL_BIT_SIZE) / CYASSL_BIT_SIZE + 1); - RNG_GenerateBlock(rng, priv, sz); + + ret = RNG_GenerateBlock(rng, priv, sz); + if (ret != 0) + return ret; + priv[0] |= 0x0C; *privSz = sz; + + return 0; } @@ -127,9 +134,9 @@ static int GeneratePublic(DhKey* key, const byte* priv, word32 privSz, int DhGenerateKeyPair(DhKey* key, RNG* rng, byte* priv, word32* privSz, byte* pub, word32* pubSz) { - GeneratePrivate(key, rng, priv, privSz); - return GeneratePublic(key, priv, *privSz, pub, pubSz); + int ret = GeneratePrivate(key, rng, priv, privSz); + return (ret != 0) ? ret : GeneratePublic(key, priv, *privSz, pub, pubSz); } int DhAgree(DhKey* key, byte* agree, word32* agreeSz, const byte* priv, diff --git a/ctaocrypt/src/dsa.c b/ctaocrypt/src/dsa.c index ef2e67360..6ee78f72a 100644 --- a/ctaocrypt/src/dsa.c +++ b/ctaocrypt/src/dsa.c @@ -83,22 +83,25 @@ void FreeDsaKey(DsaKey* key) int DsaSign(const byte* digest, byte* out, DsaKey* key, RNG* rng) { mp_int k, kInv, r, s, H; - int ret = 0, sz; + int ret, sz; byte buffer[DSA_HALF_SIZE]; - if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY) - return MP_INIT_E; - sz = min(sizeof(buffer), mp_unsigned_bin_size(&key->q)); /* generate k */ - RNG_GenerateBlock(rng, buffer, sz); + ret = RNG_GenerateBlock(rng, buffer, sz); + if (ret != 0) + return ret; + buffer[0] |= 0x0C; + if (mp_init_multi(&k, &kInv, &r, &s, &H, 0) != MP_OKAY) + return MP_INIT_E; + if (mp_read_unsigned_bin(&k, buffer, sz) != MP_OKAY) ret = MP_READ_E; - if (mp_cmp_d(&k, 1) != MP_GT) + if (ret == 0 && mp_cmp_d(&k, 1) != MP_GT) ret = MP_CMP_E; /* inverse k mod q */ diff --git a/ctaocrypt/src/ecc.c b/ctaocrypt/src/ecc.c index 042c63123..32c827d0f 100644 --- a/ctaocrypt/src/ecc.c +++ b/ctaocrypt/src/ecc.c @@ -1333,7 +1333,10 @@ int ecc_make_key_ex(RNG* rng, ecc_key* key, const ecc_set_type* dp) base = NULL; /* make up random string */ - RNG_GenerateBlock(rng, buf, keysize); + err = RNG_GenerateBlock(rng, buf, keysize); + if (err != 0) + return err; + buf[0] |= 0x0c; /* setup the key variables */ @@ -3634,9 +3637,8 @@ static int ecc_ctx_set_salt(ecEncCtx* ctx, int flags, RNG* rng) return BAD_FUNC_ARG; saltBuffer = (flags == REQ_RESP_CLIENT) ? ctx->clientSalt : ctx->serverSalt; - RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ); - return 0; + return RNG_GenerateBlock(rng, saltBuffer, EXCHANGE_SALT_SZ); } diff --git a/ctaocrypt/src/pkcs7.c b/ctaocrypt/src/pkcs7.c index 71bfe18ba..5f83e12a2 100644 --- a/ctaocrypt/src/pkcs7.c +++ b/ctaocrypt/src/pkcs7.c @@ -980,8 +980,13 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) verSz = SetMyVersion(0, ver, 0); /* generate random content encryption key */ - InitRng(&rng); - RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz); + ret = InitRng(&rng); + if (ret != 0) + return ret; + + ret = RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz); + if (ret != 0) + return ret; /* build RecipientInfo, only handle 1 for now */ recipSz = CreateRecipientInfo(pkcs7->singleCert, pkcs7->singleCertSz, RSAk, @@ -995,6 +1000,11 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) } recipSetSz = SetSet(recipSz, recipSet); + /* generate IV for block cipher */ + ret = RNG_GenerateBlock(&rng, tmpIv, DES_BLOCK_SIZE); + if (ret != 0) + return ret; + /* EncryptedContentInfo */ contentTypeSz = SetContentType(pkcs7->contentOID, contentType); if (contentTypeSz == 0) @@ -1028,9 +1038,6 @@ int PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) return MEMORY_E; } - /* generate IV for block cipher */ - RNG_GenerateBlock(&rng, tmpIv, DES_BLOCK_SIZE); - /* put together IV OCTET STRING */ ivOctetStringSz = SetOctetString(DES_BLOCK_SIZE, ivOctetString); diff --git a/ctaocrypt/src/random.c b/ctaocrypt/src/random.c index 7e424e95a..ab39089c8 100644 --- a/ctaocrypt/src/random.c +++ b/ctaocrypt/src/random.c @@ -105,18 +105,32 @@ static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type, byte* inA, word { if (InitSha256(&rng->sha) != 0) return DBRG_ERROR; - Sha256Update(&rng->sha, &ctr, sizeof(ctr)); - Sha256Update(&rng->sha, (byte*)&bits, sizeof(bits)); - /* churning V is the only string that doesn't have + + if (Sha256Update(&rng->sha, &ctr, sizeof(ctr)) != 0) + return DBRG_ERROR; + + if (Sha256Update(&rng->sha, (byte*)&bits, sizeof(bits)) != 0) + return DBRG_ERROR; + + /* churning V is the only string that doesn't have * the type added */ if (type != dbrgInitV) - Sha256Update(&rng->sha, &type, sizeof(type)); - Sha256Update(&rng->sha, inA, inASz); + if (Sha256Update(&rng->sha, &type, sizeof(type)) != 0) + return DBRG_ERROR; + + if (Sha256Update(&rng->sha, inA, inASz) != 0) + return DBRG_ERROR; + if (inB != NULL && inBSz > 0) - Sha256Update(&rng->sha, inB, inBSz); + if (Sha256Update(&rng->sha, inB, inBSz) != 0) + return DBRG_ERROR; + if (inC != NULL && inCSz > 0) - Sha256Update(&rng->sha, inC, inCSz); - Sha256Final(&rng->sha, rng->digest); + if (Sha256Update(&rng->sha, inC, inCSz) != 0) + return DBRG_ERROR; + + if (Sha256Final(&rng->sha, rng->digest) != 0) + return DBRG_ERROR; if (outSz > SHA256_DIGEST_SIZE) { XMEMCPY(out, rng->digest, SHA256_DIGEST_SIZE); @@ -134,15 +148,22 @@ static int Hash_df(RNG* rng, byte* out, word32 outSz, byte type, byte* inA, word static int Hash_DBRG_Reseed(RNG* rng, byte* entropy, word32 entropySz) { + int ret; byte seed[DBRG_SEED_LEN]; - Hash_df(rng, seed, sizeof(seed), dbrgInitV, rng->V, sizeof(rng->V), - entropy, entropySz, NULL, 0); + ret = Hash_df(rng, seed, sizeof(seed), dbrgInitV, rng->V, sizeof(rng->V), + entropy, entropySz, NULL, 0); + if (ret != 0) + return ret; + XMEMCPY(rng->V, seed, sizeof(rng->V)); XMEMSET(seed, 0, sizeof(seed)); - Hash_df(rng, rng->C, sizeof(rng->C), dbrgInitC, rng->V, sizeof(rng->V), - NULL, 0, NULL, 0); + ret = Hash_df(rng, rng->C, sizeof(rng->C), dbrgInitC, rng->V, + sizeof(rng->V), NULL, 0, NULL, 0); + if (ret != 0) + return ret; + rng->reseed_ctr = 1; return 0; } @@ -168,9 +189,17 @@ static int Hash_gen(RNG* rng, byte* out, word32 outSz, byte* V) XMEMCPY(data, V, sizeof(data)); for (i = 0; i < len; i++) { ret = InitSha256(&rng->sha); - if (ret != 0) return ret; - Sha256Update(&rng->sha, data, sizeof(data)); - Sha256Final(&rng->sha, rng->digest); + if (ret != 0) + return ret; + + ret = Sha256Update(&rng->sha, data, sizeof(data)); + if (ret != 0) + return ret; + + ret = Sha256Final(&rng->sha, rng->digest); + if (ret != 0) + return ret; + if (outSz > SHA256_DIGEST_SIZE) { XMEMCPY(out, rng->digest, SHA256_DIGEST_SIZE); outSz -= SHA256_DIGEST_SIZE; @@ -217,9 +246,13 @@ static int Hash_DBRG_Generate(RNG* rng, byte* out, word32 outSz) return DBRG_ERROR; if (InitSha256(&rng->sha) != 0) return DBRG_ERROR; - Sha256Update(&rng->sha, &type, sizeof(type)); - Sha256Update(&rng->sha, rng->V, sizeof(rng->V)); - Sha256Final(&rng->sha, rng->digest); + if (Sha256Update(&rng->sha, &type, sizeof(type)) != 0) + return DBRG_ERROR; + if (Sha256Update(&rng->sha, rng->V, sizeof(rng->V)) != 0) + return DBRG_ERROR; + if (Sha256Final(&rng->sha, rng->digest) != 0) + return DBRG_ERROR; + array_add(rng->V, sizeof(rng->V), rng->digest, sizeof(rng->digest)); array_add(rng->V, sizeof(rng->V), rng->C, sizeof(rng->C)); array_add(rng->V, sizeof(rng->V), @@ -234,13 +267,24 @@ static int Hash_DBRG_Generate(RNG* rng, byte* out, word32 outSz) } -static void Hash_DBRG_Instantiate(RNG* rng, byte* seed, word32 seedSz) +static int Hash_DBRG_Instantiate(RNG* rng, byte* seed, word32 seedSz) { + int ret; + XMEMSET(rng, 0, sizeof(*rng)); - Hash_df(rng, rng->V, sizeof(rng->V), dbrgInitV, seed, seedSz, NULL, 0, NULL, 0); - Hash_df(rng, rng->C, sizeof(rng->C), dbrgInitC, rng->V, sizeof(rng->V), - NULL, 0, NULL, 0); + ret = Hash_df(rng, rng->V, sizeof(rng->V), dbrgInitV, seed, seedSz, NULL, 0, + NULL, 0); + if (ret != 0) + return ret; + + ret = Hash_df(rng, rng->C, sizeof(rng->C), dbrgInitC, rng->V, + sizeof(rng->V), NULL, 0, NULL, 0); + if (ret != 0) + return ret; + rng->reseed_ctr = 1; + + return 0; } @@ -266,42 +310,43 @@ int InitRng(RNG* rng) byte entropy[ENTROPY_SZ]; int ret = DBRG_ERROR; - if (GenerateSeed(&rng->seed, entropy, sizeof(entropy)) == 0) { - Hash_DBRG_Instantiate(rng, entropy, sizeof(entropy)); - ret = DBRG_SUCCESS; - } + if (GenerateSeed(&rng->seed, entropy, sizeof(entropy)) == 0) + ret = Hash_DBRG_Instantiate(rng, entropy, sizeof(entropy)); + XMEMSET(entropy, 0, sizeof(entropy)); return ret; } /* place a generated block in output */ -void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) +int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) { int ret; XMEMSET(output, 0, sz); ret = Hash_DBRG_Generate(rng, output, sz); + if (ret == DBRG_NEED_RESEED) { byte entropy[ENTROPY_SZ]; ret = GenerateSeed(&rng->seed, entropy, sizeof(entropy)); if (ret == 0) { - Hash_DBRG_Reseed(rng, entropy, sizeof(entropy)); - ret = Hash_DBRG_Generate(rng, output, sz); + ret = Hash_DBRG_Reseed(rng, entropy, sizeof(entropy)); + + if (ret == 0) + ret = Hash_DBRG_Generate(rng, output, sz); } else ret = DBRG_ERROR; XMEMSET(entropy, 0, sizeof(entropy)); } + + return ret; } -byte RNG_GenerateByte(RNG* rng) +int RNG_GenerateByte(RNG* rng, byte* b) { - byte b; - RNG_GenerateBlock(rng, &b, 1); - - return b; + return RNG_GenerateBlock(rng, b, 1); } @@ -327,7 +372,8 @@ int InitRng(RNG* rng) if (ret == 0) { Arc4SetKey(&rng->cipher, key, sizeof(key)); - RNG_GenerateBlock(rng, junk, sizeof(junk)); /* rid initial state */ + + return RNG_GenerateBlock(rng, junk, sizeof(junk)); /*rid initial state*/ } return ret; @@ -338,7 +384,7 @@ int InitRng(RNG* rng) #endif /* place a generated block in output */ -void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) +int RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) { #ifdef HAVE_CAVIUM if (rng->magic == CYASSL_RNG_CAVIUM_MAGIC) @@ -346,15 +392,14 @@ void RNG_GenerateBlock(RNG* rng, byte* output, word32 sz) #endif XMEMSET(output, 0, sz); Arc4Process(&rng->cipher, output, output, sz); + + return 0; } -byte RNG_GenerateByte(RNG* rng) +int RNG_GenerateByte(RNG* rng, byte* b) { - byte b; - RNG_GenerateBlock(rng, &b, 1); - - return b; + return RNG_GenerateBlock(rng, b, 1); } diff --git a/ctaocrypt/src/rsa.c b/ctaocrypt/src/rsa.c index 05c008e5c..648d56f1b 100644 --- a/ctaocrypt/src/rsa.c +++ b/ctaocrypt/src/rsa.c @@ -124,10 +124,11 @@ int FreeRsaKey(RsaKey* key) return 0; } -static void RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, +static int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, word32 pkcsBlockLen, byte padValue, RNG* rng) { - if (inputLen == 0) return; + if (inputLen == 0) + return 0; pkcsBlock[0] = 0x0; /* set first byte to zero and advance */ pkcsBlock++; pkcsBlockLen--; @@ -139,7 +140,10 @@ static void RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, else { /* pad with non-zero random bytes */ word32 padLen = pkcsBlockLen - inputLen - 1, i; - RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); + int ret = RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); + + if (ret != 0) + return ret; /* remove zeros */ for (i = 1; i < padLen; i++) @@ -148,6 +152,8 @@ static void RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */ XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen); + + return 0; } @@ -297,7 +303,9 @@ int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) return RSA_BUFFER_E; - RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng); + ret = RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng); + if (ret != 0) + return ret; if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PUBLIC_ENCRYPT, key)) < 0) sz = ret; @@ -444,7 +452,9 @@ int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) return RSA_BUFFER_E; - RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng); + ret = RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng); + if (ret != 0) + return ret; if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PRIVATE_ENCRYPT,key)) < 0) sz = ret; @@ -502,7 +512,11 @@ static int rand_prime(mp_int* N, int len, RNG* rng, void* heap) fflush(stdout); #endif /* generate value */ - RNG_GenerateBlock(rng, buf, len); + err = RNG_GenerateBlock(rng, buf, len); + if (err != 0) { + XFREE(buf, heap, DYNAMIC_TYPE_RSA); + return err; + } /* munge bits */ buf[0] |= 0x80 | 0x40; diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index bb5f18003..c499d0728 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -2586,7 +2586,8 @@ int random_test(void) ret = InitRng(&rng); if (ret != 0) return -39; - RNG_GenerateBlock(&rng, block, sizeof(block)); + ret = RNG_GenerateBlock(&rng, block, sizeof(block)); + if (ret != 0) return -40; return 0; } @@ -2600,21 +2601,14 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out) { static RNG rng; - if (cmd == INIT) { - int ret = InitRng(&rng); - if (ret == 0) - return 1; - else - return 0; - } + if (cmd == INIT) + return (InitRng(&rng) == 0) ? 1 : 0; if (out == NULL) return 0; - if (cmd == GET_BYTE_OF_ENTROPY) { - RNG_GenerateBlock(&rng, out, 1); - return 1; - } + if (cmd == GET_BYTE_OF_ENTROPY) + return (RNG_GenerateBlock(&rng, out, 1) == 0) ? 1 : 0; if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) { *out = 1; @@ -4334,9 +4328,15 @@ int pkcs7signed_test(void) fclose(file); ret = InitRng(&rng); + if (ret != 0) + return -210; + senderNonce[0] = 0x04; senderNonce[1] = PKCS7_NONCE_SZ; - RNG_GenerateBlock(&rng, &senderNonce[2], PKCS7_NONCE_SZ); + + ret = RNG_GenerateBlock(&rng, &senderNonce[2], PKCS7_NONCE_SZ); + if (ret != 0) + return -211; PKCS7_InitWithCert(&msg, certDer, certDerSz); msg.privateKey = keyDer; @@ -4372,7 +4372,7 @@ int pkcs7signed_test(void) free(keyDer); free(out); PKCS7_Free(&msg); - return -210; + return -212; } else outSz = ret; @@ -4384,7 +4384,7 @@ int pkcs7signed_test(void) free(keyDer); free(out); PKCS7_Free(&msg); - return -211; + return -213; } ret = (int)fwrite(out, 1, outSz, file); fclose(file); @@ -4398,7 +4398,7 @@ int pkcs7signed_test(void) free(keyDer); free(out); PKCS7_Free(&msg); - return -212; + return -214; } if (msg.singleCert == NULL || msg.singleCertSz == 0) { @@ -4406,7 +4406,7 @@ int pkcs7signed_test(void) free(keyDer); free(out); PKCS7_Free(&msg); - return -213; + return -215; } file = fopen("./pkcs7cert.der", "wb"); @@ -4415,7 +4415,7 @@ int pkcs7signed_test(void) free(keyDer); free(out); PKCS7_Free(&msg); - return -214; + return -216; } ret = (int)fwrite(msg.singleCert, 1, msg.singleCertSz, file); fclose(file); diff --git a/cyassl/ctaocrypt/random.h b/cyassl/ctaocrypt/random.h index 8a11fbc09..576744028 100644 --- a/cyassl/ctaocrypt/random.h +++ b/cyassl/ctaocrypt/random.h @@ -104,8 +104,8 @@ typedef struct RNG { #endif CYASSL_API int InitRng(RNG*); -CYASSL_API void RNG_GenerateBlock(RNG*, byte*, word32 sz); -CYASSL_API byte RNG_GenerateByte(RNG*); +CYASSL_API int RNG_GenerateBlock(RNG*, byte*, word32 sz); +CYASSL_API int RNG_GenerateByte(RNG*, byte*); #ifdef NO_RC4 CYASSL_API void FreeRng(RNG*); diff --git a/cyassl/test.h b/cyassl/test.h index 64cc1171d..667476ed2 100644 --- a/cyassl/test.h +++ b/cyassl/test.h @@ -1532,7 +1532,10 @@ static INLINE int myEccSign(CYASSL* ssl, const byte* in, word32 inSz, (void)ssl; (void)ctx; - InitRng(&rng); + ret = InitRng(&rng); + if (ret != 0) + return ret; + ecc_init(&myKey); ret = EccPrivateKeyDecode(key, &idx, &myKey, keySz); @@ -1579,7 +1582,10 @@ static INLINE int myRsaSign(CYASSL* ssl, const byte* in, word32 inSz, (void)ssl; (void)ctx; - InitRng(&rng); + ret = InitRng(&rng); + if (ret != 0) + return ret; + InitRsaKey(&myKey, NULL); ret = RsaPrivateKeyDecode(key, &idx, &myKey, keySz); @@ -1630,7 +1636,10 @@ static INLINE int myRsaEnc(CYASSL* ssl, const byte* in, word32 inSz, (void)ssl; (void)ctx; - InitRng(&rng); + ret = InitRng(&rng); + if (ret != 0) + return ret; + InitRsaKey(&myKey, NULL); ret = RsaPublicKeyDecode(key, &idx, &myKey, keySz); diff --git a/mcapi/crypto.c b/mcapi/crypto.c index 44dafd800..d72324494 100644 --- a/mcapi/crypto.c +++ b/mcapi/crypto.c @@ -301,9 +301,7 @@ int CRYPT_RNG_Get(CRYPT_RNG_CTX* rng, unsigned char* b) if (rng == NULL || b == NULL) return BAD_FUNC_ARG; - *b = RNG_GenerateByte((RNG*)rng); - - return 0; + return RNG_GenerateByte((RNG*)rng, (byte*)b); } @@ -314,9 +312,7 @@ int CRYPT_RNG_BlockGenerate(CRYPT_RNG_CTX* rng, unsigned char* b, if (rng == NULL || b == NULL) return BAD_FUNC_ARG; - RNG_GenerateBlock((RNG*)rng, b, sz); - - return 0; + return RNG_GenerateBlock((RNG*)rng, b, sz); } diff --git a/src/internal.c b/src/internal.c index 4aeb7a3ac..047f6667c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -156,21 +156,14 @@ static byte GetEntropy(ENTROPY_CMD cmd, byte* out) /* TODO: add locking? */ static RNG rng; - if (cmd == INIT) { - int ret = InitRng(&rng); - if (ret == 0) - return 1; - else - return 0; - } + if (cmd == INIT) + return (InitRng(&rng) == 0) ? 1 : 0; if (out == NULL) return 0; - if (cmd == GET_BYTE_OF_ENTROPY) { - RNG_GenerateBlock(&rng, out, 1); - return 1; - } + if (cmd == GET_BYTE_OF_ENTROPY) + return (RNG_GenerateBlock(&rng, out, 1) == 0) ? 1 : 0; if (cmd == GET_NUM_BYTES_PER_BYTE_OF_ENTROPY) { *out = 1; @@ -5612,7 +5605,11 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, if (ssl->options.tls1_1) { ivSz = blockSz; sz += ivSz; - RNG_GenerateBlock(ssl->rng, iv, ivSz); + + ret = RNG_GenerateBlock(ssl->rng, iv, ivSz); + if (ret != 0) + return ret; + } sz += 1; /* pad byte */ pad = (sz - headerSz) % blockSz; @@ -7544,7 +7541,9 @@ static void PickHashSigAlgo(CYASSL* ssl, /* then random */ if (ssl->options.connectState == CONNECT_BEGIN) { - RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN); + ret = RNG_GenerateBlock(ssl->rng, output + idx, RAN_LEN); + if (ret != 0) + return ret; /* store random */ XMEMCPY(ssl->arrays->clientRandom, output + idx, RAN_LEN); @@ -8338,8 +8337,11 @@ static void PickHashSigAlgo(CYASSL* ssl, switch (ssl->specs.kea) { #ifndef NO_RSA case rsa_kea: - RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, - SECRET_LEN); + ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, + SECRET_LEN); + if (ret != 0) + return ret; + ssl->arrays->preMasterSecret[0] = ssl->chVersion.major; ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor; ssl->arrays->preMasterSz = SECRET_LEN; @@ -8441,8 +8443,11 @@ static void PickHashSigAlgo(CYASSL* ssl, 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U' }; - RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, - SECRET_LEN); + ret = RNG_GenerateBlock(ssl->rng, + ssl->arrays->preMasterSecret, SECRET_LEN); + if (ret != 0) + return ret; + ssl->arrays->preMasterSz = SECRET_LEN; if (ssl->peerNtruKeyPresent == 0) @@ -8911,8 +8916,13 @@ static void PickHashSigAlgo(CYASSL* ssl, output[idx++] = ssl->version.minor; /* then random */ - if (!ssl->options.resuming) - RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN); + if (!ssl->options.resuming) { + ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, + RAN_LEN); + if (ret != 0) + return ret; + } + XMEMCPY(output + idx, ssl->arrays->serverRandom, RAN_LEN); idx += RAN_LEN; @@ -8927,8 +8937,13 @@ static void PickHashSigAlgo(CYASSL* ssl, #endif /* then session id */ output[idx++] = ID_LEN; - if (!ssl->options.resuming) - RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID, ID_LEN); + + if (!ssl->options.resuming) { + ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->sessionID, ID_LEN); + if (ret != 0) + return ret; + } + XMEMCPY(output + idx, ssl->arrays->sessionID, ID_LEN); idx += ID_LEN; @@ -10401,7 +10416,12 @@ static void PickHashSigAlgo(CYASSL* ssl, #ifdef SESSION_CERTS ssl->session = *session; /* restore session certs. */ #endif - RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN); + + ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, + RAN_LEN); + if (ret != 0) + return ret; + #ifdef NO_OLD_TLS ret = DeriveTlsKeys(ssl); #else @@ -10678,7 +10698,12 @@ static void PickHashSigAlgo(CYASSL* ssl, #ifdef SESSION_CERTS ssl->session = *session; /* restore session certs. */ #endif - RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, RAN_LEN); + + ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->serverRandom, + RAN_LEN); + if (ret != 0) + return ret; + #ifdef NO_OLD_TLS ret = DeriveTlsKeys(ssl); #else diff --git a/src/keys.c b/src/keys.c index 33ae8af64..463ba9f4c 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1900,18 +1900,21 @@ int DeriveKeys(CYASSL* ssl) } -static void CleanPreMaster(CYASSL* ssl) +static int CleanPreMaster(CYASSL* ssl) { - int i, sz = ssl->arrays->preMasterSz; + int i, ret, sz = ssl->arrays->preMasterSz; for (i = 0; i < sz; i++) ssl->arrays->preMasterSecret[i] = 0; - RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, sz); + ret = RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, sz); + if (ret != 0) + return ret; for (i = 0; i < sz; i++) ssl->arrays->preMasterSecret[i] = 0; + return 0; } @@ -1982,9 +1985,13 @@ static int MakeSslMasterSecret(CYASSL* ssl) #endif ret = DeriveKeys(ssl); - CleanPreMaster(ssl); + if (ret != 0) { + /* always try to clean PreMaster */ + CleanPreMaster(ssl); + return ret; + } - return ret; + return CleanPreMaster(ssl); } #endif diff --git a/src/ssl.c b/src/ssl.c index f736bc301..f915d81fe 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -9545,6 +9545,7 @@ static int initGlobalRNG = 0; if (initGlobalRNG == 0) { if (InitRng(&globalRNG) < 0) { CYASSL_MSG("CyaSSL Init Global RNG failed"); + return 0; } initGlobalRNG = 1; } @@ -9569,7 +9570,10 @@ static int initGlobalRNG = 0; rng = &globalRNG; } - RNG_GenerateBlock(rng, buf, num); + if (RNG_GenerateBlock(rng, buf, num) != 0) { + CYASSL_MSG("Bad RNG_GenerateBlock"); + return 0; + } return SSL_SUCCESS; } @@ -9864,7 +9868,11 @@ static int initGlobalRNG = 0; rng = &globalRNG; } - RNG_GenerateBlock(rng, buff, len); + if (RNG_GenerateBlock(rng, buff, len) != 0) { + CYASSL_MSG("Bad RNG_GenerateBlock"); + return 0; + } + buff[0] |= 0x80 | 0x40; buff[len-1] |= 0x01;