summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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, \