summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2018-05-18 14:27:42 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-05-22 21:57:12 -0700
commit9df26ce0f2a97bbc58b1807483fd22005e253b0f (patch)
tree651d4ff123841cdc0630b423e91e61395f894b68 /common
parent4ec57f14091c42e2f9502d1c17146a06fa105a88 (diff)
downloadchrome-ec-9df26ce0f2a97bbc58b1807483fd22005e253b0f.tar.gz
cr50: Refactor tracking vendor command origin
Added flags parameter to extension_route_command(). The caller now specifies whether the command comes from the USB interface or the AP. Moved USB-specific shuffling of response to embed result code into usb_upgrade.c, so extension_route_command() can be more generic. No change to permissions/behavior for existing commands. ccd_command_wrapper() still sends vendor commands as if they come from the AP. That's fixed in the next CL. Reduces code size by 128 bytes BUG=b:79983505 BRANCH=cr50 TEST=manual Build with DEBUG_EXTENSION defined, to turn on printing each command 'ccd lock' comes from AP and works From host, 'gscutil -I' comes from USB and fails From AP, 'gscutil -t -I' comes from AP and works Change-Id: I7136bb54073de9c5951a174c308151b1871c56f3 Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1068101 Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/extension.c118
-rw-r--r--common/tpm_registers.c11
2 files changed, 50 insertions, 79 deletions
diff --git a/common/extension.c b/common/extension.c
index 610db49851..f63734025f 100644
--- a/common/extension.c
+++ b/common/extension.c
@@ -9,20 +9,48 @@
#include "link_defs.h"
#include "util.h"
-#define CPRINTF(format, args...) cprintf(CC_EXTENSION, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_EXTENSION, format, ## args)
-static uint32_t extension_route_command(uint16_t command_code,
- void *buffer,
- size_t in_size,
- size_t *out_size)
+uint32_t extension_route_command(uint16_t command_code,
+ void *buffer,
+ size_t in_size,
+ size_t *out_size,
+ uint32_t flags)
{
struct extension_command *cmd_p;
struct extension_command *end_p;
+ const char *why_ignore = "not found";
- cmd_p = (struct extension_command *)&__extension_cmds;
- end_p = (struct extension_command *)&__extension_cmds_end;
+#ifdef DEBUG_EXTENSION
+ CPRINTS("%s(%d,%s)", __func__, command_code,
+ flags & VENDOR_CMD_FROM_USB ? "USB" : "AP");
+#endif
+
+ /* Filter commands from USB */
+ if (flags & VENDOR_CMD_FROM_USB) {
+ switch (command_code) {
+#ifdef CR50_DEV
+ case VENDOR_CC_IMMEDIATE_RESET:
+ case VENDOR_CC_INVALIDATE_INACTIVE_RW:
+ case VENDOR_CC_SET_BOARD_ID:
+#endif /* defined(CR50_DEV) */
+ case EXTENSION_POST_RESET: /* Always need to reset. */
+ case VENDOR_CC_GET_BOARD_ID:
+ case VENDOR_CC_SPI_HASH: /* Requires physical presence. */
+ case VENDOR_CC_TURN_UPDATE_ON:
+ break;
+ default:
+ /* Otherwise, we don't allow this command. */
+ why_ignore = "usb";
+ goto ignore_cmd;
+ }
+ }
#ifdef CONFIG_BOARD_ID_SUPPORT
+ /*
+ * If board ID is mismatched, allow only the commands needed to upgrade
+ * Cr50 firmware.
+ */
if (board_id_is_mismatched()) {
switch (command_code) {
case EXTENSION_FW_UPGRADE:
@@ -31,13 +59,15 @@ static uint32_t extension_route_command(uint16_t command_code,
case EXTENSION_POST_RESET:
break;
default:
- CPRINTF("%s: ignoring command 0x%x "
- "due to board ID mismatch\n",
- __func__, command_code);
- return VENDOR_RC_NO_SUCH_COMMAND;
+ why_ignore = "BoardID mismatch";
+ goto ignore_cmd;
}
}
#endif
+
+ /* Find the command handler */
+ cmd_p = (struct extension_command *)&__extension_cmds;
+ end_p = (struct extension_command *)&__extension_cmds_end;
while (cmd_p != end_p) {
if (cmd_p->command_code == command_code)
return cmd_p->handler(command_code, buffer,
@@ -45,69 +75,9 @@ static uint32_t extension_route_command(uint16_t command_code,
cmd_p++;
}
- CPRINTF("%s: handler %d not found\n", __func__, command_code);
-
- /* This covers the case of the handler not found. */
+ignore_cmd:
+ /* Command not found or not allowed */
+ CPRINTS("%s: ignore %d: %s", __func__, command_code, why_ignore);
*out_size = 0;
return VENDOR_RC_NO_SUCH_COMMAND;
}
-
-void usb_extension_route_command(uint16_t command_code,
- void *buffer,
- size_t in_size,
- size_t *out_size)
-{
- uint32_t rv;
- uint8_t *buf = buffer; /* Cache it for easy pointer arithmetics. */
- size_t buf_size;
-
- switch (command_code) {
-#ifdef CR50_DEV
- case VENDOR_CC_IMMEDIATE_RESET:
- case VENDOR_CC_INVALIDATE_INACTIVE_RW:
- case VENDOR_CC_SET_BOARD_ID:
-#endif /* defined(CR50_DEV) */
- case EXTENSION_POST_RESET: /* Always need to be able to reset. */
- case VENDOR_CC_GET_BOARD_ID:
- case VENDOR_CC_SPI_HASH: /* This will require physical presence. */
- case VENDOR_CC_TURN_UPDATE_ON:
-
- /*
- * The return code normally put into the TPM response header
- * is not present in the USB response. Vendor command return
- * code is guaranteed to fit in a byte. Let's keep space for
- * it in the front of the buffer.
- */
- buf_size = *out_size - 1;
- rv = extension_route_command(command_code, buffer,
- in_size, &buf_size);
- /*
- * Copy actual response, if any, one byte up, to free room for
- * the return code.
- */
- if (buf_size)
- memmove(buf + 1, buf, buf_size);
- *out_size = buf_size + 1;
- break;
-
- default:
- /* Otherwise, we don't allow this command. */
- CPRINTF("%s: ignoring vendor cmd %d\n", __func__, command_code);
- *out_size = 1;
- rv = VENDOR_RC_NO_SUCH_COMMAND;
- break;
- }
-
- buf[0] = rv; /* We care about LSB only. */
-}
-
-uint32_t tpm_extension_route_command(uint16_t command_code,
- void *buffer,
- size_t in_size,
- size_t *out_size)
-{
- /*
- * TODO(aaboagye): Determine what commands (if any) should be filtered.
- */
- return extension_route_command(command_code, buffer, in_size, out_size);
-}
diff --git a/common/tpm_registers.c b/common/tpm_registers.c
index 06405d4b7e..959ca1c814 100644
--- a/common/tpm_registers.c
+++ b/common/tpm_registers.c
@@ -648,11 +648,12 @@ static void call_extension_command(struct tpm_cmd_header *tpmh,
*total_size -= sizeof(struct tpm_cmd_header);
subcommand_code = be16toh(tpmh->subcommand_code);
- rc = tpm_extension_route_command(subcommand_code,
- tpmh + 1,
- command_size -
- sizeof(struct tpm_cmd_header),
- total_size);
+ rc = extension_route_command(subcommand_code,
+ tpmh + 1,
+ command_size -
+ sizeof(struct tpm_cmd_header),
+ total_size,
+ 0);
/* Add the header size back. */
*total_size += sizeof(struct tpm_cmd_header);
tpmh->size = htobe32(*total_size);