summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2022-08-09 18:40:10 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-09-01 03:36:21 +0000
commit5ab30ec1c81a48c8857fb8fbbeee607074a0996f (patch)
tree7ca3662594636177b3d2bb9f9c7864a413227a5d
parent32e861a8d6411a6f4bd7ae3ed17b645072775d3c (diff)
downloadvboot-5ab30ec1c81a48c8857fb8fbbeee607074a0996f.tar.gz
firmware: 2sha: Integrate HW crypto directly into vb2_digest API
This patch moves the connection to the vb2ex_hwcrypto API further down the stack, into the low-level vb2_digest and vb2_hash APIs. These functions will now take an extra allow_hwcrypto argument that the caller can use to deny or allow hwcrypto by policy. If allowed, the function will try HW crypto first and fall back to the software implementation if the selected algorithm is not supported. vb2_hwcrypto_allowed() is made available to external callers as a vb2api function to make that decision in most cases (for others, like userspace tools and testing, HW crypto is generally not used anyway and they can just pass `false`). Since vb2ex_hwcrypto_digest_init() takes a data_size argument for the total amount of bytes expected, vb2_digest_init() will now also need to take this extra argument. But since the total data size cannot always be known in advance, callers are allowed to pass 0 to indicate that the size is unknown. The software implementations work either way, and HW crypto implementations will now need to check if data_size is 0 and return HWCRYPTO_UNSUPPORTED if they cannot handle this case. While we're touching everything anyway, let's take this opportunity to retire the vb2_digest_buffer() API in favor of the newer and usually more convenient vb2_hash_calculate(), so we can limit the amount of separate APIs we have to support going forward. BRANCH=none BUG=b:240624460 TEST=runtests Signed-off-by: Julius Werner <jwerner@chromium.org> Cq-Depend: chromium:3854282 Change-Id: I34c3f54e31742619d422d1cd871bdb77ad0439b7 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3825558 Reviewed-by: Yu-Ping Wu <yupingso@chromium.org>
-rw-r--r--firmware/2lib/2api.c33
-rw-r--r--firmware/2lib/2common.c38
-rw-r--r--firmware/2lib/2firmware.c4
-rw-r--r--firmware/2lib/2hmac.c8
-rw-r--r--firmware/2lib/2load_kernel.c18
-rw-r--r--firmware/2lib/2misc.c29
-rw-r--r--firmware/2lib/2sha_utility.c58
-rw-r--r--firmware/2lib/2struct.c28
-rw-r--r--firmware/2lib/include/2api.h15
-rw-r--r--firmware/2lib/include/2rsa.h2
-rw-r--r--firmware/2lib/include/2secdata.h20
-rw-r--r--firmware/2lib/include/2sha.h45
-rw-r--r--firmware/2lib/include/2sysincludes.h1
-rw-r--r--firmware/lib20/api_kernel.c3
-rw-r--r--futility/cmd_create.c6
-rw-r--r--futility/cmd_gscvd.c12
-rw-r--r--futility/cmd_pcr.c8
-rw-r--r--futility/file_type_usbpd1.c10
-rw-r--r--futility/misc.c25
-rw-r--r--futility/vb2_helper.c38
-rw-r--r--host/lib/file_keys.c2
-rw-r--r--host/lib/host_signature.c21
-rw-r--r--host/lib/host_signature2.c19
-rw-r--r--host/lib/signature_digest.c12
-rw-r--r--host/lib/util_misc.c16
-rw-r--r--host/lib21/host_common.c2
-rw-r--r--host/lib21/host_signature.c2
-rw-r--r--tests/sha_benchmark.c5
-rw-r--r--tests/vb20_api_kernel_tests.c2
-rw-r--r--tests/vb20_kernel_tests.c15
-rw-r--r--tests/vb2_api_tests.c135
-rw-r--r--tests/vb2_common2_tests.c39
-rw-r--r--tests/vb2_load_kernel2_tests.c5
-rw-r--r--tests/vb2_load_kernel_tests.c10
-rw-r--r--tests/vb2_sha256_x86_tests.c6
-rw-r--r--tests/vb2_sha_api_tests.c178
-rw-r--r--tests/vb2_sha_tests.c90
37 files changed, 474 insertions, 486 deletions
diff --git a/firmware/2lib/2api.c b/firmware/2lib/2api.c
index 13b3a697..ee63af3c 100644
--- a/firmware/2lib/2api.c
+++ b/firmware/2lib/2api.c
@@ -148,10 +148,7 @@ vb2_error_t vb2api_extend_hash(struct vb2_context *ctx,
sd->hash_remaining_size -= size;
- if (dc->using_hwcrypto)
- return vb2ex_hwcrypto_digest_extend(buf, size);
- else
- return vb2_digest_extend(dc, buf, size);
+ return vb2_digest_extend(dc, buf, size);
}
vb2_error_t vb2api_get_pcr_digest(struct vb2_context *ctx,
@@ -264,25 +261,8 @@ vb2_error_t vb2api_init_hash(struct vb2_context *ctx, uint32_t tag)
sd->hash_tag = tag;
sd->hash_remaining_size = pre->body_signature.data_size;
- if (vb2_hwcrypto_allowed(ctx)) {
- vb2_error_t rv = vb2ex_hwcrypto_digest_init(
- key.hash_alg, pre->body_signature.data_size);
- if (!rv) {
- VB2_DEBUG("Using HW crypto engine for hash_alg %d\n",
- key.hash_alg);
- dc->hash_alg = key.hash_alg;
- dc->using_hwcrypto = 1;
- return VB2_SUCCESS;
- }
- if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED)
- return rv;
- VB2_DEBUG("HW crypto for hash_alg %d not supported, using SW\n",
- key.hash_alg);
- } else {
- VB2_DEBUG("HW crypto forbidden by TPM flag, using SW\n");
- }
-
- return vb2_digest_init(dc, key.hash_alg);
+ return vb2_digest_init(dc, vb2api_hwcrypto_allowed(ctx),
+ key.hash_alg, pre->body_signature.data_size);
}
vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
@@ -321,10 +301,7 @@ vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST;
/* Finalize the digest */
- if (dc->using_hwcrypto)
- VB2_TRY(vb2ex_hwcrypto_digest_finalize(digest, digest_size));
- else
- VB2_TRY(vb2_digest_finalize(dc, digest, digest_size));
+ VB2_TRY(vb2_digest_finalize(dc, digest, digest_size));
/* The code below is specific to the body signature */
if (sd->hash_tag != VB2_HASH_TAG_FW_BODY)
@@ -343,7 +320,7 @@ vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx,
vb2_member_of(sd, sd->data_key_offset),
sd->data_key_size));
- key.allow_hwcrypto = vb2_hwcrypto_allowed(ctx);
+ key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx);
/*
* Check digest vs. signature. Note that this destroys the signature.
diff --git a/firmware/2lib/2common.c b/firmware/2lib/2common.c
index fa0585e3..d6ee701e 100644
--- a/firmware/2lib/2common.c
+++ b/firmware/2lib/2common.c
@@ -187,45 +187,15 @@ vb2_error_t vb2_verify_data(const uint8_t *data, uint32_t size,
const struct vb2_public_key *key,
const struct vb2_workbuf *wb)
{
- struct vb2_workbuf wblocal = *wb;
- uint8_t *digest;
- uint32_t digest_size;
- vb2_error_t rv;
+ struct vb2_hash hash;
if (sig->data_size > size) {
VB2_DEBUG("Data buffer smaller than length of signed data.\n");
return VB2_ERROR_VDATA_NOT_ENOUGH_DATA;
}
- /* Digest goes at start of work buffer */
- digest_size = vb2_digest_size(key->hash_alg);
- if (!digest_size)
- return VB2_ERROR_VDATA_DIGEST_SIZE;
+ VB2_TRY(vb2_hash_calculate(key->allow_hwcrypto, data, sig->data_size,
+ key->hash_alg, &hash));
- digest = vb2_workbuf_alloc(&wblocal, digest_size);
- if (!digest)
- return VB2_ERROR_VDATA_WORKBUF_DIGEST;
-
- if (key->allow_hwcrypto) {
- rv = vb2ex_hwcrypto_digest_init(key->hash_alg, sig->data_size);
- if (rv == VB2_SUCCESS) {
- VB2_DEBUG("Using HW crypto engine for hash_alg %d\n", key->hash_alg);
- VB2_TRY(vb2ex_hwcrypto_digest_extend(data, sig->data_size));
- VB2_TRY(vb2ex_hwcrypto_digest_finalize(digest, digest_size));
- } else if (rv == VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED) {
- VB2_DEBUG("HW crypto for hash_alg %d not supported, using SW\n",
- key->hash_alg);
- VB2_TRY(vb2_digest_buffer(data, sig->data_size, key->hash_alg,
- digest, digest_size));
- } else {
- VB2_DEBUG("HW crypto init error : %d\n", rv);
- return rv;
- }
- } else {
- VB2_DEBUG("HW crypto forbidden by TPM flag, using SW\n");
- VB2_TRY(vb2_digest_buffer(data, sig->data_size, key->hash_alg,
- digest, digest_size));
- }
-
- return vb2_verify_digest(key, sig, digest, &wblocal);
+ return vb2_verify_digest(key, sig, hash.raw, wb);
}
diff --git a/firmware/2lib/2firmware.c b/firmware/2lib/2firmware.c
index bc708dc5..49566c4f 100644
--- a/firmware/2lib/2firmware.c
+++ b/firmware/2lib/2firmware.c
@@ -43,7 +43,7 @@ vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx)
/* Unpack the root key */
VB2_TRY(vb2_unpack_key_buffer(&root_key, key_data, key_size));
- root_key.allow_hwcrypto = vb2_hwcrypto_allowed(ctx);
+ root_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx);
/* Load the firmware keyblock header after the root key */
kb = vb2_workbuf_alloc(&wb, sizeof(*kb));
@@ -149,7 +149,7 @@ vb2_error_t vb2_load_fw_preamble(struct vb2_context *ctx)
VB2_TRY(vb2_unpack_key_buffer(&data_key, key_data, key_size));
- data_key.allow_hwcrypto = vb2_hwcrypto_allowed(ctx);
+ data_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx);
/* Load the firmware preamble header */
pre = vb2_workbuf_alloc(&wb, sizeof(*pre));
diff --git a/firmware/2lib/2hmac.c b/firmware/2lib/2hmac.c
index d67da42c..70a0d82d 100644
--- a/firmware/2lib/2hmac.c
+++ b/firmware/2lib/2hmac.c
@@ -33,7 +33,9 @@ int hmac(enum vb2_hash_algorithm alg,
return -1;
if (key_size > block_size) {
- vb2_digest_buffer((uint8_t *)key, key_size, alg, k, block_size);
+ vb2_digest_init(&dc, false, alg, 0);
+ vb2_digest_extend(&dc, (uint8_t *)key, key_size);
+ vb2_digest_finalize(&dc, k, block_size);
key_size = digest_size;
} else {
memcpy(k, key, key_size);
@@ -46,12 +48,12 @@ int hmac(enum vb2_hash_algorithm alg,
i_pad[i] = 0x36 ^ k[i];
}
- vb2_digest_init(&dc, alg);
+ vb2_digest_init(&dc, false, alg, 0);
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_init(&dc, false, alg, 0);
vb2_digest_extend(&dc, o_pad, block_size);
vb2_digest_extend(&dc, b, digest_size);
vb2_digest_finalize(&dc, mac, mac_size);
diff --git a/firmware/2lib/2load_kernel.c b/firmware/2lib/2load_kernel.c
index 65e40536..35dc5b4b 100644
--- a/firmware/2lib/2load_kernel.c
+++ b/firmware/2lib/2load_kernel.c
@@ -110,11 +110,11 @@ static vb2_error_t vb2_verify_kernel_dev_key_hash(
struct vb2_packed_key *key = &keyblock->data_key;
uint8_t *buf = ((uint8_t *)key) + key->key_offset;
uint32_t buflen = key->key_size;
- uint8_t digest[VB2_SHA256_DIGEST_SIZE];
+ struct vb2_hash hash;
VB2_DEBUG("Checking developer key hash.\n");
- VB2_TRY(vb2_digest_buffer(buf, buflen, VB2_HASH_SHA256, digest,
- sizeof(digest)));
+ VB2_TRY(vb2_hash_calculate(vb2api_hwcrypto_allowed(ctx), buf, buflen,
+ VB2_HASH_SHA256, &hash));
uint8_t *fwmp_dev_key_hash =
vb2_secdata_fwmp_get_dev_key_hash(ctx);
@@ -123,8 +123,8 @@ static vb2_error_t vb2_verify_kernel_dev_key_hash(
return VB2_ERROR_KERNEL_KEYBLOCK_DEV_KEY_HASH;
}
- if (vb2_safe_memcmp(digest, fwmp_dev_key_hash,
- VB2_SHA256_DIGEST_SIZE)) {
+ if (vb2_safe_memcmp(hash.sha256, fwmp_dev_key_hash,
+ sizeof(hash.sha256))) {
int i;
VB2_DEBUG("Wrong developer key hash.\n");
@@ -134,7 +134,7 @@ static vb2_error_t vb2_verify_kernel_dev_key_hash(
VB2_DEBUG_RAW("\n");
VB2_DEBUG("Got: ");
for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++)
- VB2_DEBUG_RAW("%02x ", digest[i]);
+ VB2_DEBUG_RAW("%02x ", hash.sha256[i]);
VB2_DEBUG_RAW("\n");
return VB2_ERROR_KERNEL_KEYBLOCK_DEV_KEY_HASH;
@@ -175,8 +175,7 @@ static vb2_error_t vb2_verify_kernel_vblock(
key_size = sd->kernel_key_size;
VB2_TRY(vb2_unpack_key_buffer(&kernel_key, key_data, key_size));
- if (vb2_hwcrypto_allowed(ctx))
- kernel_key.allow_hwcrypto = 1;
+ kernel_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx);
/*
* Clear any previous keyblock-valid flag (for example, from a previous
@@ -435,8 +434,7 @@ static vb2_error_t vb2_load_partition(
return VB2_ERROR_LOAD_PARTITION_DATA_KEY;
}
- if (vb2_hwcrypto_allowed(ctx))
- data_key.allow_hwcrypto = 1;
+ data_key.allow_hwcrypto = vb2api_hwcrypto_allowed(ctx);
/* Verify kernel data */
if (vb2_verify_data(kernbuf, kernbuf_size, &preamble->body_signature,
diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c
index 62a1ab3e..333e8064 100644
--- a/firmware/2lib/2misc.c
+++ b/firmware/2lib/2misc.c
@@ -577,20 +577,22 @@ int vb2api_use_short_dev_screen_delay(struct vb2_context *ctx)
return gbb->flags & VB2_GBB_FLAG_DEV_SCREEN_SHORT_DELAY;
}
-static void snprint_sha1_sum(struct vb2_packed_key *key,
+static void snprint_sha1_sum(struct vb2_context *ctx,
+ struct vb2_packed_key *key,
char *dest, size_t dest_size)
{
uint8_t *buf = ((uint8_t *)key) + key->key_offset;
uint64_t buflen = key->key_size;
- uint8_t digest[VB2_SHA1_DIGEST_SIZE];
+ struct vb2_hash hash;
int32_t used = 0;
int i;
- vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest));
- for (i = 0; i < sizeof(digest); i++)
+ vb2_hash_calculate(vb2api_hwcrypto_allowed(ctx), buf, buflen,
+ VB2_HASH_SHA1, &hash);
+ for (i = 0; i < sizeof(hash.sha1); i++)
if (used < dest_size)
used += snprintf(dest + used, dest_size - used,
- "%02x", digest[i]);
+ "%02x", hash.sha1[i]);
dest[dest_size - 1] = '\0';
}
@@ -690,7 +692,7 @@ char *vb2api_get_debug_info(struct vb2_context *ctx)
struct vb2_workbuf wblocal = wb;
rv = vb2_gbb_read_root_key(ctx, &key, NULL, &wblocal);
if (rv == VB2_SUCCESS) {
- snprint_sha1_sum(key, sha1sum, sizeof(sha1sum));
+ snprint_sha1_sum(ctx, key, sha1sum, sizeof(sha1sum));
DEBUG_INFO_APPEND("\ngbb.rootkey: %s", sha1sum);
}
}
@@ -700,7 +702,7 @@ char *vb2api_get_debug_info(struct vb2_context *ctx)
struct vb2_workbuf wblocal = wb;
rv = vb2_gbb_read_recovery_key(ctx, &key, NULL, &wblocal);
if (rv == VB2_SUCCESS) {
- snprint_sha1_sum(key, sha1sum, sizeof(sha1sum));
+ snprint_sha1_sum(ctx, key, sha1sum, sizeof(sha1sum));
DEBUG_INFO_APPEND("\ngbb.recovery_key: %s", sha1sum);
}
}
@@ -710,7 +712,7 @@ char *vb2api_get_debug_info(struct vb2_context *ctx)
sd->kernel_key_offset) {
struct vb2_packed_key *key =
vb2_member_of(sd, sd->kernel_key_offset);
- snprint_sha1_sum(key, sha1sum, sizeof(sha1sum));
+ snprint_sha1_sum(ctx, key, sha1sum, sizeof(sha1sum));
DEBUG_INFO_APPEND("\nkernel_subkey: %s", sha1sum);
}
@@ -749,3 +751,14 @@ void vb2_set_boot_mode(struct vb2_context *ctx)
*boot_mode = VB2_BOOT_MODE_DEVELOPER;
}
}
+
+bool vb2api_hwcrypto_allowed(struct vb2_context *ctx)
+{
+ /* disable hwcrypto in recovery mode */
+ if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
+ return 0;
+
+ /* enable hwcrypto only if RW firmware set the flag */
+ return vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_FLAGS) &
+ VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED;
+}
diff --git a/firmware/2lib/2sha_utility.c b/firmware/2lib/2sha_utility.c
index 3a6c230e..4bc3f6a7 100644
--- a/firmware/2lib/2sha_utility.c
+++ b/firmware/2lib/2sha_utility.c
@@ -56,13 +56,32 @@ size_t vb2_hash_block_size(enum vb2_hash_algorithm alg)
}
test_mockable
-vb2_error_t vb2_digest_init(struct vb2_digest_context *dc,
- enum vb2_hash_algorithm hash_alg)
+vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, bool allow_hwcrypto,
+ enum vb2_hash_algorithm algo, uint32_t data_size)
{
- dc->hash_alg = hash_alg;
+ const char msg[] = "%u bytes, hash algo %d, HW acceleration %s";
+
+ dc->hash_alg = algo;
dc->using_hwcrypto = 0;
- switch (dc->hash_alg) {
+ if (allow_hwcrypto) {
+ vb2_error_t rv = vb2ex_hwcrypto_digest_init(algo, data_size);
+ if (rv == VB2_SUCCESS) {
+ VB2_DEBUG(msg, data_size, algo, "enabled\n");
+ dc->using_hwcrypto = 1;
+ return VB2_SUCCESS;
+ }
+ if (rv != VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED) {
+ VB2_DEBUG(msg, data_size, algo, "initialization error");
+ VB2_DEBUG_RAW(": %#x\n", rv);
+ return rv;
+ }
+ VB2_DEBUG(msg, data_size, algo, "unsupported\n");
+ } else {
+ VB2_DEBUG(msg, data_size, algo, "forbidden\n");
+ }
+
+ switch (algo) {
#if VB2_SUPPORT_SHA1
case VB2_HASH_SHA1:
vb2_sha1_init(&dc->sha1);
@@ -71,13 +90,13 @@ vb2_error_t vb2_digest_init(struct vb2_digest_context *dc,
#if VB2_SUPPORT_SHA256
case VB2_HASH_SHA224:
case VB2_HASH_SHA256:
- vb2_sha256_init(&dc->sha256, hash_alg);
+ vb2_sha256_init(&dc->sha256, algo);
return VB2_SUCCESS;
#endif
#if VB2_SUPPORT_SHA512
case VB2_HASH_SHA384:
case VB2_HASH_SHA512:
- vb2_sha512_init(&dc->sha512, hash_alg);
+ vb2_sha512_init(&dc->sha512, algo);
return VB2_SUCCESS;
#endif
default:
@@ -89,6 +108,9 @@ test_mockable
vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf,
uint32_t size)
{
+ if (dc->using_hwcrypto)
+ return vb2ex_hwcrypto_digest_extend(buf, size);
+
switch (dc->hash_alg) {
#if VB2_SUPPORT_SHA1
case VB2_HASH_SHA1:
@@ -116,6 +138,9 @@ test_mockable
vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest,
uint32_t digest_size)
{
+ if (dc->using_hwcrypto)
+ return vb2ex_hwcrypto_digest_finalize(digest, digest_size);
+
if (digest_size < vb2_digest_size(dc->hash_alg))
return VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE;
@@ -142,27 +167,26 @@ vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest,
}
}
-test_mockable
-vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size,
- enum vb2_hash_algorithm hash_alg, uint8_t *digest,
- uint32_t digest_size)
+vb2_error_t vb2_hash_calculate(bool allow_hwcrypto, const void *buf,
+ uint32_t size, enum vb2_hash_algorithm algo,
+ struct vb2_hash *hash)
{
struct vb2_digest_context dc;
+ hash->algo = algo;
- VB2_TRY(vb2_digest_init(&dc, hash_alg));
+ VB2_TRY(vb2_digest_init(&dc, allow_hwcrypto, algo, size));
VB2_TRY(vb2_digest_extend(&dc, buf, size));
- return vb2_digest_finalize(&dc, digest, digest_size);
+ return vb2_digest_finalize(&dc, hash->raw, vb2_digest_size(algo));
}
-vb2_error_t vb2_hash_verify(const void *buf, uint32_t size,
+vb2_error_t vb2_hash_verify(bool allow_hwcrypto, const void *buf, uint32_t size,
const struct vb2_hash *hash)
{
- uint8_t hash_buf[VB2_MAX_DIGEST_SIZE];
- size_t hash_size = vb2_digest_size(hash->algo);
+ struct vb2_hash tmp;
- VB2_TRY(vb2_digest_buffer(buf, size, hash->algo, hash_buf, hash_size));
- if (memcmp(hash_buf, hash->raw, hash_size))
+ VB2_TRY(vb2_hash_calculate(allow_hwcrypto, buf, size, hash->algo, &tmp));
+ if (memcmp(tmp.raw, hash->raw, vb2_digest_size(hash->algo)))
return VB2_ERROR_SHA_MISMATCH;
else
return VB2_SUCCESS;
diff --git a/firmware/2lib/2struct.c b/firmware/2lib/2struct.c
index a16f8690..0223570f 100644
--- a/firmware/2lib/2struct.c
+++ b/firmware/2lib/2struct.c
@@ -170,35 +170,19 @@ vb2_error_t vb2_verify_keyblock_hash(const struct vb2_keyblock *block,
const struct vb2_workbuf *wb)
{
const struct vb2_signature *sig = &block->keyblock_hash;
- struct vb2_workbuf wblocal = *wb;
- struct vb2_digest_context *dc;
- uint8_t *digest;
- uint32_t digest_size;
+ struct vb2_hash hash;
/* Validity check keyblock before attempting hash check of data */
VB2_TRY(vb2_check_keyblock(block, size, sig));
VB2_DEBUG("Checking keyblock hash...\n");
- /* Digest goes at start of work buffer */
- digest_size = vb2_digest_size(VB2_HASH_SHA512);
- digest = vb2_workbuf_alloc(&wblocal, digest_size);
- if (!digest)
- return VB2_ERROR_VDATA_WORKBUF_DIGEST;
+ /* This is only used in developer mode, so hwcrypto not important. */
+ VB2_TRY(vb2_hash_calculate(false, block, sig->data_size,
+ VB2_HASH_SHA512, &hash));
- /* Hashing requires temp space for the context */
- dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc));
- if (!dc)
- return VB2_ERROR_VDATA_WORKBUF_HASHING;
-
- VB2_TRY(vb2_digest_init(dc, VB2_HASH_SHA512));
-
- VB2_TRY(vb2_digest_extend(dc, (const uint8_t *)block, sig->data_size));
-
- VB2_TRY(vb2_digest_finalize(dc, digest, digest_size));
-
- if (vb2_safe_memcmp(vb2_signature_data(sig), digest,
- digest_size) != 0) {
+ if (vb2_safe_memcmp(vb2_signature_data(sig), hash.sha512,
+ sizeof(hash.sha512)) != 0) {
VB2_DEBUG("Invalid keyblock hash.\n");
return VB2_ERROR_KEYBLOCK_HASH_INVALID_IN_DEV_MODE;
}
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h
index fdb6a72f..f185ec4d 100644
--- a/firmware/2lib/include/2api.h
+++ b/firmware/2lib/include/2api.h
@@ -895,7 +895,11 @@ void vb2ex_printf(const char *func, const char *fmt, ...);
* Initialize the hardware crypto engine to calculate a block-style digest.
*
* @param hash_alg Hash algorithm to use
- * @param data_size Expected total size of data to hash
+ * @param data_size Expected total size of data to hash, or 0. If 0, the
+ * total size is not known in advance. Implementations that
+ * cannot handle unknown sizes should return UNSUPPORTED
+ * in that case. If the value is non-zero, implementations
+ * can trust it to be accurate.
* @return VB2_SUCCESS, or non-zero error code (HWCRYPTO_UNSUPPORTED not fatal).
*/
vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
@@ -948,6 +952,15 @@ vb2_error_t vb2ex_hwcrypto_modexp(const struct vb2_public_key *key,
uint32_t *workbuf32, int exp);
/*
+ * Report if hardware crypto is allowed in the current context. It may be
+ * disabled by TPM flag and is categorically disallowed in recovery mode.
+ *
+ * @param ctx Vboot context
+ * @returns 1 if hardware crypto is allowed, 0 if it is forbidden.
+ */
+bool vb2api_hwcrypto_allowed(struct vb2_context *ctx);
+
+/*
* Abort vboot flow due to a failed assertion or broken assumption.
*
* Likely due to caller misusing vboot (e.g. calling API functions
diff --git a/firmware/2lib/include/2rsa.h b/firmware/2lib/include/2rsa.h
index 6d5ffcbe..7597dd5e 100644
--- a/firmware/2lib/include/2rsa.h
+++ b/firmware/2lib/include/2rsa.h
@@ -22,7 +22,7 @@ struct vb2_public_key {
const char *desc; /* Description */
uint32_t version; /* Key version */
const struct vb2_id *id; /* Key ID */
- int allow_hwcrypto; /* Is hwcrypto allowed for key */
+ bool allow_hwcrypto; /* Is hwcrypto allowed for key */
};
/**
diff --git a/firmware/2lib/include/2secdata.h b/firmware/2lib/include/2secdata.h
index f9a0e308..ae9888af 100644
--- a/firmware/2lib/include/2secdata.h
+++ b/firmware/2lib/include/2secdata.h
@@ -220,24 +220,4 @@ int vb2_secdata_fwmp_get_flag(struct vb2_context *ctx,
*/
uint8_t *vb2_secdata_fwmp_get_dev_key_hash(struct vb2_context *ctx);
-/*
- * Helper function to check if hwcrypto is allowed.
- */
-static inline int vb2_hwcrypto_allowed(struct vb2_context *ctx)
-{
-
- /* disable hwcrypto in recovery mode */
- if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
- return 0;
-
- /* enable hwcrypto only if RW firmware set the flag */
- if (vb2_secdata_kernel_get(ctx, VB2_SECDATA_KERNEL_FLAGS)
- & VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED)
- return 1;
-
- return 0;
-
-}
-
-
#endif /* VBOOT_REFERENCE_2SECDATA_H_ */
diff --git a/firmware/2lib/include/2sha.h b/firmware/2lib/include/2sha.h
index e586a77d..503eb7c2 100644
--- a/firmware/2lib/include/2sha.h
+++ b/firmware/2lib/include/2sha.h
@@ -102,8 +102,8 @@ struct vb2_digest_context {
/* Current hash algorithm */
enum vb2_hash_algorithm hash_alg;
- /* 1 if digest is computed with vb2ex_hwcrypto routines, else 0 */
- int using_hwcrypto;
+ /* `true` if digest is computed with vb2ex_hwcrypto routines */
+ bool using_hwcrypto;
};
/*
@@ -206,14 +206,18 @@ size_t vb2_digest_size(enum vb2_hash_algorithm hash_alg);
size_t vb2_hash_block_size(enum vb2_hash_algorithm alg);
/**
- * Initialize a digest context for doing block-style digesting.
+ * Initialize a digest context for doing block-style digesting, potentially
+ * making use of the vb2ex_hwcrypto APIs. Whether HW crypto is allowed by policy
+ * in the current context depends on the caller and can be passed in. If HW
+ * crypto is not allowed or not supported, will automatically fall back to SW.
*
* @param dc Digest context
- * @param hash_alg Hash algorithm
+ * @param allow_hwcrypto false to forbid HW crypto by policy; true to allow.
+ * @param algo Hash algorithm
* @return VB2_SUCCESS, or non-zero on error.
*/
-vb2_error_t vb2_digest_init(struct vb2_digest_context *dc,
- enum vb2_hash_algorithm hash_alg);
+vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, bool allow_hwcrypto,
+ enum vb2_hash_algorithm algo, uint32_t data_size);
/**
* Extend a digest's hash with another block of data.
@@ -240,47 +244,30 @@ vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc,
uint8_t *digest, uint32_t digest_size);
/**
- * Calculate the digest of a buffer and store the result.
- *
- * @param buf Data to hash
- * @param size Length of data in bytes
- * @param hash_alg Hash algorithm
- * @param digest Destination for digest
- * @param digest_size Length of digest buffer in bytes.
- * @return VB2_SUCCESS, or non-zero on error.
- */
-vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size,
- enum vb2_hash_algorithm hash_alg, uint8_t *digest,
- uint32_t digest_size);
-
-/**
* Fill a vb2_hash structure with the hash of a buffer.
*
+ * @param allow_hwcrypto false to forbid HW crypto by policy; true to allow.
* @param buf Buffer to hash
* @param size Size of |buf| in bytes
* @param algo The hash algorithm to use (and store in |hash|)
* @param hash vb2_hash structure to fill with the hash of |buf|
* @return VB2_SUCCESS, or non-zero on error.
*/
-static inline vb2_error_t vb2_hash_calculate(const void *buf, uint32_t size,
- enum vb2_hash_algorithm algo,
- struct vb2_hash *hash)
-{
- hash->algo = algo;
- return vb2_digest_buffer(buf, size, algo, hash->raw,
- vb2_digest_size(algo));
-}
+vb2_error_t vb2_hash_calculate(bool allow_hwcrypto, const void *buf,
+ uint32_t size, enum vb2_hash_algorithm algo,
+ struct vb2_hash *hash);
/**
* Verify that a vb2_hash matches a buffer.
*
+ * @param allow_hwcrypto false to forbid HW crypto by policy; true to allow.
* @param buf Buffer to hash and match to |hash|
* @param size Size of |buf| in bytes
* @param hash Hash to compare to the buffer
* @return VB2_SUCCESS if hash matches, VB2_ERROR_SHA_MISMATCH if hash doesn't
* match, or non-zero on other error.
*/
-vb2_error_t vb2_hash_verify(const void *buf, uint32_t size,
+vb2_error_t vb2_hash_verify(bool allow_hwcrypto, const void *buf, uint32_t size,
const struct vb2_hash *hash);
#endif /* VBOOT_REFERENCE_2SHA_H_ */
diff --git a/firmware/2lib/include/2sysincludes.h b/firmware/2lib/include/2sysincludes.h
index 1e671e9a..00e92e95 100644
--- a/firmware/2lib/include/2sysincludes.h
+++ b/firmware/2lib/include/2sysincludes.h
@@ -15,6 +15,7 @@
#include <ctype.h>
#include <inttypes.h> /* For PRIu64 */
+#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
diff --git a/firmware/lib20/api_kernel.c b/firmware/lib20/api_kernel.c
index 403e932e..c021db33 100644
--- a/firmware/lib20/api_kernel.c
+++ b/firmware/lib20/api_kernel.c
@@ -99,7 +99,8 @@ vb2_error_t vb2api_verify_kernel_data(struct vb2_context *ctx, const void *buf,
vb2_member_of(sd, sd->data_key_offset),
sd->data_key_size));
- VB2_TRY(vb2_digest_init(dc, key.hash_alg));
+ VB2_TRY(vb2_digest_init(dc, vb2api_hwcrypto_allowed(ctx),
+ key.hash_alg, size));
VB2_TRY(vb2_digest_extend(dc, buf, size));
diff --git a/futility/cmd_create.c b/futility/cmd_create.c
index 16a37332..cf02f097 100644
--- a/futility/cmd_create.c
+++ b/futility/cmd_create.c
@@ -262,8 +262,10 @@ static int vb2_make_keypair(void)
/* Update the IDs */
if (!force_id) {
- vb2_digest_buffer(keyb_data, keyb_size, VB2_HASH_SHA1,
- opt_id.raw, sizeof(opt_id.raw));
+ struct vb2_hash hash;
+ vb2_hash_calculate(false, keyb_data, keyb_size, VB2_HASH_SHA1,
+ &hash);
+ memcpy(opt_id.raw, hash.raw, sizeof(opt_id.raw));
}
memcpy((struct vb2_id *)pubkey->id, &opt_id, sizeof(opt_id));
diff --git a/futility/cmd_gscvd.c b/futility/cmd_gscvd.c
index 458c7549..6101173f 100644
--- a/futility/cmd_gscvd.c
+++ b/futility/cmd_gscvd.c
@@ -437,7 +437,7 @@ static int calculate_ranges_digest(const struct file_buf *ap_firmware_file,
size_t i;
/* Calculate the ranges digest. */
- if (vb2_digest_init(&dc, hash_alg) != VB2_SUCCESS) {
+ if (vb2_digest_init(&dc, false, hash_alg, 0) != VB2_SUCCESS) {
ERROR("Failed to init digest!\n");
return 1;
}
@@ -904,10 +904,10 @@ static int validate_gscvd(int argc, char *argv[])
/* Find the keyblock. */
kblock = (struct vb2_keyblock *)((uintptr_t)gvd + gvd->size);
- if ((argc > 1) && (vb2_hash_verify
- (vb2_packed_key_data(&gvd->root_key_header),
- gvd->root_key_header.key_size,
- &root_key_digest) != VB2_SUCCESS)) {
+ if ((argc > 1) && (vb2_hash_verify(false,
+ vb2_packed_key_data(&gvd->root_key_header),
+ gvd->root_key_header.key_size,
+ &root_key_digest) != VB2_SUCCESS)) {
ERROR("Sha256 mismatch\n");
break;
}
@@ -946,7 +946,7 @@ static void dump_pubk_hash(const struct vb2_packed_key *pubk)
struct vb2_hash hash;
size_t i;
- vb2_hash_calculate(vb2_packed_key_data(pubk), pubk->key_size,
+ vb2_hash_calculate(false, vb2_packed_key_data(pubk), pubk->key_size,
VB2_HASH_SHA256, &hash);
printf("Root key body sha256 hash:\n");
diff --git a/futility/cmd_pcr.c b/futility/cmd_pcr.c
index e267b24a..bc6de62c 100644
--- a/futility/cmd_pcr.c
+++ b/futility/cmd_pcr.c
@@ -129,12 +129,14 @@ static int do_pcr(int argc, char *argv[])
print_digest(accum + digest_size, digest_size);
printf("\n");
- if (VB2_SUCCESS != vb2_digest_buffer(accum, digest_size * 2,
- digest_alg,
- pcr, digest_size)) {
+ struct vb2_hash hash;
+ if (VB2_SUCCESS != vb2_hash_calculate(false, accum,
+ digest_size * 2,
+ digest_alg, &hash)) {
fprintf(stderr, "Error computing digest!\n");
return 1;
}
+ memcpy(pcr, hash.raw, digest_size);
printf("PCR: ");
print_digest(pcr, digest_size);
diff --git a/futility/file_type_usbpd1.c b/futility/file_type_usbpd1.c
index a128a996..024303d8 100644
--- a/futility/file_type_usbpd1.c
+++ b/futility/file_type_usbpd1.c
@@ -345,7 +345,7 @@ static void show_usbpd1_stuff(const char *name,
{
struct vb2_public_key key;
struct vb21_packed_key *pkey;
- uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];
+ struct vb2_hash hash;
int i;
vb2_pubkey_from_usbpd1(&key, sig_alg, hash_alg,
@@ -354,16 +354,16 @@ static void show_usbpd1_stuff(const char *name,
if (vb21_public_key_pack(&pkey, &key))
return;
- vb2_digest_buffer((uint8_t *)pkey + pkey->key_offset, pkey->key_size,
- VB2_HASH_SHA1, sha1sum, sizeof(sha1sum));
+ vb2_hash_calculate(false, (uint8_t *)pkey + pkey->key_offset,
+ pkey->key_size, VB2_HASH_SHA1, &hash);
printf("USB-PD v1 image: %s\n", name);
printf(" Algorithm: %s %s\n",
vb2_get_sig_algorithm_name(sig_alg),
vb2_get_hash_algorithm_name(hash_alg));
printf(" Key sha1sum: ");
- for (i = 0; i < VB2_SHA1_DIGEST_SIZE; i++)
- printf("%02x", sha1sum[i]);
+ for (i = 0; i < sizeof(hash.sha1); i++)
+ printf("%02x", hash.sha1[i]);
printf("\n");
free(pkey);
diff --git a/futility/misc.c b/futility/misc.c
index 4aec13a3..874039f0 100644
--- a/futility/misc.c
+++ b/futility/misc.c
@@ -146,17 +146,17 @@ int print_hwid_digest(struct vb2_gbb_header *gbb,
uint8_t *buf = (uint8_t *)gbb;
char *hwid_str = (char *)(buf + gbb->hwid_offset);
int is_valid = 0;
- uint8_t digest[VB2_SHA256_DIGEST_SIZE];
+ struct vb2_hash hash;
- if (VB2_SUCCESS == vb2_digest_buffer(buf + gbb->hwid_offset,
- strlen(hwid_str), VB2_HASH_SHA256,
- digest, sizeof(digest))) {
+ if (VB2_SUCCESS == vb2_hash_calculate(false, buf + gbb->hwid_offset,
+ strlen(hwid_str), VB2_HASH_SHA256,
+ &hash)) {
int i;
is_valid = 1;
/* print it, comparing as we go */
- for (i = 0; i < VB2_SHA256_DIGEST_SIZE; i++) {
+ for (i = 0; i < sizeof(hash.sha256); i++) {
printf("%02x", gbb->hwid_digest[i]);
- if (gbb->hwid_digest[i] != digest[i])
+ if (gbb->hwid_digest[i] != hash.sha256[i])
is_valid = 0;
}
}
@@ -176,16 +176,18 @@ void update_hwid_digest(struct vb2_gbb_header *gbb)
uint8_t *buf = (uint8_t *)gbb;
char *hwid_str = (char *)(buf + gbb->hwid_offset);
+ struct vb2_hash hash;
- vb2_digest_buffer(buf + gbb->hwid_offset, strlen(hwid_str),
- VB2_HASH_SHA256,
- gbb->hwid_digest, sizeof(gbb->hwid_digest));
+ vb2_hash_calculate(false, buf + gbb->hwid_offset, strlen(hwid_str),
+ VB2_HASH_SHA256, &hash);
+ memcpy(gbb->hwid_digest, hash.raw, sizeof(gbb->hwid_digest));
}
/* Sets the HWID string field inside a GBB header. */
int futil_set_gbb_hwid(struct vb2_gbb_header *gbb, const char *hwid)
{
uint8_t *to = (uint8_t *)gbb + gbb->hwid_offset;
+ struct vb2_hash hash;
size_t len;
assert(hwid);
@@ -201,8 +203,9 @@ int futil_set_gbb_hwid(struct vb2_gbb_header *gbb, const char *hwid)
if (gbb->major_version == 1 && gbb->minor_version < 2)
return 0;
- return vb2_digest_buffer(to, len, VB2_HASH_SHA256, gbb->hwid_digest,
- sizeof(gbb->hwid_digest));
+ VB2_TRY(vb2_hash_calculate(false, to, len, VB2_HASH_SHA256, &hash));
+ memcpy(gbb->hwid_digest, hash.raw, sizeof(gbb->hwid_digest));
+ return VB2_SUCCESS;
}
/*
diff --git a/futility/vb2_helper.c b/futility/vb2_helper.c
index a8452db6..2105fe53 100644
--- a/futility/vb2_helper.c
+++ b/futility/vb2_helper.c
@@ -46,15 +46,16 @@ static inline void vb2_print_bytes(const void *ptr, uint32_t len)
printf("%02x", *buf++);
}
-static int vb2_public_key_sha1sum(struct vb2_public_key *key, uint8_t *digest)
+static int vb2_public_key_sha1sum(struct vb2_public_key *key,
+ struct vb2_hash *hash)
{
struct vb21_packed_key *pkey;
if (vb21_public_key_pack(&pkey, key))
return 0;
- vb2_digest_buffer((uint8_t *)pkey + pkey->key_offset, pkey->key_size,
- VB2_HASH_SHA1, digest, VB2_SHA1_DIGEST_SIZE);
+ vb2_hash_calculate(false, (uint8_t *)pkey + pkey->key_offset,
+ pkey->key_size, VB2_HASH_SHA1, hash);
free(pkey);
return 1;
@@ -64,7 +65,7 @@ int show_vb21_pubkey_buf(const char *name, uint8_t *buf, uint32_t len,
void *data)
{
struct vb2_public_key key;
- uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];
+ struct vb2_hash hash;
/* The key's members will point into the state buffer after this. Don't
* free anything. */
@@ -82,10 +83,10 @@ int show_vb21_pubkey_buf(const char *name, uint8_t *buf, uint32_t len,
printf(" ID: ");
vb2_print_bytes(key.id, sizeof(*key.id));
printf("\n");
- if (vb2_public_key_sha1sum(&key, sha1sum) &&
- memcmp(key.id, sha1sum, sizeof(*key.id))) {
+ if (vb2_public_key_sha1sum(&key, &hash) &&
+ memcmp(key.id, hash.sha1, sizeof(*key.id))) {
printf(" Key sha1sum: ");
- vb2_print_bytes(sha1sum, sizeof(sha1sum));
+ vb2_print_bytes(hash.sha1, sizeof(hash.sha1));
printf("\n");
}
return 0;
@@ -107,7 +108,8 @@ int ft_show_vb21_pubkey(const char *name, void *data)
return rv;
}
-static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest)
+static int vb2_private_key_sha1sum(struct vb2_private_key *key,
+ struct vb2_hash *hash)
{
uint8_t *buf;
uint32_t buflen;
@@ -115,8 +117,7 @@ static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest)
if (vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen))
return 0;
- vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest,
- VB2_SHA1_DIGEST_SIZE);
+ vb2_hash_calculate(false, buf, buflen, VB2_HASH_SHA1, hash);
free(buf);
return 1;
@@ -125,7 +126,7 @@ static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest)
int ft_show_vb21_privkey(const char *name, void *data)
{
struct vb2_private_key *key = 0;
- uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];
+ struct vb2_hash hash;
int fd = -1;
uint8_t *buf;
uint32_t len;
@@ -149,10 +150,10 @@ int ft_show_vb21_privkey(const char *name, void *data)
printf(" ID: ");
vb2_print_bytes(&key->id, sizeof(key->id));
printf("\n");
- if (vb2_private_key_sha1sum(key, sha1sum) &&
- memcmp(&key->id, sha1sum, sizeof(key->id))) {
+ if (vb2_private_key_sha1sum(key, &hash) &&
+ memcmp(&key->id, hash.sha1, sizeof(key->id))) {
printf(" Key sha1sum: ");
- vb2_print_bytes(sha1sum, sizeof(sha1sum));
+ vb2_print_bytes(hash.sha1, sizeof(hash.sha1));
printf("\n");
}
vb2_private_key_free(key);
@@ -202,8 +203,8 @@ int ft_show_pem(const char *name, void *data)
{
RSA *rsa_key;
uint8_t *keyb;
- uint8_t digest[VB2_SHA1_DIGEST_SIZE];
uint32_t keyb_len;
+ struct vb2_hash hash;
int i, bits;
const BIGNUM *rsa_key_n, *rsa_key_d;
int fd = -1;
@@ -235,10 +236,9 @@ int ft_show_pem(const char *name, void *data)
}
printf(" Key sha1sum: ");
- vb2_digest_buffer(keyb, keyb_len, VB2_HASH_SHA1,
- digest, sizeof(digest));
- for (i = 0; i < sizeof(digest); i++)
- printf("%02x", digest[i]);
+ vb2_hash_calculate(false, keyb, keyb_len, VB2_HASH_SHA1, &hash);
+ for (i = 0; i < sizeof(hash.sha1); i++)
+ printf("%02x", hash.sha1[i]);
printf("\n");
free(keyb);
diff --git a/host/lib/file_keys.c b/host/lib/file_keys.c
index 7ae71802..4349dc9b 100644
--- a/host/lib/file_keys.c
+++ b/host/lib/file_keys.c
@@ -31,7 +31,7 @@ vb2_error_t DigestFile(char *input_file, enum vb2_hash_algorithm alg,
fprintf(stderr, "Couldn't open %s\n", input_file);
return VB2_ERROR_UNKNOWN;
}
- vb2_digest_init(&ctx, alg);
+ vb2_digest_init(&ctx, false, alg, 0);
while ((len = read(input_fd, data, sizeof(data))) == sizeof(data))
vb2_digest_extend(&ctx, data, len);
if (len != -1)
diff --git a/host/lib/host_signature.c b/host/lib/host_signature.c
index 5b71d29a..68e6991d 100644
--- a/host/lib/host_signature.c
+++ b/host/lib/host_signature.c
@@ -113,34 +113,33 @@ struct vb2_signature *vb2_external_signature(const uint8_t *data, uint32_t size,
uint32_t key_algorithm,
const char *external_signer)
{
- int vb2_alg = vb2_crypto_to_hash(key_algorithm);
- uint8_t digest[VB2_MAX_DIGEST_SIZE];
- int digest_size = vb2_digest_size(vb2_alg);
+ struct vb2_hash hash;
+
+ /* Calculate the digest */
+ if (VB2_SUCCESS != vb2_hash_calculate(false, data, size,
+ vb2_crypto_to_hash(key_algorithm),
+ &hash))
+ return NULL;
uint32_t digest_info_size = 0;
const uint8_t *digest_info = NULL;
- if (VB2_SUCCESS != vb2_digest_info(vb2_alg,
+ if (VB2_SUCCESS != vb2_digest_info(hash.algo,
&digest_info, &digest_info_size))
return NULL;
-
+ int digest_size = vb2_digest_size(hash.algo);
uint8_t *signature_digest;
uint64_t signature_digest_len = digest_size + digest_info_size;
int rv;
- /* Calculate the digest */
- if (VB2_SUCCESS != vb2_digest_buffer(data, size, vb2_alg,
- digest, sizeof(digest)))
- return NULL;
-
/* Prepend the digest info to the digest */
signature_digest = calloc(signature_digest_len, 1);
if (!signature_digest)
return NULL;
memcpy(signature_digest, digest_info, digest_info_size);
- memcpy(signature_digest + digest_info_size, digest, digest_size);
+ memcpy(signature_digest + digest_info_size, hash.raw, digest_size);
/* Allocate output signature */
uint32_t sig_size =
diff --git a/host/lib/host_signature2.c b/host/lib/host_signature2.c
index b6cd6520..83b97984 100644
--- a/host/lib/host_signature2.c
+++ b/host/lib/host_signature2.c
@@ -65,17 +65,18 @@ vb2_error_t vb2_copy_signature(struct vb2_signature *dest,
struct vb2_signature *vb2_sha512_signature(const uint8_t *data, uint32_t size)
{
- uint8_t digest[VB2_SHA512_DIGEST_SIZE];
- if (VB2_SUCCESS != vb2_digest_buffer(data, size, VB2_HASH_SHA512,
- digest, sizeof(digest)))
+ struct vb2_hash hash;
+ if (VB2_SUCCESS != vb2_hash_calculate(false, data, size,
+ VB2_HASH_SHA512, &hash))
return NULL;
struct vb2_signature *sig =
- vb2_alloc_signature(VB2_SHA512_DIGEST_SIZE, size);
+ vb2_alloc_signature(sizeof(hash.sha512), size);
if (!sig)
return NULL;
- memcpy(vb2_signature_data_mutable(sig), digest, VB2_SHA512_DIGEST_SIZE);
+ memcpy(vb2_signature_data_mutable(sig), hash.sha512,
+ sizeof(hash.sha512));
return sig;
}
@@ -83,7 +84,7 @@ struct vb2_signature *vb2_calculate_signature(
const uint8_t *data, uint32_t size,
const struct vb2_private_key *key)
{
- uint8_t digest[VB2_MAX_DIGEST_SIZE];
+ struct vb2_hash hash;
uint32_t digest_size = vb2_digest_size(key->hash_alg);
uint32_t digest_info_size = 0;
@@ -93,8 +94,8 @@ struct vb2_signature *vb2_calculate_signature(
return NULL;
/* Calculate the digest */
- if (VB2_SUCCESS != vb2_digest_buffer(data, size, key->hash_alg,
- digest, digest_size))
+ if (VB2_SUCCESS != vb2_hash_calculate(false, data, size, key->hash_alg,
+ &hash))
return NULL;
/* Prepend the digest info to the digest */
@@ -104,7 +105,7 @@ struct vb2_signature *vb2_calculate_signature(
return NULL;
memcpy(signature_digest, digest_info, digest_info_size);
- memcpy(signature_digest + digest_info_size, digest, digest_size);
+ memcpy(signature_digest + digest_info_size, hash.raw, digest_size);
/* Allocate output signature */
struct vb2_signature *sig = (struct vb2_signature *)
diff --git a/host/lib/signature_digest.c b/host/lib/signature_digest.c
index f6be00a3..a0364702 100644
--- a/host/lib/signature_digest.c
+++ b/host/lib/signature_digest.c
@@ -38,8 +38,7 @@ uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
{
uint8_t* info_digest = NULL;
- uint8_t digest[VB2_SHA512_DIGEST_SIZE]; /* Longest digest */
- enum vb2_hash_algorithm hash_alg;
+ struct vb2_hash hash;
if (algorithm >= VB2_ALG_COUNT) {
fprintf(stderr,
@@ -47,11 +46,10 @@ uint8_t* SignatureDigest(const uint8_t* buf, uint64_t len,
return NULL;
}
- hash_alg = vb2_crypto_to_hash(algorithm);
-
- if (VB2_SUCCESS == vb2_digest_buffer(buf, len, hash_alg,
- digest, sizeof(digest))) {
- info_digest = PrependDigestInfo(hash_alg, digest);
+ if (VB2_SUCCESS == vb2_hash_calculate(false, buf, len,
+ vb2_crypto_to_hash(algorithm),
+ &hash)) {
+ info_digest = PrependDigestInfo(hash.algo, hash.raw);
}
return info_digest;
}
diff --git a/host/lib/util_misc.c b/host/lib/util_misc.c
index 26f7dac8..c92a2b0a 100644
--- a/host/lib/util_misc.c
+++ b/host/lib/util_misc.c
@@ -25,15 +25,15 @@ const char *packed_key_sha1_string(const struct vb2_packed_key *key)
{
uint8_t *buf = ((uint8_t *)key) + key->key_offset;
uint32_t buflen = key->key_size;
- uint8_t digest[VB2_SHA1_DIGEST_SIZE];
+ struct vb2_hash hash;
static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1];
- vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest));
+ vb2_hash_calculate(false, buf, buflen, VB2_HASH_SHA1, &hash);
char *dnext = dest;
int i;
- for (i = 0; i < sizeof(digest); i++)
- dnext += sprintf(dnext, "%02x", digest[i]);
+ for (i = 0; i < sizeof(hash.sha1); i++)
+ dnext += sprintf(dnext, "%02x", hash.sha1[i]);
return dest;
}
@@ -42,7 +42,7 @@ const char *private_key_sha1_string(const struct vb2_private_key *key)
{
uint8_t *buf;
uint32_t buflen;
- uint8_t digest[VB2_SHA1_DIGEST_SIZE];
+ struct vb2_hash hash;
static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1];
if (!key->rsa_private_key ||
@@ -50,12 +50,12 @@ const char *private_key_sha1_string(const struct vb2_private_key *key)
return "<error>";
}
- vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest));
+ vb2_hash_calculate(false, buf, buflen, VB2_HASH_SHA1, &hash);
char *dnext = dest;
int i;
- for (i = 0; i < sizeof(digest); i++)
- dnext += sprintf(dnext, "%02x", digest[i]);
+ for (i = 0; i < sizeof(hash.sha1); i++)
+ dnext += sprintf(dnext, "%02x", hash.sha1[i]);
free(buf);
return dest;
diff --git a/host/lib21/host_common.c b/host/lib21/host_common.c
index 245b1885..d0268c23 100644
--- a/host/lib21/host_common.c
+++ b/host/lib21/host_common.c
@@ -285,7 +285,7 @@ vb2_error_t vb21_verify_data(const void *data, uint32_t size,
if (!dc)
return VB2_ERROR_VDATA_WORKBUF_HASHING;
- rv = vb2_digest_init(dc, key->hash_alg);
+ rv = vb2_digest_init(dc, false, key->hash_alg, 0);
if (rv)
return rv;
diff --git a/host/lib21/host_signature.c b/host/lib21/host_signature.c
index 77ee448a..cd49b3b2 100644
--- a/host/lib21/host_signature.c
+++ b/host/lib21/host_signature.c
@@ -125,7 +125,7 @@ vb2_error_t vb21_sign_data(struct vb21_signature **sig_ptr, const uint8_t *data,
memcpy(sig_digest, info, info_size);
/* Calculate hash digest */
- if (vb2_digest_init(&dc, s.hash_alg)) {
+ if (vb2_digest_init(&dc, false, s.hash_alg, 0)) {
free(sig_digest);
return VB2_SIGN_DATA_DIGEST_INIT;
}
diff --git a/tests/sha_benchmark.c b/tests/sha_benchmark.c
index d7ba31ab..4626a429 100644
--- a/tests/sha_benchmark.c
+++ b/tests/sha_benchmark.c
@@ -20,14 +20,13 @@ int main(int argc, char *argv[]) {
double speed;
uint32_t msecs;
uint8_t *buffer = malloc(TEST_BUFFER_SIZE);
- uint8_t digest[VB2_MAX_DIGEST_SIZE];
+ struct vb2_hash hash;
ClockTimerState ct;
/* Iterate through all the hash functions. */
for(i = VB2_HASH_SHA1; i < VB2_HASH_ALG_COUNT; i++) {
StartTimer(&ct);
- vb2_digest_buffer(buffer, TEST_BUFFER_SIZE, i,
- digest, sizeof(digest));
+ vb2_hash_calculate(false, buffer, TEST_BUFFER_SIZE, i, &hash);
StopTimer(&ct);
msecs = GetDurationMsecs(&ct);
diff --git a/tests/vb20_api_kernel_tests.c b/tests/vb20_api_kernel_tests.c
index bc585b48..74aa4f4f 100644
--- a/tests/vb20_api_kernel_tests.c
+++ b/tests/vb20_api_kernel_tests.c
@@ -133,7 +133,7 @@ static void reset_common_data(enum reset_type t)
sig->sig_offset = vb2_offset_of(sig, sdata);
sig->sig_size = VB2_SHA512_DIGEST_SIZE;
- vb2_digest_init(&dc, VB2_HASH_SHA256);
+ vb2_digest_init(&dc, false, VB2_HASH_SHA256, 0);
vb2_digest_extend(&dc, (const uint8_t *)kernel_data,
sizeof(kernel_data));
vb2_digest_finalize(&dc, sdata, sig->sig_size);
diff --git a/tests/vb20_kernel_tests.c b/tests/vb20_kernel_tests.c
index 05f21ab6..6d685f64 100644
--- a/tests/vb20_kernel_tests.c
+++ b/tests/vb20_kernel_tests.c
@@ -67,7 +67,7 @@ static void rehash_keyblock(void)
hashsig->sig_offset = vb2_offset_of(hashsig, mock_vblock.k.hash);
hashsig->sig_size = sizeof(mock_vblock.k.hash);
hashsig->data_size = hashsig->sig_offset;
- vb2_digest_init(&dc, VB2_HASH_SHA512);
+ vb2_digest_init(&dc, false, VB2_HASH_SHA512, 0);
vb2_digest_extend(&dc, (const uint8_t *)kb, hashsig->data_size);
vb2_digest_finalize(&dc, mock_vblock.k.hash, hashsig->sig_size);
}
@@ -212,19 +212,6 @@ static void verify_keyblock_hash_tests(void)
"Keyblock check hash sig");
reset_common_data(FOR_KEYBLOCK);
- wb.size = VB2_SHA512_DIGEST_SIZE - 1;
- TEST_EQ(vb2_verify_keyblock_hash(kb, kb->keyblock_size, &wb),
- VB2_ERROR_VDATA_WORKBUF_DIGEST,
- "Keyblock check hash workbuf digest");
-
- reset_common_data(FOR_KEYBLOCK);
- wb.size = VB2_SHA512_DIGEST_SIZE +
- sizeof(struct vb2_digest_context) - 1;
- TEST_EQ(vb2_verify_keyblock_hash(kb, kb->keyblock_size, &wb),
- VB2_ERROR_VDATA_WORKBUF_HASHING,
- "Keyblock check hash workbuf hashing");
-
- reset_common_data(FOR_KEYBLOCK);
mock_vblock.k.data_key_data[0] ^= 0xa0;
TEST_EQ(vb2_verify_keyblock_hash(kb, kb->keyblock_size, &wb),
VB2_ERROR_KEYBLOCK_HASH_INVALID_IN_DEV_MODE,
diff --git a/tests/vb2_api_tests.c b/tests/vb2_api_tests.c
index ca2f7e93..2d0ffbf1 100644
--- a/tests/vb2_api_tests.c
+++ b/tests/vb2_api_tests.c
@@ -40,12 +40,6 @@ static const uint32_t digest_result_size = sizeof(digest_result);
/* Mocked function data */
-static enum {
- HWCRYPTO_DISABLED,
- HWCRYPTO_ENABLED,
- HWCRYPTO_FORBIDDEN,
-} hwcrypto_state;
-
static int force_dev_mode;
static vb2_error_t retval_vb2_fw_init_gbb;
static vb2_error_t retval_vb2_check_dev_switch;
@@ -81,9 +75,6 @@ static void reset_common_data(enum reset_type t)
vb2api_secdata_kernel_create(ctx);
vb2_secdata_kernel_init(ctx);
- if (hwcrypto_state != HWCRYPTO_FORBIDDEN)
- vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_FLAGS,
- VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED);
force_dev_mode = 0;
retval_vb2_fw_init_gbb = VB2_SUCCESS;
@@ -176,59 +167,19 @@ vb2_error_t vb2_unpack_key_buffer(struct vb2_public_key *key,
return VB2_SUCCESS;
}
-vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
- uint32_t data_size)
-{
- switch (hwcrypto_state) {
- case HWCRYPTO_DISABLED:
- return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
- case HWCRYPTO_ENABLED:
- if (hash_alg != mock_hash_alg)
- return VB2_ERROR_SHA_INIT_ALGORITHM;
- else
- return VB2_SUCCESS;
- case HWCRYPTO_FORBIDDEN:
- default:
- return VB2_ERROR_UNKNOWN;
- }
-}
-
-vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf,
- uint32_t size)
-{
- if (hwcrypto_state != HWCRYPTO_ENABLED)
- return VB2_ERROR_UNKNOWN;
-
- return VB2_SUCCESS;
-}
-
static void fill_digest(uint8_t *digest, uint32_t digest_size)
{
/* Set the result to a known value. */
memset(digest, 0x0a, digest_size);
}
-vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
- uint32_t digest_size)
+vb2_error_t vb2_digest_init(struct vb2_digest_context *dc, bool allow_hwcrypto,
+ enum vb2_hash_algorithm algo, uint32_t data_size)
{
- if (hwcrypto_state != HWCRYPTO_ENABLED)
- return VB2_ERROR_UNKNOWN;
-
- if (retval_vb2_digest_finalize == VB2_SUCCESS)
- fill_digest(digest, digest_size);
-
- return retval_vb2_digest_finalize;
-}
-
-vb2_error_t vb2_digest_init(struct vb2_digest_context *dc,
- enum vb2_hash_algorithm hash_alg)
-{
- if (hwcrypto_state == HWCRYPTO_ENABLED)
- return VB2_ERROR_UNKNOWN;
- if (hash_alg != mock_hash_alg)
+ if (algo != mock_hash_alg)
return VB2_ERROR_SHA_INIT_ALGORITHM;
- dc->hash_alg = hash_alg;
+ dc->hash_alg = algo;
dc->using_hwcrypto = 0;
return VB2_SUCCESS;
@@ -237,8 +188,6 @@ vb2_error_t vb2_digest_init(struct vb2_digest_context *dc,
vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf,
uint32_t size)
{
- if (hwcrypto_state == HWCRYPTO_ENABLED)
- return VB2_ERROR_UNKNOWN;
if (dc->hash_alg != mock_hash_alg)
return VB2_ERROR_SHA_EXTEND_ALGORITHM;
@@ -248,9 +197,6 @@ vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf,
vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest,
uint32_t digest_size)
{
- if (hwcrypto_state == HWCRYPTO_ENABLED)
- return VB2_ERROR_UNKNOWN;
-
if (retval_vb2_digest_finalize == VB2_SUCCESS)
fill_digest(digest, digest_size);
@@ -740,14 +686,11 @@ static void extend_hash_tests(void)
TEST_EQ(vb2api_extend_hash(ctx, mock_body, 0),
VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");
- if (hwcrypto_state != HWCRYPTO_ENABLED) {
- reset_common_data(FOR_EXTEND_HASH);
- dc = (struct vb2_digest_context *)
- vb2_member_of(sd, sd->hash_offset);
- dc->hash_alg = mock_hash_alg + 1;
- TEST_EQ(vb2api_extend_hash(ctx, mock_body, mock_body_size),
- VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
- }
+ reset_common_data(FOR_EXTEND_HASH);
+ dc = (struct vb2_digest_context *)vb2_member_of(sd, sd->hash_offset);
+ dc->hash_alg = mock_hash_alg + 1;
+ TEST_EQ(vb2api_extend_hash(ctx, mock_body, mock_body_size),
+ VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
}
static void check_hash_tests(void)
@@ -766,28 +709,30 @@ static void check_hash_tests(void)
"check digest value");
/* Test hwcrypto conditions */
- if (hwcrypto_state == HWCRYPTO_FORBIDDEN) {
- reset_common_data(FOR_CHECK_HASH);
- TEST_SUCC(vb2api_check_hash(ctx), "check hash good");
- TEST_EQ(last_used_key.allow_hwcrypto, 0,
- "hwcrypto is forbidden by TPM flag");
-
- reset_common_data(FOR_CHECK_HASH);
- ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
- TEST_SUCC(vb2api_check_hash(ctx), "check hash good");
- TEST_EQ(last_used_key.allow_hwcrypto, 0,
- "hwcrypto is forbidden by TPM flag on recovery mode");
- } else {
- reset_common_data(FOR_CHECK_HASH);
- TEST_SUCC(vb2api_check_hash(ctx), "check hash good");
- TEST_EQ(last_used_key.allow_hwcrypto, 1, "hwcrypto is allowed");
-
- reset_common_data(FOR_CHECK_HASH);
- ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
- TEST_SUCC(vb2api_check_hash(ctx), "check hash good");
- TEST_EQ(last_used_key.allow_hwcrypto, 0,
- "hwcrypto is forbidden on recovery mode");
- }
+ reset_common_data(FOR_CHECK_HASH);
+ TEST_SUCC(vb2api_check_hash(ctx), "check hash good");
+ TEST_EQ(last_used_key.allow_hwcrypto, 0,
+ "hwcrypto is forbidden by TPM flag");
+
+ reset_common_data(FOR_CHECK_HASH);
+ ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
+ TEST_SUCC(vb2api_check_hash(ctx), "check hash good");
+ TEST_EQ(last_used_key.allow_hwcrypto, 0,
+ "hwcrypto is forbidden by TPM flag on recovery mode");
+
+ reset_common_data(FOR_CHECK_HASH);
+ vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_FLAGS,
+ VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED);
+ TEST_SUCC(vb2api_check_hash(ctx), "check hash good");
+ TEST_EQ(last_used_key.allow_hwcrypto, 1, "hwcrypto is allowed");
+
+ reset_common_data(FOR_CHECK_HASH);
+ ctx->flags |= VB2_CONTEXT_RECOVERY_MODE;
+ vb2_secdata_kernel_set(ctx, VB2_SECDATA_KERNEL_FLAGS,
+ VB2_SECDATA_KERNEL_FLAG_HWCRYPTO_ALLOWED);
+ TEST_SUCC(vb2api_check_hash(ctx), "check hash good");
+ TEST_EQ(last_used_key.allow_hwcrypto, 0,
+ "hwcrypto is forbidden on recovery mode");
reset_common_data(FOR_CHECK_HASH);
TEST_EQ(vb2api_check_hash_get_digest(ctx, digest_result,
@@ -854,20 +799,6 @@ int main(int argc, char* argv[])
phase2_tests();
phase3_tests();
- fprintf(stderr, "Running hash API tests without hwcrypto support...\n");
- hwcrypto_state = HWCRYPTO_DISABLED;
- init_hash_tests();
- extend_hash_tests();
- check_hash_tests();
-
- fprintf(stderr, "Running hash API tests with hwcrypto support...\n");
- hwcrypto_state = HWCRYPTO_ENABLED;
- init_hash_tests();
- extend_hash_tests();
- check_hash_tests();
-
- fprintf(stderr, "Running hash API tests with forbidden hwcrypto...\n");
- hwcrypto_state = HWCRYPTO_FORBIDDEN;
init_hash_tests();
extend_hash_tests();
check_hash_tests();
diff --git a/tests/vb2_common2_tests.c b/tests/vb2_common2_tests.c
index e793e57a..18398c11 100644
--- a/tests/vb2_common2_tests.c
+++ b/tests/vb2_common2_tests.c
@@ -19,6 +19,28 @@
static const uint8_t test_data[] = "This is some test data to sign.";
static const uint32_t test_size = sizeof(test_data);
+static const uint8_t test_data_sha1[VB2_SHA1_DIGEST_SIZE] = {
+ 0x6f, 0xde, 0xe7, 0x73, 0x93, 0xbe, 0x23, 0x34,
+ 0xb3, 0x54, 0xc2, 0xe9, 0x18, 0xb8, 0x1b, 0xf8,
+ 0x99, 0x36, 0x63, 0x09,
+};
+static const uint8_t test_data_sha256[VB2_SHA256_DIGEST_SIZE] = {
+ 0xc0, 0x2c, 0xdb, 0x18, 0xe4, 0xd9, 0xfc, 0x65,
+ 0xcb, 0xea, 0x11, 0x8e, 0x9e, 0x1c, 0x51, 0x2d,
+ 0xeb, 0x69, 0x5f, 0x56, 0x1f, 0xd8, 0x77, 0x7b,
+ 0x7d, 0x9d, 0x4f, 0x21, 0x81, 0xac, 0x9e, 0xd5,
+};
+static const uint8_t test_data_sha512[VB2_SHA512_DIGEST_SIZE] = {
+ 0x0e, 0x0c, 0x9c, 0xf7, 0x08, 0x28, 0xee, 0xd7,
+ 0x0d, 0x62, 0xf5, 0x46, 0xa1, 0x2d, 0xf3, 0x79,
+ 0x41, 0x0c, 0x80, 0xbf, 0xaf, 0x1f, 0xfa, 0x41,
+ 0xdb, 0x8e, 0x30, 0x02, 0x16, 0xf1, 0x4b, 0x2c,
+ 0x67, 0x1f, 0x5b, 0xfb, 0x06, 0x49, 0xc9, 0xf4,
+ 0x6b, 0x62, 0xb9, 0x27, 0x94, 0xc3, 0xf4, 0xb8,
+ 0xc7, 0x23, 0x40, 0xc5, 0xfb, 0x74, 0xab, 0xa4,
+ 0x63, 0xfd, 0x3f, 0xf3, 0x2b, 0xa3, 0xc5, 0x3b,
+};
+static const uint8_t *hwcrypto_next_hash;
static enum hwcrypto_state {
HWCRYPTO_OK,
@@ -44,9 +66,23 @@ static vb2_error_t hwcrypto_mock(enum hwcrypto_state *state)
return VB2_ERROR_MOCK;
}
-vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
+vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm algo,
uint32_t data_size)
{
+ switch (algo) {
+ case VB2_HASH_SHA1:
+ hwcrypto_next_hash = test_data_sha1;
+ break;
+ case VB2_HASH_SHA256:
+ hwcrypto_next_hash = test_data_sha256;
+ break;
+ case VB2_HASH_SHA512:
+ hwcrypto_next_hash = test_data_sha512;
+ break;
+ default:
+ TEST_TRUE(false, " no mock hash for algorithm");
+ break;
+ }
return hwcrypto_mock(&hwcrypto_state_digest);
}
@@ -58,6 +94,7 @@ vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
uint32_t digest_size)
{
+ memcpy(digest, hwcrypto_next_hash, digest_size);
return hwcrypto_mock(&hwcrypto_state_digest);
}
diff --git a/tests/vb2_load_kernel2_tests.c b/tests/vb2_load_kernel2_tests.c
index dfb06fbf..3ec392fa 100644
--- a/tests/vb2_load_kernel2_tests.c
+++ b/tests/vb2_load_kernel2_tests.c
@@ -235,9 +235,8 @@ vb2_error_t vb2_verify_data(const uint8_t *data, uint32_t size,
return cur_kernel->rv;
}
-vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size,
- enum vb2_hash_algorithm hash_alg, uint8_t *digest,
- uint32_t digest_size)
+vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest,
+ uint32_t digest_size)
{
return cur_kernel->rv;
}
diff --git a/tests/vb2_load_kernel_tests.c b/tests/vb2_load_kernel_tests.c
index bb6f3487..932bc128 100644
--- a/tests/vb2_load_kernel_tests.c
+++ b/tests/vb2_load_kernel_tests.c
@@ -262,11 +262,13 @@ vb2_error_t vb2_verify_data(const uint8_t *data, uint32_t size,
return VB2_SUCCESS;
}
-vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size,
- enum vb2_hash_algorithm hash_alg, uint8_t *digest,
- uint32_t digest_size)
+vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest,
+ uint32_t digest_size)
{
- memcpy(digest, mock_digest, sizeof(mock_digest));
+ if (digest_size == sizeof(mock_digest))
+ memcpy(digest, mock_digest, digest_size);
+ else
+ TEST_TRUE(false, " unexpected digest size");
return VB2_SUCCESS;
}
diff --git a/tests/vb2_sha256_x86_tests.c b/tests/vb2_sha256_x86_tests.c
index e17d3951..3269cc54 100644
--- a/tests/vb2_sha256_x86_tests.c
+++ b/tests/vb2_sha256_x86_tests.c
@@ -13,9 +13,9 @@
#include "common/tests.h"
#include "sha_test_vectors.h"
-vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size,
- enum vb2_hash_algorithm hash_alg, uint8_t *digest,
- uint32_t digest_size)
+static vb2_error_t vb2_digest_buffer(const uint8_t *buf, uint32_t size,
+ enum vb2_hash_algorithm hash_alg,
+ uint8_t *digest, uint32_t digest_size)
{
VB2_TRY(vb2ex_hwcrypto_digest_init(hash_alg, size));
VB2_TRY(vb2ex_hwcrypto_digest_extend(buf, size));
diff --git a/tests/vb2_sha_api_tests.c b/tests/vb2_sha_api_tests.c
index 6ed0b74b..be277b38 100644
--- a/tests/vb2_sha_api_tests.c
+++ b/tests/vb2_sha_api_tests.c
@@ -2,9 +2,11 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
- * Tests for vb2_hash_(calculate|verify) functions.
+ * Tests for vb2_hash_(calculate|verify) functions, and hwcrypto handling
+ * of vb2_digest_*.
*/
+#include "2api.h"
#include "2return_codes.h"
#include "2sha.h"
#include "2sysincludes.h"
@@ -17,41 +19,83 @@ _Static_assert(sizeof(mock_sha1) == VB2_SHA1_DIGEST_SIZE, "");
struct vb2_hash mock_hash;
uint8_t mock_buffer[] = "Mock Buffer";
-vb2_error_t mock_init_rv;
-vb2_error_t mock_extend_rv;
-vb2_error_t mock_finalize_rv;
+static enum hwcrypto_state {
+ HWCRYPTO_OK,
+ HWCRYPTO_NOTSUPPORTED,
+ HWCRYPTO_ERROR,
+ HWCRYPTO_ABORT,
+} hwcrypto_state;
-static void reset_common_data(void)
+static vb2_error_t hwcrypto_mock(enum hwcrypto_state *state)
{
+ switch (*state) {
+ case HWCRYPTO_OK:
+ return VB2_SUCCESS;
+ case HWCRYPTO_NOTSUPPORTED:
+ return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
+ case HWCRYPTO_ERROR:
+ return VB2_ERROR_MOCK;
+ case HWCRYPTO_ABORT:
+ vb2ex_abort();
+ /* shouldn't reach here but added for compiler */
+ return VB2_ERROR_MOCK;
+ }
+ return VB2_ERROR_MOCK;
+}
+
+static void reset_common_data(enum hwcrypto_state state)
+{
+ hwcrypto_state = state;
memset(&mock_hash, 0xaa, sizeof(mock_hash));
+}
- mock_init_rv = VB2_SUCCESS;
- mock_extend_rv = VB2_SUCCESS;
- mock_finalize_rv = VB2_SUCCESS;
+void vb2_sha1_init(struct vb2_sha1_context *ctx)
+{
+ TEST_TRUE(hwcrypto_state == HWCRYPTO_NOTSUPPORTED ||
+ hwcrypto_state == HWCRYPTO_ABORT,
+ " hwcrypto_state in SW init");
}
-vb2_error_t vb2_digest_init(struct vb2_digest_context *dc,
- enum vb2_hash_algorithm hash_alg)
+void vb2_sha1_update(struct vb2_sha1_context *ctx,
+ const uint8_t *data,
+ uint32_t size)
{
- if (hash_alg != VB2_HASH_SHA1)
- return VB2_ERROR_MOCK;
- return mock_init_rv;
+ TEST_TRUE(hwcrypto_state == HWCRYPTO_NOTSUPPORTED ||
+ hwcrypto_state == HWCRYPTO_ABORT,
+ " hwcrypto_state in SW extend");
+ TEST_PTR_EQ(data, mock_buffer, " digest_extend buf");
+ TEST_EQ(size, sizeof(mock_buffer), " digest_extend size");
+}
+
+void vb2_sha1_finalize(struct vb2_sha1_context *ctx, uint8_t *digest)
+{
+ TEST_TRUE(hwcrypto_state == HWCRYPTO_NOTSUPPORTED ||
+ hwcrypto_state == HWCRYPTO_ABORT,
+ " hwcrypto_state in SW finalize");
+ memcpy(digest, mock_sha1, sizeof(mock_sha1));
}
-vb2_error_t vb2_digest_extend(struct vb2_digest_context *dc, const uint8_t *buf,
- uint32_t size)
+vb2_error_t vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg,
+ uint32_t data_size)
{
- TEST_PTR_EQ(buf, mock_buffer, "digest_extend unexpected buf");
- TEST_EQ(size, sizeof(mock_buffer), "digest_extend unexpected size");
- return mock_extend_rv;
+ if (data_size)
+ TEST_EQ(data_size, sizeof(mock_buffer),
+ " hwcrypto_digest_init size");
+ return hwcrypto_mock(&hwcrypto_state);
}
-vb2_error_t vb2_digest_finalize(struct vb2_digest_context *dc, uint8_t *digest,
- uint32_t size)
+vb2_error_t vb2ex_hwcrypto_digest_extend(const uint8_t *buf, uint32_t size)
{
- TEST_EQ(size, VB2_SHA1_DIGEST_SIZE, "digest_finalize unexpected size");
- memcpy(digest, mock_sha1, size);
- return mock_finalize_rv;
+ TEST_PTR_EQ(buf, mock_buffer, " hwcrypto_digest_extend buf");
+ TEST_EQ(size, sizeof(mock_buffer), " hwcrypto_digest_extend size");
+ return hwcrypto_mock(&hwcrypto_state);
+}
+
+vb2_error_t vb2ex_hwcrypto_digest_finalize(uint8_t *digest,
+ uint32_t digest_size)
+{
+ memcpy(digest, mock_sha1, sizeof(mock_sha1));
+ return hwcrypto_mock(&hwcrypto_state);
}
static void vb2_hash_cbfs_compatibility_test(void)
@@ -73,56 +117,93 @@ static void vb2_hash_cbfs_compatibility_test(void)
static void vb2_hash_calculate_tests(void)
{
- reset_common_data();
- TEST_SUCC(vb2_hash_calculate(&mock_buffer, sizeof(mock_buffer),
+ reset_common_data(HWCRYPTO_ABORT);
+ TEST_SUCC(vb2_hash_calculate(false, &mock_buffer, sizeof(mock_buffer),
VB2_HASH_SHA1, &mock_hash),
"hash_calculate success");
TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)),
" got the right hash");
TEST_EQ(mock_hash.algo, VB2_HASH_SHA1, " set algo correctly");
- reset_common_data();
- mock_init_rv = VB2_ERROR_MOCK;
- TEST_EQ(vb2_hash_calculate(mock_buffer, sizeof(mock_buffer),
- VB2_HASH_SHA1, &mock_hash),
- VB2_ERROR_MOCK, "hash_calculate init error");
-
- reset_common_data();
- mock_extend_rv = VB2_ERROR_MOCK;
- TEST_EQ(vb2_hash_calculate(mock_buffer, sizeof(mock_buffer),
- VB2_HASH_SHA1, &mock_hash),
- VB2_ERROR_MOCK, "hash_calculate extend error");
-
- reset_common_data();
- mock_finalize_rv = VB2_ERROR_MOCK;
- TEST_EQ(vb2_hash_calculate(mock_buffer, sizeof(mock_buffer),
- VB2_HASH_SHA1, &mock_hash),
- VB2_ERROR_MOCK, "hash_calculate finalize error");
+ reset_common_data(HWCRYPTO_ABORT);
+ TEST_EQ(vb2_hash_calculate(false, mock_buffer, sizeof(mock_buffer),
+ -1, &mock_hash),
+ VB2_ERROR_SHA_INIT_ALGORITHM, "hash_calculate wrong algo");
}
static void vb2_hash_verify_tests(void)
{
- reset_common_data();
+ reset_common_data(HWCRYPTO_ABORT);
memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1));
mock_hash.algo = VB2_HASH_SHA1;
- TEST_SUCC(vb2_hash_verify(mock_buffer, sizeof(mock_buffer),
+ TEST_SUCC(vb2_hash_verify(false, mock_buffer, sizeof(mock_buffer),
&mock_hash), "hash_verify success");
memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1));
- mock_hash.algo = VB2_HASH_SHA256;
- TEST_EQ(vb2_hash_verify(mock_buffer, sizeof(mock_buffer),
- &mock_hash), VB2_ERROR_MOCK,
+ mock_hash.algo = -1;
+ TEST_EQ(vb2_hash_verify(false, mock_buffer, sizeof(mock_buffer),
+ &mock_hash), VB2_ERROR_SHA_INIT_ALGORITHM,
"hash_verify wrong algo");
memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1));
mock_hash.sha1[5] = 0xfe;
mock_hash.algo = VB2_HASH_SHA1;
- TEST_EQ(vb2_hash_verify(mock_buffer, sizeof(mock_buffer),
+ TEST_EQ(vb2_hash_verify(false, mock_buffer, sizeof(mock_buffer),
&mock_hash), VB2_ERROR_SHA_MISMATCH,
"hash_verify mismatch");
}
+static void vb2_hash_hwcrypto_tests(void)
+{
+ struct vb2_digest_context dc;
+
+ reset_common_data(HWCRYPTO_OK);
+ TEST_SUCC(vb2_digest_init(&dc, true, VB2_HASH_SHA1,
+ sizeof(mock_buffer)),
+ "digest_init, HW enabled");
+ TEST_EQ(dc.using_hwcrypto, 1, " using_hwcrypto set");
+ TEST_SUCC(vb2_digest_extend(&dc, mock_buffer, sizeof(mock_buffer)),
+ "digest_extend, HW enabled");
+ TEST_SUCC(vb2_digest_finalize(&dc, mock_hash.raw, VB2_SHA1_DIGEST_SIZE),
+ "digest_finalize, HW enabled ");
+ TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)),
+ " got the right hash");
+
+ reset_common_data(HWCRYPTO_OK);
+ TEST_SUCC(vb2_hash_calculate(true, mock_buffer, sizeof(mock_buffer),
+ VB2_HASH_SHA1, &mock_hash),
+ "hash_calculate, HW enabled");
+ TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)),
+ " got the right hash");
+ TEST_EQ(mock_hash.algo, VB2_HASH_SHA1, " algo set");
+
+ reset_common_data(HWCRYPTO_ERROR);
+ TEST_EQ(vb2_hash_calculate(true, mock_buffer, sizeof(mock_buffer),
+ VB2_HASH_SHA1, &mock_hash),
+ VB2_ERROR_MOCK, "hash_calculate, HW error");
+
+ reset_common_data(HWCRYPTO_NOTSUPPORTED);
+ TEST_SUCC(vb2_hash_calculate(true, mock_buffer, sizeof(mock_buffer),
+ VB2_HASH_SHA1, &mock_hash),
+ "hash_calculate, HW unsupported");
+ TEST_SUCC(memcmp(mock_hash.sha1, mock_sha1, sizeof(mock_sha1)),
+ " got the right hash");
+
+ reset_common_data(HWCRYPTO_OK);
+ memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1));
+ mock_hash.algo = VB2_HASH_SHA1;
+ TEST_SUCC(vb2_hash_verify(true, mock_buffer, sizeof(mock_buffer),
+ &mock_hash), "hash_verify, HW enabled");
+
+ memcpy(mock_hash.sha1, mock_sha1, sizeof(mock_sha1));
+ mock_hash.sha1[5] = 0xfe;
+ mock_hash.algo = VB2_HASH_SHA1;
+ TEST_EQ(vb2_hash_verify(true, mock_buffer, sizeof(mock_buffer),
+ &mock_hash), VB2_ERROR_SHA_MISMATCH,
+ "hash_verify HW mismatch");
+}
+
int main(int argc, char *argv[])
{
TEST_EQ(sizeof(mock_hash),
@@ -132,6 +213,7 @@ int main(int argc, char *argv[])
vb2_hash_cbfs_compatibility_test();
vb2_hash_calculate_tests();
vb2_hash_verify_tests();
+ vb2_hash_hwcrypto_tests();
return gTestSuccess ? 0 : 255;
}
diff --git a/tests/vb2_sha_tests.c b/tests/vb2_sha_tests.c
index 40cf42f5..92213830 100644
--- a/tests/vb2_sha_tests.c
+++ b/tests/vb2_sha_tests.c
@@ -16,7 +16,7 @@
static void sha1_tests(void)
{
- uint8_t digest[VB2_SHA1_DIGEST_SIZE];
+ struct vb2_hash hash;
uint8_t *test_inputs[3];
int i;
@@ -25,20 +25,21 @@ static void sha1_tests(void)
test_inputs[2] = (uint8_t *) long_msg;
for (i = 0; i < 3; i++) {
- TEST_SUCC(vb2_digest_buffer(test_inputs[i],
- strlen((char *)test_inputs[i]),
- VB2_HASH_SHA1,
- digest, sizeof(digest)),
- "vb2_digest_buffer() SHA1");
- TEST_EQ(memcmp(digest, sha1_results[i], sizeof(digest)),
- 0, "SHA1 digest");
+ TEST_SUCC(vb2_hash_calculate(false, test_inputs[i],
+ strlen((const char *)test_inputs[i]),
+ VB2_HASH_SHA1, &hash),
+ "vb2_hash_calculate() SHA-1");
+ TEST_EQ(memcmp(hash.sha1, sha1_results[i],
+ sizeof(sha1_results[i])), 0, " SHA-1 digest");
}
- TEST_EQ(vb2_digest_buffer(test_inputs[0],
- strlen((char *)test_inputs[0]),
- VB2_HASH_SHA1, digest, sizeof(digest) - 1),
+ struct vb2_digest_context dc;
+ vb2_digest_init(&dc, false, VB2_HASH_SHA1, 0);
+ vb2_digest_extend(&dc, test_inputs[0],
+ strlen((const char *)test_inputs[0]));
+ TEST_EQ(vb2_digest_finalize(&dc, hash.sha1, sizeof(hash.sha1) - 1),
VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE,
- "vb2_digest_buffer() too small");
+ "vb2_digest_finalize() SHA-1 too small");
TEST_EQ(vb2_hash_block_size(VB2_HASH_SHA1), VB2_SHA1_BLOCK_SIZE,
"vb2_hash_block_size(VB2_HASH_SHA1)");
@@ -46,7 +47,7 @@ static void sha1_tests(void)
static void sha256_tests(void)
{
- uint8_t digest[VB2_SHA256_DIGEST_SIZE];
+ struct vb2_hash hash;
uint8_t *test_inputs[3];
struct vb2_sha256_context ctx;
const uint8_t expect_multiple[VB2_SHA256_DIGEST_SIZE] = {
@@ -68,41 +69,41 @@ static void sha256_tests(void)
test_inputs[2] = (uint8_t *) long_msg;
for (i = 0; i < 3; i++) {
- TEST_SUCC(vb2_digest_buffer(test_inputs[i],
- strlen((char *)test_inputs[i]),
- VB2_HASH_SHA256,
- digest, sizeof(digest)),
- "vb2_digest_buffer() SHA256");
- TEST_EQ(memcmp(digest, sha256_results[i], sizeof(digest)),
- 0, "SHA-256 digest");
+ TEST_SUCC(vb2_hash_calculate(false, test_inputs[i],
+ strlen((const char *)test_inputs[i]),
+ VB2_HASH_SHA256, &hash),
+ "vb2_hash_calculate() SHA-256");
+ TEST_EQ(memcmp(hash.sha256, sha256_results[i],
+ sizeof(sha256_results[i])), 0, " SHA-256 digest");
}
- TEST_EQ(vb2_digest_buffer(test_inputs[0],
- strlen((char *)test_inputs[0]),
- VB2_HASH_SHA256, digest, sizeof(digest) - 1),
+ struct vb2_digest_context dc;
+ vb2_digest_init(&dc, false, VB2_HASH_SHA256, 0);
+ vb2_digest_extend(&dc, test_inputs[0], strlen((const char *)test_inputs[0]));
+ TEST_EQ(vb2_digest_finalize(&dc, hash.sha256, sizeof(hash.sha256) - 1),
VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE,
- "vb2_digest_buffer() too small");
+ "vb2_digest_finalize() SHA-256 too small");
/* Test multiple small extends */
vb2_sha256_init(&ctx, VB2_HASH_SHA256);
vb2_sha256_update(&ctx, (uint8_t *)"test1", 5);
vb2_sha256_update(&ctx, (uint8_t *)"test2", 5);
vb2_sha256_update(&ctx, (uint8_t *)"test3", 5);
- vb2_sha256_finalize(&ctx, digest, VB2_HASH_SHA256);
- TEST_EQ(memcmp(digest, expect_multiple, sizeof(digest)), 0,
+ vb2_sha256_finalize(&ctx, hash.sha256, VB2_HASH_SHA256);
+ TEST_EQ(memcmp(hash.sha256, expect_multiple, sizeof(hash.sha256)), 0,
"SHA-256 multiple extends");
TEST_EQ(vb2_hash_block_size(VB2_HASH_SHA256), VB2_SHA256_BLOCK_SIZE,
"vb2_hash_block_size(VB2_HASH_SHA256)");
/* Test SHA256 hash extend */
- vb2_sha256_extend(extend_from, extend_by, digest);
- TEST_SUCC(memcmp(digest, expected_extend, sizeof(digest)), NULL);
+ vb2_sha256_extend(extend_from, extend_by, hash.sha256);
+ TEST_SUCC(memcmp(hash.sha256, expected_extend, sizeof(hash.sha256)), NULL);
}
static void sha512_tests(void)
{
- uint8_t digest[VB2_SHA512_DIGEST_SIZE];
+ struct vb2_hash hash;
uint8_t *test_inputs[3];
int i;
@@ -111,20 +112,20 @@ static void sha512_tests(void)
test_inputs[2] = (uint8_t *) long_msg;
for (i = 0; i < 3; i++) {
- TEST_SUCC(vb2_digest_buffer(test_inputs[i],
- strlen((char *)test_inputs[i]),
- VB2_HASH_SHA512,
- digest, sizeof(digest)),
- "vb2_digest_buffer() SHA512");
- TEST_EQ(memcmp(digest, sha512_results[i], sizeof(digest)),
- 0, "SHA-512 digest");
+ TEST_SUCC(vb2_hash_calculate(false, test_inputs[i],
+ strlen((const char *)test_inputs[i]),
+ VB2_HASH_SHA512, &hash),
+ "vb2_hash_calculate() SHA512");
+ TEST_EQ(memcmp(hash.sha512, sha512_results[i],
+ sizeof(sha512_results[i])), 0, " SHA-512 digest");
}
- TEST_EQ(vb2_digest_buffer(test_inputs[0],
- strlen((char *)test_inputs[0]),
- VB2_HASH_SHA512, digest, sizeof(digest) - 1),
+ struct vb2_digest_context dc;
+ vb2_digest_init(&dc, false, VB2_HASH_SHA512, 0);
+ vb2_digest_extend(&dc, test_inputs[0], strlen((const char *)test_inputs[0]));
+ TEST_EQ(vb2_digest_finalize(&dc, hash.sha512, sizeof(hash.sha512) - 1),
VB2_ERROR_SHA_FINALIZE_DIGEST_SIZE,
- "vb2_digest_buffer() too small");
+ "vb2_digest_finalize() SHA-512 too small");
TEST_EQ(vb2_hash_block_size(VB2_HASH_SHA512), VB2_SHA512_BLOCK_SIZE,
"vb2_hash_block_size(VB2_HASH_SHA512)");
@@ -153,13 +154,8 @@ static void misc_tests(void)
TEST_EQ(vb2_hash_block_size(VB2_HASH_INVALID), 0,
"vb2_hash_block_size(VB2_HASH_INVALID)");
- TEST_EQ(vb2_digest_buffer((uint8_t *)oneblock_msg, strlen(oneblock_msg),
- VB2_HASH_INVALID, digest, sizeof(digest)),
- VB2_ERROR_SHA_INIT_ALGORITHM,
- "vb2_digest_buffer() invalid alg");
-
/* Test bad algorithm inside extend and finalize */
- vb2_digest_init(&dc, VB2_HASH_SHA256);
+ vb2_digest_init(&dc, false, VB2_HASH_SHA256, 0);
dc.hash_alg = VB2_HASH_INVALID;
TEST_EQ(vb2_digest_extend(&dc, digest, sizeof(digest)),
VB2_ERROR_SHA_EXTEND_ALGORITHM,
@@ -185,7 +181,7 @@ static void known_value_tests(void)
char *sent_base = test.overflow + \
offsetof(struct vb2_hash, raw) + sizeof(value) - 1; \
strcpy(sent_base, sentinel); \
- TEST_SUCC(vb2_hash_calculate(str, sizeof(str) - 1, \
+ TEST_SUCC(vb2_hash_calculate(false, str, sizeof(str) - 1, \
algo, &test.hash), \
"Calculate known hash " #algo ": " #str); \
TEST_EQ(memcmp(test.hash.raw, value, sizeof(value) - 1), 0, \