diff options
author | Aaron Durbin <adurbin@chromium.org> | 2015-12-15 18:00:30 -0600 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2016-01-06 01:12:38 +0100 |
commit | 272a1f05b943d781acb8c04c01874bde9df3b774 (patch) | |
tree | b468be08bfa1745cb598a2db4ab5e5b3fb814f98 /util/cbfstool/cbfstool.c | |
parent | 29a04d9ed16a854f3b3a8f98476c91230ce2ba2e (diff) |
cbfstool: Add 'hashcbfs' command to compute hash of CBFS region.
For the purposes of maintaining integrity of a CBFS allow one to
hash a CBFS over a given region. The hash consists of all file
metadata and non-empty file data. The resulting digest is saved
to the requested destination region.
BUG=chrome-os-partner:48412
BUG=chromium:445938
BRANCH=None
TEST=Integrated with glados chrome os build. vboot verification
works using the same code to generate the hash in the tooling
as well as at runtime on the board in question.
Change-Id: Ib0d6bf668ffd6618f5f73e1217bdef404074dbfc
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/12790
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'util/cbfstool/cbfstool.c')
-rw-r--r-- | util/cbfstool/cbfstool.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index f00aa30183..95199536f8 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -781,6 +781,59 @@ static int cbfs_print(void) return 0; } +/* Forward declared so there aren't type collisions with cbfstool proper + * and commonlib. */ +int cbfs_calculate_hash(void *cbfs, size_t cbfs_sz, + enum vb2_hash_algorithm hash_algo, + void *digest, size_t digest_sz); + +static int cbfs_hash(void) +{ + struct cbfs_image src_image; + struct buffer src_buf; + struct buffer *dst = param.image_region; + + if (param.hash == VB2_HASH_INVALID) { + ERROR("You need to specify -A/--hash-algorithm.\n"); + return 1; + } + + if (!param.source_region) { + ERROR("You need to specify -R/--source-region.\n"); + return 1; + } + + unsigned hash_size = widths_cbfs_hash[param.hash]; + if (hash_size == 0) + return 1; + + if (buffer_size(param.image_region) != hash_size) { + ERROR("Region '%s' size (%zd) not equal to hash size (%d).\n", + param.region_name, buffer_size(param.image_region), + hash_size); + return 1; + } + + /* Obtain the source region and convert it to a cbfs_image. */ + if (!partitioned_file_read_region(&src_buf, param.image_file, + param.source_region)) { + ERROR("Region not found in image: %s\n", param.source_region); + return 1; + } + + if (cbfs_image_from_buffer(&src_image, &src_buf, param.headeroffset)) + return 1; + + if (cbfs_calculate_hash(buffer_get(&src_image.buffer), + buffer_size(&src_image.buffer), + param.hash, buffer_get(dst), hash_size)) { + ERROR("Hash calculation failed.\n"); + return 1; + } + + return 0; +} + static int cbfs_extract(void) { if (!param.filename) { @@ -947,6 +1000,7 @@ static const struct command commands[] = { {"add-master-header", "H:r:vh?", cbfs_add_master_header, true, true}, {"copy", "r:R:h?", cbfs_copy, true, true}, {"create", "M:r:s:B:b:H:o:m:vh?", cbfs_create, true, true}, + {"hashcbfs", "r:R:A:vh?", cbfs_hash, true, true}, {"extract", "H:r:m:n:f:vh?", cbfs_extract, true, false}, {"layout", "wvh?", cbfs_layout, false, false}, {"print", "H:r:vh?", cbfs_print, true, false}, @@ -1090,6 +1144,8 @@ static void usage(char *name) " print [-r image,regions] " "Show the contents of the ROM\n" " extract [-r image,regions] [-m ARCH] -n NAME -f FILE " + " hashcbfs -r image_region -R source-region " + "Hashes CBFS source-region and saves digest\n" "Extracts a raw payload from ROM\n" " write -r image,regions -f file [-u | -d] " "Write file into same-size [or larger] raw region\n" |