diff --git a/host/include/host_misc.h b/host/include/host_misc.h index abbfc0f622..cbf9eaffab 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 d8f5297020..91eaea25d5 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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; ifmap_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', required OPTIONS are:\n" " --signpubkey Signing public key in .vbpubk format\n" " --fv Firmware volume to verify\n" + "\n" + "For '--verify ', optional OPTIONS are:\n" + " --kernelkey 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 80197194b8..acf156f704 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 c076bfff0f..38d9000305 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; ialgorithm] : "(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 7d5b7c137a..ff1b44be45 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)) {