summaryrefslogtreecommitdiff
path: root/firmware/2lib/2hmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/2lib/2hmac.c')
-rw-r--r--firmware/2lib/2hmac.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/firmware/2lib/2hmac.c b/firmware/2lib/2hmac.c
new file mode 100644
index 00000000..651ae57f
--- /dev/null
+++ b/firmware/2lib/2hmac.c
@@ -0,0 +1,60 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "2sysincludes.h"
+#include "2sha.h"
+#include "2hmac.h"
+
+int hmac(enum vb2_hash_algorithm alg,
+ const void *key, uint32_t key_size,
+ const void *msg, uint32_t msg_size,
+ uint8_t *mac, uint32_t mac_size)
+{
+ uint32_t block_size;
+ uint32_t digest_size;
+ uint8_t k[VB2_MAX_BLOCK_SIZE];
+ uint8_t o_pad[VB2_MAX_BLOCK_SIZE];
+ uint8_t i_pad[VB2_MAX_BLOCK_SIZE];
+ uint8_t b[VB2_MAX_DIGEST_SIZE];
+ struct vb2_digest_context dc;
+ int i;
+
+ if (!key | !msg | !mac)
+ return -1;
+
+ digest_size = vb2_digest_size(alg);
+ block_size = vb2_hash_block_size(alg);
+ if (!digest_size || !block_size)
+ return -1;
+
+ if (mac_size < digest_size)
+ return -1;
+
+ if (key_size > block_size) {
+ vb2_digest_buffer((uint8_t *)key, key_size, alg, k, block_size);
+ key_size = digest_size;
+ } else {
+ memcpy(k, key, key_size);
+ }
+ if (key_size < block_size)
+ memset(k + key_size, 0, block_size - key_size);
+
+ for (i = 0; i < block_size; i++) {
+ o_pad[i] = 0x5c ^ k[i];
+ i_pad[i] = 0x36 ^ k[i];
+ }
+
+ vb2_digest_init(&dc, alg);
+ vb2_digest_extend(&dc, i_pad, block_size);
+ vb2_digest_extend(&dc, msg, msg_size);
+ vb2_digest_finalize(&dc, b, digest_size);
+
+ vb2_digest_init(&dc, alg);
+ vb2_digest_extend(&dc, o_pad, block_size);
+ vb2_digest_extend(&dc, b, digest_size);
+ vb2_digest_finalize(&dc, mac, mac_size);
+
+ return 0;
+}