Index: tests/tpm_lite/readonly.c |
diff --git a/tests/tpm_lite/readonly.c b/tests/tpm_lite/readonly.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9c49ec1d401ffa39fd0916b789d948c45c9f3ba1 |
--- /dev/null |
+++ b/tests/tpm_lite/readonly.c |
@@ -0,0 +1,110 @@ |
+/* 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. |
+ */ |
+ |
+/* This program mimicks the TPM usage from read-only firmware. It exercises |
+ * the TPM functionality needed in the read-only firmware. It is meant to be |
+ * integrated with the rest of the read-only firmware. It is also provided as |
+ * a test. |
+ */ |
+ |
+#include <stdio.h> |
+#include <stdint.h> |
+#include <stdlib.h> |
+#include <tss/tcs.h> |
+ |
+#include "tlcl.h" |
+#include "utility.h" |
+ |
+/* These index values are used to create NVRAM spaces. They only need to be |
+ * unique. |
+ */ |
+#define INDEX0 0xda70 |
+#define INDEX1 0xda71 |
+#define INDEX2 0xda72 |
+#define INDEX3 0xda73 |
+ |
+#define INDEX_INITIALIZED 0xda80 |
+ |
+/* This is called once at initialization time. It may be called again from |
+ * recovery mode to rebuild the spaces if something incomprehensible happened |
+ * and the spaces are gone or messed up. This is called after TPM_Startup and |
+ * before the spaces are write-locked, so there is a chance that they can be |
+ * recreated (but who knows---if anything can happen, there are plenty of ways |
+ * of making this FUBAR). |
+ */ |
+void InitializeSpaces(void) { |
+ uint32_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(INDEX0, perm, 4); |
+ TlclWrite(INDEX0, (uint8_t *) &zero, 4); |
+ TlclDefineSpace(INDEX1, perm, 4); |
+ TlclWrite(INDEX1, (uint8_t *) &zero, 4); |
+ TlclDefineSpace(INDEX2, perm, 4); |
+ TlclWrite(INDEX2, (uint8_t *) &zero, 4); |
+ TlclDefineSpace(INDEX3, perm, 4); |
+ TlclWrite(INDEX3, (uint8_t *) &zero, 4); |
+ |
+ perm = TPM_NV_PER_READ_STCLEAR | TPM_NV_PER_WRITE_STCLEAR | |
+ TPM_NV_PER_PPWRITE; |
+ TlclDefineSpace(INDEX_INITIALIZED, perm, 1); |
+} |
+ |
+ |
+void EnterRecoveryMode(void) { |
+ printf("entering recovery mode"); |
+ exit(0); |
+} |
+ |
+ |
+int main(int argc, char** argv) { |
+ uint8_t c; |
+ uint32_t index_0, index_1, index_2, index_3; |
+ |
+ TlclLibInit(); |
+ |
+ TlclStartup(); |
+ TlclSelftestfull(); |
+ |
+ TlclAssertPhysicalPresence(); |
+ |
+ /* Checks if initialization has completed by trying to read-lock a space |
+ * that's created at the end of initialization. |
+ */ |
+ if (TlclRead(INDEX_INITIALIZED, &c, 0) == TPM_E_BADINDEX) { |
+ /* The initialization did not complete. |
+ */ |
+ InitializeSpaces(); |
+ } |
+ |
+ /* Checks if spaces are OK or messed up. |
+ */ |
+ if (TlclRead(INDEX0, (uint8_t*) &index_0, sizeof(index_0)) != TPM_SUCCESS || |
+ TlclRead(INDEX1, (uint8_t*) &index_1, sizeof(index_1)) != TPM_SUCCESS || |
+ TlclRead(INDEX2, (uint8_t*) &index_2, sizeof(index_2)) != TPM_SUCCESS || |
+ TlclRead(INDEX3, (uint8_t*) &index_3, sizeof(index_3)) != TPM_SUCCESS) { |
+ EnterRecoveryMode(); |
+ } |
+ |
+ /* Writes space, and locks it. Then attempts to write again. I really wish |
+ * I could use the imperative. |
+ */ |
+ index_0 += 1; |
+ if (TlclWrite(INDEX0, (uint8_t*) &index_0, sizeof(index_0) != TPM_SUCCESS)) { |
+ error("could not write index 0\n"); |
+ } |
+ TlclWriteLock(INDEX0); |
+ if (TlclWrite(INDEX0, (uint8_t*) &index_0, sizeof(index_0)) == TPM_SUCCESS) { |
+ error("index 0 is not locked\n"); |
+ } |
+ |
+ /* Done for now. |
+ */ |
+ printf("Test completed successfully\n"); |
+ exit(0); |
+} |