summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ec_commands.h25
-rw-r--r--util/ectool.c41
2 files changed, 66 insertions, 0 deletions
diff --git a/include/ec_commands.h b/include/ec_commands.h
index e56ffad9c1..2411bbfbd3 100644
--- a/include/ec_commands.h
+++ b/include/ec_commands.h
@@ -4780,6 +4780,31 @@ struct __ec_align1 ec_params_set_cbi {
uint8_t data[]; /* For string and raw data */
};
+/*
+ * Add entropy to the device secret (stored in the rollback region).
+ *
+ * Depending on the chip, the operation may take a long time (e.g. to erase
+ * flash), so the commands are asynchronous.
+ */
+#define EC_CMD_ADD_ENTROPY 0x0122
+
+enum add_entropy_action {
+ /* Add entropy to the current secret. */
+ ADD_ENTROPY_ASYNC = 0,
+ /*
+ * Add entropy, and also make sure that the previous secret is erased.
+ * (this can be implemented by adding entropy multiple times until
+ * all rolback blocks have been overwritten).
+ */
+ ADD_ENTROPY_RESET_ASYNC = 1,
+ /* Read back result from the previous operation. */
+ ADD_ENTROPY_GET_RESULT = 2,
+};
+
+struct __ec_align1 ec_params_rollback_add_entropy {
+ uint8_t action;
+};
+
/*****************************************************************************/
/* The command range 0x200-0x2FF is reserved for Rotor. */
diff --git a/util/ectool.c b/util/ectool.c
index 19d5745b1f..1935bc270f 100644
--- a/util/ectool.c
+++ b/util/ectool.c
@@ -51,6 +51,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"
@@ -368,6 +370,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;
@@ -7990,6 +8030,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},