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