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));
|
return SafeWrite(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Creates the NVRAM spaces, and sets their initial values as needed. */
|
/* Performs one-time initializations. Creates the NVRAM spaces, and sets their
|
||||||
static uint32_t InitializeSpaces(RollbackSpaceFirmware* rsf,
|
* initial values as needed. Sets the nvLocked bit and ensures the physical
|
||||||
RollbackSpaceKernel* rsk) {
|
* presence command is enabled and locked.
|
||||||
|
*/
|
||||||
|
static uint32_t OneTimeInitializeTPM(RollbackSpaceFirmware* rsf,
|
||||||
|
RollbackSpaceKernel* rsk) {
|
||||||
static const RollbackSpaceFirmware rsf_init = {
|
static const RollbackSpaceFirmware rsf_init = {
|
||||||
ROLLBACK_SPACE_FIRMWARE_VERSION, 0, 0, 0};
|
ROLLBACK_SPACE_FIRMWARE_VERSION, 0, 0, 0};
|
||||||
static const RollbackSpaceKernel rsk_init = {
|
static const RollbackSpaceKernel rsk_init = {
|
||||||
ROLLBACK_SPACE_KERNEL_VERSION, ROLLBACK_SPACE_KERNEL_UID, 0, 0};
|
ROLLBACK_SPACE_KERNEL_VERSION, ROLLBACK_SPACE_KERNEL_UID, 0, 0};
|
||||||
uint8_t nvlocked = 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
|
/* 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.
|
* 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));
|
RETURN_ON_FAILURE(TlclGetFlags(NULL, NULL, &nvlocked));
|
||||||
VBDEBUG(("TPM: nvlocked=%d\n", nvlocked));
|
VBDEBUG(("TPM: nvlocked=%d\n", nvlocked));
|
||||||
if (!nvlocked) {
|
if (!nvlocked) {
|
||||||
@@ -119,11 +124,11 @@ static uint32_t InitializeSpaces(RollbackSpaceFirmware* rsf,
|
|||||||
RETURN_ON_FAILURE(TlclSetNvLocked());
|
RETURN_ON_FAILURE(TlclSetNvLocked());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the firmware and kernel spaces */
|
/* Initializes the firmware and kernel spaces */
|
||||||
Memcpy(rsf, &rsf_init, sizeof(RollbackSpaceFirmware));
|
Memcpy(rsf, &rsf_init, sizeof(RollbackSpaceFirmware));
|
||||||
Memcpy(rsk, &rsk_init, sizeof(RollbackSpaceKernel));
|
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,
|
RETURN_ON_FAILURE(SafeDefineSpace(FIRMWARE_NV_INDEX,
|
||||||
TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE,
|
TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE,
|
||||||
sizeof(RollbackSpaceFirmware)));
|
sizeof(RollbackSpaceFirmware)));
|
||||||
@@ -177,9 +182,17 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode,
|
|||||||
#else
|
#else
|
||||||
RETURN_ON_FAILURE(TlclSelfTestFull());
|
RETURN_ON_FAILURE(TlclSelfTestFull());
|
||||||
#endif
|
#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));
|
RETURN_ON_FAILURE(TlclGetFlags(&disable, &deactivated, NULL));
|
||||||
if (disable || deactivated) {
|
if (disable || deactivated) {
|
||||||
VBDEBUG(("TPM: disabled (%d) or deactivated (%d). Fixing...\n",
|
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;
|
return TPM_E_MUST_REBOOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the firmware space. */
|
/* Reads the firmware space. */
|
||||||
result = ReadSpaceFirmware(rsf);
|
result = ReadSpaceFirmware(rsf);
|
||||||
if (TPM_E_BADINDEX == result) {
|
if (TPM_E_BADINDEX == result) {
|
||||||
RollbackSpaceKernel rsk;
|
RollbackSpaceKernel rsk;
|
||||||
|
|
||||||
/* This is the first time we've run, and the TPM has not been
|
/* 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"));
|
VBDEBUG(("TPM: Not initialized yet.\n"));
|
||||||
RETURN_ON_FAILURE(InitializeSpaces(rsf, &rsk));
|
RETURN_ON_FAILURE(OneTimeInitializeTPM(rsf, &rsk));
|
||||||
} else if (TPM_SUCCESS != result) {
|
} else if (TPM_SUCCESS != result) {
|
||||||
VBDEBUG(("TPM: Firmware space in a bad state; giving up.\n"));
|
VBDEBUG(("TPM: Firmware space in a bad state; giving up.\n"));
|
||||||
return TPM_E_CORRUPTED_STATE;
|
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",
|
VBDEBUG(("TPM: Firmware space sv%d f%x v%x\n",
|
||||||
rsf->struct_version, rsf->flags, rsf->fw_versions));
|
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) !=
|
if ((developer_mode ? FLAG_LAST_BOOT_DEVELOPER : 0) !=
|
||||||
(rsf->flags & FLAG_LAST_BOOT_DEVELOPER)) {
|
(rsf->flags & FLAG_LAST_BOOT_DEVELOPER)) {
|
||||||
VBDEBUG(("TPM: Developer flag changed; clearing owner.\n"));
|
VBDEBUG(("TPM: Developer flag changed; clearing owner.\n"));
|
||||||
RETURN_ON_FAILURE(TPMClearAndReenable());
|
RETURN_ON_FAILURE(TPMClearAndReenable());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update flags */
|
/* Updates flags */
|
||||||
if (developer_mode)
|
if (developer_mode)
|
||||||
new_flags |= FLAG_LAST_BOOT_DEVELOPER;
|
new_flags |= FLAG_LAST_BOOT_DEVELOPER;
|
||||||
if (recovery_mode)
|
if (recovery_mode)
|
||||||
@@ -225,7 +238,7 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode,
|
|||||||
rsf_dirty = 1;
|
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) {
|
if (rsf_dirty) {
|
||||||
VBDEBUG(("TPM: Updating firmware space.\n"));
|
VBDEBUG(("TPM: Updating firmware space.\n"));
|
||||||
RETURN_ON_FAILURE(WriteSpaceFirmware(rsf));
|
RETURN_ON_FAILURE(WriteSpaceFirmware(rsf));
|
||||||
@@ -245,8 +258,8 @@ __pragma(warning (disable: 4100))
|
|||||||
|
|
||||||
uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
|
uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) {
|
||||||
#ifndef CHROMEOS_ENVIRONMENT
|
#ifndef CHROMEOS_ENVIRONMENT
|
||||||
/* Initialize the TPM, but ignore return codes. In ChromeOS
|
/* Initializes the TPM, but ignores return codes. In ChromeOS
|
||||||
* environment, don't even talk to the TPM. */
|
* environment, doesn't even talk to the TPM. */
|
||||||
TlclLibInit();
|
TlclLibInit();
|
||||||
TlclStartup();
|
TlclStartup();
|
||||||
TlclSelfTestFull();
|
TlclSelfTestFull();
|
||||||
@@ -266,8 +279,8 @@ uint32_t RollbackFirmwareLock(void) {
|
|||||||
|
|
||||||
uint32_t RollbackKernelRecovery(int developer_mode) {
|
uint32_t RollbackKernelRecovery(int developer_mode) {
|
||||||
#ifndef CHROMEOS_ENVIRONMENT
|
#ifndef CHROMEOS_ENVIRONMENT
|
||||||
/* Initialize the TPM, but ignore return codes. In ChromeOS
|
/* Initializes the TPM, but ignore return codes. In ChromeOS
|
||||||
* environment, don't even talk to the TPM. */
|
* environment, doesn't even talk to the TPM. */
|
||||||
TlclLibInit();
|
TlclLibInit();
|
||||||
TlclStartup();
|
TlclStartup();
|
||||||
TlclSelfTestFull();
|
TlclSelfTestFull();
|
||||||
|
|||||||
@@ -88,10 +88,15 @@ uint32_t TlclReadLock(uint32_t index);
|
|||||||
*/
|
*/
|
||||||
uint32_t TlclAssertPhysicalPresence(void);
|
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);
|
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
|
/* Turns off physical presence and locks it off until next reboot. The TPM
|
||||||
* error code is returned.
|
* 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, },
|
} 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{
|
struct s_tpm_pplock_cmd{
|
||||||
uint8_t buffer[12];
|
uint8_t buffer[12];
|
||||||
} tpm_pplock_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x4, },
|
} 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);
|
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) {
|
uint32_t TlclAssertPhysicalPresenceResult(void) {
|
||||||
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
|
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
|
||||||
return TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response));
|
return TlclSendReceive(tpm_ppassert_cmd.buffer, response, sizeof(response));
|
||||||
@@ -199,7 +204,8 @@ uint32_t TlclSetNvLocked(void) {
|
|||||||
int TlclIsOwned(void) {
|
int TlclIsOwned(void) {
|
||||||
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE];
|
uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE];
|
||||||
uint32_t result;
|
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);
|
return (result != TPM_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
char* VbootVersion = "VBOOv=2c899e79";
|
char* VbootVersion = "VBOOv=c0776686";
|
||||||
|
|||||||
@@ -190,6 +190,18 @@ Command* BuildPPEnableCommand(void) {
|
|||||||
return cmd;
|
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) {
|
Command* BuildPPLockCommand(void) {
|
||||||
int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
|
int size = kTpmRequestHeaderLength + sizeof(TPM_PHYSICAL_PRESENCE);
|
||||||
Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
|
Command* cmd = newCommand(TSC_ORD_PhysicalPresence, size);
|
||||||
@@ -428,6 +440,7 @@ Command* (*builders[])(void) = {
|
|||||||
BuildPPAssertCommand,
|
BuildPPAssertCommand,
|
||||||
BuildPPEnableCommand,
|
BuildPPEnableCommand,
|
||||||
BuildPPLockCommand,
|
BuildPPLockCommand,
|
||||||
|
BuildFinalizePPCommand,
|
||||||
BuildStartupCommand,
|
BuildStartupCommand,
|
||||||
BuildSelftestfullCommand,
|
BuildSelftestfullCommand,
|
||||||
BuildContinueSelfTestCommand,
|
BuildContinueSelfTestCommand,
|
||||||
|
|||||||
Reference in New Issue
Block a user