summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--host/include/host_misc.h2
-rw-r--r--host/lib/host_misc.c10
-rw-r--r--utility/Makefile12
-rwxr-xr-xutility/dev_debug_vboot67
-rw-r--r--utility/dump_fmap.c192
-rw-r--r--utility/vbutil_firmware.c36
-rw-r--r--utility/vbutil_kernel.c14
-rw-r--r--utility/vbutil_key.c13
-rw-r--r--utility/vbutil_keyblock.c12
9 files changed, 337 insertions, 21 deletions
diff --git a/host/include/host_misc.h b/host/include/host_misc.h
index abbfc0f6..cbf9eaff 100644
--- a/host/include/host_misc.h
+++ b/host/include/host_misc.h
@@ -24,5 +24,7 @@ uint8_t* ReadFile(const char* filename, uint64_t* size);
* Returns 0 if success, 1 if error. */
int WriteFile(const char* filename, const void *data, uint64_t size);
+/* Prints the sha1sum of the given VbPublicKey to stdout. */
+void PrintPubKeySha1Sum(VbPublicKey* key);
#endif /* VBOOT_REFERENCE_HOST_MISC_H_ */
diff --git a/host/lib/host_misc.c b/host/lib/host_misc.c
index d8f52970..91eaea25 100644
--- a/host/lib/host_misc.c
+++ b/host/lib/host_misc.c
@@ -66,3 +66,13 @@ int WriteFile(const char* filename, const void *data, uint64_t size) {
fclose(f);
return 0;
}
+
+void PrintPubKeySha1Sum(VbPublicKey* key) {
+ uint8_t* buf = ((uint8_t *)key) + key->key_offset;
+ uint64_t buflen = key->key_size;
+ uint8_t* digest = DigestBuf(buf, buflen, SHA1_DIGEST_ALGORITHM);
+ int i;
+ for (i=0; i<SHA1_DIGEST_SIZE; i++)
+ printf("%02x", digest[i]);
+ Free(digest);
+}
diff --git a/utility/Makefile b/utility/Makefile
index 745cc9c9..516e91a4 100644
--- a/utility/Makefile
+++ b/utility/Makefile
@@ -31,7 +31,9 @@ TARGET_NAMES = dumpRSAPublicKey \
vbutil_keyblock \
verify_data \
dev_make_keypair \
- dev_sign_file
+ dev_sign_file \
+ dump_fmap \
+ dev_debug_vboot
TARGET_BINS = $(addprefix ${BUILD_ROOT}/,$(TARGET_NAMES))
ALL_DEPS = $(addsuffix .d,${TARGET_BINS})
@@ -79,6 +81,11 @@ ${BUILD_ROOT}/tpm_init_temp_fix: tpm_init_temp_fix.c $(LIBS)
${BUILD_ROOT}/dev_make_keypair: dev_make_keypair
cp -f $< $@
+ chmod +x $@
+
+${BUILD_ROOT}/dev_debug_vboot: dev_debug_vboot
+ cp -f $< $@
+ chmod +x $@
${BUILD_ROOT}/tpmc: tpmc.c $(LIBS)
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS)
@@ -86,6 +93,9 @@ ${BUILD_ROOT}/tpmc: tpmc.c $(LIBS)
${BUILD_ROOT}/dev_sign_file: dev_sign_file.c $(LIBS)
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
+${BUILD_ROOT}/dump_fmap: dump_fmap.c
+ $(CC) $(CFLAGS) $< -o $@
+
install: $(TARGET_BINS)
mkdir -p $(DESTDIR)
cp -f $(TARGET_BINS) $(DESTDIR)
diff --git a/utility/dev_debug_vboot b/utility/dev_debug_vboot
new file mode 100755
index 00000000..424e9e41
--- /dev/null
+++ b/utility/dev_debug_vboot
@@ -0,0 +1,67 @@
+#!/bin/sh
+# 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.
+#
+
+TMPDIR=/tmp/debug_vboot
+BIOS=bios.rom
+# FIXME: support ARM
+HD_KERN_A=/dev/sda2
+HD_KERN_B=/dev/sda4
+tmp=$(rootdev -s -d)2
+if [ "$tmp" != "$HD_KERN_A" ]; then
+ USB_KERN_A="$tmp"
+fi
+
+
+[ -d ${TMPDIR} ] || mkdir -p ${TMPDIR}
+cd ${TMPDIR}
+
+echo "INFO: extracting BIOS image from flash"
+flashrom -r ${BIOS}
+
+echo "INFO: extracting kernel images from drives"
+dd if=${HD_KERN_A} of=hd_kern_a.blob
+dd if=${HD_KERN_B} of=hd_kern_b.blob
+if [ -n "$USB_KERN_A" ]; then
+ dd if=${USB_KERN_A} of=usb_kern_a.blob
+fi
+
+echo "INFO: extracting BIOS components"
+dump_fmap -x ${BIOS} || echo "FAILED"
+
+echo "INFO: pulling root and recovery keys from GBB"
+gbb_utility -g --rootkey rootkey.vbpubk --recoverykey recoverykey.vbpubk \
+ GBB_Area || echo "FAILED"
+echo "INFO: display root key"
+vbutil_key --unpack rootkey.vbpubk
+echo "INFO: display recovery key"
+vbutil_key --unpack recoverykey.vbpubk
+
+echo "TEST: verify firmware A with root key"
+vbutil_firmware --verify Firmware_A_Key --signpubkey rootkey.vbpubk \
+ --fv Firmware_A_Data --kernelkey kernel_subkey_a.vbpubk || echo "FAILED"
+echo "TEST: verify firmware B with root key"
+vbutil_firmware --verify Firmware_B_Key --signpubkey rootkey.vbpubk \
+ --fv Firmware_B_Data --kernelkey kernel_subkey_b.vbpubk || echo "FAILED"
+
+echo "TEST: verify HD kernel A with firmware A key"
+vbutil_kernel --verify hd_kern_a.blob --signpubkey kernel_subkey_a.vbpubk \
+ || echo "FAILED"
+echo "TEST: verify HD kernel B with firmware A key"
+vbutil_kernel --verify hd_kern_b.blob --signpubkey kernel_subkey_a.vbpubk \
+ || echo "FAILED"
+
+echo "TEST: verify HD kernel A with firmware B key"
+vbutil_kernel --verify hd_kern_a.blob --signpubkey kernel_subkey_b.vbpubk \
+ || echo "FAILED"
+echo "TEST: verify HD kernel B with firmware B key"
+vbutil_kernel --verify hd_kern_b.blob --signpubkey kernel_subkey_b.vbpubk \
+ || echo "FAILED"
+
+if [ -n "$USB_KERN_A" ]; then
+ echo "TEST: verify USB kernel A with recovery key"
+ vbutil_kernel --verify usb_kern_a.blob --signpubkey recoverykey.vbpubk \
+ || echo "FAILED"
+fi
diff --git a/utility/dump_fmap.c b/utility/dump_fmap.c
new file mode 100644
index 00000000..a0d24de4
--- /dev/null
+++ b/utility/dump_fmap.c
@@ -0,0 +1,192 @@
+/*
+ * 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.
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.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>
+
+/* global variables */
+static int opt_extract = 0;
+static char *progname;
+static void *base_of_rom;
+
+/* FMAP structs. See http://code.google.com/p/flashmap/wiki/FmapSpec */
+#define FMAP_SIGLEN 8
+#define FMAP_NAMELEN 32
+#define FMAP_SEARCH_STRIDE 4
+typedef struct _FmapHeader {
+ char fmap_signature[FMAP_SIGLEN]; /* avoiding endian issues */
+ uint8_t fmap_ver_major;
+ uint8_t fmap_ver_minor;
+ uint64_t fmap_base;
+ uint32_t fmap_size;
+ char fmap_name[FMAP_NAMELEN];
+ uint16_t fmap_nareas;
+} __attribute__((packed)) FmapHeader;
+
+typedef struct _AreaHeader {
+ uint32_t area_offset;
+ uint32_t area_size;
+ char area_name[FMAP_NAMELEN];
+ uint16_t area_flags;
+} __attribute__((packed)) AreaHeader;
+
+
+/* Return 0 if successful */
+static int dump_fmap(void *ptr) {
+ int i,retval = 0;
+ char buf[80]; // DWR: magic number
+ FmapHeader *fmh = (FmapHeader *)ptr;
+ AreaHeader *ah = (AreaHeader *)(ptr + sizeof(FmapHeader));
+
+ snprintf(buf, FMAP_SIGLEN+1, "%s", fmh->fmap_signature);
+ printf("fmap_signature %s\n", buf);
+ printf("fmap_version: %d.%d\n", fmh->fmap_ver_major, fmh->fmap_ver_minor);
+ printf("fmap_base: 0x%" PRIx64 "\n", fmh->fmap_base);
+ printf("fmap_size: 0x%08x (%d)\n", fmh->fmap_size, fmh->fmap_size);
+ snprintf(buf, FMAP_NAMELEN+1, "%s", fmh->fmap_name);
+ printf("fmap_name: %s\n", buf);
+ printf("fmap_nareas: %d\n", fmh->fmap_nareas);
+
+ for (i=0; i<fmh->fmap_nareas; i++) {
+ printf("area: %d\n", i+1);
+ printf("area_offset: 0x%08x\n", ah->area_offset);
+ printf("area_size: 0x%08x (%d)\n", ah->area_size, ah->area_size);
+ snprintf(buf, FMAP_NAMELEN+1, "%s", ah->area_name);
+ printf("area_name: %s\n", buf);
+
+ if (opt_extract) {
+ char *s;
+ for (s=buf; *s; s++)
+ if (*s == ' ')
+ *s = '_';
+ FILE *fp = fopen(buf,"wb");
+ if (!fp) {
+ fprintf(stderr, "%s: can't open %s: %s\n",
+ progname, buf, strerror(errno));
+ retval = 1;
+ } else {
+ if (1 != fwrite(base_of_rom + ah->area_offset, ah->area_size, 1, fp)) {
+ fprintf(stderr, "%s: can't write %s: %s\n",
+ progname, buf, strerror(errno));
+ retval = 1;
+ } else {
+ printf("saved as \"%s\"\n", buf);
+ }
+ fclose(fp);
+ }
+ }
+
+ ah++;
+ }
+
+ return retval;
+}
+
+
+int main(int argc, char *argv[]) {
+ int c;
+ int errorcnt = 0;
+ struct stat sb;
+ int fd;
+ char *s;
+ size_t i;
+ int retval = 1;
+
+ progname = strrchr(argv[0], '/');
+ if (progname)
+ progname++;
+ else
+ progname = argv[0];
+
+ opterr = 0; /* quiet, you */
+ while ((c=getopt(argc, argv, ":x")) != -1) {
+ switch (c)
+ {
+ case 'x':
+ opt_extract = 1;
+ break;
+ case '?':
+ fprintf(stderr, "%s: unrecognized switch: -%c\n",
+ progname, optopt);
+ errorcnt++;
+ break;
+ case ':':
+ fprintf(stderr, "%s: missing argument to -%c\n",
+ progname, optopt);
+ errorcnt++;
+ break;
+ default:
+ errorcnt++;
+ break;
+ }
+ }
+
+ if (errorcnt || optind >= argc) {
+ fprintf(stderr,
+ "\nUsage: %s [-x] FLASHIMAGE\n\n"
+ "Display (and extract with -x) the FMAP components from a BIOS image"
+ "\n\n",
+ progname);
+ return 1;
+ }
+
+ if (0 != stat(argv[optind], &sb)) {
+ fprintf(stderr, "%s: can't stat %s: %s\n",
+ progname,
+ argv[optind],
+ strerror(errno));
+ return 1;
+ }
+
+ fd = open(argv[optind], O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "%s: can't open %s: %s\n",
+ progname,
+ argv[optind],
+ strerror(errno));
+ return 1;
+ }
+ printf("opened %s\n", argv[optind]);
+
+ base_of_rom = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (base_of_rom == (char *)-1) {
+ fprintf(stderr, "%s: can't mmap %s: %s\n",
+ progname,
+ argv[optind],
+ strerror(errno));
+ close(fd);
+ return 1;
+ }
+ close(fd); /* done with this now */
+
+ s = (char *)base_of_rom;
+ for (i=0; i<sb.st_size; i += FMAP_SEARCH_STRIDE) {
+ if (0 == strncmp(s, "__FMAP__", 8)) {
+ printf("hit at 0x%08x\n", (uint32_t)i);
+ retval = dump_fmap(s);
+ break;
+ }
+ s++;
+ }
+
+ if (0 != munmap(base_of_rom, sb.st_size)) {
+ fprintf(stderr, "%s: can't munmap %s: %s\n",
+ progname,
+ argv[optind],
+ strerror(errno));
+ return 1;
+ }
+
+ return retval;
+}
diff --git a/utility/vbutil_firmware.c b/utility/vbutil_firmware.c
index d58e2a3a..9cff2729 100644
--- a/utility/vbutil_firmware.c
+++ b/utility/vbutil_firmware.c
@@ -60,6 +60,9 @@ static int PrintHelp(void) {
"For '--verify <file>', required OPTIONS are:\n"
" --signpubkey <file> Signing public key in .vbpubk format\n"
" --fv <file> Firmware volume to verify\n"
+ "\n"
+ "For '--verify <file>', optional OPTIONS are:\n"
+ " --kernelkey <file> Write the kernel subkey to this file\n"
"");
return 1;
}
@@ -157,14 +160,14 @@ static int Vblock(const char* outfile, const char* keyblock_file,
return 0;
}
-
static int Verify(const char* infile, const char* signpubkey,
- const char* fv_file) {
+ const char* fv_file, const char* kernelkey_file) {
VbKeyBlockHeader* key_block;
VbFirmwarePreambleHeader* preamble;
VbPublicKey* data_key;
VbPublicKey* sign_key;
+ VbPublicKey* kernel_subkey;
RSAPublicKey* rsa;
uint8_t* blob;
uint64_t blob_size;
@@ -210,11 +213,15 @@ static int Verify(const char* infile, const char* signpubkey,
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(" Flags: %" PRIu64 "\n", key_block->key_block_flags);
+ printf(" Data key sha1sum: ");
+ PrintPubKeySha1Sum(data_key);
+ printf("\n");
rsa = PublicKeyToRSA(&key_block->data_key);
if (!rsa) {
@@ -235,12 +242,16 @@ static int Verify(const char* infile, const char* signpubkey,
printf(" Header version: %" PRIu32 ".%" PRIu32"\n",
preamble->header_version_major, preamble->header_version_minor);
printf(" Firmware version: %" PRIu64 "\n", preamble->firmware_version);
+ kernel_subkey = &preamble->kernel_subkey;
printf(" Kernel key algorithm: %" PRIu64 " %s\n",
- preamble->kernel_subkey.algorithm,
- (preamble->kernel_subkey.algorithm < kNumAlgorithms ?
- algo_strings[preamble->kernel_subkey.algorithm] : "(invalid)"));
+ kernel_subkey->algorithm,
+ (kernel_subkey->algorithm < kNumAlgorithms ?
+ algo_strings[kernel_subkey->algorithm] : "(invalid)"));
printf(" Kernel key version: %" PRIu64 "\n",
- preamble->kernel_subkey.key_version);
+ kernel_subkey->key_version);
+ printf(" Kernel key sha1sum: ");
+ PrintPubKeySha1Sum(kernel_subkey);
+ printf("\n");
printf(" Firmware body size: %" PRIu64 "\n",
preamble->body_signature.data_size);
@@ -252,6 +263,15 @@ static int Verify(const char* infile, const char* signpubkey,
return 1;
}
printf("Body verification succeeded.\n");
+
+ if (kernelkey_file) {
+ if (0 != PublicKeyWrite(kernelkey_file, kernel_subkey)) {
+ fprintf(stderr,
+ "vbutil_firmware: unable to write kernel subkey\n");
+ return 1;
+ }
+ }
+
return 0;
}
@@ -322,7 +342,7 @@ int main(int argc, char* argv[]) {
return Vblock(filename, key_block_file, signprivate, version, fv_file,
kernelkey_file);
case OPT_MODE_VERIFY:
- return Verify(filename, signpubkey, fv_file);
+ return Verify(filename, signpubkey, fv_file, kernelkey_file);
default:
printf("Must specify a mode.\n");
return PrintHelp();
diff --git a/utility/vbutil_kernel.c b/utility/vbutil_kernel.c
index 80197194..acf156f7 100644
--- a/utility/vbutil_kernel.c
+++ b/utility/vbutil_kernel.c
@@ -661,11 +661,23 @@ static int Verify(const char* infile, const char* signpubkey, int verbose) {
if (verbose)
printf(" Signature: %s\n", sign_key ? "valid" : "ignored");
printf(" Size: 0x%" PRIx64 "\n", key_block->key_block_size);
+ printf(" Flags: %" PRIu64 " ", key_block->key_block_flags);
+ if (key_block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_0)
+ printf(" !DEV");
+ if (key_block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_1)
+ printf(" DEV");
+ if (key_block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0)
+ printf(" !REC");
+ if (key_block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_1)
+ printf(" REC");
+ printf("\n");
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(" Flags: %" PRIu64 "\n", key_block->key_block_flags);
+ printf(" Data key sha1sum: ");
+ PrintPubKeySha1Sum(data_key);
+ printf("\n");
rsa = PublicKeyToRSA(&key_block->data_key);
if (!rsa) {
diff --git a/utility/vbutil_key.c b/utility/vbutil_key.c
index c076bfff..38d90003 100644
--- a/utility/vbutil_key.c
+++ b/utility/vbutil_key.c
@@ -108,15 +108,6 @@ static int Pack(const char *infile, const char *outfile, uint64_t algorithm,
}
-static void PrintDigest(const uint8_t* buf, uint64_t buflen) {
- uint8_t *digest = DigestBuf(buf, buflen, SHA1_DIGEST_ALGORITHM);
- int i;
- for (i=0; i<SHA1_DIGEST_SIZE; i++)
- printf("%02x", digest[i]);
- printf("\n");
- Free(digest);
-}
-
/* Unpack a .vbpubk or .vbprivk */
static int Unpack(const char *infile, const char *outfile) {
VbPublicKey* pubkey;
@@ -134,7 +125,8 @@ static int Unpack(const char *infile, const char *outfile) {
algo_strings[pubkey->algorithm] : "(invalid)"));
printf("Key Version: %" PRIu64 "\n", pubkey->key_version);
printf("Key sha1sum: ");
- PrintDigest(((uint8_t *)pubkey) + pubkey->key_offset, pubkey->key_size);
+ PrintPubKeySha1Sum(pubkey);
+ printf("\n");
if (outfile) {
if (0 != PublicKeyWrite(outfile, pubkey)) {
fprintf(stderr, "vbutil_key: Error writing key copy.\n");
@@ -146,7 +138,6 @@ static int Unpack(const char *infile, const char *outfile) {
return 0;
}
-
if ((privkey = PrivateKeyRead(infile))) {
printf("Private Key file: %s\n", infile);
printf("Algorithm: %" PRIu64 " %s\n", privkey->algorithm,
diff --git a/utility/vbutil_keyblock.c b/utility/vbutil_keyblock.c
index 7d5b7c13..ff1b44be 100644
--- a/utility/vbutil_keyblock.c
+++ b/utility/vbutil_keyblock.c
@@ -152,12 +152,24 @@ static int Unpack(const char* infile, const char* datapubkey,
printf("Key block file: %s\n", infile);
printf("Flags: %" PRIu64 "\n", block->key_block_flags);
+ if (block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_0)
+ printf(" !DEV");
+ if (block->key_block_flags & KEY_BLOCK_FLAG_DEVELOPER_1)
+ printf(" DEV");
+ if (block->key_block_flags & KEY_BLOCK_FLAG_RECOVERY_0)
+ printf(" !REC");
+ if (block->key_block_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,
(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");
if (datapubkey) {
if (0 != PublicKeyWrite(datapubkey, data_key)) {