summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2017-05-26 17:16:51 -0700
committerBernie Thompson <bhthompson@chromium.org>2017-08-19 00:00:12 +0000
commit51aefff7c03c8648d6e5c6653fd9c170315db106 (patch)
treee378e15a094ab0bca6b595304f79ff3f0ffa0d52
parentdc5c85b5b23b416639d78b3dcdc11fc4e20d0883 (diff)
downloadchrome-ec-51aefff7c03c8648d6e5c6653fd9c170315db106.tar.gz
usb_updater: when communicating over tpm treat upgrades differentlyv1.9308_25_B.0
All extension and vendor commands' payloads need to be passed to the processing functions the same way, whether they arrive over /dev/tpm0 or over USB. The upgrade PDUs sent over USB need to include two additional fields which are stripped off by the reassembly layer on the Cr50. This patch makes sure that none of other than EXTENSION_FW_UPGRADE commands sent over /dev/tpm0 by usb_updater have the extra encapsulation. BRANCH=cr50 BUG=b:62106898 TEST=verified that updates work the same way over TPM and USB (which includes sending the 'turn_update_on' commands. Before this patch the turn_update_on command sent by usb_updater over TPM was not processed properly (the timeout value was wrong). Change-Id: I3f4ab7330037f6eb1ce8bac7c63faa5d7c309c94 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/517416 Reviewed-by: Andrey Pronin <apronin@chromium.org> (cherry picked from commit bd0f74a6f49cd3dcbed81738e376a8b05868b4f5) Reviewed-on: https://chromium-review.googlesource.com/538561 (cherry picked from commit 43ec46b4ee1e63526a787479d38d92545e5a7466) Reviewed-on: https://chromium-review.googlesource.com/622209 Reviewed-by: Bernie Thompson <bhthompson@chromium.org> Commit-Queue: Bernie Thompson <bhthompson@chromium.org> Tested-by: Bernie Thompson <bhthompson@chromium.org>
-rw-r--r--extra/usb_updater/usb_updater.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/extra/usb_updater/usb_updater.c b/extra/usb_updater/usb_updater.c
index 951b26507b..c39673535a 100644
--- a/extra/usb_updater/usb_updater.c
+++ b/extra/usb_updater/usb_updater.c
@@ -176,9 +176,20 @@ struct upgrade_pkt {
__be32 length;
__be32 ordinal;
__be16 subcmd;
- __be32 digest;
- __be32 address;
- char data[0];
+ union {
+ /*
+ * Upgrade PDUs as opposed to all other vendor and extension
+ * commands include two additional fields in the header.
+ */
+ struct {
+ __be32 digest;
+ __be32 address;
+ char data[0];
+ } upgrade;
+ struct {
+ char data[0];
+ } command;
+ };
} __packed;
#define MAX_BUF_SIZE (SIGNED_TRANSFER_SIZE + sizeof(struct upgrade_pkt))
@@ -241,26 +252,37 @@ static int tpm_send_pkt(int fd, unsigned int digest, unsigned int addr,
{
/* Used by transfer to /dev/tpm0 */
static uint8_t outbuf[MAX_BUF_SIZE];
-
struct upgrade_pkt *out = (struct upgrade_pkt *)outbuf;
/* Use the same structure, it will not be filled completely. */
int len, done;
- int response_offset = offsetof(struct upgrade_pkt, digest);
+ int response_offset = offsetof(struct upgrade_pkt, command.data);
+ void *payload;
+ size_t header_size;
debug("%s: sending to %#x %d bytes\n", __func__, addr, size);
- len = size + sizeof(struct upgrade_pkt);
-
out->tag = htobe16(0x8001);
- out->length = htobe32(len);
+ out->subcmd = htobe16(subcmd);
+
if (subcmd <= LAST_EXTENSION_COMMAND)
out->ordinal = htobe32(CONFIG_EXTENSION_COMMAND);
else
out->ordinal = htobe32(TPM_CC_VENDOR_BIT_MASK);
- out->subcmd = htobe16(subcmd);
- out->digest = digest;
- out->address = htobe32(addr);
- memcpy(out->data, data, size);
+
+ if (subcmd == EXTENSION_FW_UPGRADE) {
+ /* FW Upgrade PDU header includes a couple of extra fields. */
+ out->upgrade.digest = digest;
+ out->upgrade.address = htobe32(addr);
+ header_size = offsetof(struct upgrade_pkt, upgrade.data);
+ } else {
+ header_size = offsetof(struct upgrade_pkt, command.data);
+ }
+
+ payload = outbuf + header_size;
+ len = size + header_size;
+
+ out->length = htobe32(len);
+ memcpy(payload, data, size);
#ifdef DEBUG
{
int i;
@@ -1113,7 +1135,6 @@ static void generate_reset_request(struct transfer_descriptor *td)
fprintf(stderr, "Failed to request posted reboot\n");
exit(update_error);
}
-
}
printf("reboot %s\n", subcommand == EXTENSION_POST_RESET ?