diff options
author | Daisuke Nojiri <dnojiri@chromium.org> | 2016-05-05 17:21:29 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-05-10 19:41:46 -0700 |
commit | f3f9e00ef037695c4e792948effa1253f680c118 (patch) | |
tree | cb60549b87c41f99138ec69b7a9a403b048c612c /firmware | |
parent | 5319565988fc5b1862d649fad985859929946a91 (diff) | |
download | vboot-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.c | 60 | ||||
-rw-r--r-- | firmware/2lib/2sha_utility.c | 40 | ||||
-rw-r--r-- | firmware/2lib/include/2crypto.h | 3 | ||||
-rw-r--r-- | firmware/2lib/include/2hmac.h | 29 | ||||
-rw-r--r-- | firmware/2lib/include/2sha.h | 26 |
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 |