Add clear TPM owner request
This adds two new flags to crossystem:
clear_tpm_owner_request
clear_tpm_owner_done
The first one requests that the firmware clear the TPM owner on the
next boot. When the firmware does this, it will set
clear_tpm_owner_request=0, and set clear_tpm_owner_done=1. The OS can
use the done-flag as a hint that trusted things guarded by the TPM are
no longer trustable.
BUG=chromium-os:31974
TEST=manual
crossystem
// both flags initially 0
crossystem clear_tpm_owner_request=1
crossystem clear_tpm_owner_done=1
// request=1, done=0; done can be cleared but not set by crossystem
reboot
tpmc getownership
// owned=no
crossystem
// request=0, done=1
crossystem clear_tpm_owner_done=0
crossystem
// both flags 0 again
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Change-Id: I49f83f3c39c3efc3945116c51a241d255c2e42cd
Reviewed-on: https://gerrit.chromium.org/gerrit/25646
diff --git a/firmware/include/vboot_nvstorage.h b/firmware/include/vboot_nvstorage.h
index fbc847f..8748a5c 100644
--- a/firmware/include/vboot_nvstorage.h
+++ b/firmware/include/vboot_nvstorage.h
@@ -57,6 +57,10 @@
/* Set and cleared by vboot to request that the video Option ROM be loaded at
* boot time, so that BIOS screens can be displayed. 0=no, 1=yes. */
VBNV_OPROM_NEEDED,
+ /* Request that the firmware clear the TPM owner on the next boot. */
+ VBNV_CLEAR_TPM_OWNER_REQUEST,
+ /* Flag that TPM owner was cleared on request. */
+ VBNV_CLEAR_TPM_OWNER_DONE,
} VbNvParam;
diff --git a/firmware/lib/include/rollback_index.h b/firmware/lib/include/rollback_index.h
index 20df5b3..51e6ec1 100644
--- a/firmware/lib/include/rollback_index.h
+++ b/firmware/lib/include/rollback_index.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2012 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.
*
@@ -70,6 +70,7 @@
/* This must be called. */
uint32_t RollbackFirmwareSetup(int recovery_mode, int is_hw_dev,
int disable_dev_request,
+ int clear_tpm_owner_request,
/* two outputs on success */
int *is_virt_dev, uint32_t *tpm_version);
@@ -118,7 +119,8 @@
/* SetupTPM starts the TPM and establishes the root of trust for the
* anti-rollback mechanism. */
uint32_t SetupTPM(int recovery_mode, int developer_mode,
- int disable_dev_request, RollbackSpaceFirmware* rsf);
+ int disable_dev_request, int clear_tpm_owner_request,
+ RollbackSpaceFirmware* rsf);
/* Utility function to turn the virtual dev-mode flag on or off. 0=off, 1=on */
uint32_t SetVirtualDevMode(int val);
diff --git a/firmware/lib/mocked_rollback_index.c b/firmware/lib/mocked_rollback_index.c
index f60e2f2..65dfd4d 100644
--- a/firmware/lib/mocked_rollback_index.c
+++ b/firmware/lib/mocked_rollback_index.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2012 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.
*
@@ -22,7 +22,8 @@
uint32_t SetupTPM(int recovery_mode, int developer_mode,
- int disable_dev_request, RollbackSpaceFirmware* rsf) {
+ int disable_dev_request, int clear_tpm_owner_request,
+ RollbackSpaceFirmware* rsf) {
return TPM_SUCCESS;
}
@@ -34,6 +35,7 @@
uint32_t RollbackFirmwareSetup(int recovery_mode, int is_hw_dev,
int disable_dev_request,
+ int clear_tpm_owner_request,
int *is_virt_dev, uint32_t *version) {
*version = 0;
return TPM_SUCCESS;
diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c
index 668312e..a5bc6ae 100644
--- a/firmware/lib/rollback_index.c
+++ b/firmware/lib/rollback_index.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2012 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.
*
@@ -298,7 +298,8 @@
* the durability of the NVRAM.
*/
uint32_t SetupTPM(int recovery_mode, int developer_mode,
- int disable_dev_request, RollbackSpaceFirmware* rsf) {
+ int disable_dev_request, int clear_tpm_owner_request,
+ RollbackSpaceFirmware* rsf) {
uint8_t in_flags;
uint8_t disable;
@@ -398,11 +399,15 @@
if (rsf->flags & FLAG_VIRTUAL_DEV_MODE_ON)
developer_mode = 1;
- /* Clears ownership if developer flag has toggled */
+ /* Clears ownership if developer flag has toggled, or if an owner-clear has
+ * been requested. */
if ((developer_mode ? FLAG_LAST_BOOT_DEVELOPER : 0) !=
(in_flags & FLAG_LAST_BOOT_DEVELOPER)) {
VBDEBUG(("TPM: Developer flag changed; clearing owner.\n"));
RETURN_ON_FAILURE(TPMClearAndReenable());
+ } else if (clear_tpm_owner_request) {
+ VBDEBUG(("TPM: Clearing owner as specifically requested.\n"));
+ RETURN_ON_FAILURE(TPMClearAndReenable());
}
if (developer_mode)
@@ -441,6 +446,7 @@
uint32_t RollbackFirmwareSetup(int recovery_mode, int is_hw_dev,
int disable_dev_request,
+ int clear_tpm_owner_request,
int *is_virt_dev, uint32_t *version) {
#ifndef CHROMEOS_ENVIRONMENT
/* Initialize the TPM, but ignores return codes. In ChromeOS
@@ -495,14 +501,15 @@
uint32_t RollbackFirmwareSetup(int recovery_mode, int is_hw_dev,
int disable_dev_request,
+ int clear_tpm_owner_request,
int *is_virt_dev, uint32_t *version) {
RollbackSpaceFirmware rsf;
/* Set version to 0 in case we fail */
*version = 0;
- RETURN_ON_FAILURE(SetupTPM(recovery_mode, is_hw_dev,
- disable_dev_request, &rsf));
+ RETURN_ON_FAILURE(SetupTPM(recovery_mode, is_hw_dev, disable_dev_request,
+ clear_tpm_owner_request, &rsf));
*version = rsf.fw_versions;
*is_virt_dev = (rsf.flags & FLAG_VIRTUAL_DEV_MODE_ON) ? 1 : 0;
VBDEBUG(("TPM: RollbackFirmwareSetup %x\n", (int)rsf.fw_versions));
diff --git a/firmware/lib/vboot_api_init.c b/firmware/lib/vboot_api_init.c
index a561890..8d1540b 100644
--- a/firmware/lib/vboot_api_init.c
+++ b/firmware/lib/vboot_api_init.c
@@ -29,6 +29,7 @@
int is_hw_dev = 0;
int is_virt_dev = 0;
uint32_t disable_dev_request = 0;
+ uint32_t clear_tpm_owner_request = 0;
int is_dev = 0;
VBDEBUG(("VbInit() input flags 0x%x\n", iparams->flags));
@@ -136,12 +137,16 @@
if (gbb->flags & GBB_FLAG_FORCE_DEV_SWITCH_ON)
is_hw_dev = 1;
+ /* Check if we've been explicitly asked to clear the TPM owner */
+ VbNvGet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, &clear_tpm_owner_request);
+
VBPERFSTART("VB_TPMI");
/* Initialize the TPM. If the developer mode state has changed since the
* last boot, we need to clear TPM ownership. If the TPM space is
* initialized by this call, the virtual dev-switch will be disabled by
* default) */
tpm_status = RollbackFirmwareSetup(recovery, is_hw_dev, disable_dev_request,
+ clear_tpm_owner_request,
/* two outputs on success */
&is_virt_dev, &tpm_version);
VBPERFEND("VB_TPMI");
@@ -180,6 +185,10 @@
}
if (disable_dev_request && !is_virt_dev)
VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST, 0);
+ if (clear_tpm_owner_request) {
+ VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, 0);
+ VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_DONE, 1);
+ }
}
/* Allow BIOS to load arbitrary option ROMs? */
diff --git a/firmware/lib/vboot_nvstorage.c b/firmware/lib/vboot_nvstorage.c
index bde0b40..0f4633b 100644
--- a/firmware/lib/vboot_nvstorage.c
+++ b/firmware/lib/vboot_nvstorage.c
@@ -33,6 +33,10 @@
#define DEV_BOOT_USB_MASK 0x01
#define DEV_BOOT_SIGNED_ONLY_MASK 0x02
+#define TPM_FLAGS_OFFSET 5
+#define TPM_CLEAR_OWNER_REQUEST 0x01
+#define TPM_CLEAR_OWNER_DONE 0x02
+
#define KERNEL_FIELD_OFFSET 11
#define CRC_OFFSET 15
@@ -124,6 +128,14 @@
*dest = (raw[BOOT_OFFSET] & BOOT_OPROM_NEEDED ? 1 : 0);
return 0;
+ case VBNV_CLEAR_TPM_OWNER_REQUEST:
+ *dest = (raw[TPM_FLAGS_OFFSET] & TPM_CLEAR_OWNER_REQUEST ? 1 : 0);
+ return 0;
+
+ case VBNV_CLEAR_TPM_OWNER_DONE:
+ *dest = (raw[TPM_FLAGS_OFFSET] & TPM_CLEAR_OWNER_DONE ? 1 : 0);
+ return 0;
+
default:
return 1;
}
@@ -219,6 +231,20 @@
raw[BOOT_OFFSET] &= ~BOOT_OPROM_NEEDED;
break;
+ case VBNV_CLEAR_TPM_OWNER_REQUEST:
+ if (value)
+ raw[TPM_FLAGS_OFFSET] |= TPM_CLEAR_OWNER_REQUEST;
+ else
+ raw[TPM_FLAGS_OFFSET] &= ~TPM_CLEAR_OWNER_REQUEST;
+ break;
+
+ case VBNV_CLEAR_TPM_OWNER_DONE:
+ if (value)
+ raw[TPM_FLAGS_OFFSET] |= TPM_CLEAR_OWNER_DONE;
+ else
+ raw[TPM_FLAGS_OFFSET] &= ~TPM_CLEAR_OWNER_DONE;
+ break;
+
default:
return 1;
}
diff --git a/firmware/linktest/main.c b/firmware/linktest/main.c
index 020b589..c5ce2c1 100644
--- a/firmware/linktest/main.c
+++ b/firmware/linktest/main.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+/* Copyright (c) 2012 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.
*/
@@ -29,7 +29,7 @@
/* rollback_index.h */
RollbackS3Resume();
- RollbackFirmwareSetup(0, 0, 0, 0, 0);
+ RollbackFirmwareSetup(0, 0, 0, 0, 0, 0);
RollbackFirmwareWrite(0);
RollbackFirmwareLock();
RollbackKernelRead(0);