summaryrefslogtreecommitdiffstats
path: root/net/third_party
diff options
context:
space:
mode:
authorwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-30 19:23:14 +0000
committerwtc@chromium.org <wtc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-30 19:23:14 +0000
commit74420021f4dccfd255b87088617c064ce83e0d55 (patch)
treedb4f7e79921e3ee6efa389a772ce0c560676d75f /net/third_party
parent9021148bc55f5dc94cb3944d63015289683be2fd (diff)
downloadchromium_src-74420021f4dccfd255b87088617c064ce83e0d55.zip
chromium_src-74420021f4dccfd255b87088617c064ce83e0d55.tar.gz
chromium_src-74420021f4dccfd255b87088617c064ce83e0d55.tar.bz2
Update cbcrandomiv.patch to the currently proposed patch (v10) for the
NSS upstream in https://bugzilla.mozilla.org/show_bug.cgi?id=665814. R=agl@chromium.org BUG=87159 TEST=HTTPS sites continue to work. Review URL: http://codereview.chromium.org/8084004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103517 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/third_party')
-rw-r--r--net/third_party/nss/patches/cbcrandomiv.patch265
-rw-r--r--net/third_party/nss/ssl/ssl3con.c127
2 files changed, 286 insertions, 106 deletions
diff --git a/net/third_party/nss/patches/cbcrandomiv.patch b/net/third_party/nss/patches/cbcrandomiv.patch
index 16f2609..445b2f9 100644
--- a/net/third_party/nss/patches/cbcrandomiv.patch
+++ b/net/third_party/nss/patches/cbcrandomiv.patch
@@ -1,59 +1,226 @@
Index: mozilla/security/nss/lib/ssl/ssl3con.c
===================================================================
RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v
-retrieving revision 1.142.2.5
-diff -u -p -u -r1.142.2.5 ssl3con.c
---- mozilla/security/nss/lib/ssl/ssl3con.c 25 Jan 2011 01:49:22 -0000 1.142.2.5
-+++ mozilla/security/nss/lib/ssl/ssl3con.c 11 Aug 2011 02:15:58 -0000
-@@ -2315,6 +2315,8 @@ ssl3_SendApplicationData(sslSocket *ss,
+retrieving revision 1.151
+diff -u -p -8 -r1.151 ssl3con.c
+--- mozilla/security/nss/lib/ssl/ssl3con.c 26 Jul 2011 02:13:37 -0000 1.151
++++ mozilla/security/nss/lib/ssl/ssl3con.c 29 Sep 2011 17:39:16 -0000
+@@ -2032,56 +2032,56 @@ ssl3_ClientAuthTokenPresent(sslSessionID
+ isPresent = PR_FALSE;
+ }
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
+ return isPresent;
+ }
+
++/* Caller must hold the spec read lock. wrBuf is sometimes, but not always,
++ * ss->sec.writeBuf.
++ */
+ static SECStatus
+-ssl3_CompressMACEncryptRecord(sslSocket * ss,
++ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
++ PRBool isServer,
+ SSL3ContentType type,
+ const SSL3Opaque * pIn,
+- PRUint32 contentLen)
++ PRUint32 contentLen,
++ sslBuffer * wrBuf)
{
- PRInt32 totalSent = 0;
- PRInt32 discarded = 0;
-+ PRBool isBlockCipher;
-+ int recordIndex;
-
- PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
- if (len < 0 || !in) {
-@@ -2339,7 +2341,12 @@ ssl3_SendApplicationData(sslSocket *ss,
- len--;
- discarded = 1;
+- ssl3CipherSpec * cwSpec;
+ const ssl3BulkCipherDef * cipher_def;
+- sslBuffer * wrBuf = &ss->sec.writeBuf;
+ SECStatus rv;
+ PRUint32 macLen = 0;
+ PRUint32 fragLen;
+ PRUint32 p1Len, p2Len, oddLen = 0;
+ PRInt32 cipherBytes = 0;
+
+- ssl_GetSpecReadLock(ss); /********************************/
+-
+- cwSpec = ss->ssl3.cwSpec;
+ cipher_def = cwSpec->cipher_def;
+
+ if (cwSpec->compressor) {
+ int outlen;
+ rv = cwSpec->compressor(
+ cwSpec->compressContext, wrBuf->buf + SSL3_RECORD_HEADER_LENGTH,
+ &outlen, wrBuf->space - SSL3_RECORD_HEADER_LENGTH, pIn, contentLen);
+ if (rv != SECSuccess)
+ return rv;
+ pIn = wrBuf->buf + SSL3_RECORD_HEADER_LENGTH;
+ contentLen = outlen;
}
-- while (len > totalSent) {
-+
-+ ssl_GetSpecReadLock(ss);
-+ isBlockCipher = ss->ssl3.cwSpec->cipher_def->type == type_block;
-+ ssl_ReleaseSpecReadLock(ss);
-+
-+ for (recordIndex = 0; len > totalSent; recordIndex++) {
- PRInt32 sent, toSend;
- if (totalSent > 0) {
-@@ -2354,6 +2361,28 @@ ssl3_SendApplicationData(sslSocket *ss,
- ssl_GetXmitBufLock(ss);
+ /*
+ * Add the MAC
+ */
+- rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer),
++ rv = ssl3_ComputeRecordMAC( cwSpec, isServer,
+ type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen,
+ wrBuf->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen);
+ if (rv != SECSuccess) {
+ ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
+- goto spec_locked_loser;
++ return SECFailure;
+ }
+ p1Len = contentLen;
+ p2Len = macLen;
+ fragLen = contentLen + macLen; /* needs to be encrypted */
+ PORT_Assert(fragLen <= MAX_FRAGMENT_LENGTH + 1024);
+
+ /*
+ * Pad the text (if we're doing a block cipher)
+@@ -2124,52 +2124,46 @@ ssl3_CompressMACEncryptRecord(sslSocket
+ rv = cwSpec->encode( cwSpec->encodeContext,
+ wrBuf->buf + SSL3_RECORD_HEADER_LENGTH, /* output */
+ &cipherBytes, /* actual outlen */
+ p1Len, /* max outlen */
+ pIn, p1Len); /* input, and inputlen */
+ PORT_Assert(rv == SECSuccess && cipherBytes == p1Len);
+ if (rv != SECSuccess || cipherBytes != p1Len) {
+ PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
+- goto spec_locked_loser;
++ return SECFailure;
}
- toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH);
-+ if (isBlockCipher &&
-+ ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS) {
-+ /*
-+ * We assume that block ciphers are used in CBC mode and send
-+ * only one byte in the first record. This effectively
-+ * randomizes the IV in a backward compatible way.
-+ *
-+ * We get back to the MAX_FRAGMENT_LENGTH record boundary in
-+ * the second record. So for a large amount of data, we send
-+ * 1
-+ * MAX_FRAGMENT_LENGTH - 1
-+ * MAX_FRAGMENT_LENGTH
-+ * MAX_FRAGMENT_LENGTH
-+ * ...
+ }
+ if (p2Len > 0) {
+ PRInt32 cipherBytesPart2 = -1;
+ rv = cwSpec->encode( cwSpec->encodeContext,
+ wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len,
+ &cipherBytesPart2, /* output and actual outLen */
+ p2Len, /* max outlen */
+ wrBuf->buf + SSL3_RECORD_HEADER_LENGTH + p1Len,
+ p2Len); /* input and inputLen*/
+ PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len);
+ if (rv != SECSuccess || cipherBytesPart2 != p2Len) {
+ PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
+- goto spec_locked_loser;
++ return SECFailure;
+ }
+ cipherBytes += cipherBytesPart2;
+ }
+ PORT_Assert(cipherBytes <= MAX_FRAGMENT_LENGTH + 1024);
+
+ ssl3_BumpSequenceNumber(&cwSpec->write_seq_num);
+
+ wrBuf->len = cipherBytes + SSL3_RECORD_HEADER_LENGTH;
+ wrBuf->buf[0] = type;
+ wrBuf->buf[1] = MSB(cwSpec->version);
+ wrBuf->buf[2] = LSB(cwSpec->version);
+ wrBuf->buf[3] = MSB(cipherBytes);
+ wrBuf->buf[4] = LSB(cipherBytes);
+
+- ssl_ReleaseSpecReadLock(ss); /************************************/
+-
+ return SECSuccess;
+-
+-spec_locked_loser:
+- ssl_ReleaseSpecReadLock(ss);
+- return SECFailure;
+ }
+
+ /* Process the plain text before sending it.
+ * Returns the number of bytes of plaintext that were successfully sent
+ * plus the number of bytes of plaintext that were copied into the
+ * output (write) buffer.
+ * Returns SECFailure on a hard IO error, memory error, or crypto error.
+ * Does NOT return SECWouldBlock.
+@@ -2220,39 +2214,87 @@ ssl3_SendRecord( sslSocket * ss
+ /* check for Token Presence */
+ if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
+ PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
+ return SECFailure;
+ }
+
+ while (nIn > 0) {
+ PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
++ unsigned int spaceNeeded;
++ unsigned int numRecords;
++
++ ssl_GetSpecReadLock(ss); /********************************/
++
++ if (nIn > 1 &&
++ ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS &&
++ type == content_application_data &&
++ ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) {
++ /* We will split the first byte of the record into its own record,
++ * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h
+ */
-+ if (recordIndex == 0) {
-+ toSend = 1;
-+ } else if (recordIndex == 1 &&
-+ len - totalSent > MAX_FRAGMENT_LENGTH) {
-+ toSend--;
++ numRecords = 2;
++ } else {
++ numRecords = 1;
++ }
+
+- if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) {
+- PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen);
+- newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH);
+- newSpace += SSL3_BUFFER_FUDGE;
+- rv = sslBuffer_Grow(wrBuf, newSpace);
++ spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE);
++ if (spaceNeeded > wrBuf->space) {
++ rv = sslBuffer_Grow(wrBuf, spaceNeeded);
+ if (rv != SECSuccess) {
+ SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",
+- SSL_GETPID(), ss->fd, newSpace));
+- return SECFailure; /* sslBuffer_Grow set a memory error code. */
++ SSL_GETPID(), ss->fd, spaceNeeded));
++ goto spec_locked_loser; /* sslBuffer_Grow set a memory error code. */
+ }
+ }
- sent = ssl3_SendRecord(ss, content_application_data,
- in + totalSent, toSend, flags);
- if (sent < 0) {
++
++ if (numRecords == 2) {
++ sslBuffer secondRecord;
++
++ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
++ ss->sec.isServer, type, pIn, 1,
++ wrBuf);
++ if (rv != SECSuccess)
++ goto spec_locked_loser;
++
++ PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:",
++ wrBuf->buf, wrBuf->len));
++
++ secondRecord.buf = wrBuf->buf + wrBuf->len;
++ secondRecord.len = 0;
++ secondRecord.space = wrBuf->space - wrBuf->len;
++
++ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
++ ss->sec.isServer, type, pIn + 1,
++ contentLen - 1, &secondRecord);
++ if (rv == SECSuccess) {
++ PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
++ secondRecord.buf, secondRecord.len));
++ wrBuf->len += secondRecord.len;
++ }
++ } else {
++ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
++ ss->sec.isServer, type, pIn,
++ contentLen, wrBuf);
++ if (rv == SECSuccess) {
++ PRINT_BUF(50, (ss, "send (encrypted) record data [1/1]:",
++ wrBuf->buf, wrBuf->len));
+ }
+ }
+
+- rv = ssl3_CompressMACEncryptRecord( ss, type, pIn, contentLen);
++spec_locked_loser:
++ ssl_ReleaseSpecReadLock(ss); /************************************/
++
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ pIn += contentLen;
+ nIn -= contentLen;
+ PORT_Assert( nIn >= 0 );
+
+- PRINT_BUF(50, (ss, "send (encrypted) record data:", wrBuf->buf, wrBuf->len));
+-
+ /* If there's still some previously saved ciphertext,
+ * or the caller doesn't want us to send the data yet,
+ * then add all our new ciphertext to the amount previously saved.
+ */
+ if ((ss->pendingBuf.len > 0) ||
+ (flags & ssl_SEND_FLAG_FORCE_INTO_BUFFER)) {
+
+ rv = ssl_SaveWriteData(ss, wrBuf->buf, wrBuf->len);
diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
index f305acb..ad8f4cd 100644
--- a/net/third_party/nss/ssl/ssl3con.c
+++ b/net/third_party/nss/ssl/ssl3con.c
@@ -2042,24 +2042,24 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
return isPresent;
}
+/* Caller must hold the spec read lock. wrBuf is sometimes, but not always,
+ * ss->sec.writeBuf.
+ */
static SECStatus
-ssl3_CompressMACEncryptRecord(sslSocket * ss,
+ssl3_CompressMACEncryptRecord(ssl3CipherSpec * cwSpec,
+ PRBool isServer,
SSL3ContentType type,
const SSL3Opaque * pIn,
- PRUint32 contentLen)
+ PRUint32 contentLen,
+ sslBuffer * wrBuf)
{
- ssl3CipherSpec * cwSpec;
const ssl3BulkCipherDef * cipher_def;
- sslBuffer * wrBuf = &ss->sec.writeBuf;
SECStatus rv;
PRUint32 macLen = 0;
PRUint32 fragLen;
PRUint32 p1Len, p2Len, oddLen = 0;
PRInt32 cipherBytes = 0;
- ssl_GetSpecReadLock(ss); /********************************/
-
- cwSpec = ss->ssl3.cwSpec;
cipher_def = cwSpec->cipher_def;
if (cwSpec->compressor) {
@@ -2076,12 +2076,12 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss,
/*
* Add the MAC
*/
- rv = ssl3_ComputeRecordMAC( cwSpec, (PRBool)(ss->sec.isServer),
+ rv = ssl3_ComputeRecordMAC( cwSpec, isServer,
type, cwSpec->version, cwSpec->write_seq_num, pIn, contentLen,
wrBuf->buf + contentLen + SSL3_RECORD_HEADER_LENGTH, &macLen);
if (rv != SECSuccess) {
ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
- goto spec_locked_loser;
+ return SECFailure;
}
p1Len = contentLen;
p2Len = macLen;
@@ -2134,7 +2134,7 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss,
PORT_Assert(rv == SECSuccess && cipherBytes == p1Len);
if (rv != SECSuccess || cipherBytes != p1Len) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
- goto spec_locked_loser;
+ return SECFailure;
}
}
if (p2Len > 0) {
@@ -2148,7 +2148,7 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss,
PORT_Assert(rv == SECSuccess && cipherBytesPart2 == p2Len);
if (rv != SECSuccess || cipherBytesPart2 != p2Len) {
PORT_SetError(SSL_ERROR_ENCRYPTION_FAILURE);
- goto spec_locked_loser;
+ return SECFailure;
}
cipherBytes += cipherBytesPart2;
}
@@ -2163,13 +2163,7 @@ ssl3_CompressMACEncryptRecord(sslSocket * ss,
wrBuf->buf[3] = MSB(cipherBytes);
wrBuf->buf[4] = LSB(cipherBytes);
- ssl_ReleaseSpecReadLock(ss); /************************************/
-
return SECSuccess;
-
-spec_locked_loser:
- ssl_ReleaseSpecReadLock(ss);
- return SECFailure;
}
/* Process the plain text before sending it.
@@ -2230,20 +2224,70 @@ ssl3_SendRecord( sslSocket * ss,
while (nIn > 0) {
PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
+ unsigned int spaceNeeded;
+ unsigned int numRecords;
- if (wrBuf->space < contentLen + SSL3_BUFFER_FUDGE) {
- PRInt32 newSpace = PR_MAX(wrBuf->space * 2, contentLen);
- newSpace = PR_MIN(newSpace, MAX_FRAGMENT_LENGTH);
- newSpace += SSL3_BUFFER_FUDGE;
- rv = sslBuffer_Grow(wrBuf, newSpace);
+ ssl_GetSpecReadLock(ss); /********************************/
+
+ if (nIn > 1 &&
+ ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS &&
+ type == content_application_data &&
+ ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) {
+ /* We will split the first byte of the record into its own record,
+ * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h
+ */
+ numRecords = 2;
+ } else {
+ numRecords = 1;
+ }
+
+ spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE);
+ if (spaceNeeded > wrBuf->space) {
+ rv = sslBuffer_Grow(wrBuf, spaceNeeded);
if (rv != SECSuccess) {
SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",
- SSL_GETPID(), ss->fd, newSpace));
- return SECFailure; /* sslBuffer_Grow set a memory error code. */
+ SSL_GETPID(), ss->fd, spaceNeeded));
+ goto spec_locked_loser; /* sslBuffer_Grow set a memory error code. */
}
}
- rv = ssl3_CompressMACEncryptRecord( ss, type, pIn, contentLen);
+ if (numRecords == 2) {
+ sslBuffer secondRecord;
+
+ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
+ ss->sec.isServer, type, pIn, 1,
+ wrBuf);
+ if (rv != SECSuccess)
+ goto spec_locked_loser;
+
+ PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:",
+ wrBuf->buf, wrBuf->len));
+
+ secondRecord.buf = wrBuf->buf + wrBuf->len;
+ secondRecord.len = 0;
+ secondRecord.space = wrBuf->space - wrBuf->len;
+
+ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
+ ss->sec.isServer, type, pIn + 1,
+ contentLen - 1, &secondRecord);
+ if (rv == SECSuccess) {
+ PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
+ secondRecord.buf, secondRecord.len));
+ wrBuf->len += secondRecord.len;
+ }
+ } else {
+ rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
+ ss->sec.isServer, type, pIn,
+ contentLen, wrBuf);
+ if (rv == SECSuccess) {
+ PRINT_BUF(50, (ss, "send (encrypted) record data [1/1]:",
+ wrBuf->buf, wrBuf->len));
+ }
+ }
+
+spec_locked_loser:
+ ssl_ReleaseSpecReadLock(ss); /************************************/
+
if (rv != SECSuccess)
return SECFailure;
@@ -2251,8 +2295,6 @@ ssl3_SendRecord( sslSocket * ss,
nIn -= contentLen;
PORT_Assert( nIn >= 0 );
- PRINT_BUF(50, (ss, "send (encrypted) record data:", wrBuf->buf, wrBuf->len));
-
/* If there's still some previously saved ciphertext,
* or the caller doesn't want us to send the data yet,
* then add all our new ciphertext to the amount previously saved.
@@ -2320,8 +2362,6 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
{
PRInt32 totalSent = 0;
PRInt32 discarded = 0;
- PRBool isBlockCipher;
- int recordIndex;
PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
if (len < 0 || !in) {
@@ -2346,12 +2386,7 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
len--;
discarded = 1;
}
-
- ssl_GetSpecReadLock(ss);
- isBlockCipher = ss->ssl3.cwSpec->cipher_def->type == type_block;
- ssl_ReleaseSpecReadLock(ss);
-
- for (recordIndex = 0; len > totalSent; recordIndex++) {
+ while (len > totalSent) {
PRInt32 sent, toSend;
if (totalSent > 0) {
@@ -2366,28 +2401,6 @@ ssl3_SendApplicationData(sslSocket *ss, const unsigned char *in,
ssl_GetXmitBufLock(ss);
}
toSend = PR_MIN(len - totalSent, MAX_FRAGMENT_LENGTH);
- if (isBlockCipher &&
- ss->ssl3.cwSpec->version <= SSL_LIBRARY_VERSION_3_1_TLS) {
- /*
- * We assume that block ciphers are used in CBC mode and send
- * only one byte in the first record. This effectively
- * randomizes the IV in a backward compatible way.
- *
- * We get back to the MAX_FRAGMENT_LENGTH record boundary in
- * the second record. So for a large amount of data, we send
- * 1
- * MAX_FRAGMENT_LENGTH - 1
- * MAX_FRAGMENT_LENGTH
- * MAX_FRAGMENT_LENGTH
- * ...
- */
- if (recordIndex == 0) {
- toSend = 1;
- } else if (recordIndex == 1 &&
- len - totalSent > MAX_FRAGMENT_LENGTH) {
- toSend--;
- }
- }
sent = ssl3_SendRecord(ss, content_application_data,
in + totalSent, toSend, flags);
if (sent < 0) {