mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-07 16:11:43 +00:00
Refactor rollback interface for LoadKernel(), LoadFirmware().
Review URL: http://codereview.chromium.org/2861020
This commit is contained in:
@@ -43,6 +43,58 @@ extern uint16_t g_kernel_version;
|
||||
|
||||
/* All functions return TPM_SUCCESS (zero) if successful, non-zero if error */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Call from LoadFirmware()
|
||||
Normal or developer mode (not recovery)
|
||||
Wants firmware versions
|
||||
Must send in developer flag
|
||||
|
||||
RollbackFirmwareSetup(IN devmode, OUT firmware versions)
|
||||
(maybe) RollbackFirmwareWrite()
|
||||
RollbackFirmwareLock()
|
||||
|
||||
Call from LoadKernel()
|
||||
|
||||
RollbackKernelRecovery(IN devmode)
|
||||
(implies LockFirmwareVersions() inside the setup)
|
||||
|
||||
RollbackKernelRead(OUT kernel versions)
|
||||
(maybe) RollbackKernelWrite()
|
||||
RollbackKernelLock()
|
||||
|
||||
Any mode
|
||||
If recovery mode, this is the first time we've been called
|
||||
Must send in developer flag
|
||||
If not recovery mode, wants kernel versions
|
||||
Must send in developer and recovery flags
|
||||
*/
|
||||
|
||||
/* These functions are callable from LoadFirmware(). They cannot use
|
||||
* global variables. */
|
||||
/* Setup must be called. */
|
||||
uint32_t RollbackFirmwareSetup(int developer_mode,
|
||||
uint16_t* key_version, uint16_t* version);
|
||||
/* Write may be called if the versions change */
|
||||
uint32_t RollbackFirmwareWrite(uint16_t key_version, uint16_t version);
|
||||
/* Lock must be called */
|
||||
uint32_t RollbackFirmwareLock(void);
|
||||
|
||||
/* These functions are callable from LoadKernel(). They may use global
|
||||
* variables. */
|
||||
/* Recovery may be called. If it is, this is the first time a
|
||||
* rollback function has been called this boot, so it needs to know if
|
||||
* we're in developer mode. */
|
||||
uint32_t RollbackKernelRecovery(int developer_mode);
|
||||
/* Read and write may be called if not in developer mode. If called in
|
||||
* recovery mode, these are ignored and/or return 0 versions. */
|
||||
uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version);
|
||||
uint32_t RollbackKernelWrite(uint16_t key_version, uint16_t version);
|
||||
/* Lock must be called. Internally, it's ignored in recovery mode. */
|
||||
uint32_t RollbackKernelLock(void);
|
||||
|
||||
|
||||
/* SetupTPM is called on boot and on starting the RW firmware, passing the
|
||||
* appripriate MODE and DEVELOPER_FLAG parameters. MODE can be one of
|
||||
* RO_RECOVERY_MODE, RO_NORMAL_MODE, RW_NORMAL_MODE. DEVELOPER_FLAG is 1 when
|
||||
|
||||
@@ -368,3 +368,36 @@ uint32_t LockFirmwareVersions() {
|
||||
uint32_t LockKernelVersionsByLockingPP() {
|
||||
return TlclLockPhysicalPresence();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* NEW APIS! HELP ME LUIGI, YOU'RE MY ONLY HOPE! */
|
||||
|
||||
uint32_t RollbackFirmwareSetup(int developer_mode,
|
||||
uint16_t* key_version, uint16_t* version) {
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackFirmwareWrite(uint16_t key_version, uint16_t version) {
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackFirmwareLock(void) {
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackKernelRecovery(int developer_mode) {
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackKernelRead(uint16_t* key_version, uint16_t* version) {
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackKernelWrite(uint16_t key_version, uint16_t version) {
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t RollbackKernelLock(void) {
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -58,12 +58,7 @@ int LoadFirmware(LoadFirmwareParams* params) {
|
||||
|
||||
/* Initialize the TPM and read rollback indices. */
|
||||
/* TODO: fix SetupTPM parameter for developer mode */
|
||||
if (0 != SetupTPM(RO_NORMAL_MODE, 0)) {
|
||||
debug("SetupTPM failed\n");
|
||||
return LOAD_FIRMWARE_RECOVERY;
|
||||
}
|
||||
if (0 != GetStoredVersions(FIRMWARE_VERSIONS,
|
||||
&tpm_key_version, &tpm_fw_version)) {
|
||||
if (0 != RollbackFirmwareSetup(0, &tpm_key_version, &tpm_fw_version)) {
|
||||
debug("Unable to get stored versions.\n");
|
||||
return LOAD_FIRMWARE_RECOVERY;
|
||||
}
|
||||
@@ -217,18 +212,15 @@ int LoadFirmware(LoadFirmwareParams* params) {
|
||||
if ((lowest_key_version > tpm_key_version) ||
|
||||
(lowest_key_version == tpm_key_version &&
|
||||
lowest_fw_version > tpm_fw_version)) {
|
||||
if (0 != WriteStoredVersions(FIRMWARE_VERSIONS,
|
||||
(uint16_t)lowest_key_version,
|
||||
if (0 != RollbackFirmwareWrite((uint16_t)lowest_key_version,
|
||||
(uint16_t)lowest_fw_version)) {
|
||||
debug("Unable to write stored versions.\n");
|
||||
return LOAD_FIRMWARE_RECOVERY;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lock Firmware TPM rollback indices from further writes. In
|
||||
* this design, this is done by setting the globalLock bit, which
|
||||
* is cleared only by TPM_Init at reboot. */
|
||||
if (0 != LockFirmwareVersions()) {
|
||||
/* Lock firmware versions in TPM */
|
||||
if (0 != RollbackFirmwareLock()) {
|
||||
debug("Unable to lock firmware versions.\n");
|
||||
return LOAD_FIRMWARE_RECOVERY;
|
||||
}
|
||||
|
||||
@@ -134,22 +134,20 @@ int LoadKernel(LoadKernelParams* params) {
|
||||
params->bootloader_address = 0;
|
||||
params->bootloader_size = 0;
|
||||
|
||||
/* Set up TPM; required in all modes */
|
||||
if (0 != SetupTPM(
|
||||
((BOOT_FLAG_RECOVERY & params->boot_flags) ?
|
||||
RO_RECOVERY_MODE : RW_NORMAL_MODE),
|
||||
((BOOT_FLAG_DEVELOPER & params->boot_flags) ? 1 : 0))) {
|
||||
debug("Error setting up TPM\n");
|
||||
/* Let the TPM know if we're in recovery mode */
|
||||
if (BOOT_FLAG_RECOVERY & params->boot_flags) {
|
||||
if (0 != RollbackKernelRecovery(BOOT_FLAG_DEVELOPER & params->boot_flags
|
||||
? 1 : 0)) {
|
||||
debug("Error setting up TPM for recovery kernel\n");
|
||||
return LOAD_KERNEL_RECOVERY;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_normal) {
|
||||
/* Read current kernel key index from TPM. Assumes TPM is already
|
||||
* initialized. */
|
||||
if (0 != GetStoredVersions(KERNEL_VERSIONS,
|
||||
&tpm_key_version,
|
||||
&tpm_kernel_version)) {
|
||||
debug("Unable to get stored version from TPM\n");
|
||||
if (0 != RollbackKernelRead(&tpm_key_version, &tpm_kernel_version)) {
|
||||
debug("Unable to get kernel versions from TPM\n");
|
||||
return LOAD_KERNEL_RECOVERY;
|
||||
}
|
||||
} else if (is_dev) {
|
||||
@@ -368,24 +366,17 @@ int LoadKernel(LoadKernelParams* params) {
|
||||
if ((lowest_key_version > tpm_key_version) ||
|
||||
(lowest_key_version == tpm_key_version &&
|
||||
lowest_kernel_version > tpm_kernel_version)) {
|
||||
if (0 != WriteStoredVersions(KERNEL_VERSIONS,
|
||||
(uint16_t)lowest_key_version,
|
||||
(uint16_t)lowest_kernel_version))
|
||||
if (0 != RollbackKernelWrite((uint16_t)lowest_key_version,
|
||||
(uint16_t)lowest_kernel_version)) {
|
||||
debug("Error writing kernel versions to TPM.\n");
|
||||
return LOAD_KERNEL_RECOVERY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(BOOT_FLAG_RECOVERY & params->boot_flags)) {
|
||||
/* We can lock the TPM now, since we've decided which kernel we
|
||||
* like. If we don't find a good kernel, we leave the TPM
|
||||
* unlocked so we can try again on the next boot device. If no
|
||||
* kernels are good, we'll reboot to recovery mode, so it's ok to
|
||||
* leave the TPM unlocked in that case too.
|
||||
*
|
||||
* If we're already in recovery mode, we need to leave PP unlocked,
|
||||
* so don't lock the kernel versions. */
|
||||
debug("Lock kernel versions\n");
|
||||
if (0 != LockKernelVersionsByLockingPP())
|
||||
/* Lock the kernel versions, since we're about to boot the kernel */
|
||||
if (0 != RollbackKernelLock()) {
|
||||
debug("Error locking kernel versions.\n");
|
||||
return LOAD_KERNEL_RECOVERY;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,13 @@ int main(void)
|
||||
LoadKernel(0);
|
||||
|
||||
/* rollback_index.h */
|
||||
SetupTPM(0, 0);
|
||||
GetStoredVersions(0, &x, &y);
|
||||
WriteStoredVersions(0, 0, 0);
|
||||
LockFirmwareVersions();
|
||||
LockKernelVersionsByLockingPP();
|
||||
RollbackFirmwareSetup(0, &x, &y);
|
||||
RollbackFirmwareWrite(0, 0);
|
||||
RollbackFirmwareLock();
|
||||
RollbackKernelRecovery(0);
|
||||
RollbackKernelRead(&x, &y);
|
||||
RollbackKernelWrite(0, 0);
|
||||
RollbackKernelLock();
|
||||
|
||||
/* tlcl.h */
|
||||
TlclLibInit();
|
||||
|
||||
Reference in New Issue
Block a user