diff options
author | Joel Kitching <kitching@google.com> | 2019-06-14 16:28:33 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-10-23 16:28:15 +0000 |
commit | 53ce884528f734958d4845f6528809957b09934c (patch) | |
tree | 840ff9b00f4d582929c4e143d1d347ad4ef7260b | |
parent | 77dff643fc445f5faba647fddd4a7b17bb193f26 (diff) | |
download | vboot-53ce884528f734958d4845f6528809957b09934c.tar.gz |
vboot: fold lib20/api.c into 2lib/2api.c
All of the functions in lib20/api.c are actively used in coreboot
verstage firmware verification. Fold the functions and their
test suite into 2lib.
BUG=b:124141368, chromium:968464
TEST=make clean && make runtests
BRANCH=none
Change-Id: I2dbad2715246a8a16ee85dac553a751ae1590afa
Signed-off-by: Joel Kitching <kitching@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/1659991
Tested-by: Joel Kitching <kitching@chromium.org>
Commit-Queue: Joel Kitching <kitching@chromium.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | firmware/2lib/2api.c | 201 | ||||
-rw-r--r-- | firmware/lib20/api.c | 216 | ||||
-rw-r--r-- | tests/vb20_api_tests.c | 440 | ||||
-rw-r--r-- | tests/vb2_api_tests.c | 383 |
5 files changed, 583 insertions, 660 deletions
@@ -373,7 +373,6 @@ FWLIB2X_SRCS = \ firmware/2lib/2hmac.c FWLIB20_SRCS = \ - firmware/lib20/api.c \ firmware/lib20/api_kernel.c \ firmware/lib20/common.c \ firmware/lib20/kernel.c \ @@ -722,7 +721,6 @@ TEST2X_NAMES = \ tests/hmac_test TEST20_NAMES = \ - tests/vb20_api_tests \ tests/vb20_api_kernel_tests \ tests/vb20_common_tests \ tests/vb20_common2_tests \ @@ -1278,7 +1276,6 @@ run2tests: test_setup ${RUNTEST} ${BUILD_RUN}/tests/vb2_secdata_fwmp_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_secdata_kernel_tests ${RUNTEST} ${BUILD_RUN}/tests/vb2_sha_tests - ${RUNTEST} ${BUILD_RUN}/tests/vb20_api_tests ${RUNTEST} ${BUILD_RUN}/tests/vb20_api_kernel_tests ${RUNTEST} ${BUILD_RUN}/tests/vb20_common_tests ${RUNTEST} ${BUILD_RUN}/tests/vb20_common2_tests ${TEST_KEYS} diff --git a/firmware/2lib/2api.c b/firmware/2lib/2api.c index cc2c17bd..9b7f9533 100644 --- a/firmware/2lib/2api.c +++ b/firmware/2lib/2api.c @@ -15,6 +15,7 @@ #include "2sha.h" #include "2sysincludes.h" #include "2tpm_bootmode.h" +#include "vb2_common.h" vb2_error_t vb2api_fw_phase1(struct vb2_context *ctx) { @@ -207,3 +208,203 @@ vb2_error_t vb2api_get_pcr_digest(struct vb2_context *ctx, return VB2_SUCCESS; } + +vb2_error_t vb2api_fw_phase3(struct vb2_context *ctx) +{ + vb2_error_t rv; + + /* Verify firmware keyblock */ + rv = vb2_load_fw_keyblock(ctx); + if (rv) { + vb2api_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); + return rv; + } + + /* Verify firmware preamble */ + rv = vb2_load_fw_preamble(ctx); + if (rv) { + vb2api_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); + return rv; + } + + return VB2_SUCCESS; +} + +vb2_error_t vb2api_init_hash(struct vb2_context *ctx, uint32_t tag, + uint32_t *size) +{ + struct vb2_shared_data *sd = vb2_get_sd(ctx); + const struct vb2_fw_preamble *pre; + struct vb2_digest_context *dc; + struct vb2_public_key key; + struct vb2_workbuf wb; + vb2_error_t rv; + + vb2_workbuf_from_ctx(ctx, &wb); + + if (tag == VB2_HASH_TAG_INVALID) + return VB2_ERROR_API_INIT_HASH_TAG; + + /* Get preamble pointer */ + if (!sd->preamble_size) + return VB2_ERROR_API_INIT_HASH_PREAMBLE; + pre = (const struct vb2_fw_preamble *) + vb2_member_of(sd, sd->preamble_offset); + + /* For now, we only support the firmware body tag */ + if (tag != VB2_HASH_TAG_FW_BODY) + return VB2_ERROR_API_INIT_HASH_TAG; + + /* Allocate workbuf space for the hash */ + if (sd->hash_size) { + dc = (struct vb2_digest_context *) + vb2_member_of(sd, sd->hash_offset); + } else { + uint32_t dig_size = sizeof(*dc); + + dc = vb2_workbuf_alloc(&wb, dig_size); + if (!dc) + return VB2_ERROR_API_INIT_HASH_WORKBUF; + + sd->hash_offset = vb2_offset_of(sd, dc); + sd->hash_size = dig_size; + vb2_set_workbuf_used(ctx, sd->hash_offset + dig_size); + } + + /* + * Work buffer now contains: + * - vb2_shared_data + * - packed firmware data key + * - firmware preamble + * - hash data + */ + + /* + * Unpack the firmware data key to see which hashing algorithm we + * should use. + * + * TODO: really, the firmware body should be hashed, and not signed, + * because the signature we're checking is already signed as part of + * the firmware preamble. But until we can change the signing scripts, + * we're stuck with a signature here instead of a hash. + */ + if (!sd->data_key_size) + return VB2_ERROR_API_INIT_HASH_DATA_KEY; + + rv = vb2_unpack_key_buffer(&key, + vb2_member_of(sd, sd->data_key_offset), + sd->data_key_size); + if (rv) + return rv; + + sd->hash_tag = tag; + sd->hash_remaining_size = pre->body_signature.data_size; + + if (size) + *size = pre->body_signature.data_size; + + if (!(pre->flags & VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO)) { + 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 preamble, using SW\n"); + } + + return vb2_digest_init(dc, key.hash_alg); +} + +vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx, + void *digest_out, + uint32_t digest_out_size) +{ + struct vb2_shared_data *sd = vb2_get_sd(ctx); + struct vb2_digest_context *dc = (struct vb2_digest_context *) + vb2_member_of(sd, sd->hash_offset); + struct vb2_workbuf wb; + + uint8_t *digest; + uint32_t digest_size = vb2_digest_size(dc->hash_alg); + + struct vb2_fw_preamble *pre; + struct vb2_public_key key; + vb2_error_t rv; + + vb2_workbuf_from_ctx(ctx, &wb); + + /* Get preamble pointer */ + if (!sd->preamble_size) + return VB2_ERROR_API_CHECK_HASH_PREAMBLE; + pre = vb2_member_of(sd, sd->preamble_offset); + + /* Must have initialized hash digest work area */ + if (!sd->hash_size) + return VB2_ERROR_API_CHECK_HASH_WORKBUF; + + /* Should have hashed the right amount of data */ + if (sd->hash_remaining_size) + return VB2_ERROR_API_CHECK_HASH_SIZE; + + /* Allocate the digest */ + digest = vb2_workbuf_alloc(&wb, digest_size); + if (!digest) + return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST; + + /* Finalize the digest */ + if (dc->using_hwcrypto) + rv = vb2ex_hwcrypto_digest_finalize(digest, digest_size); + else + rv = vb2_digest_finalize(dc, digest, digest_size); + if (rv) + return rv; + + /* The code below is specific to the body signature */ + if (sd->hash_tag != VB2_HASH_TAG_FW_BODY) + return VB2_ERROR_API_CHECK_HASH_TAG; + + /* + * The body signature is currently a *signature* of the body data, not + * just its hash. So we need to verify the signature. + */ + + /* Unpack the data key */ + if (!sd->data_key_size) + return VB2_ERROR_API_CHECK_HASH_DATA_KEY; + + rv = vb2_unpack_key_buffer(&key, + vb2_member_of(sd, sd->data_key_offset), + sd->data_key_size); + if (rv) + return rv; + + /* + * Check digest vs. signature. Note that this destroys the signature. + * That's ok, because we only check each signature once per boot. + */ + rv = vb2_verify_digest(&key, &pre->body_signature, digest, &wb); + if (rv) + vb2api_fail(ctx, VB2_RECOVERY_FW_BODY, rv); + + if (digest_out != NULL) { + if (digest_out_size < digest_size) + return VB2_ERROR_API_CHECK_DIGEST_SIZE; + memcpy(digest_out, digest, digest_size); + } + + return rv; +} + +int vb2api_check_hash(struct vb2_context *ctx) +{ + return vb2api_check_hash_get_digest(ctx, NULL, 0); +} diff --git a/firmware/lib20/api.c b/firmware/lib20/api.c deleted file mode 100644 index f70e2625..00000000 --- a/firmware/lib20/api.c +++ /dev/null @@ -1,216 +0,0 @@ -/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Externally-callable APIs - * (Firmware portion) - */ - -#include "2api.h" -#include "2misc.h" -#include "2nvstorage.h" -#include "2rsa.h" -#include "2secdata.h" -#include "2sha.h" -#include "2sysincludes.h" -#include "vb2_common.h" - -vb2_error_t vb2api_fw_phase3(struct vb2_context *ctx) -{ - vb2_error_t rv; - - /* Verify firmware keyblock */ - rv = vb2_load_fw_keyblock(ctx); - if (rv) { - vb2api_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); - return rv; - } - - /* Verify firmware preamble */ - rv = vb2_load_fw_preamble(ctx); - if (rv) { - vb2api_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); - return rv; - } - - return VB2_SUCCESS; -} - -vb2_error_t vb2api_init_hash(struct vb2_context *ctx, uint32_t tag, - uint32_t *size) -{ - struct vb2_shared_data *sd = vb2_get_sd(ctx); - const struct vb2_fw_preamble *pre; - struct vb2_digest_context *dc; - struct vb2_public_key key; - struct vb2_workbuf wb; - vb2_error_t rv; - - vb2_workbuf_from_ctx(ctx, &wb); - - if (tag == VB2_HASH_TAG_INVALID) - return VB2_ERROR_API_INIT_HASH_TAG; - - /* Get preamble pointer */ - if (!sd->preamble_size) - return VB2_ERROR_API_INIT_HASH_PREAMBLE; - pre = (const struct vb2_fw_preamble *) - vb2_member_of(sd, sd->preamble_offset); - - /* For now, we only support the firmware body tag */ - if (tag != VB2_HASH_TAG_FW_BODY) - return VB2_ERROR_API_INIT_HASH_TAG; - - /* Allocate workbuf space for the hash */ - if (sd->hash_size) { - dc = (struct vb2_digest_context *) - vb2_member_of(sd, sd->hash_offset); - } else { - uint32_t dig_size = sizeof(*dc); - - dc = vb2_workbuf_alloc(&wb, dig_size); - if (!dc) - return VB2_ERROR_API_INIT_HASH_WORKBUF; - - sd->hash_offset = vb2_offset_of(sd, dc); - sd->hash_size = dig_size; - vb2_set_workbuf_used(ctx, sd->hash_offset + dig_size); - } - - /* - * Work buffer now contains: - * - vb2_shared_data - * - packed firmware data key - * - firmware preamble - * - hash data - */ - - /* - * Unpack the firmware data key to see which hashing algorithm we - * should use. - * - * TODO: really, the firmware body should be hashed, and not signed, - * because the signature we're checking is already signed as part of - * the firmware preamble. But until we can change the signing scripts, - * we're stuck with a signature here instead of a hash. - */ - if (!sd->data_key_size) - return VB2_ERROR_API_INIT_HASH_DATA_KEY; - - rv = vb2_unpack_key_buffer(&key, - vb2_member_of(sd, sd->data_key_offset), - sd->data_key_size); - if (rv) - return rv; - - sd->hash_tag = tag; - sd->hash_remaining_size = pre->body_signature.data_size; - - if (size) - *size = pre->body_signature.data_size; - - if (!(pre->flags & VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO)) { - 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 preamble, using SW\n"); - } - - return vb2_digest_init(dc, key.hash_alg); -} - -vb2_error_t vb2api_check_hash_get_digest(struct vb2_context *ctx, - void *digest_out, - uint32_t digest_out_size) -{ - struct vb2_shared_data *sd = vb2_get_sd(ctx); - struct vb2_digest_context *dc = (struct vb2_digest_context *) - vb2_member_of(sd, sd->hash_offset); - struct vb2_workbuf wb; - - uint8_t *digest; - uint32_t digest_size = vb2_digest_size(dc->hash_alg); - - struct vb2_fw_preamble *pre; - struct vb2_public_key key; - vb2_error_t rv; - - vb2_workbuf_from_ctx(ctx, &wb); - - /* Get preamble pointer */ - if (!sd->preamble_size) - return VB2_ERROR_API_CHECK_HASH_PREAMBLE; - pre = vb2_member_of(sd, sd->preamble_offset); - - /* Must have initialized hash digest work area */ - if (!sd->hash_size) - return VB2_ERROR_API_CHECK_HASH_WORKBUF; - - /* Should have hashed the right amount of data */ - if (sd->hash_remaining_size) - return VB2_ERROR_API_CHECK_HASH_SIZE; - - /* Allocate the digest */ - digest = vb2_workbuf_alloc(&wb, digest_size); - if (!digest) - return VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST; - - /* Finalize the digest */ - if (dc->using_hwcrypto) - rv = vb2ex_hwcrypto_digest_finalize(digest, digest_size); - else - rv = vb2_digest_finalize(dc, digest, digest_size); - if (rv) - return rv; - - /* The code below is specific to the body signature */ - if (sd->hash_tag != VB2_HASH_TAG_FW_BODY) - return VB2_ERROR_API_CHECK_HASH_TAG; - - /* - * The body signature is currently a *signature* of the body data, not - * just its hash. So we need to verify the signature. - */ - - /* Unpack the data key */ - if (!sd->data_key_size) - return VB2_ERROR_API_CHECK_HASH_DATA_KEY; - - rv = vb2_unpack_key_buffer(&key, - vb2_member_of(sd, sd->data_key_offset), - sd->data_key_size); - if (rv) - return rv; - - /* - * Check digest vs. signature. Note that this destroys the signature. - * That's ok, because we only check each signature once per boot. - */ - rv = vb2_verify_digest(&key, &pre->body_signature, digest, &wb); - if (rv) - vb2api_fail(ctx, VB2_RECOVERY_FW_BODY, rv); - - if (digest_out != NULL) { - if (digest_out_size < digest_size) - return VB2_ERROR_API_CHECK_DIGEST_SIZE; - memcpy(digest_out, digest, digest_size); - } - - return rv; -} - -int vb2api_check_hash(struct vb2_context *ctx) -{ - return vb2api_check_hash_get_digest(ctx, NULL, 0); -} diff --git a/tests/vb20_api_tests.c b/tests/vb20_api_tests.c deleted file mode 100644 index f75d2a17..00000000 --- a/tests/vb20_api_tests.c +++ /dev/null @@ -1,440 +0,0 @@ -/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Tests for misc library - */ - -#include <stdio.h> - -#include "2api.h" -#include "2misc.h" -#include "2nvstorage.h" -#include "2rsa.h" -#include "2secdata.h" -#include "2sysincludes.h" -#include "test_common.h" -#include "vb2_common.h" - -/* Common context for tests */ -static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE] - __attribute__ ((aligned (VB2_WORKBUF_ALIGN))); -static struct vb2_context ctx; -static struct vb2_shared_data *sd; - -const char mock_body[320] = "Mock body"; -const int mock_body_size = sizeof(mock_body); -const int mock_algorithm = VB2_ALG_RSA2048_SHA256; -const int mock_hash_alg = VB2_HASH_SHA256; -const int mock_sig_size = 64; -static uint8_t digest_result[VB2_SHA256_DIGEST_SIZE]; -static const uint32_t digest_result_size = sizeof(digest_result); - -/* Mocked function data */ - -static enum { - HWCRYPTO_DISABLED, - HWCRYPTO_ENABLED, - HWCRYPTO_FORBIDDEN, -} hwcrypto_state; - -static vb2_error_t retval_vb2_load_fw_keyblock; -static vb2_error_t retval_vb2_load_fw_preamble; -static vb2_error_t retval_vb2_digest_finalize; -static vb2_error_t retval_vb2_verify_digest; - -/* Type of test to reset for */ -enum reset_type { - FOR_MISC, - FOR_EXTEND_HASH, - FOR_CHECK_HASH, -}; - -static void reset_common_data(enum reset_type t) -{ - struct vb2_fw_preamble *pre; - struct vb2_packed_key *k; - - memset(workbuf, 0xaa, sizeof(workbuf)); - - memset(&ctx, 0, sizeof(ctx)); - ctx.workbuf = workbuf; - ctx.workbuf_size = sizeof(workbuf); - - vb2_init_context(&ctx); - sd = vb2_get_sd(&ctx); - - vb2_nv_init(&ctx); - - vb2api_secdata_firmware_create(&ctx); - vb2_secdata_firmware_init(&ctx); - - retval_vb2_load_fw_keyblock = VB2_SUCCESS; - retval_vb2_load_fw_preamble = VB2_SUCCESS; - retval_vb2_digest_finalize = VB2_SUCCESS; - retval_vb2_verify_digest = VB2_SUCCESS; - - sd->preamble_offset = ctx.workbuf_used; - sd->preamble_size = sizeof(*pre); - vb2_set_workbuf_used(&ctx, sd->preamble_offset - + sd->preamble_size); - pre = vb2_member_of(sd, sd->preamble_offset); - pre->body_signature.data_size = mock_body_size; - pre->body_signature.sig_size = mock_sig_size; - if (hwcrypto_state == HWCRYPTO_FORBIDDEN) - pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO; - else - pre->flags = 0; - - sd->data_key_offset = ctx.workbuf_used; - sd->data_key_size = sizeof(*k) + 8; - vb2_set_workbuf_used(&ctx, sd->data_key_offset + - sd->data_key_size); - k = vb2_member_of(sd, sd->data_key_offset); - k->algorithm = mock_algorithm; - - if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH) - vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, NULL); - - if (t == FOR_CHECK_HASH) - vb2api_extend_hash(&ctx, mock_body, mock_body_size); - - /* Always clear out the digest result. */ - memset(digest_result, 0, digest_result_size); -}; - -/* Mocked functions */ - -vb2_error_t vb2_load_fw_keyblock(struct vb2_context *c) -{ - return retval_vb2_load_fw_keyblock; -} - -vb2_error_t vb2_load_fw_preamble(struct vb2_context *c) -{ - return retval_vb2_load_fw_preamble; -} - -vb2_error_t vb2_unpack_key_buffer(struct vb2_public_key *key, - const uint8_t *buf, uint32_t size) -{ - struct vb2_packed_key *k = (struct vb2_packed_key *)buf; - - if (size != sizeof(*k) + 8) - return VB2_ERROR_UNPACK_KEY_SIZE; - - key->sig_alg = vb2_crypto_to_signature(k->algorithm); - key->hash_alg = vb2_crypto_to_hash(k->algorithm); - - 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) -{ - 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) - return VB2_ERROR_SHA_INIT_ALGORITHM; - - dc->hash_alg = hash_alg; - dc->using_hwcrypto = 0; - - return VB2_SUCCESS; -} - -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; - - return VB2_SUCCESS; -} - -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); - - return retval_vb2_digest_finalize; -} - -uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg) -{ - return mock_sig_size; -} - -vb2_error_t vb2_rsa_verify_digest(const struct vb2_public_key *key, - uint8_t *sig, const uint8_t *digest, - const struct vb2_workbuf *wb) -{ - return retval_vb2_verify_digest; -} - -/* Tests */ - -static void phase3_tests(void) -{ - reset_common_data(FOR_MISC); - TEST_SUCC(vb2api_fw_phase3(&ctx), "phase3 good"); - - reset_common_data(FOR_MISC); - retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK; - TEST_EQ(vb2api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock"); - TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST), - VB2_RECOVERY_RO_INVALID_RW, " recovery reason"); - - reset_common_data(FOR_MISC); - retval_vb2_load_fw_preamble = VB2_ERROR_MOCK; - TEST_EQ(vb2api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock"); - TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST), - VB2_RECOVERY_RO_INVALID_RW, " recovery reason"); -} - -static void init_hash_tests(void) -{ - struct vb2_packed_key *k; - int wb_used_before; - uint32_t size; - - /* For now, all we support is body signature hash */ - reset_common_data(FOR_MISC); - wb_used_before = ctx.workbuf_used; - TEST_SUCC(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), - "init hash good"); - TEST_EQ(sd->hash_offset, wb_used_before, - "hash context offset"); - TEST_EQ(sd->hash_size, sizeof(struct vb2_digest_context), - "hash context size"); - TEST_EQ(ctx.workbuf_used, - vb2_wb_round_up(sd->hash_offset + - sd->hash_size), - "hash uses workbuf"); - TEST_EQ(sd->hash_tag, VB2_HASH_TAG_FW_BODY, "hash tag"); - TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining"); - - wb_used_before = ctx.workbuf_used; - TEST_SUCC(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, NULL), - "init hash again"); - TEST_EQ(ctx.workbuf_used, wb_used_before, "init hash reuses context"); - - reset_common_data(FOR_MISC); - TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_INVALID, &size), - VB2_ERROR_API_INIT_HASH_TAG, "init hash invalid tag"); - - reset_common_data(FOR_MISC); - sd->preamble_size = 0; - TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), - VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble"); - - reset_common_data(FOR_MISC); - TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY + 1, &size), - VB2_ERROR_API_INIT_HASH_TAG, "init hash unknown tag"); - - reset_common_data(FOR_MISC); - ctx.workbuf_used = ctx.workbuf_size + VB2_WORKBUF_ALIGN - - vb2_wb_round_up(sizeof(struct vb2_digest_context)); - TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), - VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf"); - - reset_common_data(FOR_MISC); - sd->data_key_size = 0; - TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), - VB2_ERROR_API_INIT_HASH_DATA_KEY, "init hash data key"); - - reset_common_data(FOR_MISC); - sd->data_key_size--; - TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), - VB2_ERROR_UNPACK_KEY_SIZE, "init hash data key size"); - - reset_common_data(FOR_MISC); - k = vb2_member_of(sd, sd->data_key_offset); - k->algorithm--; - TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), - VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm"); -} - -static void extend_hash_tests(void) -{ - struct vb2_digest_context *dc; - - reset_common_data(FOR_EXTEND_HASH); - TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, 32), - "hash extend good"); - TEST_EQ(sd->hash_remaining_size, mock_body_size - 32, - "hash extend remaining"); - TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, mock_body_size - 32), - "hash extend again"); - TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2"); - - reset_common_data(FOR_EXTEND_HASH); - sd->hash_size = 0; - TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size), - VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf"); - - reset_common_data(FOR_EXTEND_HASH); - TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size + 1), - VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much"); - - reset_common_data(FOR_EXTEND_HASH); - 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"); - } -} - -static void check_hash_tests(void) -{ - struct vb2_fw_preamble *pre; - const uint32_t digest_value = 0x0a0a0a0a; - - reset_common_data(FOR_CHECK_HASH); - TEST_SUCC(vb2api_check_hash(&ctx), "check hash good"); - - reset_common_data(FOR_CHECK_HASH); - TEST_SUCC(vb2api_check_hash_get_digest(&ctx, digest_result, - digest_result_size), "check hash good with result"); - /* Check the first 4 bytes to ensure it was copied over. */ - TEST_SUCC(memcmp(digest_result, &digest_value, sizeof(digest_value)), - "check digest value"); - - reset_common_data(FOR_CHECK_HASH); - TEST_EQ(vb2api_check_hash_get_digest(&ctx, digest_result, - digest_result_size - 1), - VB2_ERROR_API_CHECK_DIGEST_SIZE, "check digest size"); - TEST_NEQ(memcmp(digest_result, &digest_value, sizeof(digest_value)), 0, - "check digest wrong size"); - - reset_common_data(FOR_CHECK_HASH); - sd->preamble_size = 0; - TEST_EQ(vb2api_check_hash(&ctx), - VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble"); - - reset_common_data(FOR_CHECK_HASH); - sd->hash_size = 0; - TEST_EQ(vb2api_check_hash(&ctx), - VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf"); - - reset_common_data(FOR_CHECK_HASH); - sd->hash_remaining_size = 1; - TEST_EQ(vb2api_check_hash(&ctx), - VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size"); - - reset_common_data(FOR_CHECK_HASH); - ctx.workbuf_used = ctx.workbuf_size; - TEST_EQ(vb2api_check_hash(&ctx), - VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf"); - - reset_common_data(FOR_CHECK_HASH); - retval_vb2_digest_finalize = VB2_ERROR_MOCK; - TEST_EQ(vb2api_check_hash(&ctx), VB2_ERROR_MOCK, "check hash finalize"); - - reset_common_data(FOR_CHECK_HASH); - sd->hash_tag = VB2_HASH_TAG_INVALID; - TEST_EQ(vb2api_check_hash(&ctx), - VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag"); - - reset_common_data(FOR_CHECK_HASH); - sd->data_key_size = 0; - TEST_EQ(vb2api_check_hash(&ctx), - VB2_ERROR_API_CHECK_HASH_DATA_KEY, "check hash data key"); - - reset_common_data(FOR_CHECK_HASH); - sd->data_key_size--; - TEST_EQ(vb2api_check_hash(&ctx), - VB2_ERROR_UNPACK_KEY_SIZE, "check hash data key size"); - - reset_common_data(FOR_CHECK_HASH); - pre = vb2_member_of(sd, sd->preamble_offset); - pre->body_signature.sig_size++; - TEST_EQ(vb2api_check_hash(&ctx), - VB2_ERROR_VDATA_SIG_SIZE, "check hash sig size"); - - reset_common_data(FOR_CHECK_HASH); - retval_vb2_digest_finalize = VB2_ERROR_RSA_VERIFY_DIGEST; - TEST_EQ(vb2api_check_hash(&ctx), - VB2_ERROR_RSA_VERIFY_DIGEST, "check hash finalize"); -} - -int main(int argc, char* argv[]) -{ - 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(); - - return gTestSuccess ? 0 : 255; -} diff --git a/tests/vb2_api_tests.c b/tests/vb2_api_tests.c index 4ce5798e..e5883002 100644 --- a/tests/vb2_api_tests.c +++ b/tests/vb2_api_tests.c @@ -2,7 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * - * Tests for misc library + * Tests for api.c */ #include <stdio.h> @@ -15,8 +15,11 @@ #include "2secdata.h" #include "2sysincludes.h" #include "test_common.h" +#include "vb2_struct.h" +#include "vb2_common.h" /* Common context for tests */ + static uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE] __attribute__ ((aligned (VB2_WORKBUF_ALIGN))); static struct vb2_context ctx; @@ -33,21 +36,41 @@ static const uint8_t mock_hwid_digest[VB2_GBB_HWID_DIGEST_SIZE] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, }; +const int mock_sig_size = 64; +static uint8_t digest_result[VB2_SHA256_DIGEST_SIZE]; +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; static vb2_error_t retval_vb2_check_tpm_clear; static vb2_error_t retval_vb2_select_fw_slot; +static vb2_error_t retval_vb2_load_fw_keyblock; +static vb2_error_t retval_vb2_load_fw_preamble; +static vb2_error_t retval_vb2_digest_finalize; +static vb2_error_t retval_vb2_verify_digest; /* Type of test to reset for */ + enum reset_type { FOR_MISC, + FOR_EXTEND_HASH, + FOR_CHECK_HASH, }; static void reset_common_data(enum reset_type t) { + struct vb2_fw_preamble *pre; + struct vb2_packed_key *k; + memset(workbuf, 0xaa, sizeof(workbuf)); memset(&ctx, 0, sizeof(ctx)); @@ -67,9 +90,41 @@ static void reset_common_data(enum reset_type t) retval_vb2_check_dev_switch = VB2_SUCCESS; retval_vb2_check_tpm_clear = VB2_SUCCESS; retval_vb2_select_fw_slot = VB2_SUCCESS; + retval_vb2_load_fw_keyblock = VB2_SUCCESS; + retval_vb2_load_fw_preamble = VB2_SUCCESS; + retval_vb2_digest_finalize = VB2_SUCCESS; + retval_vb2_verify_digest = VB2_SUCCESS; memcpy(&gbb.hwid_digest, mock_hwid_digest, sizeof(gbb.hwid_digest)); + + sd->preamble_offset = ctx.workbuf_used; + sd->preamble_size = sizeof(*pre); + vb2_set_workbuf_used(&ctx, sd->preamble_offset + + sd->preamble_size); + pre = vb2_member_of(sd, sd->preamble_offset); + pre->body_signature.data_size = mock_body_size; + pre->body_signature.sig_size = mock_sig_size; + if (hwcrypto_state == HWCRYPTO_FORBIDDEN) + pre->flags = VB2_FIRMWARE_PREAMBLE_DISALLOW_HWCRYPTO; + else + pre->flags = 0; + + sd->data_key_offset = ctx.workbuf_used; + sd->data_key_size = sizeof(*k) + 8; + vb2_set_workbuf_used(&ctx, sd->data_key_offset + + sd->data_key_size); + k = vb2_member_of(sd, sd->data_key_offset); + k->algorithm = mock_algorithm; + + if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH) + vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, NULL); + + if (t == FOR_CHECK_HASH) + vb2api_extend_hash(&ctx, mock_body, mock_body_size); + + /* Always clear out the digest result. */ + memset(digest_result, 0, digest_result_size); }; /* Mocked functions */ @@ -100,6 +155,123 @@ vb2_error_t vb2_select_fw_slot(struct vb2_context *c) return retval_vb2_select_fw_slot; } +vb2_error_t vb2_load_fw_keyblock(struct vb2_context *c) +{ + return retval_vb2_load_fw_keyblock; +} + +vb2_error_t vb2_load_fw_preamble(struct vb2_context *c) +{ + return retval_vb2_load_fw_preamble; +} + +vb2_error_t vb2_unpack_key_buffer(struct vb2_public_key *key, + const uint8_t *buf, uint32_t size) +{ + struct vb2_packed_key *k = (struct vb2_packed_key *)buf; + + if (size != sizeof(*k) + 8) + return VB2_ERROR_UNPACK_KEY_SIZE; + + key->sig_alg = vb2_crypto_to_signature(k->algorithm); + key->hash_alg = vb2_crypto_to_hash(k->algorithm); + + 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) +{ + 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) + return VB2_ERROR_SHA_INIT_ALGORITHM; + + dc->hash_alg = hash_alg; + dc->using_hwcrypto = 0; + + return VB2_SUCCESS; +} + +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; + + return VB2_SUCCESS; +} + +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); + + return retval_vb2_digest_finalize; +} + +uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg) +{ + return mock_sig_size; +} + +vb2_error_t vb2_rsa_verify_digest(const struct vb2_public_key *key, + uint8_t *sig, const uint8_t *digest, + const struct vb2_workbuf *wb) +{ + return retval_vb2_verify_digest; +} + /* Tests */ static void misc_tests(void) @@ -362,11 +534,220 @@ static void get_pcr_digest_tests(void) "invalid enum vb2_pcr_digest"); } +static void phase3_tests(void) +{ + reset_common_data(FOR_MISC); + TEST_SUCC(vb2api_fw_phase3(&ctx), "phase3 good"); + + reset_common_data(FOR_MISC); + retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK; + TEST_EQ(vb2api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock"); + TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST), + VB2_RECOVERY_RO_INVALID_RW, " recovery reason"); + + reset_common_data(FOR_MISC); + retval_vb2_load_fw_preamble = VB2_ERROR_MOCK; + TEST_EQ(vb2api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock"); + TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST), + VB2_RECOVERY_RO_INVALID_RW, " recovery reason"); +} + +static void init_hash_tests(void) +{ + struct vb2_packed_key *k; + int wb_used_before; + uint32_t size; + + /* For now, all we support is body signature hash */ + reset_common_data(FOR_MISC); + wb_used_before = ctx.workbuf_used; + TEST_SUCC(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), + "init hash good"); + TEST_EQ(sd->hash_offset, wb_used_before, + "hash context offset"); + TEST_EQ(sd->hash_size, sizeof(struct vb2_digest_context), + "hash context size"); + TEST_EQ(ctx.workbuf_used, + vb2_wb_round_up(sd->hash_offset + + sd->hash_size), + "hash uses workbuf"); + TEST_EQ(sd->hash_tag, VB2_HASH_TAG_FW_BODY, "hash tag"); + TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining"); + + wb_used_before = ctx.workbuf_used; + TEST_SUCC(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, NULL), + "init hash again"); + TEST_EQ(ctx.workbuf_used, wb_used_before, "init hash reuses context"); + + reset_common_data(FOR_MISC); + TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_INVALID, &size), + VB2_ERROR_API_INIT_HASH_TAG, "init hash invalid tag"); + + reset_common_data(FOR_MISC); + sd->preamble_size = 0; + TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), + VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble"); + + reset_common_data(FOR_MISC); + TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY + 1, &size), + VB2_ERROR_API_INIT_HASH_TAG, "init hash unknown tag"); + + reset_common_data(FOR_MISC); + ctx.workbuf_used = ctx.workbuf_size + VB2_WORKBUF_ALIGN - + vb2_wb_round_up(sizeof(struct vb2_digest_context)); + TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), + VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf"); + + reset_common_data(FOR_MISC); + sd->data_key_size = 0; + TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), + VB2_ERROR_API_INIT_HASH_DATA_KEY, "init hash data key"); + + reset_common_data(FOR_MISC); + sd->data_key_size--; + TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), + VB2_ERROR_UNPACK_KEY_SIZE, "init hash data key size"); + + reset_common_data(FOR_MISC); + k = vb2_member_of(sd, sd->data_key_offset); + k->algorithm--; + TEST_EQ(vb2api_init_hash(&ctx, VB2_HASH_TAG_FW_BODY, &size), + VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm"); +} + +static void extend_hash_tests(void) +{ + struct vb2_digest_context *dc; + + reset_common_data(FOR_EXTEND_HASH); + TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, 32), + "hash extend good"); + TEST_EQ(sd->hash_remaining_size, mock_body_size - 32, + "hash extend remaining"); + TEST_SUCC(vb2api_extend_hash(&ctx, mock_body, mock_body_size - 32), + "hash extend again"); + TEST_EQ(sd->hash_remaining_size, 0, "hash extend remaining 2"); + + reset_common_data(FOR_EXTEND_HASH); + sd->hash_size = 0; + TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size), + VB2_ERROR_API_EXTEND_HASH_WORKBUF, "hash extend no workbuf"); + + reset_common_data(FOR_EXTEND_HASH); + TEST_EQ(vb2api_extend_hash(&ctx, mock_body, mock_body_size + 1), + VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend too much"); + + reset_common_data(FOR_EXTEND_HASH); + 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"); + } +} + +static void check_hash_tests(void) +{ + struct vb2_fw_preamble *pre; + const uint32_t digest_value = 0x0a0a0a0a; + + reset_common_data(FOR_CHECK_HASH); + TEST_SUCC(vb2api_check_hash(&ctx), "check hash good"); + + reset_common_data(FOR_CHECK_HASH); + TEST_SUCC(vb2api_check_hash_get_digest(&ctx, digest_result, + digest_result_size), "check hash good with result"); + /* Check the first 4 bytes to ensure it was copied over. */ + TEST_SUCC(memcmp(digest_result, &digest_value, sizeof(digest_value)), + "check digest value"); + + reset_common_data(FOR_CHECK_HASH); + TEST_EQ(vb2api_check_hash_get_digest(&ctx, digest_result, + digest_result_size - 1), + VB2_ERROR_API_CHECK_DIGEST_SIZE, "check digest size"); + TEST_NEQ(memcmp(digest_result, &digest_value, sizeof(digest_value)), 0, + "check digest wrong size"); + + reset_common_data(FOR_CHECK_HASH); + sd->preamble_size = 0; + TEST_EQ(vb2api_check_hash(&ctx), + VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble"); + + reset_common_data(FOR_CHECK_HASH); + sd->hash_size = 0; + TEST_EQ(vb2api_check_hash(&ctx), + VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf"); + + reset_common_data(FOR_CHECK_HASH); + sd->hash_remaining_size = 1; + TEST_EQ(vb2api_check_hash(&ctx), + VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size"); + + reset_common_data(FOR_CHECK_HASH); + ctx.workbuf_used = ctx.workbuf_size; + TEST_EQ(vb2api_check_hash(&ctx), + VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf"); + + reset_common_data(FOR_CHECK_HASH); + retval_vb2_digest_finalize = VB2_ERROR_MOCK; + TEST_EQ(vb2api_check_hash(&ctx), VB2_ERROR_MOCK, "check hash finalize"); + + reset_common_data(FOR_CHECK_HASH); + sd->hash_tag = VB2_HASH_TAG_INVALID; + TEST_EQ(vb2api_check_hash(&ctx), + VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag"); + + reset_common_data(FOR_CHECK_HASH); + sd->data_key_size = 0; + TEST_EQ(vb2api_check_hash(&ctx), + VB2_ERROR_API_CHECK_HASH_DATA_KEY, "check hash data key"); + + reset_common_data(FOR_CHECK_HASH); + sd->data_key_size--; + TEST_EQ(vb2api_check_hash(&ctx), + VB2_ERROR_UNPACK_KEY_SIZE, "check hash data key size"); + + reset_common_data(FOR_CHECK_HASH); + pre = vb2_member_of(sd, sd->preamble_offset); + pre->body_signature.sig_size++; + TEST_EQ(vb2api_check_hash(&ctx), + VB2_ERROR_VDATA_SIG_SIZE, "check hash sig size"); + + reset_common_data(FOR_CHECK_HASH); + retval_vb2_digest_finalize = VB2_ERROR_RSA_VERIFY_DIGEST; + TEST_EQ(vb2api_check_hash(&ctx), + VB2_ERROR_RSA_VERIFY_DIGEST, "check hash finalize"); +} + int main(int argc, char* argv[]) { misc_tests(); phase1_tests(); 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(); get_pcr_digest_tests(); |