summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extra/usb_updater/usb_updater.c76
1 files changed, 70 insertions, 6 deletions
diff --git a/extra/usb_updater/usb_updater.c b/extra/usb_updater/usb_updater.c
index b69e60da8d..6e79be1e3a 100644
--- a/extra/usb_updater/usb_updater.c
+++ b/extra/usb_updater/usb_updater.c
@@ -237,16 +237,17 @@ struct transfer_descriptor {
static uint32_t protocol_version;
static char *progname;
-static char *short_opts = "bcd:fhipstu";
+static char *short_opts = "bcd:fhiprstu";
static const struct option long_opts[] = {
/* name hasarg *flag val */
{"binvers", 0, NULL, 'b'},
+ {"board_id", 2, NULL, 'i'},
{"corrupt", 0, NULL, 'c'},
{"device", 1, NULL, 'd'},
{"fwver", 0, NULL, 'f'},
{"help", 0, NULL, 'h'},
{"post_reset", 0, NULL, 'p'},
- {"board_id", 2, NULL, 'i'},
+ {"rma_auth", 0, NULL, 'r'},
{"systemdev", 0, NULL, 's'},
{"trunks_send", 0, NULL, 't'},
{"upstart", 0, NULL, 'u'},
@@ -538,6 +539,7 @@ static void usage(int errs)
" ID could be 32 bit hex or 4 "
"character string.\n"
" -p,--post_reset Request post reset after transfer\n"
+ " -r,--rma_auth Process RMA challenge-response\n"
" -s,--systemdev Use /dev/tpm0 (-d is ignored)\n"
" -t,--trunks_send Use `trunks_send --raw' "
"(-d is ignored)\n"
@@ -1232,10 +1234,8 @@ static uint32_t send_vendor_command(struct transfer_descriptor *td,
* to have the result code in the first byte of the response,
* to be stripped from the actual response body by this
* function.
- *
- * We never expect vendor command response larger than 32 bytes.
*/
- uint8_t temp_response[32];
+ uint8_t temp_response[MAX_BUF_SIZE];
size_t max_response_size;
if (!response_size) {
@@ -1585,6 +1585,60 @@ static void process_bid(struct transfer_descriptor *td,
}
}
+/*
+ * Retrieve the RMA authentication challenge from the Cr50, print out the
+ * challenge on the console, then prompt the user for the authentication code,
+ * and send the code back to Cr50. The Cr50 would report if the code matched
+ * its expectations or not.
+ */
+static void process_rma(struct transfer_descriptor *td)
+{
+ char rma_response[81];
+ size_t response_size = sizeof(rma_response);
+ size_t i;
+ char *authcode = NULL;
+ size_t auth_size = 0;
+
+ send_vendor_command(td, VENDOR_CC_RMA_CHALLENGE_RESPONSE,
+ NULL, 0, rma_response, &response_size);
+
+ if (response_size == 1) {
+ printf("error %d\n", rma_response[0]);
+ if (td->ep_type == usb_xfer)
+ shut_down(&td->uep);
+ exit(update_error);
+ }
+
+ printf("Challenge:");
+ for (i = 0; i < response_size; i++) {
+ if (!(i % 5)) {
+ if (!(i % 40))
+ printf("\n");
+ printf(" ");
+ }
+ printf("%c", rma_response[i]);
+ }
+ printf("\nNow enter response: ");
+ auth_size = getline(&authcode, &auth_size, stdin);
+ if (auth_size > 0) {
+
+ response_size = sizeof(rma_response);
+
+ send_vendor_command(td, VENDOR_CC_RMA_CHALLENGE_RESPONSE,
+ authcode, auth_size - 1, /* drop the '\n' */
+ rma_response, &response_size);
+
+ if (response_size == 1) {
+ printf("\nrma unlock failed, code %d\n",
+ *rma_response);
+ if (td->ep_type == usb_xfer)
+ shut_down(&td->uep);
+ exit(update_error);
+ }
+ printf("RMA unlock succeeded.\n");
+ }
+}
+
int main(int argc, char *argv[])
{
struct transfer_descriptor td;
@@ -1597,6 +1651,7 @@ int main(int argc, char *argv[])
int transferred_sections = 0;
int binary_vers = 0;
int show_fw_ver = 0;
+ int rma = 0;
int corrupt_inactive_rw = 0;
struct board_id bid;
enum board_id_action bid_action;
@@ -1647,6 +1702,9 @@ int main(int argc, char *argv[])
errorcnt++;
}
break;
+ case 'r':
+ rma = 1;
+ break;
case 's':
td.ep_type = dev_xfer;
break;
@@ -1682,7 +1740,10 @@ int main(int argc, char *argv[])
if (errorcnt)
usage(errorcnt);
- if (!show_fw_ver && !corrupt_inactive_rw && (bid_action == bid_none)) {
+ if (!show_fw_ver &&
+ !corrupt_inactive_rw &&
+ (bid_action == bid_none) &&
+ !rma) {
if (optind >= argc) {
fprintf(stderr,
"\nERROR: Missing required <binary image>\n\n");
@@ -1720,6 +1781,9 @@ int main(int argc, char *argv[])
if (bid_action != bid_none)
process_bid(&td, bid_action, &bid);
+ if (rma)
+ process_rma(&td);
+
if (corrupt_inactive_rw)
invalidate_inactive_rw(&td);