diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-11-26 15:55:41 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-11-26 15:55:41 +0100 |
commit | d9f6c3b091cc1a2a824520e22764ea1538957f3d (patch) | |
tree | f78ceec6de89fb7a8ae489c588f88a282fae362f | |
parent | f69f207490dd25b89380c21e816b1f6644a7529f (diff) | |
download | busybox-w32-d9f6c3b091cc1a2a824520e22764ea1538957f3d.tar.gz busybox-w32-d9f6c3b091cc1a2a824520e22764ea1538957f3d.tar.bz2 busybox-w32-d9f6c3b091cc1a2a824520e22764ea1538957f3d.zip |
tls: speed up prf_hmac_sha256()
function old new delta
hmac_sha_precomputed - 58 +58
prf_hmac_sha256 181 222 +41
hmac_sha256 68 - -68
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 1/0 up/down: 99/-68) Total: 31 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/tls.c | 79 |
1 files changed, 39 insertions, 40 deletions
diff --git a/networking/tls.c b/networking/tls.c index 002983273..6c87e12ff 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -420,29 +420,6 @@ typedef struct hmac_precomputed { | |||
420 | md5sha_ctx_t hashed_key_xor_opad; | 420 | md5sha_ctx_t hashed_key_xor_opad; |
421 | } hmac_precomputed_t; | 421 | } hmac_precomputed_t; |
422 | 422 | ||
423 | static unsigned hmac_sha_precomputed_v( | ||
424 | hmac_precomputed_t *pre, | ||
425 | uint8_t *out, | ||
426 | va_list va) | ||
427 | { | ||
428 | uint8_t *text; | ||
429 | unsigned len; | ||
430 | |||
431 | /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */ | ||
432 | /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */ | ||
433 | |||
434 | /* calculate out = H((key XOR ipad) + text) */ | ||
435 | while ((text = va_arg(va, uint8_t*)) != NULL) { | ||
436 | unsigned text_size = va_arg(va, unsigned); | ||
437 | md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size); | ||
438 | } | ||
439 | len = sha_end(&pre->hashed_key_xor_ipad, out); | ||
440 | |||
441 | /* out = H((key XOR opad) + out) */ | ||
442 | md5sha_hash(&pre->hashed_key_xor_opad, out, len); | ||
443 | return sha_end(&pre->hashed_key_xor_opad, out); | ||
444 | } | ||
445 | |||
446 | typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC; | 423 | typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC; |
447 | static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin) | 424 | static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin) |
448 | { | 425 | { |
@@ -485,26 +462,43 @@ static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, | |||
485 | md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE); | 462 | md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE); |
486 | } | 463 | } |
487 | 464 | ||
488 | static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) | 465 | static unsigned hmac_sha_precomputed_v( |
466 | hmac_precomputed_t *pre, | ||
467 | uint8_t *out, | ||
468 | va_list va) | ||
469 | { | ||
470 | uint8_t *text; | ||
471 | unsigned len; | ||
472 | |||
473 | /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */ | ||
474 | /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */ | ||
475 | |||
476 | /* calculate out = H((key XOR ipad) + text) */ | ||
477 | while ((text = va_arg(va, uint8_t*)) != NULL) { | ||
478 | unsigned text_size = va_arg(va, unsigned); | ||
479 | md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size); | ||
480 | } | ||
481 | len = sha_end(&pre->hashed_key_xor_ipad, out); | ||
482 | |||
483 | /* out = H((key XOR opad) + out) */ | ||
484 | md5sha_hash(&pre->hashed_key_xor_opad, out, len); | ||
485 | return sha_end(&pre->hashed_key_xor_opad, out); | ||
486 | } | ||
487 | |||
488 | static unsigned hmac_sha_precomputed(hmac_precomputed_t *pre_init, uint8_t *out, ...) | ||
489 | { | 489 | { |
490 | hmac_precomputed_t pre; | 490 | hmac_precomputed_t pre; |
491 | va_list va; | 491 | va_list va; |
492 | unsigned len; | 492 | unsigned len; |
493 | 493 | ||
494 | va_start(va, key_size); | 494 | va_start(va, out); |
495 | 495 | pre = *pre_init; /* struct copy */ | |
496 | hmac_begin(&pre, key, key_size, | ||
497 | (tls->MAC_size == SHA256_OUTSIZE) | ||
498 | ? sha256_begin | ||
499 | : sha1_begin | ||
500 | ); | ||
501 | len = hmac_sha_precomputed_v(&pre, out, va); | 496 | len = hmac_sha_precomputed_v(&pre, out, va); |
502 | |||
503 | va_end(va); | 497 | va_end(va); |
504 | return len; | 498 | return len; |
505 | } | 499 | } |
506 | 500 | ||
507 | static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, unsigned key_size, ...) | 501 | static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) |
508 | { | 502 | { |
509 | hmac_precomputed_t pre; | 503 | hmac_precomputed_t pre; |
510 | va_list va; | 504 | va_list va; |
@@ -512,7 +506,11 @@ static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, un | |||
512 | 506 | ||
513 | va_start(va, key_size); | 507 | va_start(va, key_size); |
514 | 508 | ||
515 | hmac_begin(&pre, key, key_size, sha256_begin); | 509 | hmac_begin(&pre, key, key_size, |
510 | (tls->MAC_size == SHA256_OUTSIZE) | ||
511 | ? sha256_begin | ||
512 | : sha1_begin | ||
513 | ); | ||
516 | len = hmac_sha_precomputed_v(&pre, out, va); | 514 | len = hmac_sha_precomputed_v(&pre, out, va); |
517 | 515 | ||
518 | va_end(va); | 516 | va_end(va); |
@@ -563,6 +561,7 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/ | |||
563 | const char *label, | 561 | const char *label, |
564 | uint8_t *seed, unsigned seed_size) | 562 | uint8_t *seed, unsigned seed_size) |
565 | { | 563 | { |
564 | hmac_precomputed_t pre; | ||
566 | uint8_t a[TLS_MAX_MAC_SIZE]; | 565 | uint8_t a[TLS_MAX_MAC_SIZE]; |
567 | uint8_t *out_p = outbuf; | 566 | uint8_t *out_p = outbuf; |
568 | unsigned label_size = strlen(label); | 567 | unsigned label_size = strlen(label); |
@@ -570,28 +569,28 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/ | |||
570 | 569 | ||
571 | /* In P_hash() calculation, "seed" is "label + seed": */ | 570 | /* In P_hash() calculation, "seed" is "label + seed": */ |
572 | #define SEED label, label_size, seed, seed_size | 571 | #define SEED label, label_size, seed, seed_size |
573 | #define SECRET secret, secret_size | ||
574 | #define A a, MAC_size | 572 | #define A a, MAC_size |
575 | 573 | ||
574 | hmac_begin(&pre, secret, secret_size, sha256_begin); | ||
575 | |||
576 | /* A(1) = HMAC_hash(secret, seed) */ | 576 | /* A(1) = HMAC_hash(secret, seed) */ |
577 | hmac_sha256(/*tls,*/ a, SECRET, SEED, NULL); | 577 | hmac_sha_precomputed(&pre, a, SEED, NULL); |
578 | //TODO: convert hmac to precomputed | ||
579 | 578 | ||
580 | for (;;) { | 579 | for (;;) { |
581 | /* HMAC_hash(secret, A(1) + seed) */ | 580 | /* HMAC_hash(secret, A(1) + seed) */ |
582 | if (outbuf_size <= MAC_size) { | 581 | if (outbuf_size <= MAC_size) { |
583 | /* Last, possibly incomplete, block */ | 582 | /* Last, possibly incomplete, block */ |
584 | /* (use a[] as temp buffer) */ | 583 | /* (use a[] as temp buffer) */ |
585 | hmac_sha256(/*tls,*/ a, SECRET, A, SEED, NULL); | 584 | hmac_sha_precomputed(&pre, a, A, SEED, NULL); |
586 | memcpy(out_p, a, outbuf_size); | 585 | memcpy(out_p, a, outbuf_size); |
587 | return; | 586 | return; |
588 | } | 587 | } |
589 | /* Not last block. Store directly to result buffer */ | 588 | /* Not last block. Store directly to result buffer */ |
590 | hmac_sha256(/*tls,*/ out_p, SECRET, A, SEED, NULL); | 589 | hmac_sha_precomputed(&pre, out_p, A, SEED, NULL); |
591 | out_p += MAC_size; | 590 | out_p += MAC_size; |
592 | outbuf_size -= MAC_size; | 591 | outbuf_size -= MAC_size; |
593 | /* A(2) = HMAC_hash(secret, A(1)) */ | 592 | /* A(2) = HMAC_hash(secret, A(1)) */ |
594 | hmac_sha256(/*tls,*/ a, SECRET, A, NULL); | 593 | hmac_sha_precomputed(&pre, a, A, NULL); |
595 | } | 594 | } |
596 | #undef A | 595 | #undef A |
597 | #undef SECRET | 596 | #undef SECRET |