/** * @file hsHash.c * @version $Format:%h%d$ * * Standard handshake hash for implementation for SSL 3.0 and * TLS 1.0/1.1/1.2. */ /* * Copyright (c) 2013-2018 INSIDE Secure Corporation * Copyright (c) PeerSec Networks, 2002-2011 * All Rights Reserved * * The latest version of this code is available at http://www.matrixssl.org * * This software is open source; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This General Public License does NOT permit incorporating this software * into proprietary programs. If you are unable to comply with the GPL, a * commercial license for this software may be purchased from INSIDE at * http://www.insidesecure.com/ * * This program is distributed in WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * http://www.gnu.org/copyleft/gpl.html */ #include "matrixsslImpl.h" #ifndef USE_TLS_1_3_ONLY #ifndef USE_BUFFERED_HS_HASH #ifdef USE_NATIVE_TLS_HS_HASH # define FINISHED_LABEL_SIZE 15 # define LABEL_CLIENT "client finished" # define LABEL_SERVER "server finished" /******************************************************************************/ /** Initialize the SHA1 and MD5 hash contexts for the handshake messages. The handshake hashes are used in 3 messages in TLS: ClientFinished, ServerFinished and ClientCertificateVerify. The version of TLS affects which hashes are used for the Finished messages. TLS 1.2 allows a different hash algorithm for the CertificatVerify message than is used by the Finished messages, determined by the Signature Algorithms extension. Multiple handshake hash contexts must be maintained until the handshake has progressed enough to determine the negotiated TLS version and whether or not Client Authentication is to be performed. Also, if USE_ONLY_TLS_1_2 is defined at compile time, or USE_CLIENT_AUTH is undefined at compile time, the potential runtime combinations are reduced. The various algorithms are used as follows (+ means concatenation): Client and Server Finished messages < TLS 1.2 - MD5+SHA1 TLS 1.2 - SHA256 Client CertificateVerify message. < TLS 1.2 - MD5+SHA1 TLS 1.2 - One of the hashes present in the union of the SignatureAlgorithms Client extension and the CertificateRequest message from the server. At most this is the set {SHA1,SHA256,SHA384,SHA512}. @return < 0 on failure. @param[in,out] ssl TLS context */ int32_t sslInitHSHash(ssl_t *ssl) { # ifdef USE_DTLS if (ACTV_VER(ssl, v_dtls_any)) { /* Don't allow CLIENT_HELLO message retransmit to reset hash */ if (ssl->retransmit) { return 0; } } # endif /* USE_DTLS */ #ifdef USE_TLS_1_3 if (ssl->tls13IncorrectDheKeyShare) { /* Don't allow second ClientHello after HelloRetryRequest to reset the hash. */ return 0; } /* Always has to init all hashes since we don't know with what version we end up with. */ tls13TranscriptHashInit(ssl); #endif # ifndef USE_ONLY_TLS_1_2 psMd5Sha1Init(&ssl->sec.msgHashMd5Sha1); # endif # ifdef USE_TLS_1_2 psSha256Init(&ssl->sec.msgHashSha256); # ifdef USE_SHA1 psSha1Init(&ssl->sec.msgHashSha1); # endif # ifdef USE_SHA384 psSha384Init(&ssl->sec.msgHashSha384); # endif # ifdef USE_SHA512 psSha512Init(&ssl->sec.msgHashSha512); # endif # endif return 0; } /******************************************************************************/ /** Add the given data to the running hash of the handshake messages. @param[in,out] ssl TLS context @param[in] in Pointer to handshake data to hash. @param[in] len Number of bytes of handshake data to hash. @return < 0 on failure. */ int32_t sslUpdateHSHash(ssl_t *ssl, const unsigned char *in, psSize_t len) { #ifdef USE_TLS_1_3 /* If we just received ClientHello, we have not set the version flag yet. */ if (anyTls13VersionSupported(ssl) && (ssl->hsState == SSL_HS_CLIENT_HELLO)) { /* Postpone updating the hash. This is because if the CH contains any PSK binders, we need to hash it in two parts in order to generate the binder key. We shall update the hash either in tls13VerifyBinder, if binders are present, or in parseSSLHandshake if not. */ ssl->sec.tls13CHStart = in; ssl->sec.tls13CHLen = len; } #endif # ifdef USE_DTLS if (ACTV_VER(ssl, v_dtls_any)) { /* Don't update handshake hashes on resends. Already been through here. */ if (ssl->retransmit) { return 0; } } # endif /* USE_DTLS */ # ifdef USE_TLS_1_2 /* Keep a running total of each for greatest RFC support when it comes to the CertificateVerify message. Although, trying to be smart about MD5 and SHA-2 based on protocol version. */ if (!VersionNegotiationComplete(ssl) || NGTD_VER(ssl, v_tls_sha2)) { psSha256Update(&ssl->sec.msgHashSha256, in, len); # ifdef USE_SHA1 psSha1Update(&ssl->sec.msgHashSha1, in, len); # endif /* USE_SHA1 */ # ifdef USE_SHA384 psSha384Update(&ssl->sec.msgHashSha384, in, len); # endif # ifdef USE_SHA512 psSha512Update(&ssl->sec.msgHashSha512, in, len); # endif } # endif /* USE_TLS_1_2 */ # ifndef USE_ONLY_TLS_1_2 /* Below TLS 1.2, the hash is always the md5sha1 hash. If we negotiate to TLS 1.2 and need sha1, we use just that part of the md5Sha1. */ /* TODO if (ssl->reqMinVer == 0 || ssl->minVer != TLS_1_2_MIN_VER) { */ psMd5Sha1Update(&ssl->sec.msgHashMd5Sha1, in, len); # endif return 0; } # ifdef USE_TLS_1_2 /* Functions necessary to deal with needing to keep track of both SHA-1 and SHA-256 handshake hash states. FINISHED message will always be SHA-256 but client might be sending SHA-1 CertificateVerify message */ # if defined(USE_SERVER_SIDE_SSL) && defined(USE_CLIENT_AUTH) # ifdef USE_SHA1 int32 sslSha1RetrieveHSHash(ssl_t *ssl, unsigned char *out) { Memcpy(out, ssl->sec.sha1Snapshot, SHA1_HASH_SIZE); return SHA1_HASH_SIZE; } # endif # ifdef USE_SHA384 int32 sslSha384RetrieveHSHash(ssl_t *ssl, unsigned char *out) { Memcpy(out, ssl->sec.sha384Snapshot, SHA384_HASH_SIZE); return SHA384_HASH_SIZE; } # endif # ifdef USE_SHA512 int32 sslSha512RetrieveHSHash(ssl_t *ssl, unsigned char *out) { Memcpy(out, ssl->sec.sha512Snapshot, SHA512_HASH_SIZE); return SHA512_HASH_SIZE; } # endif # endif /* USE_SERVER_SIDE_SSL && USE_CLIENT_AUTH */ # if defined(USE_CLIENT_SIDE_SSL) && defined(USE_CLIENT_AUTH) # ifdef USE_SHA1 /* It is possible the certificate verify message wants a non-SHA256 hash */ void sslSha1SnapshotHSHash(ssl_t *ssl, unsigned char *out) { psSha1Final(&ssl->sec.msgHashSha1, out); } # endif # ifdef USE_SHA384 void sslSha384SnapshotHSHash(ssl_t *ssl, unsigned char *out) { psSha384_t sha384; /* SHA384 must copy the context because it could be needed again for final handshake hash. SHA1 doesn't need this because it will not ever be used again after this client auth one-off */ psSha384Sync(&ssl->sec.msgHashSha384, 0); sha384 = ssl->sec.msgHashSha384; psSha384Final(&sha384, out); } # endif # ifdef USE_SHA512 void sslSha512SnapshotHSHash(ssl_t *ssl, unsigned char *out) { psSha512_t sha512; /* SHA512 must copy the context because it could be needed again for final handshake hash. SHA1 doesn't need this because it will not ever be used again after this client auth one-off */ psSha512Sync(&ssl->sec.msgHashSha512, 0); sha512 = ssl->sec.msgHashSha512; psSha512Final(&sha512, out); } # endif # endif /* USE_CLIENT_SIDE_SSL && USE_CLIENT_AUTH */ # endif /* USE_TLS_1_2 */ # ifdef USE_TLS /******************************************************************************/ /* TLS handshake hash computation */ static int32_t tlsGenerateFinishedHash(ssl_t *ssl, # ifndef USE_ONLY_TLS_1_2 psMd5Sha1_t *md5sha1, # endif # ifdef USE_TLS_1_2 # ifdef USE_SHA1 psSha1_t *sha1, # endif # ifdef USE_SHA256 psSha256_t *sha256, # endif # ifdef USE_SHA384 psSha384_t *sha384, # endif # ifdef USE_SHA512 psSha512_t *sha512, # endif # endif /* USE_TLS_1_2 */ unsigned char *masterSecret, unsigned char *out, int32 senderFlag) { unsigned char tmp[FINISHED_LABEL_SIZE + SHA384_HASH_SIZE]; # ifndef USE_ONLY_TLS_1_2 psMd5Sha1_t md5sha1_backup; # endif /* In each branch: Use a backup of the message hash-to-date because we don't want to destroy the state of the handshaking until truly complete */ if (senderFlag >= 0) { Memcpy(tmp, (senderFlag & SSL_FLAGS_SERVER) ? LABEL_SERVER : LABEL_CLIENT, FINISHED_LABEL_SIZE); # ifdef USE_TLS_1_2 if (ACTV_VER(ssl, v_tls_sha2)) { if (ssl->cipher->flags & CRYPTO_FLAGS_SHA3) { # ifdef USE_SHA384 psSha384_t sha384_backup; psSha384Cpy(&sha384_backup, sha384); psSha384Final(&sha384_backup, tmp + FINISHED_LABEL_SIZE); return prf2(masterSecret, SSL_HS_MASTER_SIZE, tmp, FINISHED_LABEL_SIZE + SHA384_HASH_SIZE, out, TLS_HS_FINISHED_SIZE, CRYPTO_FLAGS_SHA3); # endif } else { psSha256_t sha256_backup; psSha256Cpy(&sha256_backup, sha256); psSha256Final(&sha256_backup, tmp + FINISHED_LABEL_SIZE); return prf2(masterSecret, SSL_HS_MASTER_SIZE, tmp, FINISHED_LABEL_SIZE + SHA256_HASH_SIZE, out, TLS_HS_FINISHED_SIZE, CRYPTO_FLAGS_SHA2); } # ifndef USE_ONLY_TLS_1_2 } else { psMd5Sha1Cpy(&md5sha1_backup, md5sha1); psMd5Sha1Final(&md5sha1_backup, tmp + FINISHED_LABEL_SIZE); return prf(masterSecret, SSL_HS_MASTER_SIZE, tmp, FINISHED_LABEL_SIZE + MD5SHA1_HASHLEN, out, TLS_HS_FINISHED_SIZE); # endif } # else psMd5Sha1Cpy(&md5sha1_backup, md5sha1); psMd5Sha1Final(&md5sha1_backup, tmp + FINISHED_LABEL_SIZE); return prf(masterSecret, SSL_HS_MASTER_SIZE, tmp, FINISHED_LABEL_SIZE + MD5SHA1_HASHLEN, out, TLS_HS_FINISHED_SIZE); # endif } else { /* Overloading this function to handle the client auth needs of handshake hashing. TODO: use a separate function! */ # ifdef USE_TLS_1_2 if (ACTV_VER(ssl, v_tls_sha2)) { psSha256_t sha256_backup; psSha256Cpy(&sha256_backup, sha256); psSha256Final(&sha256_backup, out); # if defined(USE_SERVER_SIDE_SSL) && defined(USE_CLIENT_AUTH) /* Check to make sure we are a server because clients come through here as well and they do not need to snapshot any hashes because they are in a write state during the CERTIFICATE_VERIFY creation. So if they detect a non-default in digest, they just run the sslSha384SnapshotHSHash family of functions. Servers really do have to save aside the snapshots beause the CERTIFICATE_VERIFY is a parse and so the handshake hash is being set aside for all possible combos here so the sslSha384RetrieveHSHash can fetch. Previous versions were not testing for SERVER here so clients were running digest operations that were not needed in client auth */ if (ssl->flags & SSL_FLAGS_SERVER) { # ifdef USE_SHA384 { psSha384_t sha384_backup; psSha384Cpy(&sha384_backup, sha384); psSha384Final(&sha384_backup, ssl->sec.sha384Snapshot); } # endif # ifdef USE_SHA512 { psSha512_t sha512_backup; psSha512Cpy(&sha512_backup, sha512); psSha512Final(&sha512_backup, ssl->sec.sha512Snapshot); } # endif # ifdef USE_SHA1 { psSha1_t sha1_backup; psSha1Cpy(&sha1_backup, sha1); psSha1Final(&sha1_backup, ssl->sec.sha1Snapshot); } # endif } # endif return SHA256_HASH_SIZE; # ifndef USE_ONLY_TLS_1_2 } else { psMd5Sha1Cpy(&md5sha1_backup, md5sha1); psMd5Sha1Final(&md5sha1_backup, out); return MD5SHA1_HASHLEN; # endif } # else /* The handshake snapshot for client authentication is simply the appended MD5 and SHA1 hashes */ psMd5Sha1Cpy(&md5sha1_backup, md5sha1); psMd5Sha1Final(&md5sha1_backup, out); return MD5SHA1_HASHLEN; # endif /* USE_TLS_1_2 */ } /* Should not reach this */ #include "psunreachable_begin.h" return PS_FAILURE; #include "psunreachable_end.h" } # endif /* USE_TLS */ /* The extended master secret computation uses a handshake hash */ int32_t extMasterSecretSnapshotHSHash(ssl_t *ssl, unsigned char *out, uint32 *outLen) { # ifndef USE_ONLY_TLS_1_2 psMd5Sha1_t md5sha1; # endif /* Use a backup of the message hash-to-date because we don't want to destroy the state of the handshaking until truly complete */ *outLen = 0; # ifdef USE_TLS_1_2 if (ACTV_VER(ssl, v_tls_sha2)) { if (ssl->cipher->flags & CRYPTO_FLAGS_SHA3) { # ifdef USE_SHA384 psSha384_t sha384; psSha384Cpy(&sha384, &ssl->sec.msgHashSha384); psSha384Final(&sha384, out); *outLen = SHA384_HASH_SIZE; # endif } else { # ifdef USE_SHA256 psSha256_t sha256; psSha256Cpy(&sha256, &ssl->sec.msgHashSha256); psSha256Final(&sha256, out); *outLen = SHA256_HASH_SIZE; # endif } # ifndef USE_ONLY_TLS_1_2 } else { psMd5Sha1Cpy(&md5sha1, &ssl->sec.msgHashMd5Sha1); psMd5Sha1Final(&md5sha1, out); *outLen = MD5SHA1_HASHLEN; # endif } # else /* no TLS 1.2 */ psMd5Sha1Cpy(&md5sha1, &ssl->sec.msgHashMd5Sha1); psMd5Sha1Final(&md5sha1, out); *outLen = MD5SHA1_HASHLEN; # endif return *outLen; } /******************************************************************************/ /* Snapshot is called by the receiver of the finished message to produce a hash of the preceeding handshake messages for comparison to incoming message. */ int32_t sslSnapshotHSHash(ssl_t *ssl, unsigned char *out, psBool_t sender, psBool_t isFinishedHash) { int32 len = PS_FAILURE; int32_t senderFlag; /* Fill senderFlag for compability. The old tlsGenerateFinishedHash and sslGenerateFinishedHash APIs still use the senderFlag param with confusing semantics. */ if (sender) { senderFlag = (ssl->flags & SSL_FLAGS_SERVER); } else { senderFlag = (ssl->flags & SSL_FLAGS_SERVER) ? 0 : SSL_FLAGS_SERVER; } if (!isFinishedHash) { senderFlag = -1; } # ifdef USE_DTLS if (ACTV_VER(ssl, v_dtls_any)) { /* Don't allow FINISHED message retransmit to re-calc hash */ if (ssl->retransmit) { Memcpy(out, ssl->hsSnapshot, ssl->hsSnapshotLen); return ssl->hsSnapshotLen; } } # endif /* USE_DTLS */ # ifdef USE_TLS if (ACTV_VER(ssl, v_tls_any | v_dtls_any)) { len = tlsGenerateFinishedHash(ssl, # ifndef USE_ONLY_TLS_1_2 &ssl->sec.msgHashMd5Sha1, # endif # ifdef USE_TLS_1_2 # ifdef USE_SHA1 &ssl->sec.msgHashSha1, # endif # ifdef USE_SHA256 &ssl->sec.msgHashSha256, # endif # ifdef USE_SHA384 &ssl->sec.msgHashSha384, # endif # ifdef USE_SHA512 &ssl->sec.msgHashSha512, # endif # endif /* USE_TLS_1_2 */ ssl->sec.masterSecret, out, senderFlag); # ifndef DISABLE_SSLV3 } else { len = sslGenerateFinishedHash(&ssl->sec.msgHashMd5Sha1, ssl->sec.masterSecret, out, senderFlag); # endif /* DISABLE_SSLV3 */ } # endif /* USE_TLS */ # ifdef USE_DTLS if (ACTV_VER(ssl, v_dtls_any)) { if (len > 0) { Memcpy(ssl->hsSnapshot, out, len); ssl->hsSnapshotLen = len; } } # endif /* USE_DTLS */ return len; } void sslFreeHSHash(ssl_t *ssl) { /* Standard HS hash implementation does not need to free anything here. */ (void)ssl; } #endif /* USE_NATIVE_TLS_HS_HASH */ #endif /* USE_BUFFERED_HS_HASH */ #else /* USE_TLS_1_3_ONLY */ void sslFreeHSHash(ssl_t *ssl) { (void)ssl; } #endif /* USE_TLS_1_3_ONLY */ /******************************************************************************/