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

Side by Side Diff: net/third_party/nss/patches/cbc.patch

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

Powered by Google App Engine
This is Rietveld 408576698