Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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*) ¶ms; | |
| 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, ¶m); | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 */ |
| OLD | NEW |