aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-11-23 17:21:38 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-11-23 17:48:07 +0100
commit83e5c627e1b2c7f34d694696d0c3d5a3ce25dc59 (patch)
tree3bdffe7c29ee5213ba4278da9b0ee116c2806d78
parent03ad7ae08189ed88dd7e0fcb6c6001fbf3b12efb (diff)
downloadbusybox-w32-83e5c627e1b2c7f34d694696d0c3d5a3ce25dc59.tar.gz
busybox-w32-83e5c627e1b2c7f34d694696d0c3d5a3ce25dc59.tar.bz2
busybox-w32-83e5c627e1b2c7f34d694696d0c3d5a3ce25dc59.zip
tls: add support for TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 cipher
function old new delta xwrite_encrypted 209 605 +396 GHASH - 395 +395 aes_encrypt_1 - 382 +382 GMULT - 192 +192 tls_xread_record 489 659 +170 aes_encrypt_one_block - 65 +65 aesgcm_setkey - 58 +58 FlattenSzInBits - 52 +52 tls_handshake 1890 1941 +51 xwrite_and_update_handshake_hash 46 81 +35 xorbuf - 24 +24 aes_setkey - 16 +16 psRsaEncryptPub 413 421 +8 stty_main 1221 1227 +6 ssl_client_main 138 143 +5 next_token 841 845 +4 spawn_ssl_client 218 219 +1 volume_id_probe_hfs_hfsplus 564 563 -1 read_package_field 232 230 -2 i2cdetect_main 674 672 -2 fail_hunk 139 136 -3 parse_expr 891 883 -8 curve25519 802 793 -9 aes_cbc_decrypt 971 958 -13 xwrite_handshake_record 43 - -43 aes_cbc_encrypt 644 172 -472 ------------------------------------------------------------------------------ (add/remove: 9/1 grow/shrink: 9/8 up/down: 1860/-553) Total: 1307 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--include/libbb.h17
-rw-r--r--networking/tls.c360
-rw-r--r--networking/tls.h3
-rw-r--r--networking/tls_aes.c15
-rw-r--r--networking/tls_aes.h8
-rw-r--r--networking/tls_aesgcm.c148
-rw-r--r--networking/tls_aesgcm.h15
-rw-r--r--networking/tls_fe.c2
-rw-r--r--networking/tls_fe.h2
-rw-r--r--networking/tls_rsa.c2
-rw-r--r--networking/tls_rsa.h2
11 files changed, 480 insertions, 94 deletions
diff --git a/include/libbb.h b/include/libbb.h
index aa9e9d019..b041ce047 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -736,10 +736,17 @@ struct hostent *xgethostbyname(const char *name) FAST_FUNC;
736// + inet_common.c has additional IPv4-only stuff 736// + inet_common.c has additional IPv4-only stuff
737 737
738 738
739struct tls_aes {
740 uint32_t key[60];
741 unsigned rounds;
742};
739#define TLS_MAX_MAC_SIZE 32 743#define TLS_MAX_MAC_SIZE 32
740#define TLS_MAX_KEY_SIZE 32 744#define TLS_MAX_KEY_SIZE 32
745#define TLS_MAX_IV_SIZE 4
741struct tls_handshake_data; /* opaque */ 746struct tls_handshake_data; /* opaque */
742typedef struct tls_state { 747typedef struct tls_state {
748 unsigned flags;
749
743 int ofd; 750 int ofd;
744 int ifd; 751 int ifd;
745 752
@@ -748,6 +755,7 @@ typedef struct tls_state {
748 uint8_t encrypt_on_write; 755 uint8_t encrypt_on_write;
749 unsigned MAC_size; 756 unsigned MAC_size;
750 unsigned key_size; 757 unsigned key_size;
758 unsigned IV_size;
751 759
752 uint8_t *outbuf; 760 uint8_t *outbuf;
753 int outbuf_size; 761 int outbuf_size;
@@ -769,12 +777,21 @@ typedef struct tls_state {
769 /*uint64_t read_seq64_be;*/ 777 /*uint64_t read_seq64_be;*/
770 uint64_t write_seq64_be; 778 uint64_t write_seq64_be;
771 779
780 /*uint8_t *server_write_MAC_key;*/
772 uint8_t *client_write_key; 781 uint8_t *client_write_key;
773 uint8_t *server_write_key; 782 uint8_t *server_write_key;
783 uint8_t *client_write_IV;
784 uint8_t *server_write_IV;
774 uint8_t client_write_MAC_key[TLS_MAX_MAC_SIZE]; 785 uint8_t client_write_MAC_key[TLS_MAX_MAC_SIZE];
775 uint8_t server_write_MAC_k__[TLS_MAX_MAC_SIZE]; 786 uint8_t server_write_MAC_k__[TLS_MAX_MAC_SIZE];
776 uint8_t client_write_k__[TLS_MAX_KEY_SIZE]; 787 uint8_t client_write_k__[TLS_MAX_KEY_SIZE];
777 uint8_t server_write_k__[TLS_MAX_KEY_SIZE]; 788 uint8_t server_write_k__[TLS_MAX_KEY_SIZE];
789 uint8_t client_write_I_[TLS_MAX_IV_SIZE];
790 uint8_t server_write_I_[TLS_MAX_IV_SIZE];
791
792 struct tls_aes aes_encrypt;
793 struct tls_aes aes_decrypt;
794 uint8_t H[16]; //used by AES_GCM
778} tls_state_t; 795} tls_state_t;
779 796
780static inline tls_state_t *new_tls_state(void) 797static inline tls_state_t *new_tls_state(void)
diff --git a/networking/tls.c b/networking/tls.c
index fba66f6f0..38a965ad6 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -13,16 +13,17 @@
13//kbuild:lib-$(CONFIG_TLS) += tls_pstm_mul_comba.o 13//kbuild:lib-$(CONFIG_TLS) += tls_pstm_mul_comba.o
14//kbuild:lib-$(CONFIG_TLS) += tls_pstm_sqr_comba.o 14//kbuild:lib-$(CONFIG_TLS) += tls_pstm_sqr_comba.o
15//kbuild:lib-$(CONFIG_TLS) += tls_aes.o 15//kbuild:lib-$(CONFIG_TLS) += tls_aes.o
16//kbuild:lib-$(CONFIG_TLS) += tls_aesgcm.o
16//kbuild:lib-$(CONFIG_TLS) += tls_rsa.o 17//kbuild:lib-$(CONFIG_TLS) += tls_rsa.o
17//kbuild:lib-$(CONFIG_TLS) += tls_fe.o 18//kbuild:lib-$(CONFIG_TLS) += tls_fe.o
18////kbuild:lib-$(CONFIG_TLS) += tls_aes_gcm.o
19 19
20#include "tls.h" 20#include "tls.h"
21 21
22//Tested against kernel.org:
23//TLS 1.2 22//TLS 1.2
24#define TLS_MAJ 3 23#define TLS_MAJ 3
25#define TLS_MIN 3 24#define TLS_MIN 3
25
26//Tested against kernel.org:
26//#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA // ok, recvs SERVER_KEY_EXCHANGE *** matrixssl uses this on my box 27//#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA // ok, recvs SERVER_KEY_EXCHANGE *** matrixssl uses this on my box
27//#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE 28//#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE
28//#define CIPHER_ID TLS_DH_anon_WITH_AES_256_CBC_SHA // SSL_ALERT_HANDSHAKE_FAILURE 29//#define CIPHER_ID TLS_DH_anon_WITH_AES_256_CBC_SHA // SSL_ALERT_HANDSHAKE_FAILURE
@@ -36,7 +37,7 @@
36//#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 37//#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
37//#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE 38//#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE
38//#define CIPHER_ID TLS_RSA_WITH_AES_256_GCM_SHA384 // ok, no SERVER_KEY_EXCHANGE 39//#define CIPHER_ID TLS_RSA_WITH_AES_256_GCM_SHA384 // ok, no SERVER_KEY_EXCHANGE
39//#define CIPHER_ID TLS_RSA_WITH_AES_128_GCM_SHA256 // ok, no SERVER_KEY_EXCHANGE *** select this? 40//#define CIPHER_ID TLS_RSA_WITH_AES_128_GCM_SHA256 // ok, no SERVER_KEY_EXCHANGE
40 41
41// works against "openssl s_server -cipher NULL" 42// works against "openssl s_server -cipher NULL"
42// and against wolfssl-3.9.10-stable/examples/server/server.c: 43// and against wolfssl-3.9.10-stable/examples/server/server.c:
@@ -60,6 +61,11 @@
60// bug #11456: host is.gd accepts only ECDHE-ECDSA-foo (the simplest which works: ECDHE-ECDSA-AES128-SHA 0xC009) 61// bug #11456: host is.gd accepts only ECDHE-ECDSA-foo (the simplest which works: ECDHE-ECDSA-AES128-SHA 0xC009)
61#define CIPHER_ID3 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 62#define CIPHER_ID3 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
62 63
64// ftp.openbsd.org only supports ECDHE-RSA-AESnnn-GCM-SHAnnn or ECDHE-RSA-CHACHA20-POLY1305
65#define CIPHER_ID4 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
66
67#define NUM_CIPHERS 4
68
63 69
64#define TLS_DEBUG 0 70#define TLS_DEBUG 0
65#define TLS_DEBUG_HASH 0 71#define TLS_DEBUG_HASH 0
@@ -207,7 +213,6 @@ enum {
207 SHA1_OUTSIZE = 20, 213 SHA1_OUTSIZE = 20,
208 SHA256_OUTSIZE = 32, 214 SHA256_OUTSIZE = 32,
209 215
210 AES_BLOCKSIZE = 16,
211 AES128_KEYSIZE = 16, 216 AES128_KEYSIZE = 16,
212 AES256_KEYSIZE = 32, 217 AES256_KEYSIZE = 32,
213 218
@@ -216,7 +221,7 @@ enum {
216 RECHDR_LEN = 5, 221 RECHDR_LEN = 5,
217 222
218 /* 8 = 3+5. 3 extra bytes result in record data being 32-bit aligned */ 223 /* 8 = 3+5. 3 extra bytes result in record data being 32-bit aligned */
219 OUTBUF_PFX = 8 + AES_BLOCKSIZE, /* header + IV */ 224 OUTBUF_PFX = 8 + AES_BLOCK_SIZE, /* header + IV */
220 OUTBUF_SFX = TLS_MAX_MAC_SIZE + TLS_MAX_CRYPTBLOCK_SIZE, /* MAC + padding */ 225 OUTBUF_SFX = TLS_MAX_MAC_SIZE + TLS_MAX_CRYPTBLOCK_SIZE, /* MAC + padding */
221 226
222 // RFC 5246 227 // RFC 5246
@@ -263,8 +268,11 @@ struct record_hdr {
263}; 268};
264 269
265enum { 270enum {
266 KEY_ALG_RSA, 271 NEED_EC_KEY = 1 << 0,
267 KEY_ALG_ECDSA, 272 GOT_CERT_RSA_KEY_ALG = 1 << 1,
273 GOT_CERT_ECDSA_KEY_ALG = 1 << 2,
274 GOT_EC_KEY = 1 << 3,
275 ENCRYPTION_AESGCM = 1 << 4,
268}; 276};
269struct tls_handshake_data { 277struct tls_handshake_data {
270 /* In bbox, md5/sha1/sha256 ctx's are the same structure */ 278 /* In bbox, md5/sha1/sha256 ctx's are the same structure */
@@ -273,14 +281,14 @@ struct tls_handshake_data {
273 uint8_t client_and_server_rand32[2 * 32]; 281 uint8_t client_and_server_rand32[2 * 32];
274 uint8_t master_secret[48]; 282 uint8_t master_secret[48];
275 283
276 smallint key_alg;
277//TODO: store just the DER key here, parse/use/delete it when sending client key 284//TODO: store just the DER key here, parse/use/delete it when sending client key
278//this way it will stay key type agnostic here. 285//this way it will stay key type agnostic here.
279 psRsaKey_t server_rsa_pub_key; 286 psRsaKey_t server_rsa_pub_key;
280 uint8_t ecc_pub_key32[32]; 287 uint8_t ecc_pub_key32[32];
281 288
282 unsigned saved_client_hello_size; 289/* HANDSHAKE HASH: */
283 uint8_t saved_client_hello[1]; 290 //unsigned saved_client_hello_size;
291 //uint8_t saved_client_hello[1];
284}; 292};
285 293
286 294
@@ -609,7 +617,7 @@ static void *tls_get_zeroed_outbuf(tls_state_t *tls, int len)
609 return record; 617 return record;
610} 618}
611 619
612static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) 620static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, unsigned type)
613{ 621{
614 uint8_t *buf = tls->outbuf + OUTBUF_PFX; 622 uint8_t *buf = tls->outbuf + OUTBUF_PFX;
615 struct record_hdr *xhdr; 623 struct record_hdr *xhdr;
@@ -619,7 +627,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
619 if (CIPHER_ID1 != TLS_RSA_WITH_NULL_SHA256 /* if "no encryption" can't be selected */ 627 if (CIPHER_ID1 != TLS_RSA_WITH_NULL_SHA256 /* if "no encryption" can't be selected */
620 || tls->cipher_id != TLS_RSA_WITH_NULL_SHA256 /* or if it wasn't selected */ 628 || tls->cipher_id != TLS_RSA_WITH_NULL_SHA256 /* or if it wasn't selected */
621 ) { 629 ) {
622 xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCKSIZE); /* place for IV */ 630 xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCK_SIZE); /* place for IV */
623 } 631 }
624 632
625 xhdr->type = type; 633 xhdr->type = type;
@@ -722,7 +730,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
722 // AES_128_CBC Block 16 16 16 730 // AES_128_CBC Block 16 16 16
723 // AES_256_CBC Block 32 16 16 731 // AES_256_CBC Block 32 16 16
724 732
725 tls_get_random(buf - AES_BLOCKSIZE, AES_BLOCKSIZE); /* IV */ 733 tls_get_random(buf - AES_BLOCK_SIZE, AES_BLOCK_SIZE); /* IV */
726 dbg("before crypt: 5 hdr + %u data + %u hash bytes\n", 734 dbg("before crypt: 5 hdr + %u data + %u hash bytes\n",
727 size - tls->MAC_size, tls->MAC_size); 735 size - tls->MAC_size, tls->MAC_size);
728 736
@@ -742,23 +750,24 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
742 // If you need no bytes to reach BLOCKSIZE, you have to pad a full 750 // If you need no bytes to reach BLOCKSIZE, you have to pad a full
743 // BLOCKSIZE with bytes of value (BLOCKSIZE-1). 751 // BLOCKSIZE with bytes of value (BLOCKSIZE-1).
744 // It's ok to have more than minimum padding, but we do minimum. 752 // It's ok to have more than minimum padding, but we do minimum.
745 padding_length = (~size) & (AES_BLOCKSIZE - 1); 753 padding_length = (~size) & (AES_BLOCK_SIZE - 1);
746 do { 754 do {
747 buf[size++] = padding_length; /* padding */ 755 buf[size++] = padding_length; /* padding */
748 } while ((size & (AES_BLOCKSIZE - 1)) != 0); 756 } while ((size & (AES_BLOCK_SIZE - 1)) != 0);
749 757
750 /* Encrypt content+MAC+padding in place */ 758 /* Encrypt content+MAC+padding in place */
759//optimize key setup
751 aes_cbc_encrypt( 760 aes_cbc_encrypt(
752 tls->client_write_key, tls->key_size, /* selects 128/256 */ 761 tls->client_write_key, tls->key_size, /* selects 128/256 */
753 buf - AES_BLOCKSIZE, /* IV */ 762 buf - AES_BLOCK_SIZE, /* IV */
754 buf, size, /* plaintext */ 763 buf, size, /* plaintext */
755 buf /* ciphertext */ 764 buf /* ciphertext */
756 ); 765 );
757 766
758 /* Write out */ 767 /* Write out */
759 dbg("writing 5 + %u IV + %u encrypted bytes, padding_length:0x%02x\n", 768 dbg("writing 5 + %u IV + %u encrypted bytes, padding_length:0x%02x\n",
760 AES_BLOCKSIZE, size, padding_length); 769 AES_BLOCK_SIZE, size, padding_length);
761 size += AES_BLOCKSIZE; /* + IV */ 770 size += AES_BLOCK_SIZE; /* + IV */
762 xhdr->len16_hi = size >> 8; 771 xhdr->len16_hi = size >> 8;
763 xhdr->len16_lo = size & 0xff; 772 xhdr->len16_lo = size & 0xff;
764 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); 773 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size);
@@ -766,23 +775,109 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
766 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); 775 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size);
767} 776}
768 777
778/* Example how GCM encryption combines nonce, aad, input and generates
779 * "header | exp_nonce | encrypted output | tag":
780 * nonce:0d 6a 26 31 00 00 00 00 00 00 00 01 (implicit 4 bytes (derived from master secret), then explicit 8 bytes)
781 * aad: 00 00 00 00 00 00 00 01 17 03 03 00 1c
782 * in: 47 45 54 20 2f 69 6e 64 65 78 2e 68 74 6d 6c 20 48 54 54 50 2f 31 2e 30 0d 0a 0d 0a "GET /index.html HTTP/1.0\r\n\r\n" (0x1c bytes)
783 * out: f7 8a b2 8f 78 0e f6 d5 76 17 2e b5 6d 46 59 56 8b 46 9f 0b d9 2c 35 28 13 66 19 be
784 * tag: c2 86 ce 4a 50 4a d0 aa 50 b3 76 5c 49 2a 3f 33
785 * sent: 17 03 03 00 34|00 00 00 00 00 00 00 01|f7 8a b2 8f 78 0e f6 d5 76 17 2e b5 6d 46 59 56 8b 46 9f 0b d9 2c 35 28 13 66 19 be|c2 86 ce 4a 50 4a d0 aa 50 b3 76 5c 49 2a 3f 33
786 * .............................................^^ buf points here
787 */
788static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned type)
789{
790//go for [16]
791 uint8_t aad[13];
792 uint8_t nonce[12 + 4]; /* +4 creates space for AES block counter */
793 uint8_t scratch[AES_BLOCK_SIZE]; //[16]
794 uint8_t authtag[AES_BLOCK_SIZE]; //[16]
795 uint8_t *buf;
796 struct record_hdr *xhdr;
797 unsigned remaining;
798 unsigned cnt;
799
800 buf = tls->outbuf + OUTBUF_PFX; /* see above for the byte it points to */
801 dump_hex("xwrite_encrypted_aesgcm plaintext:%s\n", buf, size);
802
803 xhdr = (void*)(buf - 8 - RECHDR_LEN);
804 xhdr->type = type; /* do it here so that "type" param no longer used */
805
806 aad[8] = type;
807 aad[9] = TLS_MAJ;
808 aad[10] = TLS_MIN;
809 aad[11] = size >> 8;
810 aad[12] = size & 0xff;
811
812 memcpy(nonce, tls->client_write_IV, 4);
813 memcpy(nonce + 4, &tls->write_seq64_be, 8);
814 memcpy(aad, &tls->write_seq64_be, 8);
815 memcpy(buf - 8, &tls->write_seq64_be, 8);
816//optimize
817 /* seq64 is not used later in this func, can increment here */
818 tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(tls->write_seq64_be));
819
820#define COUNTER(v) (*(uint32_t*)(v + 12))
821
822 cnt = 1;
823 remaining = size;
824 while (remaining != 0) {
825 unsigned n;
826
827 cnt++;
828 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */
829 aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch);
830 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining;
831 xorbuf(buf, scratch, n);
832 buf += n;
833 remaining -= n;
834 }
835
836//optimize fixed sizes
837 aesgcm_GHASH(tls->H, aad, sizeof(aad), tls->outbuf + OUTBUF_PFX, size, authtag, sizeof(authtag));
838 COUNTER(nonce) = htonl(1);
839 aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch);
840 xorbuf(authtag, scratch, sizeof(authtag));
841
842 memcpy(buf, authtag, sizeof(authtag));
843#undef COUNTER
844
845 /* Write out */
846 xhdr = (void*)(tls->outbuf + OUTBUF_PFX - 8 - RECHDR_LEN);
847 size += 8 + sizeof(authtag);
848 /*xhdr->type = type; - already is */
849 xhdr->proto_maj = TLS_MAJ;
850 xhdr->proto_min = TLS_MIN;
851 xhdr->len16_hi = size >> 8;
852 xhdr->len16_lo = size & 0xff;
853 size += RECHDR_LEN;
854 dump_raw_out(">> %s\n", xhdr, size);
855 xwrite(tls->ofd, xhdr, size);
856 dbg("wrote %u bytes\n", size);
857}
858
859static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
860{
861 if (!(tls->flags & ENCRYPTION_AESGCM)) {
862 xwrite_encrypted_and_hmac_signed(tls, size, type);
863 return;
864 }
865 xwrite_encrypted_aesgcm(tls, size, type);
866}
867
769static void xwrite_handshake_record(tls_state_t *tls, unsigned size) 868static void xwrite_handshake_record(tls_state_t *tls, unsigned size)
770{ 869{
771 //if (!tls->encrypt_on_write) { 870 uint8_t *buf = tls->outbuf + OUTBUF_PFX;
772 uint8_t *buf = tls->outbuf + OUTBUF_PFX; 871 struct record_hdr *xhdr = (void*)(buf - RECHDR_LEN);
773 struct record_hdr *xhdr = (void*)(buf - RECHDR_LEN);
774 872
775 xhdr->type = RECORD_TYPE_HANDSHAKE; 873 xhdr->type = RECORD_TYPE_HANDSHAKE;
776 xhdr->proto_maj = TLS_MAJ; 874 xhdr->proto_maj = TLS_MAJ;
777 xhdr->proto_min = TLS_MIN; 875 xhdr->proto_min = TLS_MIN;
778 xhdr->len16_hi = size >> 8; 876 xhdr->len16_hi = size >> 8;
779 xhdr->len16_lo = size & 0xff; 877 xhdr->len16_lo = size & 0xff;
780 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); 878 dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size);
781 xwrite(tls->ofd, xhdr, RECHDR_LEN + size); 879 xwrite(tls->ofd, xhdr, RECHDR_LEN + size);
782 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); 880 dbg("wrote %u bytes\n", (int)RECHDR_LEN + size);
783 // return;
784 //}
785 //xwrite_encrypted(tls, size, RECORD_TYPE_HANDSHAKE);
786} 881}
787 882
788static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size) 883static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size)
@@ -826,6 +921,52 @@ static const char *alert_text(int code)
826 return itoa(code); 921 return itoa(code);
827} 922}
828 923
924static void tls_aesgcm_decrypt(tls_state_t *tls, uint8_t *buf, int size)
925{
926//go for [16]
927 //uint8_t aad[13];
928 uint8_t nonce[12 + 4]; /* +4 creates space for AES block counter */
929 uint8_t scratch[AES_BLOCK_SIZE]; //[16]
930 //uint8_t authtag[AES_BLOCK_SIZE]; //[16]
931 unsigned remaining;
932 unsigned cnt;
933
934 //aad[8] = type;
935 //aad[9] = TLS_MAJ;
936 //aad[10] = TLS_MIN;
937 //aad[11] = size >> 8;
938 //aad[12] = size & 0xff;
939
940 memcpy(nonce, tls->server_write_IV, 4);
941 memcpy(nonce + 4, buf, 8);
942 buf += 8;
943
944#define COUNTER(v) (*(uint32_t*)(v + 12))
945
946 cnt = 1;
947 remaining = size;
948 while (remaining != 0) {
949 unsigned n;
950
951 cnt++;
952 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */
953 aes_encrypt_one_block(&tls->aes_decrypt, nonce, scratch);
954 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining;
955 xorbuf(buf, scratch, n);
956 buf += n;
957 remaining -= n;
958 }
959
960////optimize fixed sizes
961 //aesgcm_GHASH(tls->H, aad, sizeof(aad), tls->outbuf + OUTBUF_PFX, size, authtag, sizeof(authtag));
962 //COUNTER(nonce) = htonl(1);
963 //aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch);
964 //xorbuf(authtag, scratch, sizeof(authtag));
965
966 //memcmp(buf, authtag, sizeof(authtag)) || DIE("HASH DOES NOT MATCH!");
967#undef COUNTER
968}
969
829static int tls_xread_record(tls_state_t *tls, const char *expected) 970static int tls_xread_record(tls_state_t *tls, const char *expected)
830{ 971{
831 struct record_hdr *xhdr; 972 struct record_hdr *xhdr;
@@ -896,34 +1037,44 @@ static int tls_xread_record(tls_state_t *tls, const char *expected)
896 sz = target - RECHDR_LEN; 1037 sz = target - RECHDR_LEN;
897 1038
898 /* Needs to be decrypted? */ 1039 /* Needs to be decrypted? */
899 if (tls->min_encrypted_len_on_read > tls->MAC_size) { 1040 if (tls->min_encrypted_len_on_read != 0) {
900 uint8_t *p = tls->inbuf + RECHDR_LEN; 1041 if (sz < (int)tls->min_encrypted_len_on_read)
901 int padding_len; 1042 bb_error_msg_and_die("bad encrypted len:%u", sz);
902 1043
903 if (sz & (AES_BLOCKSIZE-1) 1044 if (tls->flags & ENCRYPTION_AESGCM) {
904 || sz < (int)tls->min_encrypted_len_on_read 1045 /* AESGCM */
905 ) { 1046 uint8_t *p = tls->inbuf + RECHDR_LEN;
906 bb_error_msg_and_die("bad encrypted len:%u < %u", 1047
907 sz, tls->min_encrypted_len_on_read); 1048 sz -= 8 + AES_BLOCK_SIZE; /* we will overwrite nonce, drop hash */
1049 tls_aesgcm_decrypt(tls, p, sz);
1050 memmove(p, p + 8, sz);
1051 dbg("encrypted size:%u\n", sz);
1052 } else
1053 if (tls->min_encrypted_len_on_read > tls->MAC_size) {
1054 /* AES+SHA */
1055 uint8_t *p = tls->inbuf + RECHDR_LEN;
1056 int padding_len;
1057
1058 if (sz & (AES_BLOCK_SIZE-1))
1059 bb_error_msg_and_die("bad encrypted len:%u", sz);
1060
1061 /* Decrypt content+MAC+padding, moving it over IV in the process */
1062 sz -= AES_BLOCK_SIZE; /* we will overwrite IV now */
1063 aes_cbc_decrypt(
1064 tls->server_write_key, tls->key_size, /* selects 128/256 */
1065 p, /* IV */
1066 p + AES_BLOCK_SIZE, sz, /* ciphertext */
1067 p /* plaintext */
1068 );
1069 padding_len = p[sz - 1];
1070 dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[0], padding_len);
1071 padding_len++;
1072 sz -= tls->MAC_size + padding_len; /* drop MAC and padding */
1073 } else {
1074 /* if nonzero, then it's TLS_RSA_WITH_NULL_SHA256: drop MAC */
1075 /* else: no encryption yet on input, subtract zero = NOP */
1076 sz -= tls->min_encrypted_len_on_read;
908 } 1077 }
909 /* Decrypt content+MAC+padding, moving it over IV in the process */
910 sz -= AES_BLOCKSIZE; /* we will overwrite IV now */
911 aes_cbc_decrypt(
912 tls->server_write_key, tls->key_size, /* selects 128/256 */
913 p, /* IV */
914 p + AES_BLOCKSIZE, sz, /* ciphertext */
915 p /* plaintext */
916 );
917 padding_len = p[sz - 1];
918 dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[0], padding_len);
919 padding_len++;
920 sz -= tls->MAC_size + padding_len; /* drop MAC and padding */
921 //if (sz < 0)
922 // bb_error_msg_and_die("bad padding size:%u", padding_len);
923 } else {
924 /* if nonzero, then it's TLS_RSA_WITH_NULL_SHA256: drop MAC */
925 /* else: no encryption yet on input, subtract zero = NOP */
926 sz -= tls->min_encrypted_len_on_read;
927 } 1078 }
928 if (sz < 0) 1079 if (sz < 0)
929 bb_error_msg_and_die("encrypted data too short"); 1080 bb_error_msg_and_die("encrypted data too short");
@@ -964,7 +1115,8 @@ static int tls_xread_record(tls_state_t *tls, const char *expected)
964 * in our FINISHED record must include data of incoming packets too! 1115 * in our FINISHED record must include data of incoming packets too!
965 */ 1116 */
966 if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE 1117 if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE
967 && tls->MAC_size != 0 /* do we know which hash to use? (server_hello() does not!) */ 1118/* HANDSHAKE HASH: */
1119 // && do_we_know_which_hash_to_use /* server_hello() might not know it in the future! */
968 ) { 1120 ) {
969 hash_handshake(tls, "<< hash:%s", tls->inbuf + RECHDR_LEN, sz); 1121 hash_handshake(tls, "<< hash:%s", tls->inbuf + RECHDR_LEN, sz);
970 } 1122 }
@@ -1198,16 +1350,16 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len)
1198 }; 1350 };
1199 if (memcmp(der, OID_RSA_KEY_ALG, sizeof(OID_RSA_KEY_ALG)) == 0) { 1351 if (memcmp(der, OID_RSA_KEY_ALG, sizeof(OID_RSA_KEY_ALG)) == 0) {
1200 dbg("RSA key\n"); 1352 dbg("RSA key\n");
1201 tls->hsd->key_alg = KEY_ALG_RSA; 1353 tls->flags |= GOT_CERT_RSA_KEY_ALG;
1202 } else 1354 } else
1203 if (memcmp(der, OID_ECDSA_KEY_ALG, sizeof(OID_ECDSA_KEY_ALG)) == 0) { 1355 if (memcmp(der, OID_ECDSA_KEY_ALG, sizeof(OID_ECDSA_KEY_ALG)) == 0) {
1204 dbg("ECDSA key\n"); 1356 dbg("ECDSA key\n");
1205 tls->hsd->key_alg = KEY_ALG_ECDSA; 1357 tls->flags |= GOT_CERT_ECDSA_KEY_ALG;
1206 } else 1358 } else
1207 bb_error_msg_and_die("not RSA or ECDSA key"); 1359 bb_error_msg_and_die("not RSA or ECDSA cert");
1208 } 1360 }
1209 1361
1210 if (tls->hsd->key_alg == KEY_ALG_RSA) { 1362 if (tls->flags & GOT_CERT_RSA_KEY_ALG) {
1211 /* parse RSA key: */ 1363 /* parse RSA key: */
1212 //based on getAsnRsaPubKey(), pkcs1ParsePrivBin() is also of note 1364 //based on getAsnRsaPubKey(), pkcs1ParsePrivBin() is also of note
1213 /* skip subjectPublicKeyInfo.algorithm */ 1365 /* skip subjectPublicKeyInfo.algorithm */
@@ -1301,7 +1453,7 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni)
1301 uint8_t session_id_len; 1453 uint8_t session_id_len;
1302 /* uint8_t session_id[]; */ 1454 /* uint8_t session_id[]; */
1303 uint8_t cipherid_len16_hi, cipherid_len16_lo; 1455 uint8_t cipherid_len16_hi, cipherid_len16_lo;
1304 uint8_t cipherid[2 * (2 + !!CIPHER_ID2 + !!CIPHER_ID3)]; /* actually variable */ 1456 uint8_t cipherid[2 * (1 + NUM_CIPHERS)]; /* actually variable */
1305 uint8_t comprtypes_len; 1457 uint8_t comprtypes_len;
1306 uint8_t comprtypes[1]; /* actually variable */ 1458 uint8_t comprtypes[1]; /* actually variable */
1307 /* Extensions (SNI shown): 1459 /* Extensions (SNI shown):
@@ -1364,6 +1516,10 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni)
1364 if ((CIPHER_ID3 >> 8) != 0) record->cipherid[6] = CIPHER_ID3 >> 8; 1516 if ((CIPHER_ID3 >> 8) != 0) record->cipherid[6] = CIPHER_ID3 >> 8;
1365 /*************************/ record->cipherid[7] = CIPHER_ID3 & 0xff; 1517 /*************************/ record->cipherid[7] = CIPHER_ID3 & 0xff;
1366#endif 1518#endif
1519#if CIPHER_ID4
1520 if ((CIPHER_ID4 >> 8) != 0) record->cipherid[6] = CIPHER_ID4 >> 8;
1521 /*************************/ record->cipherid[7] = CIPHER_ID4 & 0xff;
1522#endif
1367 1523
1368 record->comprtypes_len = 1; 1524 record->comprtypes_len = 1;
1369 /* record->comprtypes[0] = 0; */ 1525 /* record->comprtypes[0] = 0; */
@@ -1385,15 +1541,23 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni)
1385 } 1541 }
1386 memcpy(ptr, supported_groups, sizeof(supported_groups)); 1542 memcpy(ptr, supported_groups, sizeof(supported_groups));
1387 1543
1388 dbg(">> CLIENT_HELLO\n"); 1544 tls->hsd = xzalloc(sizeof(*tls->hsd));
1389 /* Can hash it only when we know which MAC hash to use */ 1545 /* HANDSHAKE HASH: ^^^ + len if need to save saved_client_hello */
1390 /*xwrite_and_update_handshake_hash(tls, len); - WRONG! */ 1546 memcpy(tls->hsd->client_and_server_rand32, record->rand32, sizeof(record->rand32));
1391 xwrite_handshake_record(tls, len); 1547/* HANDSHAKE HASH:
1392
1393 tls->hsd = xzalloc(sizeof(*tls->hsd) + len);
1394 tls->hsd->saved_client_hello_size = len; 1548 tls->hsd->saved_client_hello_size = len;
1395 memcpy(tls->hsd->saved_client_hello, record, len); 1549 memcpy(tls->hsd->saved_client_hello, record, len);
1396 memcpy(tls->hsd->client_and_server_rand32, record->rand32, sizeof(record->rand32)); 1550 */
1551 dbg(">> CLIENT_HELLO\n");
1552 /* Can hash immediately only if we know which MAC hash to use.
1553 * So far we do know: it's sha256:
1554 */
1555 sha256_begin(&tls->hsd->handshake_hash_ctx);
1556 xwrite_and_update_handshake_hash(tls, len);
1557 /* if this would become infeasible: save tls->hsd->saved_client_hello,
1558 * use "xwrite_handshake_record(tls, len)" here,
1559 * and hash saved_client_hello later.
1560 */
1397} 1561}
1398 1562
1399static void get_server_hello(tls_state_t *tls) 1563static void get_server_hello(tls_state_t *tls)
@@ -1463,18 +1627,28 @@ static void get_server_hello(tls_state_t *tls)
1463 if (cipher == TLS_RSA_WITH_AES_128_CBC_SHA 1627 if (cipher == TLS_RSA_WITH_AES_128_CBC_SHA
1464 || cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 1628 || cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
1465 ) { 1629 ) {
1630 if (cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA)
1631 tls->flags |= NEED_EC_KEY;
1466 tls->key_size = AES128_KEYSIZE; 1632 tls->key_size = AES128_KEYSIZE;
1467 tls->MAC_size = SHA1_OUTSIZE; 1633 tls->MAC_size = SHA1_OUTSIZE;
1468 } 1634 }
1469 else { /* TLS_RSA_WITH_AES_256_CBC_SHA256 */ 1635 else
1636 if (cipher == TLS_RSA_WITH_AES_256_CBC_SHA256) {
1470 tls->key_size = AES256_KEYSIZE; 1637 tls->key_size = AES256_KEYSIZE;
1471 tls->MAC_size = SHA256_OUTSIZE; 1638 tls->MAC_size = SHA256_OUTSIZE;
1472 } 1639 }
1640 else { /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */
1641 tls->flags |= NEED_EC_KEY | ENCRYPTION_AESGCM;
1642 tls->key_size = AES128_KEYSIZE;
1643 /* tls->MAC_size = 0; */
1644 tls->IV_size = 4;
1645 }
1473 /* Handshake hash eventually destined to FINISHED record 1646 /* Handshake hash eventually destined to FINISHED record
1474 * is sha256 regardless of cipher 1647 * is sha256 regardless of cipher
1475 * (at least for all ciphers defined by RFC5246). 1648 * (at least for all ciphers defined by RFC5246).
1476 * It's not sha1 for AES_128_CBC_SHA - only MAC is sha1, not this hash. 1649 * It's not sha1 for AES_128_CBC_SHA - only MAC is sha1, not this hash.
1477 */ 1650 */
1651/* HANDSHAKE HASH:
1478 sha256_begin(&tls->hsd->handshake_hash_ctx); 1652 sha256_begin(&tls->hsd->handshake_hash_ctx);
1479 hash_handshake(tls, ">> client hello hash:%s", 1653 hash_handshake(tls, ">> client hello hash:%s",
1480 tls->hsd->saved_client_hello, tls->hsd->saved_client_hello_size 1654 tls->hsd->saved_client_hello, tls->hsd->saved_client_hello_size
@@ -1482,6 +1656,7 @@ static void get_server_hello(tls_state_t *tls)
1482 hash_handshake(tls, "<< server hello hash:%s", 1656 hash_handshake(tls, "<< server hello hash:%s",
1483 tls->inbuf + RECHDR_LEN, len 1657 tls->inbuf + RECHDR_LEN, len
1484 ); 1658 );
1659 */
1485} 1660}
1486 1661
1487static void get_server_cert(tls_state_t *tls) 1662static void get_server_cert(tls_state_t *tls)
@@ -1548,7 +1723,7 @@ static void process_server_key(tls_state_t *tls, int len)
1548// 64523d6216cb94c43c9b20e377d8c52c55be6703fd6730a155930c705eaf3af6 //32bytes 1723// 64523d6216cb94c43c9b20e377d8c52c55be6703fd6730a155930c705eaf3af6 //32bytes
1549//same about this item ^^^^^ 1724//same about this item ^^^^^
1550 1725
1551//seen from www.openbsd.org 1726//seen from ftp.openbsd.org
1552//(which only accepts ECDHE-RSA-AESnnn-GCM-SHAnnn and ECDHE-RSA-CHACHA20-POLY1305 ciphers): 1727//(which only accepts ECDHE-RSA-AESnnn-GCM-SHAnnn and ECDHE-RSA-CHACHA20-POLY1305 ciphers):
1553// 0c 000228 //SERVER_KEY_EXCHANGE, len 1728// 0c 000228 //SERVER_KEY_EXCHANGE, len
1554// 03 //curve_type: named curve 1729// 03 //curve_type: named curve
@@ -1572,6 +1747,7 @@ static void process_server_key(tls_state_t *tls, int len)
1572 bb_error_msg_and_die("elliptic curve is not x25519"); 1747 bb_error_msg_and_die("elliptic curve is not x25519");
1573 1748
1574 memcpy(tls->hsd->ecc_pub_key32, keybuf + 4, 32); 1749 memcpy(tls->hsd->ecc_pub_key32, keybuf + 4, 32);
1750 tls->flags |= GOT_EC_KEY;
1575 dbg("got eccPubKey\n"); 1751 dbg("got eccPubKey\n");
1576} 1752}
1577 1753
@@ -1612,7 +1788,11 @@ static void send_client_key_exchange(tls_state_t *tls)
1612 int premaster_size; 1788 int premaster_size;
1613 int len; 1789 int len;
1614 1790
1615 if (tls->hsd->key_alg == KEY_ALG_RSA) { 1791 if (!(tls->flags & NEED_EC_KEY)) {
1792 /* RSA */
1793 if (!(tls->flags & GOT_CERT_RSA_KEY_ALG))
1794 bb_error_msg("server cert is not RSA");
1795
1616 tls_get_random(rsa_premaster, sizeof(rsa_premaster)); 1796 tls_get_random(rsa_premaster, sizeof(rsa_premaster));
1617 if (TLS_DEBUG_FIXED_SECRETS) 1797 if (TLS_DEBUG_FIXED_SECRETS)
1618 memset(rsa_premaster, 0x44, sizeof(rsa_premaster)); 1798 memset(rsa_premaster, 0x44, sizeof(rsa_premaster));
@@ -1636,10 +1816,13 @@ static void send_client_key_exchange(tls_state_t *tls)
1636 premaster = rsa_premaster; 1816 premaster = rsa_premaster;
1637 premaster_size = sizeof(rsa_premaster); 1817 premaster_size = sizeof(rsa_premaster);
1638 } else { 1818 } else {
1639 /* KEY_ALG_ECDSA */ 1819 /* ECDHE */
1640 static const uint8_t basepoint9[CURVE25519_KEYSIZE] = {9}; 1820 static const uint8_t basepoint9[CURVE25519_KEYSIZE] = {9};
1641 uint8_t privkey[CURVE25519_KEYSIZE]; //[32] 1821 uint8_t privkey[CURVE25519_KEYSIZE]; //[32]
1642 1822
1823 if (!(tls->flags & GOT_EC_KEY))
1824 bb_error_msg("server did not provide EC key");
1825
1643 /* Generate random private key, see RFC 7748 */ 1826 /* Generate random private key, see RFC 7748 */
1644 tls_get_random(privkey, sizeof(privkey)); 1827 tls_get_random(privkey, sizeof(privkey));
1645 privkey[0] &= 0xf8; 1828 privkey[0] &= 0xf8;
@@ -1727,23 +1910,32 @@ static void send_client_key_exchange(tls_state_t *tls)
1727 memcpy(&tmp64[32], &tls->hsd->client_and_server_rand32[0] , 32); 1910 memcpy(&tmp64[32], &tls->hsd->client_and_server_rand32[0] , 32);
1728 1911
1729 prf_hmac_sha256(/*tls,*/ 1912 prf_hmac_sha256(/*tls,*/
1730 tls->client_write_MAC_key, 2 * (tls->MAC_size + tls->key_size), 1913 tls->client_write_MAC_key, 2 * (tls->MAC_size + tls->key_size + tls->IV_size),
1731 // also fills: 1914 // also fills:
1732 // server_write_MAC_key[] 1915 // server_write_MAC_key[]
1733 // client_write_key[] 1916 // client_write_key[]
1734 // server_write_key[] 1917 // server_write_key[]
1918 // client_write_IV[]
1919 // server_write_IV[]
1735 tls->hsd->master_secret, sizeof(tls->hsd->master_secret), 1920 tls->hsd->master_secret, sizeof(tls->hsd->master_secret),
1736 "key expansion", 1921 "key expansion",
1737 tmp64, 64 1922 tmp64, 64
1738 ); 1923 );
1739 tls->client_write_key = tls->client_write_MAC_key + (2 * tls->MAC_size); 1924 tls->client_write_key = tls->client_write_MAC_key + (2 * tls->MAC_size);
1740 tls->server_write_key = tls->client_write_key + tls->key_size; 1925 tls->server_write_key = tls->client_write_key + tls->key_size;
1926 tls->client_write_IV = tls->server_write_key + tls->key_size;
1927 tls->server_write_IV = tls->client_write_IV + tls->IV_size;
1741 dump_hex("client_write_MAC_key:%s\n", 1928 dump_hex("client_write_MAC_key:%s\n",
1742 tls->client_write_MAC_key, tls->MAC_size 1929 tls->client_write_MAC_key, tls->MAC_size
1743 ); 1930 );
1744 dump_hex("client_write_key:%s\n", 1931 dump_hex("client_write_key:%s\n",
1745 tls->client_write_key, tls->key_size 1932 tls->client_write_key, tls->key_size
1746 ); 1933 );
1934 dump_hex("client_write_IV:%s\n",
1935 tls->client_write_IV, tls->IV_size
1936 );
1937 aesgcm_setkey(tls->H, &tls->aes_encrypt, tls->client_write_key, tls->key_size);
1938 aes_setkey(&tls->aes_decrypt, tls->server_write_key, tls->key_size);
1747 } 1939 }
1748} 1940}
1749 1941
@@ -1876,7 +2068,7 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni)
1876 // client. 2068 // client.
1877 dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len); 2069 dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len);
1878 dump_raw_in("<< %s\n", tls->inbuf, RECHDR_LEN + len); 2070 dump_raw_in("<< %s\n", tls->inbuf, RECHDR_LEN + len);
1879 if (tls->hsd->key_alg == KEY_ALG_ECDSA) 2071 if (tls->flags & NEED_EC_KEY)
1880 process_server_key(tls, len); 2072 process_server_key(tls, len);
1881 2073
1882 // read next handshake block 2074 // read next handshake block
@@ -1922,18 +2114,22 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni)
1922 if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) 2114 if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0)
1923 bad_record_die(tls, "switch to encrypted traffic", len); 2115 bad_record_die(tls, "switch to encrypted traffic", len);
1924 dbg("<< CHANGE_CIPHER_SPEC\n"); 2116 dbg("<< CHANGE_CIPHER_SPEC\n");
2117
1925 if (CIPHER_ID1 == TLS_RSA_WITH_NULL_SHA256 2118 if (CIPHER_ID1 == TLS_RSA_WITH_NULL_SHA256
1926 && tls->cipher_id == TLS_RSA_WITH_NULL_SHA256 2119 && tls->cipher_id == TLS_RSA_WITH_NULL_SHA256
1927 ) { 2120 ) {
1928 tls->min_encrypted_len_on_read = tls->MAC_size; 2121 tls->min_encrypted_len_on_read = tls->MAC_size;
1929 } else { 2122 } else
1930 unsigned mac_blocks = (unsigned)(tls->MAC_size + AES_BLOCKSIZE-1) / AES_BLOCKSIZE; 2123 if (!(tls->flags & ENCRYPTION_AESGCM)) {
2124 unsigned mac_blocks = (unsigned)(tls->MAC_size + AES_BLOCK_SIZE-1) / AES_BLOCK_SIZE;
1931 /* all incoming packets now should be encrypted and have 2125 /* all incoming packets now should be encrypted and have
1932 * at least IV + (MAC padded to blocksize): 2126 * at least IV + (MAC padded to blocksize):
1933 */ 2127 */
1934 tls->min_encrypted_len_on_read = AES_BLOCKSIZE + (mac_blocks * AES_BLOCKSIZE); 2128 tls->min_encrypted_len_on_read = AES_BLOCK_SIZE + (mac_blocks * AES_BLOCK_SIZE);
1935 dbg("min_encrypted_len_on_read: %u", tls->min_encrypted_len_on_read); 2129 } else {
2130 tls->min_encrypted_len_on_read = 8 + AES_BLOCK_SIZE;
1936 } 2131 }
2132 dbg("min_encrypted_len_on_read: %u\n", tls->min_encrypted_len_on_read);
1937 2133
1938 /* Get (encrypted) FINISHED from the server */ 2134 /* Get (encrypted) FINISHED from the server */
1939 len = tls_xread_record(tls, "'server finished'"); 2135 len = tls_xread_record(tls, "'server finished'");
diff --git a/networking/tls.h b/networking/tls.h
index 66d25eff5..1d379c193 100644
--- a/networking/tls.h
+++ b/networking/tls.h
@@ -78,6 +78,8 @@ typedef int16_t int16;
78#define PUBKEY_TYPE 0x01 78#define PUBKEY_TYPE 0x01
79#define PRIVKEY_TYPE 0x02 79#define PRIVKEY_TYPE 0x02
80 80
81#define AES_BLOCK_SIZE 16
82
81void tls_get_random(void *buf, unsigned len); 83void tls_get_random(void *buf, unsigned len);
82 84
83#define matrixCryptoGetPrngData(buf, len, userPtr) (tls_get_random(buf, len), PS_SUCCESS) 85#define matrixCryptoGetPrngData(buf, len, userPtr) (tls_get_random(buf, len), PS_SUCCESS)
@@ -96,5 +98,6 @@ void tls_get_random(void *buf, unsigned len);
96#include "tls_pstm.h" 98#include "tls_pstm.h"
97#include "tls_symmetric.h" 99#include "tls_symmetric.h"
98#include "tls_aes.h" 100#include "tls_aes.h"
101#include "tls_aesgcm.h"
99#include "tls_rsa.h" 102#include "tls_rsa.h"
100#include "tls_fe.h" 103#include "tls_fe.h"
diff --git a/networking/tls_aes.c b/networking/tls_aes.c
index c137442e9..4d2b68975 100644
--- a/networking/tls_aes.c
+++ b/networking/tls_aes.c
@@ -340,8 +340,12 @@ static void aes_encrypt_1(unsigned astate[16], unsigned rounds, const uint32_t *
340 AddRoundKey(astate, RoundKey); 340 AddRoundKey(astate, RoundKey);
341} 341}
342 342
343#if 0 // UNUSED 343void FAST_FUNC aes_setkey(struct tls_aes *aes, const void *key, unsigned key_len)
344static void aes_encrypt_one_block(unsigned rounds, const uint32_t *RoundKey, const void *data, void *dst) 344{
345 aes->rounds = KeyExpansion(aes->key, key, key_len);
346}
347
348void FAST_FUNC aes_encrypt_one_block(struct tls_aes *aes, const void *data, void *dst)
345{ 349{
346 unsigned astate[16]; 350 unsigned astate[16];
347 unsigned i; 351 unsigned i;
@@ -351,13 +355,12 @@ static void aes_encrypt_one_block(unsigned rounds, const uint32_t *RoundKey, con
351 355
352 for (i = 0; i < 16; i++) 356 for (i = 0; i < 16; i++)
353 astate[i] = pt[i]; 357 astate[i] = pt[i];
354 aes_encrypt_1(astate, rounds, RoundKey); 358 aes_encrypt_1(astate, aes->rounds, aes->key);
355 for (i = 0; i < 16; i++) 359 for (i = 0; i < 16; i++)
356 ct[i] = astate[i]; 360 ct[i] = astate[i];
357} 361}
358#endif
359 362
360void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) 363void FAST_FUNC aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst)
361{ 364{
362 uint32_t RoundKey[60]; 365 uint32_t RoundKey[60];
363 uint8_t iv2[16]; 366 uint8_t iv2[16];
@@ -420,7 +423,7 @@ static void aes_decrypt_one_block(unsigned rounds, const uint32_t *RoundKey, con
420} 423}
421#endif 424#endif
422 425
423void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) 426void FAST_FUNC aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst)
424{ 427{
425 uint32_t RoundKey[60]; 428 uint32_t RoundKey[60];
426 uint8_t iv2[16]; 429 uint8_t iv2[16];
diff --git a/networking/tls_aes.h b/networking/tls_aes.h
index c6791866a..fc3881793 100644
--- a/networking/tls_aes.h
+++ b/networking/tls_aes.h
@@ -6,5 +6,9 @@
6 * Selected few declarations for AES. 6 * Selected few declarations for AES.
7 */ 7 */
8 8
9void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst); 9void aes_setkey(struct tls_aes *aes, const void *key, unsigned key_len) FAST_FUNC;
10void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst); 10
11void aes_encrypt_one_block(struct tls_aes *aes, const void *data, void *dst) FAST_FUNC;
12
13void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) FAST_FUNC;
14void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) FAST_FUNC;
diff --git a/networking/tls_aesgcm.c b/networking/tls_aesgcm.c
new file mode 100644
index 000000000..584cee98e
--- /dev/null
+++ b/networking/tls_aesgcm.c
@@ -0,0 +1,148 @@
1/*
2 * Copyright (C) 2018 Denys Vlasenko
3 *
4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */
6
7#include "tls.h"
8
9typedef uint8_t byte;
10typedef uint32_t word32;
11#define XMEMSET memset
12#define XMEMCPY memcpy
13
14#define TLS_MAJ 3
15#define TLS_MIN 3
16#define RECHDR_LEN 5
17#define OUTBUF_PFX (8 + AES_BLOCK_SIZE)
18
19void FAST_FUNC xorbuf(void* buf, const void* mask, unsigned count)
20{
21 word32 i;
22 byte* b = (byte*)buf;
23 const byte* m = (const byte*)mask;
24 for (i = 0; i < count; i++)
25 b[i] ^= m[i];
26}
27
28/* wolfssl-3.15.3/wolfcrypt/src/aes.c */
29
30static void FlattenSzInBits(byte* buf, word32 sz)
31{
32 /* Multiply the sz by 8 */
33 word32 szHi = (sz >> (8*sizeof(sz) - 3));
34 sz <<= 3;
35
36 /* copy over the words of the sz into the destination buffer */
37 buf[0] = (szHi >> 24) & 0xff;
38 buf[1] = (szHi >> 16) & 0xff;
39 buf[2] = (szHi >> 8) & 0xff;
40 buf[3] = szHi & 0xff;
41 buf[4] = (sz >> 24) & 0xff;
42 buf[5] = (sz >> 16) & 0xff;
43 buf[6] = (sz >> 8) & 0xff;
44 buf[7] = sz & 0xff;
45}
46
47static void RIGHTSHIFTX(byte* x)
48{
49 int i;
50 int carryOut = 0;
51 int carryIn = 0;
52 int borrow = x[15] & 0x01;
53
54 for (i = 0; i < AES_BLOCK_SIZE; i++) {
55 carryOut = x[i] & 0x01;
56 x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
57 carryIn = carryOut;
58 }
59 if (borrow) x[0] ^= 0xE1;
60}
61
62static void GMULT(byte* X, byte* Y)
63{
64 byte Z[AES_BLOCK_SIZE];
65 byte V[AES_BLOCK_SIZE];
66 int i, j;
67
68 XMEMSET(Z, 0, AES_BLOCK_SIZE);
69 XMEMCPY(V, X, AES_BLOCK_SIZE);
70 for (i = 0; i < AES_BLOCK_SIZE; i++)
71 {
72 byte y = Y[i];
73 for (j = 0; j < 8; j++)
74 {
75 if (y & 0x80) {
76 xorbuf(Z, V, AES_BLOCK_SIZE);
77 }
78
79 RIGHTSHIFTX(V);
80 y = y << 1;
81 }
82 }
83 XMEMCPY(X, Z, AES_BLOCK_SIZE);
84}
85
86void FAST_FUNC aesgcm_GHASH(byte* h, const byte* a, unsigned aSz, const byte* c,
87 unsigned cSz, byte* s, unsigned sSz)
88{
89 byte x[AES_BLOCK_SIZE];
90 byte scratch[AES_BLOCK_SIZE];
91 word32 blocks, partial;
92 //was: byte* h = aes->H;
93
94 XMEMSET(x, 0, AES_BLOCK_SIZE);
95
96 /* Hash in A, the Additional Authentication Data */
97 if (aSz != 0 && a != NULL) {
98 blocks = aSz / AES_BLOCK_SIZE;
99 partial = aSz % AES_BLOCK_SIZE;
100 while (blocks--) {
101 xorbuf(x, a, AES_BLOCK_SIZE);
102 GMULT(x, h);
103 a += AES_BLOCK_SIZE;
104 }
105 if (partial != 0) {
106 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
107 XMEMCPY(scratch, a, partial);
108 xorbuf(x, scratch, AES_BLOCK_SIZE);
109 GMULT(x, h);
110 }
111 }
112
113 /* Hash in C, the Ciphertext */
114 if (cSz != 0 && c != NULL) {
115 blocks = cSz / AES_BLOCK_SIZE;
116 partial = cSz % AES_BLOCK_SIZE;
117 while (blocks--) {
118 xorbuf(x, c, AES_BLOCK_SIZE);
119 GMULT(x, h);
120 c += AES_BLOCK_SIZE;
121 }
122 if (partial != 0) {
123 XMEMSET(scratch, 0, AES_BLOCK_SIZE);
124 XMEMCPY(scratch, c, partial);
125 xorbuf(x, scratch, AES_BLOCK_SIZE);
126 GMULT(x, h);
127 }
128 }
129
130 /* Hash in the lengths of A and C in bits */
131 FlattenSzInBits(&scratch[0], aSz);
132 FlattenSzInBits(&scratch[8], cSz);
133 xorbuf(x, scratch, AES_BLOCK_SIZE);
134 GMULT(x, h);
135
136 /* Copy the result into s. */
137 XMEMCPY(s, x, sSz);
138}
139
140void FAST_FUNC aesgcm_setkey(uint8_t H[16], struct tls_aes *aes, const byte* key, unsigned len)
141{
142 byte iv[AES_BLOCK_SIZE];
143
144 aes_setkey(aes, key, len);
145
146 memset(iv, 0, AES_BLOCK_SIZE);
147 aes_encrypt_one_block(aes, iv, H);
148}
diff --git a/networking/tls_aesgcm.h b/networking/tls_aesgcm.h
new file mode 100644
index 000000000..d4cde01f9
--- /dev/null
+++ b/networking/tls_aesgcm.h
@@ -0,0 +1,15 @@
1/*
2 * Copyright (C) 2018 Denys Vlasenko
3 *
4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */
6
7void xorbuf(void* buf, const void* mask, unsigned count) FAST_FUNC;
8
9void aesgcm_GHASH(uint8_t* h,
10 const uint8_t* a, unsigned aSz,
11 const uint8_t* c, unsigned cSz,
12 uint8_t* s, unsigned sSz
13) FAST_FUNC;
14
15void aesgcm_setkey(uint8_t H[16], struct tls_aes *aes, const uint8_t* key, unsigned len) FAST_FUNC;
diff --git a/networking/tls_fe.c b/networking/tls_fe.c
index dcb41468a..f235082f5 100644
--- a/networking/tls_fe.c
+++ b/networking/tls_fe.c
@@ -554,7 +554,7 @@ static void xc_double(byte *x3, byte *z3,
554 fe_mul_c(z3, x1sq, 4); 554 fe_mul_c(z3, x1sq, 4);
555} 555}
556 556
557void curve25519(byte *result, const byte *e, const byte *q) 557void FAST_FUNC curve25519(byte *result, const byte *e, const byte *q)
558{ 558{
559 int i; 559 int i;
560 560
diff --git a/networking/tls_fe.h b/networking/tls_fe.h
index bd2f2b3da..fe8cff228 100644
--- a/networking/tls_fe.h
+++ b/networking/tls_fe.h
@@ -4,4 +4,4 @@
4 * Licensed under GPLv2, see file LICENSE in this source tree. 4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */ 5 */
6#define CURVE25519_KEYSIZE 32 6#define CURVE25519_KEYSIZE 32
7void curve25519(uint8_t *result, const uint8_t *e, const uint8_t *q); 7void curve25519(uint8_t *result, const uint8_t *e, const uint8_t *q) FAST_FUNC;
diff --git a/networking/tls_rsa.c b/networking/tls_rsa.c
index 60c54248e..631397e4d 100644
--- a/networking/tls_rsa.c
+++ b/networking/tls_rsa.c
@@ -179,7 +179,7 @@ done:
179 return res; 179 return res;
180} 180}
181 181
182int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, 182int32 FAST_FUNC psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key,
183 unsigned char *in, uint32 inlen, 183 unsigned char *in, uint32 inlen,
184 unsigned char *out, uint32 outlen, void *data) 184 unsigned char *out, uint32 outlen, void *data)
185{ 185{
diff --git a/networking/tls_rsa.h b/networking/tls_rsa.h
index c464ed552..f42923ff5 100644
--- a/networking/tls_rsa.h
+++ b/networking/tls_rsa.h
@@ -17,4 +17,4 @@ typedef struct {
17 psRsaEncryptPub( key, in, inlen, out, outlen) 17 psRsaEncryptPub( key, in, inlen, out, outlen)
18int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, 18int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key,
19 unsigned char *in, uint32 inlen, 19 unsigned char *in, uint32 inlen,
20 unsigned char *out, uint32 outlen, void *data); 20 unsigned char *out, uint32 outlen, void *data) FAST_FUNC;