Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1169)

Unified Diff: src/platform/vboot_reference/utils/rollback_index.c

Issue 1241002: VBoot Reference: Add version checking to for preventing rollbacks. (Closed)
Patch Set: . Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/platform/vboot_reference/utils/firmware_image.c ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/platform/vboot_reference/utils/rollback_index.c
diff --git a/src/platform/vboot_reference/utils/rollback_index.c b/src/platform/vboot_reference/utils/rollback_index.c
new file mode 100644
index 0000000000000000000000000000000000000000..0b65bf490f6c574709b7b525773027d73fff407e
--- /dev/null
+++ b/src/platform/vboot_reference/utils/rollback_index.c
@@ -0,0 +1,148 @@
+/* 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 <tss/tcs.h>
+
+#include "tlcl.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;
+
+ printf("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()) {
+ fprintf(stderr, "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;
+ }
+}
« no previous file with comments | « src/platform/vboot_reference/utils/firmware_image.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698