OLD | NEW |
(Empty) | |
| 1 diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/s
sl/ssl3con.c |
| 2 index c3706fe..4247f44 100644 |
| 3 --- a/mozilla/security/nss/lib/ssl/ssl3con.c |
| 4 +++ b/mozilla/security/nss/lib/ssl/ssl3con.c |
| 5 @@ -1844,7 +1844,6 @@ static const unsigned char mac_pad_2 [60] = { |
| 6 }; |
| 7 |
| 8 /* Called from: ssl3_SendRecord() |
| 9 -** ssl3_HandleRecord() |
| 10 ** Caller must already hold the SpecReadLock. (wish we could assert that!) |
| 11 */ |
| 12 static SECStatus |
| 13 @@ -2026,6 +2025,128 @@ ssl3_ComputeRecordMAC( |
| 14 return rv; |
| 15 } |
| 16 |
| 17 +/* This is a bodge to allow this code to be compiled against older NSS headers |
| 18 + * that don't contain the CBC constant-time changes. */ |
| 19 +#ifndef CKM_NSS_HMAC_CONSTANT_TIME |
| 20 +#define CKM_NSS_HMAC_CONSTANT_TIME (CKM_NSS + 19) |
| 21 +#define CKM_NSS_SSLV3_MAC_CONSTANT_TIME (CKM_NSS + 20) |
| 22 + |
| 23 +typedef struct CK_NSS_MACConstantTimeParams { |
| 24 + CK_MECHANISM_TYPE hashAlg; /* in */ |
| 25 + CK_ULONG ulBodyTotalLength; /* in */ |
| 26 + CK_BYTE * pHeader; /* in */ |
| 27 + CK_ULONG ulHeaderLength; /* in */ |
| 28 +} CK_NSS_MACConstantTimeParams; |
| 29 +#endif |
| 30 + |
| 31 +/* Called from: ssl3_HandleRecord() |
| 32 + * Caller must already hold the SpecReadLock. (wish we could assert that!) |
| 33 + * |
| 34 + * On entry: |
| 35 + * originalLen >= inputLen >= MAC size |
| 36 +*/ |
| 37 +static SECStatus |
| 38 +ssl3_ComputeRecordMACConstantTime( |
| 39 + ssl3CipherSpec * spec, |
| 40 + PRBool useServerMacKey, |
| 41 + PRBool isDTLS, |
| 42 + SSL3ContentType type, |
| 43 + SSL3ProtocolVersion version, |
| 44 + SSL3SequenceNumber seq_num, |
| 45 + const SSL3Opaque * input, |
| 46 + int inputLen, |
| 47 + int originalLen, |
| 48 + unsigned char * outbuf, |
| 49 + unsigned int * outLen) |
| 50 +{ |
| 51 + CK_MECHANISM_TYPE macType; |
| 52 + CK_NSS_MACConstantTimeParams params; |
| 53 + PK11Context * mac_context; |
| 54 + SECItem param; |
| 55 + SECStatus rv; |
| 56 + unsigned char header[13]; |
| 57 + PK11SymKey * key; |
| 58 + int recordLength; |
| 59 + |
| 60 + PORT_Assert(inputLen >= spec->mac_size); |
| 61 + PORT_Assert(originalLen >= inputLen); |
| 62 + |
| 63 + if (spec->bypassCiphers) { |
| 64 + /* This function doesn't support PKCS#11 bypass. We fallback on the |
| 65 + * non-constant time version. */ |
| 66 + goto fallback; |
| 67 + } |
| 68 + |
| 69 + if (spec->mac_def->mac == mac_null) { |
| 70 + *outLen = 0; |
| 71 + return SECSuccess; |
| 72 + } |
| 73 + |
| 74 + header[0] = (unsigned char)(seq_num.high >> 24); |
| 75 + header[1] = (unsigned char)(seq_num.high >> 16); |
| 76 + header[2] = (unsigned char)(seq_num.high >> 8); |
| 77 + header[3] = (unsigned char)(seq_num.high >> 0); |
| 78 + header[4] = (unsigned char)(seq_num.low >> 24); |
| 79 + header[5] = (unsigned char)(seq_num.low >> 16); |
| 80 + header[6] = (unsigned char)(seq_num.low >> 8); |
| 81 + header[7] = (unsigned char)(seq_num.low >> 0); |
| 82 + header[8] = type; |
| 83 + |
| 84 + macType = CKM_NSS_HMAC_CONSTANT_TIME; |
| 85 + recordLength = inputLen - spec->mac_size; |
| 86 + if (spec->version <= SSL_LIBRARY_VERSION_3_0) { |
| 87 + macType = CKM_NSS_SSLV3_MAC_CONSTANT_TIME; |
| 88 + header[9] = recordLength >> 8; |
| 89 + header[10] = recordLength; |
| 90 + params.ulHeaderLength = 11; |
| 91 + } else { |
| 92 + header[9] = version >> 8; |
| 93 + header[10] = version; |
| 94 + header[11] = recordLength >> 8; |
| 95 + header[12] = recordLength; |
| 96 + params.ulHeaderLength = 13; |
| 97 + } |
| 98 + |
| 99 + params.hashAlg = spec->mac_def->mmech; |
| 100 + params.ulBodyTotalLength = originalLen; |
| 101 + params.pHeader = header; |
| 102 + |
| 103 + param.data = (unsigned char*) ¶ms; |
| 104 + param.len = sizeof(params); |
| 105 + param.type = 0; |
| 106 + |
| 107 + key = spec->server.write_mac_key; |
| 108 + if (!useServerMacKey) { |
| 109 + key = spec->client.write_mac_key; |
| 110 + } |
| 111 + mac_context = PK11_CreateContextBySymKey(macType, CKA_SIGN, key, ¶m); |
| 112 + if (mac_context == NULL) { |
| 113 + /* Older versions of NSS may not support constant-time MAC. */ |
| 114 + goto fallback; |
| 115 + } |
| 116 + |
| 117 + rv = PK11_DigestBegin(mac_context); |
| 118 + rv |= PK11_DigestOp(mac_context, input, inputLen); |
| 119 + rv |= PK11_DigestFinal(mac_context, outbuf, outLen, spec->mac_size); |
| 120 + PK11_DestroyContext(mac_context, PR_TRUE); |
| 121 + |
| 122 + PORT_Assert(rv != SECSuccess || *outLen == (unsigned)spec->mac_size); |
| 123 + |
| 124 + if (rv != SECSuccess) { |
| 125 + rv = SECFailure; |
| 126 + ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); |
| 127 + } |
| 128 + return rv; |
| 129 + |
| 130 +fallback: |
| 131 + /* ssl3_ComputeRecordMAC expects the MAC to have been removed from the |
| 132 + * length already. */ |
| 133 + inputLen -= spec->mac_size; |
| 134 + return ssl3_ComputeRecordMAC(spec, useServerMacKey, isDTLS, type, |
| 135 + version, seq_num, input, inputLen, |
| 136 + outbuf, outLen); |
| 137 +} |
| 138 + |
| 139 static PRBool |
| 140 ssl3_ClientAuthTokenPresent(sslSessionID *sid) { |
| 141 PK11SlotInfo *slot = NULL; |
| 142 @@ -9530,6 +9651,177 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf) |
| 143 return SECSuccess; |
| 144 } |
| 145 |
| 146 +/* These macros return the given value with the MSB copied to all the other |
| 147 + * bits. They use the fact that arithmetic shift shifts-in the sign bit. |
| 148 + * However, this is not ensured by the C standard so you may need to replace |
| 149 + * them with something else for odd compilers. */ |
| 150 +#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) ) |
| 151 +#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x))) |
| 152 + |
| 153 +/* SECStatusToMask returns, in constant time, a mask value of all ones if rv == |
| 154 + * SECSuccess. Otherwise it returns zero. */ |
| 155 +static unsigned SECStatusToMask(SECStatus rv) |
| 156 +{ |
| 157 + unsigned int good; |
| 158 + /* rv ^ SECSuccess is zero iff rv == SECSuccess. Subtracting one results in |
| 159 + * the MSB being set to one iff it was zero before. */ |
| 160 + good = rv ^ SECSuccess; |
| 161 + good--; |
| 162 + return DUPLICATE_MSB_TO_ALL(good); |
| 163 +} |
| 164 + |
| 165 +/* ssl_ConstantTimeGE returns 0xff if a>=b and 0x00 otherwise. */ |
| 166 +static unsigned char ssl_ConstantTimeGE(unsigned a, unsigned b) |
| 167 +{ |
| 168 + a -= b; |
| 169 + return DUPLICATE_MSB_TO_ALL(~a); |
| 170 +} |
| 171 + |
| 172 +/* ssl_ConstantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */ |
| 173 +static unsigned char ssl_ConstantTimeEQ8(unsigned char a, unsigned char b) |
| 174 +{ |
| 175 + unsigned c = a ^ b; |
| 176 + c--; |
| 177 + return DUPLICATE_MSB_TO_ALL_8(c); |
| 178 +} |
| 179 + |
| 180 +static SECStatus ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext, |
| 181 + unsigned blockSize, |
| 182 + unsigned macSize) { |
| 183 + unsigned int paddingLength, good, t; |
| 184 + const unsigned int overhead = 1 /* padding length byte */ + macSize; |
| 185 + |
| 186 + /* These lengths are all public so we can test them in non-constant |
| 187 + * time. */ |
| 188 + if (overhead > plaintext->len) { |
| 189 + return SECFailure; |
| 190 + } |
| 191 + |
| 192 + paddingLength = plaintext->buf[plaintext->len-1]; |
| 193 + /* SSLv3 padding bytes are random and cannot be checked. */ |
| 194 + t = plaintext->len; |
| 195 + t -= paddingLength+overhead; |
| 196 + /* If len >= padding_length+overhead then the MSB of t is zero. */ |
| 197 + good = DUPLICATE_MSB_TO_ALL(~t); |
| 198 + /* SSLv3 requires that the padding is minimal. */ |
| 199 + t = blockSize - (paddingLength+1); |
| 200 + good &= DUPLICATE_MSB_TO_ALL(~t); |
| 201 + plaintext->len -= good & (paddingLength+1); |
| 202 + return (good & SECSuccess) | (~good & SECFailure); |
| 203 +} |
| 204 + |
| 205 + |
| 206 +static SECStatus ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, |
| 207 + unsigned macSize) { |
| 208 + unsigned int paddingLength, good, t, toCheck, i; |
| 209 + const unsigned int overhead = 1 /* padding length byte */ + macSize; |
| 210 + |
| 211 + /* These lengths are all public so we can test them in non-constant |
| 212 + * time. */ |
| 213 + if (overhead > plaintext->len) { |
| 214 + return SECFailure; |
| 215 + } |
| 216 + |
| 217 + paddingLength = plaintext->buf[plaintext->len-1]; |
| 218 + t = plaintext->len; |
| 219 + t -= paddingLength+overhead; |
| 220 + /* If len >= paddingLength+overhead then the MSB of t is zero. */ |
| 221 + good = DUPLICATE_MSB_TO_ALL(~t); |
| 222 + |
| 223 + /* The padding consists of a length byte at the end of the record and then |
| 224 + * that many bytes of padding, all with the same value as the length byte. |
| 225 + * Thus, with the length byte included, there are paddingLength+1 bytes of |
| 226 + * padding. |
| 227 + * |
| 228 + * We can't check just |paddingLength+1| bytes because that leaks |
| 229 + * decrypted information. Therefore we always have to check the maximum |
| 230 + * amount of padding possible. (Again, the length of the record is |
| 231 + * public information so we can use it.) */ |
| 232 + toCheck = 255; /* maximum amount of padding. */ |
| 233 + if (toCheck > plaintext->len-1) { |
| 234 + toCheck = plaintext->len-1; |
| 235 + } |
| 236 + |
| 237 + for (i = 0; i < toCheck; i++) { |
| 238 + unsigned int t = paddingLength - i; |
| 239 + /* If i <= paddingLength then the MSB of t is zero and mask is |
| 240 + * 0xff. Otherwise, mask is 0. */ |
| 241 + unsigned char mask = DUPLICATE_MSB_TO_ALL(~t); |
| 242 + unsigned char b = plaintext->buf[plaintext->len-1-i]; |
| 243 + /* The final |paddingLength+1| bytes should all have the value |
| 244 + * |paddingLength|. Therefore the XOR should be zero. */ |
| 245 + good &= ~(mask&(paddingLength ^ b)); |
| 246 + } |
| 247 + |
| 248 + /* If any of the final |paddingLength+1| bytes had the wrong value, |
| 249 + * one or more of the lower eight bits of |good| will be cleared. We |
| 250 + * AND the bottom 8 bits together and duplicate the result to all the |
| 251 + * bits. */ |
| 252 + good &= good >> 4; |
| 253 + good &= good >> 2; |
| 254 + good &= good >> 1; |
| 255 + good <<= sizeof(good)*8-1; |
| 256 + good = DUPLICATE_MSB_TO_ALL(good); |
| 257 + |
| 258 + plaintext->len -= good & (paddingLength+1); |
| 259 + return (good & SECSuccess) | (~good & SECFailure); |
| 260 +} |
| 261 + |
| 262 +/* On entry: |
| 263 + * originalLength >= macSize |
| 264 + * macSize <= MAX_MAC_LENGTH |
| 265 + * plaintext->len >= macSize |
| 266 + */ |
| 267 +static void ssl_CBCExtractMAC(sslBuffer *plaintext, |
| 268 + unsigned int originalLength, |
| 269 + SSL3Opaque* out, |
| 270 + unsigned int macSize) { |
| 271 + unsigned char rotatedMac[MAX_MAC_LENGTH]; |
| 272 + /* macEnd is the index of |plaintext->buf| just after the end of the MAC. *
/ |
| 273 + unsigned macEnd = plaintext->len; |
| 274 + unsigned macStart = macEnd - macSize; |
| 275 + /* scanStart contains the number of bytes that we can ignore because |
| 276 + * the MAC's position can only vary by 255 bytes. */ |
| 277 + unsigned scanStart = 0; |
| 278 + unsigned i, j, divSpoiler; |
| 279 + unsigned char rotateOffset; |
| 280 + |
| 281 + if (originalLength > macSize + 255 + 1) |
| 282 + scanStart = originalLength - (macSize + 255 + 1); |
| 283 + |
| 284 + /* divSpoiler contains a multiple of macSize that is used to cause the |
| 285 + * modulo operation to be constant time. Without this, the time varies |
| 286 + * based on the amount of padding when running on Intel chips at least. |
| 287 + * |
| 288 + * The aim of right-shifting macSize is so that the compiler doesn't |
| 289 + * figure out that it can remove divSpoiler as that would require it |
| 290 + * to prove that macSize is always even, which I hope is beyond it. */ |
| 291 + divSpoiler = macSize >> 1; |
| 292 + divSpoiler <<= (sizeof(divSpoiler)-1)*8; |
| 293 + rotateOffset = (divSpoiler + macStart - scanStart) % macSize; |
| 294 + |
| 295 + memset(rotatedMac, 0, macSize); |
| 296 + for (i = scanStart; i < originalLength;) { |
| 297 + for (j = 0; j < macSize && i < originalLength; i++, j++) { |
| 298 + unsigned char macStarted = ssl_ConstantTimeGE(i, macStart); |
| 299 + unsigned char macEnded = ssl_ConstantTimeGE(i, macEnd); |
| 300 + unsigned char b = 0; |
| 301 + b = plaintext->buf[i]; |
| 302 + rotatedMac[j] |= b & macStarted & ~macEnded; |
| 303 + } |
| 304 + } |
| 305 + |
| 306 + /* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line we |
| 307 + * could line-align |rotatedMac| and rotate in place. */ |
| 308 + memset(out, 0, macSize); |
| 309 + for (i = 0; i < macSize; i++) { |
| 310 + unsigned char offset = (divSpoiler + macSize - rotateOffset + i) % macSi
ze; |
| 311 + for (j = 0; j < macSize; j++) { |
| 312 + out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, offset); |
| 313 + } |
| 314 + } |
| 315 +} |
| 316 + |
| 317 /* if cText is non-null, then decipher, check MAC, and decompress the |
| 318 * SSL record from cText->buf (typically gs->inbuf) |
| 319 * into databuf (typically gs->buf), and any previous contents of databuf |
| 320 @@ -9559,15 +9851,18 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText,
sslBuffer *databuf) |
| 321 ssl3CipherSpec * crSpec; |
| 322 SECStatus rv; |
| 323 unsigned int hashBytes = MAX_MAC_LENGTH + 1; |
| 324 - unsigned int padding_length; |
| 325 PRBool isTLS; |
| 326 - PRBool padIsBad = PR_FALSE; |
| 327 SSL3ContentType rType; |
| 328 SSL3Opaque hash[MAX_MAC_LENGTH]; |
| 329 + SSL3Opaque givenHashBuf[MAX_MAC_LENGTH]; |
| 330 + SSL3Opaque *givenHash; |
| 331 sslBuffer *plaintext; |
| 332 sslBuffer temp_buf; |
| 333 PRUint64 dtls_seq_num; |
| 334 unsigned int ivLen = 0; |
| 335 + unsigned int originalLen = 0; |
| 336 + unsigned int good; |
| 337 + unsigned int minLength; |
| 338 |
| 339 PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); |
| 340 |
| 341 @@ -9635,6 +9930,30 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, s
slBuffer *databuf) |
| 342 } |
| 343 } |
| 344 |
| 345 + good = (unsigned)-1; |
| 346 + minLength = crSpec->mac_size; |
| 347 + if (cipher_def->type == type_block) { |
| 348 + /* CBC records have a padding length byte at the end. */ |
| 349 + minLength++; |
| 350 + if (crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { |
| 351 + /* With >= TLS 1.1, CBC records have an explicit IV. */ |
| 352 + minLength += cipher_def->iv_size; |
| 353 + } |
| 354 + } |
| 355 + |
| 356 + /* We can perform this test in variable time because the record's total |
| 357 + * length and the ciphersuite are both public knowledge. */ |
| 358 + if (cText->buf->len < minLength) { |
| 359 + SSL_DBG(("%d: SSL3[%d]: HandleRecord, record too small.", |
| 360 + SSL_GETPID(), ss->fd)); |
| 361 + /* must not hold spec lock when calling SSL3_SendAlert. */ |
| 362 + ssl_ReleaseSpecReadLock(ss); |
| 363 + SSL3_SendAlert(ss, alert_fatal, bad_record_mac); |
| 364 + /* always log mac error, in case attacker can read server logs. */ |
| 365 + PORT_SetError(SSL_ERROR_BAD_MAC_READ); |
| 366 + return SECFailure; |
| 367 + } |
| 368 + |
| 369 if (cipher_def->type == type_block && |
| 370 crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) { |
| 371 /* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states |
| 372 @@ -9652,16 +9971,6 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, s
slBuffer *databuf) |
| 373 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
| 374 return SECFailure; |
| 375 } |
| 376 - if (ivLen > cText->buf->len) { |
| 377 - SSL_DBG(("%d: SSL3[%d]: HandleRecord, IV length check failed", |
| 378 - SSL_GETPID(), ss->fd)); |
| 379 - /* must not hold spec lock when calling SSL3_SendAlert. */ |
| 380 - ssl_ReleaseSpecReadLock(ss); |
| 381 - SSL3_SendAlert(ss, alert_fatal, bad_record_mac); |
| 382 - /* always log mac error, in case attacker can read server logs. */ |
| 383 - PORT_SetError(SSL_ERROR_BAD_MAC_READ); |
| 384 - return SECFailure; |
| 385 - } |
| 386 |
| 387 PRINT_BUF(80, (ss, "IV (ciphertext):", cText->buf->buf, ivLen)); |
| 388 |
| 389 @@ -9672,12 +9981,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, s
slBuffer *databuf) |
| 390 rv = crSpec->decode(crSpec->decodeContext, iv, &decoded, |
| 391 sizeof(iv), cText->buf->buf, ivLen); |
| 392 |
| 393 - if (rv != SECSuccess) { |
| 394 - /* All decryption failures must be treated like a bad record |
| 395 - * MAC; see RFC 5246 (TLS 1.2). |
| 396 - */ |
| 397 - padIsBad = PR_TRUE; |
| 398 - } |
| 399 + good &= SECStatusToMask(rv); |
| 400 } |
| 401 |
| 402 /* If we will be decompressing the buffer we need to decrypt somewhere |
| 403 @@ -9719,54 +10023,70 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText,
sslBuffer *databuf) |
| 404 rv = crSpec->decode( |
| 405 crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len, |
| 406 plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen); |
| 407 + good &= SECStatusToMask(rv); |
| 408 |
| 409 PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len)); |
| 410 - if (rv != SECSuccess) { |
| 411 - /* All decryption failures must be treated like a bad record |
| 412 - * MAC; see RFC 5246 (TLS 1.2). |
| 413 - */ |
| 414 - padIsBad = PR_TRUE; |
| 415 - } |
| 416 + |
| 417 + originalLen = plaintext->len; |
| 418 |
| 419 /* If it's a block cipher, check and strip the padding. */ |
| 420 - if (cipher_def->type == type_block && !padIsBad) { |
| 421 - PRUint8 * pPaddingLen = plaintext->buf + plaintext->len - 1; |
| 422 - padding_length = *pPaddingLen; |
| 423 - /* TLS permits padding to exceed the block size, up to 255 bytes. */ |
| 424 - if (padding_length + 1 + crSpec->mac_size > plaintext->len) |
| 425 - padIsBad = PR_TRUE; |
| 426 - else { |
| 427 - plaintext->len -= padding_length + 1; |
| 428 - /* In TLS all padding bytes must be equal to the padding length. */ |
| 429 - if (isTLS) { |
| 430 - PRUint8 *p; |
| 431 - for (p = pPaddingLen - padding_length; p < pPaddingLen; ++p) { |
| 432 - padIsBad |= *p ^ padding_length; |
| 433 - } |
| 434 - } |
| 435 - } |
| 436 - } |
| 437 + if (cipher_def->type == type_block) { |
| 438 + const unsigned int blockSize = cipher_def->iv_size; |
| 439 + const unsigned int macSize = crSpec->mac_size; |
| 440 |
| 441 - /* Remove the MAC. */ |
| 442 - if (plaintext->len >= crSpec->mac_size) |
| 443 - plaintext->len -= crSpec->mac_size; |
| 444 - else |
| 445 - padIsBad = PR_TRUE; /* really macIsBad */ |
| 446 + if (crSpec->version <= SSL_LIBRARY_VERSION_3_0) { |
| 447 + good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding( |
| 448 + plaintext, blockSize, macSize)); |
| 449 + } else { |
| 450 + good &= SECStatusToMask(ssl_RemoveTLSCBCPadding( |
| 451 + plaintext, macSize)); |
| 452 + } |
| 453 + } |
| 454 |
| 455 /* compute the MAC */ |
| 456 rType = cText->type; |
| 457 - rv = ssl3_ComputeRecordMAC( crSpec, (PRBool)(!ss->sec.isServer), |
| 458 - IS_DTLS(ss), rType, cText->version, |
| 459 - IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, |
| 460 - plaintext->buf, plaintext->len, hash, &hashBytes); |
| 461 - if (rv != SECSuccess) { |
| 462 - padIsBad = PR_TRUE; /* really macIsBad */ |
| 463 + if (cipher_def->type == type_block) { |
| 464 + rv = ssl3_ComputeRecordMACConstantTime( |
| 465 + crSpec, (PRBool)(!ss->sec.isServer), |
| 466 + IS_DTLS(ss), rType, cText->version, |
| 467 + IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, |
| 468 + plaintext->buf, plaintext->len, originalLen, |
| 469 + hash, &hashBytes); |
| 470 + |
| 471 + ssl_CBCExtractMAC(plaintext, originalLen, givenHashBuf, |
| 472 + crSpec->mac_size); |
| 473 + givenHash = givenHashBuf; |
| 474 + |
| 475 + /* plaintext->len will always have enough space to remove the MAC |
| 476 + * because in ssl_Remove{SSLv3|TLS}CBCPadding we only adjust |
| 477 + * plaintext->len if the result has enough space for the MAC and we |
| 478 + * tested the unadjusted size against minLength, above. */ |
| 479 + plaintext->len -= crSpec->mac_size; |
| 480 + } else { |
| 481 + /* This is safe because we checked the minLength above. */ |
| 482 + plaintext->len -= crSpec->mac_size; |
| 483 + |
| 484 + rv = ssl3_ComputeRecordMAC( |
| 485 + crSpec, (PRBool)(!ss->sec.isServer), |
| 486 + IS_DTLS(ss), rType, cText->version, |
| 487 + IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num, |
| 488 + plaintext->buf, plaintext->len, |
| 489 + hash, &hashBytes); |
| 490 + |
| 491 + /* We can read the MAC directly from the record because its location is |
| 492 + * public when a stream cipher is used. */ |
| 493 + givenHash = plaintext->buf + plaintext->len; |
| 494 + } |
| 495 + |
| 496 + good &= SECStatusToMask(rv); |
| 497 + |
| 498 + if (hashBytes != (unsigned)crSpec->mac_size || |
| 499 + NSS_SecureMemcmp(givenHash, hash, crSpec->mac_size) != 0) { |
| 500 + /* We're allowed to leak whether or not the MAC check was correct */ |
| 501 + good = 0; |
| 502 } |
| 503 |
| 504 - /* Check the MAC */ |
| 505 - if (hashBytes != (unsigned)crSpec->mac_size || padIsBad || |
| 506 - NSS_SecureMemcmp(plaintext->buf + plaintext->len, hash, |
| 507 - crSpec->mac_size) != 0) { |
| 508 + if (good == 0) { |
| 509 /* must not hold spec lock when calling SSL3_SendAlert. */ |
| 510 ssl_ReleaseSpecReadLock(ss); |
| 511 |
OLD | NEW |