mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 02:05:01 +00:00
This creates a new vboot_firmware subdirectory, and which contains the entirety of the BIOS code. There shouldn't be anything in this directory that is NOT required by the BIOS. Review URL: http://codereview.chromium.org/2219004
150 lines
5.0 KiB
C
150 lines
5.0 KiB
C
/* Copyright (c) 2010 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.
|
|
*
|
|
* Functions for querying, manipulating and locking rollback indices
|
|
* stored in the TPM NVRAM.
|
|
*/
|
|
|
|
#include "rollback_index.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "utility.h"
|
|
#include "tlcl.h"
|
|
#include "tss_constants.h"
|
|
|
|
uint16_t g_firmware_key_version = 0;
|
|
uint16_t g_firmware_version = 0;
|
|
uint16_t g_kernel_key_version = 0;
|
|
uint16_t g_kernel_version = 0;
|
|
|
|
static void InitializeSpaces(void) {
|
|
uint16_t zero = 0;
|
|
uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;
|
|
|
|
debug("Initializing spaces\n");
|
|
TlclSetNvLocked(); /* useful only the first time */
|
|
|
|
TlclDefineSpace(FIRMWARE_KEY_VERSION_NV_INDEX, perm, sizeof(uint16_t));
|
|
TlclWrite(FIRMWARE_KEY_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
|
|
|
|
TlclDefineSpace(FIRMWARE_VERSION_NV_INDEX, perm, sizeof(uint16_t));
|
|
TlclWrite(FIRMWARE_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
|
|
|
|
TlclDefineSpace(KERNEL_KEY_VERSION_NV_INDEX, perm, sizeof(uint16_t));
|
|
TlclWrite(KERNEL_KEY_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
|
|
|
|
TlclDefineSpace(KERNEL_VERSION_NV_INDEX, perm, sizeof(uint16_t));
|
|
TlclWrite(KERNEL_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
|
|
}
|
|
|
|
static void EnterRecovery(void) {
|
|
/* Temporary recovery stub. Currently just initalizes spaces. */
|
|
InitializeSpaces();
|
|
}
|
|
|
|
static int GetTPMRollbackIndices(void) {
|
|
/* We just perform the reads, making sure they succeed. A failure means that
|
|
* the rollback index locations are some how messed up and we must jump to
|
|
* recovery */
|
|
if (TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
|
|
(uint8_t*) &g_firmware_key_version,
|
|
sizeof(g_firmware_key_version)) ||
|
|
TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
|
|
(uint8_t*) &g_firmware_key_version,
|
|
sizeof(g_firmware_key_version)) ||
|
|
TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
|
|
(uint8_t*) &g_firmware_key_version,
|
|
sizeof(g_firmware_key_version)) ||
|
|
TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
|
|
(uint8_t*) &g_firmware_key_version,
|
|
sizeof(g_firmware_key_version)))
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
|
|
void SetupTPM(void) {
|
|
TlclLibinit();
|
|
TlclStartup();
|
|
/* TODO(gauravsh): The call to self test should probably be deferred.
|
|
* As per semenzato@chromium.org -
|
|
* TlclStartup should be called before the firmware initializes the memory
|
|
* controller, so the selftest can run in parallel with that. Here we should
|
|
* just call TlclSelftestFull to make sure the self test has
|
|
* completed---unless we want to rely on the NVRAM operations being available
|
|
* before the selftest completes. */
|
|
TlclSelftestfull();
|
|
TlclAssertPhysicalPresence();
|
|
if (!GetTPMRollbackIndices()) {
|
|
debug("Ho Ho Ho! We must jump to recovery.");
|
|
EnterRecovery();
|
|
}
|
|
}
|
|
|
|
|
|
uint16_t GetStoredVersion(int type) {
|
|
switch (type) {
|
|
case FIRMWARE_KEY_VERSION:
|
|
return g_firmware_key_version;
|
|
break;
|
|
case FIRMWARE_VERSION:
|
|
return g_firmware_version;
|
|
break;
|
|
case KERNEL_KEY_VERSION:
|
|
return g_kernel_key_version;
|
|
break;
|
|
case KERNEL_VERSION:
|
|
return g_kernel_version;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int WriteStoredVersion(int type, uint16_t version) {
|
|
switch (type) {
|
|
case FIRMWARE_KEY_VERSION:
|
|
return (TPM_SUCCESS == TlclWrite(FIRMWARE_KEY_VERSION_NV_INDEX,
|
|
(uint8_t*) &version,
|
|
sizeof(uint16_t)));
|
|
break;
|
|
case FIRMWARE_VERSION:
|
|
return (TPM_SUCCESS == TlclWrite(FIRMWARE_VERSION_NV_INDEX,
|
|
(uint8_t*) &version,
|
|
sizeof(uint16_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;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void LockStoredVersion(int type) {
|
|
/* TODO(gauravsh): Add error checking here to make sure TlclWriteLock
|
|
* did not fail. We must jump to recovery in that case.
|
|
*/
|
|
switch (type) {
|
|
case FIRMWARE_KEY_VERSION:
|
|
TlclWriteLock(FIRMWARE_KEY_VERSION_NV_INDEX);
|
|
break;
|
|
case FIRMWARE_VERSION:
|
|
TlclWriteLock(FIRMWARE_VERSION_NV_INDEX);
|
|
break;
|
|
case KERNEL_KEY_VERSION:
|
|
TlclWriteLock(KERNEL_KEY_VERSION_NV_INDEX);
|
|
break;
|
|
case KERNEL_VERSION:
|
|
TlclWriteLock(KERNEL_VERSION_NV_INDEX);
|
|
break;
|
|
}
|
|
}
|