From f80ceeb432b880ad8af8bcd1f4fa07f03ee4a8e6 Mon Sep 17 00:00:00 2001 From: Luigi Semenzato Date: Thu, 19 Mar 2015 16:45:52 -0700 Subject: [PATCH] vboot_reference: crossystem: add the "tpm_attack" command This commands reads/sets a bit in the kernel-reserved area of the vboot context nvram. The bit can also be set by the driver during execution of a TPM command, to check if the command is interrupted by a panic or power loss. Under some circumstances, this correlates with the TPM assuming it is under attack. BUG=chromium:431360 TEST=try "crossystem tpm_attack" and variations BRANCH=none Change-Id: I87215d5a0becfb5c01e0b69867a339bfe6fd0b68 Reviewed-on: https://chromium-review.googlesource.com/261339 Reviewed-by: Randall Spangler Commit-Queue: Luigi Semenzato Tested-by: Luigi Semenzato --- host/lib/crossystem.c | 22 ++++++++++++++++++++-- utility/crossystem.c | 8 ++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/host/lib/crossystem.c b/host/lib/crossystem.c index 1eef737b4f..d97effa4cc 100644 --- a/host/lib/crossystem.c +++ b/host/lib/crossystem.c @@ -65,11 +65,12 @@ static const char *fw_results[] = {"unknown", "trying", "success", "failure"}; /* Masks for kern_nv usage by kernel. */ #define KERN_NV_FWUPDATE_TRIES_MASK 0x0000000F #define KERN_NV_BLOCK_DEVMODE_FLAG 0x00000010 +#define KERN_NV_TPM_ATTACK_FLAG 0x00000020 /* If you want to use the remaining currently-unused bits in kern_nv * for something kernel-y, define a new field (the way we did for * fwupdate_tries). Don't just modify kern_nv directly, because that * makes it too easy to accidentally corrupt other sub-fields. */ -#define KERN_NV_CURRENTLY_UNUSED 0xFFFFFFE0 +#define KERN_NV_CURRENTLY_UNUSED 0xFFFFFFC0 /* Return true if the FWID starts with the specified string. */ int FwidStartsWith(const char *start) { @@ -482,6 +483,12 @@ int VbGetSystemPropertyInt(const char* name) { value &= KERN_NV_BLOCK_DEVMODE_FLAG; value = !!value; } + } else if (!strcasecmp(name,"tpm_attack")) { + value = VbGetNvStorage(VBNV_KERNEL_FIELD); + if (value != -1) { + value &= KERN_NV_TPM_ATTACK_FLAG; + value = !!value; + } } else if (!strcasecmp(name,"loc_idx")) { value = VbGetNvStorage(VBNV_LOCALIZATION_INDEX); } else if (!strcasecmp(name,"backup_nvram_request")) { @@ -626,7 +633,18 @@ int VbSetSystemPropertyInt(const char* name, int value) { return -1; kern_nv &= ~KERN_NV_BLOCK_DEVMODE_FLAG; if (value) - kern_nv |= KERN_NV_BLOCK_DEVMODE_FLAG; + kern_nv |= KERN_NV_BLOCK_DEVMODE_FLAG; + return VbSetNvStorage_WithBackup(VBNV_KERNEL_FIELD, kern_nv); + } else if (!strcasecmp(name,"tpm_attack")) { + /* This value should only be read and cleared, but we allow setting it to 1 + * for testing. + */ + int kern_nv = VbGetNvStorage(VBNV_KERNEL_FIELD); + if (kern_nv == -1) + return -1; + kern_nv &= ~KERN_NV_TPM_ATTACK_FLAG; + if (value) + kern_nv |= KERN_NV_TPM_ATTACK_FLAG; return VbSetNvStorage_WithBackup(VBNV_KERNEL_FIELD, kern_nv); } else if (!strcasecmp(name,"loc_idx")) { return VbSetNvStorage_WithBackup(VBNV_LOCALIZATION_INDEX, value); diff --git a/utility/crossystem.c b/utility/crossystem.c index adc828d7d5..3eaeaae066 100644 --- a/utility/crossystem.c +++ b/utility/crossystem.c @@ -85,6 +85,7 @@ const Param sys_param_list[] = { {"savedmem_size", 0, "RAM debug data area size in bytes"}, {"sw_wpsw_boot", 0, "Firmware write protect software setting enabled at boot"}, + {"tpm_attack", CAN_WRITE, "TPM was interrupted since this flag was cleared"}, {"tpm_fwver", 0, "Firmware version stored in TPM", "0x%08x"}, {"tpm_kernver", 0, "Kernel version stored in TPM", "0x%08x"}, {"tried_fwb", 0, "Tried firmware B before A this boot"}, @@ -291,9 +292,12 @@ int main(int argc, char* argv[]) { if (i > 1) printf(" "); /* Output params space-delimited */ - if (has_set) + if (has_set) { retval = SetParam(p, value); - else if (has_expect) + if (retval) { + fprintf(stderr, "Parameter %s is read-only\n", name); + } + } else if (has_expect) retval = CheckParam(p, value); else retval = PrintParam(p);