summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-01-24 10:59:12 -0800
committerChromeBot <chrome-bot@google.com>2013-01-24 16:46:49 -0800
commit0f872495cab2bcd8fc74f478bdbfd4293a67b47c (patch)
tree4e19fab0d328b8f11fe26d258a911b2d60b1dbbc
parent91db23243f53d677e7e522352bb5942dc2b3cb2b (diff)
downloadvboot-0f872495cab2bcd8fc74f478bdbfd4293a67b47c.tar.gz
Remove unused vbutil_ec
EC verification is done via software sync; the EC doesn't do vboot on its own. BUG=chromium-os:38139 BRANCH=none TEST=manual make runtests emerge-link vboot_reference chromeos-u-boot chromeos-bootimage Change-Id: I6e5c0db8fc54b474f044d37c2603a9c116747a85 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/41953 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r--Makefile6
-rw-r--r--firmware/lib/include/vboot_common.h13
-rw-r--r--firmware/lib/vboot_common.c79
-rwxr-xr-xtests/run_vboot_ec_tests.sh19
-rw-r--r--tests/vboot_ec_tests.c160
-rw-r--r--utility/vbutil_ec.c532
6 files changed, 0 insertions, 809 deletions
diff --git a/Makefile b/Makefile
index 36d7a125..f561e445 100644
--- a/Makefile
+++ b/Makefile
@@ -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();
- }
-}