diff options
author | Nicolas Boichat <drinkcat@google.com> | 2017-06-10 10:44:46 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-06-14 05:59:37 -0700 |
commit | c5b31e3868079b50d3f0db72632271d2b1eedea8 (patch) | |
tree | 1fa198885df7630128e6735d0ea613ee9de122ce /common | |
parent | 98dc270b23ae2fc931ffb4960dd1c2127fed4c8f (diff) | |
download | chrome-ec-c5b31e3868079b50d3f0db72632271d2b1eedea8.tar.gz |
sha256: add support for hmac_sha256, and add test for sha256
BRANCH=none
BUG=b:38486828
TEST=make run-sha256
TEST=make buildall -j
Change-Id: I4c5b5d81ae5650ebfbdc989a0d860eeb0a60f68b
Reviewed-on: https://chromium-review.googlesource.com/530207
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/sha256.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/common/sha256.c b/common/sha256.c index 7e74a7f963..06478708b0 100644 --- a/common/sha256.c +++ b/common/sha256.c @@ -188,6 +188,23 @@ void SHA256_update(struct sha256_ctx *ctx, const uint8_t *data, uint32_t len) ctx->tot_len += (block_nb + 1) << 6; } +/* + * Specialized SHA256_init + SHA256_update that takes the first data block of + * size SHA256_BLOCK_SIZE as input. + */ +static void SHA256_init_1b(struct sha256_ctx *ctx, const uint8_t *data) +{ + int i; + + for (i = 0; i < 8; i++) + ctx->h[i] = sha256_h0[i]; + + SHA256_transform(ctx, data, 1); + + ctx->len = 0; + ctx->tot_len = SHA256_BLOCK_SIZE; +} + uint8_t *SHA256_final(struct sha256_ctx *ctx) { unsigned int block_nb; @@ -212,3 +229,43 @@ uint8_t *SHA256_final(struct sha256_ctx *ctx) return ctx->buf; } + +static void hmac_SHA256_step(uint8_t *output, uint8_t mask, + const uint8_t *key, const int key_len, + const uint8_t *data, const int data_len) { + struct sha256_ctx ctx; + uint8_t *key_pad = ctx.block; + uint8_t *tmp; + int i; + + /* key_pad = key (zero-padded) ^ mask */ + memset(key_pad, mask, SHA256_BLOCK_SIZE); + for (i = 0; i < key_len; i++) + key_pad[i] ^= key[i]; + + /* tmp = hash(key_pad || message) */ + SHA256_init_1b(&ctx, key_pad); + SHA256_update(&ctx, data, data_len); + tmp = SHA256_final(&ctx); + memcpy(output, tmp, SHA256_DIGEST_SIZE); +} + +void hmac_SHA256(uint8_t *output, const uint8_t *key, const int key_len, + const uint8_t *message, const int message_len) { + /* This code does not support key_len > block_size. */ + ASSERT(key_len <= SHA256_BLOCK_SIZE); + + /* + * i_key_pad = key (zero-padded) ^ 0x36 + * output = hash(i_key_pad || message) + * (Use output as temporary buffer) + */ + hmac_SHA256_step(output, 0x36, key, key_len, message, message_len); + + /* + * o_key_pad = key (zero-padded) ^ 0x5c + * output = hash(o_key_pad || output) + */ + hmac_SHA256_step(output, 0x5c, + key, key_len, output, SHA256_DIGEST_SIZE); +} |