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