diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-24 16:00:54 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-24 16:00:54 +0100 |
| commit | 49ecee098d062b92fcf095e05e15779c32899646 (patch) | |
| tree | a02df1cfc23064d3f37a7adb15e1dafdf7a76c97 | |
| parent | 9a64c3337cc0a5e84e9ad457eeb1d475c311e9fc (diff) | |
| download | busybox-w32-49ecee098d062b92fcf095e05e15779c32899646.tar.gz busybox-w32-49ecee098d062b92fcf095e05e15779c32899646.tar.bz2 busybox-w32-49ecee098d062b92fcf095e05e15779c32899646.zip | |
tls: add 2nd cipher_id, TLS_RSA_WITH_AES_128_CBC_SHA, so far it doesn't work
Good news that TLS_RSA_WITH_AES_256_CBC_SHA256 still works with new code ;)
This change adds inevitable extension to have different sized hashes and AES key sizes.
In libbb, md5_end() and shaX_end() are extended to return result size instead of void -
this helps *a lot* in tls (the cost is ~5 bytes per _end() function).
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | coreutils/md5_sha1_sum.c | 2 | ||||
| -rw-r--r-- | include/libbb.h | 42 | ||||
| -rw-r--r-- | libbb/hash_md5_sha.c | 15 | ||||
| -rw-r--r-- | libbb/hash_md5prime.c | 3 | ||||
| -rw-r--r-- | libbb/pw_encrypt_sha.c | 3 | ||||
| -rw-r--r-- | networking/tls.c | 413 |
6 files changed, 288 insertions, 190 deletions
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c index 76788554c..50111bd26 100644 --- a/coreutils/md5_sha1_sum.c +++ b/coreutils/md5_sha1_sum.c | |||
| @@ -166,7 +166,7 @@ static uint8_t *hash_file(const char *filename, unsigned sha3_width) | |||
| 166 | } context; | 166 | } context; |
| 167 | uint8_t *hash_value; | 167 | uint8_t *hash_value; |
| 168 | void FAST_FUNC (*update)(void*, const void*, size_t); | 168 | void FAST_FUNC (*update)(void*, const void*, size_t); |
| 169 | void FAST_FUNC (*final)(void*, void*); | 169 | unsigned FAST_FUNC (*final)(void*, void*); |
| 170 | char hash_algo; | 170 | char hash_algo; |
| 171 | 171 | ||
| 172 | src_fd = open_or_warn_stdin(filename); | 172 | src_fd = open_or_warn_stdin(filename); |
diff --git a/include/libbb.h b/include/libbb.h index ba3b1479e..b1ceb3278 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -713,18 +713,19 @@ struct hostent *xgethostbyname(const char *name) FAST_FUNC; | |||
| 713 | // Also mount.c and inetd.c are using gethostbyname(), | 713 | // Also mount.c and inetd.c are using gethostbyname(), |
| 714 | // + inet_common.c has additional IPv4-only stuff | 714 | // + inet_common.c has additional IPv4-only stuff |
| 715 | 715 | ||
| 716 | #define SHA256_INSIZE 64 | 716 | |
| 717 | #define SHA256_OUTSIZE 32 | 717 | #define TLS_MAX_MAC_SIZE 32 |
| 718 | #define AES_BLOCKSIZE 16 | 718 | #define TLS_MAX_KEY_SIZE 32 |
| 719 | #define AES128_KEYSIZE 16 | ||
| 720 | #define AES256_KEYSIZE 32 | ||
| 721 | struct tls_handshake_data; /* opaque */ | 719 | struct tls_handshake_data; /* opaque */ |
| 722 | typedef struct tls_state { | 720 | typedef struct tls_state { |
| 723 | int ofd; | 721 | int ofd; |
| 724 | int ifd; | 722 | int ifd; |
| 725 | 723 | ||
| 726 | int min_encrypted_len_on_read; | 724 | int min_encrypted_len_on_read; |
| 727 | uint8_t encrypt_on_write; | 725 | uint16_t cipher_id; |
| 726 | uint8_t encrypt_on_write; | ||
| 727 | unsigned MAC_size; | ||
| 728 | unsigned key_size; | ||
| 728 | 729 | ||
| 729 | uint8_t *outbuf; | 730 | uint8_t *outbuf; |
| 730 | int outbuf_size; | 731 | int outbuf_size; |
| @@ -746,10 +747,12 @@ typedef struct tls_state { | |||
| 746 | /*uint64_t read_seq64_be;*/ | 747 | /*uint64_t read_seq64_be;*/ |
| 747 | uint64_t write_seq64_be; | 748 | uint64_t write_seq64_be; |
| 748 | 749 | ||
| 749 | uint8_t client_write_MAC_key[SHA256_OUTSIZE]; | 750 | uint8_t *client_write_key; |
| 750 | uint8_t server_write_MAC_key[SHA256_OUTSIZE]; | 751 | uint8_t *server_write_key; |
| 751 | uint8_t client_write_key[AES256_KEYSIZE]; | 752 | uint8_t client_write_MAC_key[TLS_MAX_MAC_SIZE]; |
| 752 | uint8_t server_write_key[AES256_KEYSIZE]; | 753 | uint8_t server_write_MAC_k__[TLS_MAX_MAC_SIZE]; |
| 754 | uint8_t client_write_k__[TLS_MAX_KEY_SIZE]; | ||
| 755 | uint8_t server_write_k__[TLS_MAX_KEY_SIZE]; | ||
| 753 | } tls_state_t; | 756 | } tls_state_t; |
| 754 | 757 | ||
| 755 | static inline tls_state_t *new_tls_state(void) | 758 | static inline tls_state_t *new_tls_state(void) |
| @@ -760,6 +763,7 @@ static inline tls_state_t *new_tls_state(void) | |||
| 760 | void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; | 763 | void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; |
| 761 | void tls_run_copy_loop(tls_state_t *tls) FAST_FUNC; | 764 | void tls_run_copy_loop(tls_state_t *tls) FAST_FUNC; |
| 762 | 765 | ||
| 766 | |||
| 763 | void socket_want_pktinfo(int fd) FAST_FUNC; | 767 | void socket_want_pktinfo(int fd) FAST_FUNC; |
| 764 | ssize_t send_to_from(int fd, void *buf, size_t len, int flags, | 768 | ssize_t send_to_from(int fd, void *buf, size_t len, int flags, |
| 765 | const struct sockaddr *to, | 769 | const struct sockaddr *to, |
| @@ -1799,19 +1803,23 @@ typedef struct sha3_ctx_t { | |||
| 1799 | } sha3_ctx_t; | 1803 | } sha3_ctx_t; |
| 1800 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; | 1804 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; |
| 1801 | void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 1805 | void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
| 1802 | void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1806 | unsigned md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; |
| 1803 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; | 1807 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; |
| 1804 | #define sha1_hash md5_hash | 1808 | #define sha1_hash md5_hash |
| 1805 | void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1809 | unsigned sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; |
| 1806 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; | 1810 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; |
| 1807 | #define sha256_hash md5_hash | 1811 | #define sha256_hash md5_hash |
| 1808 | #define sha256_end sha1_end | 1812 | #define sha256_end sha1_end |
| 1809 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; | 1813 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; |
| 1810 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 1814 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
| 1811 | void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1815 | unsigned sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; |
| 1812 | void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; | 1816 | void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; |
| 1813 | void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 1817 | void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
| 1814 | void sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1818 | unsigned sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; |
| 1819 | /* TLS benefits from knowing that sha1 and sha256 share these. Give them "agnostic" names too */ | ||
| 1820 | typedef struct md5_ctx_t md5sha_ctx_t; | ||
| 1821 | #define md5sha_hash md5_hash | ||
| 1822 | #define sha_end sha1_end | ||
| 1815 | 1823 | ||
| 1816 | extern uint32_t *global_crc32_table; | 1824 | extern uint32_t *global_crc32_table; |
| 1817 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; | 1825 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; |
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index d325584d7..2a7247430 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
| @@ -458,7 +458,7 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | |||
| 458 | * endian byte order, so that a byte-wise output yields to the wanted | 458 | * endian byte order, so that a byte-wise output yields to the wanted |
| 459 | * ASCII representation of the message digest. | 459 | * ASCII representation of the message digest. |
| 460 | */ | 460 | */ |
| 461 | void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | 461 | unsigned FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) |
| 462 | { | 462 | { |
| 463 | /* MD5 stores total in LE, need to swap on BE arches: */ | 463 | /* MD5 stores total in LE, need to swap on BE arches: */ |
| 464 | common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN); | 464 | common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN); |
| @@ -472,6 +472,7 @@ void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | |||
| 472 | } | 472 | } |
| 473 | 473 | ||
| 474 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); | 474 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); |
| 475 | return sizeof(ctx->hash[0]) * 4; | ||
| 475 | } | 476 | } |
| 476 | 477 | ||
| 477 | 478 | ||
| @@ -865,7 +866,7 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) | |||
| 865 | #endif /* NEED_SHA512 */ | 866 | #endif /* NEED_SHA512 */ |
| 866 | 867 | ||
| 867 | /* Used also for sha256 */ | 868 | /* Used also for sha256 */ |
| 868 | void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) | 869 | unsigned FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) |
| 869 | { | 870 | { |
| 870 | unsigned hash_size; | 871 | unsigned hash_size; |
| 871 | 872 | ||
| @@ -879,11 +880,13 @@ void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) | |||
| 879 | for (i = 0; i < hash_size; ++i) | 880 | for (i = 0; i < hash_size; ++i) |
| 880 | ctx->hash[i] = SWAP_BE32(ctx->hash[i]); | 881 | ctx->hash[i] = SWAP_BE32(ctx->hash[i]); |
| 881 | } | 882 | } |
| 882 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * hash_size); | 883 | hash_size *= sizeof(ctx->hash[0]); |
| 884 | memcpy(resbuf, ctx->hash, hash_size); | ||
| 885 | return hash_size; | ||
| 883 | } | 886 | } |
| 884 | 887 | ||
| 885 | #if NEED_SHA512 | 888 | #if NEED_SHA512 |
| 886 | void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | 889 | unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) |
| 887 | { | 890 | { |
| 888 | unsigned bufpos = ctx->total64[0] & 127; | 891 | unsigned bufpos = ctx->total64[0] & 127; |
| 889 | 892 | ||
| @@ -915,6 +918,7 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |||
| 915 | ctx->hash[i] = SWAP_BE64(ctx->hash[i]); | 918 | ctx->hash[i] = SWAP_BE64(ctx->hash[i]); |
| 916 | } | 919 | } |
| 917 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); | 920 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); |
| 921 | return sizeof(ctx->hash); | ||
| 918 | } | 922 | } |
| 919 | #endif /* NEED_SHA512 */ | 923 | #endif /* NEED_SHA512 */ |
| 920 | 924 | ||
| @@ -1450,7 +1454,7 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | |||
| 1450 | #endif | 1454 | #endif |
| 1451 | } | 1455 | } |
| 1452 | 1456 | ||
| 1453 | void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) | 1457 | unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) |
| 1454 | { | 1458 | { |
| 1455 | /* Padding */ | 1459 | /* Padding */ |
| 1456 | uint8_t *buf = (uint8_t*)ctx->state; | 1460 | uint8_t *buf = (uint8_t*)ctx->state; |
| @@ -1475,4 +1479,5 @@ void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) | |||
| 1475 | 1479 | ||
| 1476 | /* Output */ | 1480 | /* Output */ |
| 1477 | memcpy(resbuf, ctx->state, 64); | 1481 | memcpy(resbuf, ctx->state, 64); |
| 1482 | return 64; | ||
| 1478 | } | 1483 | } |
diff --git a/libbb/hash_md5prime.c b/libbb/hash_md5prime.c index e089a15f5..4b58d37ff 100644 --- a/libbb/hash_md5prime.c +++ b/libbb/hash_md5prime.c | |||
| @@ -437,7 +437,7 @@ void FAST_FUNC md5_hash(const void *buffer, size_t inputLen, md5_ctx_t *context) | |||
| 437 | * MD5 finalization. Ends an MD5 message-digest operation, | 437 | * MD5 finalization. Ends an MD5 message-digest operation, |
| 438 | * writing the message digest. | 438 | * writing the message digest. |
| 439 | */ | 439 | */ |
| 440 | void FAST_FUNC md5_end(void *digest, md5_ctx_t *context) | 440 | unsigned FAST_FUNC md5_end(void *digest, md5_ctx_t *context) |
| 441 | { | 441 | { |
| 442 | unsigned idx, padLen; | 442 | unsigned idx, padLen; |
| 443 | unsigned char bits[8]; | 443 | unsigned char bits[8]; |
| @@ -457,4 +457,5 @@ void FAST_FUNC md5_end(void *digest, md5_ctx_t *context) | |||
| 457 | 457 | ||
| 458 | /* Store state in digest */ | 458 | /* Store state in digest */ |
| 459 | memcpy32_cpu2le(digest, context->state, 16); | 459 | memcpy32_cpu2le(digest, context->state, 16); |
| 460 | return 16; | ||
| 460 | } | 461 | } |
diff --git a/libbb/pw_encrypt_sha.c b/libbb/pw_encrypt_sha.c index 72e37e485..5457d7ab6 100644 --- a/libbb/pw_encrypt_sha.c +++ b/libbb/pw_encrypt_sha.c | |||
| @@ -18,9 +18,10 @@ static char * | |||
| 18 | NOINLINE | 18 | NOINLINE |
| 19 | sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) | 19 | sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) |
| 20 | { | 20 | { |
| 21 | #undef sha_end | ||
| 21 | void (*sha_begin)(void *ctx) FAST_FUNC; | 22 | void (*sha_begin)(void *ctx) FAST_FUNC; |
| 22 | void (*sha_hash)(void *ctx, const void *buffer, size_t len) FAST_FUNC; | 23 | void (*sha_hash)(void *ctx, const void *buffer, size_t len) FAST_FUNC; |
| 23 | void (*sha_end)(void *ctx, void *resbuf) FAST_FUNC; | 24 | unsigned (*sha_end)(void *ctx, void *resbuf) FAST_FUNC; |
| 24 | int _32or64; | 25 | int _32or64; |
| 25 | 26 | ||
| 26 | char *result, *resptr; | 27 | char *result, *resptr; |
diff --git a/networking/tls.c b/networking/tls.c index 8549a21da..a65da4ad4 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
| @@ -18,10 +18,50 @@ | |||
| 18 | 18 | ||
| 19 | #include "tls.h" | 19 | #include "tls.h" |
| 20 | 20 | ||
| 21 | #define TLS_DEBUG 0 | 21 | //Tested against kernel.org: |
| 22 | #define TLS_DEBUG_HASH 0 | 22 | //TLS 1.2 |
| 23 | #define TLS_DEBUG_DER 0 | 23 | #define TLS_MAJ 3 |
| 24 | #define TLS_DEBUG_FIXED_SECRETS 0 | 24 | #define TLS_MIN 3 |
| 25 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA // ok, recvs SERVER_KEY_EXCHANGE *** matrixssl uses this on my box | ||
| 26 | //#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE | ||
| 27 | //#define CIPHER_ID TLS_DH_anon_WITH_AES_256_CBC_SHA // SSL_ALERT_HANDSHAKE_FAILURE | ||
| 28 | //^^^^^^^^^^^^^^^^^^^^^^^ (tested b/c this one doesn't req server certs... no luck, server refuses it) | ||
| 29 | //#define CIPHER_ID TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 // SSL_ALERT_HANDSHAKE_FAILURE | ||
| 30 | //#define CIPHER_ID TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE | ||
| 31 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 // ok, recvs SERVER_KEY_EXCHANGE | ||
| 32 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | ||
| 33 | //#define CIPHER_ID TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 | ||
| 34 | //#define CIPHER_ID TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE | ||
| 35 | //#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 | ||
| 36 | //#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE | ||
| 37 | //#define CIPHER_ID TLS_RSA_WITH_AES_256_GCM_SHA384 // ok, no SERVER_KEY_EXCHANGE | ||
| 38 | //#define CIPHER_ID TLS_RSA_WITH_AES_128_GCM_SHA256 // ok, no SERVER_KEY_EXCHANGE *** select this? | ||
| 39 | |||
| 40 | // works against "openssl s_server -cipher NULL" | ||
| 41 | // and against wolfssl-3.9.10-stable/examples/server/server.c: | ||
| 42 | //#define CIPHER_ID TLS_RSA_WITH_NULL_SHA256 // for testing (does everything except encrypting) | ||
| 43 | |||
| 44 | // works against wolfssl-3.9.10-stable/examples/server/server.c | ||
| 45 | // works for kernel.org | ||
| 46 | // does not work for cdn.kernel.org (e.g. downloading an actual tarball, not a web page) | ||
| 47 | // getting alert 40 "handshake failure" at once | ||
| 48 | // with GNU Wget 1.18, they agree on TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xC02F) cipher | ||
| 49 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES256-SHA256 | ||
| 50 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES256-GCM-SHA384 | ||
| 51 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-SHA256 | ||
| 52 | // ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-GCM-SHA256 | ||
| 53 | // ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-SHA | ||
| 54 | // (TLS_RSA_WITH_AES_128_CBC_SHA - in TLS 1.2 it's mandated to be always supported) | ||
| 55 | #define CIPHER_ID1 TLS_RSA_WITH_AES_256_CBC_SHA256 // no SERVER_KEY_EXCHANGE from peer | ||
| 56 | // Does not work yet: | ||
| 57 | //#define CIPHER_ID2 TLS_RSA_WITH_AES_128_CBC_SHA | ||
| 58 | #define CIPHER_ID2 0 | ||
| 59 | |||
| 60 | |||
| 61 | #define TLS_DEBUG 1 | ||
| 62 | #define TLS_DEBUG_HASH 1 | ||
| 63 | #define TLS_DEBUG_DER 1 | ||
| 64 | #define TLS_DEBUG_FIXED_SECRETS 1 | ||
| 25 | #if 0 | 65 | #if 0 |
| 26 | # define dump_raw_out(...) dump_hex(__VA_ARGS__) | 66 | # define dump_raw_out(...) dump_hex(__VA_ARGS__) |
| 27 | #else | 67 | #else |
| @@ -124,52 +164,26 @@ | |||
| 124 | #define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /* 49201 */ | 164 | #define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /* 49201 */ |
| 125 | #define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /* 49202 */ | 165 | #define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /* 49202 */ |
| 126 | 166 | ||
| 127 | //Tested against kernel.org: | 167 | /* Might go to libbb.h */ |
| 128 | //TLS 1.2 | 168 | #define TLS_MAX_CRYPTBLOCK_SIZE 16 |
| 129 | #define TLS_MAJ 3 | 169 | #define TLS_MAX_OUTBUF (1 << 14) |
| 130 | #define TLS_MIN 3 | ||
| 131 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA // ok, recvs SERVER_KEY_EXCHANGE *** matrixssl uses this on my box | ||
| 132 | //#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE | ||
| 133 | //#define CIPHER_ID TLS_DH_anon_WITH_AES_256_CBC_SHA // SSL_ALERT_HANDSHAKE_FAILURE | ||
| 134 | //^^^^^^^^^^^^^^^^^^^^^^^ (tested b/c this one doesn't req server certs... no luck, server refuses it) | ||
| 135 | //#define CIPHER_ID TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 // SSL_ALERT_HANDSHAKE_FAILURE | ||
| 136 | //#define CIPHER_ID TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE | ||
| 137 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 // ok, recvs SERVER_KEY_EXCHANGE | ||
| 138 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | ||
| 139 | //#define CIPHER_ID TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 | ||
| 140 | //#define CIPHER_ID TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE | ||
| 141 | //#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 | ||
| 142 | //#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE | ||
| 143 | //#define CIPHER_ID TLS_RSA_WITH_AES_256_GCM_SHA384 // ok, no SERVER_KEY_EXCHANGE | ||
| 144 | //#define CIPHER_ID TLS_RSA_WITH_AES_128_GCM_SHA256 // ok, no SERVER_KEY_EXCHANGE *** select this? | ||
| 145 | 170 | ||
| 146 | // works against "openssl s_server -cipher NULL" | 171 | enum { |
| 147 | // and against wolfssl-3.9.10-stable/examples/server/server.c: | 172 | SHA_INSIZE = 64, |
| 148 | //#define CIPHER_ID TLS_RSA_WITH_NULL_SHA256 // for testing (does everything except encrypting) | 173 | SHA1_OUTSIZE = 20, |
| 174 | SHA256_OUTSIZE = 32, | ||
| 149 | 175 | ||
| 150 | // works against wolfssl-3.9.10-stable/examples/server/server.c | 176 | AES_BLOCKSIZE = 16, |
| 151 | // works for kernel.org | 177 | AES128_KEYSIZE = 16, |
| 152 | // does not work for cdn.kernel.org (e.g. downloading an actual tarball, not a web page) | 178 | AES256_KEYSIZE = 32, |
| 153 | // getting alert 40 "handshake failure" at once | ||
| 154 | // with GNU Wget 1.18, they agree on TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xC02F) cipher | ||
| 155 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES256-SHA256 | ||
| 156 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES256-GCM-SHA384 | ||
| 157 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-SHA256 | ||
| 158 | // ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-GCM-SHA256 | ||
| 159 | // ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-SHA | ||
| 160 | // (TLS_RSA_WITH_AES_128_CBC_SHA - in TLS 1.2 it's mandated to be always supported) | ||
| 161 | #define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // no SERVER_KEY_EXCHANGE from peer | ||
| 162 | 179 | ||
| 163 | enum { | ||
| 164 | RSA_PREMASTER_SIZE = 48, | 180 | RSA_PREMASTER_SIZE = 48, |
| 165 | 181 | ||
| 166 | RECHDR_LEN = 5, | 182 | RECHDR_LEN = 5, |
| 167 | 183 | ||
| 168 | MAX_TLS_RECORD = (1 << 14), | ||
| 169 | /* 8 = 3+5. 3 extra bytes result in record data being 32-bit aligned */ | 184 | /* 8 = 3+5. 3 extra bytes result in record data being 32-bit aligned */ |
| 170 | OUTBUF_PFX = 8 + AES_BLOCKSIZE, /* header + IV */ | 185 | OUTBUF_PFX = 8 + AES_BLOCKSIZE, /* header + IV */ |
| 171 | OUTBUF_SFX = SHA256_OUTSIZE + AES_BLOCKSIZE, /* MAC + padding */ | 186 | OUTBUF_SFX = TLS_MAX_MAC_SIZE + TLS_MAX_CRYPTBLOCK_SIZE, /* MAC + padding */ |
| 172 | MAX_OUTBUF = MAX_TLS_RECORD - OUTBUF_PFX - OUTBUF_SFX, | ||
| 173 | 187 | ||
| 174 | // RFC 5246 | 188 | // RFC 5246 |
| 175 | // | 6.2.1. Fragmentation | 189 | // | 6.2.1. Fragmentation |
| @@ -205,7 +219,7 @@ enum { | |||
| 205 | // | length | 219 | // | length |
| 206 | // | The length (in bytes) of the following TLSCiphertext.fragment. | 220 | // | The length (in bytes) of the following TLSCiphertext.fragment. |
| 207 | // | The length MUST NOT exceed 2^14 + 2048. | 221 | // | The length MUST NOT exceed 2^14 + 2048. |
| 208 | MAX_INBUF = (1 << 14) + 2048, | 222 | MAX_INBUF = RECHDR_LEN + (1 << 14) + 2048, |
| 209 | }; | 223 | }; |
| 210 | 224 | ||
| 211 | struct record_hdr { | 225 | struct record_hdr { |
| @@ -215,12 +229,17 @@ struct record_hdr { | |||
| 215 | }; | 229 | }; |
| 216 | 230 | ||
| 217 | struct tls_handshake_data { | 231 | struct tls_handshake_data { |
| 218 | sha256_ctx_t handshake_sha256_ctx; | 232 | /* In bbox, md5/sha1/sha256 ctx's are the same structure */ |
| 233 | md5sha_ctx_t handshake_hash_ctx; | ||
| 234 | |||
| 219 | uint8_t client_and_server_rand32[2 * 32]; | 235 | uint8_t client_and_server_rand32[2 * 32]; |
| 220 | uint8_t master_secret[48]; | 236 | uint8_t master_secret[48]; |
| 221 | //TODO: store just the DER key here, parse/use/delete it when sending client key | 237 | //TODO: store just the DER key here, parse/use/delete it when sending client key |
| 222 | //this way it will stay key type agnostic here. | 238 | //this way it will stay key type agnostic here. |
| 223 | psRsaKey_t server_rsa_pub_key; | 239 | psRsaKey_t server_rsa_pub_key; |
| 240 | |||
| 241 | unsigned saved_client_hello_size; | ||
| 242 | uint8_t saved_client_hello[1]; | ||
| 224 | }; | 243 | }; |
| 225 | 244 | ||
| 226 | 245 | ||
| @@ -275,37 +294,41 @@ void tls_get_random(void *buf, unsigned len) | |||
| 275 | xfunc_die(); | 294 | xfunc_die(); |
| 276 | } | 295 | } |
| 277 | 296 | ||
| 278 | //TODO rename this to sha256_hash, and sha256_hash -> sha256_update | 297 | /* Nondestructively see the current hash value */ |
| 279 | static void hash_sha256(uint8_t out[SHA256_OUTSIZE], const void *data, unsigned size) | 298 | static unsigned sha_peek(md5sha_ctx_t *ctx, void *buffer) |
| 280 | { | 299 | { |
| 281 | sha256_ctx_t ctx; | 300 | md5sha_ctx_t ctx_copy = *ctx; /* struct copy */ |
| 282 | sha256_begin(&ctx); | 301 | return sha_end(&ctx_copy, buffer); |
| 283 | sha256_hash(&ctx, data, size); | ||
| 284 | sha256_end(&ctx, out); | ||
| 285 | } | 302 | } |
| 286 | 303 | ||
| 287 | /* Nondestructively see the current hash value */ | 304 | static ALWAYS_INLINE unsigned get_handshake_hash(tls_state_t *tls, void *buffer) |
| 288 | static void sha256_peek(sha256_ctx_t *ctx, void *buffer) | ||
| 289 | { | 305 | { |
| 290 | sha256_ctx_t ctx_copy = *ctx; | 306 | return sha_peek(&tls->hsd->handshake_hash_ctx, buffer); |
| 291 | sha256_end(&ctx_copy, buffer); | ||
| 292 | } | 307 | } |
| 293 | 308 | ||
| 294 | #if TLS_DEBUG_HASH | 309 | #if !TLS_DEBUG_HASH |
| 295 | static void sha256_hash_dbg(const char *fmt, sha256_ctx_t *ctx, const void *buffer, size_t len) | 310 | # define hash_handshake(tls, fmt, buffer, len) \ |
| 311 | hash_handshake(tls, buffer, len) | ||
| 312 | #endif | ||
| 313 | static void hash_handshake(tls_state_t *tls, const char *fmt, const void *buffer, unsigned len) | ||
| 296 | { | 314 | { |
| 297 | uint8_t h[SHA256_OUTSIZE]; | 315 | md5sha_hash(&tls->hsd->handshake_hash_ctx, buffer, len); |
| 298 | 316 | #if TLS_DEBUG_HASH | |
| 299 | sha256_hash(ctx, buffer, len); | 317 | { |
| 300 | dump_hex(fmt, buffer, len); | 318 | uint8_t h[TLS_MAX_MAC_SIZE]; |
| 301 | dbg(" (%u) ", (int)len); | 319 | dump_hex(fmt, buffer, len); |
| 302 | sha256_peek(ctx, h); | 320 | dbg(" (%u bytes) ", (int)len); |
| 303 | dump_hex("%s\n", h, SHA256_OUTSIZE); | 321 | len = sha_peek(&tls->hsd->handshake_hash_ctx, h); |
| 304 | } | 322 | if (len == SHA1_OUTSIZE) |
| 305 | #else | 323 | dump_hex("sha1:%s\n", h, len); |
| 306 | # define sha256_hash_dbg(fmt, ctx, buffer, len) \ | 324 | else |
| 307 | sha256_hash(ctx, buffer, len) | 325 | if (len == SHA256_OUTSIZE) |
| 326 | dump_hex("sha256:%s\n", h, len); | ||
| 327 | else | ||
| 328 | dump_hex("sha???:%s\n", h, len); | ||
| 329 | } | ||
| 308 | #endif | 330 | #endif |
| 331 | } | ||
| 309 | 332 | ||
| 310 | // RFC 2104 | 333 | // RFC 2104 |
| 311 | // HMAC(key, text) based on a hash H (say, sha256) is: | 334 | // HMAC(key, text) based on a hash H (say, sha256) is: |
| @@ -317,12 +340,13 @@ static void sha256_hash_dbg(const char *fmt, sha256_ctx_t *ctx, const void *buff | |||
| 317 | // if we often need HMAC hmac with the same key. | 340 | // if we often need HMAC hmac with the same key. |
| 318 | // | 341 | // |
| 319 | // text is often given in disjoint pieces. | 342 | // text is often given in disjoint pieces. |
| 320 | static void hmac_sha256_precomputed_v(uint8_t out[SHA256_OUTSIZE], | 343 | static unsigned hmac_sha_precomputed_v(uint8_t *out, |
| 321 | sha256_ctx_t *hashed_key_xor_ipad, | 344 | md5sha_ctx_t *hashed_key_xor_ipad, |
| 322 | sha256_ctx_t *hashed_key_xor_opad, | 345 | md5sha_ctx_t *hashed_key_xor_opad, |
| 323 | va_list va) | 346 | va_list va) |
| 324 | { | 347 | { |
| 325 | uint8_t *text; | 348 | uint8_t *text; |
| 349 | unsigned len; | ||
| 326 | 350 | ||
| 327 | /* hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */ | 351 | /* hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */ |
| 328 | /* hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */ | 352 | /* hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */ |
| @@ -330,24 +354,24 @@ static void hmac_sha256_precomputed_v(uint8_t out[SHA256_OUTSIZE], | |||
| 330 | /* calculate out = H((key XOR ipad) + text) */ | 354 | /* calculate out = H((key XOR ipad) + text) */ |
| 331 | while ((text = va_arg(va, uint8_t*)) != NULL) { | 355 | while ((text = va_arg(va, uint8_t*)) != NULL) { |
| 332 | unsigned text_size = va_arg(va, unsigned); | 356 | unsigned text_size = va_arg(va, unsigned); |
| 333 | sha256_hash(hashed_key_xor_ipad, text, text_size); | 357 | md5sha_hash(hashed_key_xor_ipad, text, text_size); |
| 334 | } | 358 | } |
| 335 | sha256_end(hashed_key_xor_ipad, out); | 359 | len = sha_end(hashed_key_xor_ipad, out); |
| 336 | 360 | ||
| 337 | /* out = H((key XOR opad) + out) */ | 361 | /* out = H((key XOR opad) + out) */ |
| 338 | sha256_hash(hashed_key_xor_opad, out, SHA256_OUTSIZE); | 362 | md5sha_hash(hashed_key_xor_opad, out, len); |
| 339 | sha256_end(hashed_key_xor_opad, out); | 363 | return sha_end(hashed_key_xor_opad, out); |
| 340 | } | 364 | } |
| 341 | 365 | ||
| 342 | static void hmac_sha256(uint8_t out[SHA256_OUTSIZE], uint8_t *key, unsigned key_size, ...) | 366 | static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) |
| 343 | { | 367 | { |
| 344 | sha256_ctx_t hashed_key_xor_ipad; | 368 | md5sha_ctx_t hashed_key_xor_ipad; |
| 345 | sha256_ctx_t hashed_key_xor_opad; | 369 | md5sha_ctx_t hashed_key_xor_opad; |
| 346 | uint8_t key_xor_ipad[SHA256_INSIZE]; | 370 | uint8_t key_xor_ipad[SHA_INSIZE]; |
| 347 | uint8_t key_xor_opad[SHA256_INSIZE]; | 371 | uint8_t key_xor_opad[SHA_INSIZE]; |
| 348 | uint8_t tempkey[SHA256_OUTSIZE]; | 372 | uint8_t tempkey[SHA256_OUTSIZE]; |
| 349 | va_list va; | 373 | va_list va; |
| 350 | int i; | 374 | unsigned i; |
| 351 | 375 | ||
| 352 | va_start(va, key_size); | 376 | va_start(va, key_size); |
| 353 | 377 | ||
| @@ -355,27 +379,38 @@ static void hmac_sha256(uint8_t out[SHA256_OUTSIZE], uint8_t *key, unsigned key_ | |||
| 355 | // block length of the hash function. Applications that use keys longer | 379 | // block length of the hash function. Applications that use keys longer |
| 356 | // than INSIZE bytes will first hash the key using H and then use the | 380 | // than INSIZE bytes will first hash the key using H and then use the |
| 357 | // resultant OUTSIZE byte string as the actual key to HMAC." | 381 | // resultant OUTSIZE byte string as the actual key to HMAC." |
| 358 | if (key_size > SHA256_INSIZE) { | 382 | if (key_size > SHA_INSIZE) { |
| 359 | hash_sha256(tempkey, key, key_size); | 383 | md5sha_ctx_t ctx; |
| 360 | key = tempkey; | 384 | if (tls->MAC_size == SHA256_OUTSIZE) |
| 361 | key_size = SHA256_OUTSIZE; | 385 | sha256_begin(&ctx); |
| 386 | else | ||
| 387 | sha1_begin(&ctx); | ||
| 388 | md5sha_hash(&ctx, key, key_size); | ||
| 389 | key_size = sha_end(&ctx, tempkey); | ||
| 362 | } | 390 | } |
| 363 | 391 | ||
| 364 | for (i = 0; i < key_size; i++) { | 392 | for (i = 0; i < key_size; i++) { |
| 365 | key_xor_ipad[i] = key[i] ^ 0x36; | 393 | key_xor_ipad[i] = key[i] ^ 0x36; |
| 366 | key_xor_opad[i] = key[i] ^ 0x5c; | 394 | key_xor_opad[i] = key[i] ^ 0x5c; |
| 367 | } | 395 | } |
| 368 | for (; i < SHA256_INSIZE; i++) { | 396 | for (; i < SHA_INSIZE; i++) { |
| 369 | key_xor_ipad[i] = 0x36; | 397 | key_xor_ipad[i] = 0x36; |
| 370 | key_xor_opad[i] = 0x5c; | 398 | key_xor_opad[i] = 0x5c; |
| 371 | } | 399 | } |
| 372 | sha256_begin(&hashed_key_xor_ipad); | ||
| 373 | sha256_hash(&hashed_key_xor_ipad, key_xor_ipad, SHA256_INSIZE); | ||
| 374 | sha256_begin(&hashed_key_xor_opad); | ||
| 375 | sha256_hash(&hashed_key_xor_opad, key_xor_opad, SHA256_INSIZE); | ||
| 376 | 400 | ||
| 377 | hmac_sha256_precomputed_v(out, &hashed_key_xor_ipad, &hashed_key_xor_opad, va); | 401 | if (tls->MAC_size == SHA256_OUTSIZE) { |
| 402 | sha256_begin(&hashed_key_xor_ipad); | ||
| 403 | sha256_begin(&hashed_key_xor_opad); | ||
| 404 | } else { | ||
| 405 | sha1_begin(&hashed_key_xor_ipad); | ||
| 406 | sha1_begin(&hashed_key_xor_opad); | ||
| 407 | } | ||
| 408 | md5sha_hash(&hashed_key_xor_ipad, key_xor_ipad, SHA_INSIZE); | ||
| 409 | md5sha_hash(&hashed_key_xor_opad, key_xor_opad, SHA_INSIZE); | ||
| 410 | |||
| 411 | i = hmac_sha_precomputed_v(out, &hashed_key_xor_ipad, &hashed_key_xor_opad, va); | ||
| 378 | va_end(va); | 412 | va_end(va); |
| 413 | return i; | ||
| 379 | } | 414 | } |
| 380 | 415 | ||
| 381 | // RFC 5246: | 416 | // RFC 5246: |
| @@ -406,40 +441,41 @@ static void hmac_sha256(uint8_t out[SHA256_OUTSIZE], uint8_t *key, unsigned key_ | |||
| 406 | // PRF(secret, label, seed) = P_<hash>(secret, label + seed) | 441 | // PRF(secret, label, seed) = P_<hash>(secret, label + seed) |
| 407 | // | 442 | // |
| 408 | // The label is an ASCII string. | 443 | // The label is an ASCII string. |
| 409 | static void prf_hmac_sha256( | 444 | static void prf_hmac(tls_state_t *tls, |
| 410 | uint8_t *outbuf, unsigned outbuf_size, | 445 | uint8_t *outbuf, unsigned outbuf_size, |
| 411 | uint8_t *secret, unsigned secret_size, | 446 | uint8_t *secret, unsigned secret_size, |
| 412 | const char *label, | 447 | const char *label, |
| 413 | uint8_t *seed, unsigned seed_size) | 448 | uint8_t *seed, unsigned seed_size) |
| 414 | { | 449 | { |
| 415 | uint8_t a[SHA256_OUTSIZE]; | 450 | uint8_t a[TLS_MAX_MAC_SIZE]; |
| 416 | uint8_t *out_p = outbuf; | 451 | uint8_t *out_p = outbuf; |
| 417 | unsigned label_size = strlen(label); | 452 | unsigned label_size = strlen(label); |
| 453 | unsigned MAC_size = tls->MAC_size; | ||
| 418 | 454 | ||
| 419 | /* In P_hash() calculation, "seed" is "label + seed": */ | 455 | /* In P_hash() calculation, "seed" is "label + seed": */ |
| 420 | #define SEED label, label_size, seed, seed_size | 456 | #define SEED label, label_size, seed, seed_size |
| 421 | #define SECRET secret, secret_size | 457 | #define SECRET secret, secret_size |
| 422 | #define A a, (int)(sizeof(a)) | 458 | #define A a, MAC_size |
| 423 | 459 | ||
| 424 | /* A(1) = HMAC_hash(secret, seed) */ | 460 | /* A(1) = HMAC_hash(secret, seed) */ |
| 425 | hmac_sha256(a, SECRET, SEED, NULL); | 461 | hmac(tls, a, SECRET, SEED, NULL); |
| 426 | //TODO: convert hmac_sha256 to precomputed | 462 | //TODO: convert hmac to precomputed |
| 427 | 463 | ||
| 428 | for(;;) { | 464 | for(;;) { |
| 429 | /* HMAC_hash(secret, A(1) + seed) */ | 465 | /* HMAC_hash(secret, A(1) + seed) */ |
| 430 | if (outbuf_size <= SHA256_OUTSIZE) { | 466 | if (outbuf_size <= MAC_size) { |
| 431 | /* Last, possibly incomplete, block */ | 467 | /* Last, possibly incomplete, block */ |
| 432 | /* (use a[] as temp buffer) */ | 468 | /* (use a[] as temp buffer) */ |
| 433 | hmac_sha256(a, SECRET, A, SEED, NULL); | 469 | hmac(tls, a, SECRET, A, SEED, NULL); |
| 434 | memcpy(out_p, a, outbuf_size); | 470 | memcpy(out_p, a, outbuf_size); |
| 435 | return; | 471 | return; |
| 436 | } | 472 | } |
| 437 | /* Not last block. Store directly to result buffer */ | 473 | /* Not last block. Store directly to result buffer */ |
| 438 | hmac_sha256(out_p, SECRET, A, SEED, NULL); | 474 | hmac(tls, out_p, SECRET, A, SEED, NULL); |
| 439 | out_p += SHA256_OUTSIZE; | 475 | out_p += MAC_size; |
| 440 | outbuf_size -= SHA256_OUTSIZE; | 476 | outbuf_size -= MAC_size; |
| 441 | /* A(2) = HMAC_hash(secret, A(1)) */ | 477 | /* A(2) = HMAC_hash(secret, A(1)) */ |
| 442 | hmac_sha256(a, SECRET, A, NULL); | 478 | hmac(tls, a, SECRET, A, NULL); |
| 443 | } | 479 | } |
| 444 | #undef A | 480 | #undef A |
| 445 | #undef SECRET | 481 | #undef SECRET |
| @@ -484,11 +520,12 @@ static void tls_free_outbuf(tls_state_t *tls) | |||
| 484 | 520 | ||
| 485 | static void *tls_get_outbuf(tls_state_t *tls, int len) | 521 | static void *tls_get_outbuf(tls_state_t *tls, int len) |
| 486 | { | 522 | { |
| 487 | if (len > MAX_OUTBUF) | 523 | if (len > TLS_MAX_OUTBUF) |
| 488 | xfunc_die(); | 524 | xfunc_die(); |
| 489 | if (tls->outbuf_size < len + OUTBUF_PFX + OUTBUF_SFX) { | 525 | len += OUTBUF_PFX + OUTBUF_SFX; |
| 490 | tls->outbuf_size = len + OUTBUF_PFX + OUTBUF_SFX; | 526 | if (tls->outbuf_size < len) { |
| 491 | tls->outbuf = xrealloc(tls->outbuf, tls->outbuf_size); | 527 | tls->outbuf_size = len; |
| 528 | tls->outbuf = xrealloc(tls->outbuf, len); | ||
| 492 | } | 529 | } |
| 493 | return tls->outbuf + OUTBUF_PFX; | 530 | return tls->outbuf + OUTBUF_PFX; |
| 494 | } | 531 | } |
| @@ -500,7 +537,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
| 500 | uint8_t padding_length; | 537 | uint8_t padding_length; |
| 501 | 538 | ||
| 502 | xhdr = (void*)(buf - RECHDR_LEN); | 539 | xhdr = (void*)(buf - RECHDR_LEN); |
| 503 | if (CIPHER_ID != TLS_RSA_WITH_NULL_SHA256) | 540 | if (tls->cipher_id != TLS_RSA_WITH_NULL_SHA256) |
| 504 | xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCKSIZE); /* place for IV */ | 541 | xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCKSIZE); /* place for IV */ |
| 505 | 542 | ||
| 506 | xhdr->type = type; | 543 | xhdr->type = type; |
| @@ -511,16 +548,16 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
| 511 | xhdr->len16_lo = size & 0xff; | 548 | xhdr->len16_lo = size & 0xff; |
| 512 | 549 | ||
| 513 | /* Calculate MAC signature */ | 550 | /* Calculate MAC signature */ |
| 514 | //TODO: convert hmac_sha256 to precomputed | 551 | hmac(tls, buf + size, /* result */ |
| 515 | hmac_sha256(buf + size, | 552 | tls->client_write_MAC_key, tls->MAC_size, |
| 516 | tls->client_write_MAC_key, sizeof(tls->client_write_MAC_key), | 553 | &tls->write_seq64_be, sizeof(tls->write_seq64_be), |
| 517 | &tls->write_seq64_be, sizeof(tls->write_seq64_be), | 554 | xhdr, RECHDR_LEN, |
| 518 | xhdr, RECHDR_LEN, | 555 | buf, size, |
| 519 | buf, size, | 556 | NULL |
| 520 | NULL); | 557 | ); |
| 521 | tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(tls->write_seq64_be)); | 558 | tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(tls->write_seq64_be)); |
| 522 | 559 | ||
| 523 | size += SHA256_OUTSIZE; | 560 | size += tls->MAC_size; |
| 524 | 561 | ||
| 525 | // RFC 5246 | 562 | // RFC 5246 |
| 526 | // 6.2.3.1. Null or Standard Stream Cipher | 563 | // 6.2.3.1. Null or Standard Stream Cipher |
| @@ -555,7 +592,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
| 555 | // -------- ----------- ---------- -------------- | 592 | // -------- ----------- ---------- -------------- |
| 556 | // SHA HMAC-SHA1 20 20 | 593 | // SHA HMAC-SHA1 20 20 |
| 557 | // SHA256 HMAC-SHA256 32 32 | 594 | // SHA256 HMAC-SHA256 32 32 |
| 558 | if (CIPHER_ID == TLS_RSA_WITH_NULL_SHA256) { | 595 | if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256) { |
| 559 | /* No encryption, only signing */ | 596 | /* No encryption, only signing */ |
| 560 | xhdr->len16_hi = size >> 8; | 597 | xhdr->len16_hi = size >> 8; |
| 561 | xhdr->len16_lo = size & 0xff; | 598 | xhdr->len16_lo = size & 0xff; |
| @@ -603,7 +640,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
| 603 | 640 | ||
| 604 | /* Fill IV and padding in outbuf */ | 641 | /* Fill IV and padding in outbuf */ |
| 605 | tls_get_random(buf - AES_BLOCKSIZE, AES_BLOCKSIZE); /* IV */ | 642 | tls_get_random(buf - AES_BLOCKSIZE, AES_BLOCKSIZE); /* IV */ |
| 606 | dbg("before crypt: 5 hdr + %u data + %u hash bytes\n", size, SHA256_OUTSIZE); | 643 | dbg("before crypt: 5 hdr + %u data + %u hash bytes\n", size, tls->MAC_size); |
| 607 | // RFC is talking nonsense: | 644 | // RFC is talking nonsense: |
| 608 | // "Padding that is added to force the length of the plaintext to be | 645 | // "Padding that is added to force the length of the plaintext to be |
| 609 | // an integral multiple of the block cipher's block length." | 646 | // an integral multiple of the block cipher's block length." |
| @@ -628,7 +665,7 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
| 628 | { | 665 | { |
| 629 | psCipherContext_t ctx; | 666 | psCipherContext_t ctx; |
| 630 | psAesInit(&ctx, buf - AES_BLOCKSIZE, /* IV */ | 667 | psAesInit(&ctx, buf - AES_BLOCKSIZE, /* IV */ |
| 631 | tls->client_write_key, sizeof(tls->client_write_key) | 668 | tls->client_write_key, tls->key_size /* selects 128/256 */ |
| 632 | ); | 669 | ); |
| 633 | psAesEncrypt(&ctx, | 670 | psAesEncrypt(&ctx, |
| 634 | buf, /* plaintext */ | 671 | buf, /* plaintext */ |
| @@ -648,9 +685,9 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
| 648 | dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); | 685 | dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); |
| 649 | } | 686 | } |
| 650 | 687 | ||
| 651 | static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size) | 688 | static void xwrite_handshake_record(tls_state_t *tls, unsigned size) |
| 652 | { | 689 | { |
| 653 | if (!tls->encrypt_on_write) { | 690 | //if (!tls->encrypt_on_write) { |
| 654 | uint8_t *buf = tls->outbuf + OUTBUF_PFX; | 691 | uint8_t *buf = tls->outbuf + OUTBUF_PFX; |
| 655 | struct record_hdr *xhdr = (void*)(buf - RECHDR_LEN); | 692 | struct record_hdr *xhdr = (void*)(buf - RECHDR_LEN); |
| 656 | 693 | ||
| @@ -662,8 +699,20 @@ static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size) | |||
| 662 | dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); | 699 | dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); |
| 663 | xwrite(tls->ofd, xhdr, RECHDR_LEN + size); | 700 | xwrite(tls->ofd, xhdr, RECHDR_LEN + size); |
| 664 | dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); | 701 | dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); |
| 702 | // return; | ||
| 703 | //} | ||
| 704 | //xwrite_encrypted(tls, size, RECORD_TYPE_HANDSHAKE); | ||
| 705 | } | ||
| 706 | |||
| 707 | static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size) | ||
| 708 | { | ||
| 709 | if (!tls->encrypt_on_write) { | ||
| 710 | uint8_t *buf; | ||
| 711 | |||
| 712 | xwrite_handshake_record(tls, size); | ||
| 665 | /* Handshake hash does not include record headers */ | 713 | /* Handshake hash does not include record headers */ |
| 666 | sha256_hash_dbg(">> sha256:%s", &tls->hsd->handshake_sha256_ctx, buf, size); | 714 | buf = tls->outbuf + OUTBUF_PFX; |
| 715 | hash_handshake(tls, ">> hash:%s", buf, size); | ||
| 667 | return; | 716 | return; |
| 668 | } | 717 | } |
| 669 | xwrite_encrypted(tls, size, RECORD_TYPE_HANDSHAKE); | 718 | xwrite_encrypted(tls, size, RECORD_TYPE_HANDSHAKE); |
| @@ -765,7 +814,7 @@ static int tls_xread_record(tls_state_t *tls) | |||
| 765 | sz = target - RECHDR_LEN; | 814 | sz = target - RECHDR_LEN; |
| 766 | 815 | ||
| 767 | /* Needs to be decrypted? */ | 816 | /* Needs to be decrypted? */ |
| 768 | if (tls->min_encrypted_len_on_read > SHA256_OUTSIZE) { | 817 | if (tls->min_encrypted_len_on_read > tls->MAC_size) { |
| 769 | psCipherContext_t ctx; | 818 | psCipherContext_t ctx; |
| 770 | uint8_t *p = tls->inbuf + RECHDR_LEN; | 819 | uint8_t *p = tls->inbuf + RECHDR_LEN; |
| 771 | int padding_len; | 820 | int padding_len; |
| @@ -777,7 +826,7 @@ static int tls_xread_record(tls_state_t *tls) | |||
| 777 | } | 826 | } |
| 778 | /* Decrypt content+MAC+padding, moving it over IV in the process */ | 827 | /* Decrypt content+MAC+padding, moving it over IV in the process */ |
| 779 | psAesInit(&ctx, p, /* IV */ | 828 | psAesInit(&ctx, p, /* IV */ |
| 780 | tls->server_write_key, sizeof(tls->server_write_key) | 829 | tls->server_write_key, tls->key_size /* selects 128/256 */ |
| 781 | ); | 830 | ); |
| 782 | sz -= AES_BLOCKSIZE; /* we will overwrite IV now */ | 831 | sz -= AES_BLOCKSIZE; /* we will overwrite IV now */ |
| 783 | psAesDecrypt(&ctx, | 832 | psAesDecrypt(&ctx, |
| @@ -788,7 +837,7 @@ static int tls_xread_record(tls_state_t *tls) | |||
| 788 | padding_len = p[sz - 1]; | 837 | padding_len = p[sz - 1]; |
| 789 | dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[0], padding_len); | 838 | dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[0], padding_len); |
| 790 | padding_len++; | 839 | padding_len++; |
| 791 | sz -= SHA256_OUTSIZE + padding_len; /* drop MAC and padding */ | 840 | sz -= tls->MAC_size + padding_len; /* drop MAC and padding */ |
| 792 | //if (sz < 0) | 841 | //if (sz < 0) |
| 793 | // bb_error_msg_and_die("bad padding size:%u", padding_len); | 842 | // bb_error_msg_and_die("bad padding size:%u", padding_len); |
| 794 | } else { | 843 | } else { |
| @@ -834,8 +883,10 @@ static int tls_xread_record(tls_state_t *tls) | |||
| 834 | /* RFC 5246 is not saying it explicitly, but sha256 hash | 883 | /* RFC 5246 is not saying it explicitly, but sha256 hash |
| 835 | * in our FINISHED record must include data of incoming packets too! | 884 | * in our FINISHED record must include data of incoming packets too! |
| 836 | */ | 885 | */ |
| 837 | if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE) { | 886 | if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE |
| 838 | sha256_hash_dbg("<< sha256:%s", &tls->hsd->handshake_sha256_ctx, tls->inbuf + RECHDR_LEN, sz); | 887 | && tls->MAC_size != 0 /* do we know which hash to use? (server_hello() does not!) */ |
| 888 | ) { | ||
| 889 | hash_handshake(tls, "<< hash:%s", tls->inbuf + RECHDR_LEN, sz); | ||
| 839 | } | 890 | } |
| 840 | end: | 891 | end: |
| 841 | dbg("got block len:%u\n", sz); | 892 | dbg("got block len:%u\n", sz); |
| @@ -1088,7 +1139,7 @@ static ALWAYS_INLINE void fill_handshake_record_hdr(void *buf, unsigned type, un | |||
| 1088 | h->len24_lo = len & 0xff; | 1139 | h->len24_lo = len & 0xff; |
| 1089 | } | 1140 | } |
| 1090 | 1141 | ||
| 1091 | static void send_client_hello(tls_state_t *tls, const char *sni) | 1142 | static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) |
| 1092 | { | 1143 | { |
| 1093 | struct client_hello { | 1144 | struct client_hello { |
| 1094 | uint8_t type; | 1145 | uint8_t type; |
| @@ -1098,7 +1149,7 @@ static void send_client_hello(tls_state_t *tls, const char *sni) | |||
| 1098 | uint8_t session_id_len; | 1149 | uint8_t session_id_len; |
| 1099 | /* uint8_t session_id[]; */ | 1150 | /* uint8_t session_id[]; */ |
| 1100 | uint8_t cipherid_len16_hi, cipherid_len16_lo; | 1151 | uint8_t cipherid_len16_hi, cipherid_len16_lo; |
| 1101 | uint8_t cipherid[2 * 2]; /* actually variable */ | 1152 | uint8_t cipherid[2 * (2 + !!CIPHER_ID2)]; /* actually variable */ |
| 1102 | uint8_t comprtypes_len; | 1153 | uint8_t comprtypes_len; |
| 1103 | uint8_t comprtypes[1]; /* actually variable */ | 1154 | uint8_t comprtypes[1]; /* actually variable */ |
| 1104 | /* Extensions (SNI shown): | 1155 | /* Extensions (SNI shown): |
| @@ -1136,17 +1187,19 @@ static void send_client_hello(tls_state_t *tls, const char *sni) | |||
| 1136 | tls_get_random(record->rand32, sizeof(record->rand32)); | 1187 | tls_get_random(record->rand32, sizeof(record->rand32)); |
| 1137 | if (TLS_DEBUG_FIXED_SECRETS) | 1188 | if (TLS_DEBUG_FIXED_SECRETS) |
| 1138 | memset(record->rand32, 0x11, sizeof(record->rand32)); | 1189 | memset(record->rand32, 0x11, sizeof(record->rand32)); |
| 1139 | memcpy(tls->hsd->client_and_server_rand32, record->rand32, sizeof(record->rand32)); | ||
| 1140 | /* record->session_id_len = 0; - already is */ | 1190 | /* record->session_id_len = 0; - already is */ |
| 1141 | 1191 | ||
| 1142 | /* record->cipherid_len16_hi = 0; */ | 1192 | /* record->cipherid_len16_hi = 0; */ |
| 1143 | record->cipherid_len16_lo = 2 * 2; | 1193 | record->cipherid_len16_lo = sizeof(record->cipherid); |
| 1144 | if ((CIPHER_ID >> 8) != 0) | ||
| 1145 | record->cipherid[0] = CIPHER_ID >> 8; | ||
| 1146 | record->cipherid[1] = CIPHER_ID & 0xff; | ||
| 1147 | /* RFC 5746 Renegotiation Indication Extension - some servers will refuse to work with us otherwise */ | 1194 | /* RFC 5746 Renegotiation Indication Extension - some servers will refuse to work with us otherwise */ |
| 1148 | /*record->cipherid[2] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV >> 8; - zero */ | 1195 | /*record->cipherid[0] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV >> 8; - zero */ |
| 1149 | record->cipherid[3] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV & 0xff; | 1196 | record->cipherid[1] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV & 0xff; |
| 1197 | if ((CIPHER_ID1 >> 8) != 0) record->cipherid[2] = CIPHER_ID1 >> 8; | ||
| 1198 | /*************************/ record->cipherid[3] = CIPHER_ID1 & 0xff; | ||
| 1199 | #if CIPHER_ID2 | ||
| 1200 | if ((CIPHER_ID2 >> 8) != 0) record->cipherid[4] = CIPHER_ID2 >> 8; | ||
| 1201 | /*************************/ record->cipherid[5] = CIPHER_ID2 & 0xff; | ||
| 1202 | #endif | ||
| 1150 | 1203 | ||
| 1151 | record->comprtypes_len = 1; | 1204 | record->comprtypes_len = 1; |
| 1152 | /* record->comprtypes[0] = 0; */ | 1205 | /* record->comprtypes[0] = 0; */ |
| @@ -1168,7 +1221,14 @@ static void send_client_hello(tls_state_t *tls, const char *sni) | |||
| 1168 | } | 1221 | } |
| 1169 | 1222 | ||
| 1170 | dbg(">> CLIENT_HELLO\n"); | 1223 | dbg(">> CLIENT_HELLO\n"); |
| 1171 | xwrite_and_update_handshake_hash(tls, len); | 1224 | /* Can hash it only when we know which MAC hash to use */ |
| 1225 | /*xwrite_and_update_handshake_hash(tls, len); - WRONG! */ | ||
| 1226 | xwrite_handshake_record(tls, len); | ||
| 1227 | |||
| 1228 | tls->hsd = xzalloc(sizeof(*tls->hsd) + len); | ||
| 1229 | tls->hsd->saved_client_hello_size = len; | ||
| 1230 | memcpy(tls->hsd->saved_client_hello, record, len); | ||
| 1231 | memcpy(tls->hsd->client_and_server_rand32, record->rand32, sizeof(record->rand32)); | ||
| 1172 | } | 1232 | } |
| 1173 | 1233 | ||
| 1174 | static void get_server_hello(tls_state_t *tls) | 1234 | static void get_server_hello(tls_state_t *tls) |
| @@ -1188,7 +1248,8 @@ static void get_server_hello(tls_state_t *tls) | |||
| 1188 | 1248 | ||
| 1189 | struct server_hello *hp; | 1249 | struct server_hello *hp; |
| 1190 | uint8_t *cipherid; | 1250 | uint8_t *cipherid; |
| 1191 | int len; | 1251 | unsigned cipher; |
| 1252 | int len, len24; | ||
| 1192 | 1253 | ||
| 1193 | len = tls_xread_handshake_block(tls, 74); | 1254 | len = tls_xread_handshake_block(tls, 74); |
| 1194 | 1255 | ||
| @@ -1207,6 +1268,7 @@ static void get_server_hello(tls_state_t *tls) | |||
| 1207 | } | 1268 | } |
| 1208 | 1269 | ||
| 1209 | cipherid = &hp->cipherid_hi; | 1270 | cipherid = &hp->cipherid_hi; |
| 1271 | len24 = hp->len24_lo; | ||
| 1210 | if (hp->session_id_len != 32) { | 1272 | if (hp->session_id_len != 32) { |
| 1211 | if (hp->session_id_len != 0) | 1273 | if (hp->session_id_len != 0) |
| 1212 | tls_error_die(tls); | 1274 | tls_error_die(tls); |
| @@ -1216,19 +1278,39 @@ static void get_server_hello(tls_state_t *tls) | |||
| 1216 | // may return an empty session_id to indicate that the session will | 1278 | // may return an empty session_id to indicate that the session will |
| 1217 | // not be cached and therefore cannot be resumed." | 1279 | // not be cached and therefore cannot be resumed." |
| 1218 | cipherid -= 32; | 1280 | cipherid -= 32; |
| 1219 | hp->len24_lo += 32; /* what len would be if session id would be present */ | 1281 | len24 += 32; /* what len would be if session id would be present */ |
| 1220 | } | 1282 | } |
| 1221 | 1283 | ||
| 1222 | if (hp->len24_lo < 70 | 1284 | if (len24 < 70 |
| 1223 | || cipherid[0] != (CIPHER_ID >> 8) | 1285 | // || cipherid[0] != (CIPHER_ID >> 8) |
| 1224 | || cipherid[1] != (CIPHER_ID & 0xff) | 1286 | // || cipherid[1] != (CIPHER_ID & 0xff) |
| 1225 | || cipherid[2] != 0 /* comprtype */ | 1287 | // || cipherid[2] != 0 /* comprtype */ |
| 1226 | ) { | 1288 | ) { |
| 1227 | tls_error_die(tls); | 1289 | tls_error_die(tls); |
| 1228 | } | 1290 | } |
| 1229 | |||
| 1230 | dbg("<< SERVER_HELLO\n"); | 1291 | dbg("<< SERVER_HELLO\n"); |
| 1292 | |||
| 1231 | memcpy(tls->hsd->client_and_server_rand32 + 32, hp->rand32, sizeof(hp->rand32)); | 1293 | memcpy(tls->hsd->client_and_server_rand32 + 32, hp->rand32, sizeof(hp->rand32)); |
| 1294 | |||
| 1295 | tls->cipher_id = cipher = 0x100 * cipherid[0] + cipherid[1]; | ||
| 1296 | dbg("server chose cipher %04x\n", cipher); | ||
| 1297 | |||
| 1298 | if (cipher == TLS_RSA_WITH_AES_128_CBC_SHA) { | ||
| 1299 | tls->key_size = AES128_KEYSIZE; | ||
| 1300 | tls->MAC_size = SHA1_OUTSIZE; | ||
| 1301 | sha1_begin(&tls->hsd->handshake_hash_ctx); | ||
| 1302 | } | ||
| 1303 | else { /* TLS_RSA_WITH_AES_256_CBC_SHA256 */ | ||
| 1304 | tls->key_size = AES256_KEYSIZE; | ||
| 1305 | tls->MAC_size = SHA256_OUTSIZE; | ||
| 1306 | sha256_begin(&tls->hsd->handshake_hash_ctx); | ||
| 1307 | } | ||
| 1308 | hash_handshake(tls, ">> client hello hash:%s", | ||
| 1309 | tls->hsd->saved_client_hello, tls->hsd->saved_client_hello_size | ||
| 1310 | ); | ||
| 1311 | hash_handshake(tls, "<< server hello hash:%s", | ||
| 1312 | tls->inbuf + RECHDR_LEN, len | ||
| 1313 | ); | ||
| 1232 | } | 1314 | } |
| 1233 | 1315 | ||
| 1234 | static void get_server_cert(tls_state_t *tls) | 1316 | static void get_server_cert(tls_state_t *tls) |
| @@ -1312,7 +1394,7 @@ static void send_client_key_exchange(tls_state_t *tls) | |||
| 1312 | // [0..47]; | 1394 | // [0..47]; |
| 1313 | // The master secret is always exactly 48 bytes in length. The length | 1395 | // The master secret is always exactly 48 bytes in length. The length |
| 1314 | // of the premaster secret will vary depending on key exchange method. | 1396 | // of the premaster secret will vary depending on key exchange method. |
| 1315 | prf_hmac_sha256( | 1397 | prf_hmac(tls, |
| 1316 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), | 1398 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), |
| 1317 | rsa_premaster, sizeof(rsa_premaster), | 1399 | rsa_premaster, sizeof(rsa_premaster), |
| 1318 | "master secret", | 1400 | "master secret", |
| @@ -1360,21 +1442,23 @@ static void send_client_key_exchange(tls_state_t *tls) | |||
| 1360 | memcpy(&tmp64[0] , &tls->hsd->client_and_server_rand32[32], 32); | 1442 | memcpy(&tmp64[0] , &tls->hsd->client_and_server_rand32[32], 32); |
| 1361 | memcpy(&tmp64[32], &tls->hsd->client_and_server_rand32[0] , 32); | 1443 | memcpy(&tmp64[32], &tls->hsd->client_and_server_rand32[0] , 32); |
| 1362 | 1444 | ||
| 1363 | prf_hmac_sha256( | 1445 | prf_hmac(tls, |
| 1364 | tls->client_write_MAC_key, 2 * (SHA256_OUTSIZE + AES256_KEYSIZE), | 1446 | tls->client_write_MAC_key, 2 * (tls->MAC_size + tls->key_size), |
| 1365 | // also fills: | 1447 | // also fills: |
| 1366 | // server_write_MAC_key[SHA256_OUTSIZE] | 1448 | // server_write_MAC_key[] |
| 1367 | // client_write_key[AES256_KEYSIZE] | 1449 | // client_write_key[] |
| 1368 | // server_write_key[AES256_KEYSIZE] | 1450 | // server_write_key[] |
| 1369 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), | 1451 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), |
| 1370 | "key expansion", | 1452 | "key expansion", |
| 1371 | tmp64, 64 | 1453 | tmp64, 64 |
| 1372 | ); | 1454 | ); |
| 1455 | tls->client_write_key = tls->client_write_MAC_key + (2 * tls->MAC_size); | ||
| 1456 | tls->server_write_key = tls->client_write_key + tls->key_size; | ||
| 1373 | dump_hex("client_write_MAC_key:%s\n", | 1457 | dump_hex("client_write_MAC_key:%s\n", |
| 1374 | tls->client_write_MAC_key, sizeof(tls->client_write_MAC_key) | 1458 | tls->client_write_MAC_key, tls->MAC_size |
| 1375 | ); | 1459 | ); |
| 1376 | dump_hex("client_write_key:%s\n", | 1460 | dump_hex("client_write_key:%s\n", |
| 1377 | tls->client_write_key, sizeof(tls->client_write_key) | 1461 | tls->client_write_key, tls->key_size |
| 1378 | ); | 1462 | ); |
| 1379 | } | 1463 | } |
| 1380 | } | 1464 | } |
| @@ -1435,15 +1519,17 @@ static void send_client_finished(tls_state_t *tls) | |||
| 1435 | uint8_t prf_result[12]; | 1519 | uint8_t prf_result[12]; |
| 1436 | }; | 1520 | }; |
| 1437 | struct finished *record = tls_get_outbuf(tls, sizeof(*record)); | 1521 | struct finished *record = tls_get_outbuf(tls, sizeof(*record)); |
| 1438 | uint8_t handshake_hash[SHA256_OUTSIZE]; | 1522 | uint8_t handshake_hash[TLS_MAX_MAC_SIZE]; |
| 1523 | unsigned len; | ||
| 1439 | 1524 | ||
| 1440 | fill_handshake_record_hdr(record, HANDSHAKE_FINISHED, sizeof(*record)); | 1525 | fill_handshake_record_hdr(record, HANDSHAKE_FINISHED, sizeof(*record)); |
| 1441 | 1526 | ||
| 1442 | sha256_peek(&tls->hsd->handshake_sha256_ctx, handshake_hash); | 1527 | len = get_handshake_hash(tls, handshake_hash); |
| 1443 | prf_hmac_sha256(record->prf_result, sizeof(record->prf_result), | 1528 | prf_hmac(tls, |
| 1444 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), | 1529 | record->prf_result, sizeof(record->prf_result), |
| 1445 | "client finished", | 1530 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), |
| 1446 | handshake_hash, sizeof(handshake_hash) | 1531 | "client finished", |
| 1532 | handshake_hash, len | ||
| 1447 | ); | 1533 | ); |
| 1448 | dump_hex("from secret: %s\n", tls->hsd->master_secret, sizeof(tls->hsd->master_secret)); | 1534 | dump_hex("from secret: %s\n", tls->hsd->master_secret, sizeof(tls->hsd->master_secret)); |
| 1449 | dump_hex("from labelSeed: %s", "client finished", sizeof("client finished")-1); | 1535 | dump_hex("from labelSeed: %s", "client finished", sizeof("client finished")-1); |
| @@ -1475,10 +1561,7 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | |||
| 1475 | // Application Data <------> Application Data | 1561 | // Application Data <------> Application Data |
| 1476 | int len; | 1562 | int len; |
| 1477 | 1563 | ||
| 1478 | tls->hsd = xzalloc(sizeof(*tls->hsd)); | 1564 | send_client_hello_and_alloc_hsd(tls, sni); |
| 1479 | sha256_begin(&tls->hsd->handshake_sha256_ctx); | ||
| 1480 | |||
| 1481 | send_client_hello(tls, sni); | ||
| 1482 | get_server_hello(tls); | 1565 | get_server_hello(tls); |
| 1483 | 1566 | ||
| 1484 | // RFC 5246 | 1567 | // RFC 5246 |
| @@ -1535,11 +1618,11 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | |||
| 1535 | if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) | 1618 | if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) |
| 1536 | tls_error_die(tls); | 1619 | tls_error_die(tls); |
| 1537 | dbg("<< CHANGE_CIPHER_SPEC\n"); | 1620 | dbg("<< CHANGE_CIPHER_SPEC\n"); |
| 1538 | if (CIPHER_ID == TLS_RSA_WITH_NULL_SHA256) | 1621 | if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256) |
| 1539 | tls->min_encrypted_len_on_read = SHA256_OUTSIZE; | 1622 | tls->min_encrypted_len_on_read = tls->MAC_size; |
| 1540 | else | 1623 | else |
| 1541 | /* all incoming packets now should be encrypted and have IV + MAC + padding */ | 1624 | /* all incoming packets now should be encrypted and have IV + MAC + padding */ |
| 1542 | tls->min_encrypted_len_on_read = AES_BLOCKSIZE + SHA256_OUTSIZE + AES_BLOCKSIZE; | 1625 | tls->min_encrypted_len_on_read = AES_BLOCKSIZE + tls->MAC_size + AES_BLOCKSIZE; |
| 1543 | 1626 | ||
| 1544 | /* Get (encrypted) FINISHED from the server */ | 1627 | /* Get (encrypted) FINISHED from the server */ |
| 1545 | len = tls_xread_record(tls); | 1628 | len = tls_xread_record(tls); |
| @@ -1550,7 +1633,7 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | |||
| 1550 | 1633 | ||
| 1551 | /* free handshake data */ | 1634 | /* free handshake data */ |
| 1552 | // if (PARANOIA) | 1635 | // if (PARANOIA) |
| 1553 | // memset(tls->hsd, 0, sizeof(*tls->hsd)); | 1636 | // memset(tls->hsd, 0, tls->hsd->hsd_size); |
| 1554 | free(tls->hsd); | 1637 | free(tls->hsd); |
| 1555 | tls->hsd = NULL; | 1638 | tls->hsd = NULL; |
| 1556 | } | 1639 | } |
| @@ -1614,8 +1697,8 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls) | |||
| 1614 | * read, encrypt and send bigger chunks | 1697 | * read, encrypt and send bigger chunks |
| 1615 | */ | 1698 | */ |
| 1616 | inbuf_size += INBUF_STEP; | 1699 | inbuf_size += INBUF_STEP; |
| 1617 | if (inbuf_size > MAX_OUTBUF) | 1700 | if (inbuf_size > TLS_MAX_OUTBUF) |
| 1618 | inbuf_size = MAX_OUTBUF; | 1701 | inbuf_size = TLS_MAX_OUTBUF; |
| 1619 | } | 1702 | } |
| 1620 | tls_xwrite(tls, nread); | 1703 | tls_xwrite(tls, nread); |
| 1621 | } | 1704 | } |
