1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2010 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker */
5*8617a60dSAndroid Build Coastguard Worker
6*8617a60dSAndroid Build Coastguard Worker /* This program mimicks the TPM usage from read-only firmware. It exercises
7*8617a60dSAndroid Build Coastguard Worker * the TPM functionality needed in the read-only firmware. It is meant to be
8*8617a60dSAndroid Build Coastguard Worker * integrated with the rest of the read-only firmware. It is also provided as
9*8617a60dSAndroid Build Coastguard Worker * a test.
10*8617a60dSAndroid Build Coastguard Worker */
11*8617a60dSAndroid Build Coastguard Worker
12*8617a60dSAndroid Build Coastguard Worker #include <stdio.h>
13*8617a60dSAndroid Build Coastguard Worker #include <stdint.h>
14*8617a60dSAndroid Build Coastguard Worker #include <stdlib.h>
15*8617a60dSAndroid Build Coastguard Worker
16*8617a60dSAndroid Build Coastguard Worker #include "tlcl.h"
17*8617a60dSAndroid Build Coastguard Worker
18*8617a60dSAndroid Build Coastguard Worker /* These index values are used to create NVRAM spaces. They only need to be
19*8617a60dSAndroid Build Coastguard Worker * unique.
20*8617a60dSAndroid Build Coastguard Worker */
21*8617a60dSAndroid Build Coastguard Worker #define INDEX0 0xda70
22*8617a60dSAndroid Build Coastguard Worker #define INDEX1 0xda71
23*8617a60dSAndroid Build Coastguard Worker #define INDEX2 0xda72
24*8617a60dSAndroid Build Coastguard Worker #define INDEX3 0xda73
25*8617a60dSAndroid Build Coastguard Worker
26*8617a60dSAndroid Build Coastguard Worker #define INDEX_INITIALIZED 0xda80
27*8617a60dSAndroid Build Coastguard Worker
28*8617a60dSAndroid Build Coastguard Worker /* This is called once at initialization time. It may be called again from
29*8617a60dSAndroid Build Coastguard Worker * recovery mode to rebuild the spaces if something incomprehensible happened
30*8617a60dSAndroid Build Coastguard Worker * and the spaces are gone or messed up. This is called after TPM_Startup and
31*8617a60dSAndroid Build Coastguard Worker * before the spaces are write-locked, so there is a chance that they can be
32*8617a60dSAndroid Build Coastguard Worker * recreated (but who knows---if anything can happen, there are plenty of ways
33*8617a60dSAndroid Build Coastguard Worker * of making this FUBAR).
34*8617a60dSAndroid Build Coastguard Worker */
InitializeSpaces(void)35*8617a60dSAndroid Build Coastguard Worker void InitializeSpaces(void) {
36*8617a60dSAndroid Build Coastguard Worker uint32_t zero = 0;
37*8617a60dSAndroid Build Coastguard Worker uint32_t perm = TPM_NV_PER_WRITE_STCLEAR | TPM_NV_PER_PPWRITE;
38*8617a60dSAndroid Build Coastguard Worker
39*8617a60dSAndroid Build Coastguard Worker printf("Initializing spaces\n");
40*8617a60dSAndroid Build Coastguard Worker TlclSetNvLocked(); /* useful only the first time */
41*8617a60dSAndroid Build Coastguard Worker
42*8617a60dSAndroid Build Coastguard Worker TlclDefineSpace(INDEX0, perm, 4);
43*8617a60dSAndroid Build Coastguard Worker TlclWrite(INDEX0, (uint8_t *) &zero, 4);
44*8617a60dSAndroid Build Coastguard Worker TlclDefineSpace(INDEX1, perm, 4);
45*8617a60dSAndroid Build Coastguard Worker TlclWrite(INDEX1, (uint8_t *) &zero, 4);
46*8617a60dSAndroid Build Coastguard Worker TlclDefineSpace(INDEX2, perm, 4);
47*8617a60dSAndroid Build Coastguard Worker TlclWrite(INDEX2, (uint8_t *) &zero, 4);
48*8617a60dSAndroid Build Coastguard Worker TlclDefineSpace(INDEX3, perm, 4);
49*8617a60dSAndroid Build Coastguard Worker TlclWrite(INDEX3, (uint8_t *) &zero, 4);
50*8617a60dSAndroid Build Coastguard Worker
51*8617a60dSAndroid Build Coastguard Worker perm = (TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR |
52*8617a60dSAndroid Build Coastguard Worker TPM_NV_PER_PPWRITE);
53*8617a60dSAndroid Build Coastguard Worker TlclDefineSpace(INDEX_INITIALIZED, perm, 1);
54*8617a60dSAndroid Build Coastguard Worker }
55*8617a60dSAndroid Build Coastguard Worker
56*8617a60dSAndroid Build Coastguard Worker
EnterRecoveryMode(void)57*8617a60dSAndroid Build Coastguard Worker void EnterRecoveryMode(void) {
58*8617a60dSAndroid Build Coastguard Worker printf("entering recovery mode");
59*8617a60dSAndroid Build Coastguard Worker exit(0);
60*8617a60dSAndroid Build Coastguard Worker }
61*8617a60dSAndroid Build Coastguard Worker
62*8617a60dSAndroid Build Coastguard Worker
main(int argc,char ** argv)63*8617a60dSAndroid Build Coastguard Worker int main(int argc, char** argv) {
64*8617a60dSAndroid Build Coastguard Worker uint8_t c;
65*8617a60dSAndroid Build Coastguard Worker uint32_t index_0, index_1, index_2, index_3;
66*8617a60dSAndroid Build Coastguard Worker
67*8617a60dSAndroid Build Coastguard Worker TlclLibInit();
68*8617a60dSAndroid Build Coastguard Worker
69*8617a60dSAndroid Build Coastguard Worker TlclStartup();
70*8617a60dSAndroid Build Coastguard Worker TlclSelfTestFull();
71*8617a60dSAndroid Build Coastguard Worker
72*8617a60dSAndroid Build Coastguard Worker TlclAssertPhysicalPresence();
73*8617a60dSAndroid Build Coastguard Worker
74*8617a60dSAndroid Build Coastguard Worker /* Checks if initialization has completed by trying to read-lock a space
75*8617a60dSAndroid Build Coastguard Worker * that's created at the end of initialization.
76*8617a60dSAndroid Build Coastguard Worker */
77*8617a60dSAndroid Build Coastguard Worker if (TlclRead(INDEX_INITIALIZED, &c, 0) == TPM_E_BADINDEX) {
78*8617a60dSAndroid Build Coastguard Worker /* The initialization did not complete.
79*8617a60dSAndroid Build Coastguard Worker */
80*8617a60dSAndroid Build Coastguard Worker InitializeSpaces();
81*8617a60dSAndroid Build Coastguard Worker }
82*8617a60dSAndroid Build Coastguard Worker
83*8617a60dSAndroid Build Coastguard Worker /* Checks if spaces are OK or messed up.
84*8617a60dSAndroid Build Coastguard Worker */
85*8617a60dSAndroid Build Coastguard Worker if (TlclRead(INDEX0, (uint8_t*) &index_0,
86*8617a60dSAndroid Build Coastguard Worker sizeof(index_0)) != TPM_SUCCESS ||
87*8617a60dSAndroid Build Coastguard Worker TlclRead(INDEX1, (uint8_t*) &index_1,
88*8617a60dSAndroid Build Coastguard Worker sizeof(index_1)) != TPM_SUCCESS ||
89*8617a60dSAndroid Build Coastguard Worker TlclRead(INDEX2, (uint8_t*) &index_2,
90*8617a60dSAndroid Build Coastguard Worker sizeof(index_2)) != TPM_SUCCESS ||
91*8617a60dSAndroid Build Coastguard Worker TlclRead(INDEX3, (uint8_t*) &index_3,
92*8617a60dSAndroid Build Coastguard Worker sizeof(index_3)) != TPM_SUCCESS) {
93*8617a60dSAndroid Build Coastguard Worker EnterRecoveryMode();
94*8617a60dSAndroid Build Coastguard Worker }
95*8617a60dSAndroid Build Coastguard Worker
96*8617a60dSAndroid Build Coastguard Worker /* Writes space, and locks it. Then attempts to write again. I really wish
97*8617a60dSAndroid Build Coastguard Worker * I could use the imperative.
98*8617a60dSAndroid Build Coastguard Worker */
99*8617a60dSAndroid Build Coastguard Worker index_0 += 1;
100*8617a60dSAndroid Build Coastguard Worker if (TlclWrite(INDEX0, (uint8_t*) &index_0,
101*8617a60dSAndroid Build Coastguard Worker sizeof(index_0) != TPM_SUCCESS)) {
102*8617a60dSAndroid Build Coastguard Worker error("could not write index 0\n");
103*8617a60dSAndroid Build Coastguard Worker }
104*8617a60dSAndroid Build Coastguard Worker TlclWriteLock(INDEX0);
105*8617a60dSAndroid Build Coastguard Worker if (TlclWrite(INDEX0, (uint8_t*) &index_0,
106*8617a60dSAndroid Build Coastguard Worker sizeof(index_0)) == TPM_SUCCESS) {
107*8617a60dSAndroid Build Coastguard Worker error("index 0 is not locked\n");
108*8617a60dSAndroid Build Coastguard Worker }
109*8617a60dSAndroid Build Coastguard Worker
110*8617a60dSAndroid Build Coastguard Worker /* Done for now.
111*8617a60dSAndroid Build Coastguard Worker */
112*8617a60dSAndroid Build Coastguard Worker printf("TEST SUCCEEDED\n");
113*8617a60dSAndroid Build Coastguard Worker exit(0);
114*8617a60dSAndroid Build Coastguard Worker }
115