summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2016-05-05 17:21:29 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-05-10 19:41:46 -0700
commitf3f9e00ef037695c4e792948effa1253f680c118 (patch)
treecb60549b87c41f99138ec69b7a9a403b048c612c /firmware
parent5319565988fc5b1862d649fad985859929946a91 (diff)
downloadvboot-f3f9e00ef037695c4e792948effa1253f680c118.tar.gz
hmac: Add HMAC to 2lib library
This patch adds HMAC. HMAC will be used to sign/verify NVM structures. Hash algorithms can be selected from those supported by enum vb2_hash_algorithm (i.e. SHA1, SHA256, or SHA512). BUG=chrome-os-partner:51907 BRANCH=tot TEST=make runtests Change-Id: I6d349bc807874fe2a5512aabcd7fbf67a4eaa40a Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/342880 Reviewed-by: Randall Spangler <rspangler@chromium.org>
Diffstat (limited to 'firmware')
-rw-r--r--firmware/2lib/2hmac.c60
-rw-r--r--firmware/2lib/2sha_utility.c40
-rw-r--r--firmware/2lib/include/2crypto.h3
-rw-r--r--firmware/2lib/include/2hmac.h29
-rw-r--r--firmware/2lib/include/2sha.h26
5 files changed, 158 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;
+}
diff --git a/firmware/2lib/2sha_utility.c b/firmware/2lib/2sha_utility.c
index b75f0e58..dd74f290 100644
--- a/firmware/2lib/2sha_utility.c
+++ b/firmware/2lib/2sha_utility.c
@@ -70,6 +70,46 @@ int vb2_digest_size(enum vb2_hash_algorithm hash_alg)
}
}
+int vb2_hash_block_size(enum vb2_hash_algorithm alg)
+{
+ switch (alg) {
+#if VB2_SUPPORT_SHA1
+ case VB2_HASH_SHA1:
+ return VB2_SHA1_BLOCK_SIZE;
+#endif
+#if VB2_SUPPORT_SHA256
+ case VB2_HASH_SHA256:
+ return VB2_SHA256_BLOCK_SIZE;
+#endif
+#if VB2_SUPPORT_SHA512
+ case VB2_HASH_SHA512:
+ return VB2_SHA512_BLOCK_SIZE;
+#endif
+ default:
+ return 0;
+ }
+}
+
+const char *vb2_get_hash_algorithm_name(enum vb2_hash_algorithm alg)
+{
+ switch (alg) {
+#if VB2_SUPPORT_SHA1
+ case VB2_HASH_SHA1:
+ return VB2_SHA1_ALG_NAME;
+#endif
+#if VB2_SUPPORT_SHA256
+ case VB2_HASH_SHA256:
+ return VB2_SHA256_ALG_NAME;
+#endif
+#if VB2_SUPPORT_SHA512
+ case VB2_HASH_SHA512:
+ return VB2_SHA512_ALG_NAME;
+#endif
+ default:
+ return VB2_INVALID_ALG_NAME;
+ }
+}
+
int vb2_digest_init(struct vb2_digest_context *dc,
enum vb2_hash_algorithm hash_alg)
{
diff --git a/firmware/2lib/include/2crypto.h b/firmware/2lib/include/2crypto.h
index 9cc877c7..c1f225d7 100644
--- a/firmware/2lib/include/2crypto.h
+++ b/firmware/2lib/include/2crypto.h
@@ -57,6 +57,9 @@ enum vb2_hash_algorithm {
/* SHA-256 and SHA-512 */
VB2_HASH_SHA256 = 2,
VB2_HASH_SHA512 = 3,
+
+ /* Last index. Don't add anything below. */
+ VB2_HASH_ALG_COUNT,
};
#endif /* VBOOT_REFERENCE_VBOOT_2CRYPTO_H_ */
diff --git a/firmware/2lib/include/2hmac.h b/firmware/2lib/include/2hmac.h
new file mode 100644
index 00000000..1df19397
--- /dev/null
+++ b/firmware/2lib/include/2hmac.h
@@ -0,0 +1,29 @@
+/* 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.
+ */
+
+#ifndef VBOOT_REFERENCE_VBOOT_2HMAC_H_
+#define VBOOT_REFERENCE_VBOOT_2HMAC_H_
+
+#include <stdint.h>
+#include "2crypto.h"
+
+/**
+ * Compute HMAC
+ *
+ * @param alg Hash algorithm ID
+ * @param key HMAC key
+ * @param key_size HMAC key size
+ * @param msg Message to compute HMAC for
+ * @param msg_size Message size
+ * @param mac Computed message authentication code
+ * @param mac_size Size of the buffer pointed by <mac>
+ * @return
+ */
+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);
+
+#endif
diff --git a/firmware/2lib/include/2sha.h b/firmware/2lib/include/2sha.h
index 24590244..0077f379 100644
--- a/firmware/2lib/include/2sha.h
+++ b/firmware/2lib/include/2sha.h
@@ -27,8 +27,15 @@
#define VB2_SUPPORT_SHA512 1
#endif
+/* These are set to the biggest values among the supported hash algorithms.
+ * They have to be updated as we add new hash algorithms */
+#define VB2_MAX_DIGEST_SIZE VB2_SHA512_DIGEST_SIZE
+#define VB2_MAX_BLOCK_SIZE VB2_SHA512_BLOCK_SIZE
+#define VB2_INVALID_ALG_NAME "INVALID"
+
#define VB2_SHA1_DIGEST_SIZE 20
#define VB2_SHA1_BLOCK_SIZE 64
+#define VB2_SHA1_ALG_NAME "SHA1"
/* Context structs for hash algorithms */
@@ -47,6 +54,7 @@ struct vb2_sha1_context {
#define VB2_SHA256_DIGEST_SIZE 32
#define VB2_SHA256_BLOCK_SIZE 64
+#define VB2_SHA256_ALG_NAME "SHA256"
struct vb2_sha256_context {
uint32_t h[8];
@@ -57,6 +65,7 @@ struct vb2_sha256_context {
#define VB2_SHA512_DIGEST_SIZE 64
#define VB2_SHA512_BLOCK_SIZE 128
+#define VB2_SHA512_ALG_NAME "SHA512"
struct vb2_sha512_context {
uint64_t h[8];
@@ -143,6 +152,23 @@ enum vb2_hash_algorithm vb2_crypto_to_hash(uint32_t algorithm);
int vb2_digest_size(enum vb2_hash_algorithm hash_alg);
/**
+ * Return the block size of a hash algorithm.
+ *
+ * @param hash_alg Hash algorithm
+ * @return The block size of the algorithm, or 0 if error.
+ */
+int vb2_hash_block_size(enum vb2_hash_algorithm alg);
+
+/**
+ * Return the name of a hash algorithm
+ *
+ * @param alg Hash algorithm ID
+ * @return String containing a hash name or VB2_INVALID_ALG_NAME
+ * if <alg> is invalid.
+ */
+const char *vb2_get_hash_algorithm_name(enum vb2_hash_algorithm alg);
+
+/**
* Initialize a digest context for doing block-style digesting.
*
* @param dc Digest context