From f7559e4b4652134b1e15de3ce31ee50a3de00f69 Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Thu, 23 Jun 2016 13:45:59 -0700 Subject: futility: Use vboot 2.0 APIs for public keys This replaces calls to the old vboot 1 APIs with their vboot 2.0 equivalents. BUG=chromium:611535 BRANCH=none TEST=make runtests Change-Id: Ieb1a127577c6428c47ac088c3aaa0d0dad6275a8 Signed-off-by: Randall Spangler Reviewed-on: https://chromium-review.googlesource.com/356541 Reviewed-by: Daisuke Nojiri --- firmware/2lib/include/2return_codes.h | 6 ++ firmware/lib20/include/vb2_struct.h | 9 +++ firmware/lib20/kernel.c | 4 +- firmware/lib20/misc.c | 4 +- futility/cmd_create.c | 12 ++-- futility/cmd_sign.c | 38 +++++------ futility/cmd_vbutil_firmware.c | 11 ++- futility/cmd_vbutil_kernel.c | 4 +- futility/cmd_vbutil_key.c | 42 +++++------- futility/cmd_vbutil_keyblock.c | 12 ++-- futility/file_type_bios.c | 13 ++-- futility/futility_options.h | 4 +- futility/vb1_helper.c | 55 ++++++++------- futility/vb1_helper.h | 2 +- host/lib/host_common2.c | 17 +++-- host/lib/host_key.c | 122 ++++++---------------------------- host/lib/host_key2.c | 77 +++++++++++++++++++++ host/lib/include/host_key.h | 67 +++++++++++++------ host/lib/include/util_misc.h | 4 +- host/linktest/main.c | 6 -- tests/vb20_common2_tests.c | 3 +- tests/vb20_common3_tests.c | 21 +++--- tests/vboot_common2_tests.c | 6 +- tests/vboot_common3_tests.c | 8 +-- tests/verify_kernel.c | 2 +- 25 files changed, 296 insertions(+), 253 deletions(-) diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h index e0bc6f22..af867267 100644 --- a/firmware/2lib/include/2return_codes.h +++ b/firmware/2lib/include/2return_codes.h @@ -676,6 +676,12 @@ enum vb2_return_code { /* Unable to convert back to vb1 crypto algorithm */ VB2_ERROR_VB1_CRYPTO_ALGORITHM, + /* Unable to allocate packed key */ + VB2_ERROR_PACKED_KEY_ALLOC, + + /* Unable to copy packed key */ + VB2_ERROR_PACKED_KEY_COPY, + /********************************************************************** * Errors generated by host library signature functions */ diff --git a/firmware/lib20/include/vb2_struct.h b/firmware/lib20/include/vb2_struct.h index 5220fa36..4f5d9995 100644 --- a/firmware/lib20/include/vb2_struct.h +++ b/firmware/lib20/include/vb2_struct.h @@ -17,6 +17,15 @@ #define VBOOT_REFERENCE_VB2_STRUCT_H_ #include +/* + * Rollback protection currently uses a 32-bit value comprised of the bottom 16 + * bits of the (firmware or kernel) preamble version and the bottom 16 bits of + * the key version. So each of those versions is effectively limited to 16 + * bits even though they get stored in 32-bit fields. + */ +#define VB2_MAX_KEY_VERSION 0xffff +#define VB2_MAX_PREAMBLE_VERSION 0xffff + /* Packed public key data */ struct vb2_packed_key { /* Offset of key data from start of this struct */ diff --git a/firmware/lib20/kernel.c b/firmware/lib20/kernel.c index 4ded5d55..c50614df 100644 --- a/firmware/lib20/kernel.c +++ b/firmware/lib20/kernel.c @@ -185,7 +185,7 @@ int vb2_load_kernel_keyblock(struct vb2_context *ctx) /* Check for keyblock rollback if not in recovery mode */ /* Key version is the upper 16 bits of the composite version */ - if (!rec_switch && kb->data_key.key_version > 0xffff) { + if (!rec_switch && kb->data_key.key_version > VB2_MAX_KEY_VERSION) { keyblock_is_valid = 0; if (need_keyblock_valid) return VB2_ERROR_KERNEL_KEYBLOCK_VERSION_RANGE; @@ -419,7 +419,7 @@ int vb2_load_kernel_preamble(struct vb2_context *ctx) * Kernel preamble version is the lower 16 bits of the composite kernel * version. */ - if (pre->kernel_version > 0xffff) + if (pre->kernel_version > VB2_MAX_PREAMBLE_VERSION) return VB2_ERROR_KERNEL_PREAMBLE_VERSION_RANGE; /* Combine with the key version from vb2_load_kernel_keyblock() */ diff --git a/firmware/lib20/misc.c b/firmware/lib20/misc.c index cdbd0127..dee6b139 100644 --- a/firmware/lib20/misc.c +++ b/firmware/lib20/misc.c @@ -134,7 +134,7 @@ int vb2_load_fw_keyblock(struct vb2_context *ctx) } /* Key version is the upper 16 bits of the composite firmware version */ - if (kb->data_key.key_version > 0xffff) + if (kb->data_key.key_version > VB2_MAX_KEY_VERSION) rv = VB2_ERROR_FW_KEYBLOCK_VERSION_RANGE; if (!rv && kb->data_key.key_version < (sd->fw_version_secdata >> 16)) { if (sd->gbb_flags & VB2_GBB_FLAG_DISABLE_FW_ROLLBACK_CHECK) @@ -253,7 +253,7 @@ int vb2_load_fw_preamble(struct vb2_context *ctx) * Firmware version is the lower 16 bits of the composite firmware * version. */ - if (pre->firmware_version > 0xffff) + if (pre->firmware_version > VB2_MAX_PREAMBLE_VERSION) rv = VB2_ERROR_FW_PREAMBLE_VERSION_RANGE; /* Combine with the key version from vb2_load_fw_keyblock() */ sd->fw_version |= pre->firmware_version; diff --git a/futility/cmd_create.c b/futility/cmd_create.c index 748ce2f7..c8219511 100644 --- a/futility/cmd_create.c +++ b/futility/cmd_create.c @@ -15,6 +15,7 @@ #include "2rsa.h" #include "2sha.h" #include "util_misc.h" +#include "vb2_common.h" #include "vb21_common.h" #include "host_key.h" @@ -81,7 +82,7 @@ static void print_help(int argc, char *argv[]) static int vb1_make_keypair() { struct vb2_private_key *privkey = NULL; - VbPublicKey *pubkey = 0; + struct vb2_packed_key *pubkey = NULL; struct rsa_st *rsa_key = NULL; uint8_t *keyb_data = 0; uint32_t keyb_size; @@ -136,14 +137,14 @@ static int vb1_make_keypair() goto done; } - pubkey = PublicKeyAlloc(keyb_size, vb1_algorithm, opt_version); + pubkey = vb2_alloc_packed_key(keyb_size, vb1_algorithm, opt_version); if (!pubkey) goto done; - memcpy(GetPublicKeyData(pubkey), keyb_data, keyb_size); + memcpy((uint8_t *)vb2_packed_key_data(pubkey), keyb_data, keyb_size); /* Write it out */ strcpy(outext, ".vbpubk"); - if (0 != PublicKeyWrite(outfile, pubkey)) { + if (VB2_SUCCESS != vb2_write_packed_key(outfile, pubkey)) { fprintf(stderr, "unable to write public key\n"); goto done; } @@ -214,7 +215,8 @@ static int vb2_make_keypair() privkey->sig_alg = sig_alg; privkey->hash_alg = opt_hash_alg; if (opt_desc && vb2_private_key_set_desc(privkey, opt_desc)) { - fprintf(stderr, "Unable to set the private key description\n"); + fprintf(stderr, + "Unable to set the private key description\n"); goto done; } } diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c index 3ff6ddac..0792081e 100644 --- a/futility/cmd_sign.c +++ b/futility/cmd_sign.c @@ -78,22 +78,22 @@ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data) sign_option.flags, sign_option.pem_external); } else { - sign_option.signprivate2 = vb2_read_private_key_pem( + sign_option.signprivate = vb2_read_private_key_pem( sign_option.pem_signpriv, sign_option.pem_algo); - if (!sign_option.signprivate2) { + if (!sign_option.signprivate) { fprintf(stderr, "Unable to read PEM signing key: %s\n", strerror(errno)); return 1; } block = vb2_create_keyblock(data_key, - sign_option.signprivate2, + sign_option.signprivate, sign_option.flags); } } else { /* Not PEM. Should already have a signing key. */ - block = vb2_create_keyblock(data_key, sign_option.signprivate2, + block = vb2_create_keyblock(data_key, sign_option.signprivate, sign_option.flags); } @@ -130,7 +130,7 @@ int ft_sign_raw_kernel(const char *name, uint8_t *buf, uint32_t len, sign_option.version, sign_option.kloadaddr, sign_option.keyblock, - sign_option.signprivate2, + sign_option.signprivate, sign_option.flags, &vblock_size); if (!vblock_data) { fprintf(stderr, "Unable to sign kernel blob\n"); @@ -217,7 +217,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len, sign_option.version, sign_option.kloadaddr, keyblock, - sign_option.signprivate2, + sign_option.signprivate, sign_option.flags, &vblock_size); if (!vblock_data) { @@ -255,7 +255,7 @@ int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len, struct vb2_fw_preamble *preamble; int rv; - body_sig = vb2_calculate_signature(buf, len, sign_option.signprivate2); + body_sig = vb2_calculate_signature(buf, len, sign_option.signprivate); if (!body_sig) { fprintf(stderr, "Error calculating body signature\n"); return 1; @@ -265,7 +265,7 @@ int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len, sign_option.version, (struct vb2_packed_key *)sign_option.kernel_subkey, body_sig, - sign_option.signprivate2, + sign_option.signprivate, sign_option.flags); if (!preamble) { fprintf(stderr, "Error creating firmware preamble.\n"); @@ -654,8 +654,8 @@ static int do_sign(int argc, char *argv[]) &longindex)) != -1) { switch (i) { case 's': - sign_option.signprivate2 = vb2_read_private_key(optarg); - if (!sign_option.signprivate2) { + sign_option.signprivate = vb2_read_private_key(optarg); + if (!sign_option.signprivate) { fprintf(stderr, "Error reading %s\n", optarg); errorcnt++; } @@ -668,7 +668,7 @@ static int do_sign(int argc, char *argv[]) } break; case 'k': - sign_option.kernel_subkey = PublicKeyRead(optarg); + sign_option.kernel_subkey = vb2_read_packed_key(optarg); if (!sign_option.kernel_subkey) { fprintf(stderr, "Error reading %s\n", optarg); errorcnt++; @@ -908,13 +908,13 @@ static int do_sign(int argc, char *argv[]) switch (sign_option.type) { case FILE_TYPE_PUBKEY: sign_option.create_new_outfile = 1; - if (sign_option.signprivate2 && sign_option.pem_signpriv) { + if (sign_option.signprivate && sign_option.pem_signpriv) { fprintf(stderr, "Only one of --signprivate and --pem_signpriv" " can be specified\n"); errorcnt++; } - if ((sign_option.signprivate2 && + if ((sign_option.signprivate && sign_option.pem_algo_specified) || (sign_option.pem_signpriv && !sign_option.pem_algo_specified)) { @@ -932,18 +932,18 @@ static int do_sign(int argc, char *argv[]) break; case FILE_TYPE_BIOS_IMAGE: case FILE_TYPE_OLD_BIOS_IMAGE: - errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate"); + errorcnt += no_opt_if(!sign_option.signprivate, "signprivate"); errorcnt += no_opt_if(!sign_option.keyblock, "keyblock"); errorcnt += no_opt_if(!sign_option.kernel_subkey, "kernelkey"); break; case FILE_TYPE_KERN_PREAMBLE: - errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate"); + errorcnt += no_opt_if(!sign_option.signprivate, "signprivate"); if (sign_option.vblockonly || sign_option.inout_file_count > 1) sign_option.create_new_outfile = 1; break; case FILE_TYPE_RAW_FIRMWARE: sign_option.create_new_outfile = 1; - errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate"); + errorcnt += no_opt_if(!sign_option.signprivate, "signprivate"); errorcnt += no_opt_if(!sign_option.keyblock, "keyblock"); errorcnt += no_opt_if(!sign_option.kernel_subkey, "kernelkey"); errorcnt += no_opt_if(!sign_option.version_specified, @@ -951,7 +951,7 @@ static int do_sign(int argc, char *argv[]) break; case FILE_TYPE_RAW_KERNEL: sign_option.create_new_outfile = 1; - errorcnt += no_opt_if(!sign_option.signprivate2, "signprivate"); + errorcnt += no_opt_if(!sign_option.signprivate, "signprivate"); errorcnt += no_opt_if(!sign_option.keyblock, "keyblock"); errorcnt += no_opt_if(!sign_option.version_specified, "version"); @@ -1044,8 +1044,8 @@ done: strerror(errno)); } - if (sign_option.signprivate2) - free(sign_option.signprivate2); + if (sign_option.signprivate) + free(sign_option.signprivate); if (sign_option.keyblock) free(sign_option.keyblock); if (sign_option.kernel_subkey) diff --git a/futility/cmd_vbutil_firmware.c b/futility/cmd_vbutil_firmware.c index 4f44426b..950690a0 100644 --- a/futility/cmd_vbutil_firmware.c +++ b/futility/cmd_vbutil_firmware.c @@ -285,12 +285,11 @@ static int do_verify(const char *infile, const char *signpubkey, return 1; } - if (kernelkey_file) { - if (0 != PublicKeyWrite(kernelkey_file, - (struct VbPublicKey *)kernel_subkey)) { - VbExError("Unable to write kernel subkey\n"); - return 1; - } + if (kernelkey_file && + VB2_SUCCESS != vb2_write_packed_key(kernelkey_file, + kernel_subkey)) { + VbExError("Unable to write kernel subkey\n"); + return 1; } return 0; diff --git a/futility/cmd_vbutil_kernel.c b/futility/cmd_vbutil_kernel.c index 274ea75f..cc6b83c0 100644 --- a/futility/cmd_vbutil_kernel.c +++ b/futility/cmd_vbutil_kernel.c @@ -240,7 +240,7 @@ static int do_vbutil_kernel(int argc, char *argv[]) struct vb2_keyblock *keyblock = NULL; struct vb2_keyblock *t_keyblock = NULL; struct vb2_private_key *signpriv_key = NULL; - VbPublicKey *signpub_key = NULL; + struct vb2_packed_key *signpub_key = NULL; uint8_t *kpart_data = NULL; uint64_t kpart_size = 0; uint8_t *vmlinuz_buf = NULL; @@ -547,7 +547,7 @@ static int do_vbutil_kernel(int argc, char *argv[]) /* Optional */ if (signpubkey_file) { - signpub_key = PublicKeyRead(signpubkey_file); + signpub_key = vb2_read_packed_key(signpubkey_file); if (!signpub_key) Fatal("Error reading public key.\n"); } diff --git a/futility/cmd_vbutil_key.c b/futility/cmd_vbutil_key.c index 7f61e0a5..58f724c7 100644 --- a/futility/cmd_vbutil_key.c +++ b/futility/cmd_vbutil_key.c @@ -76,16 +76,15 @@ static void print_help(int argc, char *argv[]) static int do_pack(const char *infile, const char *outfile, uint32_t algorithm, uint32_t version) { - VbPublicKey *pubkey; - if (!infile || !outfile) { fprintf(stderr, "vbutil_key: Must specify --in and --out\n"); return 1; } - pubkey = PublicKeyReadKeyb(infile, algorithm, version); + struct vb2_packed_key *pubkey = + vb2_read_packed_keyb(infile, algorithm, version); if (pubkey) { - if (0 != PublicKeyWrite(outfile, pubkey)) { + if (0 != vb2_write_packed_key(outfile, pubkey)) { fprintf(stderr, "vbutil_key: Error writing key.\n"); return 1; } @@ -111,28 +110,26 @@ static int do_pack(const char *infile, const char *outfile, uint32_t algorithm, /* Unpack a .vbpubk or .vbprivk */ static int do_unpack(const char *infile, const char *outfile) { - VbPublicKey *pubkey; + struct vb2_packed_key *pubkey; if (!infile) { fprintf(stderr, "Need file to unpack\n"); return 1; } - pubkey = PublicKeyRead(infile); + pubkey = vb2_read_packed_key(infile); if (pubkey) { printf("Public Key file: %s\n", infile); - printf("Algorithm: %" PRIu64 " %s\n", pubkey->algorithm, + printf("Algorithm: %u %s\n", pubkey->algorithm, vb1_crypto_name(pubkey->algorithm)); - printf("Key Version: %" PRIu64 "\n", pubkey->key_version); + printf("Key Version: %u\n", pubkey->key_version); printf("Key sha1sum: %s\n", - packed_key_sha1_string((struct vb2_packed_key *)pubkey)); - if (outfile) { - if (0 != PublicKeyWrite(outfile, pubkey)) { - fprintf(stderr, - "vbutil_key: Error writing key copy\n"); - free(pubkey); - return 1; - } + packed_key_sha1_string(pubkey)); + if (outfile && + VB2_SUCCESS != vb2_write_packed_key(outfile, pubkey)) { + fprintf(stderr, "butil_key: Error writing key copy\n"); + free(pubkey); + return 1; } free(pubkey); return 0; @@ -146,14 +143,11 @@ static int do_unpack(const char *infile, const char *outfile) vb2_get_crypto_algorithm(privkey->hash_alg, privkey->sig_alg); printf("Algorithm: %u %s\n", alg, vb1_crypto_name(alg)); - if (outfile) { - if (VB2_SUCCESS != - vb2_write_private_key(outfile, privkey)) { - fprintf(stderr, - "vbutil_key: Error writing key copy\n"); - free(privkey); - return 1; - } + if (outfile && + VB2_SUCCESS != vb2_write_private_key(outfile, privkey)) { + fprintf(stderr,"vbutil_key: Error writing key copy\n"); + free(privkey); + return 1; } free(privkey); return 0; diff --git a/futility/cmd_vbutil_keyblock.c b/futility/cmd_vbutil_keyblock.c index 27624931..246616b8 100644 --- a/futility/cmd_vbutil_keyblock.c +++ b/futility/cmd_vbutil_keyblock.c @@ -225,14 +225,12 @@ static int Unpack(const char *infile, const char *datapubkey, vb1_crypto_name(data_key->algorithm)); printf("Data key version: %u\n", data_key->key_version); printf("Data key sha1sum: %s\n", - packed_key_sha1_string((struct vb2_packed_key *)data_key)); + packed_key_sha1_string(data_key)); - if (datapubkey) { - if (0 != PublicKeyWrite(datapubkey, (VbPublicKey *)data_key)) { - fprintf(stderr, "vbutil_keyblock:" - " unable to write public key\n"); - return 1; - } + if (datapubkey && + VB2_SUCCESS != vb2_write_packed_key(datapubkey, data_key)) { + fprintf(stderr, "vbutil_keyblock: error writing public key\n"); + return 1; } free(block); diff --git a/futility/file_type_bios.c b/futility/file_type_bios.c index 118b0aa3..ce6371d2 100644 --- a/futility/file_type_bios.c +++ b/futility/file_type_bios.c @@ -56,7 +56,6 @@ 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; - struct vb2_packed_key *pubkey; BmpBlockHeader *bmp; int retval = 0; uint32_t maxlen = 0; @@ -96,7 +95,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 = (struct vb2_packed_key *)(buf + gbb->rootkey_offset); + struct vb2_packed_key *pubkey = + (struct vb2_packed_key *)(buf + gbb->rootkey_offset); if (packed_key_looks_ok(pubkey, gbb->rootkey_size)) { if (state) { state->rootkey.offset = @@ -282,8 +282,9 @@ static int fmap_sign_fw_preamble(const char *name, uint8_t *buf, uint32_t len, goto whatever; } - RSAPublicKey *rsa = PublicKeyToRSA((VbPublicKey *)&keyblock->data_key); - if (!rsa) { + if (!packed_key_looks_ok(&keyblock->data_key, + keyblock->data_key.key_offset + + keyblock->data_key.key_size)) { fprintf(stderr, "Warning: %s public key is invalid. " "Signing the entire FW FMAP region...\n", name); goto whatever; @@ -424,13 +425,13 @@ static int sign_bios_at_end(struct bios_state_s *state) sign_option.devkeyblock); } else { retval |= write_new_preamble(vblock_a, fw_a, - sign_option.signprivate2, + sign_option.signprivate, sign_option.keyblock); } /* FW B is always normal keys */ retval |= write_new_preamble(vblock_b, fw_b, - sign_option.signprivate2, + sign_option.signprivate, sign_option.keyblock); diff --git a/futility/futility_options.h b/futility/futility_options.h index 4739f04a..6ac95b12 100644 --- a/futility/futility_options.h +++ b/futility/futility_options.h @@ -33,9 +33,9 @@ struct show_option_s { extern struct show_option_s show_option; struct sign_option_s { - struct vb2_private_key *signprivate2; + struct vb2_private_key *signprivate; struct vb2_keyblock *keyblock; - VbPublicKey *kernel_subkey; + struct vb2_packed_key *kernel_subkey; struct vb2_private_key *devsignprivate; struct vb2_keyblock *devkeyblock; uint32_t version; diff --git a/futility/vb1_helper.c b/futility/vb1_helper.c index 2ec77501..314fd02e 100644 --- a/futility/vb1_helper.c +++ b/futility/vb1_helper.c @@ -502,17 +502,16 @@ int WriteSomeParts(const char *outfile, /* Returns 0 on success */ int VerifyKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size, - VbPublicKey *signpub_key, + struct vb2_packed_key *signpub_key, const char *keyblock_outfile, uint64_t min_version) { - RSAPublicKey *rsa; int rv = -1; uint64_t vmlinuz_header_size = 0; uint64_t vmlinuz_header_address = 0; - static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]; - static struct vb2_workbuf wb; + uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]; + struct vb2_workbuf wb; vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); if (signpub_key) { @@ -585,15 +584,18 @@ int VerifyKernelBlob(uint8_t *kernel_blob, goto done; } - rsa = PublicKeyToRSA((VbPublicKey *)data_key); - if (!rsa) { + struct vb2_public_key pubkey; + if (VB2_SUCCESS != + vb2_unpack_key(&pubkey, (uint8_t *)data_key, + data_key->key_offset + data_key->key_size)) { fprintf(stderr, "Error parsing data key.\n"); goto done; } /* Verify preamble */ - if (0 != VerifyKernelPreamble(g_preamble, - g_preamble->preamble_size, rsa)) { + if (VB2_SUCCESS != vb2_verify_kernel_preamble( + (struct vb2_kernel_preamble *)g_preamble, + g_preamble->preamble_size, &pubkey, &wb)) { fprintf(stderr, "Error verifying preamble.\n"); goto done; } @@ -642,8 +644,10 @@ int VerifyKernelBlob(uint8_t *kernel_blob, } /* Verify body */ - if (0 != VerifyData(kernel_blob, kernel_size, - &g_preamble->body_signature, rsa)) { + if (VB2_SUCCESS != + vb2_verify_data(kernel_blob, kernel_size, + (struct vb2_signature *)&g_preamble->body_signature, + &pubkey, &wb)) { fprintf(stderr, "Error verifying kernel body.\n"); goto done; } @@ -749,17 +753,14 @@ uint8_t *CreateKernelBlob(uint8_t *vmlinuz_buf, uint64_t vmlinuz_size, enum futil_file_type ft_recognize_vblock1(uint8_t *buf, uint32_t len) { - int rv; - - uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]; + uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE]; struct vb2_workbuf wb; vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); /* Vboot 2.0 signature checks destroy the buffer, so make a copy */ uint8_t *buf2 = malloc(len); memcpy(buf2, buf, len); - - struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf; + struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf2; if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) { free(buf2); return FILE_TYPE_UNKNOWN; @@ -780,18 +781,26 @@ enum futil_file_type ft_recognize_vblock1(uint8_t *buf, uint32_t len) /* 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) + if (VB2_SUCCESS == + vb2_verify_fw_preamble(pre2, len - more, &data_key, &wb)) { + free(buf2); return FILE_TYPE_FW_PREAMBLE; + } + + /* Recopy since firmware preamble check destroyed the buffer */ + memcpy(buf2, buf, len); /* 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)) + struct vb2_kernel_preamble *kern_preamble = + (struct vb2_kernel_preamble *)(buf2 + more); + if (VB2_SUCCESS == + vb2_verify_kernel_preamble(kern_preamble, len - more, + &data_key, &wb)) { + free(buf2); return FILE_TYPE_KERN_PREAMBLE; + } + + free(buf2); /* No, just keyblock */ return FILE_TYPE_KEYBLOCK; diff --git a/futility/vb1_helper.h b/futility/vb1_helper.h index 1c59da53..e8a4f5d1 100644 --- a/futility/vb1_helper.h +++ b/futility/vb1_helper.h @@ -53,7 +53,7 @@ int UpdateKernelBlobConfig(uint8_t *kblob_data, uint64_t kblob_size, int VerifyKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size, - VbPublicKey *signpub_key, + struct vb2_packed_key *signpub_key, const char *keyblock_outfile, uint64_t min_version); diff --git a/host/lib/host_common2.c b/host/lib/host_common2.c index ae02b8ba..fed2097a 100644 --- a/host/lib/host_common2.c +++ b/host/lib/host_common2.c @@ -49,15 +49,22 @@ struct vb2_fw_preamble *vb2_create_fw_preamble( h->flags = flags; /* Copy data key */ - PublicKeyInit((VbPublicKey *)&h->kernel_subkey, kernel_subkey_dest, - kernel_subkey->key_size); - PublicKeyCopy((VbPublicKey *)&h->kernel_subkey, - (VbPublicKey *)kernel_subkey); + vb2_init_packed_key(&h->kernel_subkey, kernel_subkey_dest, + kernel_subkey->key_size); + if (VB2_SUCCESS != + vb2_copy_packed_key(&h->kernel_subkey, kernel_subkey)) { + free(h); + return NULL; + } /* Copy body signature */ vb2_init_signature(&h->body_signature, body_sig_dest, body_signature->sig_size, 0); - vb2_copy_signature(&h->body_signature, body_signature); + if (VB2_SUCCESS != + vb2_copy_signature(&h->body_signature, body_signature)) { + free(h); + return NULL; + } /* Set up signature struct so we can calculate the signature */ vb2_init_signature(&h->preamble_signature, block_sig_dest, diff --git a/host/lib/host_key.c b/host/lib/host_key.c index a8b05b53..02744477 100644 --- a/host/lib/host_key.c +++ b/host/lib/host_key.c @@ -13,6 +13,10 @@ #include #include +#include "2sysincludes.h" +#include "2common.h" +#include "2rsa.h" +#include "2sha.h" #include "cryptolib.h" #include "host_common.h" #include "host_key.h" @@ -20,82 +24,15 @@ #include "vb2_common.h" #include "vboot_common.h" -/* Allocate a new public key with space for a [key_size] byte key. */ -VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm, - uint64_t version) { - VbPublicKey* key = (VbPublicKey*)malloc(sizeof(VbPublicKey) + key_size); - if (!key) - return NULL; - - key->algorithm = algorithm; - key->key_version = version; - key->key_size = key_size; - key->key_offset = sizeof(VbPublicKey); - return key; -} - -VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm, - uint64_t version) { - VbPublicKey* key; - uint8_t* key_data; - uint64_t key_size; - uint64_t expected_key_size; - - if (algorithm >= kNumAlgorithms) { - VBDEBUG(("PublicKeyReadKeyb() called with invalid algorithm!\n")); - return NULL; - } - if (version > 0xFFFF) { - /* Currently, TPM only supports 16-bit version */ - VBDEBUG(("PublicKeyReadKeyb() called with invalid version!\n")); - return NULL; - } - - key_data = ReadFile(filename, &key_size); - if (!key_data) - return NULL; - - if (!RSAProcessedKeySize(algorithm, &expected_key_size) || - expected_key_size != key_size) { - VBDEBUG(("PublicKeyReadKeyb() wrong key size for algorithm\n")); - free(key_data); - return NULL; - } - - key = PublicKeyAlloc(key_size, algorithm, version); - if (!key) { - free(key_data); - return NULL; - } - Memcpy(GetPublicKeyData(key), key_data, key_size); - - free(key_data); - return key; -} - int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size) { - uint64_t key_size; - - if (size < sizeof(*key)) + struct vb2_public_key pubkey; + if (VB2_SUCCESS != vb2_unpack_key(&pubkey, (const uint8_t *)key, size)) 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")); + if (key->key_version > VB2_MAX_KEY_VERSION) { + /* Currently, TPM only supports 16-bit version */ + VB2_DEBUG("%s() - packed key invalid version\n", __func__); return 0; } @@ -103,37 +40,20 @@ int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size) return 1; } -VbPublicKey* PublicKeyRead(const char* filename) { - struct vb2_packed_key *key; - uint64_t file_size; +/* TODO: the host code just uses this to check the embedded key length in + * uint32_t's. It should get folded into packed_key_looks_ok. */ - key = (struct vb2_packed_key *)ReadFile(filename, &file_size); - if (!key) - return NULL; - - if (packed_key_looks_ok(key, file_size)) - return (VbPublicKey *)key; - - /* Error */ - free(key); - return NULL; -} +RSAPublicKey *vb2_packed_key_to_rsa(const struct vb2_packed_key *key) +{ + RSAPublicKey *rsa; -int PublicKeyWrite(const char* filename, const VbPublicKey* key) { - VbPublicKey* kcopy; - int rv; + if (!packed_key_looks_ok(key, key->key_size)) + return NULL; - /* Copy the key, so its data is contiguous with the header */ - kcopy = PublicKeyAlloc(key->key_size, 0, 0); - if (!kcopy) - return 1; - if (0 != PublicKeyCopy(kcopy, key)) { - free(kcopy); - return 1; - } + rsa = RSAPublicKeyFromBuf(vb2_packed_key_data(key), key->key_size); + if (!rsa) + return NULL; - /* Write the copy, then free it */ - rv = WriteFile(filename, kcopy, kcopy->key_offset + kcopy->key_size); - free(kcopy); - return rv; + rsa->algorithm = (unsigned int)key->algorithm; + return rsa; } diff --git a/host/lib/host_key2.c b/host/lib/host_key2.c index 783ea5d9..ff6c1c35 100644 --- a/host/lib/host_key2.c +++ b/host/lib/host_key2.c @@ -170,6 +170,22 @@ void vb2_init_packed_key(struct vb2_packed_key *key, uint8_t *key_data, key->algorithm = VB2_ALG_COUNT; /* Key not present yet */ } +struct vb2_packed_key *vb2_alloc_packed_key(uint32_t key_size, + uint32_t algorithm, + uint32_t version) +{ + struct vb2_packed_key *key = + (struct vb2_packed_key *)calloc(sizeof(*key) + key_size, 1); + if (!key) + return NULL; + + key->algorithm = algorithm; + key->key_version = version; + key->key_size = key_size; + key->key_offset = sizeof(*key); + return key; +} + int vb2_copy_packed_key(struct vb2_packed_key *dest, const struct vb2_packed_key *src) { @@ -201,3 +217,64 @@ struct vb2_packed_key *vb2_read_packed_key(const char *filename) free(key); return NULL; } + +struct vb2_packed_key *vb2_read_packed_keyb(const char *filename, + uint32_t algorithm, + uint32_t version) +{ + if (algorithm >= VB2_ALG_COUNT) { + fprintf(stderr, "%s() - invalid algorithm\n", __func__); + return NULL; + } + if (version > VB2_MAX_KEY_VERSION) { + /* Currently, TPM only supports 16-bit version */ + fprintf(stderr, "%s() - invalid version 0x%x\n", __func__, + version); + return NULL; + } + + uint8_t *key_data = NULL; + uint32_t key_size = 0; + if (VB2_SUCCESS != vb2_read_file(filename, &key_data, &key_size)) + return NULL; + + uint64_t expected_key_size; + if (!RSAProcessedKeySize(algorithm, &expected_key_size) || + expected_key_size != key_size) { + fprintf(stderr, "%s() - wrong key size %u for algorithm %u\n", + __func__, key_size, algorithm); + free(key_data); + return NULL; + } + + struct vb2_packed_key *key = + vb2_alloc_packed_key(key_size, algorithm, version); + if (!key) { + free(key_data); + return NULL; + } + memcpy((uint8_t *)vb2_packed_key_data(key), key_data, key_size); + + free(key_data); + return key; +} + +int vb2_write_packed_key(const char *filename, + const struct vb2_packed_key *key) +{ + /* Copy the key, so its data is contiguous with the header */ + struct vb2_packed_key *kcopy = + vb2_alloc_packed_key(key->key_size, 0, 0); + if (!kcopy) + return VB2_ERROR_PACKED_KEY_ALLOC; + if (VB2_SUCCESS != vb2_copy_packed_key(kcopy, key)) { + free(kcopy); + return VB2_ERROR_PACKED_KEY_COPY; + } + + /* Write the copy, then free it */ + int rv = vb2_write_file(filename, kcopy, + kcopy->key_offset + kcopy->key_size); + free(kcopy); + return rv; +} diff --git a/host/lib/include/host_key.h b/host/lib/include/host_key.h index 0d4641b2..0040b8a2 100644 --- a/host/lib/include/host_key.h +++ b/host/lib/include/host_key.h @@ -9,8 +9,6 @@ #define VBOOT_REFERENCE_HOST_KEY_H_ #include "2crypto.h" -#include "cryptolib.h" -#include "vboot_struct.h" struct vb2_packed_key; struct vb2_private_key; @@ -68,9 +66,17 @@ int vb2_write_private_key(const char *filename, */ struct vb2_private_key *vb2_read_private_key(const char *filename); -/* Allocate a new public key with space for a [key_size] byte key. */ -VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm, - uint64_t version); +/** + * Allocate a new public key. + * @param key_size Size of key data the key can hold + * @param algorithm Algorithm to store in key header + * @param version Version to store in key header + * + * @return The public key or NULL if error. Caller must free() it. + */ +struct vb2_packed_key *vb2_alloc_packed_key(uint32_t key_size, + uint32_t algorithm, + uint32_t version); /** * Initialize a packed key structure. @@ -93,26 +99,49 @@ void vb2_init_packed_key(struct vb2_packed_key *key, uint8_t *key_data, int vb2_copy_packed_key(struct vb2_packed_key *dest, const struct vb2_packed_key *src); -/* Read a public key from a .vbpubk file. Caller owns the returned - * pointer, and must free it with Free(). +/** + * Read a packed key from a .vbpubk file. + * + * @param filename Name of file to read + * @param algorithm Crypto algorithm to associate with key + * @param version Version to store in key * - * Returns NULL if error. */ -VbPublicKey* PublicKeyRead(const char* filename); + * @return The packed key, or NULL if error. Caller must free() it. + */ struct vb2_packed_key *vb2_read_packed_key(const char *filename); -/* Return true if the packed (public) key struct appears correct. */ +/** + * Sanity-check a packed key structure. + * + * @param key Key to check + * @param size Size of key buffer in bytes + * + * @return True if the key struct appears valid. + */ 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(). +/** + * Read a packed key from a .keyb file. * - * Returns NULL if error. */ -VbPublicKey* PublicKeyReadKeyb(const char* filename, uint64_t algorithm, - uint64_t version); - - -/* Write a public key to a file in .vbpubk format. */ -int PublicKeyWrite(const char* filename, const VbPublicKey* key); + * @param filename Name of file to read + * @param algorithm Crypto algorithm to associate with key + * @param version Version to store in key + * + * @return The packed key, or NULL if error. Caller must free() it. + */ +struct vb2_packed_key *vb2_read_packed_keyb(const char *filename, + uint32_t algorithm, + uint32_t version); +/** + * Write a packed key in .vbpubk format. + * + * @param filename Name of file to write + * @param key Key to write + * + * @return VB2_SUCCESS, or non-zero if error. + */ +int vb2_write_packed_key(const char *filename, + const struct vb2_packed_key *key); #endif /* VBOOT_REFERENCE_HOST_KEY_H_ */ diff --git a/host/lib/include/util_misc.h b/host/lib/include/util_misc.h index b6372db1..cd26b30a 100644 --- a/host/lib/include/util_misc.h +++ b/host/lib/include/util_misc.h @@ -42,8 +42,8 @@ const char *private_key_sha1_string(const struct vb2_private_key *key); /* * Our packed RSBPublicKey buffer (historically in files ending with ".keyb", - * but also the part of VbPublicKey and struct vb21_packed_key that is - * referenced by .key_offset) has this binary format: + * but also the part of struct vb2_packed_key and struct vb21_packed_key that + * is referenced by .key_offset) has this binary format: * * struct { * uint32_t nwords; // size of RSA key in 32-bit words diff --git a/host/linktest/main.c b/host/linktest/main.c index b98e8755..af125151 100644 --- a/host/linktest/main.c +++ b/host/linktest/main.c @@ -15,12 +15,6 @@ int main(void) { - /* host_key.h */ - PublicKeyAlloc(0, 0, 0); - PublicKeyRead(0); - PublicKeyReadKeyb(0, 0, 0); - PublicKeyWrite(0, 0); - /* host_misc.h */ ReadFile(0, 0); WriteFile(0, 0, 0); diff --git a/tests/vb20_common2_tests.c b/tests/vb20_common2_tests.c index 623633d6..da5b2028 100644 --- a/tests/vb20_common2_tests.c +++ b/tests/vb20_common2_tests.c @@ -154,8 +154,7 @@ int test_algorithm(int key_algorithm, const char *keys_dir) } sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, rsa_len); - key1 = (struct vb2_packed_key *) - PublicKeyReadKeyb(filename, key_algorithm, 1); + key1 = vb2_read_packed_keyb(filename, key_algorithm, 1); if (!key1) { fprintf(stderr, "Error reading public_key: %s\n", filename); return 1; diff --git a/tests/vb20_common3_tests.c b/tests/vb20_common3_tests.c index 32ee0079..a89cead1 100644 --- a/tests/vb20_common3_tests.c +++ b/tests/vb20_common3_tests.c @@ -199,7 +199,7 @@ static void resign_fw_preamble(struct vb2_fw_preamble *h, free(sig); } -static void test_verify_fw_preamble(const VbPublicKey *public_key, +static void test_verify_fw_preamble(struct vb2_packed_key *public_key, struct vb2_private_key *private_key, struct vb2_packed_key *kernel_subkey) { @@ -340,7 +340,7 @@ static void resign_kernel_preamble(struct vb2_kernel_preamble *h, } static void test_verify_kernel_preamble( - const VbPublicKey *public_key, + const struct vb2_packed_key *public_key, const struct vb2_private_key *private_key) { struct vb2_kernel_preamble *hdr; @@ -512,9 +512,6 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm, int signing_rsa_len = siglen_map[signing_key_algorithm] * 8; int data_rsa_len = siglen_map[data_key_algorithm] * 8; - VbPublicKey *signing_public_key = NULL; - VbPublicKey *data_public_key = NULL; - printf("***Testing signing algorithm: %s\n", algo_strings[signing_key_algorithm]); printf("***With data key algorithm: %s\n", @@ -530,8 +527,8 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm, } sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len); - signing_public_key = PublicKeyReadKeyb(filename, - signing_key_algorithm, 1); + struct vb2_packed_key *signing_public_key = + vb2_read_packed_keyb(filename, signing_key_algorithm, 1); if (!signing_public_key) { fprintf(stderr, "Error reading signing_public_key: %s\n", filename); @@ -539,8 +536,8 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm, } sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, data_rsa_len); - data_public_key = PublicKeyReadKeyb(filename, - data_key_algorithm, 1); + struct vb2_packed_key *data_public_key = + vb2_read_packed_keyb(filename, data_key_algorithm, 1); if (!data_public_key) { fprintf(stderr, "Error reading data_public_key: %s\n", filename); @@ -560,11 +557,11 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm, } test_check_keyblock(&signing_public_key2, signing_private_key, - (struct vb2_packed_key *)data_public_key); + data_public_key); test_verify_keyblock(&signing_public_key2, signing_private_key, - (struct vb2_packed_key *)data_public_key); + data_public_key); test_verify_fw_preamble(signing_public_key, signing_private_key, - (struct vb2_packed_key *)data_public_key); + data_public_key); test_verify_kernel_preamble(signing_public_key, signing_private_key); if (signing_public_key) diff --git a/tests/vboot_common2_tests.c b/tests/vboot_common2_tests.c index 5185debb..2c0a8949 100644 --- a/tests/vboot_common2_tests.c +++ b/tests/vboot_common2_tests.c @@ -22,7 +22,8 @@ static void VerifyPublicKeyToRSA(const VbPublicKey *orig_key) { RSAPublicKey *rsa; - VbPublicKey *key = PublicKeyAlloc(orig_key->key_size, 0, 0); + VbPublicKey *key = + (VbPublicKey *)vb2_alloc_packed_key(orig_key->key_size, 0, 0); PublicKeyCopy(key, orig_key); key->algorithm = kNumAlgorithms; @@ -235,7 +236,8 @@ int test_algorithm(int key_algorithm, const char *keys_dir) } sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, rsa_len); - public_key = PublicKeyReadKeyb(filename, key_algorithm, 1); + public_key = (VbPublicKey *)vb2_read_packed_keyb(filename, + key_algorithm, 1); if (!public_key) { fprintf(stderr, "Error reading public_key: %s\n", filename); return 1; diff --git a/tests/vboot_common3_tests.c b/tests/vboot_common3_tests.c index b68c3dc5..130deb05 100644 --- a/tests/vboot_common3_tests.c +++ b/tests/vboot_common3_tests.c @@ -182,8 +182,8 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm, } sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, signing_rsa_len); - signing_public_key = PublicKeyReadKeyb(filename, - signing_key_algorithm, 1); + signing_public_key = (VbPublicKey *) + vb2_read_packed_keyb(filename, signing_key_algorithm, 1); if (!signing_public_key) { fprintf(stderr, "Error reading signing_public_key: %s\n", filename); @@ -191,8 +191,8 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm, } sprintf(filename, "%s/key_rsa%d.keyb", keys_dir, data_rsa_len); - struct vb2_packed_key *data_public_key = (struct vb2_packed_key *) - PublicKeyReadKeyb(filename, data_key_algorithm, 1); + struct vb2_packed_key *data_public_key = + vb2_read_packed_keyb(filename, data_key_algorithm, 1); if (!data_public_key) { fprintf(stderr, "Error reading data_public_key: %s\n", filename); diff --git a/tests/verify_kernel.c b/tests/verify_kernel.c index 2f5943d2..e1cd0c0c 100644 --- a/tests/verify_kernel.c +++ b/tests/verify_kernel.c @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) } /* Read public key */ - kernkey = PublicKeyRead(argv[2]); + kernkey = (VbPublicKey *)vb2_read_packed_key(argv[2]); if (!kernkey) { fprintf(stderr, "Can't read key file %s\n", argv[2]); return 1; -- cgit v1.2.1