summaryrefslogtreecommitdiff
path: root/firmware
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 /firmware
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>
Diffstat (limited to 'firmware')
-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
14 files changed, 126 insertions, 176 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));