diff options
-rw-r--r-- | board/cr50/board.h | 1 | ||||
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | common/ccd_config.c | 28 | ||||
-rw-r--r-- | common/factory_mode.c | 94 | ||||
-rw-r--r-- | common/rma_auth.c | 76 | ||||
-rw-r--r-- | extra/usb_updater/gsctool.c | 2 | ||||
-rw-r--r-- | include/ccd_config.h | 12 | ||||
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | include/tpm_vendor_cmds.h | 6 |
9 files changed, 130 insertions, 93 deletions
diff --git a/board/cr50/board.h b/board/cr50/board.h index 36a7e32ccf..b73d628ac4 100644 --- a/board/cr50/board.h +++ b/board/cr50/board.h @@ -350,6 +350,7 @@ enum nvmem_users { #define CONFIG_BASE32 #define CONFIG_CURVE25519 #define CONFIG_RMA_AUTH +#define CONFIG_FACTORY_MODE #define CONFIG_RNG /* Dummy values to be replaced with real ones. */ diff --git a/common/build.mk b/common/build.mk index 13dbcc71de..9693029080 100644 --- a/common/build.mk +++ b/common/build.mk @@ -49,6 +49,7 @@ common-$(CONFIG_DPTF)+=dptf.o common-$(CONFIG_EXTENSION_COMMAND)+=extension.o common-$(CONFIG_EXTPOWER_GPIO)+=extpower_gpio.o common-$(CONFIG_FANS)+=fan.o pwm.o +common-$(CONFIG_FACTORY_MODE)+=factory_mode.o common-$(CONFIG_FLASH)+=flash.o common-$(CONFIG_FLASH_NVCOUNTER)+=nvcounter.o common-$(CONFIG_FLASH_NVMEM)+=nvmem.o diff --git a/common/ccd_config.c b/common/ccd_config.c index 555a0eebbb..42ab73b8c4 100644 --- a/common/ccd_config.c +++ b/common/ccd_config.c @@ -336,9 +336,9 @@ static void ccd_load_config(void) /* Use defaults if config data is not present */ if (!t) { if (board_is_first_factory_boot()) { - /* Give factory RMA access */ + /* Give factory/RMA access */ CPRINTS("CCD using factory config"); - ccd_reset_config(CCD_RESET_TEST_LAB | CCD_RESET_RMA); + ccd_reset_config(CCD_RESET_FACTORY); } else { /* Somehow we lost our config; normal defaults */ CPRINTS("CCD using default config"); @@ -442,8 +442,8 @@ int ccd_reset_config(unsigned int flags) config.version = CCD_CONFIG_VERSION; } - if (flags & CCD_RESET_RMA) { - /* Force RMA settings */ + if (flags & CCD_RESET_FACTORY) { + /* Force factory mode settings */ int i; /* Allow all capabilities all the time */ @@ -685,16 +685,16 @@ static int command_ccd_reset(int argc, char **argv) int flags = 0; if (argc > 1) { - if (!strcasecmp(argv[1], "rma")) - flags = CCD_RESET_RMA; + if (!strcasecmp(argv[1], "factory")) + flags = CCD_RESET_FACTORY; else return EC_ERROR_PARAM1; } switch (ccd_state) { case CCD_STATE_OPENED: - ccprintf("%sResetting all settings.\n", - flags & CCD_RESET_RMA ? "RMA " : ""); + ccprintf("%s settings.\n", flags & CCD_RESET_FACTORY ? + "Opening factory " : "Resetting all"); /* Note that this does not reset the testlab flag */ return ccd_reset_config(flags); @@ -1115,7 +1115,7 @@ static int command_ccd_help(void) "\tSet capability to state\n\n" "password [<new password> | clear]\n" "\tSet or clear CCD password\n\n" - "reset [rma]\n" + "reset [factory]\n" "\tReset CCD config\n\n" "testlab [enable | disable | open]\n" "\tToggle testlab mode or force CCD open\n\n"); @@ -1512,10 +1512,10 @@ static enum vendor_cmd_rc ccd_vendor(enum vendor_cmd_cc code, } DECLARE_VENDOR_COMMAND(VENDOR_CC_CCD, ccd_vendor); -static enum vendor_cmd_rc ccd_disable_rma(enum vendor_cmd_cc code, - void *buf, - size_t input_size, - size_t *response_size) +static enum vendor_cmd_rc ccd_disable_factory_mode(enum vendor_cmd_cc code, + void *buf, + size_t input_size, + size_t *response_size) { int rv; int error_line; @@ -1573,4 +1573,4 @@ static enum vendor_cmd_rc ccd_disable_rma(enum vendor_cmd_cc code, *response_size = 1; return VENDOR_RC_INTERNAL_ERROR; } -DECLARE_VENDOR_COMMAND(VENDOR_CC_DISABLE_RMA, ccd_disable_rma); +DECLARE_VENDOR_COMMAND(VENDOR_CC_DISABLE_FACTORY, ccd_disable_factory_mode); diff --git a/common/factory_mode.c b/common/factory_mode.c new file mode 100644 index 0000000000..b33a0619e5 --- /dev/null +++ b/common/factory_mode.c @@ -0,0 +1,94 @@ +/* Copyright 2018 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/* CCD factory enable */ + +#include "ccd_config.h" +#include "console.h" +#include "extension.h" +#include "hooks.h" +#include "system.h" +#include "tpm_registers.h" +#include "tpm_vendor_cmds.h" + +#define CPRINTS(format, args...) cprints(CC_CCD, format, ## args) + +static uint8_t ccd_hook_active; + +static void ccd_config_changed(void) +{ + if (!ccd_hook_active) + return; + + CPRINTS("%s: saved, rebooting\n", __func__); + cflush(); + system_reset(SYSTEM_RESET_HARD); +} +DECLARE_HOOK(HOOK_CCD_CHANGE, ccd_config_changed, HOOK_PRIO_LAST); + +static void factory_enable_failed(void) +{ + ccd_hook_active = 0; + CPRINTS("factory enable failed"); + deassert_ec_rst(); +} +DECLARE_DEFERRED(factory_enable_failed); + +/* The below time constants are way longer than should be required in practice: + * + * Time it takes to finish processing TPM command + */ +#define TPM_PROCESSING_TIME (1 * SECOND) + +/* + * Time it takse TPM reset function to wipe out the NVMEM and reboot the + * device. + */ +#define TPM_RESET_TIME (10 * SECOND) + +/* Total time deep sleep should not be allowed. */ +#define DISABLE_SLEEP_TIME (TPM_PROCESSING_TIME + TPM_RESET_TIME) + +static void factory_enable_deferred(void) +{ + int rv; + + CPRINTS("%s: reset TPM\n", __func__); + + /* + * Let's make sure the rest of the system is out of the way while TPM + * is being wiped out. + */ + assert_ec_rst(); + + if (tpm_reset_request(1, 1) != EC_SUCCESS) { + CPRINTS("%s: TPM reset failed\n", __func__); + deassert_ec_rst(); + return; + } + + tpm_reinstate_nvmem_commits(); + + CPRINTS("%s: TPM reset done, enabling factory mode\n", __func__); + + ccd_hook_active = 1; + rv = ccd_reset_config(CCD_RESET_FACTORY); + if (rv != EC_SUCCESS) + factory_enable_failed(); + + /* + * Make sure we never end up with the EC held in reset, no matter what + * prevents the proper factory reset flow from succeeding. + */ + hook_call_deferred(&factory_enable_failed_data, TPM_RESET_TIME); +} +DECLARE_DEFERRED(factory_enable_deferred); + +void enable_ccd_factory_mode(void) +{ + delay_sleep_by(DISABLE_SLEEP_TIME); + hook_call_deferred(&factory_enable_deferred_data, + TPM_PROCESSING_TIME); +} diff --git a/common/rma_auth.c b/common/rma_auth.c index 2bb5550e9d..39a74b8b7a 100644 --- a/common/rma_auth.c +++ b/common/rma_auth.c @@ -226,79 +226,6 @@ static enum vendor_cmd_rc get_challenge(uint8_t *buf, size_t *buf_size) return VENDOR_RC_SUCCESS; } - -static uint8_t ccd_hook_active; - -static void ccd_config_changed(void) -{ - if (!ccd_hook_active) - return; - - CPRINTF("%s: CCD change saved, rebooting\n", __func__); - cflush(); - system_reset(SYSTEM_RESET_HARD); -} -DECLARE_HOOK(HOOK_CCD_CHANGE, ccd_config_changed, HOOK_PRIO_LAST); - -static void rma_reset_failed(void) -{ - ccd_hook_active = 0; - CPRINTF("%s: CCD RMA reset failed\n"); - deassert_ec_rst(); -} -DECLARE_DEFERRED(rma_reset_failed); - -/* The below time constants are way longer than should be required in practice: - * - * Time it takes to finish processing TPM command which provided valid RMA - * authentication code. - */ -#define TPM_PROCESSING_TIME (1 * SECOND) - -/* - * Time it takse TPM reset function to wipe out the NVMEM and reboot the - * device. - */ -#define TPM_RESET_TIME (10 * SECOND) - -/* Total time deep sleep should not be allowed. */ -#define DISABLE_SLEEP_TIME (TPM_PROCESSING_TIME + TPM_RESET_TIME) - -static void enter_rma_mode(void) -{ - int rv; - - CPRINTF("%s: resetting TPM\n", __func__); - - /* - * Let's make sure the rest of the system is out of the way while TPM - * is being wiped out. - */ - assert_ec_rst(); - - if (tpm_reset_request(1, 1) != EC_SUCCESS) { - CPRINTF("%s: TPM reset attempt failed\n", __func__); - deassert_ec_rst(); - return; - } - - tpm_reinstate_nvmem_commits(); - - CPRINTF("%s: TPM reset succeeded, RMA resetting CCD\n", __func__); - - ccd_hook_active = 1; - rv = ccd_reset_config(CCD_RESET_RMA); - if (rv != EC_SUCCESS) - rma_reset_failed(); - - /* - * Make sure we never end up with the EC held in reset, no matter what - * prevents the proper RMA flow from succeeding. - */ - hook_call_deferred(&rma_reset_failed_data, TPM_RESET_TIME); -} -DECLARE_DEFERRED(enter_rma_mode); - /* * Compare response sent by the operator with the pre-compiled auth code. * Return error code or success depending on the comparison results. @@ -323,8 +250,7 @@ static enum vendor_cmd_rc process_response(uint8_t *buf, if (rv == EC_SUCCESS) { CPRINTF("%s: success!\n", __func__); *response_size = 0; - delay_sleep_by(DISABLE_SLEEP_TIME); - hook_call_deferred(&enter_rma_mode_data, TPM_PROCESSING_TIME); + enable_ccd_factory_mode(); return VENDOR_RC_SUCCESS; } diff --git a/extra/usb_updater/gsctool.c b/extra/usb_updater/gsctool.c index 2932ab5f56..213472ca22 100644 --- a/extra/usb_updater/gsctool.c +++ b/extra/usb_updater/gsctool.c @@ -1869,7 +1869,7 @@ static void process_rma(struct transfer_descriptor *td, const char *authcode) if (!strcmp(authcode, "disable")) { printf("Disabling RMA mode\n"); - send_vendor_command(td, VENDOR_CC_DISABLE_RMA, NULL, 0, + send_vendor_command(td, VENDOR_CC_DISABLE_FACTORY, NULL, 0, rma_response, &response_size); if (response_size) { fprintf(stderr, "Failed disabling RMA, error %d\n", diff --git a/include/ccd_config.h b/include/ccd_config.h index a71db37bba..7153449883 100644 --- a/include/ccd_config.h +++ b/include/ccd_config.h @@ -254,8 +254,11 @@ enum ccd_reset_config_flags { /* Only reset Always/UnlessLocked settings */ CCD_RESET_UNLOCKED_ONLY = (1 << 1), - /* Use RMA/factory defaults */ - CCD_RESET_RMA = (1 << 2) + /* + * Do a factory reset to enable factory mode. Factory mode sets all ccd + * capabilities to always and disables write protect + */ + CCD_RESET_FACTORY = (1 << 2) }; /** @@ -272,4 +275,9 @@ int ccd_reset_config(unsigned int flags); */ void ccd_tpm_reset_callback(void); +/** + * Enter CCD factory mode. This will clear the TPM and do a hard reboot after + * updating the ccd config. + */ +void enable_ccd_factory_mode(void); #endif /* __CROS_EC_CCD_CONFIG_H */ diff --git a/include/config.h b/include/config.h index bf91e4d55c..d110e6603d 100644 --- a/include/config.h +++ b/include/config.h @@ -1068,6 +1068,9 @@ /* Default debounce time for external power signal */ #define CONFIG_EXTPOWER_DEBOUNCE_MS 30 +/* Add support for CCD factory mode */ +#undef CONFIG_FACTORY_MODE + /*****************************************************************************/ /* Number of cooling fans. Undef if none. */ #undef CONFIG_FANS diff --git a/include/tpm_vendor_cmds.h b/include/tpm_vendor_cmds.h index 2d460badfa..92530c502a 100644 --- a/include/tpm_vendor_cmds.h +++ b/include/tpm_vendor_cmds.h @@ -49,7 +49,11 @@ enum vendor_cmd_cc { /* A gap left for the no longer supported CCD password command. */ - VENDOR_CC_DISABLE_RMA = 32, + /* + * Disable factory mode. Reset all ccd capabilities to default and reset + * write protect to follow battery presence. + */ + VENDOR_CC_DISABLE_FACTORY = 32, VENDOR_CC_MANAGE_CCD_PWD = 33, VENDOR_CC_CCD = 34, VENDOR_CC_GET_ALERTS_DATA = 35, |