From d9f6c3b091cc1a2a824520e22764ea1538957f3d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 26 Nov 2018 15:55:41 +0100 Subject: 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 --- networking/tls.c | 79 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 40 deletions(-) (limited to 'networking/tls.c') 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 { md5sha_ctx_t hashed_key_xor_opad; } hmac_precomputed_t; -static unsigned hmac_sha_precomputed_v( - hmac_precomputed_t *pre, - uint8_t *out, - va_list va) -{ - uint8_t *text; - unsigned len; - - /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */ - /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */ - - /* calculate out = H((key XOR ipad) + text) */ - while ((text = va_arg(va, uint8_t*)) != NULL) { - unsigned text_size = va_arg(va, unsigned); - md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size); - } - len = sha_end(&pre->hashed_key_xor_ipad, out); - - /* out = H((key XOR opad) + out) */ - md5sha_hash(&pre->hashed_key_xor_opad, out, len); - return sha_end(&pre->hashed_key_xor_opad, out); -} - typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC; static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin) { @@ -485,26 +462,43 @@ static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE); } -static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) +static unsigned hmac_sha_precomputed_v( + hmac_precomputed_t *pre, + uint8_t *out, + va_list va) +{ + uint8_t *text; + unsigned len; + + /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */ + /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */ + + /* calculate out = H((key XOR ipad) + text) */ + while ((text = va_arg(va, uint8_t*)) != NULL) { + unsigned text_size = va_arg(va, unsigned); + md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size); + } + len = sha_end(&pre->hashed_key_xor_ipad, out); + + /* out = H((key XOR opad) + out) */ + md5sha_hash(&pre->hashed_key_xor_opad, out, len); + return sha_end(&pre->hashed_key_xor_opad, out); +} + +static unsigned hmac_sha_precomputed(hmac_precomputed_t *pre_init, uint8_t *out, ...) { hmac_precomputed_t pre; va_list va; unsigned len; - va_start(va, key_size); - - hmac_begin(&pre, key, key_size, - (tls->MAC_size == SHA256_OUTSIZE) - ? sha256_begin - : sha1_begin - ); + va_start(va, out); + pre = *pre_init; /* struct copy */ len = hmac_sha_precomputed_v(&pre, out, va); - va_end(va); return len; } -static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, unsigned key_size, ...) +static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) { hmac_precomputed_t pre; va_list va; @@ -512,7 +506,11 @@ static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, un va_start(va, key_size); - hmac_begin(&pre, key, key_size, sha256_begin); + hmac_begin(&pre, key, key_size, + (tls->MAC_size == SHA256_OUTSIZE) + ? sha256_begin + : sha1_begin + ); len = hmac_sha_precomputed_v(&pre, out, va); va_end(va); @@ -563,6 +561,7 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/ const char *label, uint8_t *seed, unsigned seed_size) { + hmac_precomputed_t pre; uint8_t a[TLS_MAX_MAC_SIZE]; uint8_t *out_p = outbuf; unsigned label_size = strlen(label); @@ -570,28 +569,28 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/ /* In P_hash() calculation, "seed" is "label + seed": */ #define SEED label, label_size, seed, seed_size -#define SECRET secret, secret_size #define A a, MAC_size + hmac_begin(&pre, secret, secret_size, sha256_begin); + /* A(1) = HMAC_hash(secret, seed) */ - hmac_sha256(/*tls,*/ a, SECRET, SEED, NULL); -//TODO: convert hmac to precomputed + hmac_sha_precomputed(&pre, a, SEED, NULL); for (;;) { /* HMAC_hash(secret, A(1) + seed) */ if (outbuf_size <= MAC_size) { /* Last, possibly incomplete, block */ /* (use a[] as temp buffer) */ - hmac_sha256(/*tls,*/ a, SECRET, A, SEED, NULL); + hmac_sha_precomputed(&pre, a, A, SEED, NULL); memcpy(out_p, a, outbuf_size); return; } /* Not last block. Store directly to result buffer */ - hmac_sha256(/*tls,*/ out_p, SECRET, A, SEED, NULL); + hmac_sha_precomputed(&pre, out_p, A, SEED, NULL); out_p += MAC_size; outbuf_size -= MAC_size; /* A(2) = HMAC_hash(secret, A(1)) */ - hmac_sha256(/*tls,*/ a, SECRET, A, NULL); + hmac_sha_precomputed(&pre, a, A, NULL); } #undef A #undef SECRET -- cgit v1.2.3