summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Bendebury <vbendeb@chromium.org>2018-01-05 16:16:07 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2018-02-01 00:48:10 +0000
commite2fc92801dabfc7f062453e3adc5fd5f1c9c5893 (patch)
tree322b4bc5d6bc009693973bc3b58399857a270bc6
parentad8d5cb82ae7c7928a8f8ffcf59cc8713a163363 (diff)
downloadchrome-ec-e2fc92801dabfc7f062453e3adc5fd5f1c9c5893.tar.gz
ccd: prepare for handling crucial CCD commands through TPM task context
We want CCD commands lock, open, password, and unlock (at least to start with) to be available over both CLI and through crosh (i.e. coming over /dev/tpm0). Let's allocate a TPM vendor command for handling all CCD subcommands, and move to this new framework the 'ccd password' command, which already is available over vendor command. BRANCH=cr50 BUG=b:62537474 TEST=verified that 'ccd password' still works both over Suzy-Q CLI and using gsctool on the target. Change-Id: I2d06230b762f47af7e580b188a587bc5678ca169 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/853280 Reviewed-by: Randall Spangler <rspangler@chromium.org> (cherry picked from commit 877e5909b403cd40b415757b2921594bb6d8a021) Reviewed-on: https://chromium-review.googlesource.com/896754
-rw-r--r--common/ccd_config.c94
-rw-r--r--extra/usb_updater/gsctool.c10
-rw-r--r--include/ccd_config.h11
-rw-r--r--include/tpm_vendor_cmds.h6
4 files changed, 96 insertions, 25 deletions
diff --git a/common/ccd_config.c b/common/ccd_config.c
index 73f6bb0246..6d19d972d2 100644
--- a/common/ccd_config.c
+++ b/common/ccd_config.c
@@ -64,6 +64,15 @@ enum ccd_capability_state {
CCD_CAP_STATE_COUNT
};
+/*
+ * CCD command header; including the subcommand code used to demultiplex
+ * various CCD commands over the same TPM vendor command.
+ */
+struct ccd_vendor_cmd_header {
+ struct tpm_cmd_header tpm_header;
+ uint8_t ccd_subcommand;
+} __packed;
+
/* Size of password salt and digest in bytes */
#define CCD_PASSWORD_SALT_SIZE 4
#define CCD_PASSWORD_DIGEST_SIZE 16
@@ -796,7 +805,7 @@ static int do_ccd_password(char *password)
static int command_ccd_password(int argc, char **argv)
{
- struct tpm_cmd_header *tpmh;
+ struct ccd_vendor_cmd_header *vch;
int rv;
size_t password_size;
size_t command_size;
@@ -812,32 +821,33 @@ static int command_ccd_password(int argc, char **argv)
return EC_ERROR_PARAM1;
}
- command_size = sizeof(struct tpm_cmd_header) + password_size;
- rv = shared_mem_acquire(command_size, (char **)&tpmh);
+ command_size = sizeof(*vch) + password_size;
+ rv = shared_mem_acquire(command_size, (char **)&vch);
if (rv != EC_SUCCESS)
return rv;
/* Build the extension command to set/clear CCD password. */
- tpmh->tag = htobe16(0x8001); /* TPM_ST_NO_SESSIONS */
- tpmh->size = htobe32(command_size);
- tpmh->command_code = htobe32(TPM_CC_VENDOR_BIT_MASK);
- tpmh->subcommand_code = htobe16(VENDOR_CC_CCD_PASSWORD);
- memcpy(tpmh + 1, argv[1], password_size);
- tpm_alt_extension(tpmh, command_size);
+ vch->tpm_header.tag = htobe16(0x8001); /* TPM_ST_NO_SESSIONS */
+ vch->tpm_header.size = htobe32(command_size);
+ vch->tpm_header.command_code = htobe32(TPM_CC_VENDOR_BIT_MASK);
+ vch->tpm_header.subcommand_code = htobe16(VENDOR_CC_CCD);
+ vch->ccd_subcommand = CCDV_PASSWORD;
+
+ memcpy(vch + 1, argv[1], password_size);
+ tpm_alt_extension(&vch->tpm_header, command_size);
/*
* Return status in the command code field now, in case of error,
* error code is the first byte after the header.
*/
- if (tpmh->command_code) {
- ccprintf("Password setting error %d\n",
- ((uint8_t *)(tpmh + 1))[0]);
+ if (vch->tpm_header.command_code) {
+ ccprintf("Password setting error %d\n", vch->ccd_subcommand);
rv = EC_ERROR_UNKNOWN;
} else {
rv = EC_SUCCESS;
}
- shared_mem_release(tpmh);
+ shared_mem_release(vch);
return EC_SUCCESS;
}
@@ -1225,14 +1235,12 @@ static enum vendor_cmd_rc manage_ccd_password(enum vendor_cmd_cc code,
DECLARE_VENDOR_COMMAND(VENDOR_CC_MANAGE_CCD_PWD, manage_ccd_password);
/*
- * Handle the VENDOR_CC_CCD_PASSWORD command.
+ * Handle the CCVD_PASSWORD subcommand.
*
- * The payload of the command is a text string to use to set the password. The
- * text string set to 'clear' has a special effect though, it clears the
- * password instead of setting it.
+ * The payload of the command is a text string to use to set or clear the
+ * password.
*/
-static enum vendor_cmd_rc ccd_password(enum vendor_cmd_cc code,
- void *buf,
+static enum vendor_cmd_rc ccd_password(void *buf,
size_t input_size,
size_t *response_size)
{
@@ -1264,8 +1272,54 @@ static enum vendor_cmd_rc ccd_password(enum vendor_cmd_cc code,
*response_size = 0;
return VENDOR_RC_SUCCESS;
}
-DECLARE_VENDOR_COMMAND(VENDOR_CC_CCD_PASSWORD, ccd_password);
+/*
+ * Common TPM Vendor command handler used to demultiplex various CCD commands
+ * which need to be available both throuh CLI and over /dev/tpm0.
+ */
+static enum vendor_cmd_rc ccd_vendor(enum vendor_cmd_cc code,
+ void *buf,
+ size_t input_size,
+ size_t *response_size)
+{
+ enum vendor_cmd_rc (*handler)(void *x, size_t y, size_t *t);
+ char *buffer;
+ enum vendor_cmd_rc rc;
+
+ /*
+ * buf points to the next byte after tpm header, i.e. to the CCD
+ * subcommand. Cache the pointer to make it easier to access and
+ * manipulate.
+ */
+ buffer = buf;
+
+ /* Pick what to do based on subcommand. */
+ switch (buffer[0]) {
+ case CCDV_PASSWORD:
+ handler = ccd_password;
+ break;
+
+ default:
+ CPRINTS("%s:%d - unknown subcommand\n", __func__, __LINE__);
+ break;
+ }
+
+ if (handler) {
+ rc = handler(buf + 1, input_size - 1, response_size);
+
+ /*
+ * Move response up for the master to see it in the right
+ * place in the response buffer.
+ */
+ memmove(buf, buf + 1, *response_size);
+ } else {
+ rc = VENDOR_RC_NO_SUCH_SUBCOMMAND;
+ *response_size = 0;
+ }
+
+ return rc;
+}
+DECLARE_VENDOR_COMMAND(VENDOR_CC_CCD, ccd_vendor);
static enum vendor_cmd_rc ccd_disable_rma(enum vendor_cmd_cc code,
void *buf,
diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c
index a0b4c28c7a..4e00c5c494 100644
--- a/extra/usb_updater/gsctool.c
+++ b/extra/usb_updater/gsctool.c
@@ -27,6 +27,7 @@
#include "config.h"
+#include "ccd_config.h"
#include "compile_time_macros.h"
#include "misc_util.h"
#include "signed_header.h"
@@ -1582,12 +1583,13 @@ static void process_password(struct transfer_descriptor *td)
}
/*
- * Ok, we have a password, let's drop the newline in the end and send
- * it down.
+ * Ok, we have a password, let's move it in the buffer to overwrite
+ * the newline and free a byte to prepend the subcommand code.
*/
- password[--len] = '\0';
+ memmove(password + 1, password, len - 1);
+ password[0] = CCDV_PASSWORD;
response_size = sizeof(response);
- rv = send_vendor_command(td, VENDOR_CC_CCD_PASSWORD,
+ rv = send_vendor_command(td, VENDOR_CC_CCD,
password, len,
&response, &response_size);
free(password);
diff --git a/include/ccd_config.h b/include/ccd_config.h
index 5319f9a045..5a1cb5add9 100644
--- a/include/ccd_config.h
+++ b/include/ccd_config.h
@@ -98,6 +98,17 @@ enum ccd_capability {
CCD_CAP_COUNT
};
+/*
+ * Subcommand code, used to pass different CCD commands using the same TPM
+ * vendor command.
+ */
+enum ccd_vendor_subcommands {
+ CCDV_PASSWORD = 0,
+ CCDV_OPEN = 1,
+ CCDV_UNLOCK = 2,
+ CCDV_LOCK = 3,
+};
+
/**
* Initialize CCD configuration at boot.
*
diff --git a/include/tpm_vendor_cmds.h b/include/tpm_vendor_cmds.h
index 830678ee0c..390097a45c 100644
--- a/include/tpm_vendor_cmds.h
+++ b/include/tpm_vendor_cmds.h
@@ -44,9 +44,12 @@ enum vendor_cmd_cc {
VENDOR_CC_POP_LOG_ENTRY = 28,
VENDOR_CC_GET_REC_BTN = 29,
VENDOR_CC_RMA_CHALLENGE_RESPONSE = 30,
- VENDOR_CC_CCD_PASSWORD = 31,
+
+ /* A gap left for the no longer supported CCD password command. */
+
VENDOR_CC_DISABLE_RMA = 32,
VENDOR_CC_MANAGE_CCD_PWD = 33,
+ VENDOR_CC_CCD = 34,
LAST_VENDOR_COMMAND = 65535,
};
@@ -69,6 +72,7 @@ enum vendor_cmd_rc {
VENDOR_RC_RESPONSE_TOO_BIG = 5,
VENDOR_RC_INTERNAL_ERROR = 6,
VENDOR_RC_NOT_ALLOWED = 7,
+ VENDOR_RC_NO_SUCH_SUBCOMMAND = 8,
/* Only 7 bits available; max is 127 */
VENDOR_RC_NO_SUCH_COMMAND = 127,
};