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