diff options
author | Bill Richardson <wfrichar@chromium.org> | 2016-10-06 10:35:56 -0700 |
---|---|---|
committer | Hung-Te Lin <hungte@chromium.org> | 2016-11-24 04:56:25 +0000 |
commit | d2f664c54c42f7e457abc0bf0548beb59481ac79 (patch) | |
tree | 05ccc095ca20955fc7ea56db25970842b206c927 | |
parent | 1c60f34089033563164e5dac5d0bba2e6b50c7f7 (diff) | |
download | chrome-ec-d2f664c54c42f7e457abc0bf0548beb59481ac79.tar.gz |
g: Upgrade protocol returns the keyid for RO/RW
The keyid field of struct SignedHeader is what distinguishes prod
keys from dev keys. This may be useful someday, so let's have the
update protocol return those values for the active RO and RW
images.
Bump the UPGRADE_PROTOCOL_VERSION accordingly.
Note: This doesn't enforce any keyid matches, it just returns the
current values as part of the initial upgrade handshake in case
we want to know.
BUG=chrome-os-partner:57956
BRANCH=none
TEST=make buildall; try on Gru
Make sure that Cr50 can be freely updated and downgraded between
firmwares that speak either v4 or v5 of the protocol, by using
the v5-aware usb_updater tool.
And of course, make sure that v5 images report their keyids. Duh.
Change-Id: If2cc0d4023dca2078b9398fd899618dc2cd409b9
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/394732
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
(cherry picked from commit afcfb4b99844ea79db732dfcad222c32550477ed)
Reviewed-on: https://chromium-review.googlesource.com/414726
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Commit-Queue: Hung-Te Lin <hungte@chromium.org>
Tested-by: Hung-Te Lin <hungte@chromium.org>
Trybot-Ready: Hung-Te Lin <hungte@chromium.org>
-rw-r--r-- | chip/g/upgrade_fw.c | 4 | ||||
-rw-r--r-- | chip/g/upgrade_fw.h | 8 | ||||
-rw-r--r-- | extra/usb_updater/usb_updater.c | 34 |
3 files changed, 33 insertions, 13 deletions
diff --git a/chip/g/upgrade_fw.c b/chip/g/upgrade_fw.c index a1c52cb56a..c01bdadc8c 100644 --- a/chip/g/upgrade_fw.c +++ b/chip/g/upgrade_fw.c @@ -210,6 +210,8 @@ void fw_upgrade_command_handler(void *body, rpdu->shv[0].minor = htobe32(header->minor_); rpdu->shv[0].major = htobe32(header->major_); rpdu->shv[0].epoch = htobe32(header->epoch_); + /* New with protocol version 5 */ + rpdu->keyid[0] = htobe32(header->keyid); /* RW header information. */ header = (const struct SignedHeader *) @@ -217,6 +219,8 @@ void fw_upgrade_command_handler(void *body, rpdu->shv[1].minor = htobe32(header->minor_); rpdu->shv[1].major = htobe32(header->major_); rpdu->shv[1].epoch = htobe32(header->epoch_); + /* New with protocol version 5 */ + rpdu->keyid[1] = htobe32(header->keyid); return; } diff --git a/chip/g/upgrade_fw.h b/chip/g/upgrade_fw.h index 239384668f..7d0fc3324b 100644 --- a/chip/g/upgrade_fw.h +++ b/chip/g/upgrade_fw.h @@ -32,7 +32,7 @@ * first_response_pdu structure below. */ -#define UPGRADE_PROTOCOL_VERSION 4 +#define UPGRADE_PROTOCOL_VERSION 5 /* This is the format of the update frame header. */ struct upgrade_command { @@ -83,7 +83,7 @@ struct signed_header_version { * It became clear that there is a need to be able to enhance the upgrade * protocol, while stayng backwards compatible. * - * All newer protocol versions (satring with version 2) respond to the very + * All newer protocol versions (starting with version 2) respond to the very * first packet with an 8 byte or larger response, where the first 4 bytes are * a version specific data, and the second 4 bytes - the protocol version * number. @@ -106,6 +106,10 @@ struct first_response_pdu { /* The below fields are present in versions 4 and up. */ /* Versions of the currently active RO and RW sections. */ struct signed_header_version shv[2]; + + /* The below fields are present in versions 5 and up */ + /* keyids of the currently active RO and RW sections. */ + uint32_t keyid[2]; }; /* TODO: Handle this in upgrade_fw.c, not usb_upgrade.c */ diff --git a/extra/usb_updater/usb_updater.c b/extra/usb_updater/usb_updater.c index b12451bcdc..8b8df2ba4c 100644 --- a/extra/usb_updater/usb_updater.c +++ b/extra/usb_updater/usb_updater.c @@ -684,11 +684,8 @@ static void transfer_section(struct transfer_descriptor *td, } } -/* - * Header versions retrieved from the target, RO at index 0 and RW at index - * 1. - */ -static struct signed_header_version target_shv[2]; +/* Information about the target */ +static struct first_response_pdu targ; /* * Each RO or RW section of the new image can be in one of the following @@ -713,6 +710,7 @@ static struct { uint32_t size; enum upgrade_status ustatus; struct signed_header_version shv; + uint32_t keyid; } sections[] = { {"RO_A", CONFIG_RO_MEM_OFF, CONFIG_RO_SIZE}, {"RW_A", CONFIG_RW_MEM_OFF, CONFIG_RW_SIZE}, @@ -736,6 +734,7 @@ static void fetch_header_versions(const void *image) sections[i].shv.epoch = h->epoch_; sections[i].shv.major = h->major_; sections[i].shv.minor = h->minor_; + sections[i].keyid = h->keyid; } } @@ -806,7 +805,7 @@ static void pick_sections(struct transfer_descriptor *td) * different. */ - if (a_newer_than_b(§ions[i].shv, target_shv + 1) || + if (a_newer_than_b(§ions[i].shv, &targ.shv[1]) || !td->upstart_mode) sections[i].ustatus = needed; continue; @@ -830,7 +829,7 @@ static void pick_sections(struct transfer_descriptor *td) * Is it newer in the new image than the running RO section on * the device? */ - if (a_newer_than_b(§ions[i].shv, target_shv)) + if (a_newer_than_b(§ions[i].shv, &targ.shv[0])) sections[i].ustatus = needed; } } @@ -868,6 +867,8 @@ static void setup_connection(struct transfer_descriptor *td) } } + /* We got something. Check for errors in response */ + if (rxed_size <= 4) { if (td->ep_type != spi_xfer) { fprintf(stderr, "Unexpected response size %zd\n", @@ -899,19 +900,27 @@ static void setup_connection(struct transfer_descriptor *td) /* All newer protocols. */ td->rw_offset = be32toh (start_resp.rpdu.backup_rw_offset); + if (protocol_version > 3) { size_t i; /* Running header versions are available. */ - for (i = 0; i < ARRAY_SIZE(target_shv); i++) { - target_shv[i].minor = be32toh + for (i = 0; i < ARRAY_SIZE(targ.shv); i++) { + targ.shv[i].minor = be32toh (start_resp.rpdu.shv[i].minor); - target_shv[i].major = be32toh + targ.shv[i].major = be32toh (start_resp.rpdu.shv[i].major); - target_shv[i].epoch = be32toh + targ.shv[i].epoch = be32toh (start_resp.rpdu.shv[i].epoch); } } + if (protocol_version > 4) { + size_t i; + + for (i = 0; i < ARRAY_SIZE(targ.keyid); i++) + targ.keyid[i] = be32toh + (start_resp.rpdu.keyid[i]); + } } } @@ -924,6 +933,9 @@ static void setup_connection(struct transfer_descriptor *td) printf("Offsets: backup RO at %#x, backup RW at %#x\n", td->ro_offset, td->rw_offset); } + if (protocol_version > 4) + printf("Keyids: RO 0x%08x, RW 0x%08x\n", + targ.keyid[0], targ.keyid[1]); pick_sections(td); return; } |