summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-11-26 15:55:41 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-11-26 15:55:41 +0100
commitd9f6c3b091cc1a2a824520e22764ea1538957f3d (patch)
treef78ceec6de89fb7a8ae489c588f88a282fae362f
parentf69f207490dd25b89380c21e816b1f6644a7529f (diff)
downloadbusybox-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.c79
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
423static 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
446typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC; 423typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC;
447static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin) 424static 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
488static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) 465static 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
488static 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
507static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, unsigned key_size, ...) 501static 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