From 3607db9077d6e6d08a62996f086d7a6c2c30b698 Mon Sep 17 00:00:00 2001 From: toddouska Date: Tue, 25 Mar 2014 16:01:17 -0700 Subject: [PATCH] add SHA1 fips mode --- ctaocrypt/benchmark/benchmark.c | 8 +++- ctaocrypt/src/asn.c | 44 ++++++++++++++------ ctaocrypt/src/hmac.c | 6 ++- ctaocrypt/src/pkcs7.c | 12 ++++-- ctaocrypt/src/pwdbased.c | 10 +++-- ctaocrypt/src/sha.c | 21 ++++++++-- ctaocrypt/test/test.c | 13 ++++-- cyassl/ctaocrypt/sha.h | 25 ++++++++--- cyassl/internal.h | 4 +- mcapi/crypto.c | 4 +- mcapi/mcapi_test.c | 9 +++- src/internal.c | 73 ++++++++++++++++++++++----------- src/io.c | 5 ++- src/keys.c | 9 +++- src/ssl.c | 59 ++++++++++++++++++++------ src/tls.c | 4 +- tests/hash.c | 5 ++- 17 files changed, 230 insertions(+), 81 deletions(-) diff --git a/ctaocrypt/benchmark/benchmark.c b/ctaocrypt/benchmark/benchmark.c index f32bcfa38..9f19c5715 100644 --- a/ctaocrypt/benchmark/benchmark.c +++ b/ctaocrypt/benchmark/benchmark.c @@ -586,9 +586,13 @@ void bench_sha(void) Sha hash; byte digest[SHA_DIGEST_SIZE]; double start, total, persec; - int i; + int i, ret; - InitSha(&hash); + ret = InitSha(&hash); + if (ret != 0) { + printf("InitSha failed, ret = %d\n", ret); + return; + } start = current_time(1); for(i = 0; i < numBlocks; i++) diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index b492d2151..43817ce73 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -1587,6 +1587,7 @@ static int GetName(DecodedCert* cert, int nameType) Sha sha; /* MUST have SHA-1 hash for cert names */ int length; /* length of all distinguished names */ int dummy; + int ret; char* full = (nameType == ISSUER) ? cert->issuer : cert->subject; word32 idx; #ifdef OPENSSL_EXTRA @@ -1613,7 +1614,9 @@ static int GetName(DecodedCert* cert, int nameType) if (GetSequence(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) return ASN_PARSE_E; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, &cert->source[idx], length + cert->srcIdx - idx); if (nameType == ISSUER) ShaFinal(&sha, cert->issuerHash); @@ -2664,7 +2667,11 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, case CTC_SHAwECDSA: { Sha sha; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) { + CYASSL_MSG("InitSha failed"); + return 0; /* not confirmed */ + } ShaUpdate(&sha, buf, bufSz); ShaFinal(&sha, digest); typeH = SHAh; @@ -3152,7 +3159,7 @@ static int DecodeAuthInfo(byte* input, int sz, DecodedCert* cert) static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert) { word32 idx = 0; - int length = 0; + int length = 0, ret = 0; CYASSL_ENTER("DecodeAuthKeyId"); @@ -3181,7 +3188,9 @@ static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert) } else { Sha sha; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, input + idx, length); ShaFinal(&sha, cert->extAuthKeyId); } @@ -3193,7 +3202,7 @@ static int DecodeAuthKeyId(byte* input, int sz, DecodedCert* cert) static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert) { word32 idx = 0; - int length = 0; + int length = 0, ret = 0; CYASSL_ENTER("DecodeSubjKeyId"); @@ -3217,12 +3226,14 @@ static int DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert) } else { Sha sha; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, input + idx, length); ShaFinal(&sha, cert->extSubjKeyId); } - return 0; + return ret; } @@ -3604,7 +3615,9 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) if (cert->extSubjKeyIdSet == 0 && cert->publicKey != NULL && cert->pubKeySize > 0) { Sha sha; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, cert->publicKey, cert->pubKeySize); ShaFinal(&sha, cert->extSubjKeyId); } @@ -3627,7 +3640,9 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) /* Need the ca's public key hash for OCSP */ { Sha sha; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, ca->publicKey, ca->pubKeySize); ShaFinal(&sha, cert->issuerKeyHash); } @@ -4718,7 +4733,7 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz, { byte digest[SHA256_DIGEST_SIZE]; /* max size */ byte encSig[MAX_ENCODED_DIG_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ]; - int encSigSz, digestSz, typeH; + int encSigSz, digestSz, typeH, ret = 0; (void)eccKey; @@ -4732,7 +4747,9 @@ static int MakeSignature(const byte* buffer, int sz, byte* sig, int sigSz, } else if (sigAlgoType == CTC_SHAwRSA || sigAlgoType == CTC_SHAwECDSA) { Sha sha; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, buffer, sz); ShaFinal(&sha, digest); digestSz = SHA_DIGEST_SIZE; @@ -6202,6 +6219,7 @@ CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, { Sha sha; int length; /* length of all distinguished names */ + int ret = 0; word32 dummy; CYASSL_ENTER("GetNameHash"); @@ -6223,7 +6241,9 @@ CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, if (GetSequence(source, idx, &length, maxIdx) < 0) return ASN_PARSE_E; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, source + dummy, length + *idx - dummy); ShaFinal(&sha, hash); diff --git a/ctaocrypt/src/hmac.c b/ctaocrypt/src/hmac.c index 25c867997..43cf18e6d 100644 --- a/ctaocrypt/src/hmac.c +++ b/ctaocrypt/src/hmac.c @@ -56,6 +56,8 @@ static int InitHmac(Hmac* hmac, int type) { + int ret = 0; + hmac->innerHashKeyed = 0; hmac->macType = (byte)type; @@ -72,7 +74,7 @@ static int InitHmac(Hmac* hmac, int type) #ifndef NO_SHA case SHA: - InitSha(&hmac->hash.sha); + ret = InitSha(&hmac->hash.sha); break; #endif @@ -104,7 +106,7 @@ static int InitHmac(Hmac* hmac, int type) return BAD_FUNC_ARG; } - return 0; + return ret; } diff --git a/ctaocrypt/src/pkcs7.c b/ctaocrypt/src/pkcs7.c index de55e2b03..1f7cc010a 100644 --- a/ctaocrypt/src/pkcs7.c +++ b/ctaocrypt/src/pkcs7.c @@ -328,7 +328,7 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) ESD esd; word32 signerInfoSz = 0; word32 totalSz = 0; - int idx = 0; + int idx = 0, ret = 0; byte* flatSignedAttribs = NULL; word32 flatSignedAttribsSz = 0; word32 innerOidSz = sizeof(innerOid); @@ -342,7 +342,9 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) return BAD_FUNC_ARG; XMEMSET(&esd, 0, sizeof(esd)); - InitSha(&esd.sha); + ret = InitSha(&esd.sha); + if (ret != 0) + return ret; if (pkcs7->contentSz != 0) { @@ -431,7 +433,11 @@ int PKCS7_EncodeSignedData(PKCS7* pkcs7, byte* output, word32 outputSz) attribSetSz = SetSet(flatSignedAttribsSz, attribSet); - InitSha(&esd.sha); + ret = InitSha(&esd.sha); + if (result < 0) { + XFREE(flatSignedAttribs, 0, NULL); + return ret; + } ShaUpdate(&esd.sha, attribSet, attribSetSz); ShaUpdate(&esd.sha, flatSignedAttribs, flatSignedAttribsSz); } diff --git a/ctaocrypt/src/pwdbased.c b/ctaocrypt/src/pwdbased.c index 6152292ca..3244ea7a7 100644 --- a/ctaocrypt/src/pwdbased.c +++ b/ctaocrypt/src/pwdbased.c @@ -74,7 +74,7 @@ int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, Md5 md5; Sha sha; int hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE; - int i; + int i, ret = 0; byte buffer[SHA_DIGEST_SIZE]; /* max size */ if (hashType != MD5 && hashType != SHA) @@ -93,7 +93,9 @@ int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, Md5Final(&md5, buffer); } else { - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, passwd, pLen); ShaUpdate(&sha, salt, sLen); ShaFinal(&sha, buffer); @@ -269,7 +271,9 @@ int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, else if (hashType == SHA) { Sha sha; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + break; ShaUpdate(&sha, buffer, totalLen); ShaFinal(&sha, Ai); diff --git a/ctaocrypt/src/sha.c b/ctaocrypt/src/sha.c index 198ca53a8..b826686bb 100644 --- a/ctaocrypt/src/sha.c +++ b/ctaocrypt/src/sha.c @@ -34,6 +34,11 @@ #define ShaFinal ShaFinal_sw #endif +#ifdef HAVE_FIPS + /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ + #define FIPS_NO_WRAPPERS +#endif + #include #ifdef NO_INLINE #include @@ -58,7 +63,7 @@ #include "stm32f2xx.h" #include "stm32f2xx_hash.h" - void InitSha(Sha* sha) + int InitSha(Sha* sha) { /* STM32F2 struct notes: * sha->buffer = first 4 bytes used to hold partial block if needed @@ -79,9 +84,11 @@ /* reset HASH processor */ HASH->CR |= HASH_CR_INIT; + + return 0; } - void ShaUpdate(Sha* sha, const byte* data, word32 len) + int ShaUpdate(Sha* sha, const byte* data, word32 len) { word32 i = 0; word32 fill = 0; @@ -125,6 +132,8 @@ /* keep track of total data length thus far */ sha->loLen += (len - sha->buffLen); + + return 0; } void ShaFinal(Sha* sha, byte* hash) @@ -175,7 +184,7 @@ #endif /* min */ -void InitSha(Sha* sha) +int InitSha(Sha* sha) { #ifdef FREESCALE_MMCAU cau_sha1_initialize_output(sha->digest); @@ -190,6 +199,8 @@ void InitSha(Sha* sha) sha->buffLen = 0; sha->loLen = 0; sha->hiLen = 0; + + return 0; } #ifndef FREESCALE_MMCAU @@ -302,7 +313,7 @@ static INLINE void AddLength(Sha* sha, word32 len) } -void ShaUpdate(Sha* sha, const byte* data, word32 len) +int ShaUpdate(Sha* sha, const byte* data, word32 len) { /* do block size increments */ byte* local = (byte*)sha->buffer; @@ -324,6 +335,8 @@ void ShaUpdate(Sha* sha, const byte* data, word32 len) sha->buffLen = 0; } } + + return 0; } diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 17d7c6efd..bc960651d 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -767,6 +767,7 @@ int sha_test(void) testVector a, b, c, d; testVector test_sha[4]; + int ret; int times = sizeof(test_sha) / sizeof(struct testVector), i; a.input = "abc"; @@ -801,7 +802,9 @@ int sha_test(void) test_sha[2] = c; test_sha[3] = d; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return -4001; for (i = 0; i < times; ++i) { ShaUpdate(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); @@ -3310,7 +3313,9 @@ int dsa_test(void) fclose(file); #endif /* USE_CERT_BUFFERS */ - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return -4002; ShaUpdate(&sha, tmp, bytes); ShaFinal(&sha, hash); @@ -4273,7 +4278,9 @@ int pkcs7signed_test(void) transId[0] = 0x13; transId[1] = SHA_DIGEST_SIZE * 2; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return -4003; ShaUpdate(&sha, msg.publicKey, msg.publicKeySz); ShaFinal(&sha, digest); diff --git a/cyassl/ctaocrypt/sha.h b/cyassl/ctaocrypt/sha.h index 4904f9b92..16d5fc026 100644 --- a/cyassl/ctaocrypt/sha.h +++ b/cyassl/ctaocrypt/sha.h @@ -54,19 +54,34 @@ typedef struct Sha { word32 hiLen; /* length in bytes */ word32 buffer[SHA_BLOCK_SIZE / sizeof(word32)]; #ifndef CYASSL_PIC32MZ_HASH - word32 digest[SHA_DIGEST_SIZE / sizeof(word32)]; + word32 digest[SHA_DIGEST_SIZE / sizeof(word32)]; #else - word32 digest[PIC32_HASH_SIZE / sizeof(word32)]; - pic32mz_desc desc ; /* Crypt Engine descripter */ + word32 digest[PIC32_HASH_SIZE / sizeof(word32)]; + pic32mz_desc desc; /* Crypt Engine descripter */ #endif } Sha; -CYASSL_API void InitSha(Sha*); -CYASSL_API void ShaUpdate(Sha*, const byte*, word32); +CYASSL_API int InitSha(Sha*); +CYASSL_API int ShaUpdate(Sha*, const byte*, word32); CYASSL_API void ShaFinal(Sha*, byte*); +#ifdef HAVE_FIPS + /* fips wrapper calls, user can call direct */ + CYASSL_API int InitSha_fips(Sha*); + CYASSL_API int ShaUpdate_fips(Sha*, const byte*, word32); + CYASSL_API int ShaFinal_fips(Sha*, byte*); + #ifndef FIPS_NO_WRAPPERS + /* if not impl or fips.c impl wrapper force fips calls if fips build */ + #define InitSha InitSha_fips + #define ShaUpdate ShaUpdate_fips + #define ShaFinal ShaFinal_fips + #endif /* FIPS_NO_WRAPPERS */ + +#endif /* HAVE_FIPS */ + + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/cyassl/internal.h b/cyassl/internal.h index 7c6abd5ad..c4610e0bc 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1524,7 +1524,7 @@ CYASSL_SESSION* GetSession(CYASSL*, byte*); CYASSL_LOCAL int SetSession(CYASSL*, CYASSL_SESSION*); -typedef void (*hmacfp) (CYASSL*, byte*, const byte*, word32, int, int); +typedef int (*hmacfp) (CYASSL*, byte*, const byte*, word32, int, int); #ifndef NO_CLIENT_CACHE CYASSL_SESSION* GetSessionClient(CYASSL*, const byte*, int); @@ -2078,7 +2078,7 @@ CYASSL_LOCAL int GrowInputBuffer(CYASSL* ssl, int size, int usedLength); #ifndef NO_TLS CYASSL_LOCAL int MakeTlsMasterSecret(CYASSL*); - CYASSL_LOCAL void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, + CYASSL_LOCAL int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, int content, int verify); #endif diff --git a/mcapi/crypto.c b/mcapi/crypto.c index 1557ac93e..a23f00f6d 100644 --- a/mcapi/crypto.c +++ b/mcapi/crypto.c @@ -91,9 +91,7 @@ int CRYPT_SHA_Initialize(CRYPT_SHA_CTX* sha) if (sha == NULL) return BAD_FUNC_ARG; - InitSha((Sha*)sha); - - return 0; + return InitSha((Sha*)sha); } diff --git a/mcapi/mcapi_test.c b/mcapi/mcapi_test.c index 5f2a84ea3..27a89a55c 100644 --- a/mcapi/mcapi_test.c +++ b/mcapi/mcapi_test.c @@ -240,11 +240,16 @@ static int check_sha(void) { CRYPT_SHA_CTX mcSha; Sha defSha; + int ret = 0; byte mcDigest[CRYPT_SHA_DIGEST_SIZE]; byte defDigest[SHA_DIGEST_SIZE]; CRYPT_SHA_Initialize(&mcSha); - InitSha(&defSha); + ret = InitSha(&defSha); + if (ret != 0) { + printf("sha init default failed\n"); + return -1; + } CRYPT_SHA_DataAdd(&mcSha, ourData, OUR_DATA_SIZE); ShaUpdate(&defSha, ourData, OUR_DATA_SIZE); @@ -253,7 +258,7 @@ static int check_sha(void) ShaFinal(&defSha, defDigest); if (memcmp(mcDigest, defDigest, CRYPT_SHA_DIGEST_SIZE) != 0) { - printf("sha final memcmp fialed\n"); + printf("sha final memcmp failed\n"); return -1; } printf("sha mcapi test passed\n"); diff --git a/src/internal.c b/src/internal.c index f29aab589..1983957d6 100644 --- a/src/internal.c +++ b/src/internal.c @@ -107,8 +107,8 @@ typedef enum { } processReply; #ifndef NO_OLD_TLS -static void SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, - int content, int verify); +static int SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, + int content, int verify); #endif @@ -1444,7 +1444,10 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) InitMd5(&ssl->hashMd5); #endif #ifndef NO_SHA - InitSha(&ssl->hashSha); + ret = InitSha(&ssl->hashSha); + if (ret != 0) { + return ret; + } #endif #endif #ifndef NO_SHA256 @@ -3647,6 +3650,8 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx, static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx, word32 size, word32 totalSz) { + int ret = 0; + if (size) /* must be 0 */ return BUFFER_ERROR; @@ -3655,8 +3660,10 @@ static int DoHelloRequest(CYASSL* ssl, const byte* input, word32* inOutIdx, int padSz = ssl->keys.encryptSz - HANDSHAKE_HEADER_SZ - ssl->specs.hash_size; - ssl->hmac(ssl, verify, input + *inOutIdx - HANDSHAKE_HEADER_SZ, - HANDSHAKE_HEADER_SZ, handshake, 1); + ret = ssl->hmac(ssl, verify, input + *inOutIdx - HANDSHAKE_HEADER_SZ, + HANDSHAKE_HEADER_SZ, handshake, 1); + if (ret != 0) + return ret; if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) padSz -= ssl->specs.block_size; @@ -4413,12 +4420,13 @@ static INLINE void Md5Rounds(int rounds, const byte* data, int sz) +/* do a dummy sha round */ static INLINE void ShaRounds(int rounds, const byte* data, int sz) { Sha sha; int i; - InitSha(&sha); + InitSha(&sha); /* no error check on purpose, dummy round */ for (i = 0; i < rounds; i++) ShaUpdate(&sha, data, sz); @@ -4490,6 +4498,7 @@ static INLINE void RmdRounds(int rounds, const byte* data, int sz) #endif +/* Do dummy rounds */ static INLINE void DoRounds(int type, int rounds, const byte* data, int sz) { switch (type) { @@ -4625,13 +4634,14 @@ static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t, { byte verify[MAX_DIGEST_SIZE]; byte dummy[MAX_PAD_SIZE]; + int ret = 0; XMEMSET(dummy, 1, sizeof(dummy)); if ( (t + padLen + 1) > pLen) { CYASSL_MSG("Plain Len not long enough for pad/mac"); PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE); - ssl->hmac(ssl, verify, input, pLen - t, content, 1); + ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */ ConstantCompare(verify, input + pLen - t, t); return VERIFY_MAC_ERROR; @@ -4640,14 +4650,14 @@ static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t, if (PadCheck(input + pLen - (padLen + 1), (byte)padLen, padLen + 1) != 0) { CYASSL_MSG("PadCheck failed"); PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1); - ssl->hmac(ssl, verify, input, pLen - t, content, 1); + ssl->hmac(ssl, verify, input, pLen - t, content, 1); /* still compare */ ConstantCompare(verify, input + pLen - t, t); return VERIFY_MAC_ERROR; } PadCheck(dummy, (byte)padLen, MAX_PAD_SIZE - padLen - 1); - ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1); + ret = ssl->hmac(ssl, verify, input, pLen - padLen - 1 - t, content, 1); CompressRounds(ssl, GetRounds(pLen, padLen, t), dummy); @@ -4656,7 +4666,7 @@ static int TimingPadVerify(CYASSL* ssl, const byte* input, int padLen, int t, return VERIFY_MAC_ERROR; } - return 0; + return ret; } @@ -4849,18 +4859,22 @@ static INLINE int VerifyMac(CYASSL* ssl, const byte* input, word32 msgSz, return ret; } else { /* sslv3, some implementations have bad padding */ - ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1, - content, 1); + ret = ssl->hmac(ssl, verify, input, msgSz - digestSz - pad - 1, + content, 1); if (ConstantCompare(verify, input + msgSz - digestSz - pad - 1, digestSz) != 0) return VERIFY_MAC_ERROR; + if (ret != 0) + return VERIFY_MAC_ERROR; } } else if (ssl->specs.cipher_type == stream) { - ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1); + ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, content, 1); if (ConstantCompare(verify, input + msgSz - digestSz, digestSz) != 0){ return VERIFY_MAC_ERROR; } + if (ret != 0) + return VERIFY_MAC_ERROR; } if (ssl->specs.cipher_type == aead) { @@ -5281,12 +5295,13 @@ int SendChangeCipher(CYASSL* ssl) #ifndef NO_OLD_TLS -static void SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, +static int SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, int content, int verify) { byte result[MAX_DIGEST_SIZE]; word32 digestSz = ssl->specs.hash_size; /* actual sizes */ word32 padSz = ssl->specs.pad_size; + int ret = 0; Md5 md5; Sha sha; @@ -5318,7 +5333,9 @@ static void SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, Md5Final(&md5, digest); } else { - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; /* inner */ ShaUpdate(&sha, macSecret, digestSz); ShaUpdate(&sha, PAD1, padSz); @@ -5333,6 +5350,7 @@ static void SSL_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, ShaUpdate(&sha, result, digestSz); ShaFinal(&sha, digest); } + return 0; } #ifndef NO_CERTS @@ -5516,14 +5534,16 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, if (ssl->truncated_hmac && ssl->specs.hash_size > digestSz) { byte hmac[MAX_DIGEST_SIZE]; - ssl->hmac(ssl, hmac, output + headerSz + ivSz, inSz, type, 0); - + ret = ssl->hmac(ssl, hmac, output + headerSz + ivSz, inSz, + type, 0); XMEMCPY(output + idx, hmac, digestSz); } else #endif - ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, + ret = ssl->hmac(ssl, output+idx, output + headerSz + ivSz, inSz, type, 0); } + if (ret != 0) + return ret; if ( (ret = Encrypt(ssl, output + headerSz, output+headerSz,size)) != 0) return ret; @@ -7746,12 +7766,14 @@ static void PickHashSigAlgo(CYASSL* ssl, { word16 length = 0; word32 begin = *inOutIdx; + int ret = 0; (void)length; /* shut up compiler warnings */ (void)begin; (void)ssl; (void)input; (void)size; + (void)ret; #ifdef CYASSL_CALLBACKS if (ssl->hsInfoOn) @@ -7938,7 +7960,9 @@ static void PickHashSigAlgo(CYASSL* ssl, Md5Final(&md5, hash); /* sha */ - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN); ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN); ShaUpdate(&sha, messageVerify, verifySz); @@ -7965,7 +7989,6 @@ static void PickHashSigAlgo(CYASSL* ssl, /* rsa */ if (sigAlgo == rsa_sa_algo) { - int ret = 0; byte* out = NULL; byte doUserRsa = 0; @@ -8042,7 +8065,7 @@ static void PickHashSigAlgo(CYASSL* ssl, #ifdef HAVE_ECC /* ecdsa */ if (sigAlgo == ecc_dsa_sa_algo) { - int verify = 0, ret = 0; + int verify = 0; #ifndef NO_OLD_TLS byte* digest = &hash[MD5_DIGEST_SIZE]; word32 digestSz = SHA_DIGEST_SIZE; @@ -8985,7 +9008,9 @@ static void PickHashSigAlgo(CYASSL* ssl, Md5Final(&md5, hash); /* sha */ - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN); ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN); ShaUpdate(&sha, output + preSigIdx, preSigSz); @@ -9309,7 +9334,9 @@ static void PickHashSigAlgo(CYASSL* ssl, Md5Final(&md5, hash); /* sha */ - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, ssl->arrays->clientRandom, RAN_LEN); ShaUpdate(&sha, ssl->arrays->serverRandom, RAN_LEN); ShaUpdate(&sha, output + preSigIdx, preSigSz); diff --git a/src/io.c b/src/io.c index 55f28eed3..ab43b1491 100644 --- a/src/io.c +++ b/src/io.c @@ -475,6 +475,7 @@ int EmbedGenerateCookie(CYASSL* ssl, byte *buf, int sz, void *ctx) XSOCKLENT peerSz = sizeof(peer); Sha sha; byte digest[SHA_DIGEST_SIZE]; + int ret = 0; (void)ctx; @@ -484,7 +485,9 @@ int EmbedGenerateCookie(CYASSL* ssl, byte *buf, int sz, void *ctx) return GEN_COOKIE_E; } - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; ShaUpdate(&sha, (byte*)&peer, peerSz); ShaFinal(&sha, digest); diff --git a/src/keys.c b/src/keys.c index b9c296c30..0d8b47c45 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1835,6 +1835,7 @@ int DeriveKeys(CYASSL* ssl) 2 * ssl->specs.key_size + 2 * ssl->specs.iv_size; int rounds = (length + MD5_DIGEST_SIZE - 1 ) / MD5_DIGEST_SIZE, i; + int ret = 0; byte shaOutput[SHA_DIGEST_SIZE]; byte md5Input[SECRET_LEN + SHA_DIGEST_SIZE]; @@ -1846,7 +1847,9 @@ int DeriveKeys(CYASSL* ssl) byte keyData[KEY_PREFIX * MD5_DIGEST_SIZE]; /* max size */ InitMd5(&md5); - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; XMEMCPY(md5Input, ssl->arrays->masterSecret, SECRET_LEN); @@ -1915,7 +1918,9 @@ static int MakeSslMasterSecret(CYASSL* ssl) #endif InitMd5(&md5); - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; XMEMCPY(md5Input, ssl->arrays->preMasterSecret, pmsSz); diff --git a/src/ssl.c b/src/ssl.c index 1db78f8e5..bf10d6c7d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -4460,7 +4460,10 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl) /* re-init hashes, exclude first hello and verify request */ #ifndef NO_OLD_TLS InitMd5(&ssl->hashMd5); - InitSha(&ssl->hashSha); + if ( (ssl->error = InitSha(&ssl->hashSha)) != 0) { + CYASSL_ERROR(ssl->error); + return SSL_FATAL_ERROR; + } #endif if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 @@ -4731,7 +4734,10 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl) /* re-init hashes, exclude first hello and verify request */ #ifndef NO_OLD_TLS InitMd5(&ssl->hashMd5); - InitSha(&ssl->hashSha); + if ( (ssl->error = InitSha(&ssl->hashSha)) != 0) { + CYASSL_ERROR(ssl->error); + return SSL_FATAL_ERROR; + } #endif if (IsAtLeastTLSv1_2(ssl)) { #ifndef NO_SHA256 @@ -4899,11 +4905,13 @@ int CyaSSL_Cleanup(void) /* some session IDs aren't random afterall, let's make them random */ -static INLINE word32 HashSession(const byte* sessionID, word32 len) +static INLINE word32 HashSession(const byte* sessionID, word32 len, int* error) { byte digest[MD5_DIGEST_SIZE]; Md5 md5; + (void)error; + InitMd5(&md5); Md5Update(&md5, sessionID, len); Md5Final(&md5, digest); @@ -4913,12 +4921,18 @@ static INLINE word32 HashSession(const byte* sessionID, word32 len) #elif !defined(NO_SHA) -static INLINE word32 HashSession(const byte* sessionID, word32 len) +/* 0 on failure */ +static INLINE word32 HashSession(const byte* sessionID, word32 len, int* error) { byte digest[SHA_DIGEST_SIZE]; Sha sha; + int ret = 0; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) { + *error = ret; + return 0; + } ShaUpdate(&sha, sessionID, len); ShaFinal(&sha, digest); @@ -4927,11 +4941,13 @@ static INLINE word32 HashSession(const byte* sessionID, word32 len) #elif !defined(NO_SHA256) -static INLINE word32 HashSession(const byte* sessionID, word32 len) +static INLINE word32 HashSession(const byte* sessionID, word32 len, int* error) { byte digest[SHA256_DIGEST_SIZE]; Sha256 sha256; + (void)error; + InitSha256(&sha256); Sha256Update(&sha256, sessionID, len); Sha256Final(&sha256, digest); @@ -4987,6 +5003,7 @@ CYASSL_SESSION* GetSessionClient(CYASSL* ssl, const byte* id, int len) word32 row; int idx; int count; + int error = 0; CYASSL_ENTER("GetSessionClient"); @@ -4994,7 +5011,11 @@ CYASSL_SESSION* GetSessionClient(CYASSL* ssl, const byte* id, int len) return NULL; len = min(SERVER_ID_LEN, (word32)len); - row = HashSession(id, len) % SESSION_ROWS; + row = HashSession(id, len, &error) % SESSION_ROWS; + if (error != 0) { + CYASSL_MSG("Hash session failed"); + return NULL; + } if (LockMutex(&session_mutex) != 0) { CYASSL_MSG("Lock session mutex failed"); @@ -5048,6 +5069,7 @@ CYASSL_SESSION* GetSession(CYASSL* ssl, byte* masterSecret) word32 row; int idx; int count; + int error = 0; if (ssl->options.sessionCacheOff) return NULL; @@ -5060,7 +5082,11 @@ CYASSL_SESSION* GetSession(CYASSL* ssl, byte* masterSecret) else id = ssl->session.sessionID; - row = HashSession(id, ID_LEN) % SESSION_ROWS; + row = HashSession(id, ID_LEN, &error) % SESSION_ROWS; + if (error != 0) { + CYASSL_MSG("Hash session failed"); + return NULL; + } if (LockMutex(&session_mutex) != 0) return 0; @@ -5126,6 +5152,7 @@ int SetSession(CYASSL* ssl, CYASSL_SESSION* session) int AddSession(CYASSL* ssl) { word32 row, idx; + int error = 0; if (ssl->options.sessionCacheOff) return 0; @@ -5133,7 +5160,11 @@ int AddSession(CYASSL* ssl) if (ssl->options.haveSessionId == 0) return 0; - row = HashSession(ssl->arrays->sessionID, ID_LEN) % SESSION_ROWS; + row = HashSession(ssl->arrays->sessionID, ID_LEN, &error) % SESSION_ROWS; + if (error != 0) { + CYASSL_MSG("Hash session failed"); + return error; + } if (LockMutex(&session_mutex) != 0) return BAD_MUTEX_E; @@ -5175,8 +5206,12 @@ int AddSession(CYASSL* ssl) XMEMCPY(SessionCache[row].Sessions[idx].serverID, ssl->session.serverID, ssl->session.idLen); - clientRow = HashSession(ssl->session.serverID, ssl->session.idLen) - % SESSION_ROWS; + clientRow = HashSession(ssl->session.serverID, ssl->session.idLen, + &error) % SESSION_ROWS; + if (error != 0) { + CYASSL_MSG("Hash session failed"); + return error; + } clientIdx = ClientCache[clientRow].nextIdx++; ClientCache[clientRow].Clients[clientIdx].serverRow = (word16)row; @@ -6443,7 +6478,7 @@ int CyaSSL_set_compression(CYASSL* ssl) (void)sizeof(sha_test); CYASSL_ENTER("SHA_Init"); - InitSha((Sha*)sha); + InitSha((Sha*)sha); /* OpenSSL compat, no ret */ } diff --git a/src/tls.c b/src/tls.c index cd6f96edd..9bc2aaa5f 100644 --- a/src/tls.c +++ b/src/tls.c @@ -498,7 +498,7 @@ int CyaSSL_SetTlsHmacInner(CYASSL* ssl, byte* inner, word32 sz, int content, /* TLS type HMAC */ -void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, +int TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, int content, int verify) { Hmac hmac; @@ -511,6 +511,8 @@ void TLS_hmac(CYASSL* ssl, byte* digest, const byte* in, word32 sz, HmacUpdate(&hmac, myInner, sizeof(myInner)); HmacUpdate(&hmac, in, sz); /* content */ HmacFinal(&hmac, digest); + + return 0; } #ifdef HAVE_TLS_EXTENSIONS diff --git a/tests/hash.c b/tests/hash.c index 245dc0941..624bbcb36 100644 --- a/tests/hash.c +++ b/tests/hash.c @@ -302,6 +302,7 @@ int sha_test(void) testVector a, b, c, d; testVector test_sha[4]; + int ret = 0; int times = sizeof(test_sha) / sizeof(struct testVector), i; a.input = "abc"; @@ -336,7 +337,9 @@ int sha_test(void) test_sha[2] = c; test_sha[3] = d; - InitSha(&sha); + ret = InitSha(&sha); + if (ret != 0) + return ret; for (i = 0; i < times; ++i) { ShaUpdate(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen);