| 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 */
 | 
| 
 |