summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2018-03-06 11:31:08 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-03-15 17:58:20 -0700
commitccbba8f968ac4bf77c7c8ed665ab96a587f65ff8 (patch)
tree8c38402a6d04e384aa570fd239c7139567e18989
parent9e95ac3e0aeeaa12aaca75bdb73a055ab969e310 (diff)
downloadchrome-ec-ccbba8f968ac4bf77c7c8ed665ab96a587f65ff8.tar.gz
gsctool: require exactly two hash sections for every board
The same Chrome OS device could have not only several released firmware images, but also several variations of the GBB contents. Any permutation of these two sets is possible, but both areas must match, as modified GBB is no smaller problem than modified code or RO data. With this patch the verifier will continue looking for board sections in the descriptors database until the entire database has been scanned. Only finding exactly two sections, and each section providing proper matches will qualify the check as 'pass'. BRANCH=none BUG=b:73668125 TEST=verified that both single and dual section descriptions are processed properly, and that matching 1 and 3 sections triggers a return error. Change-Id: I181655192246ce245c43e6ce7ba4768ac5c9e51a Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/951864 Reviewed-by: Andrey Pronin <apronin@chromium.org>
-rw-r--r--extra/usb_updater/desc_parser.c32
-rw-r--r--extra/usb_updater/verify_ro.c72
2 files changed, 62 insertions, 42 deletions
diff --git a/extra/usb_updater/desc_parser.c b/extra/usb_updater/desc_parser.c
index 6570c5f23e..5bd996bdda 100644
--- a/extra/usb_updater/desc_parser.c
+++ b/extra/usb_updater/desc_parser.c
@@ -18,6 +18,12 @@ static FILE *hash_file_;
static int line_count_;
static int section_count_;
+/*
+ * This is used to verify consistency of the description database, namely that
+ * all hash sections include the same number of hash variants.
+ */
+static size_t variant_count;
+
/* Size of the retrieved string or negative OS error value. */
static ssize_t get_next_line(char *next_line, size_t line_size)
{
@@ -239,13 +245,6 @@ int parser_get_next_range(struct addr_range **range)
int rv;
/*
- * This is used to verify consistency of the description database,
- * namely that all hash sections include the same numger of hash
- * variants.
- */
- static size_t variant_count;
-
- /*
* We come here after hash descriptor database file was opened and the
* current board's section has been found. Just in case check if the
* file has been opened.
@@ -308,11 +307,13 @@ int parser_find_board(const char *hash_file_name, const char *board_id)
char next_line[1000]; /* Should be enough for the largest descriptor. */
ssize_t id_len = strlen(board_id);
- hash_file_ = fopen(hash_file_name, "r");
if (!hash_file_) {
- fprintf(stderr, "Error:%s can not open file '%s'\n",
- strerror(errno), hash_file_name);
- return errno;
+ hash_file_ = fopen(hash_file_name, "r");
+ if (!hash_file_) {
+ fprintf(stderr, "Error:%s can not open file '%s'\n",
+ strerror(errno), hash_file_name);
+ return errno;
+ }
}
while (1) {
@@ -320,18 +321,17 @@ int parser_find_board(const char *hash_file_name, const char *board_id)
entry_size = get_next_line(next_line, sizeof(next_line));
if (entry_size < 0) {
- fclose(hash_file_);
return entry_size;
}
if ((entry_size == id_len) &&
- !memcmp(next_line, board_id, id_len))
+ !memcmp(next_line, board_id, id_len)) {
+ variant_count = 0;
return 0;
+ }
}
- fclose(hash_file_);
- hash_file_ = NULL;
- return errno;
+ return -ENODATA;
}
void parser_done(void)
diff --git a/extra/usb_updater/verify_ro.c b/extra/usb_updater/verify_ro.c
index 6f6de59867..f81fab8e67 100644
--- a/extra/usb_updater/verify_ro.c
+++ b/extra/usb_updater/verify_ro.c
@@ -15,6 +15,8 @@
#include "tpm_vendor_cmds.h"
#include "verify_ro.h"
+/* Index of the matching hash variant. */
+static ssize_t matching_variant;
/*
* Print out passed in buffer contents in hex, 16 bytes per line, each line
@@ -114,13 +116,12 @@ static int set_new_range(struct transfer_descriptor *td,
* pointer structure req has the range offset and size already initialized.
*
* Make sure that matching hashes are at the same index in the hash variants
- * array in all hash sections.
+ * arrays within the same board section.
*/
static int verify_hash_section(struct transfer_descriptor *td,
struct vendor_cc_spi_hash_request *req,
struct addr_range *range)
{
- static ssize_t matching_range = -1;
size_t i;
uint8_t response[sizeof(range->variants->expected_result)];
size_t response_size;
@@ -145,14 +146,14 @@ static int verify_hash_section(struct transfer_descriptor *td,
return -EINVAL;
}
- if (matching_range < 0) {
+ if (matching_variant < 0) {
/* This is the first hash range to be processed. */
struct result_node *variant = range->variants;
for (i = 0; i < range->variant_count; i++) {
if (!memcmp(variant->expected_result,
response, response_size)) {
- matching_range = i;
+ matching_variant = i;
return 0;
}
variant++;
@@ -163,7 +164,7 @@ static int verify_hash_section(struct transfer_descriptor *td,
return -EINVAL;
}
- if (!memcmp(range->variants[matching_range].expected_result,
+ if (!memcmp(range->variants[matching_variant].expected_result,
response, response_size))
return 0;
@@ -286,21 +287,7 @@ static int process_descriptor_sections(struct transfer_descriptor *td)
if (range)
free(range);
- parser_done();
-
- if (rv)
- return rv;
-
- memset(&req, 0, sizeof(req));
- req.subcmd = SPI_HASH_SUBCMD_DISABLE;
- rv = send_vendor_command(td, VENDOR_CC_SPI_HASH, &req,
- sizeof(req), 0, NULL);
- if (rv) {
- fprintf(stderr,
- "%s: spi hash disable TPM error %d\n", __func__, rv);
- return -EINVAL;
- }
- return 0;
+ return rv;
}
int verify_ro(struct transfer_descriptor *td,
@@ -309,6 +296,8 @@ int verify_ro(struct transfer_descriptor *td,
/* First find out board ID of the target. */
struct board_id bid;
char rlz_code[sizeof(bid.type) + 1];
+ int section_count = 0;
+ int rv = 0;
/*
* Find out what Board ID is the device we are talking to. This
@@ -329,12 +318,43 @@ int verify_ro(struct transfer_descriptor *td,
memcpy(rlz_code, &bid.type, sizeof(rlz_code) - 1);
rlz_code[sizeof(rlz_code) - 1] = '\0';
- if (!parser_find_board(desc_file_name, rlz_code)) {
- /* Opened the file and found descriptors for DUT. */
- printf("Processing sections for board ID %s\n", rlz_code);
- return process_descriptor_sections(td);
+ while (!parser_find_board(desc_file_name, rlz_code)) {
+
+ /*
+ * Each board section might have different index of the
+ * matching hash variant.
+ */
+ matching_variant = -1;
+
+ section_count++;
+ rv = process_descriptor_sections(td);
+ if (rv)
+ break;
+ }
+
+ if (section_count != 2) {
+ printf("Found wrong number of sections (%d) for board ID %s\n",
+ section_count, rlz_code);
+ rv = -EINVAL;
+ } else if (!rv) {
+ /*
+ * Check was successful, send command to exit verification
+ * mode.
+ */
+ struct vendor_cc_spi_hash_request req;
+
+ memset(&req, 0, sizeof(req));
+ req.subcmd = SPI_HASH_SUBCMD_DISABLE;
+ rv = send_vendor_command(td, VENDOR_CC_SPI_HASH, &req,
+ sizeof(req), 0, NULL);
+ if (rv) {
+ fprintf(stderr,
+ "%s: spi hash disable TPM error %d\n",
+ __func__, rv);
+ rv = -EINVAL;
+ }
}
- printf("No description for board ID %s found\n", rlz_code);
- return -1;
+ parser_done();
+ return rv;
}