mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-21 23:37:13 +00:00
Add recovery mode protection to new NVRAM locking scheme.
Also fix the TPM initialization. Review URL: http://codereview.chromium.org/2344002
This commit is contained in:
@@ -21,41 +21,32 @@ void SetupTPM(void) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t GetStoredVersion(int type) {
|
void GetStoredVersions(int type, uint16_t* key_version, uint16_t* version) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FIRMWARE_KEY_VERSION:
|
case FIRMWARE_VERSIONS:
|
||||||
return g_firmware_key_version;
|
*key_version = g_firmware_key_version;
|
||||||
|
*version = g_firmware_version;
|
||||||
break;
|
break;
|
||||||
case FIRMWARE_VERSION:
|
case KERNEL_VERSIONS:
|
||||||
return g_firmware_version;
|
*key_version = g_kernel_key_version;
|
||||||
break;
|
*version = g_kernel_version;
|
||||||
case KERNEL_KEY_VERSION:
|
|
||||||
return g_kernel_key_version;
|
|
||||||
break;
|
|
||||||
case KERNEL_VERSION:
|
|
||||||
return g_kernel_version;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int WriteStoredVersion(int type, uint16_t version) {
|
int WriteStoredVersions(int type, uint16_t key_version, uint16_t version) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FIRMWARE_KEY_VERSION:
|
case FIRMWARE_VERSIONS:
|
||||||
g_firmware_key_version = version;
|
g_firmware_key_version = key_version;
|
||||||
break;
|
|
||||||
case FIRMWARE_VERSION:
|
|
||||||
g_firmware_version = version;
|
g_firmware_version = version;
|
||||||
break;
|
break;
|
||||||
case KERNEL_KEY_VERSION:
|
case KERNEL_VERSIONS:
|
||||||
g_kernel_key_version = version;
|
g_kernel_key_version = key_version;
|
||||||
break;
|
|
||||||
case KERNEL_VERSION:
|
|
||||||
g_kernel_version = version;
|
g_kernel_version = version;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
debug("Rollback Index Library Mock: Stored Version written.\n");
|
debug("Rollback Index Library Mock: Stored Versions written.\n");
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,20 +17,20 @@ extern uint16_t g_kernel_key_version;
|
|||||||
extern uint16_t g_kernel_version;
|
extern uint16_t g_kernel_version;
|
||||||
|
|
||||||
/* Rollback version types. */
|
/* Rollback version types. */
|
||||||
#define FIRMWARE_KEY_VERSION 0
|
#define FIRMWARE_VERSIONS 0
|
||||||
#define FIRMWARE_VERSION 1
|
#define KERNEL_VERSIONS 1
|
||||||
#define KERNEL_KEY_VERSION 2
|
|
||||||
#define KERNEL_VERSION 3
|
|
||||||
|
|
||||||
/* TPM NVRAM location indices. */
|
/* TPM NVRAM location indices. */
|
||||||
#define FIRMWARE_KEY_VERSION_NV_INDEX 0x1001
|
#define FIRMWARE_VERSIONS_NV_INDEX 0x1001
|
||||||
#define FIRMWARE_VERSION_NV_INDEX 0x1002
|
#define KERNEL_VERSIONS_NV_INDEX 0x1002
|
||||||
#define KERNEL_KEY_VERSION_NV_INDEX 0x1003
|
#define TPM_IS_INITIALIZED_NV_INDEX 0x1003
|
||||||
#define KERNEL_VERSION_NV_INDEX 0x1004
|
#define KERNEL_VERSIONS_BACKUP_NV_INDEX 0x1004
|
||||||
|
#define KERNEL_BACKUP_IS_VALID_NV_INDEX 0x1005
|
||||||
|
|
||||||
|
|
||||||
void SetupTPM(void);
|
void SetupTPM(void);
|
||||||
uint16_t GetStoredVersion(int type);
|
void GetStoredVersions(int type, uint16_t* key_version, uint16_t* version);
|
||||||
int WriteStoredVersion(int type, uint16_t version);
|
int WriteStoredVersions(int type, uint16_t key_version, uint16_t version);
|
||||||
void LockFirmwareVersions();
|
void LockFirmwareVersions();
|
||||||
void LockKernelVersionsByLockingPP();
|
void LockKernelVersionsByLockingPP();
|
||||||
|
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ int VerifyFirmwareDriver_f(uint8_t* root_key_blob,
|
|||||||
uint8_t firmwareA_is_verified = 0; /* Whether firmwareA verify succeeded. */
|
uint8_t firmwareA_is_verified = 0; /* Whether firmwareA verify succeeded. */
|
||||||
uint32_t min_lversion; /* Minimum of firmware A and firmware lversion. */
|
uint32_t min_lversion; /* Minimum of firmware A and firmware lversion. */
|
||||||
uint32_t stored_lversion; /* Stored logical version in the TPM. */
|
uint32_t stored_lversion; /* Stored logical version in the TPM. */
|
||||||
|
uint16_t version, key_version; /* Temporary variables */
|
||||||
|
|
||||||
/* Initialize the TPM since we'll be reading the rollback indices. */
|
/* Initialize the TPM since we'll be reading the rollback indices. */
|
||||||
SetupTPM();
|
SetupTPM();
|
||||||
@@ -265,8 +266,8 @@ int VerifyFirmwareDriver_f(uint8_t* root_key_blob,
|
|||||||
firmwareA_lversion = GetLogicalFirmwareVersion(verification_headerA);
|
firmwareA_lversion = GetLogicalFirmwareVersion(verification_headerA);
|
||||||
firmwareB_lversion = GetLogicalFirmwareVersion(verification_headerB);
|
firmwareB_lversion = GetLogicalFirmwareVersion(verification_headerB);
|
||||||
min_lversion = Min(firmwareA_lversion, firmwareB_lversion);
|
min_lversion = Min(firmwareA_lversion, firmwareB_lversion);
|
||||||
stored_lversion = CombineUint16Pair(GetStoredVersion(FIRMWARE_KEY_VERSION),
|
GetStoredVersions(FIRMWARE_VERSIONS, &key_version, &version);
|
||||||
GetStoredVersion(FIRMWARE_VERSION));
|
stored_lversion = CombineUint16Pair(key_version, version);
|
||||||
/* Always try FirmwareA first. */
|
/* Always try FirmwareA first. */
|
||||||
if (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob,
|
if (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob,
|
||||||
verification_headerA,
|
verification_headerA,
|
||||||
@@ -280,10 +281,9 @@ int VerifyFirmwareDriver_f(uint8_t* root_key_blob,
|
|||||||
if (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob,
|
if (VERIFY_FIRMWARE_SUCCESS == VerifyFirmware(root_key_blob,
|
||||||
verification_headerB,
|
verification_headerB,
|
||||||
firmwareB)) {
|
firmwareB)) {
|
||||||
WriteStoredVersion(FIRMWARE_KEY_VERSION,
|
WriteStoredVersions(FIRMWARE_VERSIONS,
|
||||||
(uint16_t) (min_lversion >> 16));
|
(uint16_t) (min_lversion >> 16),
|
||||||
WriteStoredVersion(FIRMWARE_VERSION,
|
(uint16_t) (min_lversion & 0xFFFF));
|
||||||
(uint16_t) (min_lversion & 0x00FFFF));
|
|
||||||
stored_lversion = min_lversion; /* Update stored version as it's used
|
stored_lversion = min_lversion; /* Update stored version as it's used
|
||||||
* later. */
|
* later. */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
#define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */
|
#define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */
|
||||||
|
|
||||||
#define TPM_SUCCESS ((uint32_t)0x00000000)
|
#define TPM_SUCCESS ((uint32_t)0x00000000)
|
||||||
|
#define TPM_E_BADINDEX ((uint32_t)0x00000002)
|
||||||
|
|
||||||
#define TPM_NV_INDEX0 ((uint32_t)0x00000000)
|
#define TPM_NV_INDEX0 ((uint32_t)0x00000000)
|
||||||
#define TPM_NV_INDEX_LOCK ((uint32_t)0xffffffff)
|
#define TPM_NV_INDEX_LOCK ((uint32_t)0xffffffff)
|
||||||
#define TPM_NV_PER_WRITE_STCLEAR (((uint32_t)1)<<14)
|
#define TPM_NV_PER_WRITE_STCLEAR (((uint32_t)1)<<14)
|
||||||
|
|||||||
@@ -397,6 +397,7 @@ int VerifyKernelDriver_f(uint8_t* firmware_key_blob,
|
|||||||
kernel_entry* try_kernel[2]; /* Kernel in try order. */
|
kernel_entry* try_kernel[2]; /* Kernel in try order. */
|
||||||
int try_kernel_which[2]; /* Which corresponding kernel in the try order */
|
int try_kernel_which[2]; /* Which corresponding kernel in the try order */
|
||||||
uint32_t try_kernel_lversion[2]; /* Their logical versions. */
|
uint32_t try_kernel_lversion[2]; /* Their logical versions. */
|
||||||
|
uint16_t kernel_version, kernel_key_version; /* Temporary variables */
|
||||||
|
|
||||||
/* [kernel_to_boot] will eventually contain the boot path to follow
|
/* [kernel_to_boot] will eventually contain the boot path to follow
|
||||||
* and is returned to the caller. Initially, we set it to recovery. If
|
* and is returned to the caller. Initially, we set it to recovery. If
|
||||||
@@ -415,8 +416,8 @@ int VerifyKernelDriver_f(uint8_t* firmware_key_blob,
|
|||||||
kernelA_lversion = GetLogicalKernelVersion(kernelA->kernel_blob);
|
kernelA_lversion = GetLogicalKernelVersion(kernelA->kernel_blob);
|
||||||
kernelB_lversion = GetLogicalKernelVersion(kernelB->kernel_blob);
|
kernelB_lversion = GetLogicalKernelVersion(kernelB->kernel_blob);
|
||||||
min_lversion = Min(kernelA_lversion, kernelB_lversion);
|
min_lversion = Min(kernelA_lversion, kernelB_lversion);
|
||||||
stored_lversion = CombineUint16Pair(GetStoredVersion(KERNEL_KEY_VERSION),
|
GetStoredVersions(KERNEL_VERSIONS, &kernel_key_version, &kernel_version);
|
||||||
GetStoredVersion(KERNEL_VERSION));
|
stored_lversion = CombineUint16Pair(kernel_key_version, kernel_version);
|
||||||
|
|
||||||
/* TODO(gauravsh): The kernel entries kernelA and kernelB come from the
|
/* TODO(gauravsh): The kernel entries kernelA and kernelB come from the
|
||||||
* partition table - verify its signature/checksum before proceeding
|
* partition table - verify its signature/checksum before proceeding
|
||||||
@@ -464,9 +465,8 @@ int VerifyKernelDriver_f(uint8_t* firmware_key_blob,
|
|||||||
if (VERIFY_KERNEL_SUCCESS == VerifyKernel(firmware_key_blob,
|
if (VERIFY_KERNEL_SUCCESS == VerifyKernel(firmware_key_blob,
|
||||||
try_kernel[1]->kernel_blob,
|
try_kernel[1]->kernel_blob,
|
||||||
dev_mode)) {
|
dev_mode)) {
|
||||||
WriteStoredVersion(KERNEL_KEY_VERSION,
|
WriteStoredVersions(KERNEL_VERSIONS,
|
||||||
(uint16_t) (min_lversion >> 16));
|
(uint16_t) (min_lversion >> 16),
|
||||||
WriteStoredVersion(KERNEL_VERSION,
|
|
||||||
(uint16_t) (min_lversion & 0xFFFF));
|
(uint16_t) (min_lversion & 0xFFFF));
|
||||||
stored_lversion = min_lversion; /* Update stored version as it's
|
stored_lversion = min_lversion; /* Update stored version as it's
|
||||||
* used later. */
|
* used later. */
|
||||||
|
|||||||
@@ -19,50 +19,138 @@ uint16_t g_firmware_version = 0;
|
|||||||
uint16_t g_kernel_key_version = 0;
|
uint16_t g_kernel_key_version = 0;
|
||||||
uint16_t g_kernel_version = 0;
|
uint16_t g_kernel_version = 0;
|
||||||
|
|
||||||
static void InitializeSpaces(void) {
|
static int InitializeSpaces(void) {
|
||||||
uint16_t zero = 0;
|
uint32_t zero = 0;
|
||||||
|
uint32_t space_holder;
|
||||||
uint32_t firmware_perm = TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE;
|
uint32_t firmware_perm = TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE;
|
||||||
uint32_t kernel_perm = TPM_NV_PER_PPWRITE;
|
uint32_t kernel_perm = TPM_NV_PER_PPWRITE;
|
||||||
|
|
||||||
debug("Initializing spaces\n");
|
debug("Initializing spaces\n");
|
||||||
TlclSetNvLocked(); /* useful only the first time */
|
|
||||||
|
|
||||||
TlclDefineSpace(FIRMWARE_KEY_VERSION_NV_INDEX,
|
if (TlclRead(TPM_IS_INITIALIZED_NV_INDEX,
|
||||||
firmware_perm, sizeof(uint16_t));
|
(uint8_t*) &space_holder, sizeof(space_holder)) == TPM_SUCCESS) {
|
||||||
TlclWrite(FIRMWARE_KEY_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
|
/* Spaces are already initialized, so this is an error */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
TlclDefineSpace(FIRMWARE_VERSION_NV_INDEX, firmware_perm, sizeof(uint16_t));
|
TlclSetNvLocked();
|
||||||
TlclWrite(FIRMWARE_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
|
|
||||||
|
|
||||||
TlclDefineSpace(KERNEL_KEY_VERSION_NV_INDEX, kernel_perm, sizeof(uint16_t));
|
TlclDefineSpace(FIRMWARE_VERSIONS_NV_INDEX, firmware_perm, sizeof(uint32_t));
|
||||||
TlclWrite(KERNEL_KEY_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
|
TlclWrite(FIRMWARE_VERSIONS_NV_INDEX, (uint8_t*) &zero, sizeof(uint32_t));
|
||||||
|
|
||||||
TlclDefineSpace(KERNEL_VERSION_NV_INDEX, kernel_perm, sizeof(uint16_t));
|
TlclDefineSpace(KERNEL_VERSIONS_NV_INDEX, kernel_perm, sizeof(uint32_t));
|
||||||
TlclWrite(KERNEL_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
|
TlclWrite(KERNEL_VERSIONS_NV_INDEX, (uint8_t*) &zero, sizeof(uint32_t));
|
||||||
|
|
||||||
|
/* The space KERNEL_VERSIONS_BACKUP_NV_INDEX is used to protect the kernel
|
||||||
|
* versions when entering recovery mode. The content of space
|
||||||
|
* KERNEL_BACKUP_IS_VALID determines whether the backup value (1) or the
|
||||||
|
* regular value (0) should be trusted.
|
||||||
|
*/
|
||||||
|
TlclDefineSpace(KERNEL_VERSIONS_BACKUP_NV_INDEX,
|
||||||
|
firmware_perm, sizeof(uint32_t));
|
||||||
|
TlclWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX,
|
||||||
|
(uint8_t*) &zero, sizeof(uint32_t));
|
||||||
|
TlclDefineSpace(KERNEL_BACKUP_IS_VALID_NV_INDEX,
|
||||||
|
firmware_perm, sizeof(uint32_t));
|
||||||
|
TlclWrite(KERNEL_BACKUP_IS_VALID_NV_INDEX,
|
||||||
|
(uint8_t*) &zero, sizeof(uint32_t));
|
||||||
|
|
||||||
|
/* The space TPM_IS_INITIALIZED_NV_INDEX is used to indicate that the TPM
|
||||||
|
* initialization has completed. Without it we cannot be sure that the last
|
||||||
|
* space to be created was also initialized (power could have been lost right
|
||||||
|
* after its creation).
|
||||||
|
*/
|
||||||
|
TlclDefineSpace(TPM_IS_INITIALIZED_NV_INDEX, firmware_perm, sizeof(uint32_t));
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EnterRecovery(void) {
|
/* Enters the recovery mode. If |unlocked| is true, there is some problem with
|
||||||
/* Temporary recovery stub. Currently just initalizes spaces. */
|
* the TPM, so do not attempt to do any more TPM operations, and particularly
|
||||||
InitializeSpaces();
|
* do not set bGlobalLock.
|
||||||
|
*/
|
||||||
|
static void EnterRecovery(int unlocked) {
|
||||||
|
uint32_t combined_versions;
|
||||||
|
uint32_t one = 1;
|
||||||
|
|
||||||
|
if (!unlocked) {
|
||||||
|
/* Saves the kernel versions and indicates that we should trust the saved
|
||||||
|
* ones.
|
||||||
|
*/
|
||||||
|
TlclRead(KERNEL_VERSIONS_NV_INDEX, (uint8_t*) &combined_versions,
|
||||||
|
sizeof(uint32_t));
|
||||||
|
TlclWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX, (uint8_t*) &combined_versions,
|
||||||
|
sizeof(uint32_t));
|
||||||
|
TlclWrite(KERNEL_BACKUP_IS_VALID_NV_INDEX, (uint8_t*) &one,
|
||||||
|
sizeof(uint32_t));
|
||||||
|
/* Protects the firmware and backup kernel versions. */
|
||||||
|
LockFirmwareVersions();
|
||||||
|
}
|
||||||
|
debug("entering recovery mode");
|
||||||
|
|
||||||
|
/* and then what? */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetTPMRollbackIndices(void) {
|
static int GetTPMRollbackIndices(void) {
|
||||||
/* We just perform the reads, making sure they succeed. A failure means that
|
uint32_t backup_is_valid;
|
||||||
* the rollback index locations are some how messed up and we must jump to
|
uint32_t firmware_versions;
|
||||||
* recovery */
|
uint32_t kernel_versions;
|
||||||
if (TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
|
|
||||||
(uint8_t*) &g_firmware_key_version,
|
if (TlclRead(KERNEL_BACKUP_IS_VALID_NV_INDEX, (uint8_t*) &backup_is_valid,
|
||||||
sizeof(g_firmware_key_version)) ||
|
sizeof(uint32_t)) != TPM_SUCCESS) {
|
||||||
TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
|
EnterRecovery(1);
|
||||||
(uint8_t*) &g_firmware_key_version,
|
}
|
||||||
sizeof(g_firmware_key_version)) ||
|
if (backup_is_valid) {
|
||||||
TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
|
/* We reach this path if the previous boot went into recovery mode and we
|
||||||
(uint8_t*) &g_firmware_key_version,
|
* made a copy of the kernel versions to protect them.
|
||||||
sizeof(g_firmware_key_version)) ||
|
*/
|
||||||
TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
|
uint32_t protected_combined_versions;
|
||||||
(uint8_t*) &g_firmware_key_version,
|
uint32_t unsafe_combined_versions;
|
||||||
sizeof(g_firmware_key_version)))
|
uint32_t result;
|
||||||
|
uint32_t zero = 0;
|
||||||
|
if (TlclRead(KERNEL_VERSIONS_BACKUP_NV_INDEX,
|
||||||
|
(uint8_t*) &protected_combined_versions,
|
||||||
|
sizeof(uint32_t)) != TPM_SUCCESS) {
|
||||||
|
EnterRecovery(1);
|
||||||
|
}
|
||||||
|
result = TlclRead(KERNEL_VERSIONS_NV_INDEX,
|
||||||
|
(uint8_t*) &unsafe_combined_versions, sizeof(uint32_t));
|
||||||
|
if (result == TPM_E_BADINDEX) {
|
||||||
|
/* Jeez, someone removed the space. This is either hostile or extremely
|
||||||
|
* incompetent. Foo to them. Politeness and lack of an adequate
|
||||||
|
* character set prevent me from expressing my true feelings.
|
||||||
|
*/
|
||||||
|
TlclDefineSpace(KERNEL_VERSIONS_NV_INDEX, TPM_NV_PER_PPWRITE,
|
||||||
|
sizeof(uint32_t));
|
||||||
|
} else if (result != TPM_SUCCESS) {
|
||||||
|
EnterRecovery(1);
|
||||||
|
}
|
||||||
|
if (result == TPM_E_BADINDEX ||
|
||||||
|
protected_combined_versions != unsafe_combined_versions) {
|
||||||
|
TlclWrite(KERNEL_VERSIONS_NV_INDEX,
|
||||||
|
(uint8_t*) &protected_combined_versions, sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
/* We recovered and now we can reset the BACKUP_IS_VALID flag.
|
||||||
|
*/
|
||||||
|
TlclWrite(KERNEL_BACKUP_IS_VALID_NV_INDEX, (uint8_t*) &zero, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We perform the reads, making sure they succeed. A failure means that the
|
||||||
|
* rollback index locations are missing or somehow messed up. We let the
|
||||||
|
* caller deal with that.
|
||||||
|
*/
|
||||||
|
if (TPM_SUCCESS != TlclRead(FIRMWARE_VERSIONS_NV_INDEX,
|
||||||
|
(uint8_t*) &firmware_versions,
|
||||||
|
sizeof(firmware_versions)) ||
|
||||||
|
TPM_SUCCESS != TlclRead(KERNEL_VERSIONS_NV_INDEX,
|
||||||
|
(uint8_t*) &kernel_versions,
|
||||||
|
sizeof(kernel_versions)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
g_firmware_key_version = firmware_versions >> 16;
|
||||||
|
g_firmware_version = firmware_versions && 0xffff;
|
||||||
|
g_kernel_key_version = kernel_versions >> 16;
|
||||||
|
g_kernel_version = kernel_versions && 0xffff;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,61 +172,52 @@ void SetupTPM(void) {
|
|||||||
/* Check that the TPM is enabled and activated. */
|
/* Check that the TPM is enabled and activated. */
|
||||||
if(TlclGetFlags(&disable, &deactivated) != TPM_SUCCESS) {
|
if(TlclGetFlags(&disable, &deactivated) != TPM_SUCCESS) {
|
||||||
debug("failed to get TPM flags");
|
debug("failed to get TPM flags");
|
||||||
EnterRecovery();
|
EnterRecovery(1);
|
||||||
}
|
}
|
||||||
if (disable || deactivated) {
|
if (disable || deactivated) {
|
||||||
TlclSetEnable();
|
TlclSetEnable();
|
||||||
if (TlclSetDeactivated(0) != TPM_SUCCESS) {
|
if (TlclSetDeactivated(0) != TPM_SUCCESS) {
|
||||||
debug("failed to activate TPM");
|
debug("failed to activate TPM");
|
||||||
EnterRecovery();
|
EnterRecovery(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* We expect this to fail the first time we run on a device, indicating that
|
||||||
|
* the TPM has not been initialized yet. */
|
||||||
if (!GetTPMRollbackIndices()) {
|
if (!GetTPMRollbackIndices()) {
|
||||||
debug("failed to get rollback indices");
|
debug("failed to get rollback indices");
|
||||||
EnterRecovery();
|
if (!InitializeSpaces()) {
|
||||||
|
/* If InitializeSpaces() fails (possibly because it had been executed
|
||||||
|
* already), something is wrong. */
|
||||||
|
EnterRecovery(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GetStoredVersions(int type, uint16_t* key_version, uint16_t* version) {
|
||||||
uint16_t GetStoredVersion(int type) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FIRMWARE_KEY_VERSION:
|
case FIRMWARE_VERSIONS:
|
||||||
return g_firmware_key_version;
|
*key_version = g_firmware_key_version;
|
||||||
|
*version = g_firmware_version;
|
||||||
break;
|
break;
|
||||||
case FIRMWARE_VERSION:
|
case KERNEL_VERSIONS:
|
||||||
return g_firmware_version;
|
*key_version = g_kernel_key_version;
|
||||||
break;
|
*version = g_kernel_version;
|
||||||
case KERNEL_KEY_VERSION:
|
|
||||||
return g_kernel_key_version;
|
|
||||||
break;
|
|
||||||
case KERNEL_VERSION:
|
|
||||||
return g_kernel_version;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int WriteStoredVersion(int type, uint16_t version) {
|
int WriteStoredVersions(int type, uint16_t key_version, uint16_t version) {
|
||||||
|
uint32_t combined_version = (key_version << 16) & version;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FIRMWARE_KEY_VERSION:
|
case FIRMWARE_VERSIONS:
|
||||||
return (TPM_SUCCESS == TlclWrite(FIRMWARE_KEY_VERSION_NV_INDEX,
|
return (TPM_SUCCESS == TlclWrite(FIRMWARE_VERSIONS_NV_INDEX,
|
||||||
(uint8_t*) &version,
|
(uint8_t*) &combined_version,
|
||||||
sizeof(uint16_t)));
|
sizeof(uint32_t)));
|
||||||
break;
|
break;
|
||||||
case FIRMWARE_VERSION:
|
case KERNEL_VERSIONS:
|
||||||
return (TPM_SUCCESS == TlclWrite(FIRMWARE_VERSION_NV_INDEX,
|
return (TPM_SUCCESS == TlclWrite(KERNEL_VERSIONS_NV_INDEX,
|
||||||
(uint8_t*) &version,
|
(uint8_t*) &combined_version,
|
||||||
sizeof(uint16_t)));
|
sizeof(uint32_t)));
|
||||||
break;
|
|
||||||
case KERNEL_KEY_VERSION:
|
|
||||||
return (TPM_SUCCESS == TlclWrite(KERNEL_KEY_VERSION_NV_INDEX,
|
|
||||||
(uint8_t*) &version,
|
|
||||||
sizeof(uint16_t)));
|
|
||||||
break;
|
|
||||||
case KERNEL_VERSION:
|
|
||||||
return (TPM_SUCCESS == TlclWrite(KERNEL_VERSION_NV_INDEX,
|
|
||||||
(uint8_t*) &version,
|
|
||||||
sizeof(uint16_t)));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -147,13 +226,13 @@ int WriteStoredVersion(int type, uint16_t version) {
|
|||||||
void LockFirmwareVersions() {
|
void LockFirmwareVersions() {
|
||||||
if (TlclSetGlobalLock() != TPM_SUCCESS) {
|
if (TlclSetGlobalLock() != TPM_SUCCESS) {
|
||||||
debug("failed to set global lock");
|
debug("failed to set global lock");
|
||||||
EnterRecovery();
|
EnterRecovery(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LockKernelVersionsByLockingPP() {
|
void LockKernelVersionsByLockingPP() {
|
||||||
if (TlclLockPhysicalPresence() != TPM_SUCCESS) {
|
if (TlclLockPhysicalPresence() != TPM_SUCCESS) {
|
||||||
debug("failed to turn off PP");
|
debug("failed to turn off PP");
|
||||||
EnterRecovery();
|
EnterRecovery(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
uint16_t x, y;
|
||||||
|
|
||||||
// cgptlib.h
|
// cgptlib.h
|
||||||
GptInit(0);
|
GptInit(0);
|
||||||
GptNextKernelEntry(0, 0, 0);
|
GptNextKernelEntry(0, 0, 0);
|
||||||
@@ -36,8 +38,8 @@ int main(void)
|
|||||||
|
|
||||||
// rollback_index.h
|
// rollback_index.h
|
||||||
SetupTPM();
|
SetupTPM();
|
||||||
GetStoredVersion(0);
|
GetStoredVersions(0, &x, &y);
|
||||||
WriteStoredVersion(0, 0);
|
WriteStoredVersions(0, 0, 0);
|
||||||
LockFirmwareVersions();
|
LockFirmwareVersions();
|
||||||
LockKernelVersionsByLockingPP();
|
LockKernelVersionsByLockingPP();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user