summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/security/tpm/tss.h5
-rw-r--r--src/security/tpm/tss/tcg-1.2/tss.c19
-rw-r--r--src/security/vboot/secdata_tpm.c22
3 files changed, 46 insertions, 0 deletions
diff --git a/src/security/tpm/tss.h b/src/security/tpm/tss.h
index 5237387a74..57f3b24847 100644
--- a/src/security/tpm/tss.h
+++ b/src/security/tpm/tss.h
@@ -197,4 +197,9 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
*/
uint32_t tlcl_disable_platform_hierarchy(void);
+/**
+ * Get the permission bits for the NVRAM space with |index|.
+ */
+uint32_t tlcl_get_permissions(uint32_t index, uint32_t *permissions);
+
#endif /* TSS_H_ */
diff --git a/src/security/tpm/tss/tcg-1.2/tss.c b/src/security/tpm/tss/tcg-1.2/tss.c
index 9bc72d2733..ea3f94d5f8 100644
--- a/src/security/tpm/tss/tcg-1.2/tss.c
+++ b/src/security/tpm/tss/tcg-1.2/tss.c
@@ -359,3 +359,22 @@ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
kPcrDigestLength);
return result;
}
+
+uint32_t tlcl_get_permissions(uint32_t index, uint32_t *permissions)
+{
+ struct s_tpm_getpermissions_cmd cmd;
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+ uint8_t *nvdata;
+ uint32_t result;
+ uint32_t size;
+
+ memcpy(&cmd, &tpm_getpermissions_cmd, sizeof(cmd));
+ to_tpm_uint32(cmd.buffer + tpm_getpermissions_cmd.index, index);
+ result = tlcl_send_receive(cmd.buffer, response, sizeof(response));
+ if (result != TPM_SUCCESS)
+ return result;
+
+ nvdata = response + kTpmResponseHeaderLength + sizeof(size);
+ from_tpm_uint32(nvdata + kNvDataPublicPermissionsOffset, permissions);
+ return result;
+}
diff --git a/src/security/vboot/secdata_tpm.c b/src/security/vboot/secdata_tpm.c
index d666ae8a5e..37665bc23d 100644
--- a/src/security/vboot/secdata_tpm.c
+++ b/src/security/vboot/secdata_tpm.c
@@ -36,6 +36,8 @@
#include <security/vboot/tpm_common.h>
#include <string.h>
#include <security/tpm/tspi.h>
+#include <security/tpm/tss.h>
+#include <security/tpm/tss/tcg-1.2/tss_structures.h>
#include <vb2_api.h>
#include <console/console.h>
@@ -68,6 +70,26 @@ static uint32_t read_space_firmware(struct vb2_context *ctx)
uint32_t antirollback_read_space_kernel(struct vb2_context *ctx)
{
+ if (!CONFIG(TPM2)) {
+ /*
+ * Before reading the kernel space, verify its permissions. If
+ * the kernel space has the wrong permission, we give up. This
+ * will need to be fixed by the recovery kernel. We will have
+ * to worry about this because at any time (even with PP turned
+ * off) the TPM owner can remove and redefine a PP-protected
+ * space (but not write to it).
+ */
+ uint32_t perms;
+
+ RETURN_ON_FAILURE(tlcl_get_permissions(KERNEL_NV_INDEX,
+ &perms));
+ if (perms != TPM_NV_PER_PPWRITE) {
+ printk(BIOS_ERR,
+ "TPM: invalid secdata_kernel permissions\n");
+ return TPM_E_CORRUPTED_STATE;
+ }
+ }
+
uint8_t size = VB2_SECDATA_KERNEL_MIN_SIZE;
RETURN_ON_FAILURE(tlcl_read(KERNEL_NV_INDEX, ctx->secdata_kernel,