summaryrefslogtreecommitdiff
path: root/common/sha256.c
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@google.com>2017-06-10 10:44:46 +0800
committerchrome-bot <chrome-bot@chromium.org>2017-06-14 05:59:37 -0700
commitc5b31e3868079b50d3f0db72632271d2b1eedea8 (patch)
tree1fa198885df7630128e6735d0ea613ee9de122ce /common/sha256.c
parent98dc270b23ae2fc931ffb4960dd1c2127fed4c8f (diff)
downloadchrome-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/sha256.c')
-rw-r--r--common/sha256.c57
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);
+}