diff options
author | Randall Spangler <rspangler@chromium.org> | 2016-06-21 15:23:32 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-08-10 15:30:33 -0700 |
commit | 939cc3a5c25a3333fadafc7fc341d7e320f72fab (patch) | |
tree | bd7197c8950f44440459fc50531037d50719d3b7 | |
parent | 814aaf09ceecddb16a01e1cbe0df4299b83b5699 (diff) | |
download | vboot-939cc3a5c25a3333fadafc7fc341d7e320f72fab.tar.gz |
futility: Use only vboot 2.0 APIs for keyblocks
This refactors futility and the host library to use only vboot 2.0 APIs
to create and verify keyblocks.
BUG=chromium:611535
BRANCH=none
TEST=make runtests
Change-Id: Ia3cc1e24971b94f01bcb4890c8666a3af6f84841
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/356129
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r-- | firmware/2lib/include/2return_codes.h | 3 | ||||
-rw-r--r-- | futility/cmd_sign.c | 34 | ||||
-rw-r--r-- | futility/cmd_vbutil_firmware.c | 9 | ||||
-rw-r--r-- | futility/cmd_vbutil_kernel.c | 13 | ||||
-rw-r--r-- | futility/cmd_vbutil_keyblock.c | 79 | ||||
-rw-r--r-- | futility/dump_kernel_config_lib.c | 13 | ||||
-rw-r--r-- | futility/file_type.inc | 2 | ||||
-rw-r--r-- | futility/file_type_bios.c | 16 | ||||
-rw-r--r-- | futility/futility_options.h | 4 | ||||
-rw-r--r-- | futility/vb1_helper.c | 85 | ||||
-rw-r--r-- | futility/vb1_helper.h | 6 | ||||
-rw-r--r-- | host/lib/extract_vmlinuz.c | 10 | ||||
-rw-r--r-- | host/lib/host_key2.c | 41 | ||||
-rw-r--r-- | host/lib/host_keyblock.c | 293 | ||||
-rw-r--r-- | host/lib/host_signature2.c | 3 | ||||
-rw-r--r-- | host/lib/include/host_key.h | 21 | ||||
-rw-r--r-- | host/lib/include/host_keyblock.h | 75 | ||||
-rw-r--r-- | host/linktest/main.c | 5 | ||||
-rw-r--r-- | tests/vb20_common3_tests.c | 69 | ||||
-rw-r--r-- | tests/vboot_common3_tests.c | 19 |
20 files changed, 468 insertions, 332 deletions
diff --git a/firmware/2lib/include/2return_codes.h b/firmware/2lib/include/2return_codes.h index 636ac08d..b6979922 100644 --- a/firmware/2lib/include/2return_codes.h +++ b/firmware/2lib/include/2return_codes.h @@ -670,6 +670,9 @@ enum vb2_return_code { /* Bad hash algorithm in vb2_public_key_hash() */ VB2_ERROR_PUBLIC_KEY_HASH, + /* Bad key size in vb2_copy_packed_key() */ + VB2_ERROR_COPY_KEY_SIZE, + /********************************************************************** * Errors generated by host library signature functions */ diff --git a/futility/cmd_sign.c b/futility/cmd_sign.c index 6d448404..23e298b9 100644 --- a/futility/cmd_sign.c +++ b/futility/cmd_sign.c @@ -60,16 +60,22 @@ static int no_opt_if(int expr, const char *optname) /* This wraps/signs a public key, producing a keyblock. */ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data) { - VbPublicKey *data_key = (VbPublicKey *)buf; - VbKeyBlockHeader *vblock; + struct vb2_packed_key *data_key = (struct vb2_packed_key *)buf; + struct vb2_keyblock *block; + + if (!packed_key_looks_ok(data_key, len)) { + fprintf(stderr, "Public key looks bad.\n"); + return 1; + } if (sign_option.pem_signpriv) { if (sign_option.pem_external) { /* External signing uses the PEM file directly. */ - vblock = KeyBlockCreate_external( + block = vb2_create_keyblock_external( data_key, sign_option.pem_signpriv, - sign_option.pem_algo, sign_option.flags, + sign_option.pem_algo, + sign_option.flags, sign_option.pem_external); } else { sign_option.signprivate = PrivateKeyReadPem( @@ -90,19 +96,19 @@ int ft_sign_pubkey(const char *name, uint8_t *buf, uint32_t len, void *data) strerror(errno)); return 1; } - vblock = KeyBlockCreate(data_key, - sign_option.signprivate, - sign_option.flags); + block = vb2_create_keyblock(data_key, + sign_option.signprivate2, + sign_option.flags); } } else { /* Not PEM. Should already have a signing key. */ - vblock = KeyBlockCreate(data_key, sign_option.signprivate, - sign_option.flags); + block = vb2_create_keyblock(data_key, sign_option.signprivate2, + sign_option.flags); } /* Write it out */ return WriteSomeParts(sign_option.outfile, - vblock, vblock->key_block_size, + block, block->keyblock_size, NULL, 0); } @@ -166,7 +172,7 @@ int ft_sign_kern_preamble(const char *name, uint8_t *buf, uint32_t len, { uint8_t *kpart_data, *kblob_data, *vblock_data; uint64_t kpart_size, kblob_size, vblock_size; - VbKeyBlockHeader *keyblock = NULL; + struct vb2_keyblock *keyblock = NULL; VbKernelPreambleHeader *preamble = NULL; int rv = 0; @@ -278,7 +284,7 @@ int ft_sign_raw_firmware(const char *name, uint8_t *buf, uint32_t len, rv = WriteSomeParts(sign_option.outfile, sign_option.keyblock, - sign_option.keyblock->key_block_size, + sign_option.keyblock->keyblock_size, preamble, preamble->preamble_size); free(preamble); @@ -669,7 +675,7 @@ static int do_sign(int argc, char *argv[]) } break; case 'b': - sign_option.keyblock = KeyBlockRead(optarg); + sign_option.keyblock = vb2_read_keyblock(optarg); if (!sign_option.keyblock) { fprintf(stderr, "Error reading %s\n", optarg); errorcnt++; @@ -691,7 +697,7 @@ static int do_sign(int argc, char *argv[]) } break; case 'B': - sign_option.devkeyblock = KeyBlockRead(optarg); + sign_option.devkeyblock = vb2_read_keyblock(optarg); if (!sign_option.devkeyblock) { fprintf(stderr, "Error reading %s\n", optarg); errorcnt++; diff --git a/futility/cmd_vbutil_firmware.c b/futility/cmd_vbutil_firmware.c index b187d270..253add55 100644 --- a/futility/cmd_vbutil_firmware.c +++ b/futility/cmd_vbutil_firmware.c @@ -92,8 +92,6 @@ static int Vblock(const char *outfile, const char *keyblock_file, VbPrivateKey *signing_key; VbPublicKey *kernel_subkey; - VbKeyBlockHeader *key_block; - uint64_t key_block_size; uint8_t *fv_data; uint64_t fv_size; FILE *f; @@ -113,9 +111,8 @@ static int Vblock(const char *outfile, const char *keyblock_file, } /* Read the key block and keys */ - key_block = - (VbKeyBlockHeader *) ReadFile(keyblock_file, &key_block_size); - if (!key_block) { + struct vb2_keyblock *keyblock = vb2_read_keyblock(keyblock_file); + if (!keyblock) { VbExError("Error reading key block.\n"); return 1; } @@ -170,7 +167,7 @@ static int Vblock(const char *outfile, const char *keyblock_file, VbExError("Can't open output file %s\n", outfile); return 1; } - i = ((1 != fwrite(key_block, key_block_size, 1, f)) || + i = ((1 != fwrite(keyblock, keyblock->keyblock_size, 1, f)) || (1 != fwrite(preamble, preamble->preamble_size, 1, f))); fclose(f); if (i) { diff --git a/futility/cmd_vbutil_kernel.c b/futility/cmd_vbutil_kernel.c index d13749bf..cf8b26e0 100644 --- a/futility/cmd_vbutil_kernel.c +++ b/futility/cmd_vbutil_kernel.c @@ -25,6 +25,7 @@ #include "host_common.h" #include "kernel_blob.h" #include "vb1_helper.h" +#include "vb2_struct.h" static void Fatal(const char *format, ...) { @@ -236,8 +237,8 @@ static int do_vbutil_kernel(int argc, char *argv[]) int i = 0; int errcount = 0; int rv; - VbKeyBlockHeader *keyblock = NULL; - VbKeyBlockHeader *t_keyblock = NULL; + struct vb2_keyblock *keyblock = NULL; + struct vb2_keyblock *t_keyblock = NULL; VbPrivateKey *signpriv_key = NULL; VbPublicKey *signpub_key = NULL; uint8_t *kpart_data = NULL; @@ -395,7 +396,7 @@ static int do_vbutil_kernel(int argc, char *argv[]) if (!keyblock_file) Fatal("Missing required keyblock file.\n"); - t_keyblock = (VbKeyBlockHeader *)ReadFile(keyblock_file, 0); + t_keyblock = (struct vb2_keyblock *)ReadFile(keyblock_file, 0); if (!t_keyblock) Fatal("Error reading key block.\n"); @@ -517,8 +518,8 @@ static int do_vbutil_kernel(int argc, char *argv[]) flags = preamble->flags; if (keyblock_file) { - t_keyblock = - (VbKeyBlockHeader *)ReadFile(keyblock_file, 0); + t_keyblock = (struct vb2_keyblock *) + ReadFile(keyblock_file, 0); if (!t_keyblock) Fatal("Error reading key block.\n"); } @@ -619,7 +620,7 @@ static int do_vbutil_kernel(int argc, char *argv[]) // the keyblock and preamble sections. vmlinuz_header_offset = vmlinuz_header_address - preamble->body_load_address + - keyblock->key_block_size + + keyblock->keyblock_size + preamble->preamble_size; errcount |= (1 != fwrite(kpart_data + vmlinuz_header_offset, diff --git a/futility/cmd_vbutil_keyblock.c b/futility/cmd_vbutil_keyblock.c index 6ca6ba6e..27624931 100644 --- a/futility/cmd_vbutil_keyblock.c +++ b/futility/cmd_vbutil_keyblock.c @@ -11,6 +11,9 @@ #include <stdlib.h> #include <string.h> +#include "2sysincludes.h" +#include "2common.h" +#include "2rsa.h" #include "cryptolib.h" #include "futility.h" #include "host_common.h" @@ -86,9 +89,8 @@ static int Pack(const char *outfile, const char *datapubkey, const char *signprivate_pem, uint64_t pem_algorithm, uint64_t flags, const char *external_signer) { - VbPublicKey *data_key; - VbPrivateKey *signing_key = NULL; - VbKeyBlockHeader *block; + struct vb2_private_key *signing_key = NULL; + struct vb2_keyblock *block; if (!outfile) { fprintf(stderr, @@ -101,7 +103,7 @@ static int Pack(const char *outfile, const char *datapubkey, return 1; } - data_key = PublicKeyRead(datapubkey); + struct vb2_packed_key *data_key = vb2_read_packed_key(datapubkey); if (!data_key) { fprintf(stderr, "vbutil_keyblock: Error reading data key.\n"); return 1; @@ -116,37 +118,40 @@ static int Pack(const char *outfile, const char *datapubkey, } if (external_signer) { /* External signing uses the PEM file directly. */ - block = KeyBlockCreate_external(data_key, - signprivate_pem, - pem_algorithm, flags, - external_signer); + block = vb2_create_keyblock_external(data_key, + signprivate_pem, + pem_algorithm, + flags, + external_signer); } else { signing_key = - PrivateKeyReadPem(signprivate_pem, pem_algorithm); + vb2_read_private_key_pem(signprivate_pem, + pem_algorithm); if (!signing_key) { fprintf(stderr, "vbutil_keyblock:" " Error reading signing key.\n"); return 1; } - block = KeyBlockCreate(data_key, signing_key, flags); + block = vb2_create_keyblock(data_key, signing_key, + flags); } } else { if (signprivate) { - signing_key = PrivateKeyRead(signprivate); + signing_key = vb2_read_private_key(signprivate); if (!signing_key) { fprintf(stderr, "vbutil_keyblock:" " Error reading signing key.\n"); return 1; } } - block = KeyBlockCreate(data_key, signing_key, flags); + block = vb2_create_keyblock(data_key, signing_key, flags); } free(data_key); if (signing_key) free(signing_key); - if (0 != KeyBlockWrite(outfile, block)) { + if (VB2_SUCCESS != vb2_write_keyblock(outfile, block)) { fprintf(stderr, "vbutil_keyblock: Error writing key block.\n"); return 1; } @@ -157,32 +162,44 @@ static int Pack(const char *outfile, const char *datapubkey, static int Unpack(const char *infile, const char *datapubkey, const char *signpubkey) { - VbPublicKey *data_key; - VbPublicKey *sign_key = NULL; - VbKeyBlockHeader *block; + struct vb2_packed_key *sign_key = NULL; if (!infile) { fprintf(stderr, "vbutil_keyblock: Must specify filename\n"); return 1; } - block = KeyBlockRead(infile); + struct vb2_keyblock *block = vb2_read_keyblock(infile); if (!block) { fprintf(stderr, "vbutil_keyblock: Error reading key block.\n"); return 1; } /* If the block is signed, then verify it with the signing public key, - * since KeyBlockRead() only verified the hash. */ - if (block->key_block_signature.sig_size && signpubkey) { - sign_key = PublicKeyRead(signpubkey); + * since vb2_read_keyblock() only verified the hash. */ + if (block->keyblock_signature.sig_size && signpubkey) { + static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]; + static struct vb2_workbuf wb; + vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); + + sign_key = vb2_read_packed_key(signpubkey); if (!sign_key) { fprintf(stderr, "vbutil_keyblock: Error reading signpubkey.\n"); return 1; } - if (0 != - KeyBlockVerify(block, block->key_block_size, sign_key, 0)) { + struct vb2_public_key key; + if (VB2_SUCCESS != + vb2_unpack_key(&key, (uint8_t *)sign_key, + sign_key->key_offset + sign_key->key_size)) { + fprintf(stderr, + "vbutil_keyblock: Error reading signpubkey.\n"); + return 1; + } + + if (VB2_SUCCESS != + vb2_verify_keyblock(block, block->keyblock_size, + &key, &wb)) { fprintf(stderr, "vbutil_keyblock:" " Error verifying key block.\n"); return 1; @@ -192,26 +209,26 @@ static int Unpack(const char *infile, const char *datapubkey, printf("Key block file: %s\n", infile); printf("Signature %s\n", sign_key ? "valid" : "ignored"); - printf("Flags: %" PRIu64 " ", block->key_block_flags); - if (block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_0) + printf("Flags: %u ", block->keyblock_flags); + if (block->keyblock_flags & KEY_BLOCK_FLAG_DEVELOPER_0) printf(" !DEV"); - if (block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_1) + if (block->keyblock_flags & KEY_BLOCK_FLAG_DEVELOPER_1) printf(" DEV"); - if (block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0) + if (block->keyblock_flags & KEY_BLOCK_FLAG_RECOVERY_0) printf(" !REC"); - if (block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_1) + if (block->keyblock_flags & KEY_BLOCK_FLAG_RECOVERY_1) printf(" REC"); printf("\n"); - data_key = &block->data_key; - printf("Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm, + struct vb2_packed_key *data_key = &block->data_key; + printf("Data key algorithm: %u %s\n", data_key->algorithm, vb1_crypto_name(data_key->algorithm)); - printf("Data key version: %" PRIu64 "\n", data_key->key_version); + 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)); if (datapubkey) { - if (0 != PublicKeyWrite(datapubkey, data_key)) { + if (0 != PublicKeyWrite(datapubkey, (VbPublicKey *)data_key)) { fprintf(stderr, "vbutil_keyblock:" " unable to write public key\n"); return 1; diff --git a/futility/dump_kernel_config_lib.c b/futility/dump_kernel_config_lib.c index abf37ae1..376dfadf 100644 --- a/futility/dump_kernel_config_lib.c +++ b/futility/dump_kernel_config_lib.c @@ -16,6 +16,7 @@ #include "host_common.h" #include "kernel_blob.h" +#include "vb2_struct.h" #include "vboot_api.h" #include "vboot_host.h" @@ -73,22 +74,22 @@ static int SkipWithRead(void *ctx, ReadFullyFn read_fn, size_t count) static char *FindKernelConfigFromStream(void *ctx, ReadFullyFn read_fn, uint64_t kernel_body_load_address) { - VbKeyBlockHeader key_block; + struct vb2_keyblock keyblock; VbKernelPreambleHeader preamble; uint32_t now = 0; uint32_t offset = 0; /* Skip the key block */ - if (read_fn(ctx, &key_block, sizeof(key_block)) != sizeof(key_block)) { - VbExError("not enough data to fill key block header\n"); + if (read_fn(ctx, &keyblock, sizeof(keyblock)) != sizeof(keyblock)) { + VbExError("not enough data to fill keyblock header\n"); return NULL; } - ssize_t to_skip = key_block.key_block_size - sizeof(key_block); + ssize_t to_skip = keyblock.keyblock_size - sizeof(keyblock); if (to_skip < 0 || SkipWithRead(ctx, read_fn, to_skip)) { - VbExError("key_block_size advances past the end of the blob\n"); + VbExError("keyblock_size advances past the end of the blob\n"); return NULL; } - now += key_block.key_block_size; + now += keyblock.keyblock_size; /* Open up the preamble */ if (read_fn(ctx, &preamble, sizeof(preamble)) != sizeof(preamble)) { diff --git a/futility/file_type.inc b/futility/file_type.inc index f5a941d9..788f7e8c 100644 --- a/futility/file_type.inc +++ b/futility/file_type.inc @@ -35,7 +35,7 @@ FILE_TYPE(KERN_PREAMBLE, "kernel", "kernel preamble/partition", R_(ft_recognize_vblock1), S_(ft_show_kernel_preamble), S_(ft_sign_kern_preamble)) -FILE_TYPE(KEYBLOCK, "keyblock", "VbKeyBlock", +FILE_TYPE(KEYBLOCK, "keyblock", "keyblock (signed public key)", R_(ft_recognize_vblock1), S_(ft_show_keyblock), NONE) diff --git a/futility/file_type_bios.c b/futility/file_type_bios.c index dc518289..118b0aa3 100644 --- a/futility/file_type_bios.c +++ b/futility/file_type_bios.c @@ -264,7 +264,11 @@ static int fmap_sign_fw_main(const char *name, uint8_t *buf, uint32_t len, static int fmap_sign_fw_preamble(const char *name, uint8_t *buf, uint32_t len, void *data) { - VbKeyBlockHeader *key_block = (VbKeyBlockHeader *)buf; + static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]; + static struct vb2_workbuf wb; + vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); + + struct vb2_keyblock *keyblock = (struct vb2_keyblock *)buf; struct bios_state_s *state = (struct bios_state_s *)data; /* @@ -272,19 +276,19 @@ static int fmap_sign_fw_preamble(const char *name, uint8_t *buf, uint32_t len, * determine the size of the firmware body. Otherwise, we'll have to * just sign the whole region. */ - if (VBOOT_SUCCESS != KeyBlockVerify(key_block, len, NULL, 1)) { + if (VB2_SUCCESS != vb2_verify_keyblock_hash(keyblock, len, &wb)) { fprintf(stderr, "Warning: %s keyblock is invalid. " "Signing the entire FW FMAP region...\n", name); goto whatever; } - RSAPublicKey *rsa = PublicKeyToRSA(&key_block->data_key); + RSAPublicKey *rsa = PublicKeyToRSA((VbPublicKey *)&keyblock->data_key); if (!rsa) { fprintf(stderr, "Warning: %s public key is invalid. " "Signing the entire FW FMAP region...\n", name); goto whatever; } - uint32_t more = key_block->key_block_size; + uint32_t more = keyblock->keyblock_size; struct vb2_fw_preamble *preamble = (struct vb2_fw_preamble *)(buf + more); uint32_t fw_size = preamble->body_signature.data_size; @@ -323,7 +327,7 @@ whatever: static int write_new_preamble(struct bios_area_s *vblock, struct bios_area_s *fw_body, struct vb2_private_key *signkey, - VbKeyBlockHeader *keyblock) + struct vb2_keyblock *keyblock) { struct vb2_signature *body_sig; struct vb2_fw_preamble *preamble; @@ -346,7 +350,7 @@ static int write_new_preamble(struct bios_area_s *vblock, } /* Write the new keyblock */ - uint32_t more = keyblock->key_block_size; + uint32_t more = keyblock->keyblock_size; memcpy(vblock->buf, keyblock, more); /* and the new preamble */ memcpy(vblock->buf + more, preamble, preamble->preamble_size); diff --git a/futility/futility_options.h b/futility/futility_options.h index 456ee342..476898ef 100644 --- a/futility/futility_options.h +++ b/futility/futility_options.h @@ -35,10 +35,10 @@ extern struct show_option_s show_option; struct sign_option_s { VbPrivateKey *signprivate; struct vb2_private_key *signprivate2; - VbKeyBlockHeader *keyblock; + struct vb2_keyblock *keyblock; VbPublicKey *kernel_subkey; struct vb2_private_key *devsignprivate; - VbKeyBlockHeader *devkeyblock; + struct vb2_keyblock *devkeyblock; uint32_t version; int version_specified; uint32_t flags; diff --git a/futility/vb1_helper.c b/futility/vb1_helper.c index 13c5f5e6..b0f4fe8c 100644 --- a/futility/vb1_helper.c +++ b/futility/vb1_helper.c @@ -41,7 +41,7 @@ const char *vb1_crypto_name(uint32_t algo) */ /* The keyblock, preamble, and kernel blob are kept in separate places. */ -static VbKeyBlockHeader *g_keyblock; +static struct vb2_keyblock *g_keyblock; static VbKernelPreambleHeader *g_preamble; static uint8_t *g_kernel_blob_data; static uint64_t g_kernel_blob_size; @@ -307,11 +307,10 @@ int UpdateKernelBlobConfig(uint8_t *kblob_data, uint64_t kblob_size, /* Split a kernel partition into separate vblock and blob parts. */ uint8_t *UnpackKPart(uint8_t *kpart_data, uint64_t kpart_size, uint64_t padding, - VbKeyBlockHeader **keyblock_ptr, + struct vb2_keyblock **keyblock_ptr, VbKernelPreambleHeader **preamble_ptr, uint64_t *blob_size_ptr) { - VbKeyBlockHeader *keyblock; VbKernelPreambleHeader *preamble; uint64_t vmlinuz_header_size = 0; uint64_t vmlinuz_header_address = 0; @@ -319,17 +318,17 @@ uint8_t *UnpackKPart(uint8_t *kpart_data, uint64_t kpart_size, uint32_t flags = 0; /* Sanity-check the keyblock */ - keyblock = (VbKeyBlockHeader *)kpart_data; - Debug("Keyblock is 0x%" PRIx64 " bytes\n", keyblock->key_block_size); - now += keyblock->key_block_size; + struct vb2_keyblock *keyblock = (struct vb2_keyblock *)kpart_data; + Debug("Keyblock is 0x%x bytes\n", keyblock->keyblock_size); + now += keyblock->keyblock_size; if (now > kpart_size) { fprintf(stderr, - "key_block_size advances past the end of the blob\n"); + "keyblock_size advances past the end of the blob\n"); return NULL; } if (now > padding) { fprintf(stderr, - "key_block_size advances past %" PRIu64 + "keyblock_size advances past %" PRIu64 " byte padding\n", padding); return NULL; @@ -408,13 +407,14 @@ uint8_t *UnpackKPart(uint8_t *kpart_data, uint64_t kpart_size, uint8_t *SignKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size, uint64_t padding, int version, uint64_t kernel_body_load_address, - VbKeyBlockHeader *keyblock, VbPrivateKey *signpriv_key, + struct vb2_keyblock *keyblock, + VbPrivateKey *signpriv_key, uint32_t flags, uint64_t *vblock_size_ptr) { VbSignature *body_sig; VbKernelPreambleHeader *preamble; - uint64_t min_size = padding > keyblock->key_block_size - ? padding - keyblock->key_block_size : 0; + uint64_t min_size = padding > keyblock->keyblock_size + ? padding - keyblock->keyblock_size : 0; void *outbuf; uint64_t outsize; @@ -441,11 +441,11 @@ uint8_t *SignKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size, return 0; } - outsize = keyblock->key_block_size + preamble->preamble_size; + outsize = keyblock->keyblock_size + preamble->preamble_size; outbuf = malloc(outsize); Memset(outbuf, 0, outsize); - Memcpy(outbuf, keyblock, keyblock->key_block_size); - Memcpy(outbuf + keyblock->key_block_size, + Memcpy(outbuf, keyblock, keyblock->keyblock_size); + Memcpy(outbuf + keyblock->keyblock_size, preamble, preamble->preamble_size); if (vblock_size_ptr) @@ -504,41 +504,60 @@ int VerifyKernelBlob(uint8_t *kernel_blob, const char *keyblock_outfile, uint64_t min_version) { - VbPublicKey *data_key; RSAPublicKey *rsa; int rv = -1; uint64_t vmlinuz_header_size = 0; uint64_t vmlinuz_header_address = 0; - if (0 != KeyBlockVerify(g_keyblock, g_keyblock->key_block_size, - signpub_key, (0 == signpub_key))) { + static uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]; + static struct vb2_workbuf wb; + vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); + + if (signpub_key) { + struct vb2_public_key pubkey; + if (VB2_SUCCESS != + vb2_unpack_key(&pubkey, + (uint8_t *)signpub_key, + signpub_key->key_offset + + signpub_key->key_size)) { + fprintf(stderr, "Error unpacking signing key.\n"); + goto done; + } + if (VB2_SUCCESS != + vb2_verify_keyblock(g_keyblock, g_keyblock->keyblock_size, + &pubkey, &wb)) { + fprintf(stderr, "Error verifying key block.\n"); + goto done; + } + } else if (VB2_SUCCESS != + vb2_verify_keyblock_hash(g_keyblock, + g_keyblock->keyblock_size, + &wb)) { fprintf(stderr, "Error verifying key block.\n"); goto done; } printf("Key block:\n"); - data_key = &g_keyblock->data_key; + struct vb2_packed_key *data_key = &g_keyblock->data_key; printf(" Signature: %s\n", signpub_key ? "valid" : "ignored"); - printf(" Size: 0x%" PRIx64 "\n", - g_keyblock->key_block_size); - printf(" Flags: %" PRIu64 " ", - g_keyblock->key_block_flags); - if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_0) + printf(" Size: 0x%x\n", g_keyblock->keyblock_size); + printf(" Flags: %u ", g_keyblock->keyblock_flags); + if (g_keyblock->keyblock_flags & KEY_BLOCK_FLAG_DEVELOPER_0) printf(" !DEV"); - if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_1) + if (g_keyblock->keyblock_flags & KEY_BLOCK_FLAG_DEVELOPER_1) printf(" DEV"); - if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0) + if (g_keyblock->keyblock_flags & KEY_BLOCK_FLAG_RECOVERY_0) printf(" !REC"); - if (g_keyblock->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_1) + if (g_keyblock->keyblock_flags & KEY_BLOCK_FLAG_RECOVERY_1) printf(" REC"); printf("\n"); - printf(" Data key algorithm: %" PRIu64 " %s\n", data_key->algorithm, + printf(" Data key algorithm: %u %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 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 (keyblock_outfile) { FILE *f = NULL; @@ -548,7 +567,7 @@ int VerifyKernelBlob(uint8_t *kernel_blob, keyblock_outfile, strerror(errno)); goto done; } - if (1 != fwrite(g_keyblock, g_keyblock->key_block_size, 1, f)) { + if (1 != fwrite(g_keyblock, g_keyblock->keyblock_size, 1, f)) { fprintf(stderr, "Can't write key block file %s: %s\n", keyblock_outfile, strerror(errno)); fclose(f); @@ -558,13 +577,13 @@ int VerifyKernelBlob(uint8_t *kernel_blob, } if (data_key->key_version < (min_version >> 16)) { - fprintf(stderr, "Data key version %" PRIu64 - " is lower than minimum %" PRIu64 ".\n", + fprintf(stderr, "Data key version %u is lower than minimum " + "%" PRIu64 ".\n", data_key->key_version, (min_version >> 16)); goto done; } - rsa = PublicKeyToRSA(data_key); + rsa = PublicKeyToRSA((VbPublicKey *)data_key); if (!rsa) { fprintf(stderr, "Error parsing data key.\n"); goto done; diff --git a/futility/vb1_helper.h b/futility/vb1_helper.h index 8f3b5000..ec0f0004 100644 --- a/futility/vb1_helper.h +++ b/futility/vb1_helper.h @@ -7,6 +7,7 @@ #define VBOOT_REFERENCE_FUTILITY_VB1_HELPER_H_ struct vb2_kernel_preamble; +struct vb2_keyblock; struct vb2_packed_key; /** @@ -33,7 +34,8 @@ uint8_t *CreateKernelBlob(uint8_t *vmlinuz_buf, uint64_t vmlinuz_size, uint8_t *SignKernelBlob(uint8_t *kernel_blob, uint64_t kernel_size, uint64_t padding, int version, uint64_t kernel_body_load_address, - VbKeyBlockHeader *keyblock, VbPrivateKey *signpriv_key, + struct vb2_keyblock *keyblock, + VbPrivateKey *signpriv_key, uint32_t flags, uint64_t *vblock_size_ptr); int WriteSomeParts(const char *outfile, @@ -42,7 +44,7 @@ int WriteSomeParts(const char *outfile, uint8_t *UnpackKPart(uint8_t *kpart_data, uint64_t kpart_size, uint64_t padding, - VbKeyBlockHeader **keyblock_ptr, + struct vb2_keyblock **keyblock_ptr, VbKernelPreambleHeader **preamble_ptr, uint64_t *blob_size_ptr); diff --git a/host/lib/extract_vmlinuz.c b/host/lib/extract_vmlinuz.c index 81d3918e..dddbe561 100644 --- a/host/lib/extract_vmlinuz.c +++ b/host/lib/extract_vmlinuz.c @@ -8,13 +8,13 @@ #include <stdlib.h> #include <string.h> +#include "vb2_struct.h" #include "vboot_struct.h" int ExtractVmlinuz(void *kpart_data, size_t kpart_size, void **vmlinuz_out, size_t *vmlinuz_size) { - uint64_t now = 0; - VbKeyBlockHeader *keyblock = NULL; + size_t now = 0; VbKernelPreambleHeader *preamble = NULL; uint8_t *kblob_data = NULL; uint64_t kblob_size = 0; @@ -23,8 +23,8 @@ int ExtractVmlinuz(void *kpart_data, size_t kpart_size, uint64_t vmlinuz_header_offset = 0; void *vmlinuz = NULL; - keyblock = (VbKeyBlockHeader *)kpart_data; - now += keyblock->key_block_size; + struct vb2_keyblock *keyblock = (struct vb2_keyblock *)kpart_data; + now += keyblock->keyblock_size; if (now > kpart_size) return 1; @@ -55,7 +55,7 @@ int ExtractVmlinuz(void *kpart_data, size_t kpart_size, // the keyblock and preamble sections. vmlinuz_header_offset = vmlinuz_header_address - preamble->body_load_address + - keyblock->key_block_size + + keyblock->keyblock_size + preamble->preamble_size; vmlinuz = malloc(vmlinuz_header_size + kblob_size); diff --git a/host/lib/host_key2.c b/host/lib/host_key2.c index 28f02af5..a100455e 100644 --- a/host/lib/host_key2.c +++ b/host/lib/host_key2.c @@ -103,3 +103,44 @@ struct vb2_private_key *vb2_read_private_key_pem( /* Return the key */ return key; } + +void vb2_init_packed_key(struct vb2_packed_key *key, uint8_t *key_data, + uint32_t key_size) +{ + memset(key, 0, sizeof(*key)); + key->key_offset = vb2_offset_of(key, key_data); + key->key_size = key_size; + key->algorithm = VB2_ALG_COUNT; /* Key not present yet */ +} + +int vb2_copy_packed_key(struct vb2_packed_key *dest, + const struct vb2_packed_key *src) +{ + if (dest->key_size < src->key_size) + return VB2_ERROR_COPY_KEY_SIZE; + + dest->key_size = src->key_size; + dest->algorithm = src->algorithm; + dest->key_version = src->key_version; + memcpy((uint8_t *)vb2_packed_key_data(dest), + vb2_packed_key_data(src), src->key_size); + return VB2_SUCCESS; +} + +struct vb2_packed_key *vb2_read_packed_key(const char *filename) +{ + struct vb2_packed_key *key; + uint32_t file_size; + + if (VB2_SUCCESS != + vb2_read_file(filename, (uint8_t **)&key, &file_size)) { + return NULL; + } + + if (packed_key_looks_ok(key, file_size)) + return key; + + /* Error */ + free(key); + return NULL; +} diff --git a/host/lib/host_keyblock.c b/host/lib/host_keyblock.c index 982013fb..e4497727 100644 --- a/host/lib/host_keyblock.c +++ b/host/lib/host_keyblock.c @@ -5,167 +5,170 @@ * Host functions for verified boot. */ +#include <stdio.h> + #include "2sysincludes.h" +#include "2api.h" #include "2common.h" +#include "2rsa.h" #include "2sha.h" #include "cryptolib.h" #include "host_common.h" +#include "host_key.h" +#include "host_key2.h" #include "host_keyblock.h" +#include "vb2_common.h" +#include "vb2_struct.h" #include "vboot_common.h" - -VbKeyBlockHeader* KeyBlockCreate(const VbPublicKey* data_key, - const VbPrivateKey* signing_key, - uint64_t flags) { - - VbKeyBlockHeader* h; - uint64_t signed_size = sizeof(VbKeyBlockHeader) + data_key->key_size; - uint64_t block_size = (signed_size + VB2_SHA512_DIGEST_SIZE + - (signing_key ? - siglen_map[signing_key->algorithm] : 0)); - uint8_t* data_key_dest; - uint8_t* block_sig_dest; - uint8_t* block_chk_dest; - VbSignature *sigtmp; - - /* Allocate key block */ - h = (VbKeyBlockHeader*)malloc(block_size); - if (!h) - return NULL; - data_key_dest = (uint8_t*)(h + 1); - block_chk_dest = data_key_dest + data_key->key_size; - block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE; - - Memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE); - h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR; - h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR; - h->key_block_size = block_size; - h->key_block_flags = flags; - - /* Copy data key */ - PublicKeyInit(&h->data_key, data_key_dest, data_key->key_size); - PublicKeyCopy(&h->data_key, data_key); - - /* Set up signature structs so we can calculate the signatures */ - SignatureInit(&h->key_block_checksum, block_chk_dest, - VB2_SHA512_DIGEST_SIZE, signed_size); - if (signing_key) - SignatureInit(&h->key_block_signature, block_sig_dest, - siglen_map[signing_key->algorithm], signed_size); - else - Memset(&h->key_block_signature, 0, sizeof(VbSignature)); - - /* Calculate checksum */ - struct vb2_signature *chk = vb2_sha512_signature((uint8_t*)h, signed_size); - SignatureCopy(&h->key_block_checksum, (VbSignature *)chk); - free(chk); - - /* Calculate signature */ - if (signing_key) { - sigtmp = CalculateSignature((uint8_t*)h, signed_size, signing_key); - SignatureCopy(&h->key_block_signature, sigtmp); - free(sigtmp); - } - - /* Return the header */ - return h; +struct vb2_keyblock *vb2_create_keyblock( + const struct vb2_packed_key *data_key, + const struct vb2_private_key *signing_key, + uint32_t flags) +{ + /* Allocate key block */ + uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size; + uint32_t sig_data_size = + (signing_key ? vb2_rsa_sig_size(signing_key->sig_alg) : 0); + uint32_t block_size = + signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size; + struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1); + if (!h) + return NULL; + + uint8_t *data_key_dest = (uint8_t *)(h + 1); + uint8_t *block_chk_dest = data_key_dest + data_key->key_size; + uint8_t *block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE; + + memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE); + h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR; + h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR; + h->keyblock_size = block_size; + h->keyblock_flags = flags; + + /* Copy data key */ + vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size); + vb2_copy_packed_key(&h->data_key, data_key); + + /* Set up signature structs so we can calculate the signatures */ + vb2_init_signature(&h->keyblock_hash, block_chk_dest, + VB2_SHA512_DIGEST_SIZE, signed_size); + if (signing_key) { + vb2_init_signature(&h->keyblock_signature, block_sig_dest, + sig_data_size, signed_size); + } else { + memset(&h->keyblock_signature, 0, + sizeof(h->keyblock_signature)); + } + + /* Calculate hash */ + struct vb2_signature *chk = + vb2_sha512_signature((uint8_t*)h, signed_size); + vb2_copy_signature(&h->keyblock_hash, chk); + free(chk); + + /* Calculate signature */ + if (signing_key) { + struct vb2_signature *sigtmp = + vb2_calculate_signature((uint8_t*)h, + signed_size, + signing_key); + vb2_copy_signature(&h->keyblock_signature, sigtmp); + free(sigtmp); + } + + /* Return the header */ + return h; } -/* TODO(gauravsh): This could easily be integrated into KeyBlockCreate() +/* TODO(gauravsh): This could easily be integrated into the function above * since the code is almost a mirror - I have kept it as such to avoid changing * the existing interface. */ -VbKeyBlockHeader* KeyBlockCreate_external(const VbPublicKey* data_key, - const char* signing_key_pem_file, - uint64_t algorithm, - uint64_t flags, - const char* external_signer) { - VbKeyBlockHeader* h; - uint64_t signed_size = sizeof(VbKeyBlockHeader) + data_key->key_size; - uint64_t block_size = (signed_size + VB2_SHA512_DIGEST_SIZE + - siglen_map[algorithm]); - uint8_t* data_key_dest; - uint8_t* block_sig_dest; - uint8_t* block_chk_dest; - VbSignature *sigtmp; - - /* Allocate key block */ - h = (VbKeyBlockHeader*)malloc(block_size); - if (!h) - return NULL; - if (!signing_key_pem_file || !data_key || !external_signer) - return NULL; - - data_key_dest = (uint8_t*)(h + 1); - block_chk_dest = data_key_dest + data_key->key_size; - block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE; - - Memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE); - h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR; - h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR; - h->key_block_size = block_size; - h->key_block_flags = flags; - - /* Copy data key */ - PublicKeyInit(&h->data_key, data_key_dest, data_key->key_size); - PublicKeyCopy(&h->data_key, data_key); - - /* Set up signature structs so we can calculate the signatures */ - SignatureInit(&h->key_block_checksum, block_chk_dest, - VB2_SHA512_DIGEST_SIZE, signed_size); - SignatureInit(&h->key_block_signature, block_sig_dest, - siglen_map[algorithm], signed_size); - - /* Calculate checksum */ - struct vb2_signature *chk = vb2_sha512_signature((uint8_t*)h, signed_size); - SignatureCopy(&h->key_block_checksum, (VbSignature *)chk); - free(chk); - - /* Calculate signature */ - sigtmp = CalculateSignature_external((uint8_t*)h, signed_size, - signing_key_pem_file, algorithm, - external_signer); - SignatureCopy(&h->key_block_signature, sigtmp); - free(sigtmp); - - /* Return the header */ - return h; +struct vb2_keyblock *vb2_create_keyblock_external( + const struct vb2_packed_key *data_key, + const char *signing_key_pem_file, + uint32_t algorithm, + uint32_t flags, + const char *external_signer) +{ + uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size; + uint32_t sig_data_size = vb2_rsa_sig_size(algorithm); + uint32_t block_size = + signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size; + + /* Allocate key block */ + struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1); + if (!h) + return NULL; + if (!signing_key_pem_file || !data_key || !external_signer) + return NULL; + + uint8_t *data_key_dest = (uint8_t *)(h + 1); + uint8_t *block_chk_dest = data_key_dest + data_key->key_size; + uint8_t *block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE; + + memcpy(h->magic, KEY_BLOCK_MAGIC, KEY_BLOCK_MAGIC_SIZE); + h->header_version_major = KEY_BLOCK_HEADER_VERSION_MAJOR; + h->header_version_minor = KEY_BLOCK_HEADER_VERSION_MINOR; + h->keyblock_size = block_size; + h->keyblock_flags = flags; + + /* Copy data key */ + vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size); + vb2_copy_packed_key(&h->data_key, data_key); + + /* Set up signature structs so we can calculate the signatures */ + vb2_init_signature(&h->keyblock_hash, block_chk_dest, + VB2_SHA512_DIGEST_SIZE, signed_size); + vb2_init_signature(&h->keyblock_signature, block_sig_dest, + sig_data_size, signed_size); + + /* Calculate checksum */ + struct vb2_signature *chk = + vb2_sha512_signature((uint8_t*)h, signed_size); + vb2_copy_signature(&h->keyblock_hash, chk); + free(chk); + + /* Calculate signature */ +struct vb2_signature *sigtmp = (struct vb2_signature *) + CalculateSignature_external((uint8_t*)h, signed_size, + signing_key_pem_file, algorithm, + external_signer); + free(sigtmp); + + /* Return the header */ + return h; } -/* Read a key block from a .keyblock file. Caller owns the returned - * pointer, and must free it with free(). - * - * Returns NULL if error. */ -VbKeyBlockHeader* KeyBlockRead(const char* filename) { - - VbKeyBlockHeader* block; - uint64_t file_size; - - block = (VbKeyBlockHeader*)ReadFile(filename, &file_size); - if (!block) { - VBDEBUG(("Error reading key block file: %s\n", filename)); - return NULL; - } - - /* Verify the hash of the key block, since we can do that without - * the public signing key. */ - if (0 != KeyBlockVerify(block, file_size, NULL, 1)) { - VBDEBUG(("Invalid key block file: %s\n", filename)); - free(block); - return NULL; - } - - return block; +struct vb2_keyblock *vb2_read_keyblock(const char *filename) +{ + uint8_t workbuf[VB2_WORKBUF_RECOMMENDED_SIZE]; + struct vb2_workbuf wb; + vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); + + struct vb2_keyblock *block; + uint32_t file_size; + if (VB2_SUCCESS != + vb2_read_file(filename, (uint8_t **)&block, &file_size)) { + fprintf(stderr, "Error reading key block file: %s\n", filename); + return NULL; + } + + /* Verify the hash of the key block, since we can do that without + * the public signing key. */ + if (VB2_SUCCESS != vb2_verify_keyblock_hash(block, file_size, &wb)) { + fprintf(stderr, "Invalid key block file: %s\n", filename); + free(block); + return NULL; + } + + return block; } -/* Write a key block to a file in .keyblock format. */ -int KeyBlockWrite(const char* filename, const VbKeyBlockHeader* key_block) { - - if (0 != WriteFile(filename, key_block, key_block->key_block_size)) { - VBDEBUG(("KeyBlockWrite() error writing key block\n")); - return 1; - } - - return 0; +int vb2_write_keyblock(const char *filename, + const struct vb2_keyblock *keyblock) +{ + return vb2_write_file(filename, keyblock, keyblock->keyblock_size); } diff --git a/host/lib/host_signature2.c b/host/lib/host_signature2.c index e07f3d06..8925e6a7 100644 --- a/host/lib/host_signature2.c +++ b/host/lib/host_signature2.c @@ -44,7 +44,8 @@ struct vb2_signature *vb2_alloc_signature(uint32_t sig_size, void vb2_init_signature(struct vb2_signature *sig, uint8_t *sig_data, uint32_t sig_size, uint32_t data_size) { - sig->sig_offset = OffsetOf(sig, sig_data); + memset(sig, 0, sizeof(*sig)); + sig->sig_offset = vb2_offset_of(sig, sig_data); sig->sig_size = sig_size; sig->data_size = data_size; } diff --git a/host/lib/include/host_key.h b/host/lib/include/host_key.h index 25b7f767..d355e228 100644 --- a/host/lib/include/host_key.h +++ b/host/lib/include/host_key.h @@ -48,12 +48,33 @@ struct vb2_private_key *vb2_read_private_key(const char *filename); VbPublicKey* PublicKeyAlloc(uint64_t key_size, uint64_t algorithm, uint64_t version); +/** + * Initialize a packed key structure. + * + * @param key Structure to initialize + * @param key_data Pointer to key data (following the structure) + * @param key_size Size of key + */ +void vb2_init_packed_key(struct vb2_packed_key *key, uint8_t *key_data, + uint32_t key_size); + +/** + * Copy a packed key. + * + * @param dest Destination packed key + * @param src Source packed key + * + * @return VB2_SUCCESS, or non-zero if error. + */ +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(). * * Returns NULL if error. */ VbPublicKey* PublicKeyRead(const char* filename); +struct vb2_packed_key *vb2_read_packed_key(const char *filename); /* Return true if the packed (public) key struct appears correct. */ int packed_key_looks_ok(const struct vb2_packed_key *key, uint32_t size); diff --git a/host/lib/include/host_keyblock.h b/host/lib/include/host_keyblock.h index ea88f19b..21257965 100644 --- a/host/lib/include/host_keyblock.h +++ b/host/lib/include/host_keyblock.h @@ -11,35 +11,60 @@ #include "host_key.h" #include "vboot_struct.h" +struct vb2_keyblock; -/* Create a key block header containing [data_key] and [flags], signed - * by private key the file [signing_key_pem_file] and algorithm [algorithm] - * using the external signer program [external_signer] for all private key - * operations. - * Caller owns the returned pointer, and must free - * it with Free(). */ -VbKeyBlockHeader* KeyBlockCreate_external(const VbPublicKey* data_key, - const char* signing_key_pem_file, - uint64_t algorithm, - uint64_t flags, - const char* external_signer); - -/* Create a key block header containing [data_key] and [flags], signed - * by [signing_key]. Caller owns the returned pointer, and must free - * it with Free(). */ -VbKeyBlockHeader* KeyBlockCreate(const VbPublicKey* data_key, - const VbPrivateKey* signing_key, - uint64_t flags); - +/** + * Create a keyblock header + * + * @param data_key Data key to store in keyblock + * @param signing_key Key to sign keyblock with. May be NULL if keyblock + * only needs a hash digest. + * @param flags Keyblock flags + * + * @return The keyblock, or NULL if error. Caller must free() it. + */ +struct vb2_keyblock *vb2_create_keyblock( + const struct vb2_packed_key *data_key, + const struct vb2_private_key *signing_key, + uint32_t flags); -/* Read a key block from a .keyblock file. Caller owns the returned - * pointer, and must free it with Free(). +/** + * Create a keyblock header using an external signer for all private key + * operations. + * + * @param data_key Data key to store in keyblock + * @param signing_key_pem_file Filename of private key + * @param algorithm Signing algorithm index + * @param flags Keyblock flags + * @param external_signer Path to external signer program * - * Returns NULL if error. */ -VbKeyBlockHeader* KeyBlockRead(const char* filename); + * @return The keyblock, or NULL if error. Caller must free() it. + */ +struct vb2_keyblock *vb2_create_keyblock_external( + const struct vb2_packed_key *data_key, + const char *signing_key_pem_file, + uint32_t algorithm, + uint32_t flags, + const char *external_signer); +/** + * Read a keyblock from a .keyblock file. + * + * @param filename File to read keyblock from + * + * @return The keyblock, or NULL if error. Caller must free() it. + */ +struct vb2_keyblock *vb2_read_keyblock(const char *filename); -/* Write a key block to a file in .keyblock format. */ -int KeyBlockWrite(const char* filename, const VbKeyBlockHeader* key_block); +/** + * Write a keyblock to a file in .keyblock format. + * + * @param filename Filename to write + * @param keyblock Keyblock to write + * + * @return VB2_SUCCESS, or non-zero if error. + */ +int vb2_write_keyblock(const char *filename, + const struct vb2_keyblock *keyblock); #endif /* VBOOT_REFERENCE_HOST_KEYBLOCK_H_ */ diff --git a/host/linktest/main.c b/host/linktest/main.c index 1631ec37..5d56b892 100644 --- a/host/linktest/main.c +++ b/host/linktest/main.c @@ -23,11 +23,6 @@ int main(void) PublicKeyReadKeyb(0, 0, 0); PublicKeyWrite(0, 0); - /* host_keyblock.h */ - KeyBlockCreate(0, 0, 0); - KeyBlockRead(0); - KeyBlockWrite(0, 0); - /* host_misc.h */ ReadFile(0, 0); WriteFile(0, 0, 0); diff --git a/tests/vb20_common3_tests.c b/tests/vb20_common3_tests.c index 6de4b8a0..e1199d84 100644 --- a/tests/vb20_common3_tests.c +++ b/tests/vb20_common3_tests.c @@ -19,33 +19,27 @@ #include "vboot_common.h" #include "test_common.h" -static void resign_keyblock(struct vb2_keyblock *h, const VbPrivateKey *key) +static void resign_keyblock(struct vb2_keyblock *h, + const struct vb2_private_key *key) { - VbSignature *sig = - CalculateSignature((const uint8_t *)h, - h->keyblock_signature.data_size, key); + struct vb2_signature *sig = + vb2_calculate_signature((const uint8_t *)h, + h->keyblock_signature.data_size, key); - SignatureCopy((VbSignature *)&h->keyblock_signature, sig); + vb2_copy_signature(&h->keyblock_signature, sig); free(sig); } -static void test_check_keyblock(const VbPublicKey *public_key, - const VbPrivateKey *private_key, - const VbPublicKey *data_key) +static void test_check_keyblock(const struct vb2_public_key *public_key, + const struct vb2_private_key *private_key, + const struct vb2_packed_key *data_key) { - struct vb2_public_key key; struct vb2_keyblock *hdr; struct vb2_keyblock *h; struct vb2_signature *sig; uint32_t hsize; - /* Unpack public key */ - TEST_SUCC(vb2_unpack_key(&key, (uint8_t *)public_key, - public_key->key_offset + public_key->key_size), - "vb2_verify_keyblock public key"); - - hdr = (struct vb2_keyblock *) - KeyBlockCreate(data_key, private_key, 0x1234); + hdr = vb2_create_keyblock(data_key, private_key, 0x1234); TEST_NEQ((size_t)hdr, 0, "vb2_verify_keyblock() prerequisites"); if (!hdr) return; @@ -143,27 +137,20 @@ static void test_check_keyblock(const VbPublicKey *public_key, free(hdr); } -static void test_verify_keyblock(const VbPublicKey *public_key, - const VbPrivateKey *private_key, - const VbPublicKey *data_key) +static void test_verify_keyblock(const struct vb2_public_key *public_key, + const struct vb2_private_key *private_key, + const struct vb2_packed_key *data_key) { uint8_t workbuf[VB2_KEY_BLOCK_VERIFY_WORKBUF_BYTES] __attribute__ ((aligned (VB2_WORKBUF_ALIGN))); struct vb2_workbuf wb; - struct vb2_public_key key; struct vb2_keyblock *hdr; struct vb2_keyblock *h; uint32_t hsize; vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); - /* Unpack public key */ - TEST_SUCC(vb2_unpack_key(&key, (uint8_t *)public_key, - public_key->key_offset + public_key->key_size), - "vb2_verify_keyblock public key"); - - hdr = (struct vb2_keyblock *) - KeyBlockCreate(data_key, private_key, 0x1234); + hdr = vb2_create_keyblock(data_key, private_key, 0x1234); TEST_NEQ((size_t)hdr, 0, "vb2_verify_keyblock() prerequisites"); if (!hdr) return; @@ -171,25 +158,25 @@ static void test_verify_keyblock(const VbPublicKey *public_key, h = (struct vb2_keyblock *)malloc(hsize + 2048); Memcpy(h, hdr, hsize); - TEST_SUCC(vb2_verify_keyblock(h, hsize, &key, &wb), + TEST_SUCC(vb2_verify_keyblock(h, hsize, public_key, &wb), "vb2_verify_keyblock() ok using key"); /* Failures in keyblock check also cause verify to fail */ Memcpy(h, hdr, hsize); - TEST_EQ(vb2_verify_keyblock(h, hsize - 1, &key, &wb), + TEST_EQ(vb2_verify_keyblock(h, hsize - 1, public_key, &wb), VB2_ERROR_KEYBLOCK_SIZE, "vb2_verify_keyblock() check"); /* Check signature */ Memcpy(h, hdr, hsize); h->keyblock_signature.sig_size--; resign_keyblock(h, private_key); - TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb), + TEST_EQ(vb2_verify_keyblock(h, hsize, public_key, &wb), VB2_ERROR_KEYBLOCK_SIG_INVALID, "vb2_verify_keyblock() sig too small"); Memcpy(h, hdr, hsize); ((uint8_t *)vb2_packed_key_data(&h->data_key))[0] ^= 0x34; - TEST_EQ(vb2_verify_keyblock(h, hsize, &key, &wb), + TEST_EQ(vb2_verify_keyblock(h, hsize, public_key, &wb), VB2_ERROR_KEYBLOCK_SIG_INVALID, "vb2_verify_keyblock() sig mismatch"); @@ -568,10 +555,22 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm, return 1; } - test_check_keyblock(signing_public_key, signing_private_key, - data_public_key); - test_verify_keyblock(signing_public_key, signing_private_key, - data_public_key); + /* Unpack public key */ + struct vb2_public_key signing_public_key2; + if (VB2_SUCCESS != + vb2_unpack_key(&signing_public_key2, + (uint8_t *)signing_public_key, + signing_public_key->key_offset + + signing_public_key->key_size)) { + fprintf(stderr, "Error unpacking signing_public_key: %s\n", + filename); + return 1; + } + + test_check_keyblock(&signing_public_key2, signing_private_key2, + (struct vb2_packed_key *)data_public_key); + test_verify_keyblock(&signing_public_key2, signing_private_key2, + (struct vb2_packed_key *)data_public_key); test_verify_fw_preamble(signing_public_key, signing_private_key2, (struct vb2_packed_key *)data_public_key); test_verify_kernel_preamble(signing_public_key, signing_private_key); diff --git a/tests/vboot_common3_tests.c b/tests/vboot_common3_tests.c index 1eba971c..b68c3dc5 100644 --- a/tests/vboot_common3_tests.c +++ b/tests/vboot_common3_tests.c @@ -30,14 +30,17 @@ static void ReChecksumKeyBlock(VbKeyBlockHeader *h) } static void KeyBlockVerifyTest(const VbPublicKey *public_key, - const VbPrivateKey *private_key, - const VbPublicKey *data_key) + const struct vb2_private_key *private_key, + const struct vb2_packed_key *data_key) { VbKeyBlockHeader *hdr; VbKeyBlockHeader *h; unsigned hsize; - hdr = KeyBlockCreate(data_key, private_key, 0x1234); + hdr = (VbKeyBlockHeader *) + vb2_create_keyblock((struct vb2_packed_key *)data_key, + private_key, + 0x1234); TEST_NEQ((size_t)hdr, 0, "KeyBlockVerify() prerequisites"); if (!hdr) return; @@ -162,9 +165,7 @@ 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; - VbPrivateKey *signing_private_key = NULL; VbPublicKey *signing_public_key = NULL; - VbPublicKey *data_public_key = NULL; printf("***Testing signing algorithm: %s\n", algo_strings[signing_key_algorithm]); @@ -172,8 +173,8 @@ int test_permutation(int signing_key_algorithm, int data_key_algorithm, algo_strings[data_key_algorithm]); sprintf(filename, "%s/key_rsa%d.pem", keys_dir, signing_rsa_len); - signing_private_key = PrivateKeyReadPem(filename, - signing_key_algorithm); + struct vb2_private_key *signing_private_key = + vb2_read_private_key_pem(filename, signing_key_algorithm); if (!signing_private_key) { fprintf(stderr, "Error reading signing_private_key: %s\n", filename); @@ -190,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); - data_public_key = PublicKeyReadKeyb(filename, - data_key_algorithm, 1); + struct vb2_packed_key *data_public_key = (struct vb2_packed_key *) + PublicKeyReadKeyb(filename, data_key_algorithm, 1); if (!data_public_key) { fprintf(stderr, "Error reading data_public_key: %s\n", filename); |