mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 02:05:01 +00:00
Add physical presence initialization and locking to one-time initializations.
Change-Id: If2b6041fe93bc97885e45bbb0cf7e1b81cb06c18 BUG=none TEST=none Review URL: http://codereview.chromium.org/3229011
This commit is contained in:
@@ -98,20 +98,25 @@ static uint32_t WriteSpaceKernel(const RollbackSpaceKernel* rsk) {
|
||||
return SafeWrite(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel));
|
||||
}
|
||||
|
||||
/* Creates the NVRAM spaces, and sets their initial values as needed. */
|
||||
static uint32_t InitializeSpaces(RollbackSpaceFirmware* rsf,
|
||||
RollbackSpaceKernel* rsk) {
|
||||
/* Performs one-time initializations. Creates the NVRAM spaces, and sets their
|
||||
* initial values as needed. Sets the nvLocked bit and ensures the physical
|
||||
* presence command is enabled and locked.
|
||||
*/
|
||||
static uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware* rsf,
|
||||
RollbackSpaceKernel* rsk) {
|
||||
static const RollbackSpaceFirmware rsf_init = {
|
||||
ROLLBACK_SPACE_FIRMWARE_VERSION, 0, 0, 0};
|
||||
static const RollbackSpaceKernel rsk_init = {
|
||||
ROLLBACK_SPACE_KERNEL_VERSION, ROLLBACK_SPACE_KERNEL_UID, 0, 0};
|
||||
uint8_t nvlocked = 0;
|
||||
|
||||
VBDEBUG(("TPM: Initializing spaces\n"));
|
||||
VBDEBUG(("TPM: One-time initialization\n"));
|
||||
|
||||
RETURN_ON_FAILURE(TlclFinalizePhysicalPresence());
|
||||
|
||||
/* The TPM will not enforce the NV authorization restrictions until the
|
||||
* execution of a TPM_NV_DefineSpace with the handle of TPM_NV_INDEX_LOCK.
|
||||
* Create that space if it doesn't already exist. */
|
||||
* Here we create that space if it doesn't already exist. */
|
||||
RETURN_ON_FAILURE(TlclGetFlags(NULL, NULL, &nvlocked));
|
||||
VBDEBUG(("TPM: nvlocked=%d\n", nvlocked));
|
||||
if (!nvlocked) {
|
||||
@@ -119,11 +124,11 @@ static uint32_t InitializeSpaces(RollbackSpaceFirmware* rsf,
|
||||
RETURN_ON_FAILURE(TlclSetNvLocked());
|
||||
}
|
||||
|
||||
/* Initialize the firmware and kernel spaces */
|
||||
/* Initializes the firmware and kernel spaces */
|
||||
Memcpy(rsf, &rsf_init, sizeof(RollbackSpaceFirmware));
|
||||
Memcpy(rsk, &rsk_init, sizeof(RollbackSpaceKernel));
|
||||
|
||||
/* Define and set firmware and kernel spaces */
|
||||
/* Defines and sets firmware and kernel spaces */
|
||||
RETURN_ON_FAILURE(SafeDefineSpace(FIRMWARE_NV_INDEX,
|
||||
TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE,
|
||||
sizeof(RollbackSpaceFirmware)));
|
||||
@@ -177,9 +182,17 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode,
|
||||
#else
|
||||
RETURN_ON_FAILURE(TlclSelfTestFull());
|
||||
#endif
|
||||
RETURN_ON_FAILURE(TlclAssertPhysicalPresence());
|
||||
result = TlclAssertPhysicalPresence();
|
||||
if (result != 0) {
|
||||
/* It is possible that the TPM was delivered with the physical presence
|
||||
* command disabled. This tries enabling it, then tries asserting PP
|
||||
* again.
|
||||
*/
|
||||
RETURN_ON_FAILURE(TlclPhysicalPresenceCMDEnable());
|
||||
RETURN_ON_FAILURE(TlclAssertPhysicalPresence());
|
||||
}
|
||||
|
||||
/* Check that the TPM is enabled and activated. */
|
||||
/* Checks that the TPM is enabled and activated. */
|
||||
RETURN_ON_FAILURE(TlclGetFlags(&disable, &deactivated, NULL));
|
||||
if (disable || deactivated) {
|
||||
VBDEBUG(("TPM: disabled (%d) or deactivated (%d). Fixing...\n",
|
||||
@@ -190,15 +203,15 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode,
|
||||
return TPM_E_MUST_REBOOT;
|
||||
}
|
||||
|
||||
/* Read the firmware space. */
|
||||
/* Reads the firmware space. */
|
||||
result = ReadSpaceFirmware(rsf);
|
||||
if (TPM_E_BADINDEX == result) {
|
||||
RollbackSpaceKernel rsk;
|
||||
|
||||
/* This is the first time we've run, and the TPM has not been
|
||||
* initialized. Initialize it. */
|
||||
* initialized. This initializes it. */
|
||||
VBDEBUG(("TPM: Not initialized yet.\n"));
|
||||
RETURN_ON_FAILURE(InitializeSpaces(rsf, &rsk));
|
||||
RETURN_ON_FAILURE(OneTimeInitializeTPM(rsf, &rsk));
|
||||
} else if (TPM_SUCCESS != result) {
|
||||
VBDEBUG(("TPM: Firmware space in a bad state; giving up.\n"));
|
||||
return TPM_E_CORRUPTED_STATE;
|
||||
@@ -206,14 +219,14 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode,
|
||||
VBDEBUG(("TPM: Firmware space sv%d f%x v%x\n",
|
||||
rsf->struct_version, rsf->flags, rsf->fw_versions));
|
||||
|
||||
/* Clear ownership if developer flag has toggled */
|
||||
/* Clears ownership if developer flag has toggled */
|
||||
if ((developer_mode ? FLAG_LAST_BOOT_DEVELOPER : 0) !=
|
||||
(rsf->flags & FLAG_LAST_BOOT_DEVELOPER)) {
|
||||
VBDEBUG(("TPM: Developer flag changed; clearing owner.\n"));
|
||||
RETURN_ON_FAILURE(TPMClearAndReenable());
|
||||
}
|
||||
|
||||
/* Update flags */
|
||||
/* Updates flags */
|
||||
if (developer_mode)
|
||||
new_flags |= FLAG_LAST_BOOT_DEVELOPER;
|
||||
if (recovery_mode)
|
||||
@@ -225,7 +238,7 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode,
|
||||
rsf_dirty = 1;
|
||||
}
|
||||
|
||||
/* If firmware space is dirty, flush it back to the TPM */
|
||||
/* If firmware space is dirty, this flushes it back to the TPM */
|
||||
if (rsf_dirty) {
|
||||
VBDEBUG(("TPM: Updating firmware space.\n"));
|
||||
RETURN_ON_FAILURE(WriteSpaceFirmware(rsf));
|
||||
@@ -245,8 +258,8 @@ __pragma(warning (disable: 4100))
|
||||
|
||||
uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
|
||||
#ifndef CHROMEOS_ENVIRONMENT
|
||||
/* Initialize the TPM, but ignore return codes. In ChromeOS
|
||||
* environment, don't even talk to the TPM. */
|
||||
/* Initializes the TPM, but ignores return codes. In ChromeOS
|
||||
* environment, doesn't even talk to the TPM. */
|
||||
TlclLibInit();
|
||||
TlclStartup();
|
||||
TlclSelfTestFull();
|
||||
@@ -266,8 +279,8 @@ uint32_t RollbackFirmwareLock(void) {
|
||||
|
||||
uint32_t RollbackKernelRecovery(int developer_mode) {
|
||||
#ifndef CHROMEOS_ENVIRONMENT
|
||||
/* Initialize the TPM, but ignore return codes. In ChromeOS
|
||||
* environment, don't even talk to the TPM. */
|
||||
/* Initializes the TPM, but ignore return codes. In ChromeOS
|
||||
* environment, doesn't even talk to the TPM. */
|
||||
TlclLibInit();
|
||||
TlclStartup();
|
||||
TlclSelfTestFull();
|
||||
|
||||
@@ -88,10 +88,15 @@ uint32_t TlclReadLock(uint32_t index);
|
||||
*/
|
||||
uint32_t TlclAssertPhysicalPresence(void);
|
||||
|
||||
/* Enable the physical presence command. The TPM error code is returned.
|
||||
/* Enables the physical presence command. The TPM error code is returned.
|
||||
*/
|
||||
uint32_t TlclPhysicalPresenceCMDEnable(void);
|
||||
|
||||
/* Finalizes the physical presence settings: sofware PP is enabled, hardware PP
|
||||
* is disabled, and the lifetime lock is set. The TPM error code is returned.
|
||||
*/
|
||||
uint32_t TlclFinalizePhysicalPresence(void);
|
||||
|
||||
/* Turns off physical presence and locks it off until next reboot. The TPM
|
||||
* error code is returned.
|
||||
*/
|
||||
|
||||
@@ -64,6 +64,11 @@ struct s_tpm_startup_cmd{
|
||||
} tpm_startup_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x1, },
|
||||
};
|
||||
|
||||
struct s_tpm_finalizepp_cmd{
|
||||
uint8_t buffer[12];
|
||||
} tpm_finalizepp_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0, },
|
||||
};
|
||||
|
||||
struct s_tpm_pplock_cmd{
|
||||
uint8_t buffer[12];
|
||||
} tpm_pplock_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x4, },
|
||||
|
||||
@@ -181,6 +181,11 @@ uint32_t TlclPhysicalPresenceCMDEnable(void) {
|
||||
return Send(tpm_ppenable_cmd.buffer);
|
||||
}
|
||||
|
||||
uint32_t TlclFinalizePhysicalPresence(void) {
|
||||
VBDEBUG(("TPM: Enable PP cmd, disable HW pp, and set lifetime lock\n"));
|
||||
return Send(tpm_finalizepp_cmd.buffer);
|
||||
}
|
||||
|
||||
uint32_t TlclAssertPhysicalPresenceResult(void) {
|
||||
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
|
||||
return TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response));
|
||||
@@ -199,7 +204,8 @@ uint32_t TlclSetNvLocked(void) {
|
||||
int TlclIsOwned(void) {
|
||||
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE];
|
||||
uint32_t result;
|
||||
result = TlclSendReceive(tpm_readpubek_cmd.buffer, response, sizeof(response));
|
||||
result = TlclSendReceive(tpm_readpubek_cmd.buffer,
|
||||
response, sizeof(response));
|
||||
return (result != TPM_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
char* VbootVersion = "VBOOv=2c899e79";
|
||||
char* VbootVersion = "VBOOv=c0776686";
|
||||
|
||||
@@ -190,6 +190,18 @@ Command* BuildPPEnableCommand(void) {
|
||||
return cmd;
|
||||
}
|
||||
|
||||
Command* BuildFinalizePPCommand(void) {
|
||||
int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
|
||||
Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
|
||||
cmd->name = "tpm_finalizepp_cmd";
|
||||
AddInitializedField(cmd, kTpmRequestHeaderLength,
|
||||
sizeof(TPM_PHYSICAL_PRESENCE),
|
||||
TPM_PHYSICAL_PRESENCE_CMD_ENABLE |
|
||||
TPM_PHYSICAL_PRESENCE_HW_DISABLE |
|
||||
TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
Command* BuildPPLockCommand(void) {
|
||||
int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
|
||||
Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
|
||||
@@ -428,6 +440,7 @@ Command* (*builders[])(void) = {
|
||||
BuildPPAssertCommand,
|
||||
BuildPPEnableCommand,
|
||||
BuildPPLockCommand,
|
||||
BuildFinalizePPCommand,
|
||||
BuildStartupCommand,
|
||||
BuildSelftestfullCommand,
|
||||
BuildContinueSelfTestCommand,
|
||||
|
||||
Reference in New Issue
Block a user