diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-20 21:19:38 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-20 21:19:38 +0100 |
commit | 54b927d78bfdac54873513fb1dd992a7758d29c8 (patch) | |
tree | 52301746fefc809f05a76479d2d310fe2d15e402 | |
parent | 3916139ac4b9f60d7b958e5b2d88a277753dcc74 (diff) | |
download | busybox-w32-54b927d78bfdac54873513fb1dd992a7758d29c8.tar.gz busybox-w32-54b927d78bfdac54873513fb1dd992a7758d29c8.tar.bz2 busybox-w32-54b927d78bfdac54873513fb1dd992a7758d29c8.zip |
tls: AES decrypt does one unnecessary memmove
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/tls.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/networking/tls.c b/networking/tls.c index 55ad2d83f..fb49b1523 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -539,7 +539,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
539 | xhdr->type = type; | 539 | xhdr->type = type; |
540 | xhdr->proto_maj = TLS_MAJ; | 540 | xhdr->proto_maj = TLS_MAJ; |
541 | xhdr->proto_min = TLS_MIN; | 541 | xhdr->proto_min = TLS_MIN; |
542 | /* fake unencrypted record header len for MAC calculation */ | 542 | /* fake unencrypted record len for MAC calculation */ |
543 | xhdr->len16_hi = size >> 8; | 543 | xhdr->len16_hi = size >> 8; |
544 | xhdr->len16_lo = size & 0xff; | 544 | xhdr->len16_lo = size & 0xff; |
545 | 545 | ||
@@ -634,7 +634,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
634 | // AES_128_CBC Block 16 16 16 | 634 | // AES_128_CBC Block 16 16 16 |
635 | // AES_256_CBC Block 32 16 16 | 635 | // AES_256_CBC Block 32 16 16 |
636 | 636 | ||
637 | /* Build IV+content+MAC+padding in outbuf */ | 637 | /* Fill IV and padding in outbuf */ |
638 | tls_get_random(buf - AES_BLOCKSIZE, AES_BLOCKSIZE); /* IV */ | 638 | tls_get_random(buf - AES_BLOCKSIZE, AES_BLOCKSIZE); /* IV */ |
639 | dbg("before crypt: 5 hdr + %u data + %u hash bytes\n", size, SHA256_OUTSIZE); | 639 | dbg("before crypt: 5 hdr + %u data + %u hash bytes\n", size, SHA256_OUTSIZE); |
640 | // RFC is talking nonsense: | 640 | // RFC is talking nonsense: |
@@ -654,7 +654,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
654 | // It's ok to have more than minimum padding, but we do minimum. | 654 | // It's ok to have more than minimum padding, but we do minimum. |
655 | padding_length = (~size) & (AES_BLOCKSIZE - 1); | 655 | padding_length = (~size) & (AES_BLOCKSIZE - 1); |
656 | do { | 656 | do { |
657 | buf[size++] = padding_length; /* padding */ | 657 | buf[size++] = padding_length; /* padding */ |
658 | } while ((size & (AES_BLOCKSIZE - 1)) != 0); | 658 | } while ((size & (AES_BLOCKSIZE - 1)) != 0); |
659 | 659 | ||
660 | /* Encrypt content+MAC+padding in place */ | 660 | /* Encrypt content+MAC+padding in place */ |
@@ -796,26 +796,23 @@ static int tls_xread_record(tls_state_t *tls) | |||
796 | ) { | 796 | ) { |
797 | bb_error_msg_and_die("bad encrypted len:%u", sz); | 797 | bb_error_msg_and_die("bad encrypted len:%u", sz); |
798 | } | 798 | } |
799 | /* Decrypt content+MAC+padding in place */ | 799 | /* Decrypt content+MAC+padding, moving it over IV in the process */ |
800 | psAesInit(&ctx, p, /* IV */ | 800 | psAesInit(&ctx, p, /* IV */ |
801 | tls->server_write_key, sizeof(tls->server_write_key) | 801 | tls->server_write_key, sizeof(tls->server_write_key) |
802 | ); | 802 | ); |
803 | sz -= AES_BLOCKSIZE; /* we will overwrite IV now */ | ||
803 | psAesDecrypt(&ctx, | 804 | psAesDecrypt(&ctx, |
804 | p + AES_BLOCKSIZE, /* ciphertext */ | 805 | p + AES_BLOCKSIZE, /* ciphertext */ |
805 | p + AES_BLOCKSIZE, /* plaintext */ | 806 | p, /* plaintext */ |
806 | sz - AES_BLOCKSIZE | 807 | sz |
807 | ); | 808 | ); |
808 | padding_len = p[sz - 1]; | 809 | padding_len = p[sz - 1]; |
809 | dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[AES_BLOCKSIZE], padding_len); | 810 | dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[0], padding_len); |
810 | padding_len++; | 811 | padding_len++; |
811 | sz -= AES_BLOCKSIZE + SHA256_OUTSIZE + padding_len; | 812 | sz -= SHA256_OUTSIZE + padding_len; /* drop MAC and padding */ |
812 | if (sz < 0) { | 813 | if (sz < 0) { |
813 | bb_error_msg_and_die("bad padding size:%u", padding_len); | 814 | bb_error_msg_and_die("bad padding size:%u", padding_len); |
814 | } | 815 | } |
815 | if (sz != 0) { | ||
816 | /* Skip IV */ | ||
817 | memmove(tls->inbuf + RECHDR_LEN, tls->inbuf + RECHDR_LEN + AES_BLOCKSIZE, sz); | ||
818 | } | ||
819 | } else { | 816 | } else { |
820 | /* if nonzero, then it's TLS_RSA_WITH_NULL_SHA256: drop MAC */ | 817 | /* if nonzero, then it's TLS_RSA_WITH_NULL_SHA256: drop MAC */ |
821 | /* else: no encryption yet on input, subtract zero = NOP */ | 818 | /* else: no encryption yet on input, subtract zero = NOP */ |
@@ -828,8 +825,8 @@ static int tls_xread_record(tls_state_t *tls) | |||
828 | if (xhdr->type == RECORD_TYPE_ALERT && sz >= 2) { | 825 | if (xhdr->type == RECORD_TYPE_ALERT && sz >= 2) { |
829 | uint8_t *p = tls->inbuf + RECHDR_LEN; | 826 | uint8_t *p = tls->inbuf + RECHDR_LEN; |
830 | dbg("ALERT size:%d level:%d description:%d\n", sz, p[0], p[1]); | 827 | dbg("ALERT size:%d level:%d description:%d\n", sz, p[0], p[1]); |
831 | if (p[0] == 1) { /*warning */ | 828 | if (p[0] == 1) { /* warning */ |
832 | if (p[1] == 0) { /* warning, close_notify: EOF */ | 829 | if (p[1] == 0) { /* "close_notify" warning: it's EOF */ |
833 | dbg("EOF (TLS encoded) from peer\n"); | 830 | dbg("EOF (TLS encoded) from peer\n"); |
834 | sz = 0; | 831 | sz = 0; |
835 | goto end; | 832 | goto end; |