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

Side by Side Diff: net/third_party/nss/ssl/ssl3con.c

Issue 12417005: Split RC4-encrypted records. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 9 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 | « no previous file | 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 2398 matching lines...) Expand 10 before | Expand all | Expand 10 after
2409 SECStatus rv; 2409 SECStatus rv;
2410 PRInt32 totalSent = 0; 2410 PRInt32 totalSent = 0;
2411 PRBool capRecordVersion; 2411 PRBool capRecordVersion;
2412 2412
2413 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d", 2413 SSL_TRC(3, ("%d: SSL3[%d] SendRecord type: %s nIn=%d",
2414 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type), 2414 SSL_GETPID(), ss->fd, ssl3_DecodeContentType(type),
2415 nIn)); 2415 nIn));
2416 PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn)); 2416 PRINT_BUF(3, (ss, "Send record (plain text)", pIn, nIn));
2417 2417
2418 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) ); 2418 PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss) );
2419 PORT_Assert( wrBuf->len == 0 );
2419 2420
2420 capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0); 2421 capRecordVersion = ((flags & ssl_SEND_FLAG_CAP_RECORD_VERSION) != 0);
2421 2422
2422 if (capRecordVersion) { 2423 if (capRecordVersion) {
2423 /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the 2424 /* ssl_SEND_FLAG_CAP_RECORD_VERSION can only be used with the
2424 * TLS initial ClientHello. */ 2425 * TLS initial ClientHello. */
2425 PORT_Assert(!IS_DTLS(ss)); 2426 PORT_Assert(!IS_DTLS(ss));
2426 PORT_Assert(!ss->firstHsDone); 2427 PORT_Assert(!ss->firstHsDone);
2427 PORT_Assert(type == content_handshake); 2428 PORT_Assert(type == content_handshake);
2428 PORT_Assert(ss->ssl3.hs.ws == wait_server_hello); 2429 PORT_Assert(ss->ssl3.hs.ws == wait_server_hello);
(...skipping 13 matching lines...) Expand all
2442 2443
2443 /* check for Token Presence */ 2444 /* check for Token Presence */
2444 if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) { 2445 if (!ssl3_ClientAuthTokenPresent(ss->sec.ci.sid)) {
2445 PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL); 2446 PORT_SetError(SSL_ERROR_TOKEN_INSERTION_REMOVAL);
2446 return SECFailure; 2447 return SECFailure;
2447 } 2448 }
2448 2449
2449 while (nIn > 0) { 2450 while (nIn > 0) {
2450 PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH); 2451 PRUint32 contentLen = PR_MIN(nIn, MAX_FRAGMENT_LENGTH);
2451 unsigned int spaceNeeded; 2452 unsigned int spaceNeeded;
2452 » unsigned int numRecords; 2453 » unsigned int numRecords = 1;
2453 2454
2454 ssl_GetSpecReadLock(ss); /********************************/ 2455 ssl_GetSpecReadLock(ss); /********************************/
2455 2456
2456 if (nIn > 1 && ss->opt.cbcRandomIV && 2457 if (nIn > 1 && ss->opt.cbcRandomIV &&
2457 ss->ssl3.cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_1 && 2458 ss->ssl3.cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_1 &&
2458 type == content_application_data && 2459 type == content_application_data &&
2459 ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) { 2460 ss->ssl3.cwSpec->cipher_def->type == type_block /* CBC mode */) {
2460 /* We will split the first byte of the record into its own record, 2461 /* We will split the first byte of the record into its own record,
2461 * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h 2462 * as explained in the documentation for SSL_CBC_RANDOM_IV in ssl.h
2462 */ 2463 */
2463 numRecords = 2; 2464 numRecords = 2;
2464 » } else { 2465 » }
2465 » numRecords = 1; 2466 » if (nIn > 1 && ss->opt.cbcRandomIV &&
agl 2013/03/15 12:35:21 Unlike the CBC case, we only need to split RC4 rec
wtc 2013/03/16 01:15:38 This code only splits the first RC4 application da
2467 » type == content_application_data &&
2468 » ss->ssl3.cwSpec->cipher_def->calg == ssl_calg_rc4) {
2469 » /* Adjust these parameters. */
2470 » enum {
2471 » » BIASED_RC4_BYTES = 256,
2472 » » MIN_RECORD_SIZE = 1 + MD5_LENGTH,
2473 » » MAX_SPLIT_RECORDS =
2474 » » (BIASED_RC4_BYTES + MIN_RECORD_SIZE - 1) / MIN_RECORD_SIZE
wtc 2013/03/15 03:58:18 Here I calculate a crude estimate of how many one-
agl 2013/03/15 12:35:21 A couple of ideas for tuning: Obviously the MAC m
wtc 2013/03/16 01:15:38 Done. With Google sites we also get NextProtocol a
2475 » };
2476
2477 » numRecords = PR_MIN(nIn, MAX_SPLIT_RECORDS);
2478 » /* Split only the first application data record.
2479 » * NOTE: turning off ss->opt.cbcRandomIV is a hack. We should
2480 » * add a new boolean field to |ss|.
2481 » */
2482 » ss->opt.cbcRandomIV = PR_FALSE;
2466 } 2483 }
2467 2484
2468 spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE); 2485 spaceNeeded = contentLen + (numRecords * SSL3_BUFFER_FUDGE);
2469 if (ss->ssl3.cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1 && 2486 if (ss->ssl3.cwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1 &&
2470 ss->ssl3.cwSpec->cipher_def->type == type_block) { 2487 ss->ssl3.cwSpec->cipher_def->type == type_block) {
2471 spaceNeeded += ss->ssl3.cwSpec->cipher_def->iv_size; 2488 spaceNeeded += ss->ssl3.cwSpec->cipher_def->iv_size;
2472 } 2489 }
2473 if (spaceNeeded > wrBuf->space) { 2490 if (spaceNeeded > wrBuf->space) {
2474 rv = sslBuffer_Grow(wrBuf, spaceNeeded); 2491 rv = sslBuffer_Grow(wrBuf, spaceNeeded);
2475 if (rv != SECSuccess) { 2492 if (rv != SECSuccess) {
2476 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes", 2493 SSL_DBG(("%d: SSL3[%d]: SendRecord, tried to get %d bytes",
2477 SSL_GETPID(), ss->fd, spaceNeeded)); 2494 SSL_GETPID(), ss->fd, spaceNeeded));
2478 goto spec_locked_loser; /* sslBuffer_Grow set error code. */ 2495 goto spec_locked_loser; /* sslBuffer_Grow set error code. */
2479 } 2496 }
2480 } 2497 }
2481 2498
2482 » if (numRecords == 2) { 2499 » if (numRecords > 1) {
2483 » sslBuffer secondRecord; 2500 » sslBuffer recordBuf;
2501 » unsigned int i;
2484 2502
2485 » rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, 2503 » for (i = 0; i < numRecords; i++) {
2486 » » » » » ss->sec.isServer, IS_DTLS(ss), 2504 » » recordBuf.buf = wrBuf->buf + wrBuf->len;
2487 » » » » » capRecordVersion, type, pIn, 2505 » » recordBuf.len = 0;
2488 » » » » » 1, wrBuf); 2506 » » recordBuf.space = wrBuf->space - wrBuf->len;
2489 » if (rv != SECSuccess)
2490 » goto spec_locked_loser;
2491 2507
2492 » PRINT_BUF(50, (ss, "send (encrypted) record data [1/2]:", 2508 » » rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
2493 » wrBuf->buf, wrBuf->len)); 2509 » » » » » » ss->sec.isServer,
2510 » » » » » » IS_DTLS(ss),
2511 » » » » » » capRecordVersion, type,
2512 » » » » » » pIn + i,
2513 » » » » » » (i != numRecords - 1) ?
2514 » » » » » » 1 : contentLen - i,
2515 » » » » » » &recordBuf);
2516 » » if (rv != SECSuccess)
2517 » » break;
2494 2518
2495 » secondRecord.buf = wrBuf->buf + wrBuf->len; 2519 » » PRINT_BUF(50, (ss, "send (encrypted) record data:",
2496 » secondRecord.len = 0; 2520 » » » recordBuf.buf, recordBuf.len));
2497 » secondRecord.space = wrBuf->space - wrBuf->len; 2521 » » wrBuf->len += recordBuf.len;
2498
2499 » rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
2500 » ss->sec.isServer, IS_DTLS(ss),
2501 » » » » » capRecordVersion, type,
2502 » » » » » pIn + 1, contentLen - 1,
2503 » &secondRecord);
2504 » if (rv == SECSuccess) {
2505 » PRINT_BUF(50, (ss, "send (encrypted) record data [2/2]:",
2506 » secondRecord.buf, secondRecord.len));
2507 » wrBuf->len += secondRecord.len;
2508 } 2522 }
wtc 2013/03/15 03:58:18 I generalized this code to be able to split the ap
2509 } else { 2523 } else {
2510 if (!IS_DTLS(ss)) { 2524 if (!IS_DTLS(ss)) {
2511 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec, 2525 rv = ssl3_CompressMACEncryptRecord(ss->ssl3.cwSpec,
2512 ss->sec.isServer, 2526 ss->sec.isServer,
2513 IS_DTLS(ss), 2527 IS_DTLS(ss),
2514 capRecordVersion, 2528 capRecordVersion,
2515 type, pIn, 2529 type, pIn,
2516 contentLen, wrBuf); 2530 contentLen, wrBuf);
2517 } else { 2531 } else {
2518 rv = dtls_CompressMACEncryptRecord(ss, epoch, 2532 rv = dtls_CompressMACEncryptRecord(ss, epoch,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2584 return SECFailure; 2598 return SECFailure;
2585 } 2599 }
2586 /* now take all the remaining unsent new ciphertext and 2600 /* now take all the remaining unsent new ciphertext and
2587 * append it to the buffer of previously unsent ciphertext. 2601 * append it to the buffer of previously unsent ciphertext.
2588 */ 2602 */
2589 rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len); 2603 rv = ssl_SaveWriteData(ss, wrBuf->buf + sent, wrBuf->len);
2590 if (rv != SECSuccess) { 2604 if (rv != SECSuccess) {
2591 /* presumably a memory error, SEC_ERROR_NO_MEMORY */ 2605 /* presumably a memory error, SEC_ERROR_NO_MEMORY */
2592 return SECFailure; 2606 return SECFailure;
2593 } 2607 }
2608 wrBuf->len = 0; /* All cipher text is saved away. */
2594 } 2609 }
2595 } 2610 }
2596 totalSent += contentLen; 2611 totalSent += contentLen;
2597 } 2612 }
2598 return totalSent; 2613 return totalSent;
2599 } 2614 }
2600 2615
2601 #define SSL3_PENDING_HIGH_WATER 1024 2616 #define SSL3_PENDING_HIGH_WATER 1024
2602 2617
2603 /* Attempt to send the content of "in" in an SSL application_data record. 2618 /* Attempt to send the content of "in" in an SSL application_data record.
(...skipping 10 matching lines...) Expand all
2614 /* These flags for internal use only */ 2629 /* These flags for internal use only */
2615 PORT_Assert(!(flags & (ssl_SEND_FLAG_USE_EPOCH | 2630 PORT_Assert(!(flags & (ssl_SEND_FLAG_USE_EPOCH |
2616 ssl_SEND_FLAG_NO_RETRANSMIT))); 2631 ssl_SEND_FLAG_NO_RETRANSMIT)));
2617 if (len < 0 || !in) { 2632 if (len < 0 || !in) {
2618 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 2633 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
2619 return SECFailure; 2634 return SECFailure;
2620 } 2635 }
2621 2636
2622 if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER && 2637 if (ss->pendingBuf.len > SSL3_PENDING_HIGH_WATER &&
2623 !ssl_SocketIsBlocking(ss)) { 2638 !ssl_SocketIsBlocking(ss)) {
2624 PORT_Assert(!ssl_SocketIsBlocking(ss));
2625 PORT_SetError(PR_WOULD_BLOCK_ERROR); 2639 PORT_SetError(PR_WOULD_BLOCK_ERROR);
2626 return SECFailure; 2640 return SECFailure;
2627 } 2641 }
2628 2642
2629 if (ss->appDataBuffered && len) { 2643 if (ss->appDataBuffered && len) {
2630 PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered)); 2644 PORT_Assert (in[0] == (unsigned char)(ss->appDataBuffered));
2631 if (in[0] != (unsigned char)(ss->appDataBuffered)) { 2645 if (in[0] != (unsigned char)(ss->appDataBuffered)) {
2632 PORT_SetError(PR_INVALID_ARGUMENT_ERROR); 2646 PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
2633 return SECFailure; 2647 return SECFailure;
2634 } 2648 }
(...skipping 8631 matching lines...) Expand 10 before | Expand all | Expand 10 after
11266 PORT_Free(ss->ssl3.hs.recvdFragments.buf); 11280 PORT_Free(ss->ssl3.hs.recvdFragments.buf);
11267 } 11281 }
11268 } 11282 }
11269 11283
11270 ss->ssl3.initialized = PR_FALSE; 11284 ss->ssl3.initialized = PR_FALSE;
11271 11285
11272 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); 11286 SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE);
11273 } 11287 }
11274 11288
11275 /* End of ssl3con.c */ 11289 /* End of ssl3con.c */
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698