Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(779)

Unified Diff: net/third_party/nss/patches/tls12handshakehashes.patch

Issue 17109007: Miscellaneous cleanup of TLS 1.2 code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Make error handling in ssl3_InitHandshakeHashes more uniform. Include the patch file. Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/third_party/nss/patches/applypatches.sh ('k') | net/third_party/nss/ssl/derive.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/third_party/nss/patches/tls12handshakehashes.patch
===================================================================
--- net/third_party/nss/patches/tls12handshakehashes.patch (revision 0)
+++ net/third_party/nss/patches/tls12handshakehashes.patch (revision 0)
@@ -0,0 +1,814 @@
+Index: net/third_party/nss/ssl/derive.c
+===================================================================
+--- net/third_party/nss/ssl/derive.c (revision 206496)
++++ net/third_party/nss/ssl/derive.c (working copy)
+@@ -82,9 +82,11 @@
+ unsigned int effKeySize; /* effective size of cipher keys */
+ unsigned int macSize; /* size of MAC secret */
+ unsigned int IVSize; /* size of IV */
++ PRBool explicitIV = PR_FALSE;
+ SECStatus rv = SECFailure;
+ SECStatus status = SECSuccess;
+ PRBool isFIPS = PR_FALSE;
++ PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2;
+
+ SECItem srcr;
+ SECItem crsr;
+@@ -116,7 +118,13 @@
+ if (keySize == 0) {
+ effKeySize = IVSize = 0; /* only MACing */
+ }
+- block_needed = 2 * (macSize + effKeySize + ((!isExport) * IVSize));
++ if (cipher_def->type == type_block &&
++ pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
++ /* Block ciphers in >= TLS 1.1 use a per-record, explicit IV. */
++ explicitIV = PR_TRUE;
++ }
++ block_needed =
++ 2 * (macSize + effKeySize + ((!isExport && !explicitIV) * IVSize));
+
+ /*
+ * clear out our returned keys so we can recover on failure
+@@ -151,8 +159,13 @@
+ keyblk.data = key_block;
+ keyblk.len = block_needed;
+
+- status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk,
+- isFIPS);
++ if (isTLS12) {
++ status = TLS_P_hash(HASH_AlgSHA256, &pwSpec->msItem,
++ "key expansion", &srcr, &keyblk, isFIPS);
++ } else {
++ status = TLS_PRF(&pwSpec->msItem, "key expansion", &srcr, &keyblk,
++ isFIPS);
++ }
+ if (status != SECSuccess) {
+ goto key_and_mac_derive_fail;
+ }
+@@ -240,22 +253,34 @@
+ i += keySize;
+
+ if (IVSize > 0) {
+- /*
+- ** client_write_IV[CipherSpec.IV_size]
+- */
+- buildSSLKey(&key_block[i], IVSize, &pwSpec->client.write_iv_item, \
+- "Domestic Client Write IV");
+- i += IVSize;
++ if (explicitIV) {
++ static unsigned char zero_block[32];
++ PORT_Assert(IVSize <= sizeof zero_block);
++ buildSSLKey(&zero_block[0], IVSize, \
++ &pwSpec->client.write_iv_item, \
++ "Domestic Client Write IV");
++ buildSSLKey(&zero_block[0], IVSize, \
++ &pwSpec->server.write_iv_item, \
++ "Domestic Server Write IV");
++ } else {
++ /*
++ ** client_write_IV[CipherSpec.IV_size]
++ */
++ buildSSLKey(&key_block[i], IVSize, \
++ &pwSpec->client.write_iv_item, \
++ "Domestic Client Write IV");
++ i += IVSize;
+
+- /*
+- ** server_write_IV[CipherSpec.IV_size]
+- */
+- buildSSLKey(&key_block[i], IVSize, &pwSpec->server.write_iv_item, \
+- "Domestic Server Write IV");
+- i += IVSize;
++ /*
++ ** server_write_IV[CipherSpec.IV_size]
++ */
++ buildSSLKey(&key_block[i], IVSize, \
++ &pwSpec->server.write_iv_item, \
++ "Domestic Server Write IV");
++ i += IVSize;
++ }
+ }
+ PORT_Assert(i <= block_bytes);
+-
+ } else if (!isTLS) {
+ /*
+ ** Generate SSL3 Export write keys and IVs.
+@@ -418,6 +443,7 @@
+ unsigned char * key_block = pwSpec->key_block;
+ SECStatus rv = SECSuccess;
+ PRBool isFIPS = PR_FALSE;
++ PRBool isTLS12 = pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2;
+
+ SECItem crsr;
+
+@@ -453,7 +479,12 @@
+ master.data = key_block;
+ master.len = SSL3_MASTER_SECRET_LENGTH;
+
+- rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS);
++ if (isTLS12) {
++ rv = TLS_P_hash(HASH_AlgSHA256, pms, "master secret", &crsr,
++ &master, isFIPS);
++ } else {
++ rv = TLS_PRF(pms, "master secret", &crsr, &master, isFIPS);
++ }
+ if (rv != SECSuccess) {
+ PORT_SetError(SSL_ERROR_SESSION_KEY_GEN_FAILURE);
+ }
+Index: net/third_party/nss/ssl/sslsock.c
+===================================================================
+--- net/third_party/nss/ssl/sslsock.c (revision 206496)
++++ net/third_party/nss/ssl/sslsock.c (working copy)
+@@ -796,10 +796,7 @@
+ rv = SECFailure;
+ } else {
+ if (PR_FALSE != on) {
+- /* PKCS#11 bypass is not supported with TLS 1.2. */
+- if (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_2) {
+- ss->opt.bypassPKCS11 = PR_FALSE;
+- } else if (PR_SUCCESS == SSL_BypassSetup() ) {
++ if (PR_SUCCESS == SSL_BypassSetup() ) {
+ #ifdef NO_PKCS11_BYPASS
+ ss->opt.bypassPKCS11 = PR_FALSE;
+ #else
+@@ -1964,10 +1961,6 @@
+ }
+ ss->vrange.max = SSL_LIBRARY_VERSION_TLS_1_1;
+ }
+- /* PKCS#11 bypass is not supported with TLS 1.2. */
+- if (ss->vrange.max >= SSL_LIBRARY_VERSION_TLS_1_2) {
+- ss->opt.bypassPKCS11 = PR_FALSE;
+- }
+
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ ssl_Release1stHandshakeLock(ss);
+Index: net/third_party/nss/ssl/ssl3con.c
+===================================================================
+--- net/third_party/nss/ssl/ssl3con.c (revision 206496)
++++ net/third_party/nss/ssl/ssl3con.c (working copy)
+@@ -69,7 +69,6 @@
+ static SECStatus ssl3_SendServerHello( sslSocket *ss);
+ static SECStatus ssl3_SendServerHelloDone( sslSocket *ss);
+ static SECStatus ssl3_SendServerKeyExchange( sslSocket *ss);
+-static SECStatus ssl3_NewHandshakeHashes( sslSocket *ss);
+ static SECStatus ssl3_UpdateHandshakeHashes( sslSocket *ss,
+ const unsigned char *b,
+ unsigned int l);
+@@ -1072,6 +1071,9 @@
+ } else if (hashAlg == SEC_OID_SHA384) {
+ SHA384_HashBuf(hashes->u.raw, hashBuf, bufLen);
+ hashes->len = SHA384_LENGTH;
++ } else if (hashAlg == SEC_OID_SHA512) {
++ SHA512_HashBuf(hashes->u.raw, hashBuf, bufLen);
++ hashes->len = SHA512_LENGTH;
+ } else {
+ PORT_SetError(SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM);
+ return SECFailure;
+@@ -1535,7 +1537,8 @@
+ }
+
+ #ifndef NO_PKCS11_BYPASS
+-/* Initialize encryption and MAC contexts for pending spec.
++/* Initialize encryption contexts for pending spec.
++ * MAC contexts are set up when computing the mac, not here.
+ * Master Secret already is derived in spec->msItem
+ * Caller holds Spec write lock.
+ */
+@@ -1551,7 +1554,6 @@
+ unsigned int optArg1 = 0;
+ unsigned int optArg2 = 0;
+ PRBool server_encrypts = ss->sec.isServer;
+- CK_ULONG macLength;
+ SSLCipherAlgorithm calg;
+ SSLCompressionMethod compression_method;
+ SECStatus rv;
+@@ -1562,12 +1564,7 @@
+
+ pwSpec = ss->ssl3.pwSpec;
+ cipher_def = pwSpec->cipher_def;
+- macLength = pwSpec->mac_size;
+
+- /* MAC setup is done when computing the mac, not here.
+- * Now setup the crypto contexts.
+- */
+-
+ calg = cipher_def->calg;
+ compression_method = pwSpec->compression_method;
+
+@@ -3459,18 +3456,6 @@
+ */
+ rv = PK11_ExtractKeyValue(pwSpec->master_secret);
+ if (rv != SECSuccess) {
+-#if defined(NSS_SURVIVE_DOUBLE_BYPASS_FAILURE)
+- /* The double bypass failed.
+- * Attempt to revert to an all PKCS#11, non-bypass method.
+- * Do we need any unacquired locks here?
+- */
+- ss->opt.bypassPKCS11 = 0;
+- rv = ssl3_NewHandshakeHashes(ss);
+- if (rv == SECSuccess) {
+- rv = ssl3_UpdateHandshakeHashes(ss, ss->ssl3.hs.messages.buf,
+- ss->ssl3.hs.messages.len);
+- }
+-#endif
+ return rv;
+ }
+ /* This returns the address of the secItem inside the key struct,
+@@ -3640,34 +3625,90 @@
+ return SECFailure;
+ }
+
+-/* ssl3_InitTLS12HandshakeHash creates a handshake hash context for TLS 1.2,
+- * if needed, and hashes in any buffered messages in ss->ssl3.hs.messages. */
++/* ssl3_InitHandshakeHashes creates handshake hash contexts and hashes in
++ * buffered messages in ss->ssl3.hs.messages. */
+ static SECStatus
+-ssl3_InitTLS12HandshakeHash(sslSocket *ss)
++ssl3_InitHandshakeHashes(sslSocket *ss)
+ {
+- if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2 &&
+- ss->ssl3.hs.tls12_handshake_hash == NULL) {
+- /* If we ever support ciphersuites where the PRF hash isn't SHA-256
+- * then this will need to be updated. */
+- ss->ssl3.hs.tls12_handshake_hash =
+- PK11_CreateDigestContext(SEC_OID_SHA256);
+- if (!ss->ssl3.hs.tls12_handshake_hash ||
+- PK11_DigestBegin(ss->ssl3.hs.tls12_handshake_hash) != SECSuccess) {
+- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+- return SECFailure;
++ SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
++
++ PORT_Assert(ss->ssl3.hs.hashType == handshake_hash_unknown);
++#ifndef NO_PKCS11_BYPASS
++ if (ss->opt.bypassPKCS11) {
++ PORT_Assert(!ss->ssl3.hs.sha_obj && !ss->ssl3.hs.sha_clone);
++ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
++ /* If we ever support ciphersuites where the PRF hash isn't SHA-256
++ * then this will need to be updated. */
++ ss->ssl3.hs.sha_obj = HASH_GetRawHashObject(HASH_AlgSHA256);
++ if (!ss->ssl3.hs.sha_obj) {
++ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
++ return SECFailure;
++ }
++ ss->ssl3.hs.sha_clone = (void (*)(void *, void *))SHA256_Clone;
++ ss->ssl3.hs.hashType = handshake_hash_single;
++ ss->ssl3.hs.sha_obj->begin(ss->ssl3.hs.sha_cx);
++ } else {
++ ss->ssl3.hs.hashType = handshake_hash_combo;
++ MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx);
++ SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx);
+ }
+- }
++ } else
++#endif
++ {
++ PORT_Assert(!ss->ssl3.hs.md5 && !ss->ssl3.hs.sha);
++ /*
++ * note: We should probably lookup an SSL3 slot for these
++ * handshake hashes in hopes that we wind up with the same slots
++ * that the master secret will wind up in ...
++ */
++ if (ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
++ /* If we ever support ciphersuites where the PRF hash isn't SHA-256
++ * then this will need to be updated. */
++ ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA256);
++ if (ss->ssl3.hs.sha == NULL) {
++ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
++ return SECFailure;
++ }
++ ss->ssl3.hs.hashType = handshake_hash_single;
+
+- if (ss->ssl3.hs.tls12_handshake_hash && ss->ssl3.hs.messages.len > 0) {
+- if (PK11_DigestOp(ss->ssl3.hs.tls12_handshake_hash,
+- ss->ssl3.hs.messages.buf,
+- ss->ssl3.hs.messages.len) != SECSuccess) {
+- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+- return SECFailure;
++ if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
++ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
++ return SECFailure;
++ }
++ } else {
++ /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
++ * created successfully. */
++ ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_MD5);
++ if (ss->ssl3.hs.md5 == NULL) {
++ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
++ return SECFailure;
++ }
++ ss->ssl3.hs.sha = PK11_CreateDigestContext(SEC_OID_SHA1);
++ if (ss->ssl3.hs.sha == NULL) {
++ PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
++ ss->ssl3.hs.md5 = NULL;
++ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
++ return SECFailure;
++ }
++ ss->ssl3.hs.hashType = handshake_hash_combo;
++
++ if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
++ ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
++ return SECFailure;
++ }
++ if (PK11_DigestBegin(ss->ssl3.hs.sha) != SECSuccess) {
++ ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
++ return SECFailure;
++ }
+ }
+ }
+
+- if (ss->ssl3.hs.messages.buf && !ss->opt.bypassPKCS11) {
++ if (ss->ssl3.hs.messages.len > 0) {
++ if (ssl3_UpdateHandshakeHashes(ss, ss->ssl3.hs.messages.buf,
++ ss->ssl3.hs.messages.len) !=
++ SECSuccess) {
++ return SECFailure;
++ }
+ PORT_Free(ss->ssl3.hs.messages.buf);
+ ss->ssl3.hs.messages.buf = NULL;
+ ss->ssl3.hs.messages.len = 0;
+@@ -3682,83 +3723,30 @@
+ {
+ SECStatus rv = SECSuccess;
+
++ SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
++ SSL_GETPID(), ss->fd ));
++ ss->ssl3.hs.hashType = handshake_hash_unknown;
+ ss->ssl3.hs.messages.len = 0;
+ #ifndef NO_PKCS11_BYPASS
+- if (ss->opt.bypassPKCS11) {
+- MD5_Begin((MD5Context *)ss->ssl3.hs.md5_cx);
+- SHA1_Begin((SHA1Context *)ss->ssl3.hs.sha_cx);
+- } else
++ ss->ssl3.hs.sha_obj = NULL;
++ ss->ssl3.hs.sha_clone = NULL;
+ #endif
+- {
+- if (ss->ssl3.hs.tls12_handshake_hash) {
+- rv = PK11_DigestBegin(ss->ssl3.hs.tls12_handshake_hash);
+- if (rv != SECSuccess) {
+- ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+- return rv;
+- }
+- }
+- rv = PK11_DigestBegin(ss->ssl3.hs.md5);
+- if (rv != SECSuccess) {
+- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+- return rv;
+- }
+- rv = PK11_DigestBegin(ss->ssl3.hs.sha);
+- if (rv != SECSuccess) {
+- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+- return rv;
+- }
+- }
+- return rv;
+-}
+-
+-static SECStatus
+-ssl3_NewHandshakeHashes(sslSocket *ss)
+-{
+- PK11Context *md5 = NULL;
+- PK11Context *sha = NULL;
+-
+- /*
+- * note: We should probably lookup an SSL3 slot for these
+- * handshake hashes in hopes that we wind up with the same slots
+- * that the master secret will wind up in ...
+- */
+- SSL_TRC(30,("%d: SSL3[%d]: start handshake hashes", SSL_GETPID(), ss->fd));
+- PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space);
+- ss->ssl3.hs.messages.buf = NULL;
+- ss->ssl3.hs.messages.space = 0;
+-
+- ss->ssl3.hs.md5 = md5 = PK11_CreateDigestContext(SEC_OID_MD5);
+- ss->ssl3.hs.sha = sha = PK11_CreateDigestContext(SEC_OID_SHA1);
+- ss->ssl3.hs.tls12_handshake_hash = NULL;
+- if (md5 == NULL) {
+- ssl_MapLowLevelError(SSL_ERROR_MD5_DIGEST_FAILURE);
+- goto loser;
+- }
+- if (sha == NULL) {
+- ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
+- goto loser;
+- }
+- if (SECSuccess == ssl3_RestartHandshakeHashes(ss)) {
+- return SECSuccess;
+- }
+-
+-loser:
+- if (md5 != NULL) {
+- PK11_DestroyContext(md5, PR_TRUE);
++ if (ss->ssl3.hs.md5) {
++ PK11_DestroyContext(ss->ssl3.hs.md5,PR_TRUE);
+ ss->ssl3.hs.md5 = NULL;
+ }
+- if (sha != NULL) {
+- PK11_DestroyContext(sha, PR_TRUE);
++ if (ss->ssl3.hs.sha) {
++ PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE);
+ ss->ssl3.hs.sha = NULL;
+ }
+- return SECFailure;
+-
++ return rv;
+ }
+
+ /*
+ * Handshake messages
+ */
+-/* Called from ssl3_AppendHandshake()
++/* Called from ssl3_InitHandshakeHashes()
++** ssl3_AppendHandshake()
+ ** ssl3_StartHandshakeHash()
+ ** ssl3_HandleV2ClientHello()
+ ** ssl3_HandleHandshakeMessage()
+@@ -3772,31 +3760,27 @@
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
+
+- PRINT_BUF(90, (NULL, "MD5 & SHA handshake hash input:", b, l));
+-
+- if ((ss->version == 0 || ss->version >= SSL_LIBRARY_VERSION_TLS_1_2) &&
+- !ss->opt.bypassPKCS11 &&
+- ss->ssl3.hs.tls12_handshake_hash == NULL) {
+- /* For TLS 1.2 connections we need to buffer the handshake messages
+- * until we have established which PRF hash function to use. */
+- rv = sslBuffer_Append(&ss->ssl3.hs.messages, b, l);
+- if (rv != SECSuccess) {
+- return rv;
+- }
++ /* We need to buffer the handshake messages until we have established
++ * which handshake hash function to use. */
++ if (ss->ssl3.hs.hashType == handshake_hash_unknown) {
++ return sslBuffer_Append(&ss->ssl3.hs.messages, b, l);
+ }
+
++ PRINT_BUF(90, (NULL, "handshake hash input:", b, l));
++
+ #ifndef NO_PKCS11_BYPASS
+ if (ss->opt.bypassPKCS11) {
+- MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l);
+- SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l);
+-#if defined(NSS_SURVIVE_DOUBLE_BYPASS_FAILURE)
+- rv = sslBuffer_Append(&ss->ssl3.hs.messages, b, l);
+-#endif
++ if (ss->ssl3.hs.hashType == handshake_hash_single) {
++ ss->ssl3.hs.sha_obj->update(ss->ssl3.hs.sha_cx, b, l);
++ } else {
++ MD5_Update((MD5Context *)ss->ssl3.hs.md5_cx, b, l);
++ SHA1_Update((SHA1Context *)ss->ssl3.hs.sha_cx, b, l);
++ }
+ return rv;
+ }
+ #endif
+- if (ss->ssl3.hs.tls12_handshake_hash) {
+- rv = PK11_DigestOp(ss->ssl3.hs.tls12_handshake_hash, b, l);
++ if (ss->ssl3.hs.hashType == handshake_hash_single) {
++ rv = PK11_DigestOp(ss->ssl3.hs.sha, b, l);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ return rv;
+@@ -3924,10 +3908,6 @@
+
+ SSL_TRC(30,("%d: SSL3[%d]: append handshake header: type %s",
+ SSL_GETPID(), ss->fd, ssl3_DecodeHandshakeType(t)));
+- PRINT_BUF(60, (ss, "MD5 handshake hash:",
+- (unsigned char*)ss->ssl3.hs.md5_cx, MD5_LENGTH));
+- PRINT_BUF(95, (ss, "SHA handshake hash:",
+- (unsigned char*)ss->ssl3.hs.sha_cx, SHA1_LENGTH));
+
+ rv = ssl3_AppendHandshakeNumber(ss, t, 1);
+ if (rv != SECSuccess) {
+@@ -4275,8 +4255,28 @@
+ hashes->hashAlg = SEC_OID_UNKNOWN;
+
+ #ifndef NO_PKCS11_BYPASS
+- if (ss->opt.bypassPKCS11) {
++ if (ss->opt.bypassPKCS11 &&
++ ss->ssl3.hs.hashType == handshake_hash_single) {
+ /* compute them without PKCS11 */
++ PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
++
++ if (!spec->msItem.data) {
++ PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
++ return SECFailure;
++ }
++
++ ss->ssl3.hs.sha_clone(sha_cx, ss->ssl3.hs.sha_cx);
++ ss->ssl3.hs.sha_obj->end(sha_cx, hashes->u.raw, &hashes->len,
++ sizeof(hashes->u.raw));
++
++ PRINT_BUF(60, (NULL, "SHA-256: result", hashes->u.raw, hashes->len));
++
++ /* If we ever support ciphersuites where the PRF hash isn't SHA-256
++ * then this will need to be updated. */
++ hashes->hashAlg = SEC_OID_SHA256;
++ rv = SECSuccess;
++ } else if (ss->opt.bypassPKCS11) {
++ /* compute them without PKCS11 */
+ PRUint64 md5_cx[MAX_MAC_CONTEXT_LLONGS];
+ PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
+
+@@ -4360,7 +4360,8 @@
+ #undef shacx
+ } else
+ #endif
+- if (ss->ssl3.hs.tls12_handshake_hash) {
++ if (ss->ssl3.hs.hashType == handshake_hash_single) {
++ /* compute hashes with PKCS11 */
+ PK11Context *h;
+ unsigned int stateLen;
+ unsigned char stackBuf[1024];
+@@ -4371,7 +4372,7 @@
+ return SECFailure;
+ }
+
+- h = ss->ssl3.hs.tls12_handshake_hash;
++ h = ss->ssl3.hs.sha;
+ stateBuf = PK11_SaveContextAlloc(h, stackBuf,
+ sizeof(stackBuf), &stateLen);
+ if (stateBuf == NULL) {
+@@ -4392,8 +4393,7 @@
+
+ tls12_loser:
+ if (stateBuf) {
+- if (PK11_RestoreContext(ss->ssl3.hs.tls12_handshake_hash, stateBuf,
+- stateLen) != SECSuccess) {
++ if (PK11_RestoreContext(h, stateBuf, stateLen) != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
+ rv = SECFailure;
+ }
+@@ -4402,7 +4402,7 @@
+ }
+ }
+ } else {
+- /* compute hases with PKCS11 */
++ /* compute hashes with PKCS11 */
+ PK11Context * md5;
+ PK11Context * sha = NULL;
+ unsigned char *md5StateBuf = NULL;
+@@ -4567,6 +4567,10 @@
+ if (rv != SECSuccess) {
+ goto done; /* ssl3_InitState has set the error code. */
+ }
++ rv = ssl3_RestartHandshakeHashes(ss);
++ if (rv != SECSuccess) {
++ goto done;
++ }
+
+ PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
+ PORT_Memcpy(
+@@ -4626,8 +4630,6 @@
+ */
+ PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
+
+- SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
+- SSL_GETPID(), ss->fd ));
+ rv = ssl3_RestartHandshakeHashes(ss);
+ if (rv != SECSuccess) {
+ return rv;
+@@ -5897,12 +5899,8 @@
+ SSL_GETPID(), ss->fd));
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
++ PORT_Assert( ss->ssl3.initialized );
+
+- rv = ssl3_InitState(ss);
+- if (rv != SECSuccess) {
+- errCode = PORT_GetError(); /* ssl3_InitState has set the error code. */
+- goto alert_loser;
+- }
+ if (ss->ssl3.hs.ws != wait_server_hello) {
+ errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO;
+ desc = unexpected_message;
+@@ -5970,7 +5968,7 @@
+ }
+ isTLS = (ss->version > SSL_LIBRARY_VERSION_3_0);
+
+- rv = ssl3_InitTLS12HandshakeHash(ss);
++ rv = ssl3_InitHandshakeHashes(ss);
+ if (rv != SECSuccess) {
+ desc = internal_error;
+ errCode = PORT_GetError();
+@@ -7308,6 +7306,7 @@
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
++ PORT_Assert( ss->ssl3.initialized );
+
+ /* Get peer name of client */
+ rv = ssl_GetPeerInfo(ss);
+@@ -7335,11 +7334,6 @@
+ PORT_Memset(&ss->xtnData, 0, sizeof(TLSExtensionData));
+ ss->statelessResume = PR_FALSE;
+
+- rv = ssl3_InitState(ss);
+- if (rv != SECSuccess) {
+- return rv; /* ssl3_InitState has set the error code. */
+- }
+-
+ if ((ss->ssl3.hs.ws != wait_client_hello) &&
+ (ss->ssl3.hs.ws != idle_handshake)) {
+ desc = unexpected_message;
+@@ -7378,7 +7372,7 @@
+ goto alert_loser;
+ }
+
+- rv = ssl3_InitTLS12HandshakeHash(ss);
++ rv = ssl3_InitHandshakeHashes(ss);
+ if (rv != SECSuccess) {
+ desc = internal_error;
+ errCode = PORT_GetError();
+@@ -8106,6 +8100,11 @@
+ ssl_ReleaseSSL3HandshakeLock(ss);
+ return rv; /* ssl3_InitState has set the error code. */
+ }
++ rv = ssl3_RestartHandshakeHashes(ss);
++ if (rv != SECSuccess) {
++ ssl_ReleaseSSL3HandshakeLock(ss);
++ return rv;
++ }
+
+ if (ss->ssl3.hs.ws != wait_client_hello) {
+ desc = unexpected_message;
+@@ -8127,7 +8126,7 @@
+ goto alert_loser;
+ }
+
+- rv = ssl3_InitTLS12HandshakeHash(ss);
++ rv = ssl3_InitHandshakeHashes(ss);
+ if (rv != SECSuccess) {
+ desc = internal_error;
+ errCode = PORT_GetError();
+@@ -8858,6 +8857,7 @@
+
+ PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
++ PORT_Assert( ss->ssl3.prSpec == ss->ssl3.pwSpec );
+
+ enc_pms.data = b;
+ enc_pms.len = length;
+@@ -9886,7 +9886,12 @@
+ inData.len = valLen;
+ outData.data = out;
+ outData.len = outLen;
+- rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS);
++ if (spec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
++ rv = TLS_P_hash(HASH_AlgSHA256, &spec->msItem, label, &inData,
++ &outData, isFIPS);
++ } else {
++ rv = TLS_PRF(&spec->msItem, label, &inData, &outData, isFIPS);
++ }
+ PORT_Assert(rv != SECSuccess || outData.len == outLen);
+ #endif
+ }
+@@ -10560,10 +10565,6 @@
+ }
+ SSL_TRC(30,("%d: SSL3[%d]: handle handshake message: %s", SSL_GETPID(),
+ ss->fd, ssl3_DecodeHandshakeType(ss->ssl3.hs.msg_type)));
+- PRINT_BUF(60, (ss, "MD5 handshake hash:",
+- (unsigned char*)ss->ssl3.hs.md5_cx, MD5_LENGTH));
+- PRINT_BUF(95, (ss, "SHA handshake hash:",
+- (unsigned char*)ss->ssl3.hs.sha_cx, SHA1_LENGTH));
+
+ hdr[0] = (PRUint8)ss->ssl3.hs.msg_type;
+ hdr[1] = (PRUint8)(length >> 16);
+@@ -10572,8 +10573,6 @@
+
+ /* Start new handshake hashes when we start a new handshake */
+ if (ss->ssl3.hs.msg_type == client_hello) {
+- SSL_TRC(30,("%d: SSL3[%d]: reset handshake hashes",
+- SSL_GETPID(), ss->fd ));
+ rv = ssl3_RestartHandshakeHashes(ss);
+ if (rv != SECSuccess) {
+ return rv;
+@@ -11526,8 +11525,6 @@
+ /* Called from: ssl3_SendRecord
+ ** ssl3_StartHandshakeHash() <- ssl2_BeginClientHandshake()
+ ** ssl3_SendClientHello()
+-** ssl3_HandleServerHello()
+-** ssl3_HandleClientHello()
+ ** ssl3_HandleV2ClientHello()
+ ** ssl3_HandleRecord()
+ **
+@@ -11538,7 +11535,6 @@
+ static SECStatus
+ ssl3_InitState(sslSocket *ss)
+ {
+- SECStatus rv;
+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
+
+ if (ss->ssl3.initialized)
+@@ -11571,12 +11567,12 @@
+ dtls_SetMTU(ss, 0); /* Set the MTU to the highest plateau */
+ }
+
+- rv = ssl3_NewHandshakeHashes(ss);
+- if (rv == SECSuccess) {
+- ss->ssl3.initialized = PR_TRUE;
+- }
++ PORT_Assert(!ss->ssl3.hs.messages.buf && !ss->ssl3.hs.messages.space);
++ ss->ssl3.hs.messages.buf = NULL;
++ ss->ssl3.hs.messages.space = 0;
+
+- return rv;
++ ss->ssl3.initialized = PR_TRUE;
++ return SECSuccess;
+ }
+
+ /* Returns a reference counted object that contains a key pair.
+@@ -11942,8 +11938,12 @@
+ /* clean up handshake */
+ #ifndef NO_PKCS11_BYPASS
+ if (ss->opt.bypassPKCS11) {
+- SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
+- MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE);
++ if (ss->ssl3.hs.hashType == handshake_hash_combo) {
++ SHA1_DestroyContext((SHA1Context *)ss->ssl3.hs.sha_cx, PR_FALSE);
++ MD5_DestroyContext((MD5Context *)ss->ssl3.hs.md5_cx, PR_FALSE);
++ } else if (ss->ssl3.hs.hashType == handshake_hash_single) {
++ ss->ssl3.hs.sha_obj->destroy(ss->ssl3.hs.sha_cx, PR_FALSE);
++ }
+ }
+ #endif
+ if (ss->ssl3.hs.md5) {
+@@ -11952,9 +11952,6 @@
+ if (ss->ssl3.hs.sha) {
+ PK11_DestroyContext(ss->ssl3.hs.sha,PR_TRUE);
+ }
+- if (ss->ssl3.hs.tls12_handshake_hash) {
+- PK11_DestroyContext(ss->ssl3.hs.tls12_handshake_hash,PR_TRUE);
+- }
+ if (ss->ssl3.hs.clientSigAndHash) {
+ PORT_Free(ss->ssl3.hs.clientSigAndHash);
+ }
+Index: net/third_party/nss/ssl/sslimpl.h
+===================================================================
+--- net/third_party/nss/ssl/sslimpl.h (revision 206496)
++++ net/third_party/nss/ssl/sslimpl.h (working copy)
+@@ -506,7 +506,9 @@
+
+ typedef void (*DTLSTimerCb)(sslSocket *);
+
+-#define MAX_MAC_CONTEXT_BYTES 400
++#define MAX_MAC_CONTEXT_BYTES 400 /* 400 is large enough for MD5, SHA-1, and
++ * SHA-256. For SHA-384 support, increase
++ * it to 712. */
+ #define MAX_MAC_CONTEXT_LLONGS (MAX_MAC_CONTEXT_BYTES / 8)
+
+ #define MAX_CIPHER_CONTEXT_BYTES 2080
+@@ -788,6 +790,12 @@
+ PRUint16 len; /* The data length */
+ } DTLSQueuedMessage;
+
++typedef enum {
++ handshake_hash_unknown = 0,
++ handshake_hash_combo = 1, /* The MD5/SHA-1 combination */
++ handshake_hash_single = 2 /* A single hash */
++} SSL3HandshakeHashType;
++
+ /*
+ ** This is the "hs" member of the "ssl3" struct.
+ ** This entire struct is protected by ssl3HandshakeLock
+@@ -796,11 +804,31 @@
+ SSL3Random server_random;
+ SSL3Random client_random;
+ SSL3WaitState ws;
++
++ /* This group of members is used for handshake running hashes. */
++ SSL3HandshakeHashType hashType;
++ sslBuffer messages; /* Accumulated handshake messages */
++#ifndef NO_PKCS11_BYPASS
++ /* Bypass mode:
++ * SSL 3.0 - TLS 1.1 use both |md5_cx| and |sha_cx|. |md5_cx| is used for
++ * MD5 and |sha_cx| for SHA-1.
++ * TLS 1.2 and later use only |sha_cx|, for SHA-256. NOTE: When we support
++ * SHA-384, increase MAX_MAC_CONTEXT_BYTES to 712. */
+ PRUint64 md5_cx[MAX_MAC_CONTEXT_LLONGS];
+ PRUint64 sha_cx[MAX_MAC_CONTEXT_LLONGS];
+- PK11Context * md5; /* handshake running hashes */
++ const SECHashObject * sha_obj;
++ /* The function prototype of sha_obj->clone() does not match the prototype
++ * of the freebl <HASH>_Clone functions, so we need a dedicated function
++ * pointer for the <HASH>_Clone function. */
++ void (*sha_clone)(void *dest, void *src);
++#endif
++ /* PKCS #11 mode:
++ * SSL 3.0 - TLS 1.1 use both |md5| and |sha|. |md5| is used for MD5 and
++ * |sha| for SHA-1.
++ * TLS 1.2 and later use only |sha|, for SHA-256. */
++ PK11Context * md5;
+ PK11Context * sha;
+- PK11Context * tls12_handshake_hash;
++
+ const ssl3KEADef * kea_def;
+ ssl3CipherSuite cipher_suite;
+ const ssl3CipherSuiteDef *suite_def;
+@@ -818,7 +846,6 @@
+ PRBool sendingSCSV; /* instead of empty RI */
+ sslBuffer msgState; /* current state for handshake messages*/
+ /* protected by recvBufLock */
+- sslBuffer messages; /* Accumulated handshake messages */
+ PRUint16 finishedBytes; /* size of single finished below */
+ union {
+ TLSFinished tFinished[2]; /* client, then server */
« no previous file with comments | « net/third_party/nss/patches/applypatches.sh ('k') | net/third_party/nss/ssl/derive.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698