cr50: add vendor CCD subcommand to report CCD information

It is important for the OS to be able to find out the state of CCD and
current capabilities settings of the device.

This patch defines a structure to use to report information about CCD
state from Cr50 to the host and adds a CCD vendor subcommand to allow
to retrieve the information from Cr50.

Some structure and variable definitions had to be moved into the .h
file to make it possible to share them between Cr50 and gsctool.

BRANCH=cr50, cr50-mp
BUG=b:72718383
TEST=with the following patch applied verified that CCD info is
     properly reported. Also verified that other CCD subcommands still
     work as advertised.

Change-Id: I4a783e6817ed364b9e64522ebbe968d4a657a84c
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/999825
Reviewed-by: Randall Spangler <rspangler@chromium.org>
(cherry picked from commit c3077e63e5)
Reviewed-on: https://chromium-review.googlesource.com/1015615
This commit is contained in:
Vadim Bendebury 2018-04-05 19:05:24 -07:00 committed by ChromeOS Commit Bot
parent 268220b6dc
commit 0816d829ee
2 changed files with 122 additions and 53 deletions

View File

@ -29,6 +29,9 @@
#define CPRINTS(format, args...) cprints(CC_CCD, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_CCD, format, ## args)
/* Let's make sure that CCD capability state enum fits into two bits. */
BUILD_ASSERT(CCD_CAP_STATE_COUNT <= 4);
/* Restriction state for ccdunlock when no password is set */
enum ccd_unlock_restrict {
/* Unrestricted */
@ -47,24 +50,6 @@ enum ccd_unlock_restrict {
/* Current version of case-closed debugging configuration struct */
#define CCD_CONFIG_VERSION 0x10
/* Capability states */
enum ccd_capability_state {
/* Default value */
CCD_CAP_STATE_DEFAULT = 0,
/* Always available (state >= CCD_STATE_LOCKED) */
CCD_CAP_STATE_ALWAYS = 1,
/* Unless locked (state >= CCD_STATE_UNLOCKED) */
CCD_CAP_STATE_UNLESS_LOCKED = 2,
/* Only if opened (state >= CCD_STATE_OPENED) */
CCD_CAP_STATE_IF_OPENED = 3,
/* Number of capability states */
CCD_CAP_STATE_COUNT
};
/*
* CCD command header; including the subcommand code used to demultiplex
* various CCD commands over the same TPM vendor command.
@ -104,14 +89,6 @@ struct ccd_config {
uint8_t password_digest[CCD_PASSWORD_DIGEST_SIZE];
};
struct ccd_capability_info {
/* Capability name */
const char *name;
/* Default state, if config set to CCD_CAP_STATE_DEFAULT */
enum ccd_capability_state default_state;
};
/* Nvmem variable name for CCD config */
static const uint8_t k_ccd_config = NVMEM_VAR_CCD_CONFIG;
@ -121,33 +98,11 @@ static const uint32_t k_public_flags =
CCD_FLAG_OVERRIDE_WP_STATE_ENABLED;
/* List of CCD capability info; must be in same order as enum ccd_capability */
static const struct ccd_capability_info cap_info[CCD_CAP_COUNT] = {
{"UartGscRxAPTx", CCD_CAP_STATE_ALWAYS},
{"UartGscTxAPRx", CCD_CAP_STATE_ALWAYS},
{"UartGscRxECTx", CCD_CAP_STATE_ALWAYS},
{"UartGscTxECRx", CCD_CAP_STATE_IF_OPENED},
static const struct ccd_capability_info cap_info[CCD_CAP_COUNT] = CAP_INFO_DATA;
{"FlashAP", CCD_CAP_STATE_IF_OPENED},
{"FlashEC", CCD_CAP_STATE_IF_OPENED},
{"OverrideWP", CCD_CAP_STATE_IF_OPENED},
{"RebootECAP", CCD_CAP_STATE_IF_OPENED},
{"GscFullConsole", CCD_CAP_STATE_IF_OPENED},
{"UnlockNoReboot", CCD_CAP_STATE_ALWAYS},
{"UnlockNoShortPP", CCD_CAP_STATE_ALWAYS},
{"OpenNoTPMWipe", CCD_CAP_STATE_IF_OPENED},
{"OpenNoLongPP", CCD_CAP_STATE_IF_OPENED},
{"BatteryBypassPP", CCD_CAP_STATE_ALWAYS},
{"UpdateNoTPMWipe", CCD_CAP_STATE_ALWAYS},
{"I2C", CCD_CAP_STATE_IF_OPENED},
{"FlashRead", CCD_CAP_STATE_ALWAYS},
};
static const char *ccd_state_names[CCD_STATE_COUNT] = {
"Locked", "Unlocked", "Opened"};
static const char *ccd_cap_state_names[CCD_CAP_STATE_COUNT] = {
"Default", "Always", "UnlessLocked", "IfOpened"};
static const char *ccd_state_names[CCD_STATE_COUNT] = CCD_STATE_NAMES;
static const char *ccd_cap_state_names[CCD_CAP_STATE_COUNT] =
CCD_CAP_STATE_NAMES;
static enum ccd_state ccd_state = CCD_STATE_LOCKED;
static struct ccd_config config;
@ -1442,6 +1397,42 @@ static enum vendor_cmd_rc ccd_pp_poll_open(void *buf,
return VENDOR_RC_SUCCESS;
}
static enum vendor_cmd_rc ccd_get_info(void *buf,
size_t input_size,
size_t *response_size)
{
int i;
struct ccd_info_response response = {};
for (i = 0; i < CCD_CAP_COUNT; i++) {
int index;
int shift;
/* Each capability takes 2 bits. */
index = i / (32/2);
shift = (i % (32/2)) * 2;
response.ccd_caps_current[index] |= raw_get_cap(i, 1) << shift;
response.ccd_caps_defaults[index] |=
cap_info[i].default_state << shift;
}
response.ccd_flags = htobe32(raw_get_flags());
response.ccd_state = ccd_get_state();
response.ccd_has_password = raw_has_password();
response.ccd_force_disabled = force_disabled;
for (i = 0; i < ARRAY_SIZE(response.ccd_caps_current); i++) {
response.ccd_caps_current[i] =
htobe32(response.ccd_caps_current[i]);
response.ccd_caps_defaults[i] =
htobe32(response.ccd_caps_defaults[i]);
}
*response_size = sizeof(response);
memcpy(buf, &response, sizeof(response));
return VENDOR_RC_SUCCESS;
}
/*
* Common TPM Vendor command handler used to demultiplex various CCD commands
* which need to be available both throuh CLI and over /dev/tpm0.
@ -1488,13 +1479,24 @@ static enum vendor_cmd_rc ccd_vendor(enum vendor_cmd_cc code,
handler = ccd_pp_poll_open;
break;
case CCDV_GET_INFO:
handler = ccd_get_info;
break;
default:
CPRINTS("%s:%d - unknown subcommand\n", __func__, __LINE__);
break;
}
if (handler) {
*response_size = 0; /* Let's be optimistic: 0 means success. */
/*
* Let's be optimistic: 0 usually means success.
*
* We know the buffer is large enough to accommodate any CCD
* subcommand response, so there is no size checks in the
* processing functions.
*/
*response_size = 0;
rc = handler(buf + 1, input_size - 1, response_size);

View File

@ -7,6 +7,9 @@
#ifndef __CROS_EC_CCD_CONFIG_H
#define __CROS_EC_CCD_CONFIG_H
#include <common.h>
#include <stdint.h>
/* Case-closed debugging state */
enum ccd_state {
CCD_STATE_LOCKED = 0,
@ -101,6 +104,58 @@ enum ccd_capability {
CCD_CAP_COUNT
};
/* Capability states */
enum ccd_capability_state {
/* Default value */
CCD_CAP_STATE_DEFAULT = 0,
/* Always available (state >= CCD_STATE_LOCKED) */
CCD_CAP_STATE_ALWAYS = 1,
/* Unless locked (state >= CCD_STATE_UNLOCKED) */
CCD_CAP_STATE_UNLESS_LOCKED = 2,
/* Only if opened (state >= CCD_STATE_OPENED) */
CCD_CAP_STATE_IF_OPENED = 3,
/* Number of capability states */
CCD_CAP_STATE_COUNT
};
struct ccd_capability_info {
/* Capability name */
const char *name;
/* Default state, if config set to CCD_CAP_STATE_DEFAULT */
enum ccd_capability_state default_state;
};
#define CAP_INFO_DATA { \
{"UartGscRxAPTx", CCD_CAP_STATE_ALWAYS}, \
{"UartGscTxAPRx", CCD_CAP_STATE_ALWAYS}, \
{"UartGscRxECTx", CCD_CAP_STATE_ALWAYS}, \
{"UartGscTxECRx", CCD_CAP_STATE_IF_OPENED}, \
\
{"FlashAP", CCD_CAP_STATE_IF_OPENED}, \
{"FlashEC", CCD_CAP_STATE_IF_OPENED}, \
{"OverrideWP", CCD_CAP_STATE_IF_OPENED}, \
{"RebootECAP", CCD_CAP_STATE_IF_OPENED}, \
\
{"GscFullConsole", CCD_CAP_STATE_IF_OPENED}, \
{"UnlockNoReboot", CCD_CAP_STATE_ALWAYS}, \
{"UnlockNoShortPP", CCD_CAP_STATE_ALWAYS}, \
{"OpenNoTPMWipe", CCD_CAP_STATE_IF_OPENED}, \
\
{"OpenNoLongPP", CCD_CAP_STATE_IF_OPENED}, \
{"BatteryBypassPP", CCD_CAP_STATE_ALWAYS}, \
{"UpdateNoTPMWipe", CCD_CAP_STATE_ALWAYS}, \
{"I2C", CCD_CAP_STATE_IF_OPENED}, \
{"FlashRead", CCD_CAP_STATE_ALWAYS}, \
}
#define CCD_STATE_NAMES { "Locked", "Unlocked", "Opened" }
#define CCD_CAP_STATE_NAMES { "Default", "Always", "UnlessLocked", "IfOpened" }
/*
* Subcommand code, used to pass different CCD commands using the same TPM
* vendor command.
@ -112,6 +167,7 @@ enum ccd_vendor_subcommands {
CCDV_LOCK = 3,
CCDV_PP_POLL_UNLOCK = 4,
CCDV_PP_POLL_OPEN = 5,
CCDV_GET_INFO = 6
};
enum ccd_pp_state {
@ -121,6 +177,17 @@ enum ccd_pp_state {
CCD_PP_DONE = 3
};
/* Structure to communicate information about CCD state. */
#define CCD_CAPS_WORDS ((CCD_CAP_COUNT * 2 + 31)/32)
struct ccd_info_response {
uint32_t ccd_caps_current[CCD_CAPS_WORDS];
uint32_t ccd_caps_defaults[CCD_CAPS_WORDS];
uint32_t ccd_flags;
uint8_t ccd_state;
uint8_t ccd_force_disabled;
uint8_t ccd_has_password;
} __packed;
/**
* Initialize CCD configuration at boot.
*