summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2014-12-03 12:29:37 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-12-04 09:46:43 +0000
commit6f1b82ac14f341d9733d6e95d518b3ee352002ef (patch)
tree0d37f86365c8324416e42f1ce5cd3969de54a178
parentfe2714923b986bc461b692d45c1b5eb1b469ddc4 (diff)
downloadvboot-6f1b82ac14f341d9733d6e95d518b3ee352002ef.tar.gz
vboot2: Move old struct handling to lib20/
This is part 4 of a series of changes to rearrange the vboot2 library so that it's possible to start using the new-style data structs. This change moves knowledge of the old vboot1 data structs into lib20; 2lib now contains only code which is common to both vboot2.x libraries (that is, code which is data structure version agnostic). No functional changes; just rearranging code and tests. BUG=chromium:423882 BRANCH=none TEST=make runtests && VBOOT2=1 make runtests (works with/withoug VBOOT2 flag) And compile firmware for veyron_pinky CQ-DEPEND=CL:233051 Change-Id: I8f9e67157575e5be14952ef4809c3dfafd92596d Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/233021 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--Makefile70
-rw-r--r--firmware/2lib/2api.c158
-rw-r--r--firmware/2lib/2common.c260
-rw-r--r--firmware/2lib/2misc.c211
-rw-r--r--firmware/2lib/include/2common.h230
-rw-r--r--firmware/2lib/include/2misc.h1
-rw-r--r--firmware/2lib/include/2struct.h172
-rw-r--r--firmware/include/vb2_api.h1
-rw-r--r--firmware/lib20/api.c174
-rw-r--r--firmware/lib20/common.c272
-rw-r--r--firmware/lib20/include/vb2_common.h159
-rw-r--r--firmware/lib20/include/vb2_struct.h179
-rw-r--r--firmware/lib20/misc.c226
-rw-r--r--firmware/lib20/packed_key.c (renamed from firmware/2lib/2packed_key.c)2
-rw-r--r--firmware/lib21/include/vb2_common.h90
-rw-r--r--tests/vb20_api_tests.c346
-rw-r--r--tests/vb20_common2_tests.c (renamed from tests/vb2_common2_tests.c)2
-rw-r--r--tests/vb20_common3_tests.c (renamed from tests/vb2_common3_tests.c)2
-rw-r--r--tests/vb20_common_tests.c174
-rw-r--r--tests/vb20_misc_tests.c (renamed from tests/vb2_misc2_tests.c)2
-rw-r--r--tests/vb20_rsa_padding_tests.c (renamed from tests/vb2_rsa_padding_tests.c)2
-rw-r--r--tests/vb21_api_tests.c36
-rw-r--r--tests/vb21_misc_tests.c4
-rw-r--r--tests/vb2_api_tests.c283
-rw-r--r--tests/vb2_common_tests.c160
-rwxr-xr-xtests/vb2_rsa_tests.sh2
26 files changed, 1716 insertions, 1502 deletions
diff --git a/Makefile b/Makefile
index b56818ab..61c639f5 100644
--- a/Makefile
+++ b/Makefile
@@ -235,8 +235,12 @@ endif
# this source tree locally and link to it directly.
FWLIB = ${BUILD}/vboot_fw.a
-# Smaller firmware library. TODO: Do we still need to export this?
+# Smaller firmware library
+# Stuff common to all vboot 2.x
+FWLIB2X = ${BUILD}/vboot_fw2x.a
+# Vboot 2.0 (stuck with this filename due to dependencies in coreboot)
FWLIB20 = ${BUILD}/vboot_fw2.a
+# Vboot 2.1
FWLIB21 = ${BUILD}/vboot_fw21.a
# Firmware library sources needed by VbInit() call
@@ -278,6 +282,7 @@ VBSLK_SRCS = \
firmware/lib/region-kernel.c \
# Firmware library source needed for smaller library 2
+# Code common to vboot 2.0 (old structs) and 2.1 (new structs)
FWLIB2_SRCS = \
firmware/2lib/2api.c \
firmware/2lib/2common.c \
@@ -292,7 +297,10 @@ FWLIB2_SRCS = \
firmware/2lib/2sha_utility.c
FWLIB20_SRCS = \
- firmware/2lib/2packed_key.c
+ firmware/lib20/api.c \
+ firmware/lib20/common.c \
+ firmware/lib20/misc.c \
+ firmware/lib20/packed_key.c
FWLIB21_SRCS = \
firmware/lib21/api.c \
@@ -631,19 +639,23 @@ ifdef REGION_READ
TEST_NAMES += tests/vboot_region_tests
endif
-TEST20_NAMES = \
+TEST2X_NAMES = \
tests/vb2_api_tests \
tests/vb2_common_tests \
- tests/vb2_common2_tests \
- tests/vb2_common3_tests \
tests/vb2_misc_tests \
- tests/vb2_misc2_tests \
tests/vb2_nvstorage_tests \
- tests/vb2_rsa_padding_tests \
tests/vb2_rsa_utility_tests \
tests/vb2_secdata_tests \
tests/vb2_sha_tests
+TEST20_NAMES = \
+ tests/vb20_api_tests \
+ tests/vb20_common_tests \
+ tests/vb20_common2_tests \
+ tests/vb20_common3_tests \
+ tests/vb20_misc_tests \
+ tests/vb20_rsa_padding_tests
+
TEST21_NAMES = \
tests/vb21_api_tests \
tests/vb21_common_tests \
@@ -656,7 +668,7 @@ TEST21_NAMES = \
tests/vb21_host_sig_tests
ifneq (${VBOOT2},)
-TEST_NAMES += ${TEST20_NAMES} ${TEST21_NAMES}
+TEST_NAMES += ${TEST2X_NAMES} ${TEST20_NAMES} ${TEST21_NAMES}
endif
# And a few more...
@@ -679,6 +691,7 @@ TEST_NAMES += ${TLCL_TEST_NAMES}
TEST_BINS = $(addprefix ${BUILD}/,${TEST_NAMES})
TEST_OBJS += $(addsuffix .o,${TEST_BINS})
+TEST2X_BINS = $(addprefix ${BUILD}/,${TEST2X_NAMES})
TEST20_BINS = $(addprefix ${BUILD}/,${TEST20_NAMES})
TEST21_BINS = $(addprefix ${BUILD}/,${TEST21_NAMES})
@@ -700,7 +713,7 @@ _dir_create := $(foreach d, \
# Default target.
.PHONY: all
all: fwlib \
- $(if ${VBOOT2},fwlib2 fwlib21) \
+ $(if ${VBOOT2},fwlib2x fwlib2 fwlib21) \
$(if ${FIRMWARE_ARCH},,host_stuff) \
$(if ${COV},coverage)
@@ -772,6 +785,7 @@ ifeq (${FIRMWARE_ARCH},)
${FWLIB_OBJS}: CFLAGS += -DDISABLE_ROLLBACK_TPM
endif
+${FWLIB20_OBJS}: INCLUDES += -Ifirmware/lib20/include
${FWLIB21_OBJS}: INCLUDES += -Ifirmware/lib21/include
# Linktest ensures firmware lib doesn't rely on outside libraries
@@ -800,6 +814,16 @@ ${FWLIB}: ${FWLIB_OBJS}
@$(PRINTF) " AR $(subst ${BUILD}/,,$@)\n"
${Q}ar qc $@ $^
+.PHONY: fwlib2x
+fwlib2x: ${FWLIB2X}
+
+${FWLIB2X}: ${FWLIB2_OBJS}
+ @$(PRINTF) " RM $(subst ${BUILD}/,,$@)\n"
+ ${Q}rm -f $@
+ @$(PRINTF) " AR $(subst ${BUILD}/,,$@)\n"
+ ${Q}ar qc $@ $^
+
+# TODO: it'd be nice to call this fwlib20, but coreboot expects fwlib2
.PHONY: fwlib2
fwlib2: ${FWLIB20}
@@ -841,9 +865,7 @@ ${UTILLIB}: ${UTILLIB_OBJS} ${FWLIB_OBJS}
utillib21: ${UTILLIB21}
${UTILLIB21}: INCLUDES += -Ihost/lib21/include -Ifirmware/lib21/include
-
-# TODO: right now, firmware lib 2.1 isn't a complete standalone copy
-${UTILLIB21}: ${UTILLIB21_OBJS} ${FWLIB2_OBJS} ${FWLIB20_OBJS} ${FWLIB21_OBJS}
+${UTILLIB21}: ${UTILLIB21_OBJS} ${FWLIB2_OBJS} ${FWLIB21_OBJS}
@$(PRINTF) " RM $(subst ${BUILD}/,,$@)\n"
${Q}rm -f $@
@$(PRINTF) " AR $(subst ${BUILD}/,,$@)\n"
@@ -938,12 +960,12 @@ signing_install: ${SIGNING_SCRIPTS} ${SIGNING_SCRIPTS_DEV} ${SIGNING_COMMON}
futil: ${FUTIL_STATIC_BIN} ${FUTIL_BIN}
${FUTIL_STATIC_BIN}: ${FUTIL_STATIC_OBJS} ${UTILLIB} \
- $(if ${VBOOT2},${UTILLIB21})
+ $(if ${VBOOT2},${FWLIB20})
@$(PRINTF) " LD $(subst ${BUILD}/,,$@)\n"
${Q}${LD} -o $@ ${CFLAGS} ${LDFLAGS} -static $^ ${LDLIBS}
${FUTIL_BIN}: LDLIBS += ${CRYPTO_LIBS}
-${FUTIL_BIN}: ${FUTIL_OBJS} ${UTILLIB} $(if ${VBOOT2},${UTILLIB21})
+${FUTIL_BIN}: ${FUTIL_OBJS} ${UTILLIB} $(if ${VBOOT2},${FWLIB20})
@$(PRINTF) " LD $(subst ${BUILD}/,,$@)\n"
${Q}${LD} -o $@ ${CFLAGS} ${LDFLAGS} $^ ${LDLIBS}
@@ -981,7 +1003,11 @@ ${TEST_BINS}: ${UTILLIB} ${TESTLIB}
${TEST_BINS}: INCLUDES += -Itests
${TEST_BINS}: LIBS = ${TESTLIB} ${UTILLIB}
+${TEST2X_BINS}: ${FWLIB2X}
+${TEST2X_BINS}: LIBS += ${FWLIB2X}
+
${TEST20_BINS}: ${FWLIB20}
+${TEST20_BINS}: INCLUDES += -Ifirmware/lib20/include
${TEST20_BINS}: LIBS += ${FWLIB20}
${TEST21_BINS}: ${UTILLIB21}
@@ -1041,8 +1067,8 @@ ${BUILD}/utility/signature_digest_utility: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/host/linktest/main: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/vboot_common2_tests: LDLIBS += ${CRYPTO_LIBS}
${BUILD}/tests/vboot_common3_tests: LDLIBS += ${CRYPTO_LIBS}
-${BUILD}/tests/vb2_common2_tests: LDLIBS += ${CRYPTO_LIBS}
-${BUILD}/tests/vb2_common3_tests: LDLIBS += ${CRYPTO_LIBS}
+${BUILD}/tests/vb20_common2_tests: LDLIBS += ${CRYPTO_LIBS}
+${BUILD}/tests/vb20_common3_tests: LDLIBS += ${CRYPTO_LIBS}
${TEST21_BINS}: LDLIBS += ${CRYPTO_LIBS}
@@ -1219,14 +1245,16 @@ runmisctests: test_setup
run2tests: test_setup
${RUNTEST} ${BUILD_RUN}/tests/vb2_api_tests
${RUNTEST} ${BUILD_RUN}/tests/vb2_common_tests
- ${RUNTEST} ${BUILD_RUN}/tests/vb2_common2_tests ${TEST_KEYS}
- ${RUNTEST} ${BUILD_RUN}/tests/vb2_common3_tests ${TEST_KEYS}
${RUNTEST} ${BUILD_RUN}/tests/vb2_misc_tests
- ${RUNTEST} ${BUILD_RUN}/tests/vb2_misc2_tests
${RUNTEST} ${BUILD_RUN}/tests/vb2_nvstorage_tests
${RUNTEST} ${BUILD_RUN}/tests/vb2_rsa_utility_tests
${RUNTEST} ${BUILD_RUN}/tests/vb2_secdata_tests
${RUNTEST} ${BUILD_RUN}/tests/vb2_sha_tests
+ ${RUNTEST} ${BUILD_RUN}/tests/vb20_api_tests
+ ${RUNTEST} ${BUILD_RUN}/tests/vb20_common_tests
+ ${RUNTEST} ${BUILD_RUN}/tests/vb20_common2_tests ${TEST_KEYS}
+ ${RUNTEST} ${BUILD_RUN}/tests/vb20_common3_tests ${TEST_KEYS}
+ ${RUNTEST} ${BUILD_RUN}/tests/vb20_misc_tests
${RUNTEST} ${BUILD_RUN}/tests/vb21_api_tests
${RUNTEST} ${BUILD_RUN}/tests/vb21_common_tests
${RUNTEST} ${BUILD_RUN}/tests/vb21_common2_tests ${TEST_KEYS}
@@ -1250,8 +1278,8 @@ runlongtests: test_setup genkeys genfuzztestcases
${RUNTEST} ${BUILD_RUN}/tests/vboot_common2_tests ${TEST_KEYS} --all
${RUNTEST} ${BUILD_RUN}/tests/vboot_common3_tests ${TEST_KEYS} --all
ifneq (${VBOOT2},)
- ${RUNTEST} ${BUILD_RUN}/tests/vb2_common2_tests ${TEST_KEYS} --all
- ${RUNTEST} ${BUILD_RUN}/tests/vb2_common3_tests ${TEST_KEYS} --all
+ ${RUNTEST} ${BUILD_RUN}/tests/vb20_common2_tests ${TEST_KEYS} --all
+ ${RUNTEST} ${BUILD_RUN}/tests/vb20_common3_tests ${TEST_KEYS} --all
${RUNTEST} ${BUILD_RUN}/tests/vb21_common2_tests ${TEST_KEYS} --all
endif
tests/run_preamble_tests.sh --all
diff --git a/firmware/2lib/2api.c b/firmware/2lib/2api.c
index a01c7f57..5d2775f0 100644
--- a/firmware/2lib/2api.c
+++ b/firmware/2lib/2api.c
@@ -100,94 +100,6 @@ int vb2api_fw_phase2(struct vb2_context *ctx)
return VB2_SUCCESS;
}
-int vb2api_fw_phase3(struct vb2_context *ctx)
-{
- int rv;
-
- /* Verify firmware keyblock */
- rv = vb2_load_fw_keyblock(ctx);
- if (rv) {
- vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
- return rv;
- }
-
- /* Verify firmware preamble */
- rv = vb2_load_fw_preamble(ctx);
- if (rv) {
- vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
- return rv;
- }
-
- return VB2_SUCCESS;
-}
-
-int 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;
- int 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->workbuf_preamble_size)
- return VB2_ERROR_API_INIT_HASH_PREAMBLE;
- pre = (const struct vb2_fw_preamble *)
- (ctx->workbuf + sd->workbuf_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->workbuf_hash_size) {
- dc = (struct vb2_digest_context *)
- (ctx->workbuf + sd->workbuf_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->workbuf_hash_offset = vb2_offset_of(ctx->workbuf, dc);
- sd->workbuf_hash_size = dig_size;
- ctx->workbuf_used = sd->workbuf_hash_offset + dig_size;
- }
-
- /*
- * 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->workbuf_data_key_size)
- return VB2_ERROR_API_INIT_HASH_DATA_KEY;
-
- rv = vb2_unpack_key(&key,
- ctx->workbuf + sd->workbuf_data_key_offset,
- sd->workbuf_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;
-
- return vb2_digest_init(dc, key.hash_alg);
-}
-
int vb2api_extend_hash(struct vb2_context *ctx,
const void *buf,
uint32_t size)
@@ -208,73 +120,3 @@ int vb2api_extend_hash(struct vb2_context *ctx,
return vb2_digest_extend(dc, buf, size);
}
-
-int vb2api_check_hash(struct vb2_context *ctx)
-{
- struct vb2_shared_data *sd = vb2_get_sd(ctx);
- struct vb2_digest_context *dc = (struct vb2_digest_context *)
- (ctx->workbuf + sd->workbuf_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;
- int rv;
-
- vb2_workbuf_from_ctx(ctx, &wb);
-
- /* Get preamble pointer */
- if (!sd->workbuf_preamble_size)
- return VB2_ERROR_API_CHECK_HASH_PREAMBLE;
- pre = (struct vb2_fw_preamble *)
- (ctx->workbuf + sd->workbuf_preamble_offset);
-
- /* Must have initialized hash digest work area */
- if (!sd->workbuf_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 */
- 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->workbuf_data_key_size)
- return VB2_ERROR_API_CHECK_HASH_DATA_KEY;
-
- rv = vb2_unpack_key(&key,
- ctx->workbuf + sd->workbuf_data_key_offset,
- sd->workbuf_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)
- vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
-
- return rv;
-}
diff --git a/firmware/2lib/2common.c b/firmware/2lib/2common.c
index e15ddb77..9e75d0c3 100644
--- a/firmware/2lib/2common.c
+++ b/firmware/2lib/2common.c
@@ -110,267 +110,7 @@ void vb2_workbuf_free(struct vb2_workbuf *wb, uint32_t size)
wb->size += size;
}
-uint8_t *vb2_signature_data(struct vb2_signature *sig)
-{
- return (uint8_t *)sig + sig->sig_offset;
-}
-
ptrdiff_t vb2_offset_of(const void *base, const void *ptr)
{
return (uintptr_t)ptr - (uintptr_t)base;
}
-
-int vb2_verify_member_inside(const void *parent, size_t parent_size,
- const void *member, size_t member_size,
- ptrdiff_t member_data_offset,
- size_t member_data_size)
-{
- const uintptr_t parent_end = (uintptr_t)parent + parent_size;
- const ptrdiff_t member_offs = vb2_offset_of(parent, member);
- const ptrdiff_t member_end_offs = member_offs + member_size;
- const ptrdiff_t data_offs = member_offs + member_data_offset;
- const ptrdiff_t data_end_offs = data_offs + member_data_size;
-
- /* Make sure parent doesn't wrap */
- if (parent_size < 0 || parent_end < (uintptr_t)parent)
- return VB2_ERROR_INSIDE_PARENT_WRAPS;
-
- /*
- * Make sure the member is fully contained in the parent and doesn't
- * wrap. Use >, not >=, since member_size = 0 is possible.
- */
- if (member_size < 0 || member_end_offs < member_offs)
- return VB2_ERROR_INSIDE_MEMBER_WRAPS;
- if (member_offs < 0 || member_offs > parent_size ||
- member_end_offs > parent_size)
- return VB2_ERROR_INSIDE_MEMBER_OUTSIDE;
-
- /* Make sure the member data is after the member */
- if (member_data_size > 0 && data_offs < member_end_offs)
- return VB2_ERROR_INSIDE_DATA_OVERLAP;
-
- /* Make sure parent fully contains member data, if any */
- if (member_data_size < 0 || data_end_offs < data_offs)
- return VB2_ERROR_INSIDE_DATA_WRAPS;
- if (data_offs < 0 || data_offs > parent_size ||
- data_end_offs > parent_size)
- return VB2_ERROR_INSIDE_DATA_OUTSIDE;
-
- return VB2_SUCCESS;
-}
-
-int vb2_verify_signature_inside(const void *parent,
- uint32_t parent_size,
- const struct vb2_signature *sig)
-{
- return vb2_verify_member_inside(parent, parent_size,
- sig, sizeof(*sig),
- sig->sig_offset, sig->sig_size);
-}
-
-int vb2_verify_digest(const struct vb2_public_key *key,
- struct vb2_signature *sig,
- const uint8_t *digest,
- const struct vb2_workbuf *wb)
-{
- uint8_t *sig_data = vb2_signature_data(sig);
-
- if (sig->sig_size != vb2_rsa_sig_size(key->sig_alg)) {
- VB2_DEBUG("Wrong data signature size for algorithm, "
- "sig_size=%d, expected %d for algorithm %d.\n",
- sig->sig_size, vb2_rsa_sig_size(key->sig_alg),
- key->sig_alg);
- return VB2_ERROR_VDATA_SIG_SIZE;
- }
-
- return vb2_rsa_verify_digest(key, sig_data, digest, wb);
-}
-
-int vb2_verify_data(const uint8_t *data,
- uint32_t size,
- struct vb2_signature *sig,
- const struct vb2_public_key *key,
- const struct vb2_workbuf *wb)
-{
- struct vb2_workbuf wblocal = *wb;
- struct vb2_digest_context *dc;
- uint8_t *digest;
- uint32_t digest_size;
- int rv;
-
- 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;
-
- digest = vb2_workbuf_alloc(&wblocal, digest_size);
- if (!digest)
- return VB2_ERROR_VDATA_WORKBUF_DIGEST;
-
- /* Hashing requires temp space for the context */
- dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc));
- if (!dc)
- return VB2_ERROR_VDATA_WORKBUF_HASHING;
-
- rv = vb2_digest_init(dc, key->hash_alg);
- if (rv)
- return rv;
-
- rv = vb2_digest_extend(dc, data, sig->data_size);
- if (rv)
- return rv;
-
- rv = vb2_digest_finalize(dc, digest, digest_size);
- if (rv)
- return rv;
-
- vb2_workbuf_free(&wblocal, sizeof(*dc));
-
- return vb2_verify_digest(key, sig, digest, &wblocal);
-}
-
-int vb2_verify_keyblock(struct vb2_keyblock *block,
- uint32_t size,
- const struct vb2_public_key *key,
- const struct vb2_workbuf *wb)
-{
- struct vb2_signature *sig;
- int rv;
-
- /* Sanity checks before attempting signature of data */
- if(size < sizeof(*block)) {
- VB2_DEBUG("Not enough space for key block header.\n");
- return VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER;
- }
- if (memcmp(block->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE)) {
- VB2_DEBUG("Not a valid verified boot key block.\n");
- return VB2_ERROR_KEYBLOCK_MAGIC;
- }
- if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) {
- VB2_DEBUG("Incompatible key block header version.\n");
- return VB2_ERROR_KEYBLOCK_HEADER_VERSION;
- }
- if (size < block->keyblock_size) {
- VB2_DEBUG("Not enough data for key block.\n");
- return VB2_ERROR_KEYBLOCK_SIZE;
- }
-
- /* Check signature */
- sig = &block->keyblock_signature;
-
- if (vb2_verify_signature_inside(block, block->keyblock_size, sig)) {
- VB2_DEBUG("Key block signature off end of block\n");
- return VB2_ERROR_KEYBLOCK_SIG_OUTSIDE;
- }
-
- /* Make sure advertised signature data sizes are sane. */
- if (block->keyblock_size < sig->data_size) {
- VB2_DEBUG("Signature calculated past end of block\n");
- return VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH;
- }
-
- VB2_DEBUG("Checking key block signature...\n");
- rv = vb2_verify_data((const uint8_t *)block, size, sig, key, wb);
- if (rv) {
- VB2_DEBUG("Invalid key block signature.\n");
- return VB2_ERROR_KEYBLOCK_SIG_INVALID;
- }
-
- /* Verify we signed enough data */
- if (sig->data_size < sizeof(struct vb2_keyblock)) {
- VB2_DEBUG("Didn't sign enough data\n");
- return VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE;
- }
-
- /* Verify data key is inside the block and inside signed data */
- if (vb2_verify_packed_key_inside(block, block->keyblock_size,
- &block->data_key)) {
- VB2_DEBUG("Data key off end of key block\n");
- return VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE;
- }
- if (vb2_verify_packed_key_inside(block, sig->data_size,
- &block->data_key)) {
- VB2_DEBUG("Data key off end of signed data\n");
- return VB2_ERROR_KEYBLOCK_DATA_KEY_UNSIGNED;
- }
-
- /* Success */
- return VB2_SUCCESS;
-}
-
-int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble,
- uint32_t size,
- const struct vb2_public_key *key,
- const struct vb2_workbuf *wb)
-{
- struct vb2_signature *sig = &preamble->preamble_signature;
-
- VB2_DEBUG("Verifying preamble.\n");
-
- /* Sanity checks before attempting signature of data */
- if(size < sizeof(*preamble)) {
- VB2_DEBUG("Not enough data for preamble header\n");
- return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER;
- }
- if (preamble->header_version_major !=
- FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) {
- VB2_DEBUG("Incompatible firmware preamble header version.\n");
- return VB2_ERROR_PREAMBLE_HEADER_VERSION;
- }
-
- if (preamble->header_version_minor < 1) {
- VB2_DEBUG("Only preamble header 2.1+ supported\n");
- return VB2_ERROR_PREAMBLE_HEADER_OLD;
- }
-
- if (size < preamble->preamble_size) {
- VB2_DEBUG("Not enough data for preamble.\n");
- return VB2_ERROR_PREAMBLE_SIZE;
- }
-
- /* Check signature */
- if (vb2_verify_signature_inside(preamble, preamble->preamble_size,
- sig)) {
- VB2_DEBUG("Preamble signature off end of preamble\n");
- return VB2_ERROR_PREAMBLE_SIG_OUTSIDE;
- }
-
- /* Make sure advertised signature data sizes are sane. */
- if (preamble->preamble_size < sig->data_size) {
- VB2_DEBUG("Signature calculated past end of the block\n");
- return VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH;
- }
-
- if (vb2_verify_data((const uint8_t *)preamble, size, sig, key, wb)) {
- VB2_DEBUG("Preamble signature validation failed\n");
- return VB2_ERROR_PREAMBLE_SIG_INVALID;
- }
-
- /* Verify we signed enough data */
- if (sig->data_size < sizeof(struct vb2_fw_preamble)) {
- VB2_DEBUG("Didn't sign enough data\n");
- return VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE;
- }
-
- /* Verify body signature is inside the signed data */
- if (vb2_verify_signature_inside(preamble, sig->data_size,
- &preamble->body_signature)) {
- VB2_DEBUG("Firmware body signature off end of preamble\n");
- return VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE;
- }
-
- /* Verify kernel subkey is inside the signed data */
- if (vb2_verify_packed_key_inside(preamble, sig->data_size,
- &preamble->kernel_subkey)) {
- VB2_DEBUG("Kernel subkey off end of preamble\n");
- return VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE;
- }
-
- /* Success */
- return VB2_SUCCESS;
-}
diff --git a/firmware/2lib/2misc.c b/firmware/2lib/2misc.c
index 48357bea..5dc0014c 100644
--- a/firmware/2lib/2misc.c
+++ b/firmware/2lib/2misc.c
@@ -364,214 +364,3 @@ int vb2_select_fw_slot(struct vb2_context *ctx)
return VB2_SUCCESS;
}
-
-int vb2_load_fw_keyblock(struct vb2_context *ctx)
-{
- struct vb2_shared_data *sd = vb2_get_sd(ctx);
- struct vb2_workbuf wb;
-
- uint8_t *key_data;
- uint32_t key_size;
- struct vb2_packed_key *packed_key;
- struct vb2_public_key root_key;
-
- struct vb2_keyblock *kb;
- uint32_t block_size;
-
- uint32_t sec_version;
- int rv;
-
- vb2_workbuf_from_ctx(ctx, &wb);
-
- /* Read the root key */
- key_size = sd->gbb_rootkey_size;
- key_data = vb2_workbuf_alloc(&wb, key_size);
- if (!key_data)
- return VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY;
-
- rv = vb2ex_read_resource(ctx, VB2_RES_GBB, sd->gbb_rootkey_offset,
- key_data, key_size);
- if (rv)
- return rv;
-
- /* Unpack the root key */
- rv = vb2_unpack_key(&root_key, key_data, key_size);
- if (rv)
- return rv;
-
- /* Load the firmware keyblock header after the root key */
- kb = vb2_workbuf_alloc(&wb, sizeof(*kb));
- if (!kb)
- return VB2_ERROR_FW_KEYBLOCK_WORKBUF_HEADER;
-
- rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, sizeof(*kb));
- if (rv)
- return rv;
-
- block_size = kb->keyblock_size;
-
- /*
- * Load the entire keyblock, now that we know how big it is. Note that
- * we're loading the entire keyblock instead of just the piece after
- * the header. That means we re-read the header. But that's a tiny
- * amount of data, and it makes the code much more straightforward.
- */
- kb = vb2_workbuf_realloc(&wb, sizeof(*kb), block_size);
- if (!kb)
- return VB2_ERROR_FW_KEYBLOCK_WORKBUF;
-
- rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, block_size);
- if (rv)
- return rv;
-
- /* Verify the keyblock */
- rv = vb2_verify_keyblock(kb, block_size, &root_key, &wb);
- if (rv)
- return rv;
-
- /* Read the secure key version */
- rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS, &sec_version);
- if (rv)
- return rv;
-
- /* Key version is the upper 16 bits of the composite firmware version */
- if (kb->data_key.key_version > 0xffff)
- return VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
- if (kb->data_key.key_version < (sec_version >> 16))
- return VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
-
- sd->fw_version = kb->data_key.key_version << 16;
-
- /*
- * Save the data key in the work buffer. This overwrites the root key
- * we read above. That's ok, because now that we have the data key we
- * no longer need the root key.
- */
- packed_key = (struct vb2_packed_key *)key_data;
-
- packed_key->algorithm = kb->data_key.algorithm;
- packed_key->key_version = kb->data_key.key_version;
- packed_key->key_size = kb->data_key.key_size;
-
- /*
- * Use memmove() instead of memcpy(). In theory, the destination will
- * never overlap because with the source because the root key is likely
- * to be at least as large as the data key, but there's no harm here in
- * being paranoid.
- */
- memmove(key_data + packed_key->key_offset,
- (uint8_t*)&kb->data_key + kb->data_key.key_offset,
- packed_key->key_size);
-
- /* Save the packed key offset and size */
- sd->workbuf_data_key_offset = vb2_offset_of(ctx->workbuf, key_data);
- sd->workbuf_data_key_size =
- packed_key->key_offset + packed_key->key_size;
-
- /* Preamble follows the keyblock in the vblock */
- sd->vblock_preamble_offset = kb->keyblock_size;
-
- /* Data key will persist in the workbuf after we return */
- ctx->workbuf_used = sd->workbuf_data_key_offset +
- sd->workbuf_data_key_size;
-
- return VB2_SUCCESS;
-}
-
-int vb2_load_fw_preamble(struct vb2_context *ctx)
-{
- struct vb2_shared_data *sd = vb2_get_sd(ctx);
- struct vb2_workbuf wb;
-
- uint8_t *key_data = ctx->workbuf + sd->workbuf_data_key_offset;
- uint32_t key_size = sd->workbuf_data_key_size;
- struct vb2_public_key data_key;
-
- /* Preamble goes in the next unused chunk of work buffer */
- struct vb2_fw_preamble *pre;
- uint32_t pre_size;
-
- uint32_t sec_version;
- int rv;
-
- vb2_workbuf_from_ctx(ctx, &wb);
-
- /* Unpack the firmware data key */
- if (!sd->workbuf_data_key_size)
- return VB2_ERROR_FW_PREAMBLE2_DATA_KEY;
-
- rv = vb2_unpack_key(&data_key, key_data, key_size);
- if (rv)
- return rv;
-
- /* Load the firmware preamble header */
- pre = vb2_workbuf_alloc(&wb, sizeof(*pre));
- if (!pre)
- return VB2_ERROR_FW_PREAMBLE2_WORKBUF_HEADER;
-
- rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
- sd->vblock_preamble_offset,
- pre, sizeof(*pre));
- if (rv)
- return rv;
-
- pre_size = pre->preamble_size;
-
- /* Load the entire firmware preamble, now that we know how big it is */
- pre = vb2_workbuf_realloc(&wb, sizeof(*pre), pre_size);
- if (!pre)
- return VB2_ERROR_FW_PREAMBLE2_WORKBUF;
-
- rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
- sd->vblock_preamble_offset,
- pre, pre_size);
- if (rv)
- return rv;
-
- /* Work buffer now contains the data subkey data and the preamble */
-
- /* Verify the preamble */
- rv = vb2_verify_fw_preamble(pre, pre_size, &data_key, &wb);
- if (rv)
- return rv;
-
- /* Read the secure key version */
- rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS, &sec_version);
- if (rv)
- return rv;
-
- /*
- * Firmware version is the lower 16 bits of the composite firmware
- * version.
- */
- if (pre->firmware_version > 0xffff)
- return VB2_ERROR_FW_PREAMBLE2_VERSION_RANGE;
-
- /* Combine with the key version from vb2_load_fw_keyblock() */
- sd->fw_version |= pre->firmware_version;
- if (sd->fw_version < sec_version)
- return VB2_ERROR_FW_PREAMBLE2_VERSION_ROLLBACK;
-
- /*
- * If this is a newer version than in secure storage, and we
- * successfully booted the same slot last boot, roll forward the
- * version in secure storage.
- */
- if (sd->fw_version > sec_version &&
- sd->last_fw_slot == sd->fw_slot &&
- sd->last_fw_result == VB2_FW_RESULT_SUCCESS) {
-
- rv = vb2_secdata_set(ctx, VB2_SECDATA_VERSIONS, sd->fw_version);
- if (rv)
- return rv;
- }
-
- /* Keep track of where we put the preamble */
- sd->workbuf_preamble_offset = vb2_offset_of(ctx->workbuf, pre);
- sd->workbuf_preamble_size = pre_size;
-
- /* Preamble will persist in work buffer after we return */
- ctx->workbuf_used = sd->workbuf_preamble_offset + pre_size;
-
- return VB2_SUCCESS;
-}
diff --git a/firmware/2lib/include/2common.h b/firmware/2lib/include/2common.h
index 672bd00c..06d0ee0f 100644
--- a/firmware/2lib/include/2common.h
+++ b/firmware/2lib/include/2common.h
@@ -146,172 +146,6 @@ int vb2_align(uint8_t **ptr,
*/
ptrdiff_t vb2_offset_of(const void *base, const void *ptr);
-/*
- * Helper functions to get data pointed to by a public key or signature.
- */
-
-const uint8_t *vb2_packed_key_data(const struct vb2_packed_key *key);
-uint8_t *vb2_signature_data(struct vb2_signature *sig);
-
-/**
- * Verify the data pointed to by a subfield is inside the parent data.
- *
- * The subfield has a header pointed to by member, and a separate data
- * field at an offset relative to the header. That is:
- *
- * struct parent {
- * (possibly other parent fields)
- * struct member {
- * (member header fields)
- * };
- * (possibly other parent fields)
- * };
- * (possibly some other parent data)
- * (member data)
- * (possibly some other parent data)
- *
- * @param parent Parent data
- * @param parent_size Parent size in bytes
- * @param member Subfield header
- * @param member_size Size of subfield header in bytes
- * @param member_data_offset Offset of member data from start of member
- * @param member_data_size Size of member data in bytes
- * @return VB2_SUCCESS, or non-zero if error.
- */
-int vb2_verify_member_inside(const void *parent, size_t parent_size,
- const void *member, size_t member_size,
- ptrdiff_t member_data_offset,
- size_t member_data_size);
-
-/**
- * Return the description of an object starting with a vb2_struct_common header.
- *
- * Does not sanity-check the buffer; merely returns the pointer.
- *
- * @param buf Pointer to common object
- * @return A pointer to description or an empty string if none.
- */
-const char *vb2_common_desc(const void *buf);
-
-/**
- * Verify the common struct header is fully contained in its parent data
- *
- * Also verifies the description is either zero-length or null-terminated.
- *
- * @param parent Parent data
- * @param parent_size Parent size in bytes
- * @return VB2_SUCCESS, or non-zero if error.
- */
-int vb2_verify_common_header(const void *parent, uint32_t parent_size);
-
-/**
- * Verify a member is within the data for a parent object
- *
- * @param parent Parent data (starts with struct vb2_struct_common)
- * @param min_offset Pointer to minimum offset where member can be located.
- * If this offset is 0 on input, uses the size of the
- * fixed header (and description, if any). This will be
- * updated on return to the end of the passed member. On
- * error, the value of min_offset is undefined.
- * @param member_offset Offset of member data from start of parent, in bytes
- * @param member_size Size of member data, in bytes
- * @return VB2_SUCCESS, or non-zero if error.
- */
-int vb2_verify_common_member(const void *parent,
- uint32_t *min_offset,
- uint32_t member_offset,
- uint32_t member_size);
-
-/**
- * Verify a member which starts with a common header is within the parent
- *
- * This does not verify the contents of the member or its header, only that the
- * member's claimed total size fits within the parent's claimed total size at
- * the specified offset.
- *
- * @param parent Parent data (starts with struct vb2_struct_common)
- * @param min_offset Pointer to minimum offset where member can be located.
- * If this offset is 0 on input, uses the size of the
- * fixed header (and description, if any). This will be
- * updated on return to the end of the passed member. On
- * error, the value of min_offset is undefined.
- * @param member_offset Offset of member data from start of parent, in bytes.
- * This should be the start of the common header of the
- * member.
- * @return VB2_SUCCESS, or non-zero if error.
- */
-int vb2_verify_common_subobject(const void *parent,
- uint32_t *min_offset,
- uint32_t member_offset);
-
-/**
- * Verify a signature is fully contained in its parent data
- *
- * @param parent Parent data
- * @param parent_size Parent size in bytes
- * @param sig Signature pointer
- * @return VB2_SUCCESS, or non-zero if error.
- */
-int vb2_verify_signature_inside(const void *parent,
- uint32_t parent_size,
- const struct vb2_signature *sig);
-
-/**
- * Verify a packed key is fully contained in its parent data
- *
- * @param parent Parent data
- * @param parent_size Parent size in bytes
- * @param key Packed key pointer
- * @return VB2_SUCCESS, or non-zero if error.
- */
-int vb2_verify_packed_key_inside(const void *parent,
- uint32_t parent_size,
- const struct vb2_packed_key *key);
-
-/**
- * Unpack a vboot1-format key for use in verification
- *
- * The elements of the unpacked key will point into the source buffer, so don't
- * free the source buffer until you're done with the key.
- *
- * @param key Destintion for unpacked key
- * @param buf Source buffer containing packed key
- * @param size Size of buffer in bytes
- * @return VB2_SUCCESS, or non-zero error code if error.
- */
-int vb2_unpack_key(struct vb2_public_key *key,
- const uint8_t *buf,
- uint32_t size);
-
-/**
- * Unpack a key for use in verification
- *
- * The elements of the unpacked key will point into the source buffer, so don't
- * free the source buffer until you're done with the key.
- *
- * @param key Destintion for unpacked key
- * @param buf Source buffer containing packed key
- * @param size Size of buffer in bytes
- * @return VB2_SUCCESS, or non-zero error code if error.
- */
-int vb2_unpack_key2(struct vb2_public_key *key,
- const uint8_t *buf,
- uint32_t size);
-
-/**
- * Unpack the RSA data fields for a public key
- *
- * This is called by vb2_unpack_key2() to extract the arrays from a packed key.
- * These elements of *key will point inside the key_data buffer.
- *
- * @param key Destination key for RSA data fields
- * @param key_data Packed key data (from inside a packed key buffer)
- * @param key_size Size of packed key data in bytes
- */
-int vb2_unpack_key2_data(struct vb2_public_key *key,
- const uint8_t *key_data,
- uint32_t key_size);
-
/**
* Return expected signature size for a signature/hash algorithm pair
*
@@ -337,20 +171,6 @@ const struct vb2_guid *vb2_hash_guid(enum vb2_hash_algorithm hash_alg);
*/
#define VB2_VERIFY_DIGEST_WORKBUF_BYTES VB2_VERIFY_RSA_DIGEST_WORKBUF_BYTES
-/**
- * Verify a signature against an expected hash digest.
- *
- * @param key Key to use in signature verification
- * @param sig Signature to verify (may be destroyed in process)
- * @param digest Digest of signed data
- * @param wb Work buffer
- * @return VB2_SUCCESS, or non-zero if error.
- */
-int vb2_verify_digest(const struct vb2_public_key *key,
- struct vb2_signature *sig,
- const uint8_t *digest,
- const struct vb2_workbuf *wb);
-
/*
* Size of work buffer sufficient for vb2_verify_data() or vb2_verify_data2()
* worst case.
@@ -360,66 +180,16 @@ int vb2_verify_digest(const struct vb2_public_key *key,
VB2_MAX(VB2_VERIFY_DIGEST_WORKBUF_BYTES, \
sizeof(struct vb2_digest_context)))
-/**
- * Verify data matches signature.
- *
- * @param data Data to verify
- * @param size Size of data buffer. Note that amount of data to
- * actually validate is contained in sig->data_size.
- * @param sig Signature of data (destroyed in process)
- * @param key Key to use to validate signature
- * @param wb Work buffer
- * @return VB2_SUCCESS, or non-zero error code if error.
- */
-int vb2_verify_data(const uint8_t *data,
- uint32_t size,
- struct vb2_signature *sig,
- const struct vb2_public_key *key,
- const struct vb2_workbuf *wb);
-
/*
* Size of work buffer sufficient for vb2_verify_keyblock() or
* vb2_verify_keyblock2() worst case.
*/
#define VB2_KEY_BLOCK_VERIFY_WORKBUF_BYTES VB2_VERIFY_DATA_WORKBUF_BYTES
-/**
- * Check the sanity of a key block using a public key.
- *
- * Header fields are also checked for sanity. Does not verify key index or key
- * block flags. Signature inside block is destroyed during check.
- *
- * @param block Key block to verify
- * @param size Size of key block buffer
- * @param key Key to use to verify block
- * @param wb Work buffer
- * @return VB2_SUCCESS, or non-zero error code if error.
- */
-int vb2_verify_keyblock(struct vb2_keyblock *block,
- uint32_t size,
- const struct vb2_public_key *key,
- const struct vb2_workbuf *wb);
-
/*
* Size of work buffer sufficient for vb2_verify_fw_preamble() or
* vb2_verify_fw_preamble2() worst case.
*/
#define VB2_VERIFY_FIRMWARE_PREAMBLE_WORKBUF_BYTES VB2_VERIFY_DATA_WORKBUF_BYTES
-/**
- * Check the sanity of a firmware preamble using a public key.
- *
- * The signature in the preamble is destroyed during the check.
- *
- * @param preamble Preamble to verify
- * @param size Size of preamble buffer
- * @param key Key to use to verify preamble
- * @param wb Work buffer
- * @return VB2_SUCCESS, or non-zero error code if error.
- */
-int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble,
- uint32_t size,
- const struct vb2_public_key *key,
- const struct vb2_workbuf *wb);
-
#endif /* VBOOT_REFERENCE_VBOOT_2COMMON_H_ */
diff --git a/firmware/2lib/include/2misc.h b/firmware/2lib/include/2misc.h
index 24b32db7..e3d9bec0 100644
--- a/firmware/2lib/include/2misc.h
+++ b/firmware/2lib/include/2misc.h
@@ -11,6 +11,7 @@
#include "2api.h"
struct vb2_gbb_header;
+struct vb2_workbuf;
/**
* Get the shared data pointer from the vboot context
diff --git a/firmware/2lib/include/2struct.h b/firmware/2lib/include/2struct.h
index b2b35f24..c8ff2378 100644
--- a/firmware/2lib/include/2struct.h
+++ b/firmware/2lib/include/2struct.h
@@ -10,8 +10,6 @@
#define VBOOT_REFERENCE_VBOOT_2STRUCT_H_
#include <stdint.h>
-#include "2guid.h"
-
/* Algorithm types for signatures */
enum vb2_signature_algorithm {
/* Invalid or unsupported signature type */
@@ -43,65 +41,10 @@ enum vb2_hash_algorithm {
VB2_HASH_SHA512 = 3,
};
-/****************************************************************************/
/*
- * Vboot1-compatible data structures
+ * Key block flags.
*
- *
- * Note: Many of the structs have pairs of 32-bit fields and reserved fields.
- * This is to be backwards-compatible with older verified boot data which used
- * 64-bit fields (when we thought that hey, UEFI is 64-bit so all our fields
- * should be too).
- */
-
-/* Packed public key data */
-struct vb2_packed_key {
- /* Offset of key data from start of this struct */
- uint32_t key_offset;
- uint32_t reserved0;
-
- /* Size of key data in bytes (NOT strength of key in bits) */
- uint32_t key_size;
- uint32_t reserved1;
-
- /* Signature algorithm used by the key (enum vb2_crypto_algorithm) */
- uint32_t algorithm;
- uint32_t reserved2;
-
- /* Key version */
- uint32_t key_version;
- uint32_t reserved3;
-
- /* TODO: when redoing this struct, add a text description of the key */
-} __attribute__((packed));
-
-#define EXPECTED_VB2_PACKED_KEY_SIZE 32
-
-/* Signature data (a secure hash, possibly signed) */
-struct vb2_signature {
- /* Offset of signature data from start of this struct */
- uint32_t sig_offset;
- uint32_t reserved0;
-
- /* Size of signature data in bytes */
- uint32_t sig_size;
- uint32_t reserved1;
-
- /* Size of the data block which was signed in bytes */
- uint32_t data_size;
- uint32_t reserved2;
-} __attribute__((packed));
-
-#define EXPECTED_VB2_SIGNATURE_SIZE 24
-
-#define KEY_BLOCK_MAGIC "CHROMEOS"
-#define KEY_BLOCK_MAGIC_SIZE 8
-
-#define KEY_BLOCK_HEADER_VERSION_MAJOR 2
-#define KEY_BLOCK_HEADER_VERSION_MINOR 1
-
-/*
- * The following flags set where the key is valid. Not used by firmware
+ *The following flags set where the key is valid. Not used by firmware
* verification; only kernel verification.
*/
#define VB2_KEY_BLOCK_FLAG_DEVELOPER_0 0x01 /* Developer switch off */
@@ -109,117 +52,6 @@ struct vb2_signature {
#define VB2_KEY_BLOCK_FLAG_RECOVERY_0 0x04 /* Not recovery mode */
#define VB2_KEY_BLOCK_FLAG_RECOVERY_1 0x08 /* Recovery mode */
-/*
- * Key block, containing the public key used to sign some other chunk of data.
- *
- * This should be followed by:
- * 1) The data_key key data, pointed to by data_key.key_offset.
- * 2) The checksum data for (vb2_keyblock + data_key data), pointed to
- * by keyblock_checksum.sig_offset.
- * 3) The signature data for (vb2_keyblock + data_key data), pointed to
- * by keyblock_signature.sig_offset.
- */
-struct vb2_keyblock {
- /* Magic number */
- uint8_t magic[KEY_BLOCK_MAGIC_SIZE];
-
- /* Version of this header format */
- uint32_t header_version_major;
-
- /* Version of this header format */
- uint32_t header_version_minor;
-
- /*
- * Length of this entire key block, including keys, signatures, and
- * padding, in bytes
- */
- uint32_t keyblock_size;
- uint32_t reserved0;
-
- /*
- * Signature for this key block (header + data pointed to by data_key)
- * For use with signed data keys
- */
- struct vb2_signature keyblock_signature;
-
- /*
- * SHA-512 checksum for this key block (header + data pointed to by
- * data_key) For use with unsigned data keys.
- *
- * Note that the vb2 lib currently only supports signed blocks.
- */
- struct vb2_signature keyblock_checksum_unused;
-
- /* Flags for key (VB2_KEY_BLOCK_FLAG_*) */
- uint32_t keyblock_flags;
- uint32_t reserved1;
-
- /* Key to verify the chunk of data */
- struct vb2_packed_key data_key;
-} __attribute__((packed));
-
-#define EXPECTED_VB2_KEYBLOCK_SIZE 112
-
-
-/* Firmware preamble header */
-#define FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR 2
-#define FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR 1
-
-/* Flags for VbFirmwarePreambleHeader.flags */
-/* Reserved; do not use */
-#define VB2_FIRMWARE_PREAMBLE_RESERVED0 0x00000001
-
-/* Premable block for rewritable firmware, version 2.1.
- *
- * The firmware preamble header should be followed by:
- * 1) The kernel_subkey key data, pointed to by kernel_subkey.key_offset.
- * 2) The signature data for the firmware body, pointed to by
- * body_signature.sig_offset.
- * 3) The signature data for (header + kernel_subkey data + body signature
- * data), pointed to by preamble_signature.sig_offset.
- */
-struct vb2_fw_preamble {
- /*
- * Size of this preamble, including keys, signatures, and padding, in
- * bytes
- */
- uint32_t preamble_size;
- uint32_t reserved0;
-
- /*
- * Signature for this preamble (header + kernel subkey + body
- * signature)
- */
- struct vb2_signature preamble_signature;
-
- /* Version of this header format */
- uint32_t header_version_major;
- uint32_t header_version_minor;
-
- /* Firmware version */
- uint32_t firmware_version;
- uint32_t reserved1;
-
- /* Key to verify kernel key block */
- struct vb2_packed_key kernel_subkey;
-
- /* Signature for the firmware body */
- struct vb2_signature body_signature;
-
- /*
- * Fields added in header version 2.1. You must verify the header
- * version before reading these fields!
- */
-
- /*
- * Flags; see VB2_FIRMWARE_PREAMBLE_*. Readers should return 0 for
- * header version < 2.1.
- */
- uint32_t flags;
-} __attribute__((packed));
-
-#define EXPECTED_VB2_FW_PREAMBLE_SIZE 108
-
/****************************************************************************/
/* Flags for vb2_shared_data.flags */
diff --git a/firmware/include/vb2_api.h b/firmware/include/vb2_api.h
index 8b1bc4d5..0b32a782 100644
--- a/firmware/include/vb2_api.h
+++ b/firmware/include/vb2_api.h
@@ -25,6 +25,7 @@
*/
#ifdef NEED_VB20_INTERNALS
#include "../2lib/include/2struct.h"
+#include "../lib20/include/vb2_struct.h"
#endif
#endif /* VBOOT_VB2_API_H_ */
diff --git a/firmware/lib20/api.c b/firmware/lib20/api.c
new file mode 100644
index 00000000..16ad6dc1
--- /dev/null
+++ b/firmware/lib20/api.c
@@ -0,0 +1,174 @@
+/* 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 "2sysincludes.h"
+#include "2api.h"
+#include "2misc.h"
+#include "2nvstorage.h"
+#include "2secdata.h"
+#include "2sha.h"
+#include "2rsa.h"
+#include "vb2_common.h"
+
+int vb2api_fw_phase3(struct vb2_context *ctx)
+{
+ int rv;
+
+ /* Verify firmware keyblock */
+ rv = vb2_load_fw_keyblock(ctx);
+ if (rv) {
+ vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
+ return rv;
+ }
+
+ /* Verify firmware preamble */
+ rv = vb2_load_fw_preamble(ctx);
+ if (rv) {
+ vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
+ return rv;
+ }
+
+ return VB2_SUCCESS;
+}
+
+int 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;
+ int 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->workbuf_preamble_size)
+ return VB2_ERROR_API_INIT_HASH_PREAMBLE;
+ pre = (const struct vb2_fw_preamble *)
+ (ctx->workbuf + sd->workbuf_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->workbuf_hash_size) {
+ dc = (struct vb2_digest_context *)
+ (ctx->workbuf + sd->workbuf_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->workbuf_hash_offset = vb2_offset_of(ctx->workbuf, dc);
+ sd->workbuf_hash_size = dig_size;
+ ctx->workbuf_used = sd->workbuf_hash_offset + dig_size;
+ }
+
+ /*
+ * 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->workbuf_data_key_size)
+ return VB2_ERROR_API_INIT_HASH_DATA_KEY;
+
+ rv = vb2_unpack_key(&key,
+ ctx->workbuf + sd->workbuf_data_key_offset,
+ sd->workbuf_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;
+
+ return vb2_digest_init(dc, key.hash_alg);
+}
+
+int vb2api_check_hash(struct vb2_context *ctx)
+{
+ struct vb2_shared_data *sd = vb2_get_sd(ctx);
+ struct vb2_digest_context *dc = (struct vb2_digest_context *)
+ (ctx->workbuf + sd->workbuf_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;
+ int rv;
+
+ vb2_workbuf_from_ctx(ctx, &wb);
+
+ /* Get preamble pointer */
+ if (!sd->workbuf_preamble_size)
+ return VB2_ERROR_API_CHECK_HASH_PREAMBLE;
+ pre = (struct vb2_fw_preamble *)
+ (ctx->workbuf + sd->workbuf_preamble_offset);
+
+ /* Must have initialized hash digest work area */
+ if (!sd->workbuf_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 */
+ 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->workbuf_data_key_size)
+ return VB2_ERROR_API_CHECK_HASH_DATA_KEY;
+
+ rv = vb2_unpack_key(&key,
+ ctx->workbuf + sd->workbuf_data_key_offset,
+ sd->workbuf_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)
+ vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv);
+
+ return rv;
+}
diff --git a/firmware/lib20/common.c b/firmware/lib20/common.c
new file mode 100644
index 00000000..9ce9d840
--- /dev/null
+++ b/firmware/lib20/common.c
@@ -0,0 +1,272 @@
+/* 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.
+ *
+ * Common functions between firmware and kernel verified boot.
+ * (Firmware portion)
+ */
+
+#include "2sysincludes.h"
+#include "2rsa.h"
+#include "2sha.h"
+#include "vb2_common.h"
+
+uint8_t *vb2_signature_data(struct vb2_signature *sig)
+{
+ return (uint8_t *)sig + sig->sig_offset;
+}
+
+int vb2_verify_member_inside(const void *parent, size_t parent_size,
+ const void *member, size_t member_size,
+ ptrdiff_t member_data_offset,
+ size_t member_data_size)
+{
+ const uintptr_t parent_end = (uintptr_t)parent + parent_size;
+ const ptrdiff_t member_offs = vb2_offset_of(parent, member);
+ const ptrdiff_t member_end_offs = member_offs + member_size;
+ const ptrdiff_t data_offs = member_offs + member_data_offset;
+ const ptrdiff_t data_end_offs = data_offs + member_data_size;
+
+ /* Make sure parent doesn't wrap */
+ if (parent_size < 0 || parent_end < (uintptr_t)parent)
+ return VB2_ERROR_INSIDE_PARENT_WRAPS;
+
+ /*
+ * Make sure the member is fully contained in the parent and doesn't
+ * wrap. Use >, not >=, since member_size = 0 is possible.
+ */
+ if (member_size < 0 || member_end_offs < member_offs)
+ return VB2_ERROR_INSIDE_MEMBER_WRAPS;
+ if (member_offs < 0 || member_offs > parent_size ||
+ member_end_offs > parent_size)
+ return VB2_ERROR_INSIDE_MEMBER_OUTSIDE;
+
+ /* Make sure the member data is after the member */
+ if (member_data_size > 0 && data_offs < member_end_offs)
+ return VB2_ERROR_INSIDE_DATA_OVERLAP;
+
+ /* Make sure parent fully contains member data, if any */
+ if (member_data_size < 0 || data_end_offs < data_offs)
+ return VB2_ERROR_INSIDE_DATA_WRAPS;
+ if (data_offs < 0 || data_offs > parent_size ||
+ data_end_offs > parent_size)
+ return VB2_ERROR_INSIDE_DATA_OUTSIDE;
+
+ return VB2_SUCCESS;
+}
+
+int vb2_verify_signature_inside(const void *parent,
+ uint32_t parent_size,
+ const struct vb2_signature *sig)
+{
+ return vb2_verify_member_inside(parent, parent_size,
+ sig, sizeof(*sig),
+ sig->sig_offset, sig->sig_size);
+}
+
+int vb2_verify_digest(const struct vb2_public_key *key,
+ struct vb2_signature *sig,
+ const uint8_t *digest,
+ const struct vb2_workbuf *wb)
+{
+ uint8_t *sig_data = vb2_signature_data(sig);
+
+ if (sig->sig_size != vb2_rsa_sig_size(key->sig_alg)) {
+ VB2_DEBUG("Wrong data signature size for algorithm, "
+ "sig_size=%d, expected %d for algorithm %d.\n",
+ sig->sig_size, vb2_rsa_sig_size(key->sig_alg),
+ key->sig_alg);
+ return VB2_ERROR_VDATA_SIG_SIZE;
+ }
+
+ return vb2_rsa_verify_digest(key, sig_data, digest, wb);
+}
+
+int vb2_verify_data(const uint8_t *data,
+ uint32_t size,
+ struct vb2_signature *sig,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb)
+{
+ struct vb2_workbuf wblocal = *wb;
+ struct vb2_digest_context *dc;
+ uint8_t *digest;
+ uint32_t digest_size;
+ int rv;
+
+ 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;
+
+ digest = vb2_workbuf_alloc(&wblocal, digest_size);
+ if (!digest)
+ return VB2_ERROR_VDATA_WORKBUF_DIGEST;
+
+ /* Hashing requires temp space for the context */
+ dc = vb2_workbuf_alloc(&wblocal, sizeof(*dc));
+ if (!dc)
+ return VB2_ERROR_VDATA_WORKBUF_HASHING;
+
+ rv = vb2_digest_init(dc, key->hash_alg);
+ if (rv)
+ return rv;
+
+ rv = vb2_digest_extend(dc, data, sig->data_size);
+ if (rv)
+ return rv;
+
+ rv = vb2_digest_finalize(dc, digest, digest_size);
+ if (rv)
+ return rv;
+
+ vb2_workbuf_free(&wblocal, sizeof(*dc));
+
+ return vb2_verify_digest(key, sig, digest, &wblocal);
+}
+
+int vb2_verify_keyblock(struct vb2_keyblock *block,
+ uint32_t size,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb)
+{
+ struct vb2_signature *sig;
+ int rv;
+
+ /* Sanity checks before attempting signature of data */
+ if(size < sizeof(*block)) {
+ VB2_DEBUG("Not enough space for key block header.\n");
+ return VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER;
+ }
+ if (memcmp(block->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE)) {
+ VB2_DEBUG("Not a valid verified boot key block.\n");
+ return VB2_ERROR_KEYBLOCK_MAGIC;
+ }
+ if (block->header_version_major != KEY_BLOCK_HEADER_VERSION_MAJOR) {
+ VB2_DEBUG("Incompatible key block header version.\n");
+ return VB2_ERROR_KEYBLOCK_HEADER_VERSION;
+ }
+ if (size < block->keyblock_size) {
+ VB2_DEBUG("Not enough data for key block.\n");
+ return VB2_ERROR_KEYBLOCK_SIZE;
+ }
+
+ /* Check signature */
+ sig = &block->keyblock_signature;
+
+ if (vb2_verify_signature_inside(block, block->keyblock_size, sig)) {
+ VB2_DEBUG("Key block signature off end of block\n");
+ return VB2_ERROR_KEYBLOCK_SIG_OUTSIDE;
+ }
+
+ /* Make sure advertised signature data sizes are sane. */
+ if (block->keyblock_size < sig->data_size) {
+ VB2_DEBUG("Signature calculated past end of block\n");
+ return VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH;
+ }
+
+ VB2_DEBUG("Checking key block signature...\n");
+ rv = vb2_verify_data((const uint8_t *)block, size, sig, key, wb);
+ if (rv) {
+ VB2_DEBUG("Invalid key block signature.\n");
+ return VB2_ERROR_KEYBLOCK_SIG_INVALID;
+ }
+
+ /* Verify we signed enough data */
+ if (sig->data_size < sizeof(struct vb2_keyblock)) {
+ VB2_DEBUG("Didn't sign enough data\n");
+ return VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE;
+ }
+
+ /* Verify data key is inside the block and inside signed data */
+ if (vb2_verify_packed_key_inside(block, block->keyblock_size,
+ &block->data_key)) {
+ VB2_DEBUG("Data key off end of key block\n");
+ return VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE;
+ }
+ if (vb2_verify_packed_key_inside(block, sig->data_size,
+ &block->data_key)) {
+ VB2_DEBUG("Data key off end of signed data\n");
+ return VB2_ERROR_KEYBLOCK_DATA_KEY_UNSIGNED;
+ }
+
+ /* Success */
+ return VB2_SUCCESS;
+}
+
+int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble,
+ uint32_t size,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb)
+{
+ struct vb2_signature *sig = &preamble->preamble_signature;
+
+ VB2_DEBUG("Verifying preamble.\n");
+
+ /* Sanity checks before attempting signature of data */
+ if(size < sizeof(*preamble)) {
+ VB2_DEBUG("Not enough data for preamble header\n");
+ return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER;
+ }
+ if (preamble->header_version_major !=
+ FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) {
+ VB2_DEBUG("Incompatible firmware preamble header version.\n");
+ return VB2_ERROR_PREAMBLE_HEADER_VERSION;
+ }
+
+ if (preamble->header_version_minor < 1) {
+ VB2_DEBUG("Only preamble header 2.1+ supported\n");
+ return VB2_ERROR_PREAMBLE_HEADER_OLD;
+ }
+
+ if (size < preamble->preamble_size) {
+ VB2_DEBUG("Not enough data for preamble.\n");
+ return VB2_ERROR_PREAMBLE_SIZE;
+ }
+
+ /* Check signature */
+ if (vb2_verify_signature_inside(preamble, preamble->preamble_size,
+ sig)) {
+ VB2_DEBUG("Preamble signature off end of preamble\n");
+ return VB2_ERROR_PREAMBLE_SIG_OUTSIDE;
+ }
+
+ /* Make sure advertised signature data sizes are sane. */
+ if (preamble->preamble_size < sig->data_size) {
+ VB2_DEBUG("Signature calculated past end of the block\n");
+ return VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH;
+ }
+
+ if (vb2_verify_data((const uint8_t *)preamble, size, sig, key, wb)) {
+ VB2_DEBUG("Preamble signature validation failed\n");
+ return VB2_ERROR_PREAMBLE_SIG_INVALID;
+ }
+
+ /* Verify we signed enough data */
+ if (sig->data_size < sizeof(struct vb2_fw_preamble)) {
+ VB2_DEBUG("Didn't sign enough data\n");
+ return VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE;
+ }
+
+ /* Verify body signature is inside the signed data */
+ if (vb2_verify_signature_inside(preamble, sig->data_size,
+ &preamble->body_signature)) {
+ VB2_DEBUG("Firmware body signature off end of preamble\n");
+ return VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE;
+ }
+
+ /* Verify kernel subkey is inside the signed data */
+ if (vb2_verify_packed_key_inside(preamble, sig->data_size,
+ &preamble->kernel_subkey)) {
+ VB2_DEBUG("Kernel subkey off end of preamble\n");
+ return VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE;
+ }
+
+ /* Success */
+ return VB2_SUCCESS;
+}
diff --git a/firmware/lib20/include/vb2_common.h b/firmware/lib20/include/vb2_common.h
new file mode 100644
index 00000000..4067d694
--- /dev/null
+++ b/firmware/lib20/include/vb2_common.h
@@ -0,0 +1,159 @@
+/* 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.
+ *
+ * Common functions between firmware and kernel verified boot.
+ */
+
+#ifndef VBOOT_REFERENCE_VB2_COMMON_H_
+#define VBOOT_REFERENCE_VB2_COMMON_H_
+
+#include "2api.h"
+#include "2common.h"
+#include "2return_codes.h"
+#include "2sha.h"
+#include "2struct.h"
+#include "vb2_struct.h"
+
+/*
+ * Helper functions to get data pointed to by a public key or signature.
+ */
+
+const uint8_t *vb2_packed_key_data(const struct vb2_packed_key *key);
+uint8_t *vb2_signature_data(struct vb2_signature *sig);
+
+/**
+ * Verify the data pointed to by a subfield is inside the parent data.
+ *
+ * The subfield has a header pointed to by member, and a separate data
+ * field at an offset relative to the header. That is:
+ *
+ * struct parent {
+ * (possibly other parent fields)
+ * struct member {
+ * (member header fields)
+ * };
+ * (possibly other parent fields)
+ * };
+ * (possibly some other parent data)
+ * (member data)
+ * (possibly some other parent data)
+ *
+ * @param parent Parent data
+ * @param parent_size Parent size in bytes
+ * @param member Subfield header
+ * @param member_size Size of subfield header in bytes
+ * @param member_data_offset Offset of member data from start of member
+ * @param member_data_size Size of member data in bytes
+ * @return VB2_SUCCESS, or non-zero if error.
+ */
+int vb2_verify_member_inside(const void *parent, size_t parent_size,
+ const void *member, size_t member_size,
+ ptrdiff_t member_data_offset,
+ size_t member_data_size);
+
+/**
+ * Verify a signature is fully contained in its parent data
+ *
+ * @param parent Parent data
+ * @param parent_size Parent size in bytes
+ * @param sig Signature pointer
+ * @return VB2_SUCCESS, or non-zero if error.
+ */
+int vb2_verify_signature_inside(const void *parent,
+ uint32_t parent_size,
+ const struct vb2_signature *sig);
+
+
+/**
+ * Verify a packed key is fully contained in its parent data
+ *
+ * @param parent Parent data
+ * @param parent_size Parent size in bytes
+ * @param key Packed key pointer
+ * @return VB2_SUCCESS, or non-zero if error.
+ */
+int vb2_verify_packed_key_inside(const void *parent,
+ uint32_t parent_size,
+ const struct vb2_packed_key *key);
+
+/**
+ * Unpack a vboot1-format key for use in verification
+ *
+ * The elements of the unpacked key will point into the source buffer, so don't
+ * free the source buffer until you're done with the key.
+ *
+ * @param key Destintion for unpacked key
+ * @param buf Source buffer containing packed key
+ * @param size Size of buffer in bytes
+ * @return VB2_SUCCESS, or non-zero error code if error.
+ */
+int vb2_unpack_key(struct vb2_public_key *key,
+ const uint8_t *buf,
+ uint32_t size);
+
+/**
+ * Verify a signature against an expected hash digest.
+ *
+ * @param key Key to use in signature verification
+ * @param sig Signature to verify (may be destroyed in process)
+ * @param digest Digest of signed data
+ * @param wb Work buffer
+ * @return VB2_SUCCESS, or non-zero if error.
+ */
+int vb2_verify_digest(const struct vb2_public_key *key,
+ struct vb2_signature *sig,
+ const uint8_t *digest,
+ const struct vb2_workbuf *wb);
+
+/**
+ * Verify data matches signature.
+ *
+ * @param data Data to verify
+ * @param size Size of data buffer. Note that amount of data to
+ * actually validate is contained in sig->data_size.
+ * @param sig Signature of data (destroyed in process)
+ * @param key Key to use to validate signature
+ * @param wb Work buffer
+ * @return VB2_SUCCESS, or non-zero error code if error.
+ */
+int vb2_verify_data(const uint8_t *data,
+ uint32_t size,
+ struct vb2_signature *sig,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb);
+
+/**
+ * Check the sanity of a key block using a public key.
+ *
+ * Header fields are also checked for sanity. Does not verify key index or key
+ * block flags. Signature inside block is destroyed during check.
+ *
+ * @param block Key block to verify
+ * @param size Size of key block buffer
+ * @param key Key to use to verify block
+ * @param wb Work buffer
+ * @return VB2_SUCCESS, or non-zero error code if error.
+ */
+int vb2_verify_keyblock(struct vb2_keyblock *block,
+ uint32_t size,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb);
+
+/**
+ * Check the sanity of a firmware preamble using a public key.
+ *
+ * The signature in the preamble is destroyed during the check.
+ *
+ * @param preamble Preamble to verify
+ * @param size Size of preamble buffer
+ * @param key Key to use to verify preamble
+ * @param wb Work buffer
+ * @return VB2_SUCCESS, or non-zero error code if error.
+ */
+int vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble,
+ uint32_t size,
+ const struct vb2_public_key *key,
+ const struct vb2_workbuf *wb);
+
+#endif /* VBOOT_REFERENCE_VB2_COMMON_H_ */
diff --git a/firmware/lib20/include/vb2_struct.h b/firmware/lib20/include/vb2_struct.h
new file mode 100644
index 00000000..136ce91a
--- /dev/null
+++ b/firmware/lib20/include/vb2_struct.h
@@ -0,0 +1,179 @@
+/* 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.
+ *
+ * Vboot 2.0 data structures (compatible with vboot1)
+ *
+ * Note: Many of the structs have pairs of 32-bit fields and reserved fields.
+ * This is to be backwards-compatible with older verified boot data which used
+ * 64-bit fields (when we thought that hey, UEFI is 64-bit so all our fields
+ * should be too).
+ *
+ * Offsets should be padded to 32-bit boundaries, since some architectures
+ * have trouble with accessing unaligned integers.
+ */
+
+#ifndef VBOOT_REFERENCE_VB2_STRUCT_H_
+#define VBOOT_REFERENCE_VB2_STRUCT_H_
+#include <stdint.h>
+
+/* Packed public key data */
+struct vb2_packed_key {
+ /* Offset of key data from start of this struct */
+ uint32_t key_offset;
+ uint32_t reserved0;
+
+ /* Size of key data in bytes (NOT strength of key in bits) */
+ uint32_t key_size;
+ uint32_t reserved1;
+
+ /* Signature algorithm used by the key (enum vb2_crypto_algorithm) */
+ uint32_t algorithm;
+ uint32_t reserved2;
+
+ /* Key version */
+ uint32_t key_version;
+ uint32_t reserved3;
+
+ /* TODO: when redoing this struct, add a text description of the key */
+} __attribute__((packed));
+
+#define EXPECTED_VB2_PACKED_KEY_SIZE 32
+
+
+/* Signature data (a secure hash, possibly signed) */
+struct vb2_signature {
+ /* Offset of signature data from start of this struct */
+ uint32_t sig_offset;
+ uint32_t reserved0;
+
+ /* Size of signature data in bytes */
+ uint32_t sig_size;
+ uint32_t reserved1;
+
+ /* Size of the data block which was signed in bytes */
+ uint32_t data_size;
+ uint32_t reserved2;
+} __attribute__((packed));
+
+#define EXPECTED_VB2_SIGNATURE_SIZE 24
+
+
+#define KEY_BLOCK_MAGIC "CHROMEOS"
+#define KEY_BLOCK_MAGIC_SIZE 8
+
+#define KEY_BLOCK_HEADER_VERSION_MAJOR 2
+#define KEY_BLOCK_HEADER_VERSION_MINOR 1
+
+/*
+ * Key block, containing the public key used to sign some other chunk of data.
+ *
+ * This should be followed by:
+ * 1) The data_key key data, pointed to by data_key.key_offset.
+ * 2) The checksum data for (vb2_keyblock + data_key data), pointed to
+ * by keyblock_checksum.sig_offset.
+ * 3) The signature data for (vb2_keyblock + data_key data), pointed to
+ * by keyblock_signature.sig_offset.
+ */
+struct vb2_keyblock {
+ /* Magic number */
+ uint8_t magic[KEY_BLOCK_MAGIC_SIZE];
+
+ /* Version of this header format */
+ uint32_t header_version_major;
+
+ /* Version of this header format */
+ uint32_t header_version_minor;
+
+ /*
+ * Length of this entire key block, including keys, signatures, and
+ * padding, in bytes
+ */
+ uint32_t keyblock_size;
+ uint32_t reserved0;
+
+ /*
+ * Signature for this key block (header + data pointed to by data_key)
+ * For use with signed data keys
+ */
+ struct vb2_signature keyblock_signature;
+
+ /*
+ * SHA-512 checksum for this key block (header + data pointed to by
+ * data_key) For use with unsigned data keys.
+ *
+ * Note that the vb2 lib currently only supports signed blocks.
+ */
+ struct vb2_signature keyblock_checksum_unused;
+
+ /* Flags for key (VB2_KEY_BLOCK_FLAG_*) */
+ uint32_t keyblock_flags;
+ uint32_t reserved1;
+
+ /* Key to verify the chunk of data */
+ struct vb2_packed_key data_key;
+} __attribute__((packed));
+
+#define EXPECTED_VB2_KEYBLOCK_SIZE 112
+
+
+/* Firmware preamble header */
+#define FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR 2
+#define FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR 1
+
+/* Flags for VbFirmwarePreambleHeader.flags */
+/* Reserved; do not use */
+#define VB2_FIRMWARE_PREAMBLE_RESERVED0 0x00000001
+
+/* Premable block for rewritable firmware, vboot1 version 2.1.
+ *
+ * The firmware preamble header should be followed by:
+ * 1) The kernel_subkey key data, pointed to by kernel_subkey.key_offset.
+ * 2) The signature data for the firmware body, pointed to by
+ * body_signature.sig_offset.
+ * 3) The signature data for (header + kernel_subkey data + body signature
+ * data), pointed to by preamble_signature.sig_offset.
+ */
+struct vb2_fw_preamble {
+ /*
+ * Size of this preamble, including keys, signatures, and padding, in
+ * bytes
+ */
+ uint32_t preamble_size;
+ uint32_t reserved0;
+
+ /*
+ * Signature for this preamble (header + kernel subkey + body
+ * signature)
+ */
+ struct vb2_signature preamble_signature;
+
+ /* Version of this header format */
+ uint32_t header_version_major;
+ uint32_t header_version_minor;
+
+ /* Firmware version */
+ uint32_t firmware_version;
+ uint32_t reserved1;
+
+ /* Key to verify kernel key block */
+ struct vb2_packed_key kernel_subkey;
+
+ /* Signature for the firmware body */
+ struct vb2_signature body_signature;
+
+ /*
+ * Fields added in header version 2.1. You must verify the header
+ * version before reading these fields!
+ */
+
+ /*
+ * Flags; see VB2_FIRMWARE_PREAMBLE_*. Readers should return 0 for
+ * header version < 2.1.
+ */
+ uint32_t flags;
+} __attribute__((packed));
+
+#define EXPECTED_VB2_FW_PREAMBLE_SIZE 108
+
+#endif /* VBOOT_REFERENCE_VB2_STRUCT_H_ */
diff --git a/firmware/lib20/misc.c b/firmware/lib20/misc.c
new file mode 100644
index 00000000..7fa3787b
--- /dev/null
+++ b/firmware/lib20/misc.c
@@ -0,0 +1,226 @@
+/* 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.
+ *
+ * Misc functions which need access to vb2_context but are not public APIs
+ */
+
+#include "2sysincludes.h"
+#include "2api.h"
+#include "2misc.h"
+#include "2nvstorage.h"
+#include "2secdata.h"
+#include "2sha.h"
+#include "2rsa.h"
+#include "vb2_common.h"
+
+int vb2_load_fw_keyblock(struct vb2_context *ctx)
+{
+ struct vb2_shared_data *sd = vb2_get_sd(ctx);
+ struct vb2_workbuf wb;
+
+ uint8_t *key_data;
+ uint32_t key_size;
+ struct vb2_packed_key *packed_key;
+ struct vb2_public_key root_key;
+
+ struct vb2_keyblock *kb;
+ uint32_t block_size;
+
+ uint32_t sec_version;
+ int rv;
+
+ vb2_workbuf_from_ctx(ctx, &wb);
+
+ /* Read the root key */
+ key_size = sd->gbb_rootkey_size;
+ key_data = vb2_workbuf_alloc(&wb, key_size);
+ if (!key_data)
+ return VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY;
+
+ rv = vb2ex_read_resource(ctx, VB2_RES_GBB, sd->gbb_rootkey_offset,
+ key_data, key_size);
+ if (rv)
+ return rv;
+
+ /* Unpack the root key */
+ rv = vb2_unpack_key(&root_key, key_data, key_size);
+ if (rv)
+ return rv;
+
+ /* Load the firmware keyblock header after the root key */
+ kb = vb2_workbuf_alloc(&wb, sizeof(*kb));
+ if (!kb)
+ return VB2_ERROR_FW_KEYBLOCK_WORKBUF_HEADER;
+
+ rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, sizeof(*kb));
+ if (rv)
+ return rv;
+
+ block_size = kb->keyblock_size;
+
+ /*
+ * Load the entire keyblock, now that we know how big it is. Note that
+ * we're loading the entire keyblock instead of just the piece after
+ * the header. That means we re-read the header. But that's a tiny
+ * amount of data, and it makes the code much more straightforward.
+ */
+ kb = vb2_workbuf_realloc(&wb, sizeof(*kb), block_size);
+ if (!kb)
+ return VB2_ERROR_FW_KEYBLOCK_WORKBUF;
+
+ rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK, 0, kb, block_size);
+ if (rv)
+ return rv;
+
+ /* Verify the keyblock */
+ rv = vb2_verify_keyblock(kb, block_size, &root_key, &wb);
+ if (rv)
+ return rv;
+
+ /* Read the secure key version */
+ rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS, &sec_version);
+ if (rv)
+ return rv;
+
+ /* Key version is the upper 16 bits of the composite firmware version */
+ if (kb->data_key.key_version > 0xffff)
+ return VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE;
+ if (kb->data_key.key_version < (sec_version >> 16))
+ return VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK;
+
+ sd->fw_version = kb->data_key.key_version << 16;
+
+ /*
+ * Save the data key in the work buffer. This overwrites the root key
+ * we read above. That's ok, because now that we have the data key we
+ * no longer need the root key.
+ */
+ packed_key = (struct vb2_packed_key *)key_data;
+
+ packed_key->algorithm = kb->data_key.algorithm;
+ packed_key->key_version = kb->data_key.key_version;
+ packed_key->key_size = kb->data_key.key_size;
+
+ /*
+ * Use memmove() instead of memcpy(). In theory, the destination will
+ * never overlap because with the source because the root key is likely
+ * to be at least as large as the data key, but there's no harm here in
+ * being paranoid.
+ */
+ memmove(key_data + packed_key->key_offset,
+ (uint8_t*)&kb->data_key + kb->data_key.key_offset,
+ packed_key->key_size);
+
+ /* Save the packed key offset and size */
+ sd->workbuf_data_key_offset = vb2_offset_of(ctx->workbuf, key_data);
+ sd->workbuf_data_key_size =
+ packed_key->key_offset + packed_key->key_size;
+
+ /* Preamble follows the keyblock in the vblock */
+ sd->vblock_preamble_offset = kb->keyblock_size;
+
+ /* Data key will persist in the workbuf after we return */
+ ctx->workbuf_used = sd->workbuf_data_key_offset +
+ sd->workbuf_data_key_size;
+
+ return VB2_SUCCESS;
+}
+
+int vb2_load_fw_preamble(struct vb2_context *ctx)
+{
+ struct vb2_shared_data *sd = vb2_get_sd(ctx);
+ struct vb2_workbuf wb;
+
+ uint8_t *key_data = ctx->workbuf + sd->workbuf_data_key_offset;
+ uint32_t key_size = sd->workbuf_data_key_size;
+ struct vb2_public_key data_key;
+
+ /* Preamble goes in the next unused chunk of work buffer */
+ struct vb2_fw_preamble *pre;
+ uint32_t pre_size;
+
+ uint32_t sec_version;
+ int rv;
+
+ vb2_workbuf_from_ctx(ctx, &wb);
+
+ /* Unpack the firmware data key */
+ if (!sd->workbuf_data_key_size)
+ return VB2_ERROR_FW_PREAMBLE2_DATA_KEY;
+
+ rv = vb2_unpack_key(&data_key, key_data, key_size);
+ if (rv)
+ return rv;
+
+ /* Load the firmware preamble header */
+ pre = vb2_workbuf_alloc(&wb, sizeof(*pre));
+ if (!pre)
+ return VB2_ERROR_FW_PREAMBLE2_WORKBUF_HEADER;
+
+ rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
+ sd->vblock_preamble_offset,
+ pre, sizeof(*pre));
+ if (rv)
+ return rv;
+
+ pre_size = pre->preamble_size;
+
+ /* Load the entire firmware preamble, now that we know how big it is */
+ pre = vb2_workbuf_realloc(&wb, sizeof(*pre), pre_size);
+ if (!pre)
+ return VB2_ERROR_FW_PREAMBLE2_WORKBUF;
+
+ rv = vb2ex_read_resource(ctx, VB2_RES_FW_VBLOCK,
+ sd->vblock_preamble_offset,
+ pre, pre_size);
+ if (rv)
+ return rv;
+
+ /* Work buffer now contains the data subkey data and the preamble */
+
+ /* Verify the preamble */
+ rv = vb2_verify_fw_preamble(pre, pre_size, &data_key, &wb);
+ if (rv)
+ return rv;
+
+ /* Read the secure key version */
+ rv = vb2_secdata_get(ctx, VB2_SECDATA_VERSIONS, &sec_version);
+ if (rv)
+ return rv;
+
+ /*
+ * Firmware version is the lower 16 bits of the composite firmware
+ * version.
+ */
+ if (pre->firmware_version > 0xffff)
+ return VB2_ERROR_FW_PREAMBLE2_VERSION_RANGE;
+
+ /* Combine with the key version from vb2_load_fw_keyblock() */
+ sd->fw_version |= pre->firmware_version;
+ if (sd->fw_version < sec_version)
+ return VB2_ERROR_FW_PREAMBLE2_VERSION_ROLLBACK;
+
+ /*
+ * If this is a newer version than in secure storage, and we
+ * successfully booted the same slot last boot, roll forward the
+ * version in secure storage.
+ */
+ if (sd->fw_version > sec_version &&
+ sd->last_fw_slot == sd->fw_slot &&
+ sd->last_fw_result == VB2_FW_RESULT_SUCCESS) {
+
+ rv = vb2_secdata_set(ctx, VB2_SECDATA_VERSIONS, sd->fw_version);
+ if (rv)
+ return rv;
+ }
+
+ /* Keep track of where we put the preamble */
+ sd->workbuf_preamble_offset = vb2_offset_of(ctx->workbuf, pre);
+ sd->workbuf_preamble_size = pre_size;
+
+ /* Preamble will persist in work buffer after we return */
+ ctx->workbuf_used = sd->workbuf_preamble_offset + pre_size;
+
+ return VB2_SUCCESS;
+}
diff --git a/firmware/2lib/2packed_key.c b/firmware/lib20/packed_key.c
index 098296e4..4baf97ce 100644
--- a/firmware/2lib/2packed_key.c
+++ b/firmware/lib20/packed_key.c
@@ -6,8 +6,8 @@
*/
#include "2sysincludes.h"
-#include "2common.h"
#include "2rsa.h"
+#include "vb2_common.h"
const uint8_t *vb2_packed_key_data(const struct vb2_packed_key *key)
{
diff --git a/firmware/lib21/include/vb2_common.h b/firmware/lib21/include/vb2_common.h
index 5abac4c0..db296046 100644
--- a/firmware/lib21/include/vb2_common.h
+++ b/firmware/lib21/include/vb2_common.h
@@ -16,6 +16,96 @@
#include "vb2_struct.h"
/**
+ * Return the description of an object starting with a vb2_struct_common header.
+ *
+ * Does not sanity-check the buffer; merely returns the pointer.
+ *
+ * @param buf Pointer to common object
+ * @return A pointer to description or an empty string if none.
+ */
+const char *vb2_common_desc(const void *buf);
+
+/**
+ * Verify the common struct header is fully contained in its parent data
+ *
+ * Also verifies the description is either zero-length or null-terminated.
+ *
+ * @param parent Parent data
+ * @param parent_size Parent size in bytes
+ * @return VB2_SUCCESS, or non-zero if error.
+ */
+int vb2_verify_common_header(const void *parent, uint32_t parent_size);
+
+/**
+ * Verify a member is within the data for a parent object
+ *
+ * @param parent Parent data (starts with struct vb2_struct_common)
+ * @param min_offset Pointer to minimum offset where member can be located.
+ * If this offset is 0 on input, uses the size of the
+ * fixed header (and description, if any). This will be
+ * updated on return to the end of the passed member. On
+ * error, the value of min_offset is undefined.
+ * @param member_offset Offset of member data from start of parent, in bytes
+ * @param member_size Size of member data, in bytes
+ * @return VB2_SUCCESS, or non-zero if error.
+ */
+int vb2_verify_common_member(const void *parent,
+ uint32_t *min_offset,
+ uint32_t member_offset,
+ uint32_t member_size);
+
+/**
+ * Verify a member which starts with a common header is within the parent
+ *
+ * This does not verify the contents of the member or its header, only that the
+ * member's claimed total size fits within the parent's claimed total size at
+ * the specified offset.
+ *
+ * @param parent Parent data (starts with struct vb2_struct_common)
+ * @param min_offset Pointer to minimum offset where member can be located.
+ * If this offset is 0 on input, uses the size of the
+ * fixed header (and description, if any). This will be
+ * updated on return to the end of the passed member. On
+ * error, the value of min_offset is undefined.
+ * @param member_offset Offset of member data from start of parent, in bytes.
+ * This should be the start of the common header of the
+ * member.
+ * @return VB2_SUCCESS, or non-zero if error.
+ */
+int vb2_verify_common_subobject(const void *parent,
+ uint32_t *min_offset,
+ uint32_t member_offset);
+
+/**
+ * Unpack a key for use in verification
+ *
+ * The elements of the unpacked key will point into the source buffer, so don't
+ * free the source buffer until you're done with the key.
+ *
+ * @param key Destintion for unpacked key
+ * @param buf Source buffer containing packed key
+ * @param size Size of buffer in bytes
+ * @return VB2_SUCCESS, or non-zero error code if error.
+ */
+int vb2_unpack_key2(struct vb2_public_key *key,
+ const uint8_t *buf,
+ uint32_t size);
+
+/**
+ * Unpack the RSA data fields for a public key
+ *
+ * This is called by vb2_unpack_key2() to extract the arrays from a packed key.
+ * These elements of *key will point inside the key_data buffer.
+ *
+ * @param key Destination key for RSA data fields
+ * @param key_data Packed key data (from inside a packed key buffer)
+ * @param key_size Size of packed key data in bytes
+ */
+int vb2_unpack_key2_data(struct vb2_public_key *key,
+ const uint8_t *key_data,
+ uint32_t key_size);
+
+/**
* Verify the integrity of a signature struct
* @param sig Signature struct
* @param size Size of buffer containing signature struct
diff --git a/tests/vb20_api_tests.c b/tests/vb20_api_tests.c
new file mode 100644
index 00000000..a7be957f
--- /dev/null
+++ b/tests/vb20_api_tests.c
@@ -0,0 +1,346 @@
+/* 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 "2sysincludes.h"
+#include "2api.h"
+#include "2misc.h"
+#include "2nvstorage.h"
+#include "2rsa.h"
+#include "2secdata.h"
+#include "vb2_common.h"
+#include "test_common.h"
+
+/* Common context for tests */
+static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]
+ __attribute__ ((aligned (16)));
+static struct vb2_context cc;
+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;
+
+/* Mocked function data */
+
+static int retval_vb2_load_fw_keyblock;
+static int retval_vb2_load_fw_preamble;
+static int retval_vb2_digest_finalize;
+static int 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(&cc, 0, sizeof(cc));
+ cc.workbuf = workbuf;
+ cc.workbuf_size = sizeof(workbuf);
+
+ vb2_init_context(&cc);
+ sd = vb2_get_sd(&cc);
+
+ vb2_nv_init(&cc);
+
+ vb2_secdata_create(&cc);
+ vb2_secdata_init(&cc);
+
+ 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->workbuf_preamble_offset = cc.workbuf_used;
+ sd->workbuf_preamble_size = sizeof(*pre);
+ cc.workbuf_used = sd->workbuf_preamble_offset
+ + sd->workbuf_preamble_size;
+ pre = (struct vb2_fw_preamble *)
+ (cc.workbuf + sd->workbuf_preamble_offset);
+ pre->body_signature.data_size = mock_body_size;
+ pre->body_signature.sig_size = mock_sig_size;
+
+ sd->workbuf_data_key_offset = cc.workbuf_used;
+ sd->workbuf_data_key_size = sizeof(*k) + 8;
+ cc.workbuf_used = sd->workbuf_data_key_offset +
+ sd->workbuf_data_key_size;
+ k = (struct vb2_packed_key *)
+ (cc.workbuf + sd->workbuf_data_key_offset);
+ k->algorithm = mock_algorithm;
+
+ if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH)
+ vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL);
+
+ if (t == FOR_CHECK_HASH)
+ vb2api_extend_hash(&cc, mock_body, mock_body_size);
+};
+
+/* Mocked functions */
+
+int vb2_load_fw_keyblock(struct vb2_context *ctx)
+{
+ return retval_vb2_load_fw_keyblock;
+}
+
+int vb2_load_fw_preamble(struct vb2_context *ctx)
+{
+ return retval_vb2_load_fw_preamble;
+}
+
+int vb2_unpack_key(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;
+}
+
+int vb2_digest_init(struct vb2_digest_context *dc,
+ enum vb2_hash_algorithm hash_alg)
+{
+ if (hash_alg != mock_hash_alg)
+ return VB2_ERROR_SHA_INIT_ALGORITHM;
+
+ dc->hash_alg = hash_alg;
+
+ return VB2_SUCCESS;
+}
+
+int vb2_digest_extend(struct vb2_digest_context *dc,
+ const uint8_t *buf,
+ uint32_t size)
+{
+ if (dc->hash_alg != mock_hash_alg)
+ return VB2_ERROR_SHA_EXTEND_ALGORITHM;
+
+ return VB2_SUCCESS;
+}
+
+int vb2_digest_finalize(struct vb2_digest_context *dc,
+ uint8_t *digest,
+ uint32_t digest_size)
+{
+ return retval_vb2_digest_finalize;
+}
+
+uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
+{
+ return mock_sig_size;
+}
+
+int 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(&cc), "phase3 good");
+
+ reset_common_data(FOR_MISC);
+ retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK;
+ TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
+ TEST_EQ(vb2_nv_get(&cc, 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(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
+ TEST_EQ(vb2_nv_get(&cc, 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 = cc.workbuf_used;
+ TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
+ "init hash good");
+ TEST_EQ(sd->workbuf_hash_offset,
+ (wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
+ ~(VB2_WORKBUF_ALIGN - 1),
+ "hash context offset");
+ TEST_EQ(sd->workbuf_hash_size, sizeof(struct vb2_digest_context),
+ "hash context size");
+ TEST_EQ(cc.workbuf_used,
+ sd->workbuf_hash_offset + sd->workbuf_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 = cc.workbuf_used;
+ TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL),
+ "init hash again");
+ TEST_EQ(cc.workbuf_used, wb_used_before, "init hash reuses context");
+
+ reset_common_data(FOR_MISC);
+ TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_INVALID, &size),
+ VB2_ERROR_API_INIT_HASH_TAG, "init hash invalid tag");
+
+ reset_common_data(FOR_MISC);
+ sd->workbuf_preamble_size = 0;
+ TEST_EQ(vb2api_init_hash(&cc, 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(&cc, VB2_HASH_TAG_FW_BODY + 1, &size),
+ VB2_ERROR_API_INIT_HASH_TAG, "init hash unknown tag");
+
+ reset_common_data(FOR_MISC);
+ cc.workbuf_used =
+ cc.workbuf_size - sizeof(struct vb2_digest_context) + 8;
+ TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
+ VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf");
+
+ reset_common_data(FOR_MISC);
+ sd->workbuf_data_key_size = 0;
+ TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
+ VB2_ERROR_API_INIT_HASH_DATA_KEY, "init hash data key");
+
+ reset_common_data(FOR_MISC);
+ sd->workbuf_data_key_size--;
+ TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
+ VB2_ERROR_UNPACK_KEY_SIZE, "init hash data key size");
+
+ reset_common_data(FOR_MISC);
+ k = (struct vb2_packed_key *)(cc.workbuf + sd->workbuf_data_key_offset);
+ k->algorithm--;
+ TEST_EQ(vb2api_init_hash(&cc, 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(&cc, mock_body, 32),
+ "hash extend good");
+ TEST_EQ(sd->hash_remaining_size, mock_body_size - 32,
+ "hash extend remaining");
+ TEST_SUCC(vb2api_extend_hash(&cc, 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->workbuf_hash_size = 0;
+ TEST_EQ(vb2api_extend_hash(&cc, 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(&cc, 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(&cc, mock_body, 0),
+ VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");
+
+ reset_common_data(FOR_EXTEND_HASH);
+ dc = (struct vb2_digest_context *)
+ (cc.workbuf + sd->workbuf_hash_offset);
+ dc->hash_alg = mock_hash_alg + 1;
+ TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
+ VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
+}
+
+static void check_hash_tests(void)
+{
+ struct vb2_fw_preamble *pre;
+
+ reset_common_data(FOR_CHECK_HASH);
+ TEST_SUCC(vb2api_check_hash(&cc), "check hash good");
+
+ reset_common_data(FOR_CHECK_HASH);
+ sd->workbuf_preamble_size = 0;
+ TEST_EQ(vb2api_check_hash(&cc),
+ VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble");
+
+ reset_common_data(FOR_CHECK_HASH);
+ sd->workbuf_hash_size = 0;
+ TEST_EQ(vb2api_check_hash(&cc),
+ 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(&cc),
+ VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size");
+
+ reset_common_data(FOR_CHECK_HASH);
+ cc.workbuf_used = cc.workbuf_size;
+ TEST_EQ(vb2api_check_hash(&cc),
+ 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(&cc), VB2_ERROR_MOCK, "check hash finalize");
+
+ reset_common_data(FOR_CHECK_HASH);
+ sd->hash_tag = VB2_HASH_TAG_INVALID;
+ TEST_EQ(vb2api_check_hash(&cc),
+ VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag");
+
+ reset_common_data(FOR_CHECK_HASH);
+ sd->workbuf_data_key_size = 0;
+ TEST_EQ(vb2api_check_hash(&cc),
+ VB2_ERROR_API_CHECK_HASH_DATA_KEY, "check hash data key");
+
+ reset_common_data(FOR_CHECK_HASH);
+ sd->workbuf_data_key_size--;
+ TEST_EQ(vb2api_check_hash(&cc),
+ VB2_ERROR_UNPACK_KEY_SIZE, "check hash data key size");
+
+ reset_common_data(FOR_CHECK_HASH);
+ pre = (struct vb2_fw_preamble *)
+ (cc.workbuf + sd->workbuf_preamble_offset);
+ pre->body_signature.sig_size++;
+ TEST_EQ(vb2api_check_hash(&cc),
+ 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(&cc),
+ VB2_ERROR_RSA_VERIFY_DIGEST, "check hash finalize");
+}
+
+int main(int argc, char* argv[])
+{
+ phase3_tests();
+ init_hash_tests();
+ extend_hash_tests();
+ check_hash_tests();
+
+ return gTestSuccess ? 0 : 255;
+}
diff --git a/tests/vb2_common2_tests.c b/tests/vb20_common2_tests.c
index ec9ef183..75e05249 100644
--- a/tests/vb2_common2_tests.c
+++ b/tests/vb20_common2_tests.c
@@ -10,10 +10,10 @@
#include <string.h>
#include "2sysincludes.h"
-#include "2common.h"
#include "2rsa.h"
#include "file_keys.h"
#include "host_common.h"
+#include "vb2_common.h"
#include "vboot_common.h"
#include "test_common.h"
diff --git a/tests/vb2_common3_tests.c b/tests/vb20_common3_tests.c
index 61484fb5..365c7700 100644
--- a/tests/vb2_common3_tests.c
+++ b/tests/vb20_common3_tests.c
@@ -8,7 +8,6 @@
#include <stdio.h>
#include "2sysincludes.h"
-#include "2common.h"
#include "2rsa.h"
#include "file_keys.h"
@@ -16,6 +15,7 @@
#include "host_key.h"
#include "host_keyblock.h"
#include "host_signature.h"
+#include "vb2_common.h"
#include "vboot_common.h"
#include "test_common.h"
diff --git a/tests/vb20_common_tests.c b/tests/vb20_common_tests.c
new file mode 100644
index 00000000..4f4d6813
--- /dev/null
+++ b/tests/vb20_common_tests.c
@@ -0,0 +1,174 @@
+/* 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 firmware 2common.c
+ */
+
+#include "2sysincludes.h"
+#include "vb2_common.h"
+#include "vboot_struct.h" /* For old struct sizes */
+#include "test_common.h"
+
+/*
+ * Test struct packing for vboot_struct.h structs which are passed between
+ * firmware and OS, or passed between different phases of firmware.
+ */
+static void test_struct_packing(void)
+{
+ /* Test vboot2 versions of vboot1 structs */
+ TEST_EQ(EXPECTED_VB2_PACKED_KEY_SIZE,
+ sizeof(struct vb2_packed_key),
+ "sizeof(vb2_packed_key)");
+ TEST_EQ(EXPECTED_VB2_SIGNATURE_SIZE,
+ sizeof(struct vb2_signature),
+ "sizeof(vb2_signature)");
+ TEST_EQ(EXPECTED_VB2_KEYBLOCK_SIZE,
+ sizeof(struct vb2_keyblock),
+ "sizeof(vb2_keyblock)");
+ TEST_EQ(EXPECTED_VB2_FW_PREAMBLE_SIZE,
+ sizeof(struct vb2_fw_preamble),
+ "sizeof(vb2_fw_preamble)");
+ TEST_EQ(EXPECTED_VB2_GBB_HEADER_SIZE,
+ sizeof(struct vb2_gbb_header),
+ "sizeof(vb2_gbb_header)");
+
+ /* And make sure they're the same as their vboot1 equivalents */
+ TEST_EQ(EXPECTED_VB2_PACKED_KEY_SIZE,
+ EXPECTED_VBPUBLICKEY_SIZE,
+ "vboot1->2 packed key sizes same");
+ TEST_EQ(EXPECTED_VB2_SIGNATURE_SIZE,
+ EXPECTED_VBSIGNATURE_SIZE,
+ "vboot1->2 signature sizes same");
+ TEST_EQ(EXPECTED_VB2_KEYBLOCK_SIZE,
+ EXPECTED_VBKEYBLOCKHEADER_SIZE,
+ "vboot1->2 keyblock sizes same");
+ TEST_EQ(EXPECTED_VB2_FW_PREAMBLE_SIZE,
+ EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE,
+ "vboot1->2 firmware preamble sizes same");
+}
+
+/**
+ * Helper functions not dependent on specific key sizes
+ */
+static void test_helper_functions(void)
+{
+ {
+ uint8_t *p = (uint8_t *)test_helper_functions;
+ TEST_EQ((int)vb2_offset_of(p, p), 0, "vb2_offset_of() equal");
+ TEST_EQ((int)vb2_offset_of(p, p+10), 10,
+ "vb2_offset_of() positive");
+ }
+
+ {
+ struct vb2_packed_key k = {.key_offset = sizeof(k)};
+ TEST_EQ((int)vb2_offset_of(&k, vb2_packed_key_data(&k)),
+ sizeof(k), "vb2_packed_key_data() adjacent");
+ }
+
+ {
+ struct vb2_packed_key k = {.key_offset = 123};
+ TEST_EQ((int)vb2_offset_of(&k, vb2_packed_key_data(&k)), 123,
+ "vb2_packed_key_data() spaced");
+ }
+
+ {
+ struct vb2_signature s = {.sig_offset = sizeof(s)};
+ TEST_EQ((int)vb2_offset_of(&s, vb2_signature_data(&s)),
+ sizeof(s), "vb2_signature_data() adjacent");
+ }
+
+ {
+ struct vb2_signature s = {.sig_offset = 123};
+ TEST_EQ((int)vb2_offset_of(&s, vb2_signature_data(&s)), 123,
+ "vb2_signature_data() spaced");
+ }
+
+ {
+ uint8_t *p = (uint8_t *)test_helper_functions;
+ TEST_SUCC(vb2_verify_member_inside(p, 20, p, 6, 11, 3),
+ "MemberInside ok 1");
+ TEST_SUCC(vb2_verify_member_inside(p, 20, p+4, 4, 8, 4),
+ "MemberInside ok 2");
+ TEST_EQ(vb2_verify_member_inside(p, 20, p-4, 4, 8, 4),
+ VB2_ERROR_INSIDE_MEMBER_OUTSIDE,
+ "MemberInside member before parent");
+ TEST_EQ(vb2_verify_member_inside(p, 20, p+20, 4, 8, 4),
+ VB2_ERROR_INSIDE_MEMBER_OUTSIDE,
+ "MemberInside member after parent");
+ TEST_EQ(vb2_verify_member_inside(p, 20, p, 21, 0, 0),
+ VB2_ERROR_INSIDE_MEMBER_OUTSIDE,
+ "MemberInside member too big");
+ TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, 21, 0),
+ VB2_ERROR_INSIDE_DATA_OUTSIDE,
+ "MemberInside data after parent");
+ TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, SIZE_MAX, 0),
+ VB2_ERROR_INSIDE_DATA_OUTSIDE,
+ "MemberInside data before parent");
+ TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, 4, 17),
+ VB2_ERROR_INSIDE_DATA_OUTSIDE,
+ "MemberInside data too big");
+ TEST_EQ(vb2_verify_member_inside(p, 20, p, 8, 4, 8),
+ VB2_ERROR_INSIDE_DATA_OVERLAP,
+ "MemberInside data overlaps member");
+ TEST_EQ(vb2_verify_member_inside(p, -8, p, 12, 0, 0),
+ VB2_ERROR_INSIDE_PARENT_WRAPS,
+ "MemberInside wraparound 1");
+ TEST_EQ(vb2_verify_member_inside(p, 20, p, -8, 0, 0),
+ VB2_ERROR_INSIDE_MEMBER_WRAPS,
+ "MemberInside wraparound 2");
+ TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, 4, -12),
+ VB2_ERROR_INSIDE_DATA_WRAPS,
+ "MemberInside wraparound 3");
+ }
+
+ {
+ struct vb2_packed_key k = {.key_offset = sizeof(k),
+ .key_size = 128};
+ TEST_SUCC(vb2_verify_packed_key_inside(&k, sizeof(k)+128, &k),
+ "PublicKeyInside ok 1");
+ TEST_SUCC(vb2_verify_packed_key_inside(&k - 1,
+ 2*sizeof(k)+128, &k),
+ "PublicKeyInside ok 2");
+ TEST_EQ(vb2_verify_packed_key_inside(&k, 128, &k),
+ VB2_ERROR_INSIDE_DATA_OUTSIDE,
+ "PublicKeyInside key too big");
+ }
+
+ {
+ struct vb2_packed_key k = {.key_offset = 100,
+ .key_size = 4};
+ TEST_EQ(vb2_verify_packed_key_inside(&k, 99, &k),
+ VB2_ERROR_INSIDE_DATA_OUTSIDE,
+ "PublicKeyInside offset too big");
+ }
+
+ {
+ struct vb2_signature s = {.sig_offset = sizeof(s),
+ .sig_size = 128};
+ TEST_SUCC(vb2_verify_signature_inside(&s, sizeof(s)+128, &s),
+ "SignatureInside ok 1");
+ TEST_SUCC(vb2_verify_signature_inside(&s - 1,
+ 2*sizeof(s)+128, &s),
+ "SignatureInside ok 2");
+ TEST_EQ(vb2_verify_signature_inside(&s, 128, &s),
+ VB2_ERROR_INSIDE_DATA_OUTSIDE,
+ "SignatureInside sig too big");
+ }
+
+ {
+ struct vb2_signature s = {.sig_offset = 100,
+ .sig_size = 4};
+ TEST_EQ(vb2_verify_signature_inside(&s, 99, &s),
+ VB2_ERROR_INSIDE_DATA_OUTSIDE,
+ "SignatureInside offset too big");
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ test_struct_packing();
+ test_helper_functions();
+
+ return gTestSuccess ? 0 : 255;
+}
diff --git a/tests/vb2_misc2_tests.c b/tests/vb20_misc_tests.c
index 796d8e6a..aa602ac9 100644
--- a/tests/vb2_misc2_tests.c
+++ b/tests/vb20_misc_tests.c
@@ -13,7 +13,7 @@
#include "2misc.h"
#include "2nvstorage.h"
#include "2secdata.h"
-
+#include "vb2_common.h"
#include "test_common.h"
/* Common context for tests */
diff --git a/tests/vb2_rsa_padding_tests.c b/tests/vb20_rsa_padding_tests.c
index 8c9e80b6..e9789e90 100644
--- a/tests/vb2_rsa_padding_tests.c
+++ b/tests/vb20_rsa_padding_tests.c
@@ -14,8 +14,8 @@
#include "utility.h"
#include "2sysincludes.h"
-#include "2common.h"
#include "2rsa.h"
+#include "vb2_common.h"
/**
* Convert an old-style RSA public key struct to a new one.
diff --git a/tests/vb21_api_tests.c b/tests/vb21_api_tests.c
index 052d89b6..52ca0d9e 100644
--- a/tests/vb21_api_tests.c
+++ b/tests/vb21_api_tests.c
@@ -30,7 +30,6 @@ static struct vb2_shared_data *sd;
static const uint8_t mock_body[320] = "Mock body";
static const int mock_body_size = sizeof(mock_body);
-static const int mock_algorithm = VB2_ALG_RSA2048_SHA256;
static const int mock_hash_alg = VB2_HASH_SHA256;
static int mock_sig_size;
@@ -198,6 +197,40 @@ static void init_hash_tests(void)
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->workbuf_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");
+
+ reset_common_data(FOR_EXTEND_HASH);
+ dc = (struct vb2_digest_context *)
+ (ctx.workbuf + sd->workbuf_hash_offset);
+ dc->hash_alg = VB2_HASH_INVALID;
+ 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_preamble2 *pre;
@@ -249,6 +282,7 @@ int main(int argc, char* argv[])
{
phase3_tests();
init_hash_tests();
+ extend_hash_tests();
check_hash_tests();
return gTestSuccess ? 0 : 255;
diff --git a/tests/vb21_misc_tests.c b/tests/vb21_misc_tests.c
index 9f6489fc..03b8e4fb 100644
--- a/tests/vb21_misc_tests.c
+++ b/tests/vb21_misc_tests.c
@@ -245,7 +245,7 @@ static void load_keyblock_tests(void)
reset_common_data(FOR_KEYBLOCK);
ctx.workbuf_used = ctx.workbuf_size - sd->gbb_rootkey_size
- - sizeof(struct vb2_keyblock);
+ - sizeof(struct vb2_keyblock2);
TEST_EQ(vb2_load_fw_keyblock2(&ctx),
VB2_ERROR_READ_RESOURCE_OBJECT_BUF,
"keyblock not enough workbuf for entire keyblock");
@@ -310,7 +310,7 @@ static void load_preamble_tests(void)
reset_common_data(FOR_PREAMBLE);
ctx.workbuf_used = ctx.workbuf_size
- - sizeof(struct vb2_fw_preamble) + 8;
+ - sizeof(struct vb2_fw_preamble2) + 8;
TEST_EQ(vb2_load_fw_preamble2(&ctx),
VB2_ERROR_READ_RESOURCE_OBJECT_BUF,
"preamble not enough workbuf for header");
diff --git a/tests/vb2_api_tests.c b/tests/vb2_api_tests.c
index a7893012..ddbd8164 100644
--- a/tests/vb2_api_tests.c
+++ b/tests/vb2_api_tests.c
@@ -14,7 +14,6 @@
#include "2nvstorage.h"
#include "2rsa.h"
#include "2secdata.h"
-
#include "test_common.h"
/* Common context for tests */
@@ -27,7 +26,6 @@ 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;
/* Mocked function data */
@@ -35,23 +33,14 @@ static int retval_vb2_fw_parse_gbb;
static int retval_vb2_check_dev_switch;
static int retval_vb2_check_tpm_clear;
static int retval_vb2_select_fw_slot;
-static int retval_vb2_load_fw_keyblock;
-static int retval_vb2_load_fw_preamble;
-static int retval_vb2_digest_finalize;
-static int 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(&cc, 0, sizeof(cc));
@@ -70,33 +59,6 @@ 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;
-
- sd->workbuf_preamble_offset = cc.workbuf_used;
- sd->workbuf_preamble_size = sizeof(*pre);
- cc.workbuf_used = sd->workbuf_preamble_offset
- + sd->workbuf_preamble_size;
- pre = (struct vb2_fw_preamble *)
- (cc.workbuf + sd->workbuf_preamble_offset);
- pre->body_signature.data_size = mock_body_size;
- pre->body_signature.sig_size = mock_sig_size;
-
- sd->workbuf_data_key_offset = cc.workbuf_used;
- sd->workbuf_data_key_size = sizeof(*k) + 8;
- cc.workbuf_used = sd->workbuf_data_key_offset +
- sd->workbuf_data_key_size;
- k = (struct vb2_packed_key *)
- (cc.workbuf + sd->workbuf_data_key_offset);
- k->algorithm = mock_algorithm;
-
- if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH)
- vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL);
-
- if (t == FOR_CHECK_HASH)
- vb2api_extend_hash(&cc, mock_body, mock_body_size);
};
/* Mocked functions */
@@ -121,72 +83,6 @@ int vb2_select_fw_slot(struct vb2_context *ctx)
return retval_vb2_select_fw_slot;
}
-int vb2_load_fw_keyblock(struct vb2_context *ctx)
-{
- return retval_vb2_load_fw_keyblock;
-}
-
-int vb2_load_fw_preamble(struct vb2_context *ctx)
-{
- return retval_vb2_load_fw_preamble;
-}
-
-int vb2_unpack_key(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;
-}
-
-int vb2_digest_init(struct vb2_digest_context *dc,
- enum vb2_hash_algorithm hash_alg)
-{
- if (hash_alg != mock_hash_alg)
- return VB2_ERROR_SHA_INIT_ALGORITHM;
-
- dc->hash_alg = hash_alg;
-
- return VB2_SUCCESS;
-}
-
-int vb2_digest_extend(struct vb2_digest_context *dc,
- const uint8_t *buf,
- uint32_t size)
-{
- if (dc->hash_alg != mock_hash_alg)
- return VB2_ERROR_SHA_EXTEND_ALGORITHM;
-
- return VB2_SUCCESS;
-}
-
-int vb2_digest_finalize(struct vb2_digest_context *dc,
- uint8_t *digest,
- uint32_t digest_size)
-{
- return retval_vb2_digest_finalize;
-}
-
-uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
-{
- return mock_sig_size;
-}
-
-int 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)
@@ -270,190 +166,11 @@ static void phase2_tests(void)
VB2_RECOVERY_FW_SLOT, " recovery reason");
}
-static void phase3_tests(void)
-{
- reset_common_data(FOR_MISC);
- TEST_SUCC(vb2api_fw_phase3(&cc), "phase3 good");
-
- reset_common_data(FOR_MISC);
- retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK;
- TEST_EQ(vb2api_fw_phase3(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
- TEST_EQ(vb2_nv_get(&cc, 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(&cc), VB2_ERROR_MOCK, "phase3 keyblock");
- TEST_EQ(vb2_nv_get(&cc, 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 = cc.workbuf_used;
- TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
- "init hash good");
- TEST_EQ(sd->workbuf_hash_offset,
- (wb_used_before + (VB2_WORKBUF_ALIGN - 1)) &
- ~(VB2_WORKBUF_ALIGN - 1),
- "hash context offset");
- TEST_EQ(sd->workbuf_hash_size, sizeof(struct vb2_digest_context),
- "hash context size");
- TEST_EQ(cc.workbuf_used,
- sd->workbuf_hash_offset + sd->workbuf_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 = cc.workbuf_used;
- TEST_SUCC(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, NULL),
- "init hash again");
- TEST_EQ(cc.workbuf_used, wb_used_before, "init hash reuses context");
-
- reset_common_data(FOR_MISC);
- TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_INVALID, &size),
- VB2_ERROR_API_INIT_HASH_TAG, "init hash invalid tag");
-
- reset_common_data(FOR_MISC);
- sd->workbuf_preamble_size = 0;
- TEST_EQ(vb2api_init_hash(&cc, 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(&cc, VB2_HASH_TAG_FW_BODY + 1, &size),
- VB2_ERROR_API_INIT_HASH_TAG, "init hash unknown tag");
-
- reset_common_data(FOR_MISC);
- cc.workbuf_used =
- cc.workbuf_size - sizeof(struct vb2_digest_context) + 8;
- TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
- VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf");
-
- reset_common_data(FOR_MISC);
- sd->workbuf_data_key_size = 0;
- TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
- VB2_ERROR_API_INIT_HASH_DATA_KEY, "init hash data key");
-
- reset_common_data(FOR_MISC);
- sd->workbuf_data_key_size--;
- TEST_EQ(vb2api_init_hash(&cc, VB2_HASH_TAG_FW_BODY, &size),
- VB2_ERROR_UNPACK_KEY_SIZE, "init hash data key size");
-
- reset_common_data(FOR_MISC);
- k = (struct vb2_packed_key *)(cc.workbuf + sd->workbuf_data_key_offset);
- k->algorithm--;
- TEST_EQ(vb2api_init_hash(&cc, 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(&cc, mock_body, 32),
- "hash extend good");
- TEST_EQ(sd->hash_remaining_size, mock_body_size - 32,
- "hash extend remaining");
- TEST_SUCC(vb2api_extend_hash(&cc, 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->workbuf_hash_size = 0;
- TEST_EQ(vb2api_extend_hash(&cc, 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(&cc, 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(&cc, mock_body, 0),
- VB2_ERROR_API_EXTEND_HASH_SIZE, "hash extend empty");
-
- reset_common_data(FOR_EXTEND_HASH);
- dc = (struct vb2_digest_context *)
- (cc.workbuf + sd->workbuf_hash_offset);
- dc->hash_alg = mock_hash_alg + 1;
- TEST_EQ(vb2api_extend_hash(&cc, mock_body, mock_body_size),
- VB2_ERROR_SHA_EXTEND_ALGORITHM, "hash extend fail");
-}
-
-static void check_hash_tests(void)
-{
- struct vb2_fw_preamble *pre;
-
- reset_common_data(FOR_CHECK_HASH);
- TEST_SUCC(vb2api_check_hash(&cc), "check hash good");
-
- reset_common_data(FOR_CHECK_HASH);
- sd->workbuf_preamble_size = 0;
- TEST_EQ(vb2api_check_hash(&cc),
- VB2_ERROR_API_CHECK_HASH_PREAMBLE, "check hash preamble");
-
- reset_common_data(FOR_CHECK_HASH);
- sd->workbuf_hash_size = 0;
- TEST_EQ(vb2api_check_hash(&cc),
- 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(&cc),
- VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size");
-
- reset_common_data(FOR_CHECK_HASH);
- cc.workbuf_used = cc.workbuf_size;
- TEST_EQ(vb2api_check_hash(&cc),
- 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(&cc), VB2_ERROR_MOCK, "check hash finalize");
-
- reset_common_data(FOR_CHECK_HASH);
- sd->hash_tag = VB2_HASH_TAG_INVALID;
- TEST_EQ(vb2api_check_hash(&cc),
- VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag");
-
- reset_common_data(FOR_CHECK_HASH);
- sd->workbuf_data_key_size = 0;
- TEST_EQ(vb2api_check_hash(&cc),
- VB2_ERROR_API_CHECK_HASH_DATA_KEY, "check hash data key");
-
- reset_common_data(FOR_CHECK_HASH);
- sd->workbuf_data_key_size--;
- TEST_EQ(vb2api_check_hash(&cc),
- VB2_ERROR_UNPACK_KEY_SIZE, "check hash data key size");
-
- reset_common_data(FOR_CHECK_HASH);
- pre = (struct vb2_fw_preamble *)
- (cc.workbuf + sd->workbuf_preamble_offset);
- pre->body_signature.sig_size++;
- TEST_EQ(vb2api_check_hash(&cc),
- 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(&cc),
- VB2_ERROR_RSA_VERIFY_DIGEST, "check hash finalize");
-}
-
int main(int argc, char* argv[])
{
misc_tests();
phase1_tests();
phase2_tests();
- phase3_tests();
- init_hash_tests();
- extend_hash_tests();
- check_hash_tests();
return gTestSuccess ? 0 : 255;
}
diff --git a/tests/vb2_common_tests.c b/tests/vb2_common_tests.c
index f8502957..4c033fbd 100644
--- a/tests/vb2_common_tests.c
+++ b/tests/vb2_common_tests.c
@@ -7,9 +7,6 @@
#include "2sysincludes.h"
#include "2common.h"
-#include "2rsa.h"
-#include "vboot_struct.h" /* For old struct sizes */
-
#include "test_common.h"
/**
@@ -108,168 +105,11 @@ static void test_workbuf(void)
TEST_EQ(wb.size, 8, " size");
}
-/*
- * Test struct packing for vboot_struct.h structs which are passed between
- * firmware and OS, or passed between different phases of firmware.
- */
-static void test_struct_packing(void)
-{
- /* Test vboot2 versions of vboot1 structs */
- TEST_EQ(EXPECTED_VB2_PACKED_KEY_SIZE,
- sizeof(struct vb2_packed_key),
- "sizeof(vb2_packed_key)");
- TEST_EQ(EXPECTED_VB2_SIGNATURE_SIZE,
- sizeof(struct vb2_signature),
- "sizeof(vb2_signature)");
- TEST_EQ(EXPECTED_VB2_KEYBLOCK_SIZE,
- sizeof(struct vb2_keyblock),
- "sizeof(vb2_keyblock)");
- TEST_EQ(EXPECTED_VB2_FW_PREAMBLE_SIZE,
- sizeof(struct vb2_fw_preamble),
- "sizeof(vb2_fw_preamble)");
- TEST_EQ(EXPECTED_VB2_GBB_HEADER_SIZE,
- sizeof(struct vb2_gbb_header),
- "sizeof(vb2_gbb_header)");
-
- /* And make sure they're the same as their vboot1 equivalents */
- TEST_EQ(EXPECTED_VB2_PACKED_KEY_SIZE,
- EXPECTED_VBPUBLICKEY_SIZE,
- "vboot1->2 packed key sizes same");
- TEST_EQ(EXPECTED_VB2_SIGNATURE_SIZE,
- EXPECTED_VBSIGNATURE_SIZE,
- "vboot1->2 signature sizes same");
- TEST_EQ(EXPECTED_VB2_KEYBLOCK_SIZE,
- EXPECTED_VBKEYBLOCKHEADER_SIZE,
- "vboot1->2 keyblock sizes same");
- TEST_EQ(EXPECTED_VB2_FW_PREAMBLE_SIZE,
- EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE,
- "vboot1->2 firmware preamble sizes same");
-}
-
-/**
- * Helper functions not dependent on specific key sizes
- */
-static void test_helper_functions(void)
-{
- {
- uint8_t *p = (uint8_t *)test_helper_functions;
- TEST_EQ((int)vb2_offset_of(p, p), 0, "vb2_offset_of() equal");
- TEST_EQ((int)vb2_offset_of(p, p+10), 10,
- "vb2_offset_of() positive");
- }
-
- {
- struct vb2_packed_key k = {.key_offset = sizeof(k)};
- TEST_EQ((int)vb2_offset_of(&k, vb2_packed_key_data(&k)),
- sizeof(k), "vb2_packed_key_data() adjacent");
- }
-
- {
- struct vb2_packed_key k = {.key_offset = 123};
- TEST_EQ((int)vb2_offset_of(&k, vb2_packed_key_data(&k)), 123,
- "vb2_packed_key_data() spaced");
- }
-
- {
- struct vb2_signature s = {.sig_offset = sizeof(s)};
- TEST_EQ((int)vb2_offset_of(&s, vb2_signature_data(&s)),
- sizeof(s), "vb2_signature_data() adjacent");
- }
-
- {
- struct vb2_signature s = {.sig_offset = 123};
- TEST_EQ((int)vb2_offset_of(&s, vb2_signature_data(&s)), 123,
- "vb2_signature_data() spaced");
- }
-
- {
- uint8_t *p = (uint8_t *)test_helper_functions;
- TEST_SUCC(vb2_verify_member_inside(p, 20, p, 6, 11, 3),
- "MemberInside ok 1");
- TEST_SUCC(vb2_verify_member_inside(p, 20, p+4, 4, 8, 4),
- "MemberInside ok 2");
- TEST_EQ(vb2_verify_member_inside(p, 20, p-4, 4, 8, 4),
- VB2_ERROR_INSIDE_MEMBER_OUTSIDE,
- "MemberInside member before parent");
- TEST_EQ(vb2_verify_member_inside(p, 20, p+20, 4, 8, 4),
- VB2_ERROR_INSIDE_MEMBER_OUTSIDE,
- "MemberInside member after parent");
- TEST_EQ(vb2_verify_member_inside(p, 20, p, 21, 0, 0),
- VB2_ERROR_INSIDE_MEMBER_OUTSIDE,
- "MemberInside member too big");
- TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, 21, 0),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
- "MemberInside data after parent");
- TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, SIZE_MAX, 0),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
- "MemberInside data before parent");
- TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, 4, 17),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
- "MemberInside data too big");
- TEST_EQ(vb2_verify_member_inside(p, 20, p, 8, 4, 8),
- VB2_ERROR_INSIDE_DATA_OVERLAP,
- "MemberInside data overlaps member");
- TEST_EQ(vb2_verify_member_inside(p, -8, p, 12, 0, 0),
- VB2_ERROR_INSIDE_PARENT_WRAPS,
- "MemberInside wraparound 1");
- TEST_EQ(vb2_verify_member_inside(p, 20, p, -8, 0, 0),
- VB2_ERROR_INSIDE_MEMBER_WRAPS,
- "MemberInside wraparound 2");
- TEST_EQ(vb2_verify_member_inside(p, 20, p, 4, 4, -12),
- VB2_ERROR_INSIDE_DATA_WRAPS,
- "MemberInside wraparound 3");
- }
-
- {
- struct vb2_packed_key k = {.key_offset = sizeof(k),
- .key_size = 128};
- TEST_SUCC(vb2_verify_packed_key_inside(&k, sizeof(k)+128, &k),
- "PublicKeyInside ok 1");
- TEST_SUCC(vb2_verify_packed_key_inside(&k - 1,
- 2*sizeof(k)+128, &k),
- "PublicKeyInside ok 2");
- TEST_EQ(vb2_verify_packed_key_inside(&k, 128, &k),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
- "PublicKeyInside key too big");
- }
-
- {
- struct vb2_packed_key k = {.key_offset = 100,
- .key_size = 4};
- TEST_EQ(vb2_verify_packed_key_inside(&k, 99, &k),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
- "PublicKeyInside offset too big");
- }
-
- {
- struct vb2_signature s = {.sig_offset = sizeof(s),
- .sig_size = 128};
- TEST_SUCC(vb2_verify_signature_inside(&s, sizeof(s)+128, &s),
- "SignatureInside ok 1");
- TEST_SUCC(vb2_verify_signature_inside(&s - 1,
- 2*sizeof(s)+128, &s),
- "SignatureInside ok 2");
- TEST_EQ(vb2_verify_signature_inside(&s, 128, &s),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
- "SignatureInside sig too big");
- }
-
- {
- struct vb2_signature s = {.sig_offset = 100,
- .sig_size = 4};
- TEST_EQ(vb2_verify_signature_inside(&s, 99, &s),
- VB2_ERROR_INSIDE_DATA_OUTSIDE,
- "SignatureInside offset too big");
- }
-}
-
int main(int argc, char* argv[])
{
test_memcmp();
test_align();
test_workbuf();
- test_struct_packing();
- test_helper_functions();
return gTestSuccess ? 0 : 255;
}
diff --git a/tests/vb2_rsa_tests.sh b/tests/vb2_rsa_tests.sh
index ff570d01..903d38da 100755
--- a/tests/vb2_rsa_tests.sh
+++ b/tests/vb2_rsa_tests.sh
@@ -33,7 +33,7 @@ function test_signatures {
done
done
echo -e "Peforming ${COL_YELLOW}PKCS #1 v1.5 Padding Tests${COL_STOP}..."
- ${TEST_DIR}/vb2_rsa_padding_tests ${TESTKEY_DIR}/rsa_padding_test_pubkey.keyb
+ ${TEST_DIR}/vb20_rsa_padding_tests ${TESTKEY_DIR}/rsa_padding_test_pubkey.keyb
}
check_test_keys