summaryrefslogtreecommitdiffhomepage
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)
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 {
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