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>
This commit is contained in:
Randall Spangler
2013-01-24 10:59:12 -08:00
committed by ChromeBot
parent 91db23243f
commit 0f872495ca
6 changed files with 0 additions and 809 deletions

View File

@@ -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

View File

@@ -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].
*

View File

@@ -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) {

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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();
}
}