diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | firmware/lib/include/vboot_common.h | 13 | ||||
-rw-r--r-- | firmware/lib/vboot_common.c | 79 | ||||
-rwxr-xr-x | tests/run_vboot_ec_tests.sh | 19 | ||||
-rw-r--r-- | tests/vboot_ec_tests.c | 160 | ||||
-rw-r--r-- | utility/vbutil_ec.c | 532 |
6 files changed, 0 insertions, 809 deletions
@@ -347,7 +347,6 @@ UTIL_NAMES = ${UTIL_NAMES_STATIC} \ signature_digest_utility \ tpm_init_temp_fix \ tpmc \ - vbutil_ec \ vbutil_firmware \ vbutil_kernel \ vbutil_key \ @@ -423,7 +422,6 @@ TEST_NAMES = \ vboot_common_tests \ vboot_common2_tests \ vboot_common3_tests \ - vboot_ec_tests \ vboot_firmware_tests \ vboot_nvstorage_test @@ -805,7 +803,6 @@ ${BUILD}/utility/dumpRSAPublicKey: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/pad_digest_utility: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/signature_digest_utility: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/dev_sign_file: LDLIBS += ${CRYPTO_LIBS} -${BUILD}/utility/vbutil_ec: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/vbutil_firmware: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/vbutil_kernel: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/utility/vbutil_key: LDLIBS += ${CRYPTO_LIBS} @@ -814,8 +811,6 @@ ${BUILD}/utility/vbutil_keyblock: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/host/linktest/main: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/tests/vboot_common2_tests: LDLIBS += ${CRYPTO_LIBS} ${BUILD}/tests/vboot_common3_tests: LDLIBS += ${CRYPTO_LIBS} -${BUILD}/tests/vboot_ec_tests: LDLIBS += ${CRYPTO_LIBS} - ${BUILD}/utility/bmpblk_utility: LD = ${CXX} ${BUILD}/utility/bmpblk_utility: LDLIBS = -llzma -lyaml @@ -963,7 +958,6 @@ runlongtests: test_setup genkeys genfuzztestcases ${RUNTEST} ${BUILD_RUN}/tests/vboot_common2_tests ${TEST_KEYS} --all ${RUNTEST} ${BUILD_RUN}/tests/vboot_common3_tests ${TEST_KEYS} --all tests/run_preamble_tests.sh --all - tests/run_vboot_ec_tests.sh tests/run_vbutil_tests.sh --all # TODO: tests to run when ported to new API diff --git a/firmware/lib/include/vboot_common.h b/firmware/lib/include/vboot_common.h index 76706bf6..fe886ce4 100644 --- a/firmware/lib/include/vboot_common.h +++ b/firmware/lib/include/vboot_common.h @@ -87,11 +87,6 @@ int VerifyData(const uint8_t* data, uint64_t size, const VbSignature* sig, int VerifyDigest(const uint8_t* digest, const VbSignature *sig, const RSAPublicKey* key); -/* Uses [key] algorithm to hash [data], then compares that to the expected - * [hash]. Returns 0 if they're equal, non-zero if error. */ -int EqualData(const uint8_t* data, uint64_t size, const VbSignature *hash, - const RSAPublicKey* key); - /* Checks the sanity of a key block of size [size] bytes, using public * key [key]. If hash_only is non-zero, uses only the block checksum * to verify the key block. Header fields are also checked for @@ -100,14 +95,6 @@ int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size, const VbPublicKey *key, int hash_only); -/* Checks the sanity of an EC preamble of size [size] bytes, - * using public key [key]. - * - * Returns VBOOT_SUCCESS if successful. */ -int VerifyECPreamble(const VbECPreambleHeader* preamble, - uint64_t size, const RSAPublicKey* key); - - /* Checks the sanity of a firmware preamble of size [size] bytes, * using public key [key]. * diff --git a/firmware/lib/vboot_common.c b/firmware/lib/vboot_common.c index 7878701f..bf79b81f 100644 --- a/firmware/lib/vboot_common.c +++ b/firmware/lib/vboot_common.c @@ -173,28 +173,6 @@ int VerifyDigest(const uint8_t* digest, const VbSignature *sig, } -int EqualData(const uint8_t* data, uint64_t size, const VbSignature *hash, - const RSAPublicKey* key) { - uint8_t* digest = NULL; - int rv; - - if (hash->sig_size != hash_size_map[key->algorithm]) { - VBDEBUG(("Wrong hash size for algorithm.\n")); - return 1; - } - if (hash->data_size > size) { - VBDEBUG(("Data buffer smaller than length of signed data.\n")); - return 1; - } - - digest = DigestBuf(data, hash->data_size, key->algorithm); - - rv = SafeMemcmp(digest, GetSignatureDataC(hash), hash->sig_size); - VbExFree(digest); - return rv; -} - - int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size, const VbPublicKey *key, int hash_only) { @@ -313,63 +291,6 @@ int KeyBlockVerify(const VbKeyBlockHeader* block, uint64_t size, return VBOOT_SUCCESS; } - -int VerifyECPreamble(const VbECPreambleHeader* preamble, - uint64_t size, const RSAPublicKey* key) { - - const VbSignature* sig = &preamble->preamble_signature; - - /* Sanity checks before attempting signature of data */ - if(size < EXPECTED_VB_EC_PREAMBLE_HEADER1_0_SIZE) { - VBDEBUG(("Not enough data for EC preamble header.\n")); - return VBOOT_PREAMBLE_INVALID; - } - if (preamble->header_version_major != - EC_PREAMBLE_HEADER_VERSION_MAJOR) { - VBDEBUG(("Incompatible EC preamble header version (%d, not %d).\n", - preamble->header_version_major, - EC_PREAMBLE_HEADER_VERSION_MAJOR)); - return VBOOT_PREAMBLE_INVALID; - } - if (size < preamble->preamble_size) { - VBDEBUG(("Not enough data for EC preamble.\n")); - return VBOOT_PREAMBLE_INVALID; - } - - /* Check signature */ - if (VerifySignatureInside(preamble, preamble->preamble_size, sig)) { - VBDEBUG(("EC 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(("EC signature calculated past end of the block\n")); - return VBOOT_PREAMBLE_INVALID; - } - - if (VerifyData((const uint8_t*)preamble, size, sig, key)) { - VBDEBUG(("EC 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 digest is inside the signed data */ - if (VerifySignatureInside(preamble, sig->data_size, - &preamble->body_digest)) { - VBDEBUG(("EC body digest off end of preamble\n")); - return VBOOT_PREAMBLE_INVALID; - } - - /* Success */ - return VBOOT_SUCCESS; -} - int VerifyFirmwarePreamble(const VbFirmwarePreambleHeader* preamble, uint64_t size, const RSAPublicKey* key) { diff --git a/tests/run_vboot_ec_tests.sh b/tests/run_vboot_ec_tests.sh deleted file mode 100755 index 302a3578..00000000 --- a/tests/run_vboot_ec_tests.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -eu - -# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Run verified boot firmware and kernel verification tests. - -# Load common constants and variables. -. "$(dirname "$0")/common.sh" - -check_test_keys - -for priv in ${TESTKEY_DIR}/*.vbprivk; do - root=$(basename ${priv%.vbprivk}) - pub="${priv%.vbprivk}.vbpubk" - echo "Trying $root ..." - ${TEST_DIR}/vboot_ec_tests "$priv" "$pub" -done diff --git a/tests/vboot_ec_tests.c b/tests/vboot_ec_tests.c deleted file mode 100644 index 831565fc..00000000 --- a/tests/vboot_ec_tests.c +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Tests for EC firmware vboot stuff. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "cryptolib.h" -#include "file_keys.h" -#include "host_common.h" -#include "test_common.h" -#include "vboot_common.h" - -static void ReSignECPreamble(VbECPreambleHeader* 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 VerifyECPreambleTest(const VbPublicKey* public_key, - const VbPrivateKey* private_key) { - VbECPreambleHeader* hdr; - VbECPreambleHeader* h; - RSAPublicKey* rsa; - unsigned hsize; - - /* Create a dummy signature */ - VbSignature* body_sig = SignatureAlloc(56, 78); - - rsa = PublicKeyToRSA(public_key); - hdr = CreateECPreamble(0x1234, body_sig, private_key, - 0x5678, "Foo bar"); - TEST_NEQ(hdr && rsa, 0, "VerifyECPreamble() prerequisites"); - if (!hdr) - return; - - hsize = (unsigned) hdr->preamble_size; - h = (VbECPreambleHeader*)malloc(hsize + 16384); - - TEST_EQ(VerifyECPreamble(hdr, hsize, rsa), 0, - "VerifyECPreamble() ok using key"); - TEST_NEQ(VerifyECPreamble(hdr, hsize - 1, rsa), 0, - "VerifyECPreamble() size--"); - TEST_EQ(VerifyECPreamble(hdr, hsize + 1, rsa), 0, - "VerifyECPreamble() size++"); - - TEST_EQ(hdr->firmware_version, 0x1234, - "VerifyECPreamble() firmware version"); - TEST_EQ(hdr->flags, 0x5678, - "VerifyECPreamble() flags"); - TEST_EQ(strncmp(hdr->name, "Foo bar", sizeof(hdr->name)), 0, - "VerifyECPreamble() name"); - - /* Care about major version but not minor */ - Memcpy(h, hdr, hsize); - h->header_version_major++; - ReSignECPreamble(h, private_key); - TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, - "VerifyECPreamble() major++"); - - Memcpy(h, hdr, hsize); - h->header_version_major--; - ReSignECPreamble(h, private_key); - TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, - "VerifyECPreamble() major--"); - - Memcpy(h, hdr, hsize); - h->header_version_minor++; - ReSignECPreamble(h, private_key); - TEST_EQ(VerifyECPreamble(h, hsize, rsa), 0, - "VerifyECPreamble() minor++"); - - Memcpy(h, hdr, hsize); - h->header_version_minor--; - ReSignECPreamble(h, private_key); - TEST_EQ(VerifyECPreamble(h, hsize, rsa), 0, - "VerifyECPreamble() minor--"); - - /* Check signature */ - Memcpy(h, hdr, hsize); - h->preamble_signature.sig_offset = hsize; - ReSignECPreamble(h, private_key); - TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, - "VerifyECPreamble() sig off end"); - - Memcpy(h, hdr, hsize); - h->preamble_signature.sig_size--; - ReSignECPreamble(h, private_key); - TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, - "VerifyECPreamble() sig too small"); - - Memcpy(h, hdr, hsize); - GetSignatureData(&h->body_digest)[0] ^= 0x34; - TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, - "VerifyECPreamble() sig mismatch"); - - /* Check that we signed header and body sig */ - Memcpy(h, hdr, hsize); - h->preamble_signature.data_size = 4; - h->body_digest.sig_offset = 0; - h->body_digest.sig_size = 0; - ReSignECPreamble(h, private_key); - TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, - "VerifyECPreamble() didn't sign header"); - - Memcpy(h, hdr, hsize); - h->body_digest.sig_offset = hsize; - ReSignECPreamble(h, private_key); - TEST_NEQ(VerifyECPreamble(h, hsize, rsa), 0, - "VerifyECPreamble() body sig off end"); - - /* TODO: verify with extra padding at end of header. */ - - free(h); - RSAPublicKeyFree(rsa); - free(hdr); -} - - -int main(int argc, char* argv[]) { - VbPrivateKey* signing_private_key = NULL; - VbPublicKey* signing_public_key = NULL; - - int error_code = 0; - - if(argc != 3) { - fprintf(stderr, "Usage: %s <signing privkey> <signing pubkey>", argv[0]); - return -1; - } - - signing_private_key = PrivateKeyRead(argv[1]); - if (!signing_private_key) { - fprintf(stderr, "Error reading signing_private_key\n"); - return 1; - } - - signing_public_key = PublicKeyRead(argv[2]); - if (!signing_public_key) { - fprintf(stderr, "Error reading signing_public_key\n"); - return 1; - } - - VerifyECPreambleTest(signing_public_key, signing_private_key); - - - if (signing_public_key) - free(signing_public_key); - if (signing_private_key) - free(signing_private_key); - - return error_code; -} diff --git a/utility/vbutil_ec.c b/utility/vbutil_ec.c deleted file mode 100644 index 4aa0d3f8..00000000 --- a/utility/vbutil_ec.c +++ /dev/null @@ -1,532 +0,0 @@ -/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Verified boot utility for EC firmware - */ - -#include <errno.h> -#include <fcntl.h> -#include <getopt.h> -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <unistd.h> - -#include "cryptolib.h" -#include "fmap.h" -#include "host_common.h" -#include "vboot_common.h" - - -/* Command line options */ -enum { - OPT_MODE_SIGN = 1000, - OPT_MODE_VERIFY, - OPT_KEYBLOCK, - OPT_SIGNPUBKEY, - OPT_SIGNPRIVATE, - OPT_VERSION, - OPT_FV, - OPT_KERNELKEY, - OPT_FLAGS, - OPT_NAME, -}; - -static struct option long_opts[] = { - {"sign", 1, 0, OPT_MODE_SIGN }, - {"verify", 1, 0, OPT_MODE_VERIFY }, - {"keyblock", 1, 0, OPT_KEYBLOCK }, - {"signpubkey", 1, 0, OPT_SIGNPUBKEY }, - {"signprivate", 1, 0, OPT_SIGNPRIVATE }, - {"version", 1, 0, OPT_VERSION }, - {"flags", 1, 0, OPT_FLAGS }, - {"name", 1, 0, OPT_NAME }, - {NULL, 0, 0, 0} -}; - - -/* Print help and return error */ -static int PrintHelp(void) { - - puts("vbutil_ec - Verified boot signing utility for EC firmware\n" - "\n" - "This will sign, re-sign, or test a complete EC firmware image.\n" - "The EC image is initially completely unsigned. To make it bootable\n" - "the pubic root key must be installed in the RO section, and each RW\n" - "section must be signed with the appropriate private keys.\n" - "\n" - "To sign an image: vbutil_ec --sign <file> [OPTIONS]\n" - "\n" - "For signing, these options are required:\n" - "\n" - " --keyblock <file> Key block in .keyblock format\n" - " --signprivate <file> Signing private key in .vbprivk format\n" - " --version <number> Firmware version\n" - "\n" - "If the RO public key has not been installed, you will also need\n" - "\n" - " --signpubkey <file> Signing public key in .vbpubk format\n" - "\n" - "Optional args are:\n" - "\n" - " --flags <number> Preamble flags (defaults to 0)\n" - " --name <string> Human-readable description\n" - "\n" - "\n" - "To verify an image: vbutil_ec --verify <file>\n" - "\n"); - return 1; -} - - -static int FindInFmap(FmapHeader *fh, const char *name, - uint8_t *base, uint64_t base_size, - uint8_t **data, uint64_t *size) { - const FmapAreaHeader *ah; - int i; - - ah = (FmapAreaHeader *)(fh + 1); - for (i = 0; i < fh->fmap_nareas; i++) - if (!strncmp(ah[i].area_name, name, FMAP_NAMELEN)) { - if (ah[i].area_size + ah[i].area_offset > base_size) { - printf("FMAP region %s extends off image file\n", name); - return 0; - } - if (data) - *data = base + ah[i].area_offset; - if (size) - *size = ah[i].area_size; - return 1; - } - - return 0; -} - -static int GoodKey(VbPublicKey *key, uint64_t region_size) -{ - uint64_t key_size; - - if (0 != VerifyPublicKeyInside(key, region_size, key)) - return 0; - - if (key->algorithm >= kNumAlgorithms) - return 0; - - /* Currently, TPM only supports 16-bit version */ - if (key->key_version > 0xFFFF) - return 0; - - if (!RSAProcessedKeySize(key->algorithm, &key_size) || - key_size != key->key_size) - return 0; - - return 1; -} - - -/* We build the image file with a non-FF byte at the end of each RW firmware, - * just so we can do this. */ -static uint64_t FindImageEnd(uint8_t *data, uint64_t size) -{ - for (size-- ; size && data[size] == 0xff; size--) - ; - return size; -} - -static void SignImage(const char *filename, - VbKeyBlockHeader *key_block, uint64_t key_block_size, - VbPrivateKey *privkey, uint64_t version, - VbPublicKey *pubkey, uint32_t preamble_flags, - const char *name) { - struct stat sb; - int fd; - void *image; - uint64_t image_size; - FmapHeader* fmap; - VbECPreambleHeader *preamble; - uint8_t *fv_data = 0; - uint8_t *vblock_data = 0; - uint64_t fv_size, vblock_size; - VbSignature* body_digest; - - if (name && strlen(name)+1 > sizeof(preamble->name)) - VbExError("Name string is too long\n"); - - if (0 != stat(filename, &sb)) - VbExError("Can't stat %s: %s\n", filename, strerror(errno)); - - fd = open(filename, O_RDWR); - if (fd < 0) - VbExError("Can't open %s: %s\n", filename, strerror(errno)); - - image = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (image == (void *)-1) - VbExError("Can't mmap %s: %s\n", filename, strerror(errno)); - close(fd); /* done with this now */ - - fmap = (FmapHeader *)FmapFind(image, sb.st_size); - if (!fmap) - VbExError("File %s doesn't have an FMAP - can't continue.\n"); - - if (fmap->fmap_size > sb.st_size) - VbExError("FMAP is bigger than file size (%ld vs %ld)\n", - fmap->fmap_size, sb.st_size); - - image_size = sb.st_size; - - /* Install pubkey if provided */ - if (pubkey) { - if (!FindInFmap(fmap, "ROOT_KEY", image, image_size, - &vblock_data, &vblock_size)) - VbExError("Can't find ROOT_KEY in %s\n", filename); - - if (pubkey->key_offset + pubkey->key_size > vblock_size) - VbExError("ROOT_KEY is too small for pubkey (%d bytes, needs %d)\n", - vblock_size, pubkey->key_offset + pubkey->key_size); - - memcpy(vblock_data, pubkey, pubkey->key_offset + pubkey->key_size); - } - - - /* Sign FW A */ - if (!FindInFmap(fmap, "FW_MAIN_A", image, image_size, &fv_data, &fv_size)) - VbExError("Can't find FW_MAIN_A in %s\n", filename); - - if (!FindInFmap(fmap, "VBLOCK_A", image, image_size, - &vblock_data, &vblock_size)) - VbExError("Can't find VBLOCK_A in %s\n", filename); - - fv_size = FindImageEnd(fv_data, fv_size); - - body_digest = CalculateHash(fv_data, fv_size, privkey); - if (!body_digest) - VbExError("Error calculating body digest\n"); - - preamble = CreateECPreamble(version, body_digest, privkey, - preamble_flags, name); - if (!preamble) - VbExError("Error creating preamble.\n"); - - if (key_block_size + preamble->preamble_size > vblock_size) - VbExError("VBLOCK_A is too small for digest (%d bytes, needs %d)\n", - vblock_size, key_block_size + preamble->preamble_size); - - memcpy(vblock_data, key_block, key_block_size); - memcpy(vblock_data + key_block_size, preamble, preamble->preamble_size); - - free(body_digest); - free(preamble); - - - /* Sign FW B - skip if there isn't one */ - if (!FindInFmap(fmap, "FW_MAIN_B", image, image_size, &fv_data, &fv_size) || - !FindInFmap(fmap, "VBLOCK_B", image, image_size, - &vblock_data, &vblock_size)) { - printf("Image does not contain FW B - ignoring that part\n"); - } else { - fv_size = FindImageEnd(fv_data, fv_size); - - body_digest = CalculateHash(fv_data, fv_size, privkey); - if (!body_digest) - VbExError("Error calculating body digest\n"); - - preamble = CreateECPreamble(version, body_digest, privkey, - preamble_flags, name); - if (!preamble) - VbExError("Error creating preamble.\n"); - - if (key_block_size + preamble->preamble_size > vblock_size) - VbExError("VBLOCK_B is too small for digest (%d bytes, needs %d)\n", - vblock_size, key_block_size + preamble->preamble_size); - - memcpy(vblock_data, key_block, key_block_size); - memcpy(vblock_data + key_block_size, preamble, preamble->preamble_size); - - free(body_digest); - free(preamble); - } - - /* Unmap to write changes to disk. */ - if (0 != munmap(image, sb.st_size)) - VbExError("Can't munmap %s: %s\n", filename, strerror(errno)); - - printf("Image signing completed\n"); - -} - -static int Verify(const char *filename) { - struct stat sb; - int fd; - void *image; - uint64_t image_size; - FmapHeader* fmap; - VbECPreambleHeader *preamble; - VbPublicKey *pubkey; - uint64_t pubkey_size; - VbKeyBlockHeader *key_block; - uint64_t key_block_size; - uint8_t *fv_data = 0; - uint64_t fv_size; - VbPublicKey *data_key; - RSAPublicKey* rsa; - int errorcnt = 0; - char buf[80]; - int i; - - if (0 != stat(filename, &sb)) - VbExError("Can't stat %s: %s\n", filename, strerror(errno)); - - fd = open(filename, O_RDONLY); - if (fd < 0) - VbExError("Can't open %s: %s\n", filename, strerror(errno)); - - image = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (image == (void *)-1) - VbExError("Can't mmap %s: %s\n", filename, strerror(errno)); - close(fd); /* done with this now */ - - fmap = (FmapHeader *)FmapFind(image, sb.st_size); - if (!fmap) - VbExError("File %s doesn't have an FMAP - can't continue.\n"); - - if (fmap->fmap_size > sb.st_size) - VbExError("FMAP is bigger than file size (%ld vs %ld)\n", - fmap->fmap_size, sb.st_size); - - image_size = sb.st_size; - - /* Read pubkey */ - if (!FindInFmap(fmap, "ROOT_KEY", image, image_size, - (uint8_t **)&pubkey, &pubkey_size)) { - printf("Can't find ROOT_KEY in %s\n", filename); - errorcnt++; - } else if (!GoodKey(pubkey, pubkey_size)) { - printf("ROOT_KEY is invalid\n"); - errorcnt++; - } else { - printf("ROOT_KEY\n"); - printf(" Algorithm: %" PRIu64 " %s\n", pubkey->algorithm, - (pubkey->algorithm < kNumAlgorithms ? - algo_strings[pubkey->algorithm] : "(invalid)")); - printf(" Key Version: %" PRIu64 "\n", pubkey->key_version); - printf(" Key sha1sum: "); - PrintPubKeySha1Sum(pubkey); - printf("\n"); - } - - for (i = 'A'; i <= 'B'; i++) { - - fv_data = 0; - key_block = 0; - preamble = 0; - - printf("FW %c\n", i); - sprintf(buf, "FW_MAIN_%c", i); - if (!FindInFmap(fmap, buf, image, image_size, &fv_data, &fv_size)) { - printf("Can't find %s in %s\n", buf, filename); - /* Not an error for firmware B */ - if (i != 'B') - errorcnt++; - continue; - } - - sprintf(buf, "VBLOCK_%c", i); - if (!FindInFmap(fmap, buf, image, image_size, - (uint8_t **)&key_block, &key_block_size)) { - printf("Can't find %s in %s\n", buf, filename); - /* Not an error for firmware B */ - if (i != 'B') - errorcnt++; - continue; - } - - if (0 != KeyBlockVerify(key_block, key_block_size, pubkey, !pubkey)) { - printf("Error verifying key block for %s.\n", buf); - errorcnt++; - continue; - } - 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"); - - preamble = (VbECPreambleHeader*) - ((uint8_t *)key_block + key_block->key_block_size); - - rsa = PublicKeyToRSA(&key_block->data_key); - if (!rsa) { - printf("Error parsing data key.\n"); - errorcnt++; - } - /* Verify preamble */ - if (0 != VerifyECPreamble(preamble, - key_block_size - key_block->key_block_size, - rsa)) { - printf("Error verifying preamble.\n"); - errorcnt++; - free(rsa); - continue; - } - 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); - printf(" Firmware body size: %" PRIu64 "\n", - preamble->body_digest.data_size); - printf(" Preamble flags: %" PRIu32 "\n", preamble->flags); - printf(" Preamble name: %s\n", preamble->name); - - /* TODO: verify body size same as signature size */ - - /* Verify body */ - if (preamble->flags & VB_FIRMWARE_PREAMBLE_USE_RO_NORMAL) { - printf("Preamble requests USE_RO_NORMAL; skipping verification.\n"); - } else { - if (0 != EqualData(fv_data, fv_size, - &preamble->body_digest, rsa)) { - printf("Error verifying firmware body.\n"); - errorcnt++; - } - } - free(rsa); - } - - /* Done */ - if (0 != munmap(image, sb.st_size)) - VbExError("Can't munmap %s: %s\n", filename, strerror(errno)); - - printf("Done\n"); - return errorcnt; -} - -int main(int argc, char* argv[]) { - - char* filename = NULL; - uint64_t version = 0; - int got_version = 0; - uint32_t preamble_flags = 0; - char *name = NULL; - int mode = 0; - VbKeyBlockHeader* key_block = 0; - VbPrivateKey* privkey = 0; - VbPublicKey* pubkey = 0; - uint64_t key_block_size; - int errorcnt = 0; - char* e; - int i; - - while ((i = getopt_long(argc, argv, "", long_opts, NULL)) != -1) { - switch (i) { - case '?': - /* Unhandled option */ - printf("Unknown option\n"); - errorcnt++; - break; - - case OPT_MODE_SIGN: - case OPT_MODE_VERIFY: - mode = i; - filename = optarg; - break; - - case OPT_KEYBLOCK: - /* Read the key block and keys */ - key_block = (VbKeyBlockHeader*)ReadFile(optarg, &key_block_size); - if (!key_block) { - printf("Error reading key block from %s\n", optarg); - errorcnt++; - } - break; - - case OPT_SIGNPUBKEY: - pubkey = PublicKeyRead(optarg); - if (!pubkey) { - printf("Error reading public key from %s\n", optarg); - errorcnt++; - } - break; - - case OPT_SIGNPRIVATE: - privkey = PrivateKeyRead(optarg); - if (!privkey) { - printf("Error reading private key from %s\n", optarg); - errorcnt++; - } - break; - - case OPT_VERSION: - version = strtoul(optarg, &e, 0); - if (!*optarg || (e && *e)) { - printf("Invalid --version argument: \"%s\"\n", optarg); - errorcnt++; - } - got_version = 1; - break; - - case OPT_FLAGS: - preamble_flags = strtoul(optarg, &e, 0); - if (!*optarg || (e && *e)) { - printf("Invalid --flags argument: \"%s\"\n", optarg); - errorcnt++; - } - break; - - case OPT_NAME: - name = optarg; - break; - } - } - - switch(mode) { - - case OPT_MODE_SIGN: - /* Check required args */ - if (!key_block) { - printf("The ----keyblock arg is required when signing\n"); - errorcnt++; - } - if (!privkey) { - printf("The --signprivate arg is required when signing\n"); - errorcnt++; - } - if (!got_version) { - printf("The --version arg is required when signing\n"); - errorcnt++; - } - - if (errorcnt) - return PrintHelp(); - - /* Sign or die */ - SignImage(filename, key_block, key_block_size, - privkey, version, pubkey, preamble_flags, name); - - /* fall through and verify what we've just done */ - - case OPT_MODE_VERIFY: - return Verify(filename); - - default: - printf("\nMust specify a mode, either --sign or --verify.\n\n"); - return PrintHelp(); - } -} |