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

Side by Side Diff: net/third_party/nss/ssl/ssl3con.c

Issue 12193010: net: implement CBC processing in constant-time in libssl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update patch file. Created 7 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/third_party/nss/patches/cbc.patch ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* 2 /*
3 * SSL3 Protocol 3 * SSL3 Protocol
4 * 4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public 5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 /* $Id: ssl3con.c,v 1.192 2012/09/28 05:10:25 wtc%google.com Exp $ */ 8 /* $Id: ssl3con.c,v 1.192 2012/09/28 05:10:25 wtc%google.com Exp $ */
9 9
10 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ 10 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
(...skipping 1828 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 1839 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1840 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 1840 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1841 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 1841 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1842 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 1842 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1843 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 1843 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1844 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 1844 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
1845 0x5c, 0x5c, 0x5c, 0x5c 1845 0x5c, 0x5c, 0x5c, 0x5c
1846 }; 1846 };
1847 1847
1848 /* Called from: ssl3_SendRecord() 1848 /* Called from: ssl3_SendRecord()
1849 ** ssl3_HandleRecord()
1850 ** Caller must already hold the SpecReadLock. (wish we could assert that!) 1849 ** Caller must already hold the SpecReadLock. (wish we could assert that!)
1851 */ 1850 */
1852 static SECStatus 1851 static SECStatus
1853 ssl3_ComputeRecordMAC( 1852 ssl3_ComputeRecordMAC(
1854 ssl3CipherSpec * spec, 1853 ssl3CipherSpec * spec,
1855 PRBool useServerMacKey, 1854 PRBool useServerMacKey,
1856 PRBool isDTLS, 1855 PRBool isDTLS,
1857 SSL3ContentType type, 1856 SSL3ContentType type,
1858 SSL3ProtocolVersion version, 1857 SSL3ProtocolVersion version,
1859 SSL3SequenceNumber seq_num, 1858 SSL3SequenceNumber seq_num,
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 2020
2022 PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLength)); 2021 PRINT_BUF(95, (NULL, "frag hash2: result", outbuf, *outLength));
2023 2022
2024 if (rv != SECSuccess) { 2023 if (rv != SECSuccess) {
2025 rv = SECFailure; 2024 rv = SECFailure;
2026 ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); 2025 ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
2027 } 2026 }
2028 return rv; 2027 return rv;
2029 } 2028 }
2030 2029
2030 /* This is a bodge to allow this code to be compiled against older NSS headers
2031 * that don't contains the CBC constant-time changes. */
2032 #ifndef CKM_NSS_HMAC_CONSTANT_TIME
2033 #define CKM_NSS_HMAC_CONSTANT_TIME (CKM_NSS + 19)
2034 #define CKM_NSS_SSLV3_MAC_CONSTANT_TIME (CKM_NSS + 20)
2035
2036 typedef struct CK_NSS_MACConstantTimeParams {
2037 CK_MECHANISM_TYPE hashAlg; /* in */
2038 CK_ULONG ulBodyTotalLength; /* in */
2039 CK_BYTE * pHeader; /* in */
2040 CK_ULONG ulHeaderLength; /* in */
wtc 2013/02/05 16:45:48 I'm going to suggest three naming changes here to
agl 2013/02/05 21:44:18 I have applied all your suggested naming changes.
2041 } CK_NSS_MACConstantTimeParams;
2042 #endif
2043
2044 /* Called from: ssl3_HandleRecord()
2045 * Caller must already hold the SpecReadLock. (wish we could assert that!)
2046 *
2047 * On entry:
2048 * originalLen >= inputLen >= MAC size
2049 */
2050 static SECStatus
2051 ssl3_ComputeRecordMACConstantTime(
2052 ssl3CipherSpec * spec,
2053 PRBool useServerMacKey,
2054 PRBool isDTLS,
2055 SSL3ContentType type,
2056 SSL3ProtocolVersion version,
2057 SSL3SequenceNumber seq_num,
2058 const SSL3Opaque * input,
2059 int inputLen,
2060 int originalLen,
2061 unsigned char * outbuf,
2062 unsigned int * outLen)
2063 {
2064 CK_MECHANISM_TYPE macType;
2065 CK_NSS_MACConstantTimeParams params;
2066 PK11Context * mac_context;
2067 SECItem param;
2068 SECStatus rv;
2069 unsigned char header[13];
2070 PK11SymKey * key;
2071 int recordLength;
2072
2073 PORT_Assert(inputLen >= spec->mac_size);
2074 PORT_Assert(originalLen >= inputLen);
2075
2076 if (spec->bypassCiphers) {
2077 /* This function doesn't support PKCS#11 bypass. We fallback on the
2078 * non-constant time version. */
2079 goto fallback;
2080 }
2081
2082 if (spec->mac_def->mac == mac_null) {
2083 *outLen = 0;
2084 return SECSuccess;
2085 }
2086
2087 header[0] = (unsigned char)(seq_num.high >> 24);
2088 header[1] = (unsigned char)(seq_num.high >> 16);
2089 header[2] = (unsigned char)(seq_num.high >> 8);
2090 header[3] = (unsigned char)(seq_num.high >> 0);
2091 header[4] = (unsigned char)(seq_num.low >> 24);
2092 header[5] = (unsigned char)(seq_num.low >> 16);
2093 header[6] = (unsigned char)(seq_num.low >> 8);
2094 header[7] = (unsigned char)(seq_num.low >> 0);
2095 header[8] = type;
2096
2097 macType = CKM_NSS_HMAC_CONSTANT_TIME;
2098 recordLength = inputLen - spec->mac_size;
2099 if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
2100 macType = CKM_NSS_SSLV3_MAC_CONSTANT_TIME;
2101 header[9] = recordLength >> 8;
2102 header[10] = recordLength;
2103 params.ulHeaderLength = 11;
2104 } else {
2105 header[9] = version >> 8;
2106 header[10] = version;
wtc 2013/02/05 16:45:48 IMPORTANT: please port my isDTLS change from https
agl 2013/02/05 21:44:18 Done.
2107 header[11] = recordLength >> 8;
2108 header[12] = recordLength;
2109 params.ulHeaderLength = 13;
2110 }
2111
2112 params.hashAlg = spec->mac_def->mmech;
2113 params.ulBodyTotalLength = originalLen;
2114 params.pHeader = header;
2115
2116 param.data = (unsigned char*) &params;
2117 param.len = sizeof(params);
2118 param.type = 0;
2119
2120 key = spec->server.write_mac_key;
2121 if (!useServerMacKey) {
2122 key = spec->client.write_mac_key;
2123 }
2124 mac_context = PK11_CreateContextBySymKey(macType, CKA_SIGN, key, &param);
2125 if (mac_context == NULL) {
2126 /* Older versions of NSS may not support constant-time MAC. */
wtc 2013/02/05 16:45:48 I think this code is also appropriate for NSS upst
agl 2013/02/05 21:44:18 That's true, although it's only local memory acces
2127 goto fallback;
2128 }
2129
2130 rv = PK11_DigestBegin(mac_context);
2131 rv |= PK11_DigestOp(mac_context, input, inputLen);
2132 rv |= PK11_DigestFinal(mac_context, outbuf, outLen, spec->mac_size);
2133 PK11_DestroyContext(mac_context, PR_TRUE);
2134
2135 PORT_Assert(rv != SECSuccess || *outLen == (unsigned)spec->mac_size);
2136
2137 if (rv != SECSuccess) {
2138 rv = SECFailure;
2139 ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
2140 }
2141 return rv;
2142
2143 fallback:
2144 /* ssl3_ComputeRecordMAC expects the MAC to have been removed from the
2145 * length already. */
2146 inputLen -= spec->mac_size;
2147 return ssl3_ComputeRecordMAC(spec, useServerMacKey, isDTLS, type,
2148 version, seq_num, input, inputLen,
2149 outbuf, outLen);
2150 }
2151
2031 static PRBool 2152 static PRBool
2032 ssl3_ClientAuthTokenPresent(sslSessionID *sid) { 2153 ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
2033 PK11SlotInfo *slot = NULL; 2154 PK11SlotInfo *slot = NULL;
2034 PRBool isPresent = PR_TRUE; 2155 PRBool isPresent = PR_TRUE;
2035 2156
2036 /* we only care if we are doing client auth */ 2157 /* we only care if we are doing client auth */
2037 /* If NSS_PLATFORM_CLIENT_AUTH is defined and a platformClientKey is being 2158 /* If NSS_PLATFORM_CLIENT_AUTH is defined and a platformClientKey is being
2038 * used, u.ssl3.clAuthValid will be false and this function will always 2159 * used, u.ssl3.clAuthValid will be false and this function will always
2039 * return PR_TRUE. */ 2160 * return PR_TRUE. */
2040 if (!sid || !sid->u.ssl3.clAuthValid) { 2161 if (!sid || !sid->u.ssl3.clAuthValid) {
(...skipping 7997 matching lines...) Expand 10 before | Expand all | Expand 10 after
10038 break; 10159 break;
10039 } 10160 }
10040 } 10161 }
10041 } /* end loop */ 10162 } /* end loop */
10042 10163
10043 origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */ 10164 origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
10044 buf->buf = NULL; /* not a leak. */ 10165 buf->buf = NULL; /* not a leak. */
10045 return SECSuccess; 10166 return SECSuccess;
10046 } 10167 }
10047 10168
10169 /* These macros return the given value with the MSB copied to all the other
10170 * bits. They use the fact that arithmetic shift shifts-in the sign bit.
10171 * However, this is not ensured by the C standard so you may need to replace
10172 * them with something else for odd compilers. */
10173 #define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
10174 #define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
10175
10176 /* SECStatusToMask returns, in constant time, a mask value of all ones if rv ==
10177 * SECSuccess. Otherwise it returns zero. */
10178 static unsigned SECStatusToMask(SECStatus rv)
10179 {
10180 unsigned int good;
10181 /* rv ^ SECSuccess is zero iff rv == SECSuccess. Subtracting one results in
10182 * the MSB being set to one iff it was zero before. */
10183 good = rv ^ SECSuccess;
10184 good--;
10185 return DUPLICATE_MSB_TO_ALL(good);
10186 }
10187
10188 /* ssl_ConstantTimeGE returns 0xff if a>=b and 0x00 otherwise. */
10189 static unsigned char ssl_ConstantTimeGE(unsigned a, unsigned b)
10190 {
10191 a -= b;
10192 return DUPLICATE_MSB_TO_ALL(~a);
10193 }
10194
10195 /* ssl_ConstantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */
10196 static unsigned char ssl_ConstantTimeEQ8(unsigned char a, unsigned char b)
10197 {
10198 unsigned c = a ^ b;
10199 c--;
10200 return DUPLICATE_MSB_TO_ALL_8(c);
10201 }
10202
10203 static SECStatus ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext,
10204 unsigned blockSize,
10205 unsigned macSize) {
10206 unsigned int paddingLength, good, t;
10207 const unsigned int overhead = 1 /* padding length byte */ + macSize;
10208
10209 /* These lengths are all public so we can test them in non-constant
10210 * time. */
10211 if (overhead > plaintext->len) {
10212 return SECFailure;
10213 }
10214
10215 paddingLength = plaintext->buf[plaintext->len-1];
10216 /* SSLv3 padding bytes are random and cannot be checked. */
10217 t = plaintext->len;
10218 t -= paddingLength+overhead;
10219 /* If len >= padding_length+overhead then the MSB of t is zero. */
10220 good = DUPLICATE_MSB_TO_ALL(~t);
10221 /* SSLv3 requires that the padding is minimal. */
10222 t = blockSize - (paddingLength+1);
10223 good &= DUPLICATE_MSB_TO_ALL(~t);
10224 plaintext->len -= good & (paddingLength+1);
10225 return (good & SECSuccess) | (~good & SECFailure);
10226 }
10227
10228
10229 static SECStatus ssl_RemoveTLSCBCPadding(sslBuffer *plaintext,
10230 unsigned macSize) {
10231 unsigned int paddingLength, good, t, toCheck, i;
10232 const unsigned int overhead = 1 /* padding length byte */ + macSize;
10233
10234 /* These lengths are all public so we can test them in non-constant
10235 * time. */
10236 if (overhead > plaintext->len) {
10237 return SECFailure;
10238 }
10239
10240 paddingLength = plaintext->buf[plaintext->len-1];
10241 t = plaintext->len;
10242 t -= paddingLength+overhead;
10243 /* If len >= paddingLength+overhead then the MSB of t is zero. */
10244 good = DUPLICATE_MSB_TO_ALL(~t);
10245
10246 /* The padding consists of a length byte at the end of the record and then
10247 * that many bytes of padding, all with the same value as the length byte.
10248 * Thus, with the length byte included, there are paddingLength+1 bytes of
10249 * padding.
10250 *
10251 * We can't check just |paddingLength+1| bytes because that leaks
10252 * decrypted information. Therefore we always have to check the maximum
10253 * amount of padding possible. (Again, the length of the record is
10254 * public information so we can use it.) */
10255 toCheck = 255; /* maximum amount of padding. */
10256 if (toCheck > plaintext->len-1) {
10257 toCheck = plaintext->len-1;
10258 }
10259
10260 for (i = 0; i < toCheck; i++) {
10261 unsigned int t = paddingLength - i;
10262 /* If i <= paddingLength then the MSB of t is zero and mask is
10263 * 0xff. Otherwise, mask is 0. */
10264 unsigned char mask = DUPLICATE_MSB_TO_ALL(~t);
10265 unsigned char b = plaintext->buf[plaintext->len-1-i];
10266 /* The final |paddingLength+1| bytes should all have the value
10267 * |paddingLength|. Therefore the XOR should be zero. */
10268 good &= ~(mask&(paddingLength ^ b));
10269 }
10270
10271 /* If any of the final |paddingLength+1| bytes had the wrong value,
10272 * one or more of the lower eight bits of |good| will be cleared. We
10273 * AND the bottom 8 bits together and duplicate the result to all the
10274 * bits. */
10275 good &= good >> 4;
10276 good &= good >> 2;
10277 good &= good >> 1;
10278 good <<= sizeof(good)*8-1;
10279 good = DUPLICATE_MSB_TO_ALL(good);
10280
10281 plaintext->len -= good & (paddingLength+1);
10282 return (good & SECSuccess) | (~good & SECFailure);
10283 }
10284
10285 /* On entry:
10286 * originalLength >= macSize
10287 * macSize <= MAX_MAC_LENGTH
10288 * plaintext->len >= macSize
10289 */
10290 static void ssl_CBCExtractMAC(sslBuffer *plaintext,
10291 unsigned int originalLength,
10292 SSL3Opaque* out,
10293 unsigned int macSize) {
10294 unsigned char rotatedMac[MAX_MAC_LENGTH];
10295 /* macEnd is the index of |plaintext->buf| just after the end of the MAC. */
10296 unsigned macEnd = plaintext->len;
10297 unsigned macStart = macEnd - macSize;
10298 /* scanStart contains the number of bytes that we can ignore because
10299 * the MAC's position can only vary by 255 bytes. */
10300 unsigned scanStart = 0;
10301 unsigned i, j, divSpoiler;
10302 unsigned char rotateOffset;
10303
10304 if (originalLength > macSize + 255 + 1)
10305 scanStart = originalLength - (macSize + 255 + 1);
10306
10307 /* divSpoiler contains a multiple of macSize that is used to cause the
10308 * modulo operation to be constant time. Without this, the time varies
10309 * based on the amount of padding when running on Intel chips at least.
10310 *
10311 * The aim of right-shifting macSize is so that the compiler doesn't
10312 * figure out that it can remove divSpoiler as that would require it
10313 * to prove that macSize is always even, which I hope is beyond it. */
10314 divSpoiler = macSize >> 1;
10315 divSpoiler <<= (sizeof(divSpoiler)-1)*8;
10316 rotateOffset = (divSpoiler + macStart - scanStart) % macSize;
10317
10318 memset(rotatedMac, 0, macSize);
10319 for (i = scanStart; i < originalLength;) {
10320 for (j = 0; j < macSize && i < originalLength; i++, j++) {
10321 unsigned char macStarted = ssl_ConstantTimeGE(i, macStart);
10322 unsigned char macEnded = ssl_ConstantTimeGE(i, macEnd);
10323 unsigned char b = 0;
10324 b = plaintext->buf[i];
10325 rotatedMac[j] |= b & macStarted & ~macEnded;
10326 }
10327 }
10328
10329 /* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line we
10330 * could line-align |rotatedMac| and rotate in place. */
10331 memset(out, 0, macSize);
10332 for (i = 0; i < macSize; i++) {
10333 unsigned char offset = (divSpoiler + macSize - rotateOffset + i) % macSi ze;
10334 for (j = 0; j < macSize; j++) {
10335 out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, offset);
10336 }
10337 }
10338 }
10339
10048 /* if cText is non-null, then decipher, check MAC, and decompress the 10340 /* if cText is non-null, then decipher, check MAC, and decompress the
10049 * SSL record from cText->buf (typically gs->inbuf) 10341 * SSL record from cText->buf (typically gs->inbuf)
10050 * into databuf (typically gs->buf), and any previous contents of databuf 10342 * into databuf (typically gs->buf), and any previous contents of databuf
10051 * is lost. Then handle databuf according to its SSL record type, 10343 * is lost. Then handle databuf according to its SSL record type,
10052 * unless it's an application record. 10344 * unless it's an application record.
10053 * 10345 *
10054 * If cText is NULL, then the ciphertext has previously been deciphered and 10346 * If cText is NULL, then the ciphertext has previously been deciphered and
10055 * checked, and is already sitting in databuf. It is processed as an SSL 10347 * checked, and is already sitting in databuf. It is processed as an SSL
10056 * Handshake message. 10348 * Handshake message.
10057 * 10349 *
10058 * DOES NOT process the decrypted/decompressed application data. 10350 * DOES NOT process the decrypted/decompressed application data.
10059 * On return, databuf contains the decrypted/decompressed record. 10351 * On return, databuf contains the decrypted/decompressed record.
10060 * 10352 *
10061 * Called from ssl3_GatherCompleteHandshake 10353 * Called from ssl3_GatherCompleteHandshake
10062 * ssl3_RestartHandshakeAfterCertReq 10354 * ssl3_RestartHandshakeAfterCertReq
10063 * 10355 *
10064 * Caller must hold the RecvBufLock. 10356 * Caller must hold the RecvBufLock.
10065 * 10357 *
10066 * This function aquires and releases the SSL3Handshake Lock, holding the 10358 * This function aquires and releases the SSL3Handshake Lock, holding the
10067 * lock around any calls to functions that handle records other than 10359 * lock around any calls to functions that handle records other than
10068 * Application Data records. 10360 * Application Data records.
10069 */ 10361 */
10070 SECStatus 10362 SECStatus
10071 ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) 10363 ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
10072 { 10364 {
10073 const ssl3BulkCipherDef *cipher_def; 10365 const ssl3BulkCipherDef *cipher_def;
10074 ssl3CipherSpec * crSpec; 10366 ssl3CipherSpec * crSpec;
10075 SECStatus rv; 10367 SECStatus rv;
10076 unsigned int hashBytes = MAX_MAC_LENGTH + 1; 10368 unsigned int hashBytes = MAX_MAC_LENGTH + 1;
10077 unsigned int padding_length;
10078 PRBool isTLS; 10369 PRBool isTLS;
10079 PRBool padIsBad = PR_FALSE;
10080 SSL3ContentType rType; 10370 SSL3ContentType rType;
10081 SSL3Opaque hash[MAX_MAC_LENGTH]; 10371 SSL3Opaque hash[MAX_MAC_LENGTH];
10372 SSL3Opaque givenHashBuf[MAX_MAC_LENGTH];
10373 SSL3Opaque *givenHash;
10082 sslBuffer *plaintext; 10374 sslBuffer *plaintext;
10083 sslBuffer temp_buf; 10375 sslBuffer temp_buf;
10084 PRUint64 dtls_seq_num; 10376 PRUint64 dtls_seq_num;
10085 unsigned int ivLen = 0; 10377 unsigned int ivLen = 0;
10378 unsigned int originalLen = 0;
10379 unsigned int good;
10380 unsigned int minLength;
10086 10381
10087 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 10382 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
10088 10383
10089 if (!ss->ssl3.initialized) { 10384 if (!ss->ssl3.initialized) {
10090 ssl_GetSSL3HandshakeLock(ss); 10385 ssl_GetSSL3HandshakeLock(ss);
10091 rv = ssl3_InitState(ss); 10386 rv = ssl3_InitState(ss);
10092 ssl_ReleaseSSL3HandshakeLock(ss); 10387 ssl_ReleaseSSL3HandshakeLock(ss);
10093 if (rv != SECSuccess) { 10388 if (rv != SECSuccess) {
10094 return rv; /* ssl3_InitState has set the error code. */ 10389 return rv; /* ssl3_InitState has set the error code. */
10095 } 10390 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
10143 if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) { 10438 if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) {
10144 ssl_ReleaseSpecReadLock(ss); 10439 ssl_ReleaseSpecReadLock(ss);
10145 SSL_DBG(("%d: SSL3[%d]: HandleRecord, rejecting " 10440 SSL_DBG(("%d: SSL3[%d]: HandleRecord, rejecting "
10146 "potentially replayed packet", SSL_GETPID(), ss->fd)); 10441 "potentially replayed packet", SSL_GETPID(), ss->fd));
10147 /* Silently drop the packet */ 10442 /* Silently drop the packet */
10148 databuf->len = 0; /* Needed to ensure data not left around */ 10443 databuf->len = 0; /* Needed to ensure data not left around */
10149 return SECSuccess; 10444 return SECSuccess;
10150 } 10445 }
10151 } 10446 }
10152 10447
10448 good = (unsigned)-1;
10449 minLength = crSpec->mac_size;
10450 if (cipher_def->type == type_block) {
10451 /* CBC records have a padding length byte at the end. */
10452 minLength++;
10453 if (crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
10454 /* With >= TLS 1.1, CBC records have an explicit IV. */
10455 minLength += cipher_def->iv_size;
10456 }
10457 }
10458
10459 /* We can perform this test in variable time because the record's total
10460 * length and the ciphersuite are both public knowledge. */
10461 if (cText->buf->len < minLength) {
10462 SSL_DBG(("%d: SSL3[%d]: HandleRecord, record too small.",
10463 SSL_GETPID(), ss->fd));
10464 /* must not hold spec lock when calling SSL3_SendAlert. */
10465 ssl_ReleaseSpecReadLock(ss);
10466 SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
10467 /* always log mac error, in case attacker can read server logs. */
10468 PORT_SetError(SSL_ERROR_BAD_MAC_READ);
10469 return SECFailure;
10470 }
10471
10153 if (cipher_def->type == type_block && 10472 if (cipher_def->type == type_block &&
10154 crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { 10473 crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
10155 /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states 10474 /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states
10156 * "The receiver decrypts the entire GenericBlockCipher structure and 10475 * "The receiver decrypts the entire GenericBlockCipher structure and
10157 * then discards the first cipher block corresponding to the IV 10476 * then discards the first cipher block corresponding to the IV
10158 * component." Instead, we decrypt the first cipher block and then 10477 * component." Instead, we decrypt the first cipher block and then
10159 * discard it before decrypting the rest. 10478 * discard it before decrypting the rest.
10160 */ 10479 */
10161 SSL3Opaque iv[MAX_IV_LENGTH]; 10480 SSL3Opaque iv[MAX_IV_LENGTH];
10162 int decoded; 10481 int decoded;
10163 10482
10164 ivLen = cipher_def->iv_size; 10483 ivLen = cipher_def->iv_size;
10165 if (ivLen < 8 || ivLen > sizeof(iv)) { 10484 if (ivLen < 8 || ivLen > sizeof(iv)) {
10166 ssl_ReleaseSpecReadLock(ss); 10485 ssl_ReleaseSpecReadLock(ss);
10167 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 10486 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
10168 return SECFailure; 10487 return SECFailure;
10169 } 10488 }
10170 if (ivLen > cText->buf->len) {
10171 SSL_DBG(("%d: SSL3[%d]: HandleRecord, IV length check failed",
10172 SSL_GETPID(), ss->fd));
10173 /* must not hold spec lock when calling SSL3_SendAlert. */
10174 ssl_ReleaseSpecReadLock(ss);
10175 SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
10176 /* always log mac error, in case attacker can read server logs. */
10177 PORT_SetError(SSL_ERROR_BAD_MAC_READ);
10178 return SECFailure;
10179 }
10180 10489
10181 PRINT_BUF(80, (ss, "IV (ciphertext):", cText->buf->buf, ivLen)); 10490 PRINT_BUF(80, (ss, "IV (ciphertext):", cText->buf->buf, ivLen));
10182 10491
10183 /* The decryption result is garbage, but since we just throw away 10492 /* The decryption result is garbage, but since we just throw away
10184 * the block it doesn't matter. The decryption of the next block 10493 * the block it doesn't matter. The decryption of the next block
10185 * depends only on the ciphertext of the IV block. 10494 * depends only on the ciphertext of the IV block.
10186 */ 10495 */
10187 rv = crSpec->decode(crSpec->decodeContext, iv, &decoded, 10496 rv = crSpec->decode(crSpec->decodeContext, iv, &decoded,
10188 sizeof(iv), cText->buf->buf, ivLen); 10497 sizeof(iv), cText->buf->buf, ivLen);
10189 10498
10190 » if (rv != SECSuccess) { 10499 » good &= SECStatusToMask(rv);
10191 » /* All decryption failures must be treated like a bad record
10192 » * MAC; see RFC 5246 (TLS 1.2).
10193 » */
10194 » padIsBad = PR_TRUE;
10195 » }
10196 } 10500 }
10197 10501
10198 /* If we will be decompressing the buffer we need to decrypt somewhere 10502 /* If we will be decompressing the buffer we need to decrypt somewhere
10199 * other than into databuf */ 10503 * other than into databuf */
10200 if (crSpec->decompressor) { 10504 if (crSpec->decompressor) {
10201 temp_buf.buf = NULL; 10505 temp_buf.buf = NULL;
10202 temp_buf.space = 0; 10506 temp_buf.space = 0;
10203 plaintext = &temp_buf; 10507 plaintext = &temp_buf;
10204 } else { 10508 } else {
10205 plaintext = databuf; 10509 plaintext = databuf;
(...skipping 21 matching lines...) Expand all
10227 ssl_ReleaseSpecReadLock(ss); 10531 ssl_ReleaseSpecReadLock(ss);
10228 SSL3_SendAlert(ss, alert_fatal, record_overflow); 10532 SSL3_SendAlert(ss, alert_fatal, record_overflow);
10229 PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); 10533 PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
10230 return SECFailure; 10534 return SECFailure;
10231 } 10535 }
10232 10536
10233 /* decrypt from cText buf to plaintext. */ 10537 /* decrypt from cText buf to plaintext. */
10234 rv = crSpec->decode( 10538 rv = crSpec->decode(
10235 crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len, 10539 crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len,
10236 plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen); 10540 plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen);
10541 good &= SECStatusToMask(rv);
10237 10542
10238 PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len)); 10543 PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len));
10239 if (rv != SECSuccess) { 10544
10240 /* All decryption failures must be treated like a bad record 10545 originalLen = plaintext->len;
10241 * MAC; see RFC 5246 (TLS 1.2).
10242 */
10243 padIsBad = PR_TRUE;
10244 }
10245 10546
10246 /* If it's a block cipher, check and strip the padding. */ 10547 /* If it's a block cipher, check and strip the padding. */
10247 if (cipher_def->type == type_block && !padIsBad) { 10548 if (cipher_def->type == type_block) {
10248 PRUint8 * pPaddingLen = plaintext->buf + plaintext->len - 1; 10549 » const unsigned int blockSize = cipher_def->iv_size;
10249 » padding_length = *pPaddingLen; 10550 » const unsigned int macSize = crSpec->mac_size;
10250 » /* TLS permits padding to exceed the block size, up to 255 bytes. */ 10551
10251 » if (padding_length + 1 + crSpec->mac_size > plaintext->len) 10552 » if (crSpec->version <= SSL_LIBRARY_VERSION_3_0) {
10252 » padIsBad = PR_TRUE; 10553 » good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding(
10253 » else { 10554 » » » plaintext, blockSize, macSize));
10254 plaintext->len -= padding_length + 1; 10555 » } else {
10255 /* In TLS all padding bytes must be equal to the padding length. */ 10556 » good &= SECStatusToMask(ssl_RemoveTLSCBCPadding(
10256 if (isTLS) { 10557 » » » plaintext, macSize));
10257 PRUint8 *p; 10558 » }
10258 for (p = pPaddingLen - padding_length; p < pPaddingLen; ++p) {
10259 padIsBad |= *p ^ padding_length;
10260 }
10261 }
10262 }
10263 } 10559 }
10264 10560
10265 /* Remove the MAC. */
10266 if (plaintext->len >= crSpec->mac_size)
10267 plaintext->len -= crSpec->mac_size;
10268 else
10269 padIsBad = PR_TRUE; /* really macIsBad */
10270
10271 /* compute the MAC */ 10561 /* compute the MAC */
10272 rType = cText->type; 10562 rType = cText->type;
10273 rv = ssl3_ComputeRecordMAC( crSpec, (PRBool)(!ss->sec.isServer), 10563 if (cipher_def->type == type_block) {
10274 IS_DTLS(ss), rType, cText->version, 10564 » rv = ssl3_ComputeRecordMACConstantTime(
10275 IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, 10565 » crSpec, (PRBool)(!ss->sec.isServer),
10276 » plaintext->buf, plaintext->len, hash, &hashBytes); 10566 » IS_DTLS(ss), rType, cText->version,
10277 if (rv != SECSuccess) { 10567 » IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
10278 padIsBad = PR_TRUE; /* really macIsBad */ 10568 » plaintext->buf, plaintext->len, originalLen,
10569 » hash, &hashBytes);
10570
10571 » ssl_CBCExtractMAC(plaintext, originalLen, givenHashBuf,
10572 » » » crSpec->mac_size);
10573 » givenHash = givenHashBuf;
10574
10575 » /* plaintext->len will always have enough space to remove the MAC
10576 » * because in ssl_Remove{SSLv3|TLS}CBCPadding we only adjust
10577 » * plaintext->len if the result has enough space for the MAC and we
10578 » * tested the unadjusted size against minLength, above. */
10579 » plaintext->len -= crSpec->mac_size;
10580 } else {
10581 » /* This is safe because we checked the minLength above. */
10582 » plaintext->len -= crSpec->mac_size;
10583
10584 » rv = ssl3_ComputeRecordMAC(
10585 » crSpec, (PRBool)(!ss->sec.isServer),
10586 » IS_DTLS(ss), rType, cText->version,
10587 » IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
10588 » plaintext->buf, plaintext->len,
10589 » hash, &hashBytes);
10590
10591 » /* We can read the MAC directly from the record because its location is
10592 » * public when a stream cipher is used. */
10593 » givenHash = plaintext->buf + plaintext->len;
10279 } 10594 }
10280 10595
10281 /* Check the MAC */ 10596 good &= SECStatusToMask(rv);
10282 if (hashBytes != (unsigned)crSpec->mac_size || padIsBad || 10597
10283 » NSS_SecureMemcmp(plaintext->buf + plaintext->len, hash, 10598 if (hashBytes != (unsigned)crSpec->mac_size ||
10284 » crSpec->mac_size) != 0) { 10599 » NSS_SecureMemcmp(givenHash, hash, crSpec->mac_size) != 0) {
10600 » /* We're allowed to leak whether or not the MAC check was correct */
10601 » good = 0;
10602 }
10603
10604 if (good == 0) {
10285 /* must not hold spec lock when calling SSL3_SendAlert. */ 10605 /* must not hold spec lock when calling SSL3_SendAlert. */
10286 ssl_ReleaseSpecReadLock(ss); 10606 ssl_ReleaseSpecReadLock(ss);
10287 10607
10288 SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd)); 10608 SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd));
10289 10609
10290 if (!IS_DTLS(ss)) { 10610 if (!IS_DTLS(ss)) {
10291 SSL3_SendAlert(ss, alert_fatal, bad_record_mac); 10611 SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
10292 /* always log mac error, in case attacker can read server logs. */ 10612 /* always log mac error, in case attacker can read server logs. */
10293 PORT_SetError(SSL_ERROR_BAD_MAC_READ); 10613 PORT_SetError(SSL_ERROR_BAD_MAC_READ);
10294 return SECFailure; 10614 return SECFailure;
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
10934 PORT_Free(ss->ssl3.hs.recvdFragments.buf); 11254 PORT_Free(ss->ssl3.hs.recvdFragments.buf);
10935 } 11255 }
10936 } 11256 }
10937 11257
10938 ss->ssl3.initialized = PR_FALSE; 11258 ss->ssl3.initialized = PR_FALSE;
10939 11259
10940 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 11260 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
10941 } 11261 }
10942 11262
10943 /* End of ssl3con.c */ 11263 /* End of ssl3con.c */
OLDNEW
« no previous file with comments | « net/third_party/nss/patches/cbc.patch ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698