| 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);
 | 
|  	}
 | 
| 
 |