diff options
Diffstat (limited to 'tests/tpm_lite/readonly.c')
-rw-r--r-- | tests/tpm_lite/readonly.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/tests/tpm_lite/readonly.c b/tests/tpm_lite/readonly.c new file mode 100644 index 00000000..9c49ec1d --- /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); +} |