diff options
Diffstat (limited to 'networking/tls.c')
-rw-r--r-- | networking/tls.c | 200 |
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 | ||
190 | enum { | 190 | enum { |
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 | ||
338 | static 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 | |||
347 | void FAST_FUNC xorbuf(void *dst, const void *src, unsigned count) | ||
348 | { | ||
349 | xorbuf3(dst, dst, src, count); | ||
350 | } | ||
351 | |||
352 | void 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. | ||
406 | typedef struct hmac_precomputed { | ||
407 | md5sha_ctx_t hashed_key_xor_ipad; | ||
408 | md5sha_ctx_t hashed_key_xor_opad; | ||
409 | } hmac_precomputed_t; | ||
410 | |||
411 | typedef 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 | ||
417 | static 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 | |||
459 | static 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 | |||
482 | static 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 | ||
499 | static 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 | ||
511 | static 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 | |||
658 | static void xwrite_encrypted_and_hmac_signed(tls_state_t *tls, unsigned size, unsigned type) | 529 | static 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 | } |