diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2018-07-10 15:39:12 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-07-31 12:07:37 -0700 |
commit | d6f54b711f64b42f9c4e53f5071a65bef9750f89 (patch) | |
tree | e910934a04d92f13a7c994e624f8b8ea9256de9d /util | |
parent | 143f2808ec04f3fb66b7d5821ec554f41993a7a8 (diff) | |
download | chrome-ec-d6f54b711f64b42f9c4e53f5071a65bef9750f89.tar.gz |
rollback: Add host command to add entropy
To generate a new secret, we add entropy (generated from local
HW TRNG) to the existing secret (sha256(old secret || entropy)).
This essentially re-keys the EC.
On STM32H7, erasing rollback flash block can take up to 4 seconds,
which exceeds the timeout of a normal host command. Therefore,
ADD_ENTROPY command is asynchronous (adding the entropy itself
is performed in a deferred hook), and its status must be checked
repeatedly by the host.
In some cases, it is critical that the old key is not left in
the backup rollback block(s). For this purpose, we add a special
action ADD_ENTROPY_RESET_ASYNC that adds entropy multiple times,
until all the rollback blocks have been overwritten.
BRANCH=none
BUG=b:111190988
TEST=EC> rollbackinfo
DUT> ./ectool --name=cros_fp reboot_ec RO && \
sleep 0.3 && ./ectool --name=cros_fp addentropy
EC> rollbackinfo
=> See that that a single rollback block has been overridden
TEST=Repeat with ./ectool --name=cros_fp addentropy reset
=> See that both rollback blocks have been overridden
Change-Id: I3058b0a91591fab543ba6890f7356e671016edfa
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1132826
Reviewed-by: Nicolas Norvez <norvez@chromium.org>
Diffstat (limited to 'util')
-rw-r--r-- | util/ectool.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/util/ectool.c b/util/ectool.c index cf28ccca08..130c8744b1 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -54,6 +54,8 @@ static struct option long_opts[] = { const char help_str[] = "Commands:\n" + " addentropy [reset]\n" + " Add entropy to device secret\n" " autofanctrl <on>\n" " Turn on automatic fan speed control.\n" " backlight <enabled>\n" @@ -380,6 +382,44 @@ static int read_mapped_string(uint8_t offset, char *buffer, int max_size) return ret; } +int cmd_add_entropy(int argc, char *argv[]) +{ + struct ec_params_rollback_add_entropy p; + int rv; + int tries = 100; /* Wait for 10 seconds at most */ + + if (argc >= 2 && !strcmp(argv[1], "reset")) + p.action = ADD_ENTROPY_RESET_ASYNC; + else + p.action = ADD_ENTROPY_ASYNC; + + rv = ec_command(EC_CMD_ADD_ENTROPY, 0, &p, sizeof(p), NULL, 0); + + if (rv != EC_RES_SUCCESS) + goto out; + + while (tries--) { + usleep(100000); + + p.action = ADD_ENTROPY_GET_RESULT; + rv = ec_command(EC_CMD_ADD_ENTROPY, 0, &p, sizeof(p), NULL, 0); + + if (rv == EC_RES_SUCCESS) { + printf("Entropy added successfully\n"); + return EC_RES_SUCCESS; + } + + /* Abort if EC returns an error other than EC_RES_BUSY. */ + if (rv <= -EECRESULT && rv != -EECRESULT-EC_RES_BUSY) + goto out; + } + + rv = -EECRESULT-EC_RES_TIMEOUT; +out: + fprintf(stderr, "Failed to add entropy: %d\n", rv); + return rv; +} + int cmd_hello(int argc, char *argv[]) { struct ec_params_hello p; @@ -8134,6 +8174,7 @@ int cmd_cec(int argc, char *argv[]) /* NULL-terminated list of commands */ const struct command commands[] = { + {"addentropy", cmd_add_entropy}, {"autofanctrl", cmd_thermal_auto_fan_ctrl}, {"backlight", cmd_lcd_backlight}, {"battery", cmd_battery}, |