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

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: Addressing wtc's comments. 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 contain 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_SSL3_MAC_CONSTANT_TIME (CKM_NSS + 20)
2035
2036 typedef struct CK_NSS_MAC_CONSTANT_TIME_PARAMS {
2037 CK_MECHANISM_TYPE hashAlg; /* in */
2038 CK_ULONG ulBodyTotalLen; /* in */
2039 CK_BYTE * pHeader; /* in */
2040 CK_ULONG ulHeaderLen; /* in */
2041 } CK_NSS_MAC_CONSTANT_TIME_PARAMS;
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_MAC_CONSTANT_TIME_PARAMS 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_SSL3_MAC_CONSTANT_TIME;
2101 header[9] = recordLength >> 8;
2102 header[10] = recordLength;
2103 params.ulHeaderLen = 11;
2104 } else {
2105 if (isDTLS) {
2106 SSL3ProtocolVersion dtls_version;
2107
2108 dtls_version = dtls_TLSVersionToDTLSVersion(version);
2109 header[9] = dtls_version >> 8;
2110 header[10] = dtls_version;
2111 } else {
2112 header[9] = version >> 8;
2113 header[10] = version;
2114 }
2115 header[11] = recordLength >> 8;
2116 header[12] = recordLength;
2117 params.ulHeaderLen = 13;
2118 }
2119
2120 params.hashAlg = spec->mac_def->mmech;
2121 params.ulBodyTotalLen = originalLen;
2122 params.pHeader = header;
2123
2124 param.data = (unsigned char*) &params;
2125 param.len = sizeof(params);
2126 param.type = 0;
2127
2128 key = spec->server.write_mac_key;
2129 if (!useServerMacKey) {
2130 key = spec->client.write_mac_key;
2131 }
2132 mac_context = PK11_CreateContextBySymKey(macType, CKA_SIGN, key, &param);
2133 if (mac_context == NULL) {
2134 /* Older versions of NSS may not support constant-time MAC. */
2135 goto fallback;
2136 }
2137
2138 rv = PK11_DigestBegin(mac_context);
2139 rv |= PK11_DigestOp(mac_context, input, inputLen);
2140 rv |= PK11_DigestFinal(mac_context, outbuf, outLen, spec->mac_size);
2141 PK11_DestroyContext(mac_context, PR_TRUE);
2142
2143 PORT_Assert(rv != SECSuccess || *outLen == (unsigned)spec->mac_size);
2144
2145 if (rv != SECSuccess) {
2146 rv = SECFailure;
2147 ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
2148 }
2149 return rv;
2150
2151 fallback:
2152 /* ssl3_ComputeRecordMAC expects the MAC to have been removed from the
2153 * length already. */
2154 inputLen -= spec->mac_size;
2155 return ssl3_ComputeRecordMAC(spec, useServerMacKey, isDTLS, type,
2156 version, seq_num, input, inputLen,
2157 outbuf, outLen);
2158 }
2159
2031 static PRBool 2160 static PRBool
2032 ssl3_ClientAuthTokenPresent(sslSessionID *sid) { 2161 ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
2033 PK11SlotInfo *slot = NULL; 2162 PK11SlotInfo *slot = NULL;
2034 PRBool isPresent = PR_TRUE; 2163 PRBool isPresent = PR_TRUE;
2035 2164
2036 /* we only care if we are doing client auth */ 2165 /* we only care if we are doing client auth */
2037 /* If NSS_PLATFORM_CLIENT_AUTH is defined and a platformClientKey is being 2166 /* 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 2167 * used, u.ssl3.clAuthValid will be false and this function will always
2039 * return PR_TRUE. */ 2168 * return PR_TRUE. */
2040 if (!sid || !sid->u.ssl3.clAuthValid) { 2169 if (!sid || !sid->u.ssl3.clAuthValid) {
(...skipping 7997 matching lines...) Expand 10 before | Expand all | Expand 10 after
10038 break; 10167 break;
10039 } 10168 }
10040 } 10169 }
10041 } /* end loop */ 10170 } /* end loop */
10042 10171
10043 origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */ 10172 origBuf->len = 0; /* So ssl3_GatherAppDataRecord will keep looping. */
10044 buf->buf = NULL; /* not a leak. */ 10173 buf->buf = NULL; /* not a leak. */
10045 return SECSuccess; 10174 return SECSuccess;
10046 } 10175 }
10047 10176
10177 /* These macros return the given value with the MSB copied to all the other
10178 * bits. They use the fact that arithmetic shift shifts-in the sign bit.
10179 * However, this is not ensured by the C standard so you may need to replace
10180 * them with something else for odd compilers. */
10181 #define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
10182 #define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
10183
10184 /* SECStatusToMask returns, in constant time, a mask value of all ones if rv ==
10185 * SECSuccess. Otherwise it returns zero. */
10186 static unsigned SECStatusToMask(SECStatus rv)
10187 {
10188 unsigned int good;
10189 /* rv ^ SECSuccess is zero iff rv == SECSuccess. Subtracting one results in
10190 * the MSB being set to one iff it was zero before. */
10191 good = rv ^ SECSuccess;
10192 good--;
10193 return DUPLICATE_MSB_TO_ALL(good);
10194 }
10195
10196 /* ssl_ConstantTimeGE returns 0xff if a>=b and 0x00 otherwise. */
10197 static unsigned char ssl_ConstantTimeGE(unsigned a, unsigned b)
10198 {
10199 a -= b;
10200 return DUPLICATE_MSB_TO_ALL(~a);
10201 }
10202
10203 /* ssl_ConstantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */
10204 static unsigned char ssl_ConstantTimeEQ8(unsigned char a, unsigned char b)
10205 {
10206 unsigned c = a ^ b;
10207 c--;
10208 return DUPLICATE_MSB_TO_ALL_8(c);
10209 }
10210
10211 static SECStatus ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext,
10212 unsigned blockSize,
10213 unsigned macSize) {
10214 unsigned int paddingLength, good, t;
10215 const unsigned int overhead = 1 /* padding length byte */ + macSize;
10216
10217 /* These lengths are all public so we can test them in non-constant
10218 * time. */
10219 if (overhead > plaintext->len) {
10220 return SECFailure;
10221 }
10222
10223 paddingLength = plaintext->buf[plaintext->len-1];
10224 /* SSLv3 padding bytes are random and cannot be checked. */
10225 t = plaintext->len;
10226 t -= paddingLength+overhead;
10227 /* If len >= padding_length+overhead then the MSB of t is zero. */
10228 good = DUPLICATE_MSB_TO_ALL(~t);
10229 /* SSLv3 requires that the padding is minimal. */
10230 t = blockSize - (paddingLength+1);
10231 good &= DUPLICATE_MSB_TO_ALL(~t);
10232 plaintext->len -= good & (paddingLength+1);
10233 return (good & SECSuccess) | (~good & SECFailure);
10234 }
10235
10236
10237 static SECStatus ssl_RemoveTLSCBCPadding(sslBuffer *plaintext,
10238 unsigned macSize) {
10239 unsigned int paddingLength, good, t, toCheck, i;
10240 const unsigned int overhead = 1 /* padding length byte */ + macSize;
10241
10242 /* These lengths are all public so we can test them in non-constant
10243 * time. */
10244 if (overhead > plaintext->len) {
10245 return SECFailure;
10246 }
10247
10248 paddingLength = plaintext->buf[plaintext->len-1];
10249 t = plaintext->len;
10250 t -= paddingLength+overhead;
10251 /* If len >= paddingLength+overhead then the MSB of t is zero. */
10252 good = DUPLICATE_MSB_TO_ALL(~t);
10253
10254 /* The padding consists of a length byte at the end of the record and then
10255 * that many bytes of padding, all with the same value as the length byte.
10256 * Thus, with the length byte included, there are paddingLength+1 bytes of
10257 * padding.
10258 *
10259 * We can't check just |paddingLength+1| bytes because that leaks
10260 * decrypted information. Therefore we always have to check the maximum
10261 * amount of padding possible. (Again, the length of the record is
10262 * public information so we can use it.) */
10263 toCheck = 255; /* maximum amount of padding. */
10264 if (toCheck > plaintext->len-1) {
10265 toCheck = plaintext->len-1;
10266 }
10267
10268 for (i = 0; i < toCheck; i++) {
10269 unsigned int t = paddingLength - i;
10270 /* If i <= paddingLength then the MSB of t is zero and mask is
10271 * 0xff. Otherwise, mask is 0. */
10272 unsigned char mask = DUPLICATE_MSB_TO_ALL(~t);
10273 unsigned char b = plaintext->buf[plaintext->len-1-i];
10274 /* The final |paddingLength+1| bytes should all have the value
10275 * |paddingLength|. Therefore the XOR should be zero. */
10276 good &= ~(mask&(paddingLength ^ b));
10277 }
10278
10279 /* If any of the final |paddingLength+1| bytes had the wrong value,
10280 * one or more of the lower eight bits of |good| will be cleared. We
10281 * AND the bottom 8 bits together and duplicate the result to all the
10282 * bits. */
10283 good &= good >> 4;
10284 good &= good >> 2;
10285 good &= good >> 1;
10286 good <<= sizeof(good)*8-1;
10287 good = DUPLICATE_MSB_TO_ALL(good);
10288
10289 plaintext->len -= good & (paddingLength+1);
10290 return (good & SECSuccess) | (~good & SECFailure);
10291 }
10292
10293 /* On entry:
10294 * originalLength >= macSize
10295 * macSize <= MAX_MAC_LENGTH
10296 * plaintext->len >= macSize
10297 */
10298 static void ssl_CBCExtractMAC(sslBuffer *plaintext,
10299 unsigned int originalLength,
10300 SSL3Opaque* out,
10301 unsigned int macSize) {
10302 unsigned char rotatedMac[MAX_MAC_LENGTH];
10303 /* macEnd is the index of |plaintext->buf| just after the end of the MAC. */
10304 unsigned macEnd = plaintext->len;
10305 unsigned macStart = macEnd - macSize;
10306 /* scanStart contains the number of bytes that we can ignore because
10307 * the MAC's position can only vary by 255 bytes. */
10308 unsigned scanStart = 0;
10309 unsigned i, j, divSpoiler;
10310 unsigned char rotateOffset;
10311
10312 if (originalLength > macSize + 255 + 1)
10313 scanStart = originalLength - (macSize + 255 + 1);
10314
10315 /* divSpoiler contains a multiple of macSize that is used to cause the
10316 * modulo operation to be constant time. Without this, the time varies
10317 * based on the amount of padding when running on Intel chips at least.
10318 *
10319 * The aim of right-shifting macSize is so that the compiler doesn't
10320 * figure out that it can remove divSpoiler as that would require it
10321 * to prove that macSize is always even, which I hope is beyond it. */
10322 divSpoiler = macSize >> 1;
10323 divSpoiler <<= (sizeof(divSpoiler)-1)*8;
10324 rotateOffset = (divSpoiler + macStart - scanStart) % macSize;
10325
10326 memset(rotatedMac, 0, macSize);
10327 for (i = scanStart; i < originalLength;) {
10328 for (j = 0; j < macSize && i < originalLength; i++, j++) {
10329 unsigned char macStarted = ssl_ConstantTimeGE(i, macStart);
10330 unsigned char macEnded = ssl_ConstantTimeGE(i, macEnd);
10331 unsigned char b = 0;
10332 b = plaintext->buf[i];
10333 rotatedMac[j] |= b & macStarted & ~macEnded;
10334 }
10335 }
10336
10337 /* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line we
10338 * could line-align |rotatedMac| and rotate in place. */
10339 memset(out, 0, macSize);
10340 for (i = 0; i < macSize; i++) {
10341 unsigned char offset = (divSpoiler + macSize - rotateOffset + i) % macSi ze;
10342 for (j = 0; j < macSize; j++) {
10343 out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, offset);
10344 }
10345 }
10346 }
10347
10048 /* if cText is non-null, then decipher, check MAC, and decompress the 10348 /* if cText is non-null, then decipher, check MAC, and decompress the
10049 * SSL record from cText->buf (typically gs->inbuf) 10349 * SSL record from cText->buf (typically gs->inbuf)
10050 * into databuf (typically gs->buf), and any previous contents of databuf 10350 * into databuf (typically gs->buf), and any previous contents of databuf
10051 * is lost. Then handle databuf according to its SSL record type, 10351 * is lost. Then handle databuf according to its SSL record type,
10052 * unless it's an application record. 10352 * unless it's an application record.
10053 * 10353 *
10054 * If cText is NULL, then the ciphertext has previously been deciphered and 10354 * 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 10355 * checked, and is already sitting in databuf. It is processed as an SSL
10056 * Handshake message. 10356 * Handshake message.
10057 * 10357 *
10058 * DOES NOT process the decrypted/decompressed application data. 10358 * DOES NOT process the decrypted/decompressed application data.
10059 * On return, databuf contains the decrypted/decompressed record. 10359 * On return, databuf contains the decrypted/decompressed record.
10060 * 10360 *
10061 * Called from ssl3_GatherCompleteHandshake 10361 * Called from ssl3_GatherCompleteHandshake
10062 * ssl3_RestartHandshakeAfterCertReq 10362 * ssl3_RestartHandshakeAfterCertReq
10063 * 10363 *
10064 * Caller must hold the RecvBufLock. 10364 * Caller must hold the RecvBufLock.
10065 * 10365 *
10066 * This function aquires and releases the SSL3Handshake Lock, holding the 10366 * This function aquires and releases the SSL3Handshake Lock, holding the
10067 * lock around any calls to functions that handle records other than 10367 * lock around any calls to functions that handle records other than
10068 * Application Data records. 10368 * Application Data records.
10069 */ 10369 */
10070 SECStatus 10370 SECStatus
10071 ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf) 10371 ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
10072 { 10372 {
10073 const ssl3BulkCipherDef *cipher_def; 10373 const ssl3BulkCipherDef *cipher_def;
10074 ssl3CipherSpec * crSpec; 10374 ssl3CipherSpec * crSpec;
10075 SECStatus rv; 10375 SECStatus rv;
10076 unsigned int hashBytes = MAX_MAC_LENGTH + 1; 10376 unsigned int hashBytes = MAX_MAC_LENGTH + 1;
10077 unsigned int padding_length;
10078 PRBool isTLS; 10377 PRBool isTLS;
10079 PRBool padIsBad = PR_FALSE;
10080 SSL3ContentType rType; 10378 SSL3ContentType rType;
10081 SSL3Opaque hash[MAX_MAC_LENGTH]; 10379 SSL3Opaque hash[MAX_MAC_LENGTH];
10380 SSL3Opaque givenHashBuf[MAX_MAC_LENGTH];
10381 SSL3Opaque *givenHash;
10082 sslBuffer *plaintext; 10382 sslBuffer *plaintext;
10083 sslBuffer temp_buf; 10383 sslBuffer temp_buf;
10084 PRUint64 dtls_seq_num; 10384 PRUint64 dtls_seq_num;
10085 unsigned int ivLen = 0; 10385 unsigned int ivLen = 0;
10386 unsigned int originalLen = 0;
10387 unsigned int good;
10388 unsigned int minLength;
10086 10389
10087 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); 10390 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
10088 10391
10089 if (!ss->ssl3.initialized) { 10392 if (!ss->ssl3.initialized) {
10090 ssl_GetSSL3HandshakeLock(ss); 10393 ssl_GetSSL3HandshakeLock(ss);
10091 rv = ssl3_InitState(ss); 10394 rv = ssl3_InitState(ss);
10092 ssl_ReleaseSSL3HandshakeLock(ss); 10395 ssl_ReleaseSSL3HandshakeLock(ss);
10093 if (rv != SECSuccess) { 10396 if (rv != SECSuccess) {
10094 return rv; /* ssl3_InitState has set the error code. */ 10397 return rv; /* ssl3_InitState has set the error code. */
10095 } 10398 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
10143 if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) { 10446 if (dtls_RecordGetRecvd(&crSpec->recvdRecords, dtls_seq_num) != 0) {
10144 ssl_ReleaseSpecReadLock(ss); 10447 ssl_ReleaseSpecReadLock(ss);
10145 SSL_DBG(("%d: SSL3[%d]: HandleRecord, rejecting " 10448 SSL_DBG(("%d: SSL3[%d]: HandleRecord, rejecting "
10146 "potentially replayed packet", SSL_GETPID(), ss->fd)); 10449 "potentially replayed packet", SSL_GETPID(), ss->fd));
10147 /* Silently drop the packet */ 10450 /* Silently drop the packet */
10148 databuf->len = 0; /* Needed to ensure data not left around */ 10451 databuf->len = 0; /* Needed to ensure data not left around */
10149 return SECSuccess; 10452 return SECSuccess;
10150 } 10453 }
10151 } 10454 }
10152 10455
10456 good = (unsigned)-1;
10457 minLength = crSpec->mac_size;
10458 if (cipher_def->type == type_block) {
10459 /* CBC records have a padding length byte at the end. */
10460 minLength++;
10461 if (crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
10462 /* With >= TLS 1.1, CBC records have an explicit IV. */
10463 minLength += cipher_def->iv_size;
10464 }
10465 }
10466
10467 /* We can perform this test in variable time because the record's total
10468 * length and the ciphersuite are both public knowledge. */
10469 if (cText->buf->len < minLength) {
10470 SSL_DBG(("%d: SSL3[%d]: HandleRecord, record too small.",
10471 SSL_GETPID(), ss->fd));
10472 /* must not hold spec lock when calling SSL3_SendAlert. */
10473 ssl_ReleaseSpecReadLock(ss);
10474 SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
10475 /* always log mac error, in case attacker can read server logs. */
10476 PORT_SetError(SSL_ERROR_BAD_MAC_READ);
10477 return SECFailure;
10478 }
10479
10153 if (cipher_def->type == type_block && 10480 if (cipher_def->type == type_block &&
10154 crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { 10481 crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
10155 /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states 10482 /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states
10156 * "The receiver decrypts the entire GenericBlockCipher structure and 10483 * "The receiver decrypts the entire GenericBlockCipher structure and
10157 * then discards the first cipher block corresponding to the IV 10484 * then discards the first cipher block corresponding to the IV
10158 * component." Instead, we decrypt the first cipher block and then 10485 * component." Instead, we decrypt the first cipher block and then
10159 * discard it before decrypting the rest. 10486 * discard it before decrypting the rest.
10160 */ 10487 */
10161 SSL3Opaque iv[MAX_IV_LENGTH]; 10488 SSL3Opaque iv[MAX_IV_LENGTH];
10162 int decoded; 10489 int decoded;
10163 10490
10164 ivLen = cipher_def->iv_size; 10491 ivLen = cipher_def->iv_size;
10165 if (ivLen < 8 || ivLen > sizeof(iv)) { 10492 if (ivLen < 8 || ivLen > sizeof(iv)) {
10166 ssl_ReleaseSpecReadLock(ss); 10493 ssl_ReleaseSpecReadLock(ss);
10167 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 10494 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
10168 return SECFailure; 10495 return SECFailure;
10169 } 10496 }
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 10497
10181 PRINT_BUF(80, (ss, "IV (ciphertext):", cText->buf->buf, ivLen)); 10498 PRINT_BUF(80, (ss, "IV (ciphertext):", cText->buf->buf, ivLen));
10182 10499
10183 /* The decryption result is garbage, but since we just throw away 10500 /* The decryption result is garbage, but since we just throw away
10184 * the block it doesn't matter. The decryption of the next block 10501 * the block it doesn't matter. The decryption of the next block
10185 * depends only on the ciphertext of the IV block. 10502 * depends only on the ciphertext of the IV block.
10186 */ 10503 */
10187 rv = crSpec->decode(crSpec->decodeContext, iv, &decoded, 10504 rv = crSpec->decode(crSpec->decodeContext, iv, &decoded,
10188 sizeof(iv), cText->buf->buf, ivLen); 10505 sizeof(iv), cText->buf->buf, ivLen);
10189 10506
10190 » if (rv != SECSuccess) { 10507 » 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 } 10508 }
10197 10509
10198 /* If we will be decompressing the buffer we need to decrypt somewhere 10510 /* If we will be decompressing the buffer we need to decrypt somewhere
10199 * other than into databuf */ 10511 * other than into databuf */
10200 if (crSpec->decompressor) { 10512 if (crSpec->decompressor) {
10201 temp_buf.buf = NULL; 10513 temp_buf.buf = NULL;
10202 temp_buf.space = 0; 10514 temp_buf.space = 0;
10203 plaintext = &temp_buf; 10515 plaintext = &temp_buf;
10204 } else { 10516 } else {
10205 plaintext = databuf; 10517 plaintext = databuf;
(...skipping 21 matching lines...) Expand all
10227 ssl_ReleaseSpecReadLock(ss); 10539 ssl_ReleaseSpecReadLock(ss);
10228 SSL3_SendAlert(ss, alert_fatal, record_overflow); 10540 SSL3_SendAlert(ss, alert_fatal, record_overflow);
10229 PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG); 10541 PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
10230 return SECFailure; 10542 return SECFailure;
10231 } 10543 }
10232 10544
10233 /* decrypt from cText buf to plaintext. */ 10545 /* decrypt from cText buf to plaintext. */
10234 rv = crSpec->decode( 10546 rv = crSpec->decode(
10235 crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len, 10547 crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len,
10236 plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen); 10548 plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen);
10549 good &= SECStatusToMask(rv);
10237 10550
10238 PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len)); 10551 PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len));
10239 if (rv != SECSuccess) { 10552
10240 /* All decryption failures must be treated like a bad record 10553 originalLen = plaintext->len;
10241 * MAC; see RFC 5246 (TLS 1.2).
10242 */
10243 padIsBad = PR_TRUE;
10244 }
10245 10554
10246 /* If it's a block cipher, check and strip the padding. */ 10555 /* If it's a block cipher, check and strip the padding. */
10247 if (cipher_def->type == type_block && !padIsBad) { 10556 if (cipher_def->type == type_block) {
10248 PRUint8 * pPaddingLen = plaintext->buf + plaintext->len - 1; 10557 » const unsigned int blockSize = cipher_def->iv_size;
10249 » padding_length = *pPaddingLen; 10558 » const unsigned int macSize = crSpec->mac_size;
10250 » /* TLS permits padding to exceed the block size, up to 255 bytes. */ 10559
10251 » if (padding_length + 1 + crSpec->mac_size > plaintext->len) 10560 » if (crSpec->version <= SSL_LIBRARY_VERSION_3_0) {
10252 » padIsBad = PR_TRUE; 10561 » good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding(
10253 » else { 10562 » » » plaintext, blockSize, macSize));
10254 plaintext->len -= padding_length + 1; 10563 » } else {
10255 /* In TLS all padding bytes must be equal to the padding length. */ 10564 » good &= SECStatusToMask(ssl_RemoveTLSCBCPadding(
10256 if (isTLS) { 10565 » » » plaintext, macSize));
10257 PRUint8 *p; 10566 » }
10258 for (p = pPaddingLen - padding_length; p < pPaddingLen; ++p) {
10259 padIsBad |= *p ^ padding_length;
10260 }
10261 }
10262 }
10263 } 10567 }
10264 10568
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 */ 10569 /* compute the MAC */
10272 rType = cText->type; 10570 rType = cText->type;
10273 rv = ssl3_ComputeRecordMAC( crSpec, (PRBool)(!ss->sec.isServer), 10571 if (cipher_def->type == type_block) {
10274 IS_DTLS(ss), rType, cText->version, 10572 » rv = ssl3_ComputeRecordMACConstantTime(
10275 IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, 10573 » crSpec, (PRBool)(!ss->sec.isServer),
10276 » plaintext->buf, plaintext->len, hash, &hashBytes); 10574 » IS_DTLS(ss), rType, cText->version,
10277 if (rv != SECSuccess) { 10575 » IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
10278 padIsBad = PR_TRUE; /* really macIsBad */ 10576 » plaintext->buf, plaintext->len, originalLen,
10577 » hash, &hashBytes);
10578
10579 » ssl_CBCExtractMAC(plaintext, originalLen, givenHashBuf,
10580 » » » crSpec->mac_size);
10581 » givenHash = givenHashBuf;
10582
10583 » /* plaintext->len will always have enough space to remove the MAC
10584 » * because in ssl_Remove{SSLv3|TLS}CBCPadding we only adjust
10585 » * plaintext->len if the result has enough space for the MAC and we
10586 » * tested the unadjusted size against minLength, above. */
10587 » plaintext->len -= crSpec->mac_size;
10588 } else {
10589 » /* This is safe because we checked the minLength above. */
10590 » plaintext->len -= crSpec->mac_size;
10591
10592 » rv = ssl3_ComputeRecordMAC(
10593 » crSpec, (PRBool)(!ss->sec.isServer),
10594 » IS_DTLS(ss), rType, cText->version,
10595 » IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
10596 » plaintext->buf, plaintext->len,
10597 » hash, &hashBytes);
10598
10599 » /* We can read the MAC directly from the record because its location is
10600 » * public when a stream cipher is used. */
10601 » givenHash = plaintext->buf + plaintext->len;
10279 } 10602 }
10280 10603
10281 /* Check the MAC */ 10604 good &= SECStatusToMask(rv);
10282 if (hashBytes != (unsigned)crSpec->mac_size || padIsBad || 10605
10283 » NSS_SecureMemcmp(plaintext->buf + plaintext->len, hash, 10606 if (hashBytes != (unsigned)crSpec->mac_size ||
10284 » crSpec->mac_size) != 0) { 10607 » NSS_SecureMemcmp(givenHash, hash, crSpec->mac_size) != 0) {
10608 » /* We're allowed to leak whether or not the MAC check was correct */
10609 » good = 0;
10610 }
10611
10612 if (good == 0) {
10285 /* must not hold spec lock when calling SSL3_SendAlert. */ 10613 /* must not hold spec lock when calling SSL3_SendAlert. */
10286 ssl_ReleaseSpecReadLock(ss); 10614 ssl_ReleaseSpecReadLock(ss);
10287 10615
10288 SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd)); 10616 SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd));
10289 10617
10290 if (!IS_DTLS(ss)) { 10618 if (!IS_DTLS(ss)) {
10291 SSL3_SendAlert(ss, alert_fatal, bad_record_mac); 10619 SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
10292 /* always log mac error, in case attacker can read server logs. */ 10620 /* always log mac error, in case attacker can read server logs. */
10293 PORT_SetError(SSL_ERROR_BAD_MAC_READ); 10621 PORT_SetError(SSL_ERROR_BAD_MAC_READ);
10294 return SECFailure; 10622 return SECFailure;
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
10934 PORT_Free(ss->ssl3.hs.recvdFragments.buf); 11262 PORT_Free(ss->ssl3.hs.recvdFragments.buf);
10935 } 11263 }
10936 } 11264 }
10937 11265
10938 ss->ssl3.initialized = PR_FALSE; 11266 ss->ssl3.initialized = PR_FALSE;
10939 11267
10940 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 11268 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
10941 } 11269 }
10942 11270
10943 /* End of ssl3con.c */ 11271 /* 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