diff options
author | Vadim Bendebury <vbendeb@chromium.org> | 2017-10-26 21:41:50 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-10-30 10:44:58 -0700 |
commit | a0f43d59d0b58390b22b7e9b58e2b7a799db4070 (patch) | |
tree | 42572a85fe8c941b9b03c7d992ad8686dd94ca18 /extra | |
parent | 32cc460bad5ad02a4b7e0a85ef54361049e80897 (diff) | |
download | chrome-ec-a0f43d59d0b58390b22b7e9b58e2b7a799db4070.tar.gz |
gsctool: provide an option to set/clear password
This patch makes use of a recently introduced vendor command for
password control.
The new option '-P,password' is introduced to allow the device user to
set/clear the CCD password. Command line echo is suppressed when
password is being entered, so it is required to enter it twice.
To stay consistent with the 'ccd' Cr50 console command conventions the
word 'clear' should be used as the password when one wants to clear
the CCD password. All policies for setting/clearing the password are
the same as when setting it from the Cr50 console.
BRANCH=cr50
BUG=b:62537474
TEST=set and clear password when accessing over /dev/tpm0. Verified
that attempts to set/clear password over USB fail.
Change-Id: I7721d9ce12da8b7c89fc80eaa69cb8dd001abdb8
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/741172
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
Diffstat (limited to 'extra')
-rw-r--r-- | extra/usb_updater/gsctool.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c index f3ade1c4d7..fa3c461ea9 100644 --- a/extra/usb_updater/gsctool.c +++ b/extra/usb_updater/gsctool.c @@ -17,6 +17,7 @@ #include <string.h> #include <sys/stat.h> #include <sys/types.h> +#include <termios.h> #include <unistd.h> @@ -237,7 +238,7 @@ struct transfer_descriptor { static uint32_t protocol_version; static char *progname; -static char *short_opts = "bcd:fhiprstu"; +static char *short_opts = "bcd:fhiPprstu"; static const struct option long_opts[] = { /* name hasarg *flag val */ {"binvers", 0, NULL, 'b'}, @@ -246,6 +247,7 @@ static const struct option long_opts[] = { {"device", 1, NULL, 'd'}, {"fwver", 0, NULL, 'f'}, {"help", 0, NULL, 'h'}, + {"password", 0, NULL, 'P'}, {"post_reset", 0, NULL, 'p'}, {"rma_auth", 2, NULL, 'r'}, {"systemdev", 0, NULL, 's'}, @@ -543,6 +545,9 @@ static void usage(int errs) " Get or set Info1 board ID fields\n" " ID could be 32 bit hex or 4 " "character string.\n" + " -P,--password <password>\n" + " Set or clear CCD password. Use\n" + " 'clear' to clear it.\n" " -p,--post_reset Request post reset after transfer\n" " -r,--rma_auth [auth_code]\n" " Request RMA challenge or process " @@ -1531,6 +1536,70 @@ static int parse_bid(const char *opt, return 1; } +static void process_password(struct transfer_descriptor *td) +{ + size_t response_size; + uint8_t response; + uint32_t rv; + char *password = NULL; + char *password_copy = NULL; + size_t copy_len = 0; + size_t len = 0; + struct termios oldattr, newattr; + + /* Suppress command line echo while password is being entered. */ + tcgetattr(STDIN_FILENO, &oldattr); + newattr = oldattr; + newattr.c_lflag &= ~ECHO; + newattr.c_lflag |= (ICANON | ECHONL); + tcsetattr(STDIN_FILENO, TCSANOW, &newattr); + + /* With command line echo suppressed request password entry twice. */ + printf("Enter password:"); + len = getline(&password, &len, stdin); + printf("Re-enter password:"); + getline(&password_copy, ©_len, stdin); + + /* Restore command line echo. */ + tcsetattr(STDIN_FILENO, TCSANOW, &oldattr); + + /* Empty password will still have the newline. */ + if ((len <= 1) || !password_copy) { + if (password) + free(password); + if (password_copy) + free(password_copy); + fprintf(stderr, "Error reading password\n"); + exit(update_error); + } + + /* Compare the two inputs. */ + if (strcmp(password, password_copy)) { + fprintf(stderr, "Entered passwords don't match\n"); + free(password); + free(password_copy); + exit(update_error); + } + + /* + * Ok, we have a password, let's drop the newline in the end and send + * it down. + */ + password[--len] = '\0'; + response_size = sizeof(response); + rv = send_vendor_command(td, VENDOR_CC_CCD_PASSWORD, + password, len, + &response, &response_size); + free(password); + free(password_copy); + if (!rv) + return; + + fprintf(stderr, "Error setting password: rv %d, response %d\n", + rv, response_size ? 0 : response); + exit(update_error); +} + static void process_bid(struct transfer_descriptor *td, enum board_id_action bid_action, struct board_id *bid) @@ -1664,6 +1733,7 @@ int main(int argc, char *argv[]) int corrupt_inactive_rw = 0; struct board_id bid; enum board_id_action bid_action; + int password = 0; progname = strrchr(argv[0], '/'); if (progname) @@ -1728,6 +1798,9 @@ int main(int argc, char *argv[]) case 'p': td.post_reset = 1; break; + case 'P': + password = 1; + break; case 'u': td.upstart_mode = 1; break; @@ -1757,7 +1830,8 @@ int main(int argc, char *argv[]) if (!show_fw_ver && !corrupt_inactive_rw && (bid_action == bid_none) && - !rma) { + !rma && + !password) { if (optind >= argc) { fprintf(stderr, "\nERROR: Missing required <binary image>\n\n"); @@ -1792,6 +1866,9 @@ int main(int argc, char *argv[]) } } + if (password) + process_password(&td); + if (bid_action != bid_none) process_bid(&td, bid_action, &bid); |