From 5bb81214ccc5d285cf81f39e7b86df0a6f96bf42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 11 Jul 2014 10:28:55 +0000 Subject: [PATCH] Instead of storing the key in the hmac_sha1_ctx so we can compute the output pad in hmac_sha1_final(), prepare a sha1 context in advance and discard the key as early as possible. Inspired by Colin Percival's HMAC-SHA-256 implementation. --- include/cryb/hmac_sha1.h | 4 ++-- lib/mac/hmac_sha1.c | 45 ++++++++++++++++++++++++---------------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/include/cryb/hmac_sha1.h b/include/cryb/hmac_sha1.h index 96bdd28..8e9800b 100644 --- a/include/cryb/hmac_sha1.h +++ b/include/cryb/hmac_sha1.h @@ -43,8 +43,8 @@ #define hmac_sha1_complete cryb_hmac_sha1_complete typedef struct { - sha1_ctx sha1_ctx; - uint8_t key[64]; + sha1_ctx ictx; + sha1_ctx octx; } hmac_sha1_ctx; void hmac_sha1_init(hmac_sha1_ctx *, const void *, size_t); diff --git a/lib/mac/hmac_sha1.c b/lib/mac/hmac_sha1.c index 55c1e90..e054b1c 100644 --- a/lib/mac/hmac_sha1.c +++ b/lib/mac/hmac_sha1.c @@ -52,38 +52,47 @@ void hmac_sha1_init(hmac_sha1_ctx *ctx, const void *key, size_t keylen) { - uint8_t ipad[64]; + uint8_t keybuf[SHA1_BLOCK_LEN], pad[SHA1_BLOCK_LEN]; - memset(ctx, 0, sizeof *ctx); - if (keylen > sizeof ctx->key) - sha1_complete(key, keylen, ctx->key); + /* prepare key */ + memset(keybuf, 0, sizeof keybuf); + if (keylen > sizeof keybuf) + sha1_complete(key, keylen, keybuf); else - memcpy(ctx->key, key, keylen); - sha1_init(&ctx->sha1_ctx); - for (unsigned int i = 0; i < sizeof ipad; ++i) - ipad[i] = 0x36 ^ ctx->key[i]; - sha1_update(&ctx->sha1_ctx, ipad, sizeof ipad); + memcpy(keybuf, key, keylen); + + /* input pad */ + for (unsigned int i = 0; i < sizeof pad; ++i) + pad[i] = 0x36 ^ keybuf[i]; + sha1_init(&ctx->ictx); + sha1_update(&ctx->ictx, pad, sizeof pad); + + /* output pad */ + for (unsigned int i = 0; i < sizeof pad; ++i) + pad[i] = 0x5c ^ keybuf[i]; + sha1_init(&ctx->octx); + sha1_update(&ctx->octx, pad, sizeof pad); + + /* hide the evidence */ + memset(keybuf, 0, sizeof keybuf); + memset(pad, 0, sizeof pad); } void hmac_sha1_update(hmac_sha1_ctx *ctx, const void *buf, size_t len) { - sha1_update(&ctx->sha1_ctx, buf, len); + sha1_update(&ctx->ictx, buf, len); } void hmac_sha1_final(hmac_sha1_ctx *ctx, void *mac) { - uint8_t digest[20], opad[64]; + uint8_t digest[SHA1_DIGEST_LEN]; - sha1_final(&ctx->sha1_ctx, digest); - for (unsigned int i = 0; i < sizeof opad; ++i) - opad[i] = 0x5c ^ ctx->key[i]; - sha1_init(&ctx->sha1_ctx); - sha1_update(&ctx->sha1_ctx, opad, sizeof opad); - sha1_update(&ctx->sha1_ctx, digest, sizeof digest); - sha1_final(&ctx->sha1_ctx, mac); + sha1_final(&ctx->ictx, digest); + sha1_update(&ctx->octx, digest, sizeof digest); + sha1_final(&ctx->octx, mac); memset(ctx, 0, sizeof *ctx); }