summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMary Ruthven <mruthven@google.com>2018-05-21 13:03:44 -0700
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2019-01-22 17:55:32 +0000
commit7005f8d29c5153256c49107ecaf30dcc07c255ec (patch)
tree80d261858ae9f638f9ebf1e4c23ae65e3e3eec9e
parent845e87bcd4a1965a465e5eb3564e91813d77235b (diff)
downloadchrome-ec-7005f8d29c5153256c49107ecaf30dcc07c255ec.tar.gz
cr50: add command for factory reset
The factory reset command can be used to enable ccd factory mode. The command can open ccd if write protect is removed and ccd hasn't been restricted. Right now we check FWMP and the ccd password before allowing factory reset. Factory reset cannot be used to get around anything that disables ccd. This adds 72 bytes. BUG=b:77543904,b/123000167 BRANCH=cr50 TEST=Try enabling factory mode using factory reset. Verify setting write protect, setting the FWMP disable ccd bit, or setting a ccd password prevents factory reset from enabling factory mode. Change-Id: I6e203bf6068250f009881aa95c13bc56cb2aa9e7 Signed-off-by: Mary Ruthven <mruthven@google.com> Reviewed-on: https://chromium-review.googlesource.com/1069369 Commit-Ready: Mary Ruthven <mruthven@chromium.org> Tested-by: Mary Ruthven <mruthven@chromium.org> Reviewed-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/1422661 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--board/cr50/factory_mode.c42
-rw-r--r--common/ccd_config.c5
-rw-r--r--include/ccd_config.h9
-rw-r--r--include/tpm_vendor_cmds.h8
4 files changed, 64 insertions, 0 deletions
diff --git a/board/cr50/factory_mode.c b/board/cr50/factory_mode.c
index c8a5dd2cdd..22d028d4ee 100644
--- a/board/cr50/factory_mode.c
+++ b/board/cr50/factory_mode.c
@@ -5,6 +5,8 @@
#include "board_id.h"
#include "console.h"
+#include "ccd_config.h"
+#include "extension.h"
#include "system.h"
#define CPRINTS(format, args...) cprints(CC_CCD, format, ## args)
@@ -75,3 +77,43 @@ int board_is_first_factory_boot(void)
return (!(system_get_reset_flags() & RESET_FLAG_HIBERNATE) &&
inactive_image_is_guc_image() && board_id_is_erased());
}
+
+/*
+ * Vendor command for ccd factory reset.
+ *
+ * This vendor command can be used to enable ccd and disable write protect with
+ * a factory reset. A factory reset is automatically done during the first
+ * factory boot, but this vendor command can be used to do a factory reset at
+ * any time. Before calling factory reset, cr50 will make sure it is safe to do
+ * so. Cr50 checks batt_is_present to make sure the user has physical access to
+ * the device. Cr50 also checks ccd isn't disabled by the FWMP or ccd password.
+ *
+ * checks:
+ * - batt_is_present - Factory reset can only be done if HW write protect is
+ * removed.
+ * - FWMP disables ccd - If FWMP has disabled ccd, then we can't bypass it with
+ * a factory reset.
+ * - CCD password is set - If there is a password, someone will have to use that
+ * to open ccd and enable ccd manually. A factory reset cannot be
+ * used to get around the password.
+ */
+static enum vendor_cmd_rc vc_factory_reset(enum vendor_cmd_cc code,
+ void *buf,
+ size_t input_size,
+ size_t *response_size)
+{
+ *response_size = 0;
+
+ if (input_size)
+ return VENDOR_RC_BOGUS_ARGS;
+
+ if (board_battery_is_present() || !board_fwmp_allows_unlock() ||
+ ccd_has_password())
+ return VENDOR_RC_NOT_ALLOWED;
+
+ CPRINTF("factory reset\n");
+ enable_ccd_factory_mode();
+
+ return VENDOR_RC_SUCCESS;
+}
+DECLARE_VENDOR_COMMAND(VENDOR_CC_RESET_FACTORY, vc_factory_reset);
diff --git a/common/ccd_config.c b/common/ccd_config.c
index c356d0a04e..a3d419356c 100644
--- a/common/ccd_config.c
+++ b/common/ccd_config.c
@@ -581,6 +581,11 @@ static void ccd_testlab_toggle(void)
/******************************************************************************/
/* External interface */
+int ccd_has_password(void)
+{
+ return raw_has_password();
+}
+
void ccd_config_init(enum ccd_state state)
{
/* Set initial state, after making sure it's a valid one */
diff --git a/include/ccd_config.h b/include/ccd_config.h
index 7153449883..240feb5240 100644
--- a/include/ccd_config.h
+++ b/include/ccd_config.h
@@ -276,6 +276,15 @@ int ccd_reset_config(unsigned int flags);
void ccd_tpm_reset_callback(void);
/**
+ * Return True if the ccd password is set. It is possible that a pending ccd
+ * change would set or clear the password, but we don't think this is a big
+ * issue or risk for now.
+ *
+ * @return 1 if password is set, 0 if it's not
+ */
+int ccd_has_password(void);
+
+/**
* Enter CCD factory mode. This will clear the TPM and do a hard reboot after
* updating the ccd config.
*/
diff --git a/include/tpm_vendor_cmds.h b/include/tpm_vendor_cmds.h
index 58bb669d4a..b6b32c3ef7 100644
--- a/include/tpm_vendor_cmds.h
+++ b/include/tpm_vendor_cmds.h
@@ -55,6 +55,14 @@ enum vendor_cmd_cc {
VENDOR_CC_GET_ALERTS_DATA = 35,
VENDOR_CC_SPI_HASH = 36,
VENDOR_CC_PINWEAVER = 37,
+ /*
+ * Check the factory reset settings. If they're all set correctly, do a
+ * factory reset to enable ccd factory mode. All capabilities will be
+ * set to Always and write protect will be permanently disabled. This
+ * mode can't be reset unless VENDOR_CC_DISABLE_FACTORY is called or
+ * the 'ccd reset' console command is run.
+ */
+ VENDOR_CC_RESET_FACTORY = 38,
LAST_VENDOR_COMMAND = 65535,
};