summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2016-10-06 10:35:56 -0700
committerHung-Te Lin <hungte@chromium.org>2016-11-24 04:56:25 +0000
commitd2f664c54c42f7e457abc0bf0548beb59481ac79 (patch)
tree05ccc095ca20955fc7ea56db25970842b206c927
parent1c60f34089033563164e5dac5d0bba2e6b50c7f7 (diff)
downloadchrome-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.c4
-rw-r--r--chip/g/upgrade_fw.h8
-rw-r--r--extra/usb_updater/usb_updater.c34
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(&sections[i].shv, target_shv + 1) ||
+ if (a_newer_than_b(&sections[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(&sections[i].shv, target_shv))
+ if (a_newer_than_b(&sections[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;
}