diff options
Diffstat (limited to 'networking/tls.c')
-rw-r--r-- | networking/tls.c | 102 |
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 | ||
370 | static void hmac_sha256_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size) | 370 | typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC; |
371 | static 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? | ||
403 | static 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 | ||
1741 | void FAST_FUNC tls_run_copy_loop(tls_state_t *tls) | 1716 | void 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; |