aboutsummaryrefslogtreecommitdiff
path: root/src/security/vboot
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2021-05-24 17:04:38 -0700
committerJulius Werner <jwerner@chromium.org>2021-06-10 23:38:53 +0000
commit08938a9be3fd5f02650926f87d00d0029fafc3c2 (patch)
tree987be1e8f7d52f3b5231892e31f3c75c70e66246 /src/security/vboot
parent4ad0420e82f46b2d92e318019a89842f28e6c08a (diff)
security/vboot: Add support for ZTE spaces
This commit adds support for the Chrome OS Zero-Touch Enrollment related spaces. For TPM 2.0 devices which don't use Cr50, coreboot will define the RMA+SN Bits, Board ID, and RMA Bytes counter spaces. The RMA+SN Bits space is 16 bytes initialized to all 0xFFs. The Board ID space is 12 bytes initialized to all 0xFFs. The RMA Bytes counter space is 8 bytes intialized to 0. BUG=b:184676425 BRANCH=None TEST=Build and flash lalala, verify that the ZTE spaces are created successfully by undefining the firmware antirollback space in the TPM such that the TPM undergoes factory initialization in coreboot. Reboot the DUT. Boot to CrOS and run `tpm_manager_client list_spaces` and verify that the ZTE spaces are listed. Run `tpm_manager_client read_space` with the various indices and verify that the sizes and initial values of the spaces are correct. TEST=Attempt to undefine the ZTE spaces and verify that it fails due to the unsatisfiable policy. Signed-off-by: Aseda Aboagye <aaboagye@google.com> Change-Id: I97e3ae7e18fc9ee9a02afadbbafeb226b41af0eb Reviewed-on: https://review.coreboot.org/c/coreboot/+/55242 Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/security/vboot')
-rw-r--r--src/security/vboot/antirollback.h4
-rw-r--r--src/security/vboot/secdata_tpm.c122
2 files changed, 118 insertions, 8 deletions
diff --git a/src/security/vboot/antirollback.h b/src/security/vboot/antirollback.h
index fcfa7a270c..a208c04610 100644
--- a/src/security/vboot/antirollback.h
+++ b/src/security/vboot/antirollback.h
@@ -28,6 +28,10 @@ enum vb2_pcr_digest;
/* 0x100d: Hash of MRC_CACHE training data for non-recovery boot */
#define MRC_RW_HASH_NV_INDEX 0x100d
#define HASH_NV_SIZE VB2_SHA256_DIGEST_SIZE
+/* Zero-Touch Enrollment related spaces */
+#define ZTE_BOARD_ID_NV_INDEX 0x3fff00
+#define ZTE_RMA_SN_BITS_INDEX 0x3fff01
+#define ZTE_RMA_BYTES_COUNTER_INDEX 0x3fff04
/* Structure definitions for TPM spaces */
diff --git a/src/security/vboot/secdata_tpm.c b/src/security/vboot/secdata_tpm.c
index dd367964cc..bedead7a81 100644
--- a/src/security/vboot/secdata_tpm.c
+++ b/src/security/vboot/secdata_tpm.c
@@ -117,6 +117,29 @@ static const TPMA_NV fwmp_attr = {
.TPMA_NV_PPWRITE = 1,
};
+/* Attributes for spaces that enable zero-touch enrollment (ZTE) */
+static const TPMA_NV zte_attr = {
+ .TPMA_NV_PLATFORMCREATE = 1,
+ .TPMA_NV_WRITEDEFINE = 1,
+ .TPMA_NV_AUTHWRITE = 1,
+ .TPMA_NV_AUTHREAD = 1,
+ .TPMA_NV_PPWRITE = 1,
+ .TPMA_NV_PPREAD = 1,
+ .TPMA_NV_NO_DA = 1,
+ .TPMA_NV_POLICY_DELETE = 1,
+};
+
+static const TPMA_NV zte_rma_bytes_attr = {
+ .TPMA_NV_PLATFORMCREATE = 1,
+ .TPMA_NV_BITS = 1,
+ .TPMA_NV_AUTHWRITE = 1,
+ .TPMA_NV_AUTHREAD = 1,
+ .TPMA_NV_PPWRITE = 1,
+ .TPMA_NV_PPREAD = 1,
+ .TPMA_NV_NO_DA = 1,
+ .TPMA_NV_POLICY_DELETE = 1,
+};
+
/*
* This policy digest was obtained using TPM2_PolicyOR on 3 digests
* corresponding to a sequence of
@@ -154,15 +177,12 @@ static const uint8_t pcr0_allowed_policy[] = {
0x50, 0xEF, 0x96, 0x98, 0x0A, 0x2B, 0x96, 0x6E, 0xA9, 0x09, 0x04,
0x4A, 0x01, 0xB8, 0x5F, 0xA5, 0x4A, 0x96, 0xFC, 0x59, 0x84};
-/* Nothing special in the TPM2 path yet. */
-static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
-{
- return tlcl_write(index, data, length);
-}
+static const uint8_t unsatisfiable_policy[VB2_SHA256_DIGEST_SIZE] =
+ "hmwhat if RBR beat merc in 2021";
-static uint32_t setup_space(const char *name, uint32_t index, const void *data,
- uint32_t length, const TPMA_NV nv_attributes,
- const uint8_t *nv_policy, size_t nv_policy_size)
+static uint32_t define_space(const char *name, uint32_t index, uint32_t length,
+ const TPMA_NV nv_attributes,
+ const uint8_t *nv_policy, size_t nv_policy_size)
{
uint32_t rv;
@@ -181,6 +201,23 @@ static uint32_t setup_space(const char *name, uint32_t index, const void *data,
rv = TPM_SUCCESS;
}
+ return rv;
+}
+
+/* Nothing special in the TPM2 path yet. */
+static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
+{
+ return tlcl_write(index, data, length);
+}
+
+static uint32_t setup_space(const char *name, uint32_t index, const void *data,
+ uint32_t length, const TPMA_NV nv_attributes,
+ const uint8_t *nv_policy, size_t nv_policy_size)
+{
+ uint32_t rv;
+
+ rv = define_space(name, index, length, nv_attributes, nv_policy,
+ nv_policy_size);
if (rv != TPM_SUCCESS)
return rv;
@@ -225,6 +262,67 @@ static uint32_t set_mrc_hash_space(uint32_t index, const uint8_t *data)
}
}
+/**
+ * Set up the Zero-Touch Enrollment(ZTE) related spaces.
+ *
+ * These spaces are not used by firmware, but we do need to initialize them.
+ */
+static uint32_t setup_zte_spaces(void)
+{
+ uint32_t rv;
+ uint64_t rma_bytes_counter_default = 0;
+ uint8_t rma_sn_bits_default[16];
+ uint8_t board_id_default[12];
+
+ /* Initialize defaults: Board ID and RMA+SN Bits must be initialized
+ to all 0xFFs. */
+ memset(rma_sn_bits_default, 0xFF, ARRAY_SIZE(rma_sn_bits_default));
+ memset(board_id_default, 0xFF, ARRAY_SIZE(board_id_default));
+
+ /* Set up RMA + SN Bits */
+ rv = setup_space("RMA + SN Bits", ZTE_RMA_SN_BITS_INDEX,
+ rma_sn_bits_default, sizeof(rma_sn_bits_default),
+ zte_attr,
+ unsatisfiable_policy, sizeof(unsatisfiable_policy));
+ if (rv != TPM_SUCCESS) {
+ VBDEBUG("%s: Failed to set up RMA + SN Bits space\n", __func__);
+ return rv;
+ }
+
+ rv = setup_space("Board ID", ZTE_BOARD_ID_NV_INDEX,
+ board_id_default, sizeof(board_id_default),
+ zte_attr,
+ unsatisfiable_policy, sizeof(unsatisfiable_policy));
+ if (rv != TPM_SUCCESS) {
+ VBDEBUG("%s: Failed to set up Board ID space\n", __func__);
+ return rv;
+ }
+
+ /* Set up RMA Bytes counter */
+ rv = define_space("RMA Bytes Counter", ZTE_RMA_BYTES_COUNTER_INDEX,
+ sizeof(rma_bytes_counter_default),
+ zte_rma_bytes_attr,
+ unsatisfiable_policy, sizeof(unsatisfiable_policy));
+ if (rv != TPM_SUCCESS) {
+ VBDEBUG("%s: Failed to define RMA Bytes space\n", __func__);
+ return rv;
+ }
+
+ /*
+ * Since the RMA counter has the BITS attribute, we need to call
+ * TPM2_NV_SetBits() in order to initialize it.
+ */
+ rv = tlcl_set_bits(ZTE_RMA_BYTES_COUNTER_INDEX,
+ rma_bytes_counter_default);
+ if (rv != TPM_SUCCESS) {
+ VBDEBUG("%s: Failed to init RMA Bytes counter space\n",
+ __func__);
+ return rv;
+ }
+
+ return rv;
+}
+
static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
{
RETURN_ON_FAILURE(tlcl_force_clear());
@@ -250,6 +348,14 @@ static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
/* Define and write firmware management parameters space. */
RETURN_ON_FAILURE(setup_fwmp_space(ctx));
+ /*
+ * Define and write zero-touch enrollment (ZTE) spaces. For Cr50 devices,
+ * these are set up elsewhere via TPM vendor commands.
+ */
+ if (CONFIG(CHROMEOS) && (!(CONFIG(MAINBOARD_HAS_SPI_TPM_CR50) ||
+ CONFIG(MAINBOARD_HAS_I2C_TPM_CR50))))
+ RETURN_ON_FAILURE(setup_zte_spaces());
+
RETURN_ON_FAILURE(setup_firmware_space(ctx));
return TPM_SUCCESS;