From afcfb4b99844ea79db732dfcad222c32550477ed Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 6 Oct 2016 10:35:56 -0700 Subject: 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 Reviewed-on: https://chromium-review.googlesource.com/394732 Reviewed-by: Vadim Bendebury --- extra/usb_updater/usb_updater.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'extra') 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; } -- cgit v1.2.1