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.
This commit is contained in:
Dag-Erling Smørgrav 2014-07-11 10:28:55 +00:00 committed by des
parent 950a1770e5
commit 5bb81214cc
2 changed files with 29 additions and 20 deletions

View file

@ -43,8 +43,8 @@
#define hmac_sha1_complete cryb_hmac_sha1_complete #define hmac_sha1_complete cryb_hmac_sha1_complete
typedef struct { typedef struct {
sha1_ctx sha1_ctx; sha1_ctx ictx;
uint8_t key[64]; sha1_ctx octx;
} hmac_sha1_ctx; } hmac_sha1_ctx;
void hmac_sha1_init(hmac_sha1_ctx *, const void *, size_t); void hmac_sha1_init(hmac_sha1_ctx *, const void *, size_t);

View file

@ -52,38 +52,47 @@
void void
hmac_sha1_init(hmac_sha1_ctx *ctx, const void *key, size_t keylen) 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); /* prepare key */
if (keylen > sizeof ctx->key) memset(keybuf, 0, sizeof keybuf);
sha1_complete(key, keylen, ctx->key); if (keylen > sizeof keybuf)
sha1_complete(key, keylen, keybuf);
else else
memcpy(ctx->key, key, keylen); memcpy(keybuf, key, keylen);
sha1_init(&ctx->sha1_ctx);
for (unsigned int i = 0; i < sizeof ipad; ++i) /* input pad */
ipad[i] = 0x36 ^ ctx->key[i]; for (unsigned int i = 0; i < sizeof pad; ++i)
sha1_update(&ctx->sha1_ctx, ipad, sizeof ipad); 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 void
hmac_sha1_update(hmac_sha1_ctx *ctx, const void *buf, size_t len) 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 void
hmac_sha1_final(hmac_sha1_ctx *ctx, void *mac) 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); sha1_final(&ctx->ictx, digest);
for (unsigned int i = 0; i < sizeof opad; ++i) sha1_update(&ctx->octx, digest, sizeof digest);
opad[i] = 0x5c ^ ctx->key[i]; sha1_final(&ctx->octx, mac);
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);
memset(ctx, 0, sizeof *ctx); memset(ctx, 0, sizeof *ctx);
} }