aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
Diffstat (limited to 'networking')
-rw-r--r--networking/Config.src3
-rw-r--r--networking/ftpd.c39
-rw-r--r--networking/hostname.c4
-rw-r--r--networking/httpd.c2
-rw-r--r--networking/libiproute/iproute.c16
-rw-r--r--networking/ntpd.c6
-rw-r--r--networking/telnetd.c4
-rw-r--r--networking/tftp.c2
-rw-r--r--networking/tls.c906
-rw-r--r--networking/tls.h6
-rw-r--r--networking/tls_aesgcm.c5
11 files changed, 358 insertions, 635 deletions
diff --git a/networking/Config.src b/networking/Config.src
index d5fc9d377..aa0806a18 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -84,7 +84,7 @@ config FEATURE_TLS_INTERNAL
84 84
85config FEATURE_TLS_SCHANNEL 85config FEATURE_TLS_SCHANNEL
86 bool "Schannel SSP" 86 bool "Schannel SSP"
87 depends on TLS 87 depends on TLS && PLATFORM_MINGW32
88 help 88 help
89 Use the Schannel SSP to provide TLS support. 89 Use the Schannel SSP to provide TLS support.
90 Reduces code size and enables certificate checking. 90 Reduces code size and enables certificate checking.
@@ -113,7 +113,6 @@ config FEATURE_TLS_SCHANNEL_1_3
113 113
114INSERT 114INSERT
115 115
116
117source networking/udhcp/Config.in 116source networking/udhcp/Config.in
118 117
119config IFUPDOWN_UDHCPC_CMD_OPTIONS 118config IFUPDOWN_UDHCPC_CMD_OPTIONS
diff --git a/networking/ftpd.c b/networking/ftpd.c
index 0d6a289c7..c3125410e 100644
--- a/networking/ftpd.c
+++ b/networking/ftpd.c
@@ -190,54 +190,39 @@ struct globals {
190} while (0) 190} while (0)
191 191
192 192
193/* escape_text("pfx:", str, (0xff << 8) + '\r')
194 * Duplicate 0xff, append \r ^^^^^^^^^^^^^^^^^^
195 */
193static char * 196static char *
194escape_text(const char *prepend, const char *str, unsigned escapee) 197escape_text(const char *prepend, const char *str, unsigned escapee)
195{ 198{
196 unsigned retlen, remainlen, chunklen; 199 char *ret, *p;
197 char *ret, *found;
198 char append; 200 char append;
199 201
200 append = (char)escapee; 202 append = (char)escapee;
201 escapee >>= 8; 203 escapee >>= 8;
202 204
203 remainlen = strlen(str); 205 ret = xmalloc(strlen(prepend) + strlen(str) * 2 + 1 + 1);
204 retlen = strlen(prepend); 206 p = stpcpy(ret, prepend);
205 ret = xmalloc(retlen + remainlen * 2 + 1 + 1);
206 strcpy(ret, prepend);
207 207
208 for (;;) { 208 for (;;) {
209 found = strchrnul(str, escapee); 209 char *found = strchrnul(str, escapee);
210 chunklen = found - str + 1;
211 210
212 /* Copy chunk up to and including escapee (or NUL) to ret */ 211 /* Copy up to and including escapee (or NUL) */
213 memcpy(ret + retlen, str, chunklen); 212 p = mempcpy(p, str, found - str + 1);
214 retlen += chunklen;
215 213
216 if (*found == '\0') { 214 if (*found == '\0') {
217 /* It wasn't escapee, it was NUL! */ 215 /* It wasn't escapee, it was NUL! */
218 ret[retlen - 1] = append; /* replace NUL */
219 ret[retlen] = '\0'; /* add NUL */
220 break; 216 break;
221 } 217 }
222 ret[retlen++] = escapee; /* duplicate escapee */
223 str = found + 1; 218 str = found + 1;
219 *p++ = escapee; /* duplicate escapee */
224 } 220 }
221 p[-1] = append; /* replace NUL */
222 *p = '\0'; /* add NUL */
225 return ret; 223 return ret;
226} 224}
227 225
228/* Returns strlen as a bonus */
229static unsigned
230replace_char(char *str, char from, char to)
231{
232 char *p = str;
233 while (*p) {
234 if (*p == from)
235 *p = to;
236 p++;
237 }
238 return p - str;
239}
240
241static void 226static void
242verbose_log(const char *str) 227verbose_log(const char *str)
243{ 228{
diff --git a/networking/hostname.c b/networking/hostname.c
index 36cb70866..101b89e77 100644
--- a/networking/hostname.c
+++ b/networking/hostname.c
@@ -25,8 +25,8 @@
25//applet:IF_DNSDOMAINNAME(APPLET_NOEXEC(dnsdomainname, hostname, BB_DIR_BIN, BB_SUID_DROP, dnsdomainname)) 25//applet:IF_DNSDOMAINNAME(APPLET_NOEXEC(dnsdomainname, hostname, BB_DIR_BIN, BB_SUID_DROP, dnsdomainname))
26//applet:IF_HOSTNAME( APPLET_NOEXEC(hostname, hostname, BB_DIR_BIN, BB_SUID_DROP, hostname )) 26//applet:IF_HOSTNAME( APPLET_NOEXEC(hostname, hostname, BB_DIR_BIN, BB_SUID_DROP, hostname ))
27 27
28//kbuild: lib-$(CONFIG_HOSTNAME) += hostname.o 28//kbuild:lib-$(CONFIG_HOSTNAME) += hostname.o
29//kbuild: lib-$(CONFIG_DNSDOMAINNAME) += hostname.o 29//kbuild:lib-$(CONFIG_DNSDOMAINNAME) += hostname.o
30 30
31//usage:#define hostname_trivial_usage 31//usage:#define hostname_trivial_usage
32//usage: "[-sidf] [HOSTNAME | -F FILE]" 32//usage: "[-sidf] [HOSTNAME | -F FILE]"
diff --git a/networking/httpd.c b/networking/httpd.c
index 1dae602ee..50595104c 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -3074,7 +3074,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv)
3074 salt[0] = '$'; 3074 salt[0] = '$';
3075 salt[1] = '1'; 3075 salt[1] = '1';
3076 salt[2] = '$'; 3076 salt[2] = '$';
3077 crypt_make_salt(salt + 3, 4); 3077 crypt_make_rand64encoded(salt + 3, 8 / 2); /* 8 chars */
3078 puts(pw_encrypt(pass, salt, /*cleanup:*/ 0)); 3078 puts(pw_encrypt(pass, salt, /*cleanup:*/ 0));
3079 return 0; 3079 return 0;
3080 } 3080 }
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index cd77f642f..a30f070eb 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -302,24 +302,22 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
302 printf("notify "); 302 printf("notify ");
303 } 303 }
304 304
305 if (r->rtm_family == AF_INET6) { 305 if (r->rtm_family == AF_INET || r->rtm_family == AF_INET6) {
306 struct rta_cacheinfo *ci = NULL; 306 if (r->rtm_family == AF_INET) {
307 if (tb[RTA_CACHEINFO]) {
308 ci = RTA_DATA(tb[RTA_CACHEINFO]);
309 }
310 if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) {
311 if (r->rtm_flags & RTM_F_CLONED) { 307 if (r->rtm_flags & RTM_F_CLONED) {
312 printf("%c cache ", _SL_); 308 printf("%c cache ", _SL_);
309 /* upstream: print_cache_flags() prints more here */
313 } 310 }
311 }
312 if (tb[RTA_CACHEINFO]) {
313 struct rta_cacheinfo *ci = RTA_DATA(tb[RTA_CACHEINFO]);
314 if (ci->rta_expires) { 314 if (ci->rta_expires) {
315 printf(" expires %dsec", ci->rta_expires / get_hz()); 315 printf(" expires %dsec", ci->rta_expires / get_hz());
316 } 316 }
317 if (ci->rta_error != 0) { 317 if (ci->rta_error != 0) {
318 printf(" error %d", ci->rta_error); 318 printf(" error %d", ci->rta_error);
319 } 319 }
320 } else if (ci) { 320 /* upstream: print_rta_cacheinfo() prints more here */
321 if (ci->rta_error != 0)
322 printf(" error %d", ci->rta_error);
323 } 321 }
324 } 322 }
325 if (tb[RTA_IIF] && G_filter.iif == 0) { 323 if (tb[RTA_IIF] && G_filter.iif == 0) {
diff --git a/networking/ntpd.c b/networking/ntpd.c
index dcbdb8e60..dd0a9c91f 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -205,7 +205,7 @@
205#define MINDISP 0.01 /* minimum dispersion (sec) */ 205#define MINDISP 0.01 /* minimum dispersion (sec) */
206#define MAXDISP 16 /* maximum dispersion (sec) */ 206#define MAXDISP 16 /* maximum dispersion (sec) */
207#define MAXSTRAT 16 /* maximum stratum (infinity metric) */ 207#define MAXSTRAT 16 /* maximum stratum (infinity metric) */
208#define MAXDIST 1 /* distance threshold (sec) */ 208#define MAXDIST 3 /* distance threshold (sec): do not use peers who are farther away */
209#define MIN_SELECTED 1 /* minimum intersection survivors */ 209#define MIN_SELECTED 1 /* minimum intersection survivors */
210#define MIN_CLUSTERED 3 /* minimum cluster survivors */ 210#define MIN_CLUSTERED 3 /* minimum cluster survivors */
211 211
@@ -1057,7 +1057,7 @@ step_time(double offset)
1057 } 1057 }
1058 tval = tvn.tv_sec; 1058 tval = tvn.tv_sec;
1059 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval); 1059 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval);
1060 bb_info_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset); 1060 bb_error_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset);
1061 //maybe? G.FREQHOLD_cnt = 0; 1061 //maybe? G.FREQHOLD_cnt = 0;
1062 1062
1063 /* Correct various fields which contain time-relative values: */ 1063 /* Correct various fields which contain time-relative values: */
@@ -1976,7 +1976,7 @@ recv_and_process_peer_pkt(peer_t *p)
1976 1976
1977 p->reachable_bits |= 1; 1977 p->reachable_bits |= 1;
1978 if ((MAX_VERBOSE && G.verbose) || (option_mask32 & OPT_w)) { 1978 if ((MAX_VERBOSE && G.verbose) || (option_mask32 & OPT_w)) {
1979 bb_info_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x", 1979 bb_error_msg("reply from %s: offset:%+f delay:%f status:0x%02x strat:%d refid:0x%08x rootdelay:%f reach:0x%02x",
1980 p->p_dotted, 1980 p->p_dotted,
1981 offset, 1981 offset,
1982 p->p_raw_delay, 1982 p->p_raw_delay,
diff --git a/networking/telnetd.c b/networking/telnetd.c
index bfeea1400..a5a783047 100644
--- a/networking/telnetd.c
+++ b/networking/telnetd.c
@@ -104,8 +104,8 @@
104//usage:#define telnetd_full_usage "\n\n" 104//usage:#define telnetd_full_usage "\n\n"
105//usage: "Handle incoming telnet connections" 105//usage: "Handle incoming telnet connections"
106//usage: IF_NOT_FEATURE_TELNETD_STANDALONE(" via inetd") "\n" 106//usage: IF_NOT_FEATURE_TELNETD_STANDALONE(" via inetd") "\n"
107//usage: "\n -l LOGIN Exec LOGIN on connect" 107//usage: "\n -l LOGIN Exec LOGIN on connect (default /bin/login)"
108//usage: "\n -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue" 108//usage: "\n -f ISSUE_FILE Display ISSUE_FILE instead of /etc/issue.net"
109//usage: "\n -K Close connection as soon as login exits" 109//usage: "\n -K Close connection as soon as login exits"
110//usage: "\n (normally wait until all programs close slave pty)" 110//usage: "\n (normally wait until all programs close slave pty)"
111//usage: IF_FEATURE_TELNETD_STANDALONE( 111//usage: IF_FEATURE_TELNETD_STANDALONE(
diff --git a/networking/tftp.c b/networking/tftp.c
index f5b4367ca..b698a9288 100644
--- a/networking/tftp.c
+++ b/networking/tftp.c
@@ -250,7 +250,7 @@ static int tftp_blksize_check(const char *blksize_str, int maxsize)
250 return -1; 250 return -1;
251 } 251 }
252# if ENABLE_TFTP_DEBUG 252# if ENABLE_TFTP_DEBUG
253 bb_info_msg("using blksize %u", blksize); 253 bb_error_msg("using blksize %u", blksize);
254# endif 254# endif
255 return blksize; 255 return blksize;
256} 256}
diff --git a/networking/tls.c b/networking/tls.c
index b048d6eeb..c099d056f 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -22,19 +22,7 @@
22 22
23#include "tls.h" 23#include "tls.h"
24 24
25#if ENABLE_FEATURE_TLS_SCHANNEL || ENABLE_FEATURE_USE_CNG_API
26#include <windows.h>
27#endif
28
29#if !ENABLE_FEATURE_TLS_SCHANNEL 25#if !ENABLE_FEATURE_TLS_SCHANNEL
30#if ENABLE_FEATURE_USE_CNG_API
31# include <bcrypt.h>
32
33// these work on Windows >= 10
34# define BCRYPT_HMAC_SHA1_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x000000a1)
35# define BCRYPT_HMAC_SHA256_ALG_HANDLE ((BCRYPT_ALG_HANDLE) 0x000000b1)
36#endif
37
38// Usually enabled. You can disable some of them to force only 26// Usually enabled. You can disable some of them to force only
39// specific ciphers to be advertized to server. 27// specific ciphers to be advertized to server.
40// (this would not exclude code to handle disabled ciphers, no code size win) 28// (this would not exclude code to handle disabled ciphers, no code size win)
@@ -201,8 +189,6 @@
201#define TLS_MAX_OUTBUF (1 << 14) 189#define TLS_MAX_OUTBUF (1 << 14)
202 190
203enum { 191enum {
204 SHA_INSIZE = 64,
205
206 AES128_KEYSIZE = 16, 192 AES128_KEYSIZE = 16,
207 AES256_KEYSIZE = 32, 193 AES256_KEYSIZE = 32,
208 194
@@ -348,34 +334,6 @@ void FAST_FUNC tls_get_random(void *buf, unsigned len)
348 xfunc_die(); 334 xfunc_die();
349} 335}
350 336
351static void xorbuf3(void *dst, const void *src1, const void *src2, unsigned count)
352{
353 uint8_t *d = dst;
354 const uint8_t *s1 = src1;
355 const uint8_t* s2 = src2;
356 while (count--)
357 *d++ = *s1++ ^ *s2++;
358}
359
360void FAST_FUNC xorbuf(void *dst, const void *src, unsigned count)
361{
362 xorbuf3(dst, dst, src, count);
363}
364
365void FAST_FUNC xorbuf_aligned_AES_BLOCK_SIZE(void *dst, const void *src)
366{
367 unsigned long *d = dst;
368 const unsigned long *s = src;
369 d[0] ^= s[0];
370#if ULONG_MAX <= 0xffffffffffffffff
371 d[1] ^= s[1];
372 #if ULONG_MAX == 0xffffffff
373 d[2] ^= s[2];
374 d[3] ^= s[3];
375 #endif
376#endif
377}
378
379#if !TLS_DEBUG_HASH 337#if !TLS_DEBUG_HASH
380# define hash_handshake(tls, fmt, buffer, len) \ 338# define hash_handshake(tls, fmt, buffer, len) \
381 hash_handshake(tls, buffer, len) 339 hash_handshake(tls, buffer, len)
@@ -406,191 +364,6 @@ static void hash_handshake(tls_state_t *tls, const char *fmt, const void *buffer
406# define TLS_MAC_SIZE(tls) (tls)->MAC_size 364# define TLS_MAC_SIZE(tls) (tls)->MAC_size
407#endif 365#endif
408 366
409// RFC 2104:
410// HMAC(key, text) based on a hash H (say, sha256) is:
411// ipad = [0x36 x INSIZE]
412// opad = [0x5c x INSIZE]
413// HMAC(key, text) = H((key XOR opad) + H((key XOR ipad) + text))
414//
415// H(key XOR opad) and H(key XOR ipad) can be precomputed
416// if we often need HMAC hmac with the same key.
417//
418// text is often given in disjoint pieces.
419#if !ENABLE_FEATURE_USE_CNG_API
420typedef struct hmac_precomputed {
421 md5sha_ctx_t hashed_key_xor_ipad;
422 md5sha_ctx_t hashed_key_xor_opad;
423} hmac_precomputed_t;
424
425typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC;
426
427#define sha1_begin_hmac sha1_begin
428#define sha256_begin_hmac sha256_begin
429#define hmac_uninit(...) ((void)0)
430
431#if !ENABLE_FEATURE_TLS_SHA1
432#define hmac_begin(pre,key,key_size,begin) \
433 hmac_begin(pre,key,key_size)
434#define begin sha256_begin
435#endif
436
437static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin)
438{
439 uint8_t key_xor_ipad[SHA_INSIZE];
440 uint8_t key_xor_opad[SHA_INSIZE];
441// uint8_t tempkey[SHA1_OUTSIZE < SHA256_OUTSIZE ? SHA256_OUTSIZE : SHA1_OUTSIZE];
442 unsigned i;
443
444 // "The authentication key can be of any length up to INSIZE, the
445 // block length of the hash function. Applications that use keys longer
446 // than INSIZE bytes will first hash the key using H and then use the
447 // resultant OUTSIZE byte string as the actual key to HMAC."
448 if (key_size > SHA_INSIZE) {
449 bb_simple_error_msg_and_die("HMAC key>64"); //does not happen (yet?)
450// md5sha_ctx_t ctx;
451// begin(&ctx);
452// md5sha_hash(&ctx, key, key_size);
453// key_size = sha_end(&ctx, tempkey);
454// //key = tempkey; - right? RIGHT? why does it work without this?
455// // because SHA_INSIZE is 64, but hmac() is always called with
456// // key_size = tls->MAC_size = SHA1/256_OUTSIZE (20 or 32),
457// // and prf_hmac_sha256() -> hmac_sha256() key sizes are:
458// // - RSA_PREMASTER_SIZE is 48
459// // - CURVE25519_KEYSIZE is 32
460// // - master_secret[] is 48
461 }
462
463 for (i = 0; i < key_size; i++) {
464 key_xor_ipad[i] = key[i] ^ 0x36;
465 key_xor_opad[i] = key[i] ^ 0x5c;
466 }
467 for (; i < SHA_INSIZE; i++) {
468 key_xor_ipad[i] = 0x36;
469 key_xor_opad[i] = 0x5c;
470 }
471
472 begin(&pre->hashed_key_xor_ipad);
473 begin(&pre->hashed_key_xor_opad);
474 md5sha_hash(&pre->hashed_key_xor_ipad, key_xor_ipad, SHA_INSIZE);
475 md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE);
476}
477#undef begin
478
479static unsigned hmac_sha_precomputed_v(
480 hmac_precomputed_t *pre,
481 uint8_t *out,
482 va_list va)
483{
484 uint8_t *text;
485 unsigned len;
486
487 /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */
488 /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */
489
490 /* calculate out = H((key XOR ipad) + text) */
491 while ((text = va_arg(va, uint8_t*)) != NULL) {
492 unsigned text_size = va_arg(va, unsigned);
493 md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size);
494 }
495 len = sha_end(&pre->hashed_key_xor_ipad, out);
496
497 /* out = H((key XOR opad) + out) */
498 md5sha_hash(&pre->hashed_key_xor_opad, out, len);
499 return sha_end(&pre->hashed_key_xor_opad, out);
500}
501#else
502#define sha1_begin_hmac BCRYPT_HMAC_SHA1_ALG_HANDLE
503#define sha256_begin_hmac BCRYPT_HMAC_SHA256_ALG_HANDLE
504
505#if !ENABLE_FEATURE_TLS_SHA1
506#define hmac_begin(pre,key,key_size,begin) _hmac_begin(pre, key, key_size, sha256_begin_hmac)
507#else
508#define hmac_begin _hmac_begin
509#endif
510
511typedef struct bcrypt_hash_ctx_t hmac_precomputed_t;
512
513static void _hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, BCRYPT_ALG_HANDLE alg_handle) {
514 DWORD hash_object_length = 0;
515 ULONG _unused;
516 NTSTATUS status;
517
518 status = BCryptGetProperty(alg_handle, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hash_object_length, sizeof(DWORD), &_unused, 0);
519 mingw_die_if_error(status, "BCryptGetProperty");
520 status = BCryptGetProperty(alg_handle, BCRYPT_HASH_LENGTH, (PUCHAR)&pre->output_size, sizeof(DWORD), &_unused, 0);
521 mingw_die_if_error(status, "BCryptGetProperty");
522
523
524 pre->hash_obj = xmalloc(hash_object_length);
525
526 status = BCryptCreateHash(alg_handle, &pre->handle, pre->hash_obj, hash_object_length, key, key_size, BCRYPT_HASH_REUSABLE_FLAG);
527 mingw_die_if_error(status, "BCryptCreateHash");
528}
529
530static unsigned hmac_sha_precomputed_v(
531 hmac_precomputed_t *pre,
532 uint8_t *out,
533 va_list va)
534{
535 uint8_t *text;
536 NTSTATUS status;
537
538 while ((text = va_arg(va, uint8_t*)) != NULL) {
539 unsigned text_size = va_arg(va, unsigned);
540 /*status = */ BCryptHashData(pre->handle, text, text_size, 0);
541 //mingw_die_if_error(status, "BCryptHashData");
542 }
543
544 status = BCryptFinishHash(pre->handle, out, pre->output_size, 0);
545 mingw_die_if_error(status, "BCryptFinishHash");
546
547 return pre->output_size;
548}
549
550static void hmac_uninit(hmac_precomputed_t *pre) {
551 BCryptDestroyHash(pre->handle);
552 free(pre->hash_obj);
553}
554
555#endif
556
557static unsigned hmac_sha_precomputed(hmac_precomputed_t *pre_init, uint8_t *out, ...)
558{
559 hmac_precomputed_t pre;
560 va_list va;
561 unsigned len;
562
563 va_start(va, out);
564 pre = *pre_init; /* struct copy */
565 len = hmac_sha_precomputed_v(&pre, out, va);
566 va_end(va);
567 return len;
568}
569
570#if !ENABLE_FEATURE_TLS_SHA1
571#define hmac(tls,out,key,key_size,...) \
572 hmac(out,key,key_size, __VA_ARGS__)
573#endif
574static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...)
575{
576 hmac_precomputed_t pre;
577 va_list va;
578 unsigned len;
579
580 va_start(va, key_size);
581
582 hmac_begin(&pre, key, key_size,
583 (ENABLE_FEATURE_TLS_SHA1 && tls->MAC_size == SHA1_OUTSIZE)
584 ? sha1_begin_hmac
585 : sha256_begin_hmac
586 );
587 len = hmac_sha_precomputed_v(&pre, out, va);
588
589 va_end(va);
590 hmac_uninit(&pre);
591 return len;
592}
593
594// RFC 5246: 367// RFC 5246:
595// 5. HMAC and the Pseudorandom Function 368// 5. HMAC and the Pseudorandom Function
596//... 369//...
@@ -635,7 +408,7 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/
635 const char *label, 408 const char *label,
636 uint8_t *seed, unsigned seed_size) 409 uint8_t *seed, unsigned seed_size)
637{ 410{
638 hmac_precomputed_t pre; 411 hmac_ctx_t ctx;
639 uint8_t a[TLS_MAX_MAC_SIZE]; 412 uint8_t a[TLS_MAX_MAC_SIZE];
640 uint8_t *out_p = outbuf; 413 uint8_t *out_p = outbuf;
641 unsigned label_size = strlen(label); 414 unsigned label_size = strlen(label);
@@ -645,29 +418,28 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/
645#define SEED label, label_size, seed, seed_size 418#define SEED label, label_size, seed, seed_size
646#define A a, MAC_size 419#define A a, MAC_size
647 420
648 hmac_begin(&pre, secret, secret_size, sha256_begin_hmac); 421 hmac_begin(&ctx, secret, secret_size, sha256_begin_hmac);
649 422
650 /* A(1) = HMAC_hash(secret, seed) */ 423 /* A(1) = HMAC_hash(secret, seed) */
651 hmac_sha_precomputed(&pre, a, SEED, NULL); 424 hmac_peek_hash(&ctx, a, SEED, NULL);
652 425
653 for (;;) { 426 for (;;) {
654 /* HMAC_hash(secret, A(1) + seed) */ 427 /* HMAC_hash(secret, A(1) + seed) */
655 if (outbuf_size <= MAC_size) { 428 if (outbuf_size <= MAC_size) {
656 /* Last, possibly incomplete, block */ 429 /* Last, possibly incomplete, block */
657 /* (use a[] as temp buffer) */ 430 /* (use a[] as temp buffer) */
658 hmac_sha_precomputed(&pre, a, A, SEED, NULL); 431 hmac_peek_hash(&ctx, a, A, SEED, NULL);
659 memcpy(out_p, a, outbuf_size); 432 memcpy(out_p, a, outbuf_size);
433 hmac_uninit(&ctx);
660 return; 434 return;
661 } 435 }
662 /* Not last block. Store directly to result buffer */ 436 /* Not last block. Store directly to result buffer */
663 hmac_sha_precomputed(&pre, out_p, A, SEED, NULL); 437 hmac_peek_hash(&ctx, out_p, A, SEED, NULL);
664 out_p += MAC_size; 438 out_p += MAC_size;
665 outbuf_size -= MAC_size; 439 outbuf_size -= MAC_size;
666 /* A(2) = HMAC_hash(secret, A(1)) */ 440 /* A(2) = HMAC_hash(secret, A(1)) */
667 hmac_sha_precomputed(&pre, a, A, NULL); 441 hmac_peek_hash(&ctx, a, A, NULL);
668 } 442 }
669
670 hmac_uninit(&pre);
671#undef A 443#undef A
672#undef SECRET 444#undef SECRET
673#undef SEED 445#undef SEED
@@ -733,6 +505,32 @@ static void *tls_get_zeroed_outbuf(tls_state_t *tls, int len)
733 return record; 505 return record;
734} 506}
735 507
508/* Calculate the HMAC over the list of blocks */
509#if !ENABLE_FEATURE_TLS_SHA1
510#define hmac_blocks(tls,out,key,key_size,...) \
511 hmac_blocks(out,key,key_size, __VA_ARGS__)
512#endif
513static unsigned hmac_blocks(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...)
514{
515 hmac_ctx_t ctx;
516 va_list va;
517 unsigned len;
518
519 hmac_begin(&ctx, key, key_size,
520 (ENABLE_FEATURE_TLS_SHA1 && tls->MAC_size == SHA1_OUTSIZE)
521 ? sha1_begin_hmac
522 : sha256_begin_hmac
523 );
524
525 va_start(va, key_size);
526 hmac_hash_v(&ctx, va);
527 va_end(va);
528
529 len = hmac_end(&ctx, out);
530 hmac_uninit(&ctx);
531 return len;
532}
533
736static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, unsigned type) 534static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, unsigned type)
737{ 535{
738 uint8_t *buf = tls->outbuf + OUTBUF_PFX; 536 uint8_t *buf = tls->outbuf + OUTBUF_PFX;
@@ -754,7 +552,7 @@ static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, un
754 xhdr->len16_lo = size & 0xff; 552 xhdr->len16_lo = size & 0xff;
755 553
756 /* Calculate MAC signature */ 554 /* Calculate MAC signature */
757 hmac(tls, buf + size, /* result */ 555 hmac_blocks(tls, buf + size, /* result */
758 tls->client_write_MAC_key, TLS_MAC_SIZE(tls), 556 tls->client_write_MAC_key, TLS_MAC_SIZE(tls),
759 &tls->write_seq64_be, sizeof(tls->write_seq64_be), 557 &tls->write_seq64_be, sizeof(tls->write_seq64_be),
760 xhdr, RECHDR_LEN, 558 xhdr, RECHDR_LEN,
@@ -943,8 +741,13 @@ static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned ty
943 cnt++; 741 cnt++;
944 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */ 742 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */
945 aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); 743 aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch);
946 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining; 744 if (remaining >= AES_BLOCK_SIZE) {
947 xorbuf(buf, scratch, n); 745 n = AES_BLOCK_SIZE;
746 xorbuf_AES_BLOCK_SIZE(buf, scratch);
747 } else {
748 n = remaining;
749 xorbuf(buf, scratch, n);
750 }
948 buf += n; 751 buf += n;
949 remaining -= n; 752 remaining -= n;
950 } 753 }
@@ -1102,7 +905,7 @@ static void tls_aesgcm_decrypt(tls_state_t *tls, uint8_t *buf, int size)
1102 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */ 905 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */
1103 aes_encrypt_one_block(&tls->aes_decrypt, nonce, scratch); 906 aes_encrypt_one_block(&tls->aes_decrypt, nonce, scratch);
1104 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining; 907 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining;
1105 xorbuf3(buf, scratch, buf + 8, n); 908 xorbuf_3(buf, scratch, buf + 8, n);
1106 buf += n; 909 buf += n;
1107 remaining -= n; 910 remaining -= n;
1108 } 911 }
@@ -2560,6 +2363,7 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags)
2560 } 2363 }
2561} 2364}
2562#else 2365#else
2366#include <stdbool.h>
2563 2367
2564#if ENABLE_FEATURE_TLS_SCHANNEL_1_3 2368#if ENABLE_FEATURE_TLS_SCHANNEL_1_3
2565#include <subauth.h> 2369#include <subauth.h>
@@ -2575,6 +2379,8 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags)
2575 (ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY | ISC_REQ_REPLAY_DETECT | \ 2379 (ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_INTEGRITY | ISC_REQ_REPLAY_DETECT | \
2576 ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM | ISC_REQ_USE_SUPPLIED_CREDS) 2380 ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM | ISC_REQ_USE_SUPPLIED_CREDS)
2577 2381
2382#define SEC_STATUS_FAIL(status) ((status) != SEC_E_OK)
2383
2578static char *hresult_to_error_string(HRESULT result) { 2384static char *hresult_to_error_string(HRESULT result) {
2579 char *output = NULL; 2385 char *output = NULL;
2580 2386
@@ -2586,234 +2392,210 @@ static char *hresult_to_error_string(HRESULT result) {
2586 return output; 2392 return output;
2587} 2393}
2588 2394
2589static ssize_t tls_read(struct tls_state *state, char *buf, ssize_t len) { 2395static void init_sec_buffer(SecBuffer *buffer, void *pvBuffer, unsigned long cbBuffer, unsigned long BufferType) {
2396 buffer->BufferType = BufferType;
2397 buffer->cbBuffer = cbBuffer;
2398 buffer->pvBuffer = pvBuffer;
2399}
2400
2401#define init_sec_buffer_empty(buffer, BufferType) init_sec_buffer(buffer, NULL, 0, BufferType)
2402
2403static void init_sec_buffer_desc(SecBufferDesc *desc, SecBuffer *buffers, unsigned long buffer_count) {
2404 desc->ulVersion = SECBUFFER_VERSION;
2405 desc->cBuffers = buffer_count;
2406 desc->pBuffers = buffers;
2407}
2408
2409static ssize_t tls_read(tls_state_t *state, char *buf, ssize_t len) {
2590 ssize_t amount_read = 0; 2410 ssize_t amount_read = 0;
2591 2411
2592 if (state->closed) { 2412 if (state->connection_state > BB_SCHANNEL_OPEN) {
2593 return 0; 2413 goto Success;
2594 } 2414 }
2595 2415
2596 while (len > 0) { 2416 while (len > 0) {
2597 if (state->out_buffer && (state->out_buffer_size > 0)) { 2417 if (state->out_buffer) {
2598 unsigned long copy_amount = 2418 unsigned long copy_amount =
2599 min(len, (ssize_t) state->out_buffer_size); 2419 min(len, (ssize_t)state->out_buffer_length);
2600 memcpy(buf, state->out_buffer, copy_amount); 2420 memcpy(buf, state->out_buffer, copy_amount);
2601 2421
2602 amount_read += copy_amount; 2422 amount_read += copy_amount;
2603 buf += copy_amount; 2423 buf += copy_amount;
2604 len -= copy_amount; 2424 len -= copy_amount;
2605 2425
2606 if (copy_amount == state->out_buffer_size) { 2426 if (copy_amount == state->out_buffer_length) {
2607 // We've used all the decrypted data 2427 if (state->out_buffer_extra > 0) {
2608 // Move extra data to the front 2428 memmove(
2609 memmove(state->in_buffer, 2429 state->in_buffer,
2610 state->in_buffer + state->out_buffer_used, 2430 state->in_buffer +
2611 state->in_buffer_size - state->out_buffer_used); 2431 (state->in_buffer_offset - state->out_buffer_extra),
2612 state->in_buffer_size -= state->out_buffer_used; 2432 state->in_buffer_offset - (state->in_buffer_offset -
2433 state->out_buffer_extra));
2434 state->in_buffer_offset = state->out_buffer_extra;
2435 } else {
2436 state->in_buffer_offset = 0;
2437 }
2613 2438
2614 state->out_buffer = NULL; 2439 state->out_buffer = NULL;
2615 state->out_buffer_used = 0; 2440 state->out_buffer_length = 0;
2616 state->out_buffer_size = 0; 2441 state->out_buffer_extra = 0;
2442
2617 } else { 2443 } else {
2618 state->out_buffer_size -= copy_amount; 2444 state->out_buffer_length -= copy_amount;
2619 state->out_buffer += copy_amount; 2445 state->out_buffer += copy_amount;
2620 } 2446 }
2621 } else { 2447 } else {
2622 SECURITY_STATUS status;
2623
2624 int received;
2625
2626 SecBuffer buffers[4]; 2448 SecBuffer buffers[4];
2627
2628 SecBufferDesc desc; 2449 SecBufferDesc desc;
2450 SECURITY_STATUS status;
2629 2451
2630 buffers[0].BufferType = SECBUFFER_DATA; 2452 init_sec_buffer(&buffers[0],
2631 buffers[0].pvBuffer = state->in_buffer; 2453 state->in_buffer,
2632 buffers[0].cbBuffer = state->in_buffer_size; 2454 state->in_buffer_offset,
2633 2455 SECBUFFER_DATA);
2634 buffers[1].BufferType = SECBUFFER_EMPTY; 2456 init_sec_buffer_empty(&buffers[1], SECBUFFER_EMPTY);
2635 buffers[1].pvBuffer = NULL; 2457 init_sec_buffer_empty(&buffers[2], SECBUFFER_EMPTY);
2636 buffers[1].cbBuffer = 0; 2458 init_sec_buffer_empty(&buffers[3], SECBUFFER_EMPTY);
2637
2638 buffers[2].BufferType = SECBUFFER_EMPTY;
2639 buffers[2].pvBuffer = NULL;
2640 buffers[2].cbBuffer = 0;
2641
2642 buffers[3].BufferType = SECBUFFER_EMPTY;
2643 buffers[3].pvBuffer = NULL;
2644 buffers[3].cbBuffer = 0;
2645 2459
2646 desc.ulVersion = SECBUFFER_VERSION; 2460 init_sec_buffer_desc(&desc, buffers, _countof(buffers));
2647 desc.pBuffers = buffers;
2648 desc.cBuffers = _countof(buffers);
2649 2461
2650 status = DecryptMessage(&state->ctx_handle, &desc, 0, NULL); 2462 status = DecryptMessage(&state->ctx_handle, &desc, 0, NULL);
2651 2463
2652 switch (status) { 2464 switch (status) {
2653 case SEC_E_OK:{ 2465 case SEC_E_OK: {
2654 state->out_buffer = buffers[1].pvBuffer; 2466 state->out_buffer = buffers[1].pvBuffer;
2655 state->out_buffer_size = buffers[1].cbBuffer; 2467 state->out_buffer_length = buffers[1].cbBuffer;
2656 2468 state->out_buffer_extra = state->in_buffer_offset;
2657 state->out_buffer_used = state->in_buffer_size; 2469
2658 if (buffers[3].BufferType == SECBUFFER_EXTRA) { 2470 if (buffers[3].BufferType == SECBUFFER_EXTRA) {
2659 state->out_buffer_used -= buffers[3].cbBuffer; 2471 state->out_buffer_extra = buffers[3].cbBuffer;
2472 } else {
2473 state->out_buffer_extra = 0;
2474 }
2475
2476 continue;
2660 } 2477 }
2661 2478 case SEC_I_CONTEXT_EXPIRED: {
2662 continue; 2479 // Shut down the connection
2663 } 2480 state->connection_state = BB_SCHANNEL_CLOSED;
2664 case SEC_I_CONTEXT_EXPIRED:{ 2481 goto Success;
2665 state->closed = 1;
2666 goto Success;
2667 }
2668 case SEC_I_RENEGOTIATE:{
2669 // Renegotiate the TLS connection.
2670 // Microsoft repurposed this flag
2671 // for TLS 1.3 support.
2672 int i;
2673
2674 DWORD flags;
2675
2676 SecBuffer in_buffers[2];
2677
2678 SecBuffer out_buffers[2];
2679
2680 SecBufferDesc in_desc;
2681
2682 SecBufferDesc out_desc;
2683
2684
2685 for (i = 0; i < 4; i++) {
2686 if (buffers[i].BufferType == SECBUFFER_EXTRA)
2687 break;
2688 } 2482 }
2689 2483 case SEC_E_INCOMPLETE_MESSAGE: {
2690 flags = BB_SCHANNEL_ISC_FLAGS; 2484 int result = safe_read(state->ifd,
2691 2485 state->in_buffer + state->in_buffer_offset,
2692 in_buffers[0].BufferType = SECBUFFER_TOKEN; 2486 sizeof(state->in_buffer) - state->in_buffer_offset);
2693 in_buffers[0].pvBuffer = buffers[i].pvBuffer; 2487 if (result == 0) {
2694 in_buffers[0].cbBuffer = buffers[i].cbBuffer; 2488 state->connection_state = BB_SCHANNEL_CLOSED;
2695 2489 goto Success;
2696 in_buffers[1].BufferType = SECBUFFER_EMPTY; 2490 } else if (result < 0) {
2697 in_buffers[1].pvBuffer = NULL; 2491 bb_error_msg_and_die("schannel: read() failed");
2698 in_buffers[1].cbBuffer = 0; 2492 }
2699 2493
2700 out_buffers[0].BufferType = SECBUFFER_TOKEN; 2494 state->in_buffer_offset += result;
2701 out_buffers[0].pvBuffer = NULL; 2495 continue;
2702 out_buffers[0].cbBuffer = 0;
2703
2704 out_buffers[1].BufferType = SECBUFFER_ALERT;
2705 out_buffers[1].pvBuffer = NULL;
2706 out_buffers[1].cbBuffer = 0;
2707
2708 in_desc.ulVersion = SECBUFFER_VERSION;
2709 in_desc.pBuffers = in_buffers;
2710 in_desc.cBuffers = _countof(in_buffers);
2711
2712 out_desc.ulVersion = SECBUFFER_VERSION;
2713 out_desc.pBuffers = out_buffers;
2714 out_desc.cBuffers = _countof(out_buffers);
2715
2716 status = InitializeSecurityContext(&state->cred_handle,
2717 state->initialized ?
2718 &state->ctx_handle : NULL,
2719 state->initialized ? NULL :
2720 state->hostname, flags, 0,
2721 0,
2722 state->initialized ?
2723 &in_desc : NULL, 0,
2724 state->initialized ? NULL :
2725 &state->ctx_handle,
2726 &out_desc, &flags, 0);
2727
2728 if (status != SEC_E_OK) {
2729 bb_error_msg_and_die("schannel: renegotiate failed: (0x%08lx): %s",
2730 status, hresult_to_error_string(status));
2731 } 2496 }
2732 2497 case SEC_I_RENEGOTIATE: {
2733 if (in_buffers[1].BufferType == SECBUFFER_EXTRA) { 2498 DWORD flags = BB_SCHANNEL_ISC_FLAGS;
2734 memmove(state->in_buffer, 2499
2735 state->in_buffer + (state->in_buffer_size - 2500 SecBuffer in_buffers[2];
2736 in_buffers[1].cbBuffer), 2501 SecBufferDesc in_buffers_desc;
2737 in_buffers[1].cbBuffer); 2502
2503 SecBuffer out_buffers[2];
2504 SecBufferDesc out_buffers_desc;
2505
2506 init_sec_buffer(&in_buffers[0],
2507 buffers[3].pvBuffer,
2508 buffers[3].cbBuffer,
2509 SECBUFFER_TOKEN);
2510 init_sec_buffer_empty(&in_buffers[1], SECBUFFER_EMPTY);
2511
2512 init_sec_buffer_empty(&out_buffers[0], SECBUFFER_TOKEN);
2513 init_sec_buffer_empty(&out_buffers[1], SECBUFFER_ALERT);
2514
2515 init_sec_buffer_desc(
2516 &in_buffers_desc, in_buffers, _countof(in_buffers));
2517 init_sec_buffer_desc(
2518 &out_buffers_desc, out_buffers, _countof(out_buffers));
2519
2520 status = InitializeSecurityContextA(&state->cred_handle,
2521 &state->ctx_handle,
2522 state->hostname,
2523 flags,
2524 0,
2525 0,
2526 &in_buffers_desc,
2527 0,
2528 &state->ctx_handle,
2529 &out_buffers_desc,
2530 &flags,
2531 0);
2532
2533 if (SEC_STATUS_FAIL(status)) {
2534 bb_error_msg_and_die("schannel: renegotiate failed: (0x%08lx): %s",
2535 status, hresult_to_error_string(status));
2536 }
2537
2538 if (in_buffers[1].BufferType == SECBUFFER_EXTRA) {
2539 memmove(state->in_buffer,
2540 state->in_buffer + (state->in_buffer_offset -
2541 in_buffers[1].cbBuffer),
2542 in_buffers[1].cbBuffer);
2543 state->in_buffer_offset = in_buffers[1].cbBuffer;
2544 } else {
2545 state->in_buffer_offset = 0;
2546 }
2547
2548 continue;
2549 }
2550 default: {
2551 bb_error_msg_and_die("schannel: DecryptMessage failed: (0x%08lx): %s",
2552 status, hresult_to_error_string(status));
2738 } 2553 }
2739
2740 state->out_buffer_used =
2741 state->in_buffer_size - in_buffers[1].cbBuffer;
2742 state->in_buffer_size = in_buffers[1].cbBuffer;
2743
2744 continue;
2745 }
2746 case SEC_E_INCOMPLETE_MESSAGE:{
2747 break;
2748 }
2749 default:{
2750 bb_error_msg_and_die("schannel: DecryptMessage failed: (0x%08lx): %s", status,
2751 hresult_to_error_string(status));
2752 }
2753 }
2754
2755 received =
2756 safe_read(state->ifd,
2757 state->in_buffer + state->in_buffer_size,
2758 sizeof(state->in_buffer) - state->in_buffer_size);
2759 if (received == 0) {
2760 state->closed = 1;
2761 goto Success;
2762 } else if (received < 0) {
2763 bb_error_msg_and_die("schannel: read() failed");
2764 } 2554 }
2765
2766 state->in_buffer_size += received;
2767 } 2555 }
2768 } 2556 }
2769 2557
2770 Success: 2558Success:
2771 return amount_read; 2559 return amount_read;
2772} 2560}
2773 2561
2774static void tls_write(struct tls_state *state, char *buf, size_t len) { 2562static void tls_write(tls_state_t *state, char *buf, size_t len) {
2775 if (state->closed) { 2563 if (state->connection_state > BB_SCHANNEL_OPEN) {
2776 bb_error_msg_and_die("schannel: attempted to write to a closed connection"); 2564 bb_error_msg_and_die("schannel: attempted to write to a closed connection");
2777 } 2565 }
2778 2566
2779 while (len > 0) { 2567 while (len > 0) {
2568 SECURITY_STATUS status;
2780 unsigned long copy_amount = 2569 unsigned long copy_amount =
2781 min(len, (size_t) state->stream_sizes.cbMaximumMessage); 2570 min(len, (size_t)state->stream_sizes.cbMaximumMessage);
2782 char *write_buffer = _alloca(sizeof(state->in_buffer)); 2571 char *write_buffer = _alloca(sizeof(state->in_buffer));
2783 2572
2784 SECURITY_STATUS status;
2785
2786 SecBuffer buffers[4]; 2573 SecBuffer buffers[4];
2787
2788 SecBufferDesc desc; 2574 SecBufferDesc desc;
2789 2575
2790 buffers[0].BufferType = SECBUFFER_STREAM_HEADER; 2576 init_sec_buffer(&buffers[0],
2791 buffers[0].pvBuffer = write_buffer; 2577 write_buffer,
2792 buffers[0].cbBuffer = state->stream_sizes.cbHeader; 2578 state->stream_sizes.cbHeader,
2793 2579 SECBUFFER_STREAM_HEADER);
2794 buffers[1].BufferType = SECBUFFER_DATA; 2580 init_sec_buffer(&buffers[1],
2795 buffers[1].pvBuffer = write_buffer + state->stream_sizes.cbHeader; 2581 write_buffer + state->stream_sizes.cbHeader,
2796 buffers[1].cbBuffer = copy_amount; 2582 copy_amount,
2797 2583 SECBUFFER_DATA);
2798 buffers[2].BufferType = SECBUFFER_STREAM_TRAILER; 2584 init_sec_buffer(&buffers[2],
2799 buffers[2].pvBuffer = 2585 write_buffer + state->stream_sizes.cbHeader +
2800 write_buffer + state->stream_sizes.cbHeader + copy_amount; 2586 copy_amount,
2801 buffers[2].cbBuffer = state->stream_sizes.cbTrailer; 2587 state->stream_sizes.cbTrailer,
2802 2588 SECBUFFER_STREAM_TRAILER);
2803 buffers[3].BufferType = SECBUFFER_EMPTY; 2589 init_sec_buffer_empty(&buffers[3], SECBUFFER_EMPTY);
2804 buffers[3].pvBuffer = NULL; 2590
2805 buffers[3].cbBuffer = 0; 2591 init_sec_buffer_desc(&desc, buffers, _countof(buffers));
2806 2592
2807 memcpy(buffers[1].pvBuffer, buf, copy_amount); 2593 memcpy(buffers[1].pvBuffer, buf, copy_amount);
2808 2594
2809 desc.ulVersion = SECBUFFER_VERSION;
2810 desc.pBuffers = buffers;
2811 desc.cBuffers = _countof(buffers);
2812
2813 status = EncryptMessage(&state->ctx_handle, 0, &desc, 0); 2595 status = EncryptMessage(&state->ctx_handle, 0, &desc, 0);
2814 if (status != SEC_E_OK) { 2596 if (SEC_STATUS_FAIL(status)) {
2815 bb_error_msg_and_die("schannel: EncryptMessage failed: (0x%08lx): %s", status, 2597 bb_error_msg_and_die("schannel: EncryptMessage failed: (0x%08lx): %s",
2816 hresult_to_error_string(status)); 2598 status, hresult_to_error_string(status));
2817 } 2599 }
2818 2600
2819 xwrite(state->ofd, write_buffer, 2601 xwrite(state->ofd, write_buffer,
@@ -2826,72 +2608,44 @@ static void tls_write(struct tls_state *state, char *buf, size_t len) {
2826 2608
2827static void tls_disconnect(tls_state_t * state) { 2609static void tls_disconnect(tls_state_t * state) {
2828 SECURITY_STATUS status; 2610 SECURITY_STATUS status;
2611
2829 DWORD token = SCHANNEL_SHUTDOWN; 2612 DWORD token = SCHANNEL_SHUTDOWN;
2830 DWORD flags = BB_SCHANNEL_ISC_FLAGS; 2613 DWORD flags = BB_SCHANNEL_ISC_FLAGS;
2831 2614
2832 SecBuffer buf_token; 2615 SecBuffer buf_token;
2833
2834 SecBufferDesc buf_token_desc; 2616 SecBufferDesc buf_token_desc;
2835
2836 SecBuffer in_buffers[2];
2837 SecBuffer out_buffers[2];
2838 2617
2839 SecBufferDesc in_desc; 2618 SecBuffer out_buffer;
2840 SecBufferDesc out_desc; 2619 SecBufferDesc out_buffer_desc;
2841 2620
2842 buf_token.BufferType = SECBUFFER_TOKEN; 2621 if (state->connection_state == BB_SCHANNEL_CLOSED_AND_FREED)
2843 buf_token.pvBuffer = &token; 2622 return;
2844 buf_token.cbBuffer = sizeof(token); 2623 state->connection_state = BB_SCHANNEL_CLOSED_AND_FREED;
2845 2624
2846 buf_token_desc.ulVersion = SECBUFFER_VERSION; 2625 init_sec_buffer(&buf_token, &token, sizeof(token), SECBUFFER_TOKEN);
2847 buf_token_desc.pBuffers = &buf_token; 2626 init_sec_buffer_desc(&buf_token_desc, &buf_token, 1);
2848 buf_token_desc.cBuffers = 1;
2849 2627
2850 ApplyControlToken(&state->ctx_handle, &buf_token_desc); 2628 ApplyControlToken(&state->ctx_handle, &buf_token_desc);
2851 2629
2852 // attempt to send any final data 2630 init_sec_buffer_empty(&out_buffer, SECBUFFER_TOKEN);
2853 2631 init_sec_buffer_desc(&out_buffer_desc, &out_buffer, 1);
2854 in_buffers[0].BufferType = SECBUFFER_TOKEN; 2632
2855 in_buffers[0].pvBuffer = state->in_buffer; 2633 status = InitializeSecurityContextA(&state->cred_handle,
2856 in_buffers[0].cbBuffer = state->in_buffer_size; 2634 &state->ctx_handle,
2857 2635 state->hostname,
2858 in_buffers[1].BufferType = SECBUFFER_EMPTY; 2636 flags,
2859 in_buffers[1].pvBuffer = NULL; 2637 0,
2860 in_buffers[1].cbBuffer = 0; 2638 0,
2861 2639 NULL,
2862 out_buffers[0].BufferType = SECBUFFER_TOKEN; 2640 0,
2863 out_buffers[0].pvBuffer = NULL; 2641 &state->ctx_handle,
2864 out_buffers[0].cbBuffer = 0; 2642 &out_buffer_desc,
2865 2643 &flags,
2866 out_buffers[1].BufferType = SECBUFFER_ALERT; 2644 0);
2867 out_buffers[1].pvBuffer = NULL; 2645
2868 out_buffers[1].cbBuffer = 0; 2646 if ((status == SEC_E_OK) || (status == SEC_I_CONTEXT_EXPIRED)) {
2869 2647 write(state->ofd, out_buffer.pvBuffer, out_buffer.cbBuffer);
2870 in_desc.ulVersion = SECBUFFER_VERSION; 2648 FreeContextBuffer(out_buffer.pvBuffer);
2871 in_desc.pBuffers = in_buffers;
2872 in_desc.cBuffers = _countof(in_buffers);
2873
2874 out_desc.ulVersion = SECBUFFER_VERSION;
2875 out_desc.pBuffers = out_buffers;
2876 out_desc.cBuffers = _countof(out_buffers);
2877
2878 status = InitializeSecurityContext(&state->cred_handle,
2879 state->
2880 initialized ? &state->ctx_handle :
2881 NULL,
2882 state->
2883 initialized ? NULL : state->hostname,
2884 flags, 0, 0,
2885 state->initialized ? &in_desc : NULL,
2886 0,
2887 state->
2888 initialized ? NULL :
2889 &state->ctx_handle, &out_desc, &flags,
2890 0);
2891
2892 if (status == SEC_E_OK) {
2893 // attempt to write any extra data
2894 write(state->ofd, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
2895 } 2649 }
2896 2650
2897 DeleteSecurityContext(&state->ctx_handle); 2651 DeleteSecurityContext(&state->ctx_handle);
@@ -2900,9 +2654,8 @@ static void tls_disconnect(tls_state_t * state) {
2900} 2654}
2901 2655
2902 2656
2903void FAST_FUNC tls_handshake(tls_state_t * state, const char *hostname) { 2657void FAST_FUNC tls_handshake(tls_state_t *state, const char *hostname) {
2904 SECURITY_STATUS status; 2658 SECURITY_STATUS status;
2905 int received;
2906 2659
2907#if ENABLE_FEATURE_TLS_SCHANNEL_1_3 2660#if ENABLE_FEATURE_TLS_SCHANNEL_1_3
2908 SCH_CREDENTIALS credential = {.dwVersion = SCH_CREDENTIALS_VERSION, 2661 SCH_CREDENTIALS credential = {.dwVersion = SCH_CREDENTIALS_VERSION,
@@ -2941,133 +2694,124 @@ void FAST_FUNC tls_handshake(tls_state_t * state, const char *hostname) {
2941 }; 2694 };
2942#endif 2695#endif
2943 2696
2944 if ((status = AcquireCredentialsHandleA(NULL, (SEC_CHAR *) UNISP_NAME_A, 2697 state->in_buffer_offset = 0;
2945 SECPKG_CRED_OUTBOUND, NULL,
2946 &credential,
2947 NULL, NULL, &state->cred_handle,
2948 NULL)) != SEC_E_OK) {
2949 bb_error_msg_and_die("schannel: AcquireCredentialsHandleA failed: (0x%08lx): %s",
2950 status, hresult_to_error_string(status));
2951 }
2952
2953 state->in_buffer_size = 0;
2954 state->out_buffer_size = 0;
2955 state->out_buffer_used = 0;
2956 2698
2957 state->out_buffer = NULL; 2699 state->out_buffer = NULL;
2700 state->out_buffer_length = 0;
2701 state->out_buffer_extra = 0;
2702
2703 state->hostname = xstrdup(hostname);
2704 state->initialized = false;
2705 state->connection_state = BB_SCHANNEL_OPEN;
2706
2707 if (SEC_STATUS_FAIL(status = AcquireCredentialsHandleA(NULL,
2708 (SEC_CHAR *)UNISP_NAME_A,
2709 SECPKG_CRED_OUTBOUND,
2710 NULL,
2711 &credential,
2712 NULL,
2713 NULL,
2714 &state->cred_handle,
2715 NULL))) {
2716 bb_error_msg_and_die("schannel: AcquireCredentialsHandleA failed: (0x%08lx): %s",
2717 status, hresult_to_error_string(status));
2718 }
2958 2719
2959 state->hostname = strdup(hostname); 2720 // InitializeSecurityContext loop
2960 2721 while (true) {
2961 state->initialized = 0;
2962 state->closed = 0;
2963
2964 while (1) {
2965 DWORD flags = BB_SCHANNEL_ISC_FLAGS; 2722 DWORD flags = BB_SCHANNEL_ISC_FLAGS;
2966 2723
2967 SecBuffer in_buffers[2]; 2724 SecBuffer in_buffers[2];
2968 SecBuffer out_buffers[2]; 2725 SecBufferDesc in_buffers_desc;
2969
2970 SecBufferDesc in_desc;
2971 SecBufferDesc out_desc;
2972
2973 in_buffers[0].BufferType = SECBUFFER_TOKEN;
2974 in_buffers[0].pvBuffer = state->in_buffer;
2975 in_buffers[0].cbBuffer = state->in_buffer_size;
2976
2977 in_buffers[1].BufferType = SECBUFFER_EMPTY;
2978 in_buffers[1].pvBuffer = NULL;
2979 in_buffers[1].cbBuffer = 0;
2980 2726
2981 out_buffers[0].BufferType = SECBUFFER_TOKEN; 2727 SecBuffer out_buffers[2];
2982 out_buffers[0].pvBuffer = NULL; 2728 SecBufferDesc out_buffers_desc;
2983 out_buffers[0].cbBuffer = 0; 2729
2984 2730 init_sec_buffer(&in_buffers[0],
2985 out_buffers[1].BufferType = SECBUFFER_ALERT; 2731 state->in_buffer,
2986 out_buffers[1].pvBuffer = NULL; 2732 state->in_buffer_offset,
2987 out_buffers[1].cbBuffer = 0; 2733 SECBUFFER_TOKEN);
2988 2734 init_sec_buffer_empty(&in_buffers[1], SECBUFFER_EMPTY);
2989 in_desc.ulVersion = SECBUFFER_VERSION; 2735
2990 in_desc.pBuffers = in_buffers; 2736 init_sec_buffer_empty(&out_buffers[0], SECBUFFER_TOKEN);
2991 in_desc.cBuffers = _countof(in_buffers); 2737 init_sec_buffer_empty(&out_buffers[1], SECBUFFER_ALERT);
2992 2738
2993 out_desc.ulVersion = SECBUFFER_VERSION; 2739 init_sec_buffer_desc(
2994 out_desc.pBuffers = out_buffers; 2740 &in_buffers_desc, in_buffers, _countof(in_buffers));
2995 out_desc.cBuffers = _countof(out_buffers); 2741 init_sec_buffer_desc(
2996 2742 &out_buffers_desc, out_buffers, _countof(out_buffers));
2997 status = InitializeSecurityContext(&state->cred_handle, 2743
2998 state-> 2744 status = InitializeSecurityContextA(
2999 initialized ? &state->ctx_handle : 2745 &state->cred_handle,
3000 NULL, 2746 state->initialized ? &state->ctx_handle : NULL,
3001 state-> 2747 state->hostname,
3002 initialized ? NULL : 2748 flags,
3003 state->hostname, flags, 0, 0, 2749 0,
3004 state->initialized ? &in_desc : 2750 0,
3005 NULL, 0, 2751 state->initialized ? &in_buffers_desc : NULL,
3006 state->initialized ? NULL : 2752 0,
3007 &state->ctx_handle, &out_desc, 2753 &state->ctx_handle,
3008 &flags, 0); 2754 &out_buffers_desc,
3009 2755 &flags,
3010 state->initialized = 1; 2756 0);
2757
2758 state->initialized = true;
3011 2759
3012 if (in_buffers[1].BufferType == SECBUFFER_EXTRA) { 2760 if (in_buffers[1].BufferType == SECBUFFER_EXTRA) {
3013 memmove(state->in_buffer, 2761 memmove(state->in_buffer,
3014 state->in_buffer + (state->in_buffer_size - 2762 state->in_buffer +
3015 in_buffers[1].cbBuffer), 2763 (state->in_buffer_offset - in_buffers[1].cbBuffer),
3016 in_buffers[1].cbBuffer); 2764 in_buffers[1].cbBuffer);
3017 state->in_buffer_size = in_buffers[1].cbBuffer; 2765 state->in_buffer_offset = in_buffers[1].cbBuffer;
3018 } else if (in_buffers[1].BufferType != SECBUFFER_MISSING) {
3019 state->in_buffer_size = 0;
3020 } 2766 }
3021 2767
3022 switch (status) { 2768 switch (status) {
3023 case SEC_E_OK:{ 2769 case SEC_E_OK: {
3024 if (out_buffers[0].cbBuffer > 0) { 2770 state->in_buffer_offset =
3025 xwrite(state->ofd, out_buffers[0].pvBuffer, 2771 (in_buffers[1].BufferType == SECBUFFER_EXTRA)
3026 out_buffers[0].cbBuffer); 2772 ? in_buffers[1].cbBuffer
2773 : 0;
2774
2775 if (out_buffers[0].cbBuffer > 0) {
2776 xwrite(state->ifd, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
2777 FreeContextBuffer(out_buffers[0].pvBuffer);
2778 }
2779
2780 goto Success;
2781 }
2782 case SEC_I_CONTINUE_NEEDED: {
2783 xwrite(state->ofd, out_buffers[0].pvBuffer, out_buffers[0].cbBuffer);
3027 FreeContextBuffer(out_buffers[0].pvBuffer); 2784 FreeContextBuffer(out_buffers[0].pvBuffer);
2785 if (in_buffers[1].BufferType != SECBUFFER_EXTRA) {
2786 state->in_buffer_offset = 0;
2787 }
2788 break;
3028 } 2789 }
3029 goto Success; 2790 case SEC_E_INCOMPLETE_MESSAGE: {
3030 } 2791 int amount_read =
3031 case SEC_I_CONTINUE_NEEDED:{ 2792 safe_read(state->ifd, state->in_buffer + state->in_buffer_offset,
3032 xwrite(state->ofd, out_buffers[0].pvBuffer, 2793 sizeof(state->in_buffer) - state->in_buffer_offset);
3033 out_buffers[0].cbBuffer); 2794 if (amount_read <= 0) {
3034 FreeContextBuffer(out_buffers[0].pvBuffer); 2795 bb_error_msg_and_die("schannel: handshake read() failed");
3035 break; 2796 }
3036 }
3037 case SEC_I_INCOMPLETE_CREDENTIALS:{
3038 // we don't support this
3039 bb_error_msg_and_die("schannel: client certificates not supported");
3040 }
3041 case SEC_E_INCOMPLETE_MESSAGE:{
3042 break;
3043 }
3044 default:{
3045 bb_error_msg_and_die("schannel: handshake failed: (0x%08lx): %s",
3046 status, hresult_to_error_string(status));
3047 }
3048 }
3049 2797
3050 received = 2798 state->in_buffer_offset += amount_read;
3051 safe_read(state->ifd, state->in_buffer + state->in_buffer_size, 2799 continue;
3052 sizeof(state->in_buffer) - state->in_buffer_size); 2800 }
3053 if (received <= 0) { 2801 default: {
3054 bb_error_msg_and_die("schannel: handshake read() failed"); 2802 bb_error_msg_and_die("schannel: handshake failed: (0x%08lx): %s",
2803 status, hresult_to_error_string(status));
2804 }
3055 } 2805 }
3056 state->in_buffer_size += received;
3057 } 2806 }
3058 2807
3059 Success: 2808Success:
3060 QueryContextAttributes(&state->ctx_handle, SECPKG_ATTR_STREAM_SIZES, 2809 QueryContextAttributes(
3061 &state->stream_sizes); 2810 &state->ctx_handle, SECPKG_ATTR_STREAM_SIZES, &state->stream_sizes);
3062 2811 return;
3063 //SecPkgContext_ConnectionInfo info;
3064 //QueryContextAttributes(&state->ctx_handle, SECPKG_ATTR_CONNECTION_INFO,
3065 // &info);
3066 //
3067 //fprintf(stderr, "TLS 1.%d\n", (((uint32_t)(8 * sizeof(unsigned long long) - __builtin_clzll((info.dwProtocol)) - 1)) - 7)/2);
3068} 2812}
3069 2813
3070void FAST_FUNC tls_run_copy_loop(tls_state_t * tls, unsigned flags) { 2814void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags) {
3071 char buffer[65536]; 2815 char buffer[65536];
3072 2816
3073 struct pollfd pfds[2]; 2817 struct pollfd pfds[2];
@@ -3104,4 +2848,4 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t * tls, unsigned flags) {
3104 } 2848 }
3105 } 2849 }
3106} 2850}
3107#endif \ No newline at end of file 2851#endif
diff --git a/networking/tls.h b/networking/tls.h
index b34c678c8..eee5a7617 100644
--- a/networking/tls.h
+++ b/networking/tls.h
@@ -10,6 +10,7 @@
10 */ 10 */
11#include "libbb.h" 11#include "libbb.h"
12 12
13
13#if !ENABLE_FEATURE_TLS_SCHANNEL 14#if !ENABLE_FEATURE_TLS_SCHANNEL
14/* Config tweaks */ 15/* Config tweaks */
15#define HAVE_NATIVE_INT64 16#define HAVE_NATIVE_INT64
@@ -82,10 +83,9 @@ typedef int16_t int16;
82 83
83void tls_get_random(void *buf, unsigned len) FAST_FUNC; 84void tls_get_random(void *buf, unsigned len) FAST_FUNC;
84 85
85void xorbuf(void* buf, const void* mask, unsigned count) FAST_FUNC;
86
87#define ALIGNED_long ALIGNED(sizeof(long)) 86#define ALIGNED_long ALIGNED(sizeof(long))
88void xorbuf_aligned_AES_BLOCK_SIZE(void* buf, const void* mask) FAST_FUNC; 87#define xorbuf_aligned_AES_BLOCK_SIZE(dst,src) xorbuf16_aligned_long(dst,src)
88#define xorbuf_AES_BLOCK_SIZE(dst,src) xorbuf16(dst,src)
89 89
90#define matrixCryptoGetPrngData(buf, len, userPtr) (tls_get_random(buf, len), PS_SUCCESS) 90#define matrixCryptoGetPrngData(buf, len, userPtr) (tls_get_random(buf, len), PS_SUCCESS)
91 91
diff --git a/networking/tls_aesgcm.c b/networking/tls_aesgcm.c
index 5ddcdd2ad..9c2381a57 100644
--- a/networking/tls_aesgcm.c
+++ b/networking/tls_aesgcm.c
@@ -167,10 +167,7 @@ void FAST_FUNC aesgcm_GHASH(byte* h,
167 blocks = cSz / AES_BLOCK_SIZE; 167 blocks = cSz / AES_BLOCK_SIZE;
168 partial = cSz % AES_BLOCK_SIZE; 168 partial = cSz % AES_BLOCK_SIZE;
169 while (blocks--) { 169 while (blocks--) {
170 if (BB_UNALIGNED_MEMACCESS_OK) // c is not guaranteed to be aligned 170 xorbuf_AES_BLOCK_SIZE(x, c);
171 xorbuf_aligned_AES_BLOCK_SIZE(x, c);
172 else
173 xorbuf(x, c, AES_BLOCK_SIZE);
174 GMULT(x, h); 171 GMULT(x, h);
175 c += AES_BLOCK_SIZE; 172 c += AES_BLOCK_SIZE;
176 } 173 }