diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-11-23 17:21:38 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-11-23 17:48:07 +0100 |
commit | 83e5c627e1b2c7f34d694696d0c3d5a3ce25dc59 (patch) | |
tree | 3bdffe7c29ee5213ba4278da9b0ee116c2806d78 | |
parent | 03ad7ae08189ed88dd7e0fcb6c6001fbf3b12efb (diff) | |
download | busybox-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.h | 17 | ||||
-rw-r--r-- | networking/tls.c | 360 | ||||
-rw-r--r-- | networking/tls.h | 3 | ||||
-rw-r--r-- | networking/tls_aes.c | 15 | ||||
-rw-r--r-- | networking/tls_aes.h | 8 | ||||
-rw-r--r-- | networking/tls_aesgcm.c | 148 | ||||
-rw-r--r-- | networking/tls_aesgcm.h | 15 | ||||
-rw-r--r-- | networking/tls_fe.c | 2 | ||||
-rw-r--r-- | networking/tls_fe.h | 2 | ||||
-rw-r--r-- | networking/tls_rsa.c | 2 | ||||
-rw-r--r-- | networking/tls_rsa.h | 2 |
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 | ||
739 | struct 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 | ||
741 | struct tls_handshake_data; /* opaque */ | 746 | struct tls_handshake_data; /* opaque */ |
742 | typedef struct tls_state { | 747 | typedef 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 | ||
780 | static inline tls_state_t *new_tls_state(void) | 797 | static 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 | ||
265 | enum { | 270 | enum { |
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 | }; |
269 | struct tls_handshake_data { | 277 | struct 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 | ||
612 | static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | 620 | static 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 | */ | ||
788 | static 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 | |||
859 | static 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 | |||
769 | static void xwrite_handshake_record(tls_state_t *tls, unsigned size) | 868 | static 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 | ||
788 | static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size) | 883 | static 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 | ||
924 | static 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 | |||
829 | static int tls_xread_record(tls_state_t *tls, const char *expected) | 970 | static 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 | ||
1399 | static void get_server_hello(tls_state_t *tls) | 1563 | static 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 | ||
1487 | static void get_server_cert(tls_state_t *tls) | 1662 | static 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 | |||
81 | void tls_get_random(void *buf, unsigned len); | 83 | void 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 | 343 | void FAST_FUNC aes_setkey(struct tls_aes *aes, const void *key, unsigned key_len) |
344 | static 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 | |||
348 | void 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 | ||
360 | void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) | 363 | void 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 | ||
423 | void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) | 426 | void 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 | ||
9 | void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst); | 9 | void aes_setkey(struct tls_aes *aes, const void *key, unsigned key_len) FAST_FUNC; |
10 | void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst); | 10 | |
11 | void aes_encrypt_one_block(struct tls_aes *aes, const void *data, void *dst) FAST_FUNC; | ||
12 | |||
13 | void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) FAST_FUNC; | ||
14 | void 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 | |||
9 | typedef uint8_t byte; | ||
10 | typedef 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 | |||
19 | void 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 | |||
30 | static 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 | |||
47 | static 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 | |||
62 | static 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 | |||
86 | void 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 | |||
140 | void 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 | |||
7 | void xorbuf(void* buf, const void* mask, unsigned count) FAST_FUNC; | ||
8 | |||
9 | void 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 | |||
15 | void 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 | ||
557 | void curve25519(byte *result, const byte *e, const byte *q) | 557 | void 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 |
7 | void curve25519(uint8_t *result, const uint8_t *e, const uint8_t *q); | 7 | void 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 | ||
182 | int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, | 182 | int32 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) |
18 | int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, | 18 | int32 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; |