aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-20 17:59:25 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-20 18:04:04 +0100
commite7863f394e6a963d1e2c6af77ea064442d3ef594 (patch)
treeee638eb584ad34fdc16219dde8f476cc81bcdadb
parent6e511393f90a30c93c445c3d1ed6090e79e7384b (diff)
downloadbusybox-w32-e7863f394e6a963d1e2c6af77ea064442d3ef594.tar.gz
busybox-w32-e7863f394e6a963d1e2c6af77ea064442d3ef594.tar.bz2
busybox-w32-e7863f394e6a963d1e2c6af77ea064442d3ef594.zip
tls: was psAesDecrypt'ing one block too many, trashing buffered data
For the first time printf "GET / HTTP/1.1\r\nHost: kernel.org\r\n\r\n" | ./busybox tls kernel.org successfully reads entire server response and TLS shutdown. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/tls.c136
1 files changed, 73 insertions, 63 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 2674997ff..cdce1004e 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -26,7 +26,7 @@
26//#include "common_bufsiz.h" 26//#include "common_bufsiz.h"
27 27
28#define TLS_DEBUG 1 28#define TLS_DEBUG 1
29#define TLS_DEBUG_HASH 1 29#define TLS_DEBUG_HASH 0
30#define TLS_DEBUG_DER 0 30#define TLS_DEBUG_DER 0
31#define TLS_DEBUG_FIXED_SECRETS 0 31#define TLS_DEBUG_FIXED_SECRETS 0
32 32
@@ -42,6 +42,18 @@
42# define dbg_der(...) ((void)0) 42# define dbg_der(...) ((void)0)
43#endif 43#endif
44 44
45#if 0
46# define dump_raw_out(...) dump_hex(__VA_ARGS__)
47#else
48# define dump_raw_out(...) ((void)0)
49#endif
50
51#if 1
52# define dump_raw_in(...) dump_hex(__VA_ARGS__)
53#else
54# define dump_raw_in(...) ((void)0)
55#endif
56
45#define RECORD_TYPE_CHANGE_CIPHER_SPEC 20 57#define RECORD_TYPE_CHANGE_CIPHER_SPEC 20
46#define RECORD_TYPE_ALERT 21 58#define RECORD_TYPE_ALERT 21
47#define RECORD_TYPE_HANDSHAKE 22 59#define RECORD_TYPE_HANDSHAKE 22
@@ -482,49 +494,11 @@ static void *tls_get_outbuf(tls_state_t *tls, int len)
482 return tls->outbuf + OUTBUF_PFX; 494 return tls->outbuf + OUTBUF_PFX;
483} 495}
484 496
485// RFC 5246
486// 6.2.3.1. Null or Standard Stream Cipher
487//
488// Stream ciphers (including BulkCipherAlgorithm.null; see Appendix A.6)
489// convert TLSCompressed.fragment structures to and from stream
490// TLSCiphertext.fragment structures.
491//
492// stream-ciphered struct {
493// opaque content[TLSCompressed.length];
494// opaque MAC[SecurityParameters.mac_length];
495// } GenericStreamCipher;
496//
497// The MAC is generated as:
498// MAC(MAC_write_key, seq_num +
499// TLSCompressed.type +
500// TLSCompressed.version +
501// TLSCompressed.length +
502// TLSCompressed.fragment);
503// where "+" denotes concatenation.
504// seq_num
505// The sequence number for this record.
506// MAC
507// The MAC algorithm specified by SecurityParameters.mac_algorithm.
508//
509// Note that the MAC is computed before encryption. The stream cipher
510// encrypts the entire block, including the MAC.
511//...
512// Appendix C. Cipher Suite Definitions
513//...
514// Key IV Block
515// Cipher Type Material Size Size
516// ------------ ------ -------- ---- -----
517// AES_128_CBC Block 16 16 16
518// AES_256_CBC Block 32 16 16
519//
520// MAC Algorithm mac_length mac_key_length
521// -------- ----------- ---------- --------------
522// SHA HMAC-SHA1 20 20
523// SHA256 HMAC-SHA256 32 32
524static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) 497static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
525{ 498{
526 uint8_t *buf = tls->outbuf + OUTBUF_PFX; 499 uint8_t *buf = tls->outbuf + OUTBUF_PFX;
527 struct record_hdr *xhdr; 500 struct record_hdr *xhdr;
501 uint8_t padding_length;
528 502
529 xhdr = (void*)(buf - RECHDR_LEN); 503 xhdr = (void*)(buf - RECHDR_LEN);
530 if (CIPHER_ID != TLS_RSA_WITH_NULL_SHA256) 504 if (CIPHER_ID != TLS_RSA_WITH_NULL_SHA256)
@@ -549,17 +523,49 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
549 523
550 size += SHA256_OUTSIZE; 524 size += SHA256_OUTSIZE;
551 525
526 // RFC 5246
527 // 6.2.3.1. Null or Standard Stream Cipher
528 //
529 // Stream ciphers (including BulkCipherAlgorithm.null; see Appendix A.6)
530 // convert TLSCompressed.fragment structures to and from stream
531 // TLSCiphertext.fragment structures.
532 //
533 // stream-ciphered struct {
534 // opaque content[TLSCompressed.length];
535 // opaque MAC[SecurityParameters.mac_length];
536 // } GenericStreamCipher;
537 //
538 // The MAC is generated as:
539 // MAC(MAC_write_key, seq_num +
540 // TLSCompressed.type +
541 // TLSCompressed.version +
542 // TLSCompressed.length +
543 // TLSCompressed.fragment);
544 // where "+" denotes concatenation.
545 // seq_num
546 // The sequence number for this record.
547 // MAC
548 // The MAC algorithm specified by SecurityParameters.mac_algorithm.
549 //
550 // Note that the MAC is computed before encryption. The stream cipher
551 // encrypts the entire block, including the MAC.
552 //...
553 // Appendix C. Cipher Suite Definitions
554 //...
555 // MAC Algorithm mac_length mac_key_length
556 // -------- ----------- ---------- --------------
557 // SHA HMAC-SHA1 20 20
558 // SHA256 HMAC-SHA256 32 32
552 if (CIPHER_ID == TLS_RSA_WITH_NULL_SHA256) { 559 if (CIPHER_ID == TLS_RSA_WITH_NULL_SHA256) {
553 /* No encryption, only signing */ 560 /* No encryption, only signing */
554 xhdr->len16_hi = size >> 8; 561 xhdr->len16_hi = size >> 8;
555 xhdr->len16_lo = size & 0xff; 562 xhdr->len16_lo = size & 0xff;
556 dump_hex(">> %s\n", xhdr, RECHDR_LEN + size); 563 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size);
557 xwrite(tls->fd, xhdr, RECHDR_LEN + size); 564 xwrite(tls->fd, xhdr, RECHDR_LEN + size);
558 dbg("wrote %u bytes (NULL crypt, SHA256 hash)\n", size); 565 dbg("wrote %u bytes (NULL crypt, SHA256 hash)\n", size);
559 return; 566 return;
560 } 567 }
561 568
562 // RFC 5246
563 // 6.2.3.2. CBC Block Cipher 569 // 6.2.3.2. CBC Block Cipher
564 // For block ciphers (such as 3DES or AES), the encryption and MAC 570 // For block ciphers (such as 3DES or AES), the encryption and MAC
565 // functions convert TLSCompressed.fragment structures to and from block 571 // functions convert TLSCompressed.fragment structures to and from block
@@ -595,10 +601,6 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
595 // ------------ ------ -------- ---- ----- 601 // ------------ ------ -------- ---- -----
596 // AES_128_CBC Block 16 16 16 602 // AES_128_CBC Block 16 16 16
597 // AES_256_CBC Block 32 16 16 603 // AES_256_CBC Block 32 16 16
598 {
599 psCipherContext_t ctx;
600 uint8_t *p;
601 uint8_t padding_length;
602 604
603 /* Build IV+content+MAC+padding in outbuf */ 605 /* Build IV+content+MAC+padding in outbuf */
604 tls_get_random(buf - AES_BLOCKSIZE, AES_BLOCKSIZE); /* IV */ 606 tls_get_random(buf - AES_BLOCKSIZE, AES_BLOCKSIZE); /* IV */
@@ -618,22 +620,23 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
618 // If you need no bytes to reach BLOCKSIZE, you have to pad a full 620 // If you need no bytes to reach BLOCKSIZE, you have to pad a full
619 // BLOCKSIZE with bytes of value (BLOCKSIZE-1). 621 // BLOCKSIZE with bytes of value (BLOCKSIZE-1).
620 // It's ok to have more than minimum padding, but we do minimum. 622 // It's ok to have more than minimum padding, but we do minimum.
621 p = buf + size;
622 padding_length = (~size) & (AES_BLOCKSIZE - 1); 623 padding_length = (~size) & (AES_BLOCKSIZE - 1);
623 do { 624 do {
624 *p++ = padding_length; /* padding */ 625 buf[size++] = padding_length; /* padding */
625 size++;
626 } while ((size & (AES_BLOCKSIZE - 1)) != 0); 626 } while ((size & (AES_BLOCKSIZE - 1)) != 0);
627 627
628 /* Encrypt content+MAC+padding in place */ 628 /* Encrypt content+MAC+padding in place */
629 psAesInit(&ctx, buf - AES_BLOCKSIZE, /* IV */ 629 {
630 psCipherContext_t ctx;
631 psAesInit(&ctx, buf - AES_BLOCKSIZE, /* IV */
630 tls->client_write_key, sizeof(tls->client_write_key) 632 tls->client_write_key, sizeof(tls->client_write_key)
631 ); 633 );
632 psAesEncrypt(&ctx, 634 psAesEncrypt(&ctx,
633 buf, /* plaintext */ 635 buf, /* plaintext */
634 buf, /* ciphertext */ 636 buf, /* ciphertext */
635 size 637 size
636 ); 638 );
639 }
637 640
638 /* Write out */ 641 /* Write out */
639 dbg("writing 5 + %u IV + %u encrypted bytes, padding_length:0x%02x\n", 642 dbg("writing 5 + %u IV + %u encrypted bytes, padding_length:0x%02x\n",
@@ -641,10 +644,9 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
641 size += AES_BLOCKSIZE; /* + IV */ 644 size += AES_BLOCKSIZE; /* + IV */
642 xhdr->len16_hi = size >> 8; 645 xhdr->len16_hi = size >> 8;
643 xhdr->len16_lo = size & 0xff; 646 xhdr->len16_lo = size & 0xff;
644 dump_hex(">> %s\n", xhdr, RECHDR_LEN + size); 647 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size);
645 xwrite(tls->fd, xhdr, RECHDR_LEN + size); 648 xwrite(tls->fd, xhdr, RECHDR_LEN + size);
646 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); 649 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size);
647 }
648} 650}
649 651
650static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size) 652static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size)
@@ -658,7 +660,7 @@ static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size)
658 xhdr->proto_min = TLS_MIN; 660 xhdr->proto_min = TLS_MIN;
659 xhdr->len16_hi = size >> 8; 661 xhdr->len16_hi = size >> 8;
660 xhdr->len16_lo = size & 0xff; 662 xhdr->len16_lo = size & 0xff;
661 dump_hex(">> %s\n", xhdr, RECHDR_LEN + size); 663 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size);
662 xwrite(tls->fd, xhdr, RECHDR_LEN + size); 664 xwrite(tls->fd, xhdr, RECHDR_LEN + size);
663 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); 665 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size);
664 /* Handshake hash does not include record headers */ 666 /* Handshake hash does not include record headers */
@@ -677,10 +679,13 @@ static int xread_tls_block(tls_state_t *tls)
677 679
678 again: 680 again:
679 dbg("insize:%u tail:%u\n", tls->insize, tls->tail); 681 dbg("insize:%u tail:%u\n", tls->insize, tls->tail);
680 if (tls->tail != 0)
681 memmove(tls->inbuf, tls->inbuf + tls->insize, tls->tail);
682 errno = 0;
683 total = tls->tail; 682 total = tls->tail;
683 if (total != 0) {
684 memmove(tls->inbuf, tls->inbuf + tls->insize, total);
685 //dbg("<< remaining at %d [%d] ", tls->insize, total);
686 //dump_raw_in("<< %s\n", tls->inbuf, total);
687 }
688 errno = 0;
684 target = sizeof(tls->inbuf); 689 target = sizeof(tls->inbuf);
685 for (;;) { 690 for (;;) {
686 if (total >= RECHDR_LEN && target == sizeof(tls->inbuf)) { 691 if (total >= RECHDR_LEN && target == sizeof(tls->inbuf)) {
@@ -692,7 +697,11 @@ static int xread_tls_block(tls_state_t *tls)
692 tls->insize = total; 697 tls->insize = total;
693 tls_error_die(tls); 698 tls_error_die(tls);
694 } 699 }
695 // can also check type/proto_maj/proto_min here 700 /* can also check type/proto_maj/proto_min here */
701 dbg("xhdr type:%d ver:%d.%d len:%d\n",
702 xhdr->type, xhdr->proto_maj, xhdr->proto_min,
703 0x100 * xhdr->len16_hi + xhdr->len16_lo
704 );
696 } 705 }
697 /* if total >= target, we have a full packet (and possibly more)... */ 706 /* if total >= target, we have a full packet (and possibly more)... */
698 if (total - target >= 0) 707 if (total - target >= 0)
@@ -707,12 +716,13 @@ static int xread_tls_block(tls_state_t *tls)
707 } 716 }
708 bb_perror_msg_and_die("short read, have only %d", total); 717 bb_perror_msg_and_die("short read, have only %d", total);
709 } 718 }
710 dbg("read():%d\n", sz); 719 dump_raw_in("<< %s\n", tls->inbuf + total, sz);
711 total += sz; 720 total += sz;
712 } 721 }
713 tls->tail = total - target; 722 tls->tail = total - target;
714 tls->insize = target; 723 tls->insize = target;
715 dbg("new insize:%u tail:%u\n", tls->insize, tls->tail); 724 //dbg("<< stashing at %d [%d] ", tls->insize, tls->tail);
725 //dump_hex("<< %s\n", tls->inbuf + tls->insize, tls->tail);
716 726
717 sz = target - RECHDR_LEN; 727 sz = target - RECHDR_LEN;
718 728
@@ -734,7 +744,7 @@ static int xread_tls_block(tls_state_t *tls)
734 psAesDecrypt(&ctx, 744 psAesDecrypt(&ctx,
735 p + AES_BLOCKSIZE, /* ciphertext */ 745 p + AES_BLOCKSIZE, /* ciphertext */
736 p + AES_BLOCKSIZE, /* plaintext */ 746 p + AES_BLOCKSIZE, /* plaintext */
737 sz 747 sz - AES_BLOCKSIZE
738 ); 748 );
739 padding_len = p[sz - 1]; 749 padding_len = p[sz - 1];
740 dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[AES_BLOCKSIZE], padding_len); 750 dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[AES_BLOCKSIZE], padding_len);