diff --git a/src/internal.c b/src/internal.c index 176c98b3f..4f644fd2f 100644 --- a/src/internal.c +++ b/src/internal.c @@ -588,6 +588,10 @@ static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int idx = 0; if (haveECDSAsig) { + #ifdef WOLFSSL_SHA512 + suites->hashSigAlgo[idx++] = sha512_mac; + suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo; + #endif #ifdef WOLFSSL_SHA384 suites->hashSigAlgo[idx++] = sha384_mac; suites->hashSigAlgo[idx++] = ecc_dsa_sa_algo; @@ -603,6 +607,10 @@ static void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, } if (haveRSAsig) { + #ifdef WOLFSSL_SHA512 + suites->hashSigAlgo[idx++] = sha512_mac; + suites->hashSigAlgo[idx++] = rsa_sa_algo; + #endif #ifdef WOLFSSL_SHA384 suites->hashSigAlgo[idx++] = sha384_mac; suites->hashSigAlgo[idx++] = rsa_sa_algo; @@ -1622,6 +1630,12 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx) return ret; } #endif +#ifdef WOLFSSL_SHA512 + ret = wc_InitSha512(&ssl->hsHashes->hashSha512); + if (ret != 0) { + return ret; + } +#endif /* increment CTX reference count */ if (LockMutex(&ctx->countMutex) != 0) { @@ -2427,6 +2441,11 @@ static int HashOutput(WOLFSSL* ssl, const byte* output, int sz, int ivSz) ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz); if (ret != 0) return ret; +#endif +#ifdef WOLFSSL_SHA512 + ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz); + if (ret != 0) + return ret; #endif } @@ -2468,6 +2487,11 @@ static int HashInput(WOLFSSL* ssl, const byte* input, int sz) ret = wc_Sha384Update(&ssl->hsHashes->hashSha384, adj, sz); if (ret != 0) return ret; +#endif +#ifdef WOLFSSL_SHA512 + ret = wc_Sha512Update(&ssl->hsHashes->hashSha512, adj, sz); + if (ret != 0) + return ret; #endif } @@ -3018,6 +3042,7 @@ static void BuildSHA(WOLFSSL* ssl, Hashes* hashes, const byte* sender) #endif +/* Finished doesn't support SHA512, not SHA512 cipher suites yet */ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) { int ret = 0; @@ -6881,6 +6906,9 @@ static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes) #ifdef WOLFSSL_SHA384 Sha384 sha384 = ssl->hsHashes->hashSha384; #endif + #ifdef WOLFSSL_SHA512 + Sha512 sha512 = ssl->hsHashes->hashSha512; + #endif if (ssl->options.tls) { #if ! defined( NO_OLD_TLS ) @@ -6900,6 +6928,11 @@ static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes) if (ret != 0) return ret; #endif + #ifdef WOLFSSL_SHA512 + ret = wc_Sha512Final(&ssl->hsHashes->hashSha512,hashes->sha512); + if (ret != 0) + return ret; + #endif } } #if ! defined( NO_OLD_TLS ) @@ -6919,6 +6952,9 @@ static int BuildCertHashes(WOLFSSL* ssl, Hashes* hashes) #ifdef WOLFSSL_SHA384 ssl->hsHashes->hashSha384 = sha384; #endif + #ifdef WOLFSSL_SHA512 + ssl->hsHashes->hashSha512 = sha512; + #endif } return 0; @@ -8881,6 +8917,12 @@ static void PickHashSigAlgo(WOLFSSL* ssl, break; } #endif + #ifdef WOLFSSL_SHA512 + else if (hashSigAlgo[i] == sha512_mac) { + ssl->suites->hashAlgo = sha512_mac; + break; + } + #endif } } } @@ -9907,6 +9949,15 @@ static void PickHashSigAlgo(WOLFSSL* ssl, byte hash384[SHA384_DIGEST_SIZE]; #endif #endif +#ifdef WOLFSSL_SHA512 +#ifdef WOLFSSL_SMALL_STACK + Sha512* sha512 = NULL; + byte* hash512 = NULL; +#else + Sha512 sha512[1]; + byte hash512[SHA512_DIGEST_SIZE]; +#endif +#endif #ifdef WOLFSSL_SMALL_STACK byte* hash = NULL; byte* messageVerify = NULL; @@ -10026,6 +10077,24 @@ static void PickHashSigAlgo(WOLFSSL* ssl, goto done; #endif +#ifdef WOLFSSL_SHA512 + #ifdef WOLFSSL_SMALL_STACK + sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (sha512 == NULL || hash512 == NULL) + ERROR_OUT(MEMORY_E, done); + #endif + if (!(ret = wc_InitSha512(sha512)) + && !(ret = wc_Sha512Update(sha512, ssl->arrays->clientRandom, RAN_LEN)) + && !(ret = wc_Sha512Update(sha512, ssl->arrays->serverRandom, RAN_LEN)) + && !(ret = wc_Sha512Update(sha512, messageVerify, verifySz))) + ret = wc_Sha512Final(sha512, hash512); + if (ret != 0) + goto done; +#endif + #ifndef NO_RSA /* rsa */ if (sigAlgo == rsa_sa_algo) @@ -10094,6 +10163,13 @@ static void PickHashSigAlgo(WOLFSSL* ssl, digestSz = SHA384_DIGEST_SIZE; #endif } + else if (hashAlgo == sha512_mac) { + #ifdef WOLFSSL_SHA512 + digest = hash512; + typeH = SHA512h; + digestSz = SHA512_DIGEST_SIZE; + #endif + } #ifdef WOLFSSL_SMALL_STACK encodedSig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, NULL, @@ -10159,6 +10235,12 @@ static void PickHashSigAlgo(WOLFSSL* ssl, digestSz = SHA384_DIGEST_SIZE; #endif } + else if (hashAlgo == sha512_mac) { + #ifdef WOLFSSL_SHA512 + digest = hash512; + digestSz = SHA512_DIGEST_SIZE; + #endif + } } if (doUserEcc) { #ifdef HAVE_PK_CALLBACKS @@ -10198,6 +10280,10 @@ static void PickHashSigAlgo(WOLFSSL* ssl, #ifdef WOLFSSL_SHA384 XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + #ifdef WOLFSSL_SHA512 + XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(messageVerify, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -10887,6 +10973,12 @@ static void PickHashSigAlgo(WOLFSSL* ssl, digestSz = SHA384_DIGEST_SIZE; #endif } + else if (ssl->suites->hashAlgo == sha512_mac) { + #ifdef WOLFSSL_SHA512 + digest = ssl->hsHashes->certHashes.sha512; + digestSz = SHA512_DIGEST_SIZE; + #endif + } } if (doUserEcc) { @@ -10955,6 +11047,14 @@ static void PickHashSigAlgo(WOLFSSL* ssl, didSet = 1; #endif } + else if (ssl->suites->hashAlgo == sha512_mac) { + #ifdef WOLFSSL_SHA512 + digest = ssl->hsHashes->certHashes.sha512; + typeH = SHA512h; + digestSz = SHA512_DIGEST_SIZE; + didSet = 1; + #endif + } if (didSet == 0) { /* defaults */ @@ -11685,6 +11785,15 @@ int DoSessionTicket(WOLFSSL* ssl, byte hash384[SHA384_DIGEST_SIZE]; #endif #endif + #ifdef WOLFSSL_SHA512 + #ifdef WOLFSSL_SMALL_STACK + Sha512* sha512 = NULL; + byte* hash512 = NULL; + #else + Sha512 sha512[1]; + byte hash512[SHA512_DIGEST_SIZE]; + #endif + #endif #ifdef WOLFSSL_SMALL_STACK hash = (byte*)XMALLOC(FINISHED_SZ, NULL, @@ -11765,6 +11874,28 @@ int DoSessionTicket(WOLFSSL* ssl, goto done_a2; #endif + #ifdef WOLFSSL_SHA512 + #ifdef WOLFSSL_SMALL_STACK + sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (sha512 == NULL || hash512 == NULL) + ERROR_OUT(MEMORY_E, done_a2); + #endif + + if (!(ret = wc_InitSha512(sha512)) + && !(ret = wc_Sha512Update(sha512, ssl->arrays->clientRandom, + RAN_LEN)) + && !(ret = wc_Sha512Update(sha512, ssl->arrays->serverRandom, + RAN_LEN)) + && !(ret = wc_Sha512Update(sha512, output + preSigIdx, preSigSz))) + ret = wc_Sha512Final(sha512, hash512); + + if (ret != 0) + goto done_a2; + #endif + #ifndef NO_RSA if (ssl->suites->sigAlgo == rsa_sa_algo) { byte* signBuffer = hash; @@ -11807,6 +11938,13 @@ int DoSessionTicket(WOLFSSL* ssl, digestSz = SHA384_DIGEST_SIZE; #endif } + else if (ssl->suites->hashAlgo == sha512_mac) { + #ifdef WOLFSSL_SHA512 + digest = hash512; + typeH = SHA512h; + digestSz = SHA512_DIGEST_SIZE; + #endif + } signSz = wc_EncodeSignature(encodedSig, digest, digestSz, typeH); @@ -11877,6 +12015,12 @@ int DoSessionTicket(WOLFSSL* ssl, digestSz = SHA384_DIGEST_SIZE; #endif } + else if (ssl->suites->hashAlgo == sha512_mac) { + #ifdef WOLFSSL_SHA512 + digest = hash512; + digestSz = SHA512_DIGEST_SIZE; + #endif + } } if (doUserEcc) { @@ -11923,6 +12067,10 @@ int DoSessionTicket(WOLFSSL* ssl, XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif + #ifdef WOLFSSL_SHA512 + XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif #endif if (ret < 0) @@ -12126,6 +12274,15 @@ int DoSessionTicket(WOLFSSL* ssl, byte hash384[SHA384_DIGEST_SIZE]; #endif #endif + #ifdef WOLFSSL_SHA512 + #ifdef WOLFSSL_SMALL_STACK + Sha512* sha512 = NULL; + byte* hash512 = NULL; + #else + Sha512 sha512[1]; + byte hash512[SHA512_DIGEST_SIZE]; + #endif + #endif /* Add hash/signature algo ID */ if (IsAtLeastTLSv1_2(ssl)) { @@ -12220,6 +12377,28 @@ int DoSessionTicket(WOLFSSL* ssl, goto done_b; #endif + #ifdef WOLFSSL_SHA512 + #ifdef WOLFSSL_SMALL_STACK + sha512 = (Sha512*)XMALLOC(sizeof(Sha512), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + hash512 = (byte*)XMALLOC(SHA512_DIGEST_SIZE, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (sha512 == NULL || hash512 == NULL) + ERROR_OUT(MEMORY_E, done_b); + #endif + + if (!(ret = wc_InitSha512(sha512)) + && !(ret = wc_Sha512Update(sha512, ssl->arrays->clientRandom, + RAN_LEN)) + && !(ret = wc_Sha512Update(sha512, ssl->arrays->serverRandom, + RAN_LEN)) + && !(ret = wc_Sha512Update(sha512, output + preSigIdx, preSigSz))) + ret = wc_Sha512Final(sha512, hash512); + + if (ret != 0) + goto done_b; + #endif + #ifndef NO_RSA if (ssl->suites->sigAlgo == rsa_sa_algo) { byte* signBuffer = hash; @@ -12262,6 +12441,13 @@ int DoSessionTicket(WOLFSSL* ssl, digestSz = SHA384_DIGEST_SIZE; #endif } + else if (ssl->suites->hashAlgo == sha512_mac) { + #ifdef WOLFSSL_SHA512 + digest = hash512; + typeH = SHA512h; + digestSz = SHA512_DIGEST_SIZE; + #endif + } signSz = wc_EncodeSignature(encodedSig, digest, digestSz, typeH); @@ -12304,6 +12490,10 @@ int DoSessionTicket(WOLFSSL* ssl, XFREE(sha384, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(hash384, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif + #ifdef WOLFSSL_SHA512 + XFREE(sha512, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(hash512, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif #endif if (ret < 0) return ret; @@ -13045,6 +13235,13 @@ int DoSessionTicket(WOLFSSL* ssl, digestSz = SHA384_DIGEST_SIZE; #endif } + else if (hashAlgo == sha512_mac) { + #ifdef WOLFSSL_SHA512 + digest = ssl->hsHashes->certHashes.sha512; + typeH = SHA512h; + digestSz = SHA512_DIGEST_SIZE; + #endif + } sigSz = wc_EncodeSignature(encodedSig, digest, digestSz, typeH); @@ -13097,6 +13294,12 @@ int DoSessionTicket(WOLFSSL* ssl, digestSz = SHA384_DIGEST_SIZE; #endif } + else if (hashAlgo == sha512_mac) { + #ifdef WOLFSSL_SHA512 + digest = ssl->hsHashes->certHashes.sha512; + digestSz = SHA512_DIGEST_SIZE; + #endif + } } if (doUserEcc) { diff --git a/src/ssl.c b/src/ssl.c index 5902555c5..d907f443a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -849,6 +849,11 @@ int wolfSSL_Rehandshake(WOLFSSL* ssl) if (ret !=0) return ret; #endif +#ifdef WOLFSSL_SHA512 + ret = wc_InitSha512(&ssl->hsHashes->hashSha512); + if (ret !=0) + return ret; +#endif ret = wolfSSL_negotiate(ssl); return ret; @@ -5167,6 +5172,13 @@ int wolfSSL_dtls_got_timeout(WOLFSSL* ssl) return SSL_FATAL_ERROR; } #endif + #ifdef WOLFSSL_SHA512 + if ( (ssl->error = wc_InitSha512( + &ssl->hsHashes->hashSha512)) != 0) { + WOLFSSL_ERROR(ssl->error); + return SSL_FATAL_ERROR; + } + #endif } if ( (ssl->error = SendClientHello(ssl)) != 0) { WOLFSSL_ERROR(ssl->error); @@ -5446,6 +5458,13 @@ int wolfSSL_dtls_got_timeout(WOLFSSL* ssl) return SSL_FATAL_ERROR; } #endif + #ifdef WOLFSSL_SHA512 + if ( (ssl->error = wc_InitSha512( + &ssl->hsHashes->hashSha512)) != 0) { + WOLFSSL_ERROR(ssl->error); + return SSL_FATAL_ERROR; + } + #endif } while (ssl->options.clientState < CLIENT_HELLO_COMPLETE) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 55af1d1b9..3ead47d88 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1714,6 +1714,9 @@ typedef struct Hashes { #ifdef WOLFSSL_SHA384 byte sha384[SHA384_DIGEST_SIZE]; #endif + #ifdef WOLFSSL_SHA512 + byte sha512[SHA512_DIGEST_SIZE]; + #endif } Hashes; @@ -2090,6 +2093,9 @@ typedef struct HS_Hashes { #ifdef WOLFSSL_SHA384 Sha384 hashSha384; /* sha384 hash of handshake msgs */ #endif +#ifdef WOLFSSL_SHA512 + Sha512 hashSha512; /* sha512 hash of handshake msgs */ +#endif } HS_Hashes;