summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-09-12 13:48:07 -0700
committerGerrit <chrome-bot@google.com>2012-09-12 15:42:25 -0700
commit88ff608ae261ceca193e7d5689dc67b1536ce3eb (patch)
tree11245c8dcbaf87f526e071a44ba50e2122412293
parent0ac4bc36537ce3ee98a3ce3068a79919cd9804d3 (diff)
downloadchrome-ec-88ff608ae261ceca193e7d5689dc67b1536ce3eb.tar.gz
Add capability to auto-hash correct size for EC-RO or EC-RW
Otherwise the host needs to tell the EC how big this image is (which it knows, but it's inconvenient for it to provide). BUG=chrome-os-partner:13511 BRANCH=all TEST=manual 1. ectool echash recalc ro -> prints hash of RO code (offset 0) 2. ectool echash recalc rw -> prints hash of RW code (offset non-zero) In each case, size should be an exact number and not the size of the whole RO or RW section. So for link, output should be something similar to: localhost ~ # ectool echash recalc ro Hashing EC-RO... status: done type: SHA-256 offset: 0x00000000 size: 0x00012a64 hash: 03a66c076d6dd4b4aa9ed6386713f45291f5143f9af2093003e632485899daf1 localhost ~ # ectool echash recalc rw Hashing EC-RW... status: done type: SHA-256 offset: 0x00014000 size: 0x000123d1 hash: 0d6225e70f0b1e0419e987370371e00783f945827ef25915a8fb8549159dd2a4 Signed-off-by: Randall Spangler <rspangler@chromium.org> 3. At ec console, 'hash ro' or 'hash rw' should regenerate the same hash values printed above. Change-Id: I3f6085d29927b8cdf9dabc6930f0fdc7222bd8b5 Reviewed-on: https://gerrit.chromium.org/gerrit/33123 Tested-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Simon Glass <sjg@chromium.org> Commit-Ready: Randall Spangler <rspangler@chromium.org>
-rw-r--r--common/vboot_hash.c85
-rw-r--r--include/ec_commands.h24
-rw-r--r--util/ectool.c42
3 files changed, 102 insertions, 49 deletions
diff --git a/common/vboot_hash.c b/common/vboot_hash.c
index 535f7f81c0..c80c174588 100644
--- a/common/vboot_hash.c
+++ b/common/vboot_hash.c
@@ -193,9 +193,21 @@ static int command_hash(int argc, char **argv)
return EC_SUCCESS;
}
- if (argc == 2 && !strcasecmp(argv[1], "abort")) {
- vboot_hash_abort();
- return EC_SUCCESS;
+ if (argc == 2) {
+ if (!strcasecmp(argv[1], "abort")) {
+ vboot_hash_abort();
+ return EC_SUCCESS;
+ } else if (!strcasecmp(argv[1], "rw")) {
+ return vboot_hash_start(
+ CONFIG_FW_RW_OFF,
+ system_get_image_used(SYSTEM_IMAGE_RW),
+ NULL, 0);
+ } else if (!strcasecmp(argv[1], "ro")) {
+ return vboot_hash_start(
+ CONFIG_FW_RO_OFF,
+ system_get_image_used(SYSTEM_IMAGE_RO),
+ NULL, 0);
+ }
}
if (argc >= 3) {
@@ -220,7 +232,7 @@ static int command_hash(int argc, char **argv)
return vboot_hash_start(offset, size, NULL, 0);
}
DECLARE_CONSOLE_COMMAND(hash, command_hash,
- "[abort] | [<offset> <size> [<nonce>]]",
+ "[abort | ro | rw] | [<offset> <size> [<nonce>]]",
"Request hash recomputation",
NULL);
@@ -245,6 +257,42 @@ static void fill_response(struct ec_response_vboot_hash *r)
r->status = EC_VBOOT_HASH_STATUS_NONE;
}
+/**
+ * Start computing a hash, with sanity checking on params.
+ *
+ * @return EC_RES_SUCCESS if success, or other result code on error.
+ */
+static int host_start_hash(const struct ec_params_vboot_hash *p)
+{
+ int offset = p->offset;
+ int size = p->size;
+ int rv;
+
+ /* Sanity-check input params */
+ if (p->hash_type != EC_VBOOT_HASH_TYPE_SHA256)
+ return EC_RES_INVALID_PARAM;
+ if (p->nonce_size > sizeof(p->nonce_data))
+ return EC_RES_INVALID_PARAM;
+
+ /* Handle special offset values */
+ if (offset == EC_VBOOT_HASH_OFFSET_RO) {
+ offset = CONFIG_FW_RO_OFF;
+ size = system_get_image_used(SYSTEM_IMAGE_RO);
+ } else if (p->offset == EC_VBOOT_HASH_OFFSET_RW) {
+ offset = CONFIG_FW_RW_OFF;
+ size = system_get_image_used(SYSTEM_IMAGE_RW);
+ }
+
+ rv = vboot_hash_start(offset, size, p->nonce_data, p->nonce_size);
+
+ if (rv == EC_SUCCESS)
+ return EC_RES_SUCCESS;
+ else if (rv == EC_ERROR_INVAL)
+ return EC_RES_INVALID_PARAM;
+ else
+ return EC_RES_ERROR;
+}
+
static int host_command_vboot_hash(struct host_cmd_handler_args *args)
{
const struct ec_params_vboot_hash *p = args->params;
@@ -262,33 +310,12 @@ static int host_command_vboot_hash(struct host_cmd_handler_args *args)
return EC_RES_SUCCESS;
case EC_VBOOT_HASH_START:
- if (p->hash_type != EC_VBOOT_HASH_TYPE_SHA256)
- return EC_RES_INVALID_PARAM;
- if (p->nonce_size > sizeof(p->nonce_data))
- return EC_RES_INVALID_PARAM;
-
- rv = vboot_hash_start(p->offset, p->size, p->nonce_data,
- p->nonce_size);
-
- if (rv == EC_SUCCESS)
- return EC_RES_SUCCESS;
- else if (rv == EC_ERROR_INVAL)
- return EC_RES_INVALID_PARAM;
- else
- return EC_RES_ERROR;
+ return host_start_hash(p);
case EC_VBOOT_HASH_RECALC:
- if (p->hash_type != EC_VBOOT_HASH_TYPE_SHA256)
- return EC_RES_INVALID_PARAM;
- if (p->nonce_size > sizeof(p->nonce_data))
- return EC_RES_INVALID_PARAM;
-
- rv = vboot_hash_start(p->offset, p->size, p->nonce_data,
- p->nonce_size);
- if (rv == EC_ERROR_INVAL)
- return EC_RES_INVALID_PARAM;
- else if (rv != EC_SUCCESS)
- return EC_RES_ERROR;
+ rv = host_start_hash(p);
+ if (rv != EC_RES_SUCCESS)
+ return rv;
/* Wait for hash to finish */
while (in_progress)
diff --git a/include/ec_commands.h b/include/ec_commands.h
index 4e3bd7082f..296b0d7ea9 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -712,22 +712,30 @@ struct ec_response_vboot_hash {
} __packed;
enum ec_vboot_hash_cmd {
- EC_VBOOT_HASH_GET, /* Get current hash status */
- EC_VBOOT_HASH_ABORT, /* Abort calculating current hash */
- EC_VBOOT_HASH_START, /* Start computing a new hash */
- EC_VBOOT_HASH_RECALC, /* Synchronously compute a new hash */
+ EC_VBOOT_HASH_GET = 0, /* Get current hash status */
+ EC_VBOOT_HASH_ABORT = 1, /* Abort calculating current hash */
+ EC_VBOOT_HASH_START = 2, /* Start computing a new hash */
+ EC_VBOOT_HASH_RECALC = 3, /* Synchronously compute a new hash */
};
enum ec_vboot_hash_type {
- EC_VBOOT_HASH_TYPE_SHA256, /* SHA-256 */
+ EC_VBOOT_HASH_TYPE_SHA256 = 0, /* SHA-256 */
};
enum ec_vboot_hash_status {
- EC_VBOOT_HASH_STATUS_NONE, /* No hash (not started, or aborted) */
- EC_VBOOT_HASH_STATUS_DONE, /* Finished computing a hash */
- EC_VBOOT_HASH_STATUS_BUSY, /* Busy computing a hash */
+ EC_VBOOT_HASH_STATUS_NONE = 0, /* No hash (not started, or aborted) */
+ EC_VBOOT_HASH_STATUS_DONE = 1, /* Finished computing a hash */
+ EC_VBOOT_HASH_STATUS_BUSY = 2, /* Busy computing a hash */
};
+/*
+ * Special values for offset for EC_VBOOT_HASH_START and EC_VBOOT_HASH_RECALC.
+ * If one of these is specified, the EC will automatically update offset and
+ * size to the correct values for the specified image (RO or RW).
+ */
+#define EC_VBOOT_HASH_OFFSET_RO 0xfffffffe
+#define EC_VBOOT_HASH_OFFSET_RW 0xfffffffd
+
/*****************************************************************************/
/* USB charging control commands */
diff --git a/util/ectool.c b/util/ectool.c
index 90b0d558ee..4fbc6ce781 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -1990,6 +1990,10 @@ static int ec_hash_help(const char *cmd)
printf(" %s abort - abort hashing\n", cmd);
printf(" %s start [<offset> <size> [<nonce>]] - start hashing\n", cmd);
printf(" %s recalc [<offset> <size> [<nonce>]] - sync rehash\n", cmd);
+ printf("\n"
+ "If <offset> is RO or RW, offset and size are computed\n"
+ "automatically for the EC-RO or EC-RW firmware image.\n");
+
return 0;
}
@@ -2060,21 +2064,36 @@ int cmd_ec_hash(int argc, char *argv[])
else
return ec_hash_help(argv[0]);
- if (argc < 4) {
- fprintf(stderr, "Must specify offset and size\n");
- return -1;
- }
-
p.hash_type = EC_VBOOT_HASH_TYPE_SHA256;
- p.offset = strtol(argv[2], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad offset.\n");
+
+ if (argc < 3) {
+ fprintf(stderr, "Must specify offset\n");
return -1;
}
- p.size = strtol(argv[3], &e, 0);
- if (e && *e) {
- fprintf(stderr, "Bad size.\n");
+
+ if (!strcasecmp(argv[2], "ro")) {
+ p.offset = EC_VBOOT_HASH_OFFSET_RO;
+ p.size = 0;
+ printf("Hashing EC-RO...\n");
+ } else if (!strcasecmp(argv[2], "rw")) {
+ p.offset = EC_VBOOT_HASH_OFFSET_RW;
+ p.size = 0;
+ printf("Hashing EC-RW...\n");
+ } else if (argc < 4) {
+ fprintf(stderr, "Must specify size\n");
return -1;
+ } else {
+ p.offset = strtol(argv[2], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad offset.\n");
+ return -1;
+ }
+ p.size = strtol(argv[3], &e, 0);
+ if (e && *e) {
+ fprintf(stderr, "Bad size.\n");
+ return -1;
+ }
+ printf("Hashing %d bytes at offset %d...\n", p.size, p.offset);
}
if (argc == 5) {
@@ -2092,7 +2111,6 @@ int cmd_ec_hash(int argc, char *argv[])
} else
p.nonce_size = 0;
- printf("Hashing %d bytes at offset %d...\n", p.size, p.offset);
rv = ec_command(EC_CMD_VBOOT_HASH, 0, &p, sizeof(p), &r, sizeof(r));
if (rv < 0)
return rv;