diff options
author | Randall Spangler <rspangler@chromium.org> | 2016-06-02 16:05:49 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-07-26 19:42:38 -0700 |
commit | 98263a1b17397032b3f7d747d48f8fd914217237 (patch) | |
tree | 5a9ce0f9da372f8a8d3ce49990d2d7de47e96a6a | |
parent | bba272a8776c61f308aafa5ed7d8bbd1f99f5282 (diff) | |
download | vboot-98263a1b17397032b3f7d747d48f8fd914217237.tar.gz |
vboot: Upgrade VerifyFirmwarePreamble() to vboot2.0
This replaces all calls to vboot1 VerifyFirmwarePreamble() with
equivalent vb2.0 functions. No effect on ToT firmware, which already
uses the vboot2.0 functions.
BUG=chromium:611535
BRANCH=none
TEST=make runtests
Change-Id: I5c84e9ed0e0c75e2ea8dbd9bfcde0597bc457f24
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/349322
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r-- | Makefile | 11 | ||||
-rw-r--r-- | firmware/2lib/include/2api.h | 14 | ||||
-rw-r--r-- | firmware/2lib/include/2misc.h | 2 | ||||
-rw-r--r-- | firmware/lib/include/vboot_common.h | 19 | ||||
-rw-r--r-- | firmware/lib/vboot_common.c | 87 | ||||
-rw-r--r-- | firmware/lib21/api.c | 10 | ||||
-rw-r--r-- | firmware/lib21/misc.c | 24 | ||||
-rw-r--r-- | firmware/linktest/main.c | 2 | ||||
-rw-r--r-- | futility/cmd_show.c | 191 | ||||
-rw-r--r-- | futility/cmd_vbutil_firmware.c | 156 | ||||
-rw-r--r-- | futility/cmd_vbutil_key.c | 17 | ||||
-rw-r--r-- | futility/cmd_vbutil_keyblock.c | 10 | ||||
-rw-r--r-- | futility/file_type_bios.c | 11 | ||||
-rw-r--r-- | futility/futility_options.h | 2 | ||||
-rw-r--r-- | futility/vb1_helper.c | 78 | ||||
-rw-r--r-- | futility/vb1_helper.h | 12 | ||||
-rw-r--r-- | host/lib/host_key.c | 75 | ||||
-rw-r--r-- | host/lib/include/host_key.h | 5 | ||||
-rw-r--r-- | host/lib/include/util_misc.h | 15 | ||||
-rw-r--r-- | host/lib/util_misc.c | 11 | ||||
-rw-r--r-- | tests/vb21_api_tests.c | 58 | ||||
-rw-r--r-- | tests/vb21_misc_tests.c | 54 | ||||
-rw-r--r-- | tests/vboot_common3_tests.c | 123 |
23 files changed, 424 insertions, 563 deletions
@@ -287,7 +287,8 @@ INCLUDES += \ -Ifirmware/lib/cgptlib/include \ -Ifirmware/lib/cryptolib/include \ -Ifirmware/lib/tpm_lite/include \ - -Ifirmware/2lib/include + -Ifirmware/2lib/include \ + -Ifirmware/lib20/include # If we're not building for a specific target, just stub out things like the # TPM commands and various external functions that are provided by the BIOS. @@ -925,7 +926,6 @@ ifeq (${FIRMWARE_ARCH},) ${FWLIB_OBJS}: CFLAGS += -DDISABLE_ROLLBACK_TPM endif -${FWLIB20_OBJS}: INCLUDES += -Ifirmware/lib20/include ${FWLIB21_OBJS}: INCLUDES += -Ifirmware/lib21/include ${BDBLIB_OBJS}: INCLUDES += -Ifirmware/bdb @@ -995,7 +995,7 @@ utillib: ${UTILLIB} \ ${BUILD}/host/linktest/main # TODO: better way to make .a than duplicating this recipe each time? -${UTILLIB}: ${UTILLIB_OBJS} ${FWLIB_OBJS} ${FWLIB2X_OBJS} +${UTILLIB}: ${UTILLIB_OBJS} ${FWLIB_OBJS} ${FWLIB2X_OBJS} ${FWLIB20_OBJS} @${PRINTF} " RM $(subst ${BUILD}/,,$@)\n" ${Q}rm -f $@ @${PRINTF} " AR $(subst ${BUILD}/,,$@)\n" @@ -1147,8 +1147,8 @@ ${FUTIL_STATIC_BIN}: ${FUTIL_STATIC_OBJS} ${UTILLIB} @${PRINTF} " LD $(subst ${BUILD}/,,$@)\n" ${Q}${LD} -o $@ ${CFLAGS} ${LDFLAGS} -static $^ ${LDLIBS} -${FUTIL_BIN}: LDLIBS += ${CRYPTO_LIBS} -${FUTIL_BIN}: ${FUTIL_OBJS} ${UTILLIB} +${FUTIL_BIN}: LDLIBS += ${CRYPTO_LIBS} ${FWLIB20} +${FUTIL_BIN}: ${FUTIL_OBJS} ${UTILLIB} ${FWLIB20} @${PRINTF} " LD $(subst ${BUILD}/,,$@)\n" ${Q}${LD} -o $@ ${CFLAGS} ${LDFLAGS} $^ ${LDLIBS} @@ -1196,7 +1196,6 @@ ${TEST2X_BINS}: ${FWLIB2X} ${TEST2X_BINS}: LIBS += ${FWLIB2X} ${TEST20_BINS}: ${FWLIB20} -${TEST20_BINS}: INCLUDES += -Ifirmware/lib20/include ${TEST20_BINS}: LIBS += ${FWLIB20} ${TEST21_BINS}: ${UTILLIB21} diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h index 709db48b..e4c6ad0c 100644 --- a/firmware/2lib/include/2api.h +++ b/firmware/2lib/include/2api.h @@ -460,6 +460,11 @@ int vb2api_fw_phase2(struct vb2_context *ctx); int vb2api_fw_phase3(struct vb2_context *ctx); /** + * Same, but for new-style structs. + */ +int vb21api_fw_phase3(struct vb2_context *ctx); + +/** * Initialize hashing data for the specified tag. * * @param ctx Vboot context @@ -473,7 +478,7 @@ int vb2api_init_hash(struct vb2_context *ctx, uint32_t tag, uint32_t *size); /** * Same, but for new-style structs. */ -int vb2api_init_hash2(struct vb2_context *ctx, +int vb21api_init_hash(struct vb2_context *ctx, const struct vb2_id *id, uint32_t *size); @@ -500,6 +505,11 @@ int vb2api_extend_hash(struct vb2_context *ctx, int vb2api_check_hash(struct vb2_context *ctx); /** + * Same, but for new-style structs. + */ +int vb21api_check_hash(struct vb2_context *ctx); + +/** * Check the hash value started by vb2api_init_hash() while retrieving * calculated digest. * @@ -509,7 +519,7 @@ int vb2api_check_hash(struct vb2_context *ctx); * @return VB2_SUCCESS, or error code on error. */ int vb2api_check_hash_get_digest(struct vb2_context *ctx, void *digest_out, - uint32_t digest_out_size); + uint32_t digest_out_size); /** * Get a PCR digest diff --git a/firmware/2lib/include/2misc.h b/firmware/2lib/include/2misc.h index 5e3363cb..f562fade 100644 --- a/firmware/2lib/include/2misc.h +++ b/firmware/2lib/include/2misc.h @@ -130,6 +130,7 @@ int vb2_select_fw_slot(struct vb2_context *ctx); * @return VB2_SUCCESS, or error code on error. */ int vb2_load_fw_keyblock(struct vb2_context *ctx); +int vb21_load_fw_keyblock(struct vb2_context *ctx); /** * Verify the firmware preamble using the data subkey from the keyblock. @@ -140,6 +141,7 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx); * @return VB2_SUCCESS, or error code on error. */ int vb2_load_fw_preamble(struct vb2_context *ctx); +int vb21_load_fw_preamble(struct vb2_context *ctx); /** * Verify the kernel keyblock using the previously-loaded kernel key. diff --git a/firmware/lib/include/vboot_common.h b/firmware/lib/include/vboot_common.h index 35d7676d..5b783e27 100644 --- a/firmware/lib/include/vboot_common.h +++ b/firmware/lib/include/vboot_common.h @@ -121,25 +121,6 @@ int VerifyDigest(const uint8_t *digest, const VbSignature *sig, int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size, const VbPublicKey *key, int hash_only); - -/** - * Check the sanity of a firmware preamble of size [size] bytes, using public - * key [key]. - * - * Returns VBOOT_SUCCESS if successful. - */ -int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader *preamble, - uint64_t size, const RSAPublicKey *key); - - -/** - * Return the flags from a firmware preamble, or a default value for older - * preamble versions which didn't contain flags. Use this function to ensure - * compatibility with older preamble versions (2.0). Assumes the preamble has - * already been verified via VerifyFirmwarePreamble(). - */ -uint32_t VbGetFirmwarePreambleFlags(const VbFirmwarePreambleHeader *preamble); - /** * Check the sanity of a kernel preamble of size [size] bytes, using public key * [key]. diff --git a/firmware/lib/vboot_common.c b/firmware/lib/vboot_common.c index 308bfeed..3535952f 100644 --- a/firmware/lib/vboot_common.c +++ b/firmware/lib/vboot_common.c @@ -311,93 +311,6 @@ int KeyBlockVerify(const VbKeyBlockHeader *block, uint64_t size, return VBOOT_SUCCESS; } -int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader *preamble, - uint64_t size, const RSAPublicKey *key) -{ - const VbSignature *sig = &preamble->preamble_signature; - - VBDEBUG(("Verifying preamble.\n")); - /* Sanity checks before attempting signature of data */ - if(size < EXPECTED_VBFIRMWAREPREAMBLEHEADER2_0_SIZE) { - VBDEBUG(("Not enough data for preamble header 2.0.\n")); - return VBOOT_PREAMBLE_INVALID; - } - if (preamble->header_version_major != - FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) { - VBDEBUG(("Incompatible firmware preamble header version.\n")); - return VBOOT_PREAMBLE_INVALID; - } - if (size < preamble->preamble_size) { - VBDEBUG(("Not enough data for preamble.\n")); - return VBOOT_PREAMBLE_INVALID; - } - - /* Check signature */ - if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) { - VBDEBUG(("Preamble signature off end of preamble\n")); - return VBOOT_PREAMBLE_INVALID; - } - - /* Make sure advertised signature data sizes are sane. */ - if (preamble->preamble_size < sig->data_size) { - VBDEBUG(("Signature calculated past end of the block\n")); - return VBOOT_PREAMBLE_INVALID; - } - - if (VerifyData((const uint8_t *)preamble, size, sig, key)) { - VBDEBUG(("Preamble signature validation failed\n")); - return VBOOT_PREAMBLE_SIGNATURE; - } - - /* Verify we signed enough data */ - if (sig->data_size < sizeof(VbFirmwarePreambleHeader)) { - VBDEBUG(("Didn't sign enough data\n")); - return VBOOT_PREAMBLE_INVALID; - } - - /* Verify body signature is inside the signed data */ - if (VerifySignatureInside(preamble, sig->data_size, - &preamble->body_signature)) { - VBDEBUG(("Firmware body signature off end of preamble\n")); - return VBOOT_PREAMBLE_INVALID; - } - - /* Verify kernel subkey is inside the signed data */ - if (VerifyPublicKeyInside(preamble, sig->data_size, - &preamble->kernel_subkey)) { - VBDEBUG(("Kernel subkey off end of preamble\n")); - return VBOOT_PREAMBLE_INVALID; - } - - /* - * If the preamble header version is at least 2.1, verify we have space - * for the added fields from 2.1. - */ - if (preamble->header_version_minor >= 1) { - if(size < EXPECTED_VBFIRMWAREPREAMBLEHEADER2_1_SIZE) { - VBDEBUG(("Not enough data for preamble header 2.1.\n")); - return VBOOT_PREAMBLE_INVALID; - } - } - - /* Success */ - return VBOOT_SUCCESS; -} - -uint32_t VbGetFirmwarePreambleFlags(const VbFirmwarePreambleHeader *preamble) -{ - if (preamble->header_version_minor < 1) { - /* - * Old structure; return default flags. (Note that we don't - * need to check header_version_major; if that's not 2 then - * VerifyFirmwarePreamble() would have already failed. - */ - return 0; - } - - return preamble->flags; -} - int VerifyKernelPreamble(const VbKernelPreambleHeader *preamble, uint64_t size, const RSAPublicKey *key) { diff --git a/firmware/lib21/api.c b/firmware/lib21/api.c index a7938b9e..c9774863 100644 --- a/firmware/lib21/api.c +++ b/firmware/lib21/api.c @@ -16,19 +16,19 @@ #include "2rsa.h" #include "vb21_common.h" -int vb2api_fw_phase3(struct vb2_context *ctx) +int vb21api_fw_phase3(struct vb2_context *ctx) { int rv; /* Verify firmware keyblock */ - rv = vb2_load_fw_keyblock(ctx); + rv = vb21_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); + rv = vb21_load_fw_preamble(ctx); if (rv) { vb2_fail(ctx, VB2_RECOVERY_RO_INVALID_RW, rv); return rv; @@ -37,7 +37,7 @@ int vb2api_fw_phase3(struct vb2_context *ctx) return VB2_SUCCESS; } -int vb2api_init_hash2(struct vb2_context *ctx, +int vb21api_init_hash(struct vb2_context *ctx, const struct vb2_id *id, uint32_t *size) { @@ -113,7 +113,7 @@ int vb2api_init_hash2(struct vb2_context *ctx, return vb2_digest_init(dc, sig->hash_alg); } -int vb2api_check_hash(struct vb2_context *ctx) +int vb21api_check_hash(struct vb2_context *ctx) { struct vb2_shared_data *sd = vb2_get_sd(ctx); struct vb2_digest_context *dc = (struct vb2_digest_context *) diff --git a/firmware/lib21/misc.c b/firmware/lib21/misc.c index 2d2cb594..cb6da77e 100644 --- a/firmware/lib21/misc.c +++ b/firmware/lib21/misc.c @@ -28,11 +28,11 @@ * @param buf_ptr Destination for object pointer * @return VB2_SUCCESS, or error code on error. */ -int vb2_read_resource_object(struct vb2_context *ctx, - enum vb2_resource_index index, - uint32_t offset, - struct vb2_workbuf *wb, - void **buf_ptr) +static int vb21_read_resource_object(struct vb2_context *ctx, + enum vb2_resource_index index, + uint32_t offset, + struct vb2_workbuf *wb, + void **buf_ptr) { struct vb21_struct_common c; void *buf; @@ -62,7 +62,7 @@ int vb2_read_resource_object(struct vb2_context *ctx, return VB2_SUCCESS; } -int vb2_load_fw_keyblock(struct vb2_context *ctx) +int vb21_load_fw_keyblock(struct vb2_context *ctx) { struct vb2_shared_data *sd = vb2_get_sd(ctx); struct vb2_workbuf wb; @@ -97,8 +97,8 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx) * Load the firmware keyblock common header into the work buffer after * the root key. */ - rv = vb2_read_resource_object(ctx, VB2_RES_FW_VBLOCK, 0, &wb, - (void **)&kb); + rv = vb21_read_resource_object(ctx, VB2_RES_FW_VBLOCK, 0, &wb, + (void **)&kb); if (rv) return rv; @@ -154,7 +154,7 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx) return VB2_SUCCESS; } -int vb2_load_fw_preamble(struct vb2_context *ctx) +int vb21_load_fw_preamble(struct vb2_context *ctx) { struct vb2_shared_data *sd = vb2_get_sd(ctx); struct vb2_workbuf wb; @@ -179,9 +179,9 @@ int vb2_load_fw_preamble(struct vb2_context *ctx) return rv; /* Load the firmware preamble */ - rv = vb2_read_resource_object(ctx, VB2_RES_FW_VBLOCK, - sd->vblock_preamble_offset, &wb, - (void **)&pre); + rv = vb21_read_resource_object(ctx, VB2_RES_FW_VBLOCK, + sd->vblock_preamble_offset, &wb, + (void **)&pre); if (rv) return rv; diff --git a/firmware/linktest/main.c b/firmware/linktest/main.c index fad11101..1c9b614d 100644 --- a/firmware/linktest/main.c +++ b/firmware/linktest/main.c @@ -71,8 +71,6 @@ int main(void) VerifyData(0, 0, 0, 0); VerifyDigest(0, 0, 0); KeyBlockVerify(0, 0, 0, 0); - VerifyFirmwarePreamble(0, 0, 0); - VbGetFirmwarePreambleFlags(0); VerifyKernelPreamble(0, 0, 0); VbSharedDataInit(0, 0); VbSharedDataReserve(0, 0); diff --git a/futility/cmd_show.c b/futility/cmd_show.c index bcb0e1dd..b2781809 100644 --- a/futility/cmd_show.c +++ b/futility/cmd_show.c @@ -20,6 +20,10 @@ #include <sys/types.h> #include <unistd.h> +#include "2sysincludes.h" +#include "2api.h" +#include "2common.h" +#include "2sha.h" #include "file_type.h" #include "file_type_bios.h" #include "fmap.h" @@ -28,8 +32,8 @@ #include "host_common.h" #include "util_misc.h" #include "vb1_helper.h" +#include "vb2_common.h" #include "vboot_common.h" -#include "2api.h" #include "host_key2.h" /* Options */ @@ -38,19 +42,21 @@ struct show_option_s show_option = { .type = FILE_TYPE_UNKNOWN, }; -void show_pubkey(VbPublicKey *pubkey, const char *sp) +/* Shared work buffer */ +static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]; +static struct vb2_workbuf wb; + +void show_pubkey(const struct vb2_packed_key *pubkey, const char *sp) { printf("%sVboot API: 1.0\n", sp); - printf("%sAlgorithm: %" PRIu64 " %s\n", sp, pubkey->algorithm, - (pubkey->algorithm < kNumAlgorithms ? - algo_strings[pubkey->algorithm] : "(invalid)")); - printf("%sKey Version: %" PRIu64 "\n", sp, pubkey->key_version); - printf("%sKey sha1sum: ", sp); - PrintPubKeySha1Sum(pubkey); - printf("\n"); + printf("%sAlgorithm: %d %s\n", sp, pubkey->algorithm, + vb1_crypto_name(pubkey->algorithm)); + printf("%sKey Version: %d\n", sp, pubkey->key_version); + printf("%sKey sha1sum: %s\n", + sp, packed_key_sha1_string(pubkey)); } -static void show_keyblock(VbKeyBlockHeader *key_block, const char *name, +static void show_keyblock(struct vb2_keyblock *keyblock, const char *name, int sign_key, int good_sig) { if (name) @@ -59,36 +65,31 @@ static void show_keyblock(VbKeyBlockHeader *key_block, const char *name, printf("Key block:\n"); printf(" Signature: %s\n", sign_key ? (good_sig ? "valid" : "invalid") : "ignored"); - printf(" Size: 0x%" PRIx64 "\n", - key_block->key_block_size); - printf(" Flags: %" PRIu64 " ", - key_block->key_block_flags); - if (key_block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_0) + printf(" Size: 0x%x\n", keyblock->keyblock_size); + printf(" Flags: %d ", keyblock->keyblock_flags); + if (keyblock->keyblock_flags & VB2_KEY_BLOCK_FLAG_DEVELOPER_0) printf(" !DEV"); - if (key_block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_1) + if (keyblock->keyblock_flags & VB2_KEY_BLOCK_FLAG_DEVELOPER_1) printf(" DEV"); - if (key_block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0) + if (keyblock->keyblock_flags & VB2_KEY_BLOCK_FLAG_RECOVERY_0) printf(" !REC"); - if (key_block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_1) + if (keyblock->keyblock_flags & VB2_KEY_BLOCK_FLAG_RECOVERY_1) printf(" REC"); printf("\n"); - VbPublicKey *data_key = &key_block->data_key; - printf(" Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm, - (data_key->algorithm < kNumAlgorithms - ? algo_strings[data_key->algorithm] - : "(invalid)")); - printf(" Data key version: %" PRIu64 "\n", data_key->key_version); - printf(" Data key sha1sum: "); - PrintPubKeySha1Sum(data_key); - printf("\n"); + struct vb2_packed_key *data_key = &keyblock->data_key; + printf(" Data key algorithm: %d %s\n", data_key->algorithm, + vb1_crypto_name(data_key->algorithm)); + printf(" Data key version: %d\n", data_key->key_version); + printf(" Data key sha1sum: %s\n", + packed_key_sha1_string(data_key)); } int ft_show_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data) { - VbPublicKey *pubkey = (VbPublicKey *)buf; + struct vb2_packed_key *pubkey = (struct vb2_packed_key *)buf; - if (!PublicKeyLooksOkay(pubkey, len)) { + if (!packed_key_looks_ok(pubkey, len)) { printf("%s looks bogus\n", name); return 1; } @@ -103,7 +104,6 @@ int ft_show_privkey(const char *name, uint8_t *buf, uint32_t len, void *data) { VbPrivateKey key; const unsigned char *start; - int alg_okay; key.algorithm = *(typeof(key.algorithm) *)buf; start = buf + sizeof(key.algorithm); @@ -116,9 +116,8 @@ int ft_show_privkey(const char *name, uint8_t *buf, uint32_t len, void *data) printf("Private Key file: %s\n", name); printf(" Vboot API: 1.0\n"); - alg_okay = key.algorithm < kNumAlgorithms; printf(" Algorithm: %" PRIu64 " %s\n", key.algorithm, - alg_okay ? algo_strings[key.algorithm] : "(unknown)"); + vb1_crypto_name(key.algorithm)); printf(" Key sha1sum: "); if (key.rsa_private_key) { PrintPrivKeySha1Sum(&key); @@ -133,20 +132,20 @@ int ft_show_privkey(const char *name, uint8_t *buf, uint32_t len, void *data) int ft_show_keyblock(const char *name, uint8_t *buf, uint32_t len, void *data) { - VbKeyBlockHeader *block = (VbKeyBlockHeader *)buf; - VbPublicKey *sign_key = show_option.k; + struct vb2_keyblock *block = (struct vb2_keyblock *)buf; + struct vb2_public_key *sign_key = show_option.k; int good_sig = 0; int retval = 0; /* Check the hash only first */ - if (0 != KeyBlockVerify(block, len, NULL, 1)) { + if (0 != vb2_verify_keyblock_hash(block, len, &wb)) { printf("%s is invalid\n", name); return 1; } /* Check the signature if we have one */ - if (sign_key && VBOOT_SUCCESS == - KeyBlockVerify(block, len, sign_key, 0)) + if (sign_key && + VB2_SUCCESS == vb2_verify_keyblock(block, len, sign_key, &wb)) good_sig = 1; if (show_option.strict && (!sign_key || !good_sig)) @@ -160,9 +159,9 @@ int ft_show_keyblock(const char *name, uint8_t *buf, uint32_t len, void *data) int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len, void *data) { - VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)buf; + struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf; struct bios_state_s *state = (struct bios_state_s *)data; - VbPublicKey *sign_key = show_option.k; + struct vb2_public_key *sign_key = show_option.k; uint8_t *fv_data = show_option.fv; uint64_t fv_size = show_option.fv_size; struct bios_area_s *fw_body_area = 0; @@ -170,7 +169,7 @@ int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len, int retval = 0; /* Check the hash... */ - if (VBOOT_SUCCESS != KeyBlockVerify(key_block, len, NULL, 1)) { + if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) { printf("%s keyblock component is invalid\n", name); return 1; } @@ -181,10 +180,16 @@ int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len, * have no state, then we're just looking at a standalone fw_preamble, * so we'll have to get any keys or data from options. */ + struct vb2_public_key root_key; if (state) { - if (!sign_key && state->rootkey.is_valid) + if (!sign_key && + state->rootkey.is_valid && + VB2_SUCCESS == vb2_unpack_key(&root_key, state->rootkey.buf, + state->rootkey.len)) { /* BIOS should have a rootkey in the GBB */ - sign_key = (VbPublicKey *)state->rootkey.buf; + sign_key = &root_key; + } + /* Identify the firmware body for this VBLOCK */ enum bios_component body_c = state->c == BIOS_FMAP_VBLOCK_A ? BIOS_FMAP_FW_MAIN_A @@ -193,54 +198,53 @@ int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len, } /* If we have a key, check the signature too */ - if (sign_key && VBOOT_SUCCESS == - KeyBlockVerify(key_block, len, sign_key, 0)) + if (sign_key && VB2_SUCCESS == + vb2_verify_keyblock(keyblock, len, sign_key, &wb)) good_sig = 1; - show_keyblock(key_block, name, !!sign_key, good_sig); + show_keyblock(keyblock, name, !!sign_key, good_sig); if (show_option.strict && (!sign_key || !good_sig)) retval = 1; - RSAPublicKey *rsa = PublicKeyToRSA(&key_block->data_key); - if (!rsa) { + struct vb2_public_key data_key; + if (VB2_SUCCESS != + vb2_unpack_key(&data_key, (const uint8_t *)&keyblock->data_key, + keyblock->data_key.key_offset + + keyblock->data_key.key_size)) { fprintf(stderr, "Error parsing data key in %s\n", name); return 1; } - uint32_t more = key_block->key_block_size; - VbFirmwarePreambleHeader *preamble = - (VbFirmwarePreambleHeader *)(buf + more); - if (VBOOT_SUCCESS != VerifyFirmwarePreamble(preamble, - len - more, rsa)) { + uint32_t more = keyblock->keyblock_size; + struct vb2_fw_preamble *pre2 = (struct vb2_fw_preamble *)(buf + more); + if (VB2_SUCCESS != vb2_verify_fw_preamble(pre2, len - more, + &data_key, &wb)) { printf("%s is invalid\n", name); return 1; } - uint32_t flags = VbGetFirmwarePreambleFlags(preamble); + uint32_t flags = pre2->flags; + if (pre2->header_version_minor < 1) + flags = 0; /* Old 2.0 structure didn't have flags */ + printf("Firmware Preamble:\n"); - printf(" Size: %" PRIu64 "\n", - preamble->preamble_size); - printf(" Header version: %" PRIu32 ".%" PRIu32 "\n", - preamble->header_version_major, preamble->header_version_minor); - printf(" Firmware version: %" PRIu64 "\n", - preamble->firmware_version); - VbPublicKey *kernel_subkey = &preamble->kernel_subkey; - printf(" Kernel key algorithm: %" PRIu64 " %s\n", + printf(" Size: %d\n", pre2->preamble_size); + printf(" Header version: %d.%d\n", + pre2->header_version_major, pre2->header_version_minor); + printf(" Firmware version: %d\n", pre2->firmware_version); + + struct vb2_packed_key *kernel_subkey = &pre2->kernel_subkey; + printf(" Kernel key algorithm: %d %s\n", kernel_subkey->algorithm, - (kernel_subkey->algorithm < kNumAlgorithms ? - algo_strings[kernel_subkey->algorithm] : "(invalid)")); + vb1_crypto_name(kernel_subkey->algorithm)); if (kernel_subkey->algorithm >= kNumAlgorithms) retval = 1; - printf(" Kernel key version: %" PRIu64 "\n", - kernel_subkey->key_version); - printf(" Kernel key sha1sum: "); - PrintPubKeySha1Sum(kernel_subkey); - printf("\n"); - printf(" Firmware body size: %" PRIu64 "\n", - preamble->body_signature.data_size); - printf(" Preamble flags: %" PRIu32 "\n", flags); - + printf(" Kernel key version: %d\n", kernel_subkey->key_version); + printf(" Kernel key sha1sum: %s\n", + packed_key_sha1_string(kernel_subkey)); + printf(" Firmware body size: %d\n", pre2->body_signature.data_size); + printf(" Preamble flags: %d\n", flags); if (flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) { printf("Preamble requests USE_RO_NORMAL;" @@ -261,8 +265,9 @@ int ft_show_fw_preamble(const char *name, uint8_t *buf, uint32_t len, return 0; } - if (VBOOT_SUCCESS != - VerifyData(fv_data, fv_size, &preamble->body_signature, rsa)) { + if (VB2_SUCCESS != + vb2_verify_data(fv_data, fv_size, &pre2->body_signature, + &data_key, &wb)) { fprintf(stderr, "Error verifying firmware body.\n"); return 1; } @@ -287,8 +292,8 @@ done: int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len, void *data) { - VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)buf; - VbPublicKey *sign_key = show_option.k; + struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf; + struct vb2_public_key *sign_key = show_option.k; uint8_t *kernel_blob = 0; uint64_t kernel_size = 0; int good_sig = 0; @@ -298,28 +303,28 @@ int ft_show_kernel_preamble(const char *name, uint8_t *buf, uint32_t len, uint32_t flags = 0; /* Check the hash... */ - if (VBOOT_SUCCESS != KeyBlockVerify(key_block, len, NULL, 1)) { + if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) { printf("%s keyblock component is invalid\n", name); return 1; } /* If we have a key, check the signature too */ - if (sign_key && VBOOT_SUCCESS == - KeyBlockVerify(key_block, len, sign_key, 0)) + if (sign_key && VB2_SUCCESS == + vb2_verify_keyblock(keyblock, len, sign_key, &wb)) good_sig = 1; printf("Kernel partition: %s\n", name); - show_keyblock(key_block, NULL, !!sign_key, good_sig); + show_keyblock(keyblock, NULL, !!sign_key, good_sig); if (show_option.strict && (!sign_key || !good_sig)) retval = 1; - RSAPublicKey *rsa = PublicKeyToRSA(&key_block->data_key); + RSAPublicKey *rsa = PublicKeyToRSA((VbPublicKey *)&keyblock->data_key); if (!rsa) { fprintf(stderr, "Error parsing data key in %s\n", name); return 1; } - uint32_t more = key_block->key_block_size; + uint32_t more = keyblock->keyblock_size; VbKernelPreambleHeader *preamble = (VbKernelPreambleHeader *)(buf + more); @@ -482,6 +487,8 @@ static int show_type(char *filename) static int do_show(int argc, char *argv[]) { + uint8_t *pubkbuf = NULL; + struct vb2_public_key pubk2; char *infile = 0; int ifd, i; int errorcnt = 0; @@ -491,6 +498,8 @@ static int do_show(int argc, char *argv[]) int type_override = 0; enum futil_file_type type; + vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); + opterr = 0; /* quiet, you */ while ((i = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) { switch (i) { @@ -504,11 +513,21 @@ static int do_show(int argc, char *argv[]) } break; case 'k': - show_option.k = PublicKeyRead(optarg); - if (!show_option.k) { + if (VB2_SUCCESS != + vb2_read_file(optarg, &pubkbuf, &len)) { fprintf(stderr, "Error reading %s\n", optarg); errorcnt++; + break; } + + if (VB2_SUCCESS != + vb2_unpack_key(&pubk2, pubkbuf, len)) { + fprintf(stderr, "Error unpacking %s\n", optarg); + errorcnt++; + break; + } + + show_option.k = &pubk2; break; case 't': show_option.t_flag = 1; @@ -611,8 +630,8 @@ boo: } done: - if (show_option.k) - free(show_option.k); + if (pubkbuf) + free(pubkbuf); if (show_option.fv) free(show_option.fv); diff --git a/futility/cmd_vbutil_firmware.c b/futility/cmd_vbutil_firmware.c index 4e312b29..66a05c19 100644 --- a/futility/cmd_vbutil_firmware.c +++ b/futility/cmd_vbutil_firmware.c @@ -12,12 +12,19 @@ #include <stdlib.h> #include <unistd.h> +#include "2sysincludes.h" +#include "2api.h" +#include "2common.h" +#include "2rsa.h" #include "cryptolib.h" #include "futility.h" #include "host_common.h" +#include "host_key2.h" #include "kernel_blob.h" #include "util_misc.h" #include "vboot_common.h" +#include "vb1_helper.h" +#include "vb2_common.h" /* Command line options */ enum { @@ -174,19 +181,11 @@ static int Vblock(const char *outfile, const char *keyblock_file, static int Verify(const char *infile, const char *signpubkey, const char *fv_file, const char *kernelkey_file) { + uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]; + struct vb2_workbuf wb; + vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); - VbKeyBlockHeader *key_block; - VbFirmwarePreambleHeader *preamble; - VbPublicKey *data_key; - VbPublicKey *sign_key; - VbPublicKey *kernel_subkey; - RSAPublicKey *rsa; - uint8_t *blob; - uint64_t blob_size; - uint8_t *fv_data; - uint64_t fv_size; - uint64_t now = 0; - uint32_t flags; + uint32_t now = 0; if (!infile || !signpubkey || !fv_file) { VbExError("Must specify filename, signpubkey, and fv\n"); @@ -194,105 +193,112 @@ static int Verify(const char *infile, const char *signpubkey, } /* Read public signing key */ - sign_key = PublicKeyRead(signpubkey); - if (!sign_key) { - VbExError("Error reading signpubkey.\n"); + uint8_t *pubkbuf; + uint32_t pubklen; + struct vb2_public_key sign_key; + if (VB2_SUCCESS != vb2_read_file(signpubkey, &pubkbuf, &pubklen)) { + fprintf(stderr, "Error reading signpubkey.\n"); + return 1; + } + if (VB2_SUCCESS != vb2_unpack_key(&sign_key, pubkbuf, pubklen)) { + fprintf(stderr, "Error unpacking signpubkey.\n"); return 1; } /* Read blob */ - blob = ReadFile(infile, &blob_size); - if (!blob) { + uint8_t *blob; + uint32_t blob_size; + if (VB2_SUCCESS != vb2_read_file(infile, &blob, &blob_size)) { VbExError("Error reading input file\n"); return 1; } /* Read firmware volume */ - fv_data = ReadFile(fv_file, &fv_size); - if (!fv_data) { + uint8_t *fv_data; + uint32_t fv_size; + if (VB2_SUCCESS != vb2_read_file(fv_file, &fv_data, &fv_size)) { VbExError("Error reading firmware volume\n"); return 1; } /* Verify key block */ - key_block = (VbKeyBlockHeader *) blob; - if (0 != KeyBlockVerify(key_block, blob_size, sign_key, 0)) { + struct vb2_keyblock *keyblock = (struct vb2_keyblock *)blob; + if (VB2_SUCCESS != + vb2_verify_keyblock(keyblock, blob_size, &sign_key, &wb)) { VbExError("Error verifying key block.\n"); return 1; } - free(sign_key); - now += key_block->key_block_size; + free(pubkbuf); + + now += keyblock->keyblock_size; printf("Key block:\n"); - data_key = &key_block->data_key; - printf(" Size: %" PRIu64 "\n", - key_block->key_block_size); - printf(" Flags: %" PRIu64 " (ignored)\n", - key_block->key_block_flags); - printf(" Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm, - (data_key->algorithm < - kNumAlgorithms ? algo_strings[data_key-> - algorithm] : "(invalid)")); - printf(" Data key version: %" PRIu64 "\n", data_key->key_version); - printf(" Data key sha1sum: "); - PrintPubKeySha1Sum(data_key); - printf("\n"); - - rsa = PublicKeyToRSA(&key_block->data_key); - if (!rsa) { - VbExError("Error parsing data key.\n"); + printf(" Size: %d\n", keyblock->keyblock_size); + printf(" Flags: %d (ignored)\n", + keyblock->keyblock_flags); + + struct vb2_packed_key *packed_key = &keyblock->data_key; + printf(" Data key algorithm: %d %s\n", packed_key->algorithm, + vb1_crypto_name(packed_key->algorithm)); + printf(" Data key version: %d\n", packed_key->key_version); + printf(" Data key sha1sum: %s\n", + packed_key_sha1_string(packed_key)); + + struct vb2_public_key data_key; + if (VB2_SUCCESS != + vb2_unpack_key(&data_key, (const uint8_t *)&keyblock->data_key, + keyblock->data_key.key_offset + + keyblock->data_key.key_size)) { + fprintf(stderr, "Error parsing data key.\n"); return 1; } /* Verify preamble */ - preamble = (VbFirmwarePreambleHeader *) (blob + now); - if (0 != VerifyFirmwarePreamble(preamble, blob_size - now, rsa)) { - VbExError("Error verifying preamble.\n"); + struct vb2_fw_preamble *pre2 = (struct vb2_fw_preamble *)(blob + now); + if (VB2_SUCCESS != + vb2_verify_fw_preamble(pre2, blob_size - now, &data_key, &wb)) { + VbExError("Error2 verifying preamble.\n"); return 1; } - now += preamble->preamble_size; + now += pre2->preamble_size; + + uint32_t flags = pre2->flags; + if (pre2->header_version_minor < 1) + flags = 0; /* Old 2.0 structure didn't have flags */ - flags = VbGetFirmwarePreambleFlags(preamble); printf("Preamble:\n"); - printf(" Size: %" PRIu64 "\n", - preamble->preamble_size); - printf(" Header version: %" PRIu32 ".%" PRIu32 "\n", - preamble->header_version_major, preamble->header_version_minor); - printf(" Firmware version: %" PRIu64 "\n", - preamble->firmware_version); - kernel_subkey = &preamble->kernel_subkey; - printf(" Kernel key algorithm: %" PRIu64 " %s\n", - kernel_subkey->algorithm, - (kernel_subkey->algorithm < kNumAlgorithms ? - algo_strings[kernel_subkey->algorithm] : "(invalid)")); - printf(" Kernel key version: %" PRIu64 "\n", - kernel_subkey->key_version); - printf(" Kernel key sha1sum: "); - PrintPubKeySha1Sum(kernel_subkey); - printf("\n"); - printf(" Firmware body size: %" PRIu64 "\n", - preamble->body_signature.data_size); - printf(" Preamble flags: %" PRIu32 "\n", flags); + printf(" Size: %d\n", pre2->preamble_size); + printf(" Header version: %d.%d\n", + pre2->header_version_major, pre2->header_version_minor); + printf(" Firmware version: %d\n", pre2->firmware_version); + + struct vb2_packed_key *kernel_subkey = &pre2->kernel_subkey; + printf(" Kernel key algorithm: %d %s\n", kernel_subkey->algorithm, + vb1_crypto_name(kernel_subkey->algorithm)); + printf(" Kernel key version: %d\n", kernel_subkey->key_version); + printf(" Kernel key sha1sum: %s\n", + packed_key_sha1_string(kernel_subkey)); + printf(" Firmware body size: %d\n", pre2->body_signature.data_size); + printf(" Preamble flags: %d\n", flags); /* TODO: verify body size same as signature size */ /* Verify body */ if (flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) { - printf - ("Preamble requests USE_RO_NORMAL;" - " skipping body verification.\n"); - } else { - if (0 != - VerifyData(fv_data, fv_size, &preamble->body_signature, - rsa)) { - VbExError("Error verifying firmware body.\n"); - return 1; - } + printf("Preamble requests USE_RO_NORMAL;" + " skipping body verification.\n"); + } else if (VB2_SUCCESS == + vb2_verify_data(fv_data, fv_size, &pre2->body_signature, + &data_key, &wb)) { printf("Body verification succeeded.\n"); + } else { + VbExError("Error verifying firmware body.\n"); + return 1; } if (kernelkey_file) { - if (0 != PublicKeyWrite(kernelkey_file, kernel_subkey)) { + if (0 != PublicKeyWrite(kernelkey_file, + (struct VbPublicKey *)kernel_subkey)) { VbExError("Unable to write kernel subkey\n"); return 1; } diff --git a/futility/cmd_vbutil_key.c b/futility/cmd_vbutil_key.c index 840a14df..e4e919ef 100644 --- a/futility/cmd_vbutil_key.c +++ b/futility/cmd_vbutil_key.c @@ -16,6 +16,8 @@ #include "futility.h" #include "host_common.h" #include "util_misc.h" +#include "vb1_helper.h" +#include "vb2_common.h" #include "vboot_common.h" /* Command line options */ @@ -57,7 +59,7 @@ static void print_help(int argc, char *argv[]) for (i = 0; i < kNumAlgorithms; i++) { printf(" %d = (%s)\n", - i, algo_strings[i]); + i, vb1_crypto_name(i)); } printf("\nOR\n\n" @@ -119,12 +121,10 @@ static int Unpack(const char *infile, const char *outfile) if (pubkey) { printf("Public Key file: %s\n", infile); printf("Algorithm: %" PRIu64 " %s\n", pubkey->algorithm, - (pubkey->algorithm < kNumAlgorithms ? - algo_strings[pubkey->algorithm] : "(invalid)")); + vb1_crypto_name(pubkey->algorithm)); printf("Key Version: %" PRIu64 "\n", pubkey->key_version); - printf("Key sha1sum: "); - PrintPubKeySha1Sum(pubkey); - printf("\n"); + printf("Key sha1sum: %s\n", + packed_key_sha1_string((struct vb2_packed_key *)pubkey)); if (outfile) { if (0 != PublicKeyWrite(outfile, pubkey)) { fprintf(stderr, @@ -142,10 +142,7 @@ static int Unpack(const char *infile, const char *outfile) printf("Private Key file: %s\n", infile); printf("Algorithm: %" PRIu64 " %s\n", privkey->algorithm, - (privkey->algorithm < - kNumAlgorithms ? algo_strings[privkey-> - algorithm] : - "(invalid)")); + vb1_crypto_name(privkey->algorithm)); if (outfile) { if (0 != PrivateKeyWrite(outfile, privkey)) { fprintf(stderr, diff --git a/futility/cmd_vbutil_keyblock.c b/futility/cmd_vbutil_keyblock.c index 4be6b2d0..6ca6ba6e 100644 --- a/futility/cmd_vbutil_keyblock.c +++ b/futility/cmd_vbutil_keyblock.c @@ -15,6 +15,8 @@ #include "futility.h" #include "host_common.h" #include "util_misc.h" +#include "vb1_helper.h" +#include "vb2_common.h" #include "vboot_common.h" /* Command line options */ @@ -203,12 +205,10 @@ static int Unpack(const char *infile, const char *datapubkey, data_key = &block->data_key; printf("Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm, - (data_key->algorithm < kNumAlgorithms ? - algo_strings[data_key->algorithm] : "(invalid)")); + vb1_crypto_name(data_key->algorithm)); printf("Data key version: %" PRIu64 "\n", data_key->key_version); - printf("Data key sha1sum: "); - PrintPubKeySha1Sum(data_key); - printf("\n"); + printf("Data key sha1sum: %s\n", + packed_key_sha1_string((struct vb2_packed_key *)data_key)); if (datapubkey) { if (0 != PublicKeyWrite(datapubkey, data_key)) { diff --git a/futility/file_type_bios.c b/futility/file_type_bios.c index 247bb3f9..037a007b 100644 --- a/futility/file_type_bios.c +++ b/futility/file_type_bios.c @@ -18,6 +18,7 @@ #include "gbb_header.h" #include "host_common.h" #include "vb1_helper.h" +#include "vb2_common.h" static const char * const fmap_name[] = { "GBB", /* BIOS_FMAP_GBB */ @@ -55,7 +56,7 @@ int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data) { GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader *)buf; struct bios_state_s *state = (struct bios_state_s *)data; - VbPublicKey *pubkey; + struct vb2_packed_key *pubkey; BmpBlockHeader *bmp; int retval = 0; uint32_t maxlen = 0; @@ -95,8 +96,8 @@ int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data) printf(" HWID: %s\n", buf + gbb->hwid_offset); print_hwid_digest(gbb, " digest: ", "\n"); - pubkey = (VbPublicKey *)(buf + gbb->rootkey_offset); - if (PublicKeyLooksOkay(pubkey, gbb->rootkey_size)) { + pubkey = (struct vb2_packed_key *)(buf + gbb->rootkey_offset); + if (packed_key_looks_ok(pubkey, gbb->rootkey_size)) { if (state) { state->rootkey.offset = state->area[BIOS_FMAP_GBB].offset + @@ -112,8 +113,8 @@ int ft_show_gbb(const char *name, uint8_t *buf, uint32_t len, void *data) printf(" Root Key: <invalid>\n"); } - pubkey = (VbPublicKey *)(buf + gbb->recovery_key_offset); - if (PublicKeyLooksOkay(pubkey, gbb->recovery_key_size)) { + pubkey = (struct vb2_packed_key *)(buf + gbb->recovery_key_offset); + if (packed_key_looks_ok(pubkey, gbb->recovery_key_size)) { if (state) { state->recovery_key.offset = state->area[BIOS_FMAP_GBB].offset + diff --git a/futility/futility_options.h b/futility/futility_options.h index e3ea4c04..92d9a950 100644 --- a/futility/futility_options.h +++ b/futility/futility_options.h @@ -20,7 +20,7 @@ struct vb2_private_key; struct vb21_packed_key; struct show_option_s { - VbPublicKey *k; + struct vb2_public_key *k; uint8_t *fv; uint64_t fv_size; uint32_t padding; diff --git a/futility/vb1_helper.c b/futility/vb1_helper.c index b93fe6e7..c4cdda21 100644 --- a/futility/vb1_helper.c +++ b/futility/vb1_helper.c @@ -11,12 +11,23 @@ #include <unistd.h> #include <openssl/rsa.h> +#include "2sysincludes.h" +#include "2api.h" +#include "2common.h" +#include "2rsa.h" +#include "2sha.h" #include "file_type.h" #include "futility.h" #include "host_common.h" #include "kernel_blob.h" #include "util_misc.h" #include "vb1_helper.h" +#include "vb2_common.h" + +const char *vb1_crypto_name(uint32_t algo) +{ + return algo < kNumAlgorithms ? algo_strings[algo] : "(invalid)"; +} /****************************************************************************/ /* Here are globals containing all the bits & pieces I'm working on. @@ -526,9 +537,8 @@ int VerifyKernelBlob(uint8_t *kernel_blob, (data_key->algorithm < kNumAlgorithms ? algo_strings[data_key->algorithm] : "(invalid)")); printf(" Data key version: %" PRIu64 "\n", data_key->key_version); - printf(" Data key sha1sum: "); - PrintPubKeySha1Sum(data_key); - printf("\n"); + printf(" Data key sha1sum: %s\n", + packed_key_sha1_string((struct vb2_packed_key *)data_key)); if (keyblock_outfile) { FILE *f = NULL; @@ -717,42 +727,62 @@ uint8_t *CreateKernelBlob(uint8_t *vmlinuz_buf, uint64_t vmlinuz_size, enum futil_file_type ft_recognize_vblock1(uint8_t *buf, uint32_t len) { - VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)buf; - VbFirmwarePreambleHeader *fw_preamble; - VbKernelPreambleHeader *kern_preamble; - RSAPublicKey *rsa; + int rv; - if (VBOOT_SUCCESS == KeyBlockVerify(key_block, len, NULL, 1)) { - rsa = PublicKeyToRSA(&key_block->data_key); - uint32_t more = key_block->key_block_size; + uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]; + struct vb2_workbuf wb; + vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); - /* and firmware preamble too? */ - fw_preamble = (VbFirmwarePreambleHeader *)(buf + more); - if (VBOOT_SUCCESS == - VerifyFirmwarePreamble(fw_preamble, len - more, rsa)) - return FILE_TYPE_FW_PREAMBLE; + /* Vboot 2.0 signature checks destroy the buffer, so make a copy */ + uint8_t *buf2 = malloc(len); + memcpy(buf2, buf, len); - /* or maybe kernel preamble? */ - kern_preamble = (VbKernelPreambleHeader *)(buf + more); - if (VBOOT_SUCCESS == - VerifyKernelPreamble(kern_preamble, len - more, rsa)) - return FILE_TYPE_KERN_PREAMBLE; + struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf; + if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) { + free(buf2); + return FILE_TYPE_UNKNOWN; + } - /* no, just keyblock */ + /* Try unpacking the data key from the keyblock */ + struct vb2_public_key data_key; + if (VB2_SUCCESS != + vb2_unpack_key(&data_key, (const uint8_t *)&keyblock->data_key, + keyblock->data_key.key_offset + + keyblock->data_key.key_size)) { + /* It looks like a bad keyblock, but still a keyblock */ + free(buf2); return FILE_TYPE_KEYBLOCK; } - return FILE_TYPE_UNKNOWN; + uint32_t more = keyblock->keyblock_size; + + /* Followed by firmware preamble too? */ + struct vb2_fw_preamble *pre2 = (struct vb2_fw_preamble *)(buf2 + more); + rv = vb2_verify_fw_preamble(pre2, len - more, &data_key, &wb); + free(buf2); + if (VB2_SUCCESS == rv) + return FILE_TYPE_FW_PREAMBLE; + + /* Or maybe kernel preamble? */ + RSAPublicKey *rsa = PublicKeyToRSA((VbPublicKey *)&keyblock->data_key); + VbKernelPreambleHeader *kern_preamble = + (VbKernelPreambleHeader *)(buf + more); + if (VBOOT_SUCCESS == + VerifyKernelPreamble(kern_preamble, len - more, rsa)) + return FILE_TYPE_KERN_PREAMBLE; + + /* No, just keyblock */ + return FILE_TYPE_KEYBLOCK; } enum futil_file_type ft_recognize_vb1_key(uint8_t *buf, uint32_t len) { - VbPublicKey *pubkey = (VbPublicKey *)buf; + struct vb2_packed_key *pubkey = (struct vb2_packed_key *)buf; VbPrivateKey key; const unsigned char *start; /* Maybe just a VbPublicKey? */ - if (len >= sizeof(VbPublicKey) && PublicKeyLooksOkay(pubkey, len)) + if (packed_key_looks_ok(pubkey, len)) return FILE_TYPE_PUBKEY; /* How about a VbPrivateKey? */ diff --git a/futility/vb1_helper.h b/futility/vb1_helper.h index 59732e7a..fbe36184 100644 --- a/futility/vb1_helper.h +++ b/futility/vb1_helper.h @@ -6,8 +6,18 @@ #ifndef VBOOT_REFERENCE_FUTILITY_VB1_HELPER_H_ #define VBOOT_REFERENCE_FUTILITY_VB1_HELPER_H_ +struct vb2_packed_key; + +/** + * Return the name of the vb1 crypto algorithm + * + * @param algo Crypto algorithm + * @return The name of the algorithm, or "(invalid)" if algo is not valid. + */ +const char *vb1_crypto_name(uint32_t algo); + /* Display a public key with variable indentation */ -void show_pubkey(VbPublicKey *pubkey, const char *sp); +void show_pubkey(const struct vb2_packed_key *pubkey, const char *sp); /* Other random functions needed for backward compatibility */ diff --git a/host/lib/host_key.c b/host/lib/host_key.c index fed579a2..e594b2cd 100644 --- a/host/lib/host_key.c +++ b/host/lib/host_key.c @@ -17,6 +17,7 @@ #include "host_common.h" #include "host_key.h" #include "host_misc.h" +#include "vb2_common.h" #include "vboot_common.h" @@ -196,50 +197,50 @@ VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm, return key; } - -int PublicKeyLooksOkay(VbPublicKey *key, uint64_t file_size) +int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size) { - uint64_t key_size; - - /* Sanity-check key data */ - if (0 != VerifyPublicKeyInside(key, file_size, key)) { - VBDEBUG(("PublicKeyRead() not a VbPublicKey\n")); - return 0; - } - if (key->algorithm >= kNumAlgorithms) { - VBDEBUG(("PublicKeyRead() invalid algorithm\n")); - return 0; - } - if (key->key_version > 0xFFFF) { - VBDEBUG(("PublicKeyRead() invalid version\n")); - return 0; /* Currently, TPM only supports 16-bit version */ - } - if (!RSAProcessedKeySize(key->algorithm, &key_size) || - key_size != key->key_size) { - VBDEBUG(("PublicKeyRead() wrong key size for algorithm\n")); - return 0; - } - - /* Success */ - return 1; + uint64_t key_size; + + if (size < sizeof(*key)) + return 0; + + /* Sanity-check key data */ + if (0 != VerifyPublicKeyInside(key, size, (VbPublicKey *)key)) { + VBDEBUG(("PublicKeyRead() not a VbPublicKey\n")); + return 0; + } + if (key->algorithm >= kNumAlgorithms) { + VBDEBUG(("PublicKeyRead() invalid algorithm\n")); + return 0; + } + if (key->key_version > 0xFFFF) { + VBDEBUG(("PublicKeyRead() invalid version\n")); + return 0; /* Currently, TPM only supports 16-bit version */ + } + if (!RSAProcessedKeySize(key->algorithm, &key_size) || + key_size != key->key_size) { + VBDEBUG(("PublicKeyRead() wrong key size for algorithm\n")); + return 0; + } + + /* Success */ + return 1; } - - VbPublicKey* PublicKeyRead(const char* filename) { - VbPublicKey* key; - uint64_t file_size; + struct vb2_packed_key *key; + uint64_t file_size; - key = (VbPublicKey*)ReadFile(filename, &file_size); - if (!key) - return NULL; + key = (struct vb2_packed_key *)ReadFile(filename, &file_size); + if (!key) + return NULL; - if (PublicKeyLooksOkay(key, file_size)) - return key; + if (packed_key_looks_ok(key, file_size)) + return (VbPublicKey *)key; - /* Error */ - free(key); - return NULL; + /* Error */ + free(key); + return NULL; } int PublicKeyWrite(const char* filename, const VbPublicKey* key) { diff --git a/host/lib/include/host_key.h b/host/lib/include/host_key.h index 9f98ccc3..cdfc81bd 100644 --- a/host/lib/include/host_key.h +++ b/host/lib/include/host_key.h @@ -11,6 +11,7 @@ #include "cryptolib.h" #include "vboot_struct.h" +struct vb2_packed_key; typedef struct rsa_st RSA; @@ -51,8 +52,8 @@ VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm, * Returns NULL if error. */ VbPublicKey* PublicKeyRead(const char* filename); -/* Return true if the public key struct appears correct. */ -int PublicKeyLooksOkay(VbPublicKey *key, uint64_t file_size); +/* Return true if the packed (public) key struct appears correct. */ +int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size); /* Read a public key from a .keyb file. Caller owns the returned * pointer, and must free it with Free(). diff --git a/host/lib/include/util_misc.h b/host/lib/include/util_misc.h index f5db22b9..648f2da8 100644 --- a/host/lib/include/util_misc.h +++ b/host/lib/include/util_misc.h @@ -11,9 +11,20 @@ #include "host_key.h" #include "vboot_struct.h" struct rsa_st; +struct vb2_packed_key; -/* Prints the sha1sum of a VbPublicKey to stdout. */ -void PrintPubKeySha1Sum(VbPublicKey *key); +/** + * Returns the SHA1 digest of the packed key data as a string. + * + * The returned string is a global static buffer, so each call to this + * overwrites the previous digest string. So don't call this more than once + * per printf(). + * + * @param key Key to print digest for + * + * @return A string containing the SHA1 digest. + */ +const char *packed_key_sha1_string(const struct vb2_packed_key *key); /* Prints the sha1sum of a VbPrivateKey to stdout. */ void PrintPrivKeySha1Sum(VbPrivateKey *key); diff --git a/host/lib/util_misc.c b/host/lib/util_misc.c index dbcdc6e1..2b0f91c8 100644 --- a/host/lib/util_misc.c +++ b/host/lib/util_misc.c @@ -20,19 +20,24 @@ #include "cryptolib.h" #include "host_common.h" #include "util_misc.h" +#include "vb2_common.h" #include "vboot_common.h" -void PrintPubKeySha1Sum(VbPublicKey *key) +const char *packed_key_sha1_string(const struct vb2_packed_key *key) { uint8_t *buf = ((uint8_t *)key) + key->key_offset; - uint64_t buflen = key->key_size; + uint32_t buflen = key->key_size; uint8_t digest[VB2_SHA1_DIGEST_SIZE]; + static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1]; + char *dnext = dest; vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest, sizeof(digest)); int i; for (i = 0; i < sizeof(digest); i++) - printf("%02x", digest[i]); + dnext += sprintf(dnext, "%02x", digest[i]); + + return dest; } void PrintPrivKeySha1Sum(VbPrivateKey *key) diff --git a/tests/vb21_api_tests.c b/tests/vb21_api_tests.c index 83ee0f62..cab2d140 100644 --- a/tests/vb21_api_tests.c +++ b/tests/vb21_api_tests.c @@ -51,8 +51,8 @@ static enum { static struct vb2_digest_context hwcrypto_emulation_dc; static int retval_hwcrypto; -static int retval_vb2_load_fw_keyblock; -static int retval_vb2_load_fw_preamble; +static int retval_vb21_load_fw_keyblock; +static int retval_vb21_load_fw_preamble; /* Type of test to reset for */ enum reset_type { @@ -86,8 +86,8 @@ static void reset_common_data(enum reset_type t) memset(&hwcrypto_emulation_dc, 0, sizeof(hwcrypto_emulation_dc)); retval_hwcrypto = VB2_SUCCESS; - retval_vb2_load_fw_keyblock = VB2_SUCCESS; - retval_vb2_load_fw_preamble = VB2_SUCCESS; + retval_vb21_load_fw_keyblock = VB2_SUCCESS; + retval_vb21_load_fw_preamble = VB2_SUCCESS; vb2_private_key_hash(&hash_key, mock_hash_alg); @@ -116,7 +116,7 @@ static void reset_common_data(enum reset_type t) + sd->workbuf_preamble_size; if (t == FOR_EXTEND_HASH || t == FOR_CHECK_HASH) - vb2api_init_hash2(&ctx, test_id, NULL); + vb21api_init_hash(&ctx, test_id, NULL); if (t == FOR_CHECK_HASH) vb2api_extend_hash(&ctx, mock_body, mock_body_size); @@ -124,14 +124,14 @@ static void reset_common_data(enum reset_type t) /* Mocked functions */ -int vb2_load_fw_keyblock(struct vb2_context *ctx) +int vb21_load_fw_keyblock(struct vb2_context *ctx) { - return retval_vb2_load_fw_keyblock; + return retval_vb21_load_fw_keyblock; } -int vb2_load_fw_preamble(struct vb2_context *ctx) +int vb21_load_fw_preamble(struct vb2_context *ctx) { - return retval_vb2_load_fw_preamble; + return retval_vb21_load_fw_preamble; } int vb2ex_hwcrypto_digest_init(enum vb2_hash_algorithm hash_alg, @@ -180,17 +180,17 @@ int vb2ex_hwcrypto_digest_finalize(uint8_t *digest, static void phase3_tests(void) { reset_common_data(FOR_MISC); - TEST_SUCC(vb2api_fw_phase3(&ctx), "phase3 good"); + TEST_SUCC(vb21api_fw_phase3(&ctx), "phase3 good"); reset_common_data(FOR_MISC); - retval_vb2_load_fw_keyblock = VB2_ERROR_MOCK; - TEST_EQ(vb2api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock"); + retval_vb21_load_fw_keyblock = VB2_ERROR_MOCK; + TEST_EQ(vb21api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock"); TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST), VB2_RECOVERY_RO_INVALID_RW, " recovery reason"); reset_common_data(FOR_MISC); - retval_vb2_load_fw_preamble = VB2_ERROR_MOCK; - TEST_EQ(vb2api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock"); + retval_vb21_load_fw_preamble = VB2_ERROR_MOCK; + TEST_EQ(vb21api_fw_phase3(&ctx), VB2_ERROR_MOCK, "phase3 keyblock"); TEST_EQ(vb2_nv_get(&ctx, VB2_NV_RECOVERY_REQUEST), VB2_RECOVERY_RO_INVALID_RW, " recovery reason"); } @@ -208,7 +208,7 @@ static void init_hash_tests(void) sig = (struct vb21_signature *)((uint8_t *)pre + pre->hash_offset); wb_used_before = ctx.workbuf_used; - TEST_SUCC(vb2api_init_hash2(&ctx, test_id, &size), + TEST_SUCC(vb21api_init_hash(&ctx, test_id, &size), "init hash good"); TEST_EQ(sd->workbuf_hash_offset, (wb_used_before + (VB2_WORKBUF_ALIGN - 1)) & @@ -225,7 +225,7 @@ static void init_hash_tests(void) TEST_EQ(sd->hash_remaining_size, mock_body_size, "hash remaining"); wb_used_before = ctx.workbuf_used; - TEST_SUCC(vb2api_init_hash2(&ctx, test_id + 2, NULL), + TEST_SUCC(vb21api_init_hash(&ctx, test_id + 2, NULL), "init hash again"); TEST_EQ(ctx.workbuf_used, wb_used_before, "init hash reuses context"); TEST_EQ(sd->hash_tag, @@ -234,29 +234,29 @@ static void init_hash_tests(void) "hash signature offset 2"); reset_common_data(FOR_MISC); - TEST_EQ(vb2api_init_hash2(&ctx, test_id + 3, &size), + TEST_EQ(vb21api_init_hash(&ctx, test_id + 3, &size), VB2_ERROR_API_INIT_HASH_ID, "init hash invalid id"); reset_common_data(FOR_MISC); sd->workbuf_preamble_size = 0; - TEST_EQ(vb2api_init_hash2(&ctx, test_id, &size), + TEST_EQ(vb21api_init_hash(&ctx, test_id, &size), VB2_ERROR_API_INIT_HASH_PREAMBLE, "init hash preamble"); reset_common_data(FOR_MISC); ctx.workbuf_used = ctx.workbuf_size - sizeof(struct vb2_digest_context) + 8; - TEST_EQ(vb2api_init_hash2(&ctx, test_id, &size), + TEST_EQ(vb21api_init_hash(&ctx, test_id, &size), VB2_ERROR_API_INIT_HASH_WORKBUF, "init hash workbuf"); reset_common_data(FOR_MISC); sig->hash_alg = VB2_HASH_INVALID; - TEST_EQ(vb2api_init_hash2(&ctx, test_id, &size), + TEST_EQ(vb21api_init_hash(&ctx, test_id, &size), VB2_ERROR_SHA_INIT_ALGORITHM, "init hash algorithm"); if (hwcrypto_state == HWCRYPTO_ENABLED) { reset_common_data(FOR_MISC); retval_hwcrypto = VB2_ERROR_MOCK; - TEST_EQ(vb2api_init_hash2(&ctx, test_id, &size), + TEST_EQ(vb21api_init_hash(&ctx, test_id, &size), VB2_ERROR_MOCK, "init hash use hwcrypto"); } } @@ -315,43 +315,43 @@ static void check_hash_tests(void) dc = (struct vb2_digest_context *) (ctx.workbuf + sd->workbuf_hash_offset); - TEST_SUCC(vb2api_check_hash(&ctx), "check hash good"); + TEST_SUCC(vb21api_check_hash(&ctx), "check hash good"); reset_common_data(FOR_CHECK_HASH); sd->hash_tag = 0; - TEST_EQ(vb2api_check_hash(&ctx), + TEST_EQ(vb21api_check_hash(&ctx), VB2_ERROR_API_CHECK_HASH_TAG, "check hash tag"); reset_common_data(FOR_CHECK_HASH); sd->workbuf_hash_size = 0; - TEST_EQ(vb2api_check_hash(&ctx), + TEST_EQ(vb21api_check_hash(&ctx), VB2_ERROR_API_CHECK_HASH_WORKBUF, "check hash no workbuf"); reset_common_data(FOR_CHECK_HASH); sd->hash_remaining_size = 1; - TEST_EQ(vb2api_check_hash(&ctx), + TEST_EQ(vb21api_check_hash(&ctx), VB2_ERROR_API_CHECK_HASH_SIZE, "check hash size"); reset_common_data(FOR_CHECK_HASH); ctx.workbuf_used = ctx.workbuf_size; - TEST_EQ(vb2api_check_hash(&ctx), + TEST_EQ(vb21api_check_hash(&ctx), VB2_ERROR_API_CHECK_HASH_WORKBUF_DIGEST, "check hash workbuf"); reset_common_data(FOR_CHECK_HASH); *((uint8_t *)sig + sig->sig_offset) ^= 0x55; - TEST_EQ(vb2api_check_hash(&ctx), + TEST_EQ(vb21api_check_hash(&ctx), VB2_ERROR_API_CHECK_HASH_SIG, "check hash sig"); if (hwcrypto_state == HWCRYPTO_ENABLED) { reset_common_data(FOR_CHECK_HASH); retval_hwcrypto = VB2_ERROR_MOCK; - TEST_EQ(vb2api_check_hash(&ctx), + TEST_EQ(vb21api_check_hash(&ctx), VB2_ERROR_MOCK, "check hash use hwcrypto"); } else { reset_common_data(FOR_CHECK_HASH); dc->hash_alg = VB2_HASH_INVALID; *((uint8_t *)sig + sig->sig_offset) ^= 0x55; - TEST_EQ(vb2api_check_hash(&ctx), + TEST_EQ(vb21api_check_hash(&ctx), VB2_ERROR_SHA_FINALIZE_ALGORITHM, "check hash finaliz"); } } diff --git a/tests/vb21_misc_tests.c b/tests/vb21_misc_tests.c index d68cf3f8..d7cfbd26 100644 --- a/tests/vb21_misc_tests.c +++ b/tests/vb21_misc_tests.c @@ -114,7 +114,7 @@ static void reset_common_data(enum reset_type t) /* If verifying preamble, verify keyblock first to set up data key */ if (t == FOR_PREAMBLE) - vb2_load_fw_keyblock(&ctx); + vb21_load_fw_keyblock(&ctx); }; /* Mocked functions */ @@ -186,7 +186,7 @@ static void load_keyblock_tests(void) /* Test successful call */ reset_common_data(FOR_KEYBLOCK); wb_used_before = ctx.workbuf_used; - TEST_SUCC(vb2_load_fw_keyblock(&ctx), "keyblock verify"); + TEST_SUCC(vb21_load_fw_keyblock(&ctx), "keyblock verify"); TEST_EQ(sd->fw_version, 0x20000, "keyblock version"); TEST_EQ(sd->vblock_preamble_offset, sizeof(mock_vblock.k), "preamble offset"); @@ -216,69 +216,69 @@ static void load_keyblock_tests(void) /* Test failures */ reset_common_data(FOR_KEYBLOCK); ctx.workbuf_used = ctx.workbuf_size - sd->gbb_rootkey_size + 8; - TEST_EQ(vb2_load_fw_keyblock(&ctx), + TEST_EQ(vb21_load_fw_keyblock(&ctx), VB2_ERROR_FW_KEYBLOCK_WORKBUF_ROOT_KEY, "keyblock not enough workbuf for root key"); reset_common_data(FOR_KEYBLOCK); sd->gbb_rootkey_size = sizeof(mock_gbb); - TEST_EQ(vb2_load_fw_keyblock(&ctx), + TEST_EQ(vb21_load_fw_keyblock(&ctx), VB2_ERROR_EX_READ_RESOURCE_SIZE, "keyblock read root key"); reset_common_data(FOR_KEYBLOCK); mock_unpack_key_retval = VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM; - TEST_EQ(vb2_load_fw_keyblock(&ctx), + TEST_EQ(vb21_load_fw_keyblock(&ctx), VB2_ERROR_UNPACK_KEY_SIG_ALGORITHM, "keyblock unpack root key"); reset_common_data(FOR_KEYBLOCK); ctx.workbuf_used = ctx.workbuf_size - sd->gbb_rootkey_size - 8; - TEST_EQ(vb2_load_fw_keyblock(&ctx), + TEST_EQ(vb21_load_fw_keyblock(&ctx), VB2_ERROR_READ_RESOURCE_OBJECT_BUF, "keyblock not enough workbuf for header"); reset_common_data(FOR_KEYBLOCK); mock_read_res_fail_on_call = 2; - TEST_EQ(vb2_load_fw_keyblock(&ctx), + TEST_EQ(vb21_load_fw_keyblock(&ctx), VB2_ERROR_EX_READ_RESOURCE_INDEX, "keyblock read keyblock header"); reset_common_data(FOR_KEYBLOCK); ctx.workbuf_used = ctx.workbuf_size - sd->gbb_rootkey_size - sizeof(struct vb21_keyblock); - TEST_EQ(vb2_load_fw_keyblock(&ctx), + TEST_EQ(vb21_load_fw_keyblock(&ctx), VB2_ERROR_READ_RESOURCE_OBJECT_BUF, "keyblock not enough workbuf for entire keyblock"); reset_common_data(FOR_KEYBLOCK); kb->c.total_size = sizeof(mock_vblock) + 1; - TEST_EQ(vb2_load_fw_keyblock(&ctx), + TEST_EQ(vb21_load_fw_keyblock(&ctx), VB2_ERROR_EX_READ_RESOURCE_SIZE, "keyblock read keyblock"); reset_common_data(FOR_KEYBLOCK); mock_verify_keyblock_retval = VB2_ERROR_KEYBLOCK_MAGIC; - TEST_EQ(vb2_load_fw_keyblock(&ctx), + TEST_EQ(vb21_load_fw_keyblock(&ctx), VB2_ERROR_KEYBLOCK_MAGIC, "keyblock verify keyblock"); reset_common_data(FOR_KEYBLOCK); dk->key_version = 0x10000; - TEST_EQ(vb2_load_fw_keyblock(&ctx), + TEST_EQ(vb21_load_fw_keyblock(&ctx), VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE, "keyblock version range"); reset_common_data(FOR_KEYBLOCK); dk->key_version = 1; - TEST_EQ(vb2_load_fw_keyblock(&ctx), + TEST_EQ(vb21_load_fw_keyblock(&ctx), VB2_ERROR_FW_KEYBLOCK_VERSION_ROLLBACK, "keyblock rollback"); reset_common_data(FOR_KEYBLOCK); dk->key_version = 1; sd->gbb_flags |= VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK; - TEST_SUCC(vb2_load_fw_keyblock(&ctx), "keyblock rollback + GBB flag"); + TEST_SUCC(vb21_load_fw_keyblock(&ctx), "keyblock rollback + GBB flag"); } static void load_preamble_tests(void) @@ -290,7 +290,7 @@ static void load_preamble_tests(void) /* Test successful call */ reset_common_data(FOR_PREAMBLE); data_key_offset_before = sd->workbuf_data_key_offset; - TEST_SUCC(vb2_load_fw_preamble(&ctx), "preamble good"); + TEST_SUCC(vb21_load_fw_preamble(&ctx), "preamble good"); TEST_EQ(sd->fw_version, 0x20002, "combined version"); TEST_EQ(sd->workbuf_preamble_offset, data_key_offset_before, "preamble offset"); @@ -304,67 +304,67 @@ static void load_preamble_tests(void) /* Expected failures */ reset_common_data(FOR_PREAMBLE); sd->workbuf_data_key_size = 0; - TEST_EQ(vb2_load_fw_preamble(&ctx), + TEST_EQ(vb21_load_fw_preamble(&ctx), VB2_ERROR_FW_PREAMBLE2_DATA_KEY, "preamble no data key"); reset_common_data(FOR_PREAMBLE); mock_unpack_key_retval = VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM; - TEST_EQ(vb2_load_fw_preamble(&ctx), + TEST_EQ(vb21_load_fw_preamble(&ctx), VB2_ERROR_UNPACK_KEY_HASH_ALGORITHM, "preamble unpack data key"); reset_common_data(FOR_PREAMBLE); ctx.workbuf_used = ctx.workbuf_size - sizeof(struct vb21_fw_preamble) + 8; - TEST_EQ(vb2_load_fw_preamble(&ctx), + TEST_EQ(vb21_load_fw_preamble(&ctx), VB2_ERROR_READ_RESOURCE_OBJECT_BUF, "preamble not enough workbuf for header"); reset_common_data(FOR_PREAMBLE); sd->vblock_preamble_offset = sizeof(mock_vblock); - TEST_EQ(vb2_load_fw_preamble(&ctx), + TEST_EQ(vb21_load_fw_preamble(&ctx), VB2_ERROR_EX_READ_RESOURCE_SIZE, "preamble read header"); reset_common_data(FOR_PREAMBLE); ctx.workbuf_used = ctx.workbuf_size - sizeof(mock_vblock.p) + 8; - TEST_EQ(vb2_load_fw_preamble(&ctx), + TEST_EQ(vb21_load_fw_preamble(&ctx), VB2_ERROR_READ_RESOURCE_OBJECT_BUF, "preamble not enough workbuf"); reset_common_data(FOR_PREAMBLE); pre->c.total_size = sizeof(mock_vblock); - TEST_EQ(vb2_load_fw_preamble(&ctx), + TEST_EQ(vb21_load_fw_preamble(&ctx), VB2_ERROR_EX_READ_RESOURCE_SIZE, "preamble read full"); reset_common_data(FOR_PREAMBLE); mock_verify_preamble_retval = VB2_ERROR_PREAMBLE_SIG_INVALID; - TEST_EQ(vb2_load_fw_preamble(&ctx), + TEST_EQ(vb21_load_fw_preamble(&ctx), VB2_ERROR_PREAMBLE_SIG_INVALID, "preamble verify"); reset_common_data(FOR_PREAMBLE); pre->fw_version = 0x10000; - TEST_EQ(vb2_load_fw_preamble(&ctx), + TEST_EQ(vb21_load_fw_preamble(&ctx), VB2_ERROR_FW_PREAMBLE_VERSION_RANGE, "preamble version range"); reset_common_data(FOR_PREAMBLE); pre->fw_version = 1; - TEST_EQ(vb2_load_fw_preamble(&ctx), + TEST_EQ(vb21_load_fw_preamble(&ctx), VB2_ERROR_FW_PREAMBLE_VERSION_ROLLBACK, "preamble version rollback"); reset_common_data(FOR_PREAMBLE); pre->fw_version = 1; sd->gbb_flags |= VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK; - TEST_SUCC(vb2_load_fw_preamble(&ctx), "version rollback with GBB flag"); + TEST_SUCC(vb21_load_fw_preamble(&ctx), "version rollback with GBB flag"); reset_common_data(FOR_PREAMBLE); pre->fw_version = 3; - TEST_SUCC(vb2_load_fw_preamble(&ctx), + TEST_SUCC(vb21_load_fw_preamble(&ctx), "preamble version roll forward"); vb2_secdata_get(&ctx, VB2_SECDATA_VERSIONS, &v); TEST_EQ(v, 0x20003, "roll forward"); @@ -373,7 +373,7 @@ static void load_preamble_tests(void) reset_common_data(FOR_PREAMBLE); pre->fw_version = 3; sd->last_fw_result = VB2_FW_RESULT_UNKNOWN; - TEST_SUCC(vb2_load_fw_preamble(&ctx), + TEST_SUCC(vb21_load_fw_preamble(&ctx), "preamble version no roll forward 1"); vb2_secdata_get(&ctx, VB2_SECDATA_VERSIONS, &v); TEST_EQ(v, 0x20002, "no roll forward"); @@ -382,7 +382,7 @@ static void load_preamble_tests(void) reset_common_data(FOR_PREAMBLE); pre->fw_version = 3; sd->last_fw_slot = 1; - TEST_SUCC(vb2_load_fw_preamble(&ctx), + TEST_SUCC(vb21_load_fw_preamble(&ctx), "preamble version no roll forward 2"); vb2_secdata_get(&ctx, VB2_SECDATA_VERSIONS, &v); TEST_EQ(v, 0x20002, "no roll forward"); diff --git a/tests/vboot_common3_tests.c b/tests/vboot_common3_tests.c index 7ae7eb27..1eba971c 100644 --- a/tests/vboot_common3_tests.c +++ b/tests/vboot_common3_tests.c @@ -155,127 +155,6 @@ static void KeyBlockVerifyTest(const VbPublicKey *public_key, free(hdr); } -static void ReSignFirmwarePreamble(VbFirmwarePreambleHeader *h, - const VbPrivateKey *key) -{ - VbSignature *sig = CalculateSignature( - (const uint8_t *)h, h->preamble_signature.data_size, key); - - SignatureCopy(&h->preamble_signature, sig); - free(sig); -} - -static void VerifyFirmwarePreambleTest(const VbPublicKey *public_key, - const VbPrivateKey *private_key, - const VbPublicKey *kernel_subkey) -{ - VbFirmwarePreambleHeader *hdr; - VbFirmwarePreambleHeader *h; - RSAPublicKey *rsa; - unsigned hsize; - - /* Create a dummy signature */ - VbSignature* body_sig = SignatureAlloc(56, 78); - - rsa = PublicKeyToRSA(public_key); - hdr = CreateFirmwarePreamble(0x1234, kernel_subkey, body_sig, - private_key, 0x5678); - TEST_NEQ(hdr && rsa, 0, "VerifyFirmwarePreamble() prerequisites"); - if (!hdr) - return; - hsize = (unsigned) hdr->preamble_size; - h = (VbFirmwarePreambleHeader *)malloc(hsize + 16384); - - TEST_EQ(VerifyFirmwarePreamble(hdr, hsize, rsa), 0, - "VerifyFirmwarePreamble() ok using key"); - TEST_NEQ(VerifyFirmwarePreamble(hdr, 4, rsa), 0, - "VerifyFirmwarePreamble() size tiny"); - TEST_NEQ(VerifyFirmwarePreamble(hdr, hsize - 1, rsa), 0, - "VerifyFirmwarePreamble() size--"); - TEST_EQ(VerifyFirmwarePreamble(hdr, hsize + 1, rsa), 0, - "VerifyFirmwarePreamble() size++"); - - /* Care about major version but not minor */ - Memcpy(h, hdr, hsize); - h->header_version_major++; - ReSignFirmwarePreamble(h, private_key); - TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, - "VerifyFirmwarePreamble() major++"); - - Memcpy(h, hdr, hsize); - h->header_version_major--; - ReSignFirmwarePreamble(h, private_key); - TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, - "VerifyFirmwarePreamble() major--"); - - Memcpy(h, hdr, hsize); - h->header_version_minor++; - ReSignFirmwarePreamble(h, private_key); - TEST_EQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, - "VerifyFirmwarePreamble() minor++"); - - Memcpy(h, hdr, hsize); - h->header_version_minor--; - ReSignFirmwarePreamble(h, private_key); - TEST_EQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, - "VerifyFirmwarePreamble() minor--"); - - /* Check signature */ - Memcpy(h, hdr, hsize); - h->preamble_signature.sig_offset = hsize; - ReSignFirmwarePreamble(h, private_key); - TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, - "VerifyFirmwarePreamble() sig off end"); - - Memcpy(h, hdr, hsize); - h->preamble_signature.sig_size--; - ReSignFirmwarePreamble(h, private_key); - TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, - "VerifyFirmwarePreamble() sig too small"); - - Memcpy(h, hdr, hsize); - GetPublicKeyData(&h->kernel_subkey)[0] ^= 0x34; - TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, - "VerifyFirmwarePreamble() sig mismatch"); - - /* Check that we signed header, kernel subkey, and body sig */ - Memcpy(h, hdr, hsize); - h->preamble_signature.data_size = 4; - h->kernel_subkey.key_offset = 0; - h->kernel_subkey.key_size = 0; - h->body_signature.sig_offset = 0; - h->body_signature.sig_size = 0; - ReSignFirmwarePreamble(h, private_key); - TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, - "VerifyFirmwarePreamble() didn't sign header"); - - Memcpy(h, hdr, hsize); - h->kernel_subkey.key_offset = hsize; - ReSignFirmwarePreamble(h, private_key); - TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, - "VerifyFirmwarePreamble() kernel subkey off end"); - - Memcpy(h, hdr, hsize); - h->body_signature.sig_offset = hsize; - ReSignFirmwarePreamble(h, private_key); - TEST_NEQ(VerifyFirmwarePreamble(h, hsize, rsa), 0, - "VerifyFirmwarePreamble() body sig off end"); - - /* Check that we return flags properly for new and old structs */ - Memcpy(h, hdr, hsize); - TEST_EQ(VbGetFirmwarePreambleFlags(h), 0x5678, - "VbGetFirmwarePreambleFlags() v2.1"); - h->header_version_minor = 0; - TEST_EQ(VbGetFirmwarePreambleFlags(h), 0, - "VbGetFirmwarePreambleFlags() v2.0"); - - /* TODO: verify with extra padding at end of header. */ - - free(h); - RSAPublicKeyFree(rsa); - free(hdr); -} - int test_permutation(int signing_key_algorithm, int data_key_algorithm, const char *keys_dir) { @@ -321,8 +200,6 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm, KeyBlockVerifyTest(signing_public_key, signing_private_key, data_public_key); - VerifyFirmwarePreambleTest(signing_public_key, signing_private_key, - data_public_key); if (signing_public_key) free(signing_public_key); |