aboutsummaryrefslogtreecommitdiff
path: root/networking/tls.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/tls.c')
-rw-r--r--networking/tls.c102
1 files changed, 37 insertions, 65 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 30afd9ea9..db518bf90 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -39,7 +39,7 @@
39 39
40// works against "openssl s_server -cipher NULL" 40// works against "openssl s_server -cipher NULL"
41// and against wolfssl-3.9.10-stable/examples/server/server.c: 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) 42//#define CIPHER_ID1 TLS_RSA_WITH_NULL_SHA256 // for testing (does everything except encrypting)
43 43
44// works against wolfssl-3.9.10-stable/examples/server/server.c 44// works against wolfssl-3.9.10-stable/examples/server/server.c
45// works for kernel.org 45// works for kernel.org
@@ -367,11 +367,12 @@ static unsigned hmac_sha_precomputed_v(
367 return sha_end(&pre->hashed_key_xor_opad, out); 367 return sha_end(&pre->hashed_key_xor_opad, out);
368} 368}
369 369
370static void hmac_sha256_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size) 370typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC;
371static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin)
371{ 372{
372 uint8_t key_xor_ipad[SHA_INSIZE]; 373 uint8_t key_xor_ipad[SHA_INSIZE];
373 uint8_t key_xor_opad[SHA_INSIZE]; 374 uint8_t key_xor_opad[SHA_INSIZE];
374 uint8_t tempkey[SHA256_OUTSIZE]; 375 uint8_t tempkey[SHA1_OUTSIZE < SHA256_OUTSIZE ? SHA256_OUTSIZE : SHA1_OUTSIZE];
375 unsigned i; 376 unsigned i;
376 377
377 // "The authentication key can be of any length up to INSIZE, the 378 // "The authentication key can be of any length up to INSIZE, the
@@ -380,7 +381,7 @@ static void hmac_sha256_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned ke
380 // resultant OUTSIZE byte string as the actual key to HMAC." 381 // resultant OUTSIZE byte string as the actual key to HMAC."
381 if (key_size > SHA_INSIZE) { 382 if (key_size > SHA_INSIZE) {
382 md5sha_ctx_t ctx; 383 md5sha_ctx_t ctx;
383 sha256_begin(&ctx); 384 begin(&ctx);
384 md5sha_hash(&ctx, key, key_size); 385 md5sha_hash(&ctx, key, key_size);
385 key_size = sha_end(&ctx, tempkey); 386 key_size = sha_end(&ctx, tempkey);
386 } 387 }
@@ -394,41 +395,8 @@ static void hmac_sha256_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned ke
394 key_xor_opad[i] = 0x5c; 395 key_xor_opad[i] = 0x5c;
395 } 396 }
396 397
397 sha256_begin(&pre->hashed_key_xor_ipad); 398 begin(&pre->hashed_key_xor_ipad);
398 sha256_begin(&pre->hashed_key_xor_opad); 399 begin(&pre->hashed_key_xor_opad);
399 md5sha_hash(&pre->hashed_key_xor_ipad, key_xor_ipad, SHA_INSIZE);
400 md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE);
401}
402// TODO: ^^^ vvv merge?
403static void hmac_sha1_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size)
404{
405 uint8_t key_xor_ipad[SHA_INSIZE];
406 uint8_t key_xor_opad[SHA_INSIZE];
407 uint8_t tempkey[SHA1_OUTSIZE];
408 unsigned i;
409
410 // "The authentication key can be of any length up to INSIZE, the
411 // block length of the hash function. Applications that use keys longer
412 // than INSIZE bytes will first hash the key using H and then use the
413 // resultant OUTSIZE byte string as the actual key to HMAC."
414 if (key_size > SHA_INSIZE) {
415 md5sha_ctx_t ctx;
416 sha1_begin(&ctx);
417 md5sha_hash(&ctx, key, key_size);
418 key_size = sha_end(&ctx, tempkey);
419 }
420
421 for (i = 0; i < key_size; i++) {
422 key_xor_ipad[i] = key[i] ^ 0x36;
423 key_xor_opad[i] = key[i] ^ 0x5c;
424 }
425 for (; i < SHA_INSIZE; i++) {
426 key_xor_ipad[i] = 0x36;
427 key_xor_opad[i] = 0x5c;
428 }
429
430 sha1_begin(&pre->hashed_key_xor_ipad);
431 sha1_begin(&pre->hashed_key_xor_opad);
432 md5sha_hash(&pre->hashed_key_xor_ipad, key_xor_ipad, SHA_INSIZE); 400 md5sha_hash(&pre->hashed_key_xor_ipad, key_xor_ipad, SHA_INSIZE);
433 md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE); 401 md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE);
434} 402}
@@ -441,11 +409,11 @@ static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_
441 409
442 va_start(va, key_size); 410 va_start(va, key_size);
443 411
444 if (tls->MAC_size == SHA256_OUTSIZE) 412 hmac_begin(&pre, key, key_size,
445 hmac_sha256_begin(&pre, key, key_size); 413 (tls->MAC_size == SHA256_OUTSIZE)
446 else 414 ? sha256_begin
447 hmac_sha1_begin(&pre, key, key_size); 415 : sha1_begin
448 416 );
449 len = hmac_sha_precomputed_v(&pre, out, va); 417 len = hmac_sha_precomputed_v(&pre, out, va);
450 418
451 va_end(va); 419 va_end(va);
@@ -460,7 +428,7 @@ static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, un
460 428
461 va_start(va, key_size); 429 va_start(va, key_size);
462 430
463 hmac_sha256_begin(&pre, key, key_size); 431 hmac_begin(&pre, key, key_size, sha256_begin);
464 len = hmac_sha_precomputed_v(&pre, out, va); 432 len = hmac_sha_precomputed_v(&pre, out, va);
465 433
466 va_end(va); 434 va_end(va);
@@ -507,7 +475,7 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/
507 uint8_t a[TLS_MAX_MAC_SIZE]; 475 uint8_t a[TLS_MAX_MAC_SIZE];
508 uint8_t *out_p = outbuf; 476 uint8_t *out_p = outbuf;
509 unsigned label_size = strlen(label); 477 unsigned label_size = strlen(label);
510 unsigned MAC_size = SHA256_OUTSIZE;///tls->MAC_size; 478 unsigned MAC_size = SHA256_OUTSIZE;
511 479
512 /* In P_hash() calculation, "seed" is "label + seed": */ 480 /* In P_hash() calculation, "seed" is "label + seed": */
513#define SEED label, label_size, seed, seed_size 481#define SEED label, label_size, seed, seed_size
@@ -518,7 +486,7 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/
518 hmac_sha256(/*tls,*/ a, SECRET, SEED, NULL); 486 hmac_sha256(/*tls,*/ a, SECRET, SEED, NULL);
519//TODO: convert hmac to precomputed 487//TODO: convert hmac to precomputed
520 488
521 for(;;) { 489 for (;;) {
522 /* HMAC_hash(secret, A(1) + seed) */ 490 /* HMAC_hash(secret, A(1) + seed) */
523 if (outbuf_size <= MAC_size) { 491 if (outbuf_size <= MAC_size) {
524 /* Last, possibly incomplete, block */ 492 /* Last, possibly incomplete, block */
@@ -597,8 +565,11 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
597 uint8_t padding_length; 565 uint8_t padding_length;
598 566
599 xhdr = (void*)(buf - RECHDR_LEN); 567 xhdr = (void*)(buf - RECHDR_LEN);
600 if (tls->cipher_id != TLS_RSA_WITH_NULL_SHA256) 568 if (CIPHER_ID1 != TLS_RSA_WITH_NULL_SHA256 /* if "no encryption" can't be selected */
569 || tls->cipher_id != TLS_RSA_WITH_NULL_SHA256 /* or if it wasn't selected */
570 ) {
601 xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCKSIZE); /* place for IV */ 571 xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCKSIZE); /* place for IV */
572 }
602 573
603 xhdr->type = type; 574 xhdr->type = type;
604 xhdr->proto_maj = TLS_MAJ; 575 xhdr->proto_maj = TLS_MAJ;
@@ -652,7 +623,9 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type)
652 // -------- ----------- ---------- -------------- 623 // -------- ----------- ---------- --------------
653 // SHA HMAC-SHA1 20 20 624 // SHA HMAC-SHA1 20 20
654 // SHA256 HMAC-SHA256 32 32 625 // SHA256 HMAC-SHA256 32 32
655 if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256) { 626 if (CIPHER_ID1 == TLS_RSA_WITH_NULL_SHA256
627 && tls->cipher_id == TLS_RSA_WITH_NULL_SHA256
628 ) {
656 /* No encryption, only signing */ 629 /* No encryption, only signing */
657 xhdr->len16_hi = size >> 8; 630 xhdr->len16_hi = size >> 8;
658 xhdr->len16_lo = size & 0xff; 631 xhdr->len16_lo = size & 0xff;
@@ -1698,9 +1671,11 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni)
1698 if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) 1671 if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0)
1699 bad_record_die(tls, "switch to encrypted traffic", len); 1672 bad_record_die(tls, "switch to encrypted traffic", len);
1700 dbg("<< CHANGE_CIPHER_SPEC\n"); 1673 dbg("<< CHANGE_CIPHER_SPEC\n");
1701 if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256) 1674 if (CIPHER_ID1 == TLS_RSA_WITH_NULL_SHA256
1675 && tls->cipher_id == TLS_RSA_WITH_NULL_SHA256
1676 ) {
1702 tls->min_encrypted_len_on_read = tls->MAC_size; 1677 tls->min_encrypted_len_on_read = tls->MAC_size;
1703 else { 1678 } else {
1704 unsigned mac_blocks = (unsigned)(tls->MAC_size + AES_BLOCKSIZE-1) / AES_BLOCKSIZE; 1679 unsigned mac_blocks = (unsigned)(tls->MAC_size + AES_BLOCKSIZE-1) / AES_BLOCKSIZE;
1705 /* all incoming packets now should be encrypted and have 1680 /* all incoming packets now should be encrypted and have
1706 * at least IV + (MAC padded to blocksize): 1681 * at least IV + (MAC padded to blocksize):
@@ -1740,26 +1715,23 @@ static void tls_xwrite(tls_state_t *tls, int len)
1740 1715
1741void FAST_FUNC tls_run_copy_loop(tls_state_t *tls) 1716void FAST_FUNC tls_run_copy_loop(tls_state_t *tls)
1742{ 1717{
1743 fd_set readfds;
1744 int inbuf_size; 1718 int inbuf_size;
1745 const int INBUF_STEP = 4 * 1024; 1719 const int INBUF_STEP = 4 * 1024;
1720 struct pollfd pfds[2];
1746 1721
1747//TODO: convert to poll 1722 pfds[0].fd = STDIN_FILENO;
1748 /* Select loop copying stdin to ofd, and ifd to stdout */ 1723 pfds[0].events = POLLIN;
1749 FD_ZERO(&readfds); 1724 pfds[1].fd = tls->ifd;
1750 FD_SET(tls->ifd, &readfds); 1725 pfds[1].events = POLLIN;
1751 FD_SET(STDIN_FILENO, &readfds);
1752 1726
1753 inbuf_size = INBUF_STEP; 1727 inbuf_size = INBUF_STEP;
1754 for (;;) { 1728 for (;;) {
1755 fd_set testfds;
1756 int nread; 1729 int nread;
1757 1730
1758 testfds = readfds; 1731 if (safe_poll(pfds, 2, -1) < 0)
1759 if (select(tls->ifd + 1, &testfds, NULL, NULL, NULL) < 0) 1732 bb_perror_msg_and_die("poll");
1760 bb_perror_msg_and_die("select");
1761 1733
1762 if (FD_ISSET(STDIN_FILENO, &testfds)) { 1734 if (pfds[0].revents) {
1763 void *buf; 1735 void *buf;
1764 1736
1765 dbg("STDIN HAS DATA\n"); 1737 dbg("STDIN HAS DATA\n");
@@ -1774,7 +1746,7 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls)
1774 /* But TLS has no way to encode this, 1746 /* But TLS has no way to encode this,
1775 * doubt it's ok to do it "raw" 1747 * doubt it's ok to do it "raw"
1776 */ 1748 */
1777 FD_CLR(STDIN_FILENO, &readfds); 1749 pfds[0].fd = -1;
1778 tls_free_outbuf(tls); /* mem usage optimization */ 1750 tls_free_outbuf(tls); /* mem usage optimization */
1779 } else { 1751 } else {
1780 if (nread == inbuf_size) { 1752 if (nread == inbuf_size) {
@@ -1788,7 +1760,7 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls)
1788 tls_xwrite(tls, nread); 1760 tls_xwrite(tls, nread);
1789 } 1761 }
1790 } 1762 }
1791 if (FD_ISSET(tls->ifd, &testfds)) { 1763 if (pfds[1].revents) {
1792 dbg("NETWORK HAS DATA\n"); 1764 dbg("NETWORK HAS DATA\n");
1793 read_record: 1765 read_record:
1794 nread = tls_xread_record(tls); 1766 nread = tls_xread_record(tls);
@@ -1796,7 +1768,7 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls)
1796 /* TLS protocol has no real concept of one-sided shutdowns: 1768 /* TLS protocol has no real concept of one-sided shutdowns:
1797 * if we get "TLS EOF" from the peer, writes will fail too 1769 * if we get "TLS EOF" from the peer, writes will fail too
1798 */ 1770 */
1799 //FD_CLR(tls->ifd, &readfds); 1771 //pfds[1].fd = -1;
1800 //close(STDOUT_FILENO); 1772 //close(STDOUT_FILENO);
1801 //tls_free_inbuf(tls); /* mem usage optimization */ 1773 //tls_free_inbuf(tls); /* mem usage optimization */
1802 //continue; 1774 //continue;