blob: 89e97a3ce977c30055edfe5331aaa29f54d37895 [file] [log] [blame]
Gaurav Shahce0cc302010-03-24 13:48:55 -07001/* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 *
5 * Functions for querying, manipulating and locking rollback indices
6 * stored in the TPM NVRAM.
7 */
8
9#include "rollback_index.h"
10
11#include <stdint.h>
Gaurav Shahce0cc302010-03-24 13:48:55 -070012
Gaurav Shahf3dd1a62010-04-05 15:50:00 -070013#include "utility.h"
Gaurav Shahce0cc302010-03-24 13:48:55 -070014#include "tlcl.h"
Gaurav Shah887e3d42010-04-27 16:26:48 -070015#include "tss_constants.h"
Gaurav Shahce0cc302010-03-24 13:48:55 -070016
17uint16_t g_firmware_key_version = 0;
18uint16_t g_firmware_version = 0;
19uint16_t g_kernel_key_version = 0;
20uint16_t g_kernel_version = 0;
21
22static void InitializeSpaces(void) {
23 uint16_t zero = 0;
Luigi Semenzato596b6402010-05-27 14:04:52 -070024 uint32_t firmware_perm = TPM_NV_PER_GLOBALLOCK | TPM_NV_PER_PPWRITE;
25 uint32_t kernel_perm = TPM_NV_PER_PPWRITE;
Gaurav Shahce0cc302010-03-24 13:48:55 -070026
Gaurav Shahf3dd1a62010-04-05 15:50:00 -070027 debug("Initializing spaces\n");
Gaurav Shahce0cc302010-03-24 13:48:55 -070028 TlclSetNvLocked(); /* useful only the first time */
29
Luigi Semenzato596b6402010-05-27 14:04:52 -070030 TlclDefineSpace(FIRMWARE_KEY_VERSION_NV_INDEX,
31 firmware_perm, sizeof(uint16_t));
Gaurav Shahce0cc302010-03-24 13:48:55 -070032 TlclWrite(FIRMWARE_KEY_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
33
Luigi Semenzato596b6402010-05-27 14:04:52 -070034 TlclDefineSpace(FIRMWARE_VERSION_NV_INDEX, firmware_perm, sizeof(uint16_t));
Gaurav Shahce0cc302010-03-24 13:48:55 -070035 TlclWrite(FIRMWARE_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
36
Luigi Semenzato596b6402010-05-27 14:04:52 -070037 TlclDefineSpace(KERNEL_KEY_VERSION_NV_INDEX, kernel_perm, sizeof(uint16_t));
Gaurav Shahce0cc302010-03-24 13:48:55 -070038 TlclWrite(KERNEL_KEY_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
39
Luigi Semenzato596b6402010-05-27 14:04:52 -070040 TlclDefineSpace(KERNEL_VERSION_NV_INDEX, kernel_perm, sizeof(uint16_t));
Gaurav Shahce0cc302010-03-24 13:48:55 -070041 TlclWrite(KERNEL_VERSION_NV_INDEX, (uint8_t*) &zero, sizeof(uint16_t));
42}
43
44static void EnterRecovery(void) {
45 /* Temporary recovery stub. Currently just initalizes spaces. */
46 InitializeSpaces();
47}
48
49static int GetTPMRollbackIndices(void) {
50 /* We just perform the reads, making sure they succeed. A failure means that
51 * the rollback index locations are some how messed up and we must jump to
52 * recovery */
53 if (TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
54 (uint8_t*) &g_firmware_key_version,
55 sizeof(g_firmware_key_version)) ||
56 TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
57 (uint8_t*) &g_firmware_key_version,
58 sizeof(g_firmware_key_version)) ||
59 TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
Luigi Semenzato596b6402010-05-27 14:04:52 -070060 (uint8_t*) &g_firmware_key_version,
61 sizeof(g_firmware_key_version)) ||
Gaurav Shahce0cc302010-03-24 13:48:55 -070062 TPM_SUCCESS != TlclRead(FIRMWARE_KEY_VERSION_NV_INDEX,
63 (uint8_t*) &g_firmware_key_version,
64 sizeof(g_firmware_key_version)))
65 return 0;
66 return 1;
67}
68
69
70void SetupTPM(void) {
Luigi Semenzato596b6402010-05-27 14:04:52 -070071 uint8_t disable;
72 uint8_t deactivated;
Gaurav Shahce0cc302010-03-24 13:48:55 -070073 TlclLibinit();
74 TlclStartup();
75 /* TODO(gauravsh): The call to self test should probably be deferred.
76 * As per semenzato@chromium.org -
77 * TlclStartup should be called before the firmware initializes the memory
78 * controller, so the selftest can run in parallel with that. Here we should
79 * just call TlclSelftestFull to make sure the self test has
80 * completed---unless we want to rely on the NVRAM operations being available
81 * before the selftest completes. */
82 TlclSelftestfull();
83 TlclAssertPhysicalPresence();
Luigi Semenzato596b6402010-05-27 14:04:52 -070084 /* Check that the TPM is enabled and activated. */
85 if(TlclGetFlags(&disable, &deactivated) != TPM_SUCCESS) {
86 debug("failed to get TPM flags");
87 EnterRecovery();
88 }
89 if (disable || deactivated) {
90 TlclSetEnable();
91 if (TlclSetDeactivated(0) != TPM_SUCCESS) {
92 debug("failed to activate TPM");
93 EnterRecovery();
94 }
95 }
Gaurav Shahce0cc302010-03-24 13:48:55 -070096 if (!GetTPMRollbackIndices()) {
Luigi Semenzato596b6402010-05-27 14:04:52 -070097 debug("failed to get rollback indices");
Gaurav Shahce0cc302010-03-24 13:48:55 -070098 EnterRecovery();
99 }
100}
101
102
103uint16_t GetStoredVersion(int type) {
104 switch (type) {
105 case FIRMWARE_KEY_VERSION:
106 return g_firmware_key_version;
107 break;
108 case FIRMWARE_VERSION:
109 return g_firmware_version;
110 break;
111 case KERNEL_KEY_VERSION:
112 return g_kernel_key_version;
113 break;
114 case KERNEL_VERSION:
115 return g_kernel_version;
116 break;
117 }
118 return 0;
119}
120
121int WriteStoredVersion(int type, uint16_t version) {
122 switch (type) {
123 case FIRMWARE_KEY_VERSION:
124 return (TPM_SUCCESS == TlclWrite(FIRMWARE_KEY_VERSION_NV_INDEX,
125 (uint8_t*) &version,
126 sizeof(uint16_t)));
127 break;
128 case FIRMWARE_VERSION:
129 return (TPM_SUCCESS == TlclWrite(FIRMWARE_VERSION_NV_INDEX,
130 (uint8_t*) &version,
131 sizeof(uint16_t)));
132 break;
133 case KERNEL_KEY_VERSION:
134 return (TPM_SUCCESS == TlclWrite(KERNEL_KEY_VERSION_NV_INDEX,
135 (uint8_t*) &version,
136 sizeof(uint16_t)));
137 break;
138 case KERNEL_VERSION:
139 return (TPM_SUCCESS == TlclWrite(KERNEL_VERSION_NV_INDEX,
140 (uint8_t*) &version,
141 sizeof(uint16_t)));
142 break;
143 }
144 return 0;
145}
146
Luigi Semenzato596b6402010-05-27 14:04:52 -0700147void LockFirmwareVersions() {
148 if (TlclSetGlobalLock() != TPM_SUCCESS) {
149 debug("failed to set global lock");
150 EnterRecovery();
151 }
152}
153
154void LockKernelVersionsByLockingPP() {
155 if (TlclLockPhysicalPresence() != TPM_SUCCESS) {
156 debug("failed to turn off PP");
157 EnterRecovery();
Gaurav Shahce0cc302010-03-24 13:48:55 -0700158 }
159}