From 6df3e33912baf2633ed27fce6fe166d87e2f04a8 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 2 Oct 2014 18:50:33 -0700 Subject: Add hwid digest field to GBB header This adds a field in the GBB header to store the sha256 digest of the HWID string, and updates gbb_utility so that it stores the digest when it modifies the HWID. Because this is a new field, the GBB_MINOR_VER is incremented. BUG=chromium:415227 BRANCH=ToT TEST=make runtests, VBOOT2=1 make runtests Since the GBB is in the RO firmware, there should be no side effects for existing devices (but even without that, they should handle a minor version change without complaint). Change-Id: Icdb2a0b564677b0b65e58df897d2ec5af3964998 Signed-off-by: Bill Richardson Reviewed-on: https://chromium-review.googlesource.com/221360 --- futility/cmd_gbb_utility.c | 16 ++++++++++++++- futility/cmd_show.c | 4 ++-- futility/futility.c | 2 +- futility/futility.h | 8 ++++++++ futility/misc.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 4 deletions(-) (limited to 'futility') diff --git a/futility/cmd_gbb_utility.c b/futility/cmd_gbb_utility.c index e8910e67..9e608d1f 100644 --- a/futility/cmd_gbb_utility.c +++ b/futility/cmd_gbb_utility.c @@ -29,6 +29,7 @@ static void print_help(const char *prog) "with following options:\n" " --hwid \tReport hardware id (default).\n" " --flags \tReport header flags.\n" + " --digest \tReport digest of hwid (>= v1.2)\n" " -k, --rootkey=FILE \tFile name to export Root Key.\n" " -b, --bmpfv=FILE \tFile name to export Bitmap FV.\n" " -r --recoverykey=FILE\tFile name to export Recovery Key.\n" @@ -55,6 +56,10 @@ static void print_help(const char *prog) prog, prog, prog, prog); } +enum { + OPT_DIGEST = 1000, +}; + /* Command line options */ static const struct option long_opts[] = { /* name hasarg *flag val */ @@ -67,6 +72,7 @@ static const struct option long_opts[] = { {"recoverykey", 1, NULL, 'R'}, {"hwid", 2, NULL, 'i'}, {"flags", 2, NULL, 'L'}, + {"digest", 0, NULL, OPT_DIGEST}, {NULL, 0, NULL, 0}, }; @@ -340,6 +346,7 @@ static int do_gbb_utility(int argc, char *argv[]) char *opt_hwid = NULL; char *opt_flags = NULL; int sel_hwid = 0; + int sel_digest = 0; int sel_flags = 0; uint8_t *inbuf = NULL; off_t filesize; @@ -386,6 +393,9 @@ static int do_gbb_utility(int argc, char *argv[]) opt_flags = optarg; sel_flags = 1; break; + case OPT_DIGEST: + sel_digest = 1; + break; case '?': errorcnt++; if (optopt) @@ -437,7 +447,7 @@ static int do_gbb_utility(int argc, char *argv[]) /* With no args, show the HWID */ if (!opt_rootkey && !opt_bmpfv && !opt_recoverykey - && !sel_flags) + && !sel_flags && !sel_digest) sel_hwid = 1; inbuf = read_entire_file(infile, &filesize); @@ -457,6 +467,9 @@ static int do_gbb_utility(int argc, char *argv[]) gbb->hwid_size ? (char *)(gbb_base + gbb-> hwid_offset) : ""); + if (sel_digest) + print_hwid_digest(gbb, "digest: ", "\n"); + if (sel_flags) printf("flags: 0x%08x\n", gbb->flags); if (opt_rootkey) @@ -540,6 +553,7 @@ static int do_gbb_utility(int argc, char *argv[]) gbb->hwid_size); strcpy((char *)(gbb_base + gbb->hwid_offset), opt_hwid); + update_hwid_digest(gbb); } } diff --git a/futility/cmd_show.c b/futility/cmd_show.c index 2873f60b..f065b42c 100644 --- a/futility/cmd_show.c +++ b/futility/cmd_show.c @@ -141,8 +141,8 @@ int futil_cb_show_gbb(struct futil_traverse_state_s *state) } printf("GBB content:\n"); - printf(" HWID: %s\n", - (const char *)(buf + gbb->hwid_offset)); + printf(" HWID: %s\n", buf + gbb->hwid_offset); + print_hwid_digest(gbb, " digest: ", "\n"); pubkey = (VbPublicKey *)(buf + gbb->rootkey_offset); if (PublicKeyLooksOkay(pubkey, gbb->rootkey_size)) { diff --git a/futility/futility.c b/futility/futility.c index 19ee65b7..b4070618 100644 --- a/futility/futility.c +++ b/futility/futility.c @@ -129,7 +129,7 @@ static void log_args(int argc, char *argv[]) log_open(); /* delimiter */ - log_str(NULL, "##### HEY #####"); + log_str(NULL, "##### LOG #####"); /* Can we tell who called us? */ parent = getppid(); diff --git a/futility/futility.h b/futility/futility.h index 7892c5ad..52c007cc 100644 --- a/futility/futility.h +++ b/futility/futility.h @@ -71,6 +71,14 @@ int futil_looks_like_gbb(GoogleBinaryBlockHeader *gbb, uint32_t len); int futil_valid_gbb_header(GoogleBinaryBlockHeader *gbb, uint32_t len, uint32_t *maxlen); +/* For GBB v1.2 and later, update the hwid_digest */ +void update_hwid_digest(GoogleBinaryBlockHeader *gbb); + +/* For GBB v1.2 and later, print the stored digest of the HWID (and whether + * it's correct). Return true if it is correct. */ +int print_hwid_digest(GoogleBinaryBlockHeader *gbb, + const char *banner, const char *footer); + /* Copies a file or dies with an error message */ void futil_copy_file_or_die(const char *infile, const char *outfile); diff --git a/futility/misc.c b/futility/misc.c index 513fc8b6..42e8bb44 100644 --- a/futility/misc.c +++ b/futility/misc.c @@ -114,6 +114,57 @@ int futil_valid_gbb_header(GoogleBinaryBlockHeader *gbb, uint32_t len, return 1; } +/* For GBB v1.2 and later, print the stored digest of the HWID (and whether + * it's correct). Return true if it is correct. */ +int print_hwid_digest(GoogleBinaryBlockHeader *gbb, + const char *banner, const char *footer) +{ + printf("%s", banner); + + /* There isn't one for v1.1 and earlier, so assume it's good. */ + if (gbb->minor_version < 2) { + printf("%s", footer); + return 1; + } + + uint8_t *buf = (uint8_t *)gbb; + char *hwid_str = (char *)(buf + gbb->hwid_offset); + int is_valid = 0; + uint8_t* digest = DigestBuf(buf + gbb->hwid_offset, + strlen(hwid_str), + SHA256_DIGEST_ALGORITHM); + if (digest) { + int i; + is_valid = 1; + /* print it, comparing as we go */ + for (i = 0; i < SHA256_DIGEST_SIZE; i++) { + printf("%02x", gbb->hwid_digest[i]); + if (gbb->hwid_digest[i] != digest[i]) + is_valid = 0; + } + free(digest); + } + + printf(" %s", is_valid ? "valid" : ""); + printf("%s", footer); + return is_valid; +} + +/* For GBB v1.2 and later, update the hwid_digest field. */ +void update_hwid_digest(GoogleBinaryBlockHeader *gbb) +{ + /* There isn't one for v1.1 and earlier */ + if (gbb->minor_version < 2) + return; + + uint8_t *buf = (uint8_t *)gbb; + char *hwid_str = (char *)(buf + gbb->hwid_offset); + uint8_t* digest = DigestBuf(buf + gbb->hwid_offset, + strlen(hwid_str), + SHA256_DIGEST_ALGORITHM); + memcpy(gbb->hwid_digest, digest, SHA256_DIGEST_SIZE); + free(digest); +} /* * TODO: All sorts of race conditions likely here, and everywhere this is used. -- cgit v1.2.1