aboutsummaryrefslogtreecommitdiff
path: root/networking/tls.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/tls.c')
-rw-r--r--networking/tls.c200
1 files changed, 38 insertions, 162 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 8d074c058..ac6f0767f 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -188,8 +188,6 @@
188#define TLS_MAX_OUTBUF (1 << 14) 188#define TLS_MAX_OUTBUF (1 << 14)
189 189
190enum { 190enum {
191 SHA_INSIZE = 64,
192
193 AES128_KEYSIZE = 16, 191 AES128_KEYSIZE = 16,
194 AES256_KEYSIZE = 32, 192 AES256_KEYSIZE = 32,
195 193
@@ -335,34 +333,6 @@ void FAST_FUNC tls_get_random(void *buf, unsigned len)
335 xfunc_die(); 333 xfunc_die();
336} 334}
337 335
338static void xorbuf3(void *dst, const void *src1, const void *src2, unsigned count)
339{
340 uint8_t *d = dst;
341 const uint8_t *s1 = src1;
342 const uint8_t* s2 = src2;
343 while (count--)
344 *d++ = *s1++ ^ *s2++;
345}
346
347void FAST_FUNC xorbuf(void *dst, const void *src, unsigned count)
348{
349 xorbuf3(dst, dst, src, count);
350}
351
352void FAST_FUNC xorbuf_aligned_AES_BLOCK_SIZE(void *dst, const void *src)
353{
354 unsigned long *d = dst;
355 const unsigned long *s = src;
356 d[0] ^= s[0];
357#if ULONG_MAX <= 0xffffffffffffffff
358 d[1] ^= s[1];
359 #if ULONG_MAX == 0xffffffff
360 d[2] ^= s[2];
361 d[3] ^= s[3];
362 #endif
363#endif
364}
365
366#if !TLS_DEBUG_HASH 336#if !TLS_DEBUG_HASH
367# define hash_handshake(tls, fmt, buffer, len) \ 337# define hash_handshake(tls, fmt, buffer, len) \
368 hash_handshake(tls, buffer, len) 338 hash_handshake(tls, buffer, len)
@@ -393,128 +363,6 @@ static void hash_handshake(tls_state_t *tls, const char *fmt, const void *buffer
393# define TLS_MAC_SIZE(tls) (tls)->MAC_size 363# define TLS_MAC_SIZE(tls) (tls)->MAC_size
394#endif 364#endif
395 365
396// RFC 2104:
397// HMAC(key, text) based on a hash H (say, sha256) is:
398// ipad = [0x36 x INSIZE]
399// opad = [0x5c x INSIZE]
400// HMAC(key, text) = H((key XOR opad) + H((key XOR ipad) + text))
401//
402// H(key XOR opad) and H(key XOR ipad) can be precomputed
403// if we often need HMAC hmac with the same key.
404//
405// text is often given in disjoint pieces.
406typedef struct hmac_precomputed {
407 md5sha_ctx_t hashed_key_xor_ipad;
408 md5sha_ctx_t hashed_key_xor_opad;
409} hmac_precomputed_t;
410
411typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC;
412#if !ENABLE_FEATURE_TLS_SHA1
413#define hmac_begin(pre,key,key_size,begin) \
414 hmac_begin(pre,key,key_size)
415#define begin sha256_begin
416#endif
417static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin)
418{
419 uint8_t key_xor_ipad[SHA_INSIZE];
420 uint8_t key_xor_opad[SHA_INSIZE];
421// uint8_t tempkey[SHA1_OUTSIZE < SHA256_OUTSIZE ? SHA256_OUTSIZE : SHA1_OUTSIZE];
422 unsigned i;
423
424 // "The authentication key can be of any length up to INSIZE, the
425 // block length of the hash function. Applications that use keys longer
426 // than INSIZE bytes will first hash the key using H and then use the
427 // resultant OUTSIZE byte string as the actual key to HMAC."
428 if (key_size > SHA_INSIZE) {
429 bb_simple_error_msg_and_die("HMAC key>64"); //does not happen (yet?)
430// md5sha_ctx_t ctx;
431// begin(&ctx);
432// md5sha_hash(&ctx, key, key_size);
433// key_size = sha_end(&ctx, tempkey);
434// //key = tempkey; - right? RIGHT? why does it work without this?
435// // because SHA_INSIZE is 64, but hmac() is always called with
436// // key_size = tls->MAC_size = SHA1/256_OUTSIZE (20 or 32),
437// // and prf_hmac_sha256() -> hmac_sha256() key sizes are:
438// // - RSA_PREMASTER_SIZE is 48
439// // - CURVE25519_KEYSIZE is 32
440// // - master_secret[] is 48
441 }
442
443 for (i = 0; i < key_size; i++) {
444 key_xor_ipad[i] = key[i] ^ 0x36;
445 key_xor_opad[i] = key[i] ^ 0x5c;
446 }
447 for (; i < SHA_INSIZE; i++) {
448 key_xor_ipad[i] = 0x36;
449 key_xor_opad[i] = 0x5c;
450 }
451
452 begin(&pre->hashed_key_xor_ipad);
453 begin(&pre->hashed_key_xor_opad);
454 md5sha_hash(&pre->hashed_key_xor_ipad, key_xor_ipad, SHA_INSIZE);
455 md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE);
456}
457#undef begin
458
459static unsigned hmac_sha_precomputed_v(
460 hmac_precomputed_t *pre,
461 uint8_t *out,
462 va_list va)
463{
464 uint8_t *text;
465 unsigned len;
466
467 /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */
468 /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */
469
470 /* calculate out = H((key XOR ipad) + text) */
471 while ((text = va_arg(va, uint8_t*)) != NULL) {
472 unsigned text_size = va_arg(va, unsigned);
473 md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size);
474 }
475 len = sha_end(&pre->hashed_key_xor_ipad, out);
476
477 /* out = H((key XOR opad) + out) */
478 md5sha_hash(&pre->hashed_key_xor_opad, out, len);
479 return sha_end(&pre->hashed_key_xor_opad, out);
480}
481
482static unsigned hmac_sha_precomputed(hmac_precomputed_t *pre_init, uint8_t *out, ...)
483{
484 hmac_precomputed_t pre;
485 va_list va;
486 unsigned len;
487
488 va_start(va, out);
489 pre = *pre_init; /* struct copy */
490 len = hmac_sha_precomputed_v(&pre, out, va);
491 va_end(va);
492 return len;
493}
494
495#if !ENABLE_FEATURE_TLS_SHA1
496#define hmac(tls,out,key,key_size,...) \
497 hmac(out,key,key_size, __VA_ARGS__)
498#endif
499static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...)
500{
501 hmac_precomputed_t pre;
502 va_list va;
503 unsigned len;
504
505 va_start(va, key_size);
506
507 hmac_begin(&pre, key, key_size,
508 (ENABLE_FEATURE_TLS_SHA1 && tls->MAC_size == SHA1_OUTSIZE)
509 ? sha1_begin
510 : sha256_begin
511 );
512 len = hmac_sha_precomputed_v(&pre, out, va);
513
514 va_end(va);
515 return len;
516}
517
518// RFC 5246: 366// RFC 5246:
519// 5. HMAC and the Pseudorandom Function 367// 5. HMAC and the Pseudorandom Function
520//... 368//...
@@ -559,7 +407,7 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/
559 const char *label, 407 const char *label,
560 uint8_t *seed, unsigned seed_size) 408 uint8_t *seed, unsigned seed_size)
561{ 409{
562 hmac_precomputed_t pre; 410 hmac_ctx_t ctx;
563 uint8_t a[TLS_MAX_MAC_SIZE]; 411 uint8_t a[TLS_MAX_MAC_SIZE];
564 uint8_t *out_p = outbuf; 412 uint8_t *out_p = outbuf;
565 unsigned label_size = strlen(label); 413 unsigned label_size = strlen(label);
@@ -569,26 +417,26 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/
569#define SEED label, label_size, seed, seed_size 417#define SEED label, label_size, seed, seed_size
570#define A a, MAC_size 418#define A a, MAC_size
571 419
572 hmac_begin(&pre, secret, secret_size, sha256_begin); 420 hmac_begin(&ctx, secret, secret_size, sha256_begin);
573 421
574 /* A(1) = HMAC_hash(secret, seed) */ 422 /* A(1) = HMAC_hash(secret, seed) */
575 hmac_sha_precomputed(&pre, a, SEED, NULL); 423 hmac_peek_hash(&ctx, a, SEED, NULL);
576 424
577 for (;;) { 425 for (;;) {
578 /* HMAC_hash(secret, A(1) + seed) */ 426 /* HMAC_hash(secret, A(1) + seed) */
579 if (outbuf_size <= MAC_size) { 427 if (outbuf_size <= MAC_size) {
580 /* Last, possibly incomplete, block */ 428 /* Last, possibly incomplete, block */
581 /* (use a[] as temp buffer) */ 429 /* (use a[] as temp buffer) */
582 hmac_sha_precomputed(&pre, a, A, SEED, NULL); 430 hmac_peek_hash(&ctx, a, A, SEED, NULL);
583 memcpy(out_p, a, outbuf_size); 431 memcpy(out_p, a, outbuf_size);
584 return; 432 return;
585 } 433 }
586 /* Not last block. Store directly to result buffer */ 434 /* Not last block. Store directly to result buffer */
587 hmac_sha_precomputed(&pre, out_p, A, SEED, NULL); 435 hmac_peek_hash(&ctx, out_p, A, SEED, NULL);
588 out_p += MAC_size; 436 out_p += MAC_size;
589 outbuf_size -= MAC_size; 437 outbuf_size -= MAC_size;
590 /* A(2) = HMAC_hash(secret, A(1)) */ 438 /* A(2) = HMAC_hash(secret, A(1)) */
591 hmac_sha_precomputed(&pre, a, A, NULL); 439 hmac_peek_hash(&ctx, a, A, NULL);
592 } 440 }
593#undef A 441#undef A
594#undef SECRET 442#undef SECRET
@@ -655,6 +503,29 @@ static void *tls_get_zeroed_outbuf(tls_state_t *tls, int len)
655 return record; 503 return record;
656} 504}
657 505
506/* Calculate the HMAC over the list of blocks */
507#if !ENABLE_FEATURE_TLS_SHA1
508#define hmac_blocks(tls,out,key,key_size,...) \
509 hmac_blocks(out,key,key_size, __VA_ARGS__)
510#endif
511static unsigned hmac_blocks(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...)
512{
513 hmac_ctx_t ctx;
514 va_list va;
515
516 hmac_begin(&ctx, key, key_size,
517 (ENABLE_FEATURE_TLS_SHA1 && tls->MAC_size == SHA1_OUTSIZE)
518 ? sha1_begin
519 : sha256_begin
520 );
521
522 va_start(va, key_size);
523 hmac_hash_v(&ctx, va);
524 va_end(va);
525
526 return hmac_end(&ctx, out);
527}
528
658static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, unsigned type) 529static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, unsigned type)
659{ 530{
660 uint8_t *buf = tls->outbuf + OUTBUF_PFX; 531 uint8_t *buf = tls->outbuf + OUTBUF_PFX;
@@ -676,7 +547,7 @@ static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, un
676 xhdr->len16_lo = size & 0xff; 547 xhdr->len16_lo = size & 0xff;
677 548
678 /* Calculate MAC signature */ 549 /* Calculate MAC signature */
679 hmac(tls, buf + size, /* result */ 550 hmac_blocks(tls, buf + size, /* result */
680 tls->client_write_MAC_key, TLS_MAC_SIZE(tls), 551 tls->client_write_MAC_key, TLS_MAC_SIZE(tls),
681 &tls->write_seq64_be, sizeof(tls->write_seq64_be), 552 &tls->write_seq64_be, sizeof(tls->write_seq64_be),
682 xhdr, RECHDR_LEN, 553 xhdr, RECHDR_LEN,
@@ -865,8 +736,13 @@ static void xwrite_encrypted_aesgcm(tls_state_t *tls, unsigned size, unsigned ty
865 cnt++; 736 cnt++;
866 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */ 737 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */
867 aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch); 738 aes_encrypt_one_block(&tls->aes_encrypt, nonce, scratch);
868 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining; 739 if (remaining >= AES_BLOCK_SIZE) {
869 xorbuf(buf, scratch, n); 740 n = AES_BLOCK_SIZE;
741 xorbuf_AES_BLOCK_SIZE(buf, scratch);
742 } else {
743 n = remaining;
744 xorbuf(buf, scratch, n);
745 }
870 buf += n; 746 buf += n;
871 remaining -= n; 747 remaining -= n;
872 } 748 }
@@ -1024,7 +900,7 @@ static void tls_aesgcm_decrypt(tls_state_t *tls, uint8_t *buf, int size)
1024 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */ 900 COUNTER(nonce) = htonl(cnt); /* yes, first cnt here is 2 (!) */
1025 aes_encrypt_one_block(&tls->aes_decrypt, nonce, scratch); 901 aes_encrypt_one_block(&tls->aes_decrypt, nonce, scratch);
1026 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining; 902 n = remaining > AES_BLOCK_SIZE ? AES_BLOCK_SIZE : remaining;
1027 xorbuf3(buf, scratch, buf + 8, n); 903 xorbuf_3(buf, scratch, buf + 8, n);
1028 buf += n; 904 buf += n;
1029 remaining -= n; 905 remaining -= n;
1030 } 906 }