From 1ba76eb15e68b55760cbdf47147e969313203422 Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Wed, 21 Feb 2018 17:59:44 -0800 Subject: gsctool: refactor PP polling into a function Both CCD and SPI_HASH commands need to enforce physical presence. This patch separates PP polling into a function which can be used by both commands. BRANCH=none BUG=b:73668125 TEST=verified that running 'gsctool -a -o' on a Robo device still allows to unlock CCD with PP enforced. Change-Id: I49abb0e56ad37664eaad7cc34de44e1ac06e2d1b Signed-off-by: Vadim Bendebury Reviewed-on: https://chromium-review.googlesource.com/930567 Reviewed-by: Randall Spangler (cherry picked from commit 1850d5908a348e31d61b2816f6f086fd4d3596de) Reviewed-on: https://chromium-review.googlesource.com/1141525 Reviewed-by: Nick Sanders Commit-Queue: Nick Sanders Tested-by: Nick Sanders --- extra/usb_updater/gsctool.c | 103 ++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 42 deletions(-) (limited to 'extra/usb_updater/gsctool.c') diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c index 2fbc443a78..b7075d1c4b 100644 --- a/extra/usb_updater/gsctool.c +++ b/extra/usb_updater/gsctool.c @@ -1624,57 +1624,29 @@ static void process_password(struct transfer_descriptor *td) exit(update_error); } -static void process_ccd_state(struct transfer_descriptor *td, int ccd_unlock, - int ccd_open, int ccd_lock) +/* + * This function can be used to retrieve the current PP status from Cr50 and + * prompt the user when a PP press is required. + * + * Physical presence can be required by different gsctool options, for which + * Cr50 behavior also differs. The 'command' and 'poll_type' parameters are + * used by Cr50 to tell what the host is polling for. + */ +static void poll_for_pp(struct transfer_descriptor *td, + uint16_t command, + uint8_t poll_type) { - uint8_t payload; uint8_t response; uint8_t prev_response; size_t response_size; int rv; - if (ccd_unlock) - payload = CCDV_UNLOCK; - else if (ccd_open) - payload = CCDV_OPEN; - else - payload = CCDV_LOCK; - - response_size = sizeof(response); - rv = send_vendor_command(td, VENDOR_CC_CCD, - &payload, sizeof(payload), - &response, &response_size); - - /* - * If password is required - try sending the same subcommand - * accompanied by user password. - */ - if (rv == VENDOR_RC_PASSWORD_REQUIRED) - rv = common_process_password(td, payload); - - if (rv == VENDOR_RC_SUCCESS) - return; - - if (rv != VENDOR_RC_IN_PROGRESS) { - fprintf(stderr, "Error: rv %d, response %d\n", - rv, response_size ? response : 0); - exit(update_error); - } - - /* - * Physical presence process started, poll for the state the user - * asked for. Only two subcommands would return 'IN_PROGRESS'. - */ - if (ccd_unlock) - payload = CCDV_PP_POLL_UNLOCK; - else - payload = CCDV_PP_POLL_OPEN; - prev_response = ~0; /* Guaranteed invalid value. */ + while (1) { response_size = sizeof(response); - rv = send_vendor_command(td, VENDOR_CC_CCD, - &payload, sizeof(payload), + rv = send_vendor_command(td, command, + &poll_type, sizeof(poll_type), &response, &response_size); if (((rv != VENDOR_RC_SUCCESS) && (rv != VENDOR_RC_IN_PROGRESS)) @@ -1710,6 +1682,53 @@ static void process_ccd_state(struct transfer_descriptor *td, int ccd_unlock, usleep(500 * 1000); /* Poll every half a second. */ } + +} + +static void process_ccd_state(struct transfer_descriptor *td, int ccd_unlock, + int ccd_open, int ccd_lock) +{ + uint8_t payload; + uint8_t response; + size_t response_size; + int rv; + + if (ccd_unlock) + payload = CCDV_UNLOCK; + else if (ccd_open) + payload = CCDV_OPEN; + else + payload = CCDV_LOCK; + + response_size = sizeof(response); + rv = send_vendor_command(td, VENDOR_CC_CCD, + &payload, sizeof(payload), + &response, &response_size); + + /* + * If password is required - try sending the same subcommand + * accompanied by user password. + */ + if (rv == VENDOR_RC_PASSWORD_REQUIRED) + rv = common_process_password(td, payload); + + if (rv == VENDOR_RC_SUCCESS) + return; + + if (rv != VENDOR_RC_IN_PROGRESS) { + fprintf(stderr, "Error: rv %d, response %d\n", + rv, response_size ? response : 0); + exit(update_error); + } + + /* + * Physical presence process started, poll for the state the user + * asked for. Only two subcommands would return 'IN_PROGRESS'. + */ + if (ccd_unlock) + poll_for_pp(td, VENDOR_CC_CCD, CCDV_PP_POLL_UNLOCK); + else + poll_for_pp(td, VENDOR_CC_CCD, CCDV_PP_POLL_OPEN); } static void process_bid(struct transfer_descriptor *td, -- cgit v1.2.1