summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2017-10-26 21:41:50 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2017-11-13 18:58:41 +0000
commit0a3a60ec48b086f51dec542f40c6d0f54a5893e8 (patch)
tree6e533bfd72b002d88f315ce7ebb66e854fda3cd5
parent13038f7cad0f2354a43e01707713ec7949acf665 (diff)
downloadchrome-ec-0a3a60ec48b086f51dec542f40c6d0f54a5893e8.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> (cherry picked from commit a0f43d59d0b58390b22b7e9b58e2b7a799db4070) Reviewed-on: https://chromium-review.googlesource.com/766075
-rw-r--r--extra/usb_updater/gsctool.c81
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, &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);