diff options
-rw-r--r-- | include/ec_commands.h | 25 | ||||
-rw-r--r-- | util/ectool.c | 41 |
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}, |