LEFT | RIGHT |
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 | 8 |
9 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ | 9 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */ |
10 | 10 |
(...skipping 12538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12549 sid->u.ssl3.cipherSuite = | 12549 sid->u.ssl3.cipherSuite = |
12550 ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 ? ss->ssl3.hs.origCipherSuite
: ss->ssl3.hs.cipher_suite; | 12550 ss->version >= SSL_LIBRARY_VERSION_TLS_1_3 ? ss->ssl3.hs.origCipherSuite
: ss->ssl3.hs.cipher_suite; |
12551 sid->u.ssl3.compression = ss->ssl3.hs.compression; | 12551 sid->u.ssl3.compression = ss->ssl3.hs.compression; |
12552 sid->u.ssl3.policy = ss->ssl3.policy; | 12552 sid->u.ssl3.policy = ss->ssl3.policy; |
12553 sid->version = ss->version; | 12553 sid->version = ss->version; |
12554 sid->authType = ss->sec.authType; | 12554 sid->authType = ss->sec.authType; |
12555 sid->authKeyBits = ss->sec.authKeyBits; | 12555 sid->authKeyBits = ss->sec.authKeyBits; |
12556 sid->keaType = ss->sec.keaType; | 12556 sid->keaType = ss->sec.keaType; |
12557 sid->keaKeyBits = ss->sec.keaKeyBits; | 12557 sid->keaKeyBits = ss->sec.keaKeyBits; |
12558 sid->namedGroupPreferenceCount = ss->namedGroupPreferenceCount; | 12558 sid->namedGroupPreferenceCount = ss->namedGroupPreferenceCount; |
12559 if (ss->namedGroupPreferenceCount) { | 12559 PORT_Memcpy(sid->namedGroupPreferences, ss->namedGroupPreferences, |
12560 int i; | 12560 ss->namedGroupPreferenceCount * sizeof(namedGroupDef)); |
12561 for (i = 0; i < ss->namedGroupPreferenceCount; ++i) { | |
12562 sid->namedGroupPreferences[i] = ss->namedGroupPreferences[i]; | |
12563 } | |
12564 } | |
12565 sid->lastAccessTime = sid->creationTime = ssl_Time(); | 12561 sid->lastAccessTime = sid->creationTime = ssl_Time(); |
12566 sid->expirationTime = sid->creationTime + ssl3_sid_timeout; | 12562 sid->expirationTime = sid->creationTime + ssl3_sid_timeout; |
12567 sid->localCert = CERT_DupCertificate(ss->sec.localCert); | 12563 sid->localCert = CERT_DupCertificate(ss->sec.localCert); |
12568 if (ss->sec.isServer) { | 12564 if (ss->sec.isServer) { |
12569 memcpy(&sid->certType, &ss->sec.serverCert->certType, sizeof(sid->certTy
pe)); | 12565 memcpy(&sid->certType, &ss->sec.serverCert->certType, sizeof(sid->certTy
pe)); |
12570 } else { | 12566 } else { |
12571 sid->certType.authType = ssl_auth_null; | 12567 sid->certType.authType = ssl_auth_null; |
12572 } | 12568 } |
12573 | 12569 |
12574 if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && | 12570 if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13100 | 13096 |
13101 /* ssl_ConstantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */ | 13097 /* ssl_ConstantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */ |
13102 static unsigned char | 13098 static unsigned char |
13103 ssl_ConstantTimeEQ8(unsigned char a, unsigned char b) | 13099 ssl_ConstantTimeEQ8(unsigned char a, unsigned char b) |
13104 { | 13100 { |
13105 unsigned int c = a ^ b; | 13101 unsigned int c = a ^ b; |
13106 c--; | 13102 c--; |
13107 return DUPLICATE_MSB_TO_ALL_8(c); | 13103 return DUPLICATE_MSB_TO_ALL_8(c); |
13108 } | 13104 } |
13109 | 13105 |
| 13106 /* ssl_constantTimeSelect return a if mask is 0xFF and b if mask is 0x00 */ |
| 13107 static unsigned char |
| 13108 ssl_constantTimeSelect(unsigned char mask, unsigned char a, unsigned char b) |
| 13109 { |
| 13110 return (mask & a) | (~mask & b); |
| 13111 } |
| 13112 |
13110 static SECStatus | 13113 static SECStatus |
13111 ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext, | 13114 ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext, |
13112 unsigned int blockSize, | 13115 unsigned int blockSize, |
13113 unsigned int macSize) | 13116 unsigned int macSize) |
13114 { | 13117 { |
13115 unsigned int paddingLength, good, t; | 13118 unsigned int paddingLength, good, t; |
13116 const unsigned int overhead = 1 /* padding length byte */ + macSize; | 13119 const unsigned int overhead = 1 /* padding length byte */ + macSize; |
13117 | 13120 |
13118 /* These lengths are all public so we can test them in non-constant | 13121 /* These lengths are all public so we can test them in non-constant |
13119 * time. */ | 13122 * time. */ |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13203 unsigned int macSize) | 13206 unsigned int macSize) |
13204 { | 13207 { |
13205 unsigned char rotatedMac[MAX_MAC_LENGTH]; | 13208 unsigned char rotatedMac[MAX_MAC_LENGTH]; |
13206 /* macEnd is the index of |plaintext->buf| just after the end of the | 13209 /* macEnd is the index of |plaintext->buf| just after the end of the |
13207 * MAC. */ | 13210 * MAC. */ |
13208 unsigned macEnd = plaintext->len; | 13211 unsigned macEnd = plaintext->len; |
13209 unsigned macStart = macEnd - macSize; | 13212 unsigned macStart = macEnd - macSize; |
13210 /* scanStart contains the number of bytes that we can ignore because | 13213 /* scanStart contains the number of bytes that we can ignore because |
13211 * the MAC's position can only vary by 255 bytes. */ | 13214 * the MAC's position can only vary by 255 bytes. */ |
13212 unsigned scanStart = 0; | 13215 unsigned scanStart = 0; |
13213 unsigned i, j, divSpoiler; | 13216 unsigned i, j; |
13214 unsigned char rotateOffset; | 13217 unsigned char rotateOffset; |
13215 | 13218 |
13216 if (originalLength > macSize + 255 + 1) | 13219 if (originalLength > macSize + 255 + 1) { |
13217 scanStart = originalLength - (macSize + 255 + 1); | 13220 scanStart = originalLength - (macSize + 255 + 1); |
13218 | 13221 } |
13219 /* divSpoiler contains a multiple of macSize that is used to cause the | 13222 |
13220 * modulo operation to be constant time. Without this, the time varies | 13223 /* We want to compute |
13221 * based on the amount of padding when running on Intel chips at least. | 13224 * rotateOffset = (macStart - scanStart) % macSize |
13222 * | 13225 * But the time to compute this varies based on the amount of padding. Thus |
13223 * The aim of right-shifting macSize is so that the compiler doesn't | 13226 * we explicitely handle all mac sizes with (hopefully) constant time modulo |
13224 * figure out that it can remove divSpoiler as that would require it | 13227 * using Barrett reduction: |
13225 * to prove that macSize is always even, which I hope is beyond it. */ | 13228 * q := (rotateOffset * m) >> k |
13226 divSpoiler = macSize >> 1; | 13229 * rotateOffset -= q * n |
13227 divSpoiler <<= (sizeof(divSpoiler) - 1) * 8; | 13230 * if (n <= rotateOffset) rotateOffset -= n |
13228 rotateOffset = (divSpoiler + macStart - scanStart) % macSize; | 13231 */ |
| 13232 rotateOffset = macStart - scanStart; |
| 13233 /* rotateOffset < 255 + 1 + 48 = 304 */ |
| 13234 if (macSize == 16) { |
| 13235 rotateOffset &= 15; |
| 13236 } else if (macSize == 20) { |
| 13237 /* |
| 13238 * Correctness: rotateOffset * ( 1/20 - 25/2^9 ) < 1 |
| 13239 * with rotateOffset <= 853 |
| 13240 */ |
| 13241 unsigned q = (rotateOffset * 25) >> 9; |
| 13242 rotateOffset -= q * 20; |
| 13243 rotateOffset -= ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset,
20), |
| 13244 20, 0); |
| 13245 } else if (macSize == 32) { |
| 13246 rotateOffset &= 31; |
| 13247 } else if (macSize == 48) { |
| 13248 /* |
| 13249 * Correctness: rotateOffset * ( 1/48 - 10/2^9 ) < 1 |
| 13250 * with rotateOffset < 768 |
| 13251 */ |
| 13252 unsigned q = (rotateOffset * 10) >> 9; |
| 13253 rotateOffset -= q * 48; |
| 13254 rotateOffset -= ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset,
48), |
| 13255 48, 0); |
| 13256 } else { |
| 13257 /* |
| 13258 * SHA384 (macSize == 48) is the largest we support. We should never |
| 13259 * get here. |
| 13260 */ |
| 13261 PORT_Assert(0); |
| 13262 rotateOffset = rotateOffset % macSize; |
| 13263 } |
13229 | 13264 |
13230 memset(rotatedMac, 0, macSize); | 13265 memset(rotatedMac, 0, macSize); |
13231 for (i = scanStart; i < originalLength;) { | 13266 for (i = scanStart; i < originalLength;) { |
13232 for (j = 0; j < macSize && i < originalLength; i++, j++) { | 13267 for (j = 0; j < macSize && i < originalLength; i++, j++) { |
13233 unsigned char macStarted = ssl_ConstantTimeGE(i, macStart); | 13268 unsigned char macStarted = ssl_ConstantTimeGE(i, macStart); |
13234 unsigned char macEnded = ssl_ConstantTimeGE(i, macEnd); | 13269 unsigned char macEnded = ssl_ConstantTimeGE(i, macEnd); |
13235 unsigned char b = 0; | 13270 unsigned char b = 0; |
13236 b = plaintext->buf[i]; | 13271 b = plaintext->buf[i]; |
13237 rotatedMac[j] |= b & macStarted & ~macEnded; | 13272 rotatedMac[j] |= b & macStarted & ~macEnded; |
13238 } | 13273 } |
13239 } | 13274 } |
13240 | 13275 |
13241 /* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line | 13276 /* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line |
13242 * we could line-align |rotatedMac| and rotate in place. */ | 13277 * we could line-align |rotatedMac| and rotate in place. */ |
13243 memset(out, 0, macSize); | 13278 memset(out, 0, macSize); |
| 13279 rotateOffset = macSize - rotateOffset; |
| 13280 rotateOffset = ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, macSi
ze), |
| 13281 0, rotateOffset); |
13244 for (i = 0; i < macSize; i++) { | 13282 for (i = 0; i < macSize; i++) { |
13245 unsigned char offset = | |
13246 (divSpoiler + macSize - rotateOffset + i) % macSize; | |
13247 for (j = 0; j < macSize; j++) { | 13283 for (j = 0; j < macSize; j++) { |
13248 out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, offset); | 13284 out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, rotateOffset); |
13249 } | 13285 } |
| 13286 rotateOffset++; |
| 13287 rotateOffset = ssl_constantTimeSelect(ssl_ConstantTimeGE(rotateOffset, m
acSize), |
| 13288 0, rotateOffset); |
13250 } | 13289 } |
13251 } | 13290 } |
13252 | 13291 |
13253 /* Unprotect an SSL3 record and leave the result in plaintext. | 13292 /* Unprotect an SSL3 record and leave the result in plaintext. |
13254 * | 13293 * |
13255 * If SECFailure is returned, we: | 13294 * If SECFailure is returned, we: |
13256 * 1. Set |*alert| to the alert to be sent. | 13295 * 1. Set |*alert| to the alert to be sent. |
13257 * 2. Call PORT_SetError() with an appropriate code. | 13296 * 2. Call PORT_SetError() with an appropriate code. |
13258 * | 13297 * |
13259 * Called by ssl3_HandleRecord. Caller must hold the spec read lock. | 13298 * Called by ssl3_HandleRecord. Caller must hold the spec read lock. |
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14261 } | 14300 } |
14262 } | 14301 } |
14263 } | 14302 } |
14264 | 14303 |
14265 rv = ssl3_ConstrainRangeByPolicy(); | 14304 rv = ssl3_ConstrainRangeByPolicy(); |
14266 | 14305 |
14267 return rv; | 14306 return rv; |
14268 } | 14307 } |
14269 | 14308 |
14270 /* End of ssl3con.c */ | 14309 /* End of ssl3con.c */ |
LEFT | RIGHT |