mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-14 00:26:30 +00:00
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>
This commit is contained in:
committed by
chrome-bot
parent
4ec57f1409
commit
9df26ce0f2
@@ -106,6 +106,35 @@ static int valid_transfer_start(struct consumer const *consumer, size_t count,
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void usb_extension_route_command(uint16_t command_code,
|
||||
uint8_t *buffer,
|
||||
size_t in_size,
|
||||
size_t *out_size)
|
||||
{
|
||||
uint32_t rv;
|
||||
size_t buf_size;
|
||||
|
||||
/*
|
||||
* 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,
|
||||
VENDOR_CMD_FROM_USB);
|
||||
/*
|
||||
* Copy actual response, if any, one byte up, to free room for
|
||||
* the return code.
|
||||
*/
|
||||
if (buf_size)
|
||||
memmove(buffer + 1, buffer, buf_size);
|
||||
*out_size = buf_size + 1;
|
||||
|
||||
buffer[0] = rv; /* We care about LSB only. */
|
||||
}
|
||||
|
||||
static int try_vendor_command(struct consumer const *consumer, size_t count)
|
||||
{
|
||||
struct update_frame_header ufh;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -12,6 +12,16 @@
|
||||
#include "common.h"
|
||||
#include "tpm_vendor_cmds.h"
|
||||
|
||||
/* Flags for vendor or extension commands */
|
||||
enum vendor_cmd_flags {
|
||||
/*
|
||||
* Command is coming from the USB interface (either via the vendor
|
||||
* command endpoint or the console). If this flag is not present,
|
||||
* the command is coming from the AP.
|
||||
*/
|
||||
VENDOR_CMD_FROM_USB = (1 << 0),
|
||||
};
|
||||
|
||||
/*
|
||||
* Type of function handling extension commands.
|
||||
*
|
||||
@@ -35,19 +45,17 @@ typedef enum vendor_cmd_rc (*extension_handler)(enum vendor_cmd_cc code,
|
||||
* @param command_code Code associated with a extension command handler.
|
||||
* @param buffer Data to be processd by the handler, the same space
|
||||
* is used for data returned by the handler.
|
||||
* @command_size Size of the input data.
|
||||
* @param size On input - max size of the buffer, on output - actual number of
|
||||
* data returned by the handler. A single byte return
|
||||
* @param in_size Size of the input data.
|
||||
* @param out_size On input: max size of the buffer. On output: actual
|
||||
* number of bytes returned by the handler; a single byte
|
||||
* usually indicates an error and contains the error code.
|
||||
* @param flags Zero or more flags from vendor_cmd_flags.
|
||||
*/
|
||||
void usb_extension_route_command(uint16_t command_code,
|
||||
uint32_t extension_route_command(uint16_t command_code,
|
||||
void *buffer,
|
||||
size_t command_size,
|
||||
size_t *size);
|
||||
uint32_t tpm_extension_route_command(uint16_t command_code,
|
||||
void *buffer,
|
||||
size_t command_size,
|
||||
size_t *size);
|
||||
size_t in_size,
|
||||
size_t *out_size,
|
||||
uint32_t flags);
|
||||
|
||||
/* Pointer table */
|
||||
struct extension_command {
|
||||
|
||||
Reference in New Issue
Block a user