diff options
-rw-r--r-- | chip/g/flash.c | 65 | ||||
-rw-r--r-- | common/extension.c | 1 | ||||
-rw-r--r-- | include/tpm_vendor_cmds.h | 1 |
3 files changed, 66 insertions, 1 deletions
diff --git a/chip/g/flash.c b/chip/g/flash.c index 443ab23efe..28c97875f4 100644 --- a/chip/g/flash.c +++ b/chip/g/flash.c @@ -42,6 +42,7 @@ #include "board_id.h" #include "console.h" #include "cryptoc/util.h" +#include "extension.h" #include "flash.h" #include "flash_log.h" #include "registers.h" @@ -50,6 +51,7 @@ #include "timer.h" #include "watchdog.h" +#define CPRINTS(format, args...) cprints(CC_EXTENSION, format, ## args) #define CPRINTF(format, args...) cprintf(CC_EXTENSION, format, ## args) /* Mutex to prevent concurrent accesses to flash engine. */ @@ -460,8 +462,69 @@ void flash_open_ro_window(uint32_t offset, size_t size_b) GWRITE_FIELD(GLOBALSEC, FLASH_REGION6_CTRL, WR_EN, 1); } -#ifdef CR50_RELAXED +#ifdef CR50_DEV +/* + * The seed is the first 32 bytes of the manufacture state space. That is all + * we care about. We can ignore the rest of the manufacture state. + */ +#define ENDORSEMENT_SEED_SIZE 32 + +static enum vendor_cmd_rc vc_endorsement_seed(enum vendor_cmd_cc code, + void *buf, + size_t input_size, + size_t *response_size) +{ + uint8_t endorsement_seed[ENDORSEMENT_SEED_SIZE]; + int rv = VENDOR_RC_SUCCESS; + int is_erased = 1; + int set_seed = input_size == ENDORSEMENT_SEED_SIZE; + int i; + uint32_t *p; + int offset; + + *response_size = 0; + if (input_size && !set_seed) { + CPRINTS("%s: invalid seed", __func__); + return VENDOR_RC_BOGUS_ARGS; + } + + /* Read the endorsement key seed. */ + p = (uint32_t *)endorsement_seed; + for (i = 0; i < (ENDORSEMENT_SEED_SIZE / sizeof(*p)); i++) { + offset = FLASH_INFO_MANUFACTURE_STATE_OFFSET + i * sizeof(*p); + if (flash_physical_info_read_word(offset, p + i) != + EC_SUCCESS) { + CPRINTS("%s: failed read", __func__); + return VENDOR_RC_INTERNAL_ERROR; + } + if (p[i] != 0xffffffff) + is_erased = 0; + } + + if (set_seed && !is_erased) { + CPRINTS("%s: seed already set!", __func__); + return VENDOR_RC_NOT_ALLOWED; + } + if (!input_size) { + *response_size = ENDORSEMENT_SEED_SIZE; + memcpy(buf, endorsement_seed, *response_size); + return VENDOR_RC_SUCCESS; + } + + flash_info_write_enable(); + if (flash_info_physical_write(FLASH_INFO_MANUFACTURE_STATE_OFFSET, + input_size, + (char *)buf) != EC_SUCCESS) { + CPRINTS("%s: failed write", __func__); + rv = VENDOR_RC_INTERNAL_ERROR; + } + flash_info_write_disable(); + return rv; +} +DECLARE_VENDOR_COMMAND(VENDOR_CC_ENDORSEMENT_SEED, vc_endorsement_seed); +#endif +#ifdef CR50_RELAXED static int command_erase_flash_info(int argc, char **argv) { int i; diff --git a/common/extension.c b/common/extension.c index fb1f24c309..d2a26a6cd2 100644 --- a/common/extension.c +++ b/common/extension.c @@ -33,6 +33,7 @@ uint32_t extension_route_command(struct vendor_cmd_params *p) case VENDOR_CC_TPM_MODE: case VENDOR_CC_SN_SET_HASH: case VENDOR_CC_SN_INC_RMA: + case VENDOR_CC_ENDORSEMENT_SEED: #endif /* defined(CR50_DEV) */ case EXTENSION_POST_RESET: /* Always need to reset. */ case VENDOR_CC_CCD: diff --git a/include/tpm_vendor_cmds.h b/include/tpm_vendor_cmds.h index 0e17d9d53b..5aef9ec150 100644 --- a/include/tpm_vendor_cmds.h +++ b/include/tpm_vendor_cmds.h @@ -132,6 +132,7 @@ enum vendor_cmd_cc { VENDOR_CC_U2F_ATTEST = 46, VENDOR_CC_FLOG_TIMESTAMP = 47, + VENDOR_CC_ENDORSEMENT_SEED = 48, LAST_VENDOR_COMMAND = 65535, }; |