summaryrefslogtreecommitdiffstats
path: root/src/tpm_tpm12_tis.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tpm_tpm12_tis.c')
-rw-r--r--src/tpm_tpm12_tis.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/src/tpm_tpm12_tis.c b/src/tpm_tpm12_tis.c
new file mode 100644
index 0000000..0253cba
--- /dev/null
+++ b/src/tpm_tpm12_tis.c
@@ -0,0 +1,280 @@
+/********************************************************************************/
+/* */
+/* TPM TIS I/O */
+/* Written by Ken Goldman */
+/* IBM Thomas J. Watson Research Center */
+/* $Id: tpm_tis.c 4505 2011-03-20 17:43:27Z kgoldman $ */
+/* */
+/* (c) Copyright IBM Corporation 2006, 2011. */
+/* */
+/* All rights reserved. */
+/* */
+/* Redistribution and use in source and binary forms, with or without */
+/* modification, are permitted provided that the following conditions are */
+/* met: */
+/* */
+/* Redistributions of source code must retain the above copyright notice, */
+/* this list of conditions and the following disclaimer. */
+/* */
+/* Redistributions in binary form must reproduce the above copyright */
+/* notice, this list of conditions and the following disclaimer in the */
+/* documentation and/or other materials provided with the distribution. */
+/* */
+/* Neither the names of the IBM Corporation nor the names of its */
+/* contributors may be used to endorse or promote products derived from */
+/* this software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
+/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
+/* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
+/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/********************************************************************************/
+
+/*
+ This file implements the TPM TIS interface out-of-band commands.
+*/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "tpm12/tpm_crypto.h"
+#include "tpm12/tpm_cryptoh.h"
+#include "tpm_debug.h"
+#include "tpm_error.h"
+#include "tpm12/tpm_digest.h"
+#include "tpm12/tpm_global.h"
+#include "tpm12/tpm_pcr.h"
+#include "tpm12/tpm_permanent.h"
+#include "tpm12/tpm_platform.h"
+#include "tpm12/tpm_process.h"
+#include "tpm12/tpm_transport.h"
+
+#include "tpm_tis.h"
+
+/* These commands do not test for TPM_ContinueSelfTest:
+
+ The following operations MUST be available after TPM_Init and before a call to
+ TPM_ContinueSelfTest 1.9. TPM_HASH_START / TPM_HASH_DATA / TPM_HASH_END */
+
+/* TPM_IO_Hash_Start() implements the LPC bus TPM_HASH_START command
+ */
+TPM_RESULT TPM12_IO_Hash_Start(void)
+{
+ TPM_RESULT rc = 0;
+ tpm_state_t *tpm_state = tpm_instances[0]; /* TPM global state */
+ TPM_PCRVALUE zeroPCR;
+ TPM_BOOL altered = FALSE; /* TRUE if the structure has been changed */
+
+ printf("\nTPM_IO_Hash_Start: Ordinal Entry\n");
+ TPM_Digest_Init(zeroPCR);
+
+ /* Prior to receiving the TPM_HASH_START command the TPM must have received a TPM_Startup
+ command. If the TPM receives a TPM_HASH_START after a TPM_Init but before a startup command,
+ the TPM treats this as an error */
+ if (rc == 0) {
+ if (tpm_state->tpm_stany_flags.postInitialise) {
+ printf("TPM_IO_Hash_Start: Error, postInitialise is TRUE\n");
+ rc = TPM_INVALID_POSTINIT;
+ }
+ }
+ /* NOTE: Done by caller
+ (1) If no TPM_ACCESS_x.activeLocality field is set, the TPM MUST set the
+ TPM_ACCESS_x.activeLocality field to indicate Locality 4. Any currently executing command
+ MUST be aborted per and subject to Section 11.2.3. */
+ /* NOTE: Done by caller
+ (2) If TPM_ACCESS_x.activeLocality is set, and if the TPM_ACCESS_x.activeLocality field is
+ not 4, the TPM MUST ignore this command. */
+ /* NOTE: Done by caller
+ (3) The TPM MUST clear the write FIFO. */
+ if (rc == 0) {
+ /* (4) If there is an exclusive transport session, it MUST be invalidated. */
+ if (tpm_state->tpm_stany_flags.transportExclusive != 0) { /* active exclusive */
+ rc = TPM_TransportSessions_TerminateHandle
+ (tpm_state->tpm_stclear_data.transSessions,
+ tpm_state->tpm_stany_flags.transportExclusive,
+ &(tpm_state->tpm_stany_flags.transportExclusive));
+ }
+ }
+ if (rc == 0) {
+ /* (5) Set the TPM_PERMANENT_FLAGS->tpmEstablished flag to TRUE (1). Note: see description of
+ Bit Field: tpmEstablishment in 11.2.11 Access Register. */
+ TPM_SetCapability_Flag(&altered,
+ &(tpm_state->tpm_permanent_flags.tpmEstablished),
+ TRUE);
+ }
+ if (rc == 0) {
+ /* (6) Set the TPM_STANY_FLAGS->TOSPresent flag to TRUE (1). */
+ tpm_state->tpm_stany_flags.TOSPresent = TRUE;
+ /* (7) Set PCRs per column labeled TPM_HASH_START in Table 5: PCR Initial and Reset Values.
+ (PCR 17-22 to zero, others unchanged */
+ TPM_PCR_Store(tpm_state->tpm_stclear_data.PCRS, 17, zeroPCR);
+ TPM_PCR_Store(tpm_state->tpm_stclear_data.PCRS, 18, zeroPCR);
+ TPM_PCR_Store(tpm_state->tpm_stclear_data.PCRS, 19, zeroPCR);
+ TPM_PCR_Store(tpm_state->tpm_stclear_data.PCRS, 20, zeroPCR);
+ TPM_PCR_Store(tpm_state->tpm_stclear_data.PCRS, 21, zeroPCR);
+ TPM_PCR_Store(tpm_state->tpm_stclear_data.PCRS, 22, zeroPCR);
+ /* (8) Ignore any data component of the TPM_HASH_START LPC command. */
+ /* (9) Allocate tempLocation of a size required to perform the SHA-1 operation. */
+ /* (10) Initialize tempLocation per SHA-1. */
+ rc = TPM_SHA1InitCmd(&(tpm_state->sha1_context_tis));
+ }
+ rc = TPM_PermanentAll_NVStore(tpm_state,
+ altered,
+ rc);
+ /*
+ 1) Upon any error in the above steps the TPM:
+ a) MUST enter Failure Mode.
+ NOTE: Done by caller
+ b) MUST release locality.
+ */
+ if (rc != 0) {
+ printf("TPM_IO_Hash_Start: Error, (fatal)\n");
+ printf(" TPM_IO_Hash_Start: Set testState to %u \n", TPM_TEST_STATE_FAILURE);
+ tpm_state->testState = TPM_TEST_STATE_FAILURE;
+ }
+ return rc;
+}
+
+/* TPM_IO_Hash_Data() implements the LPC bus TPM_HASH_DATA command
+ */
+TPM_RESULT TPM12_IO_Hash_Data(const unsigned char *data,
+ uint32_t data_length)
+{
+ TPM_RESULT rc = 0;
+ tpm_state_t *tpm_state = tpm_instances[0]; /* TPM global state */
+
+ printf("\nTPM_IO_Hash_Data: Ordinal Entry\n");
+ /* (1) Transform tempLocation per SHA-1 with data received from this command. */
+ /* (2) Repeat for each TPM_HASH_DATA LPC command received. */
+ if (rc == 0) {
+ if (tpm_state->sha1_context_tis == NULL) {
+ printf("TPM_IO_Hash_Data: Error, no existing SHA1 thread\n");
+ rc = TPM_SHA_THREAD;
+ }
+ }
+ if (rc == 0) {
+ rc = TPM_SHA1UpdateCmd(tpm_state->sha1_context_tis, data, data_length);
+ }
+ /*
+ 1) Upon any error in the above steps the TPM:
+ a) MUST enter Failure Mode.
+ NOTE: Done by caller
+ b) MUST release locality.
+ */
+ if (rc != 0) {
+ printf("TPM_IO_Hash_Data: Error, (fatal)\n");
+ printf(" TPM_IO_Hash_Data: Set testState to %u \n", TPM_TEST_STATE_FAILURE);
+ tpm_state->testState = TPM_TEST_STATE_FAILURE;
+ }
+ return rc;
+}
+
+/* TPM_IO_Hash_End() implements the LPC bus TPM_HASH_END command
+ */
+TPM_RESULT TPM12_IO_Hash_End(void)
+{
+ TPM_RESULT rc = 0;
+ TPM_PCRVALUE zeroPCR;
+ TPM_DIGEST extendDigest;
+ tpm_state_t *tpm_state = tpm_instances[0]; /* TPM global state */
+
+ printf("\nTPM_IO_Hash_End: Ordinal Entry\n");
+ if (rc == 0) {
+ if (tpm_state->sha1_context_tis == NULL) {
+ printf("TPM_IO_Hash_End: Error, no existing SHA1 thread\n");
+ rc = TPM_SHA_THREAD;
+ }
+ }
+ /* (1) Ignore any data sent with the command. */
+ /* (2) Perform finalize operation on tempLocation per SHA-1. */
+ if (rc == 0) {
+ rc = TPM_SHA1FinalCmd(extendDigest, tpm_state->sha1_context_tis);
+ }
+ /* (3) Perform an “extend” operation, as defined in the TPM_Extend command, of the value within
+ tempLocation into PCR[Locality 4]. */
+ if (rc == 0) {
+ /* In the previous line above, “PCR[Locality 4]” within and before the SHA-1 function is
+ TPM_PCRVALUE = 0 (i.e., 20 bytes of all zeros). */
+ TPM_Digest_Init(zeroPCR); /* initial PCR value */
+ /* PCR[Locality 4] = SHA-1( PCR[Locality 4] || tempLoc) */
+ rc = TPM_SHA1(tpm_state->tpm_stclear_data.PCRS[TPM_LOCALITY_4_PCR],
+ TPM_DIGEST_SIZE, zeroPCR,
+ TPM_DIGEST_SIZE, extendDigest,
+ 0, NULL);
+ }
+ /* NOTE: Done by caller
+ (4) Clear TPM_ACCESS_x.activeLocality for Locality 4. */
+ /*
+ 1) Upon any error in the above steps the TPM:
+ a) MUST enter Failure Mode.
+ NOTE: Done by caller
+ b) MUST release locality.
+ */
+ if (rc != 0) {
+ printf("TPM_IO_Hash_End: Error, (fatal)\n");
+ printf(" TPM_IO_Hash_End: Set testState to %u \n", TPM_TEST_STATE_FAILURE);
+ tpm_state->testState = TPM_TEST_STATE_FAILURE;
+ }
+ TPM_SHA1Delete(&(tpm_state->sha1_context_tis));
+ return rc;
+}
+
+TPM_RESULT TPM12_IO_TpmEstablished_Get(TPM_BOOL *tpmEstablished)
+{
+ TPM_RESULT rc = 0;
+ tpm_state_t *tpm_state = tpm_instances[0]; /* TPM global state */
+
+ if (rc == 0) {
+ *tpmEstablished = tpm_state->tpm_permanent_flags.tpmEstablished;
+ }
+ /*
+ 1) Upon any error in the above steps the TPM:
+ a) MUST enter Failure Mode.
+ NOTE: Done by caller
+ b) MUST release locality.
+ */
+ if (rc != 0) {
+ printf("TPM_IO_TpmEstablished_Get: Error, (fatal)\n");
+ printf(" TPM_IO_TpmEstablished_Get: Set testState to %u \n", TPM_TEST_STATE_FAILURE);
+ tpm_state->testState = TPM_TEST_STATE_FAILURE;
+ }
+ return 0;
+}
+
+TPM_RESULT TPM12_IO_TpmEstablished_Reset(void)
+{
+ TPM_RESULT returnCode = 0;
+ tpm_state_t *tpm_state = tpm_instances[0]; /* TPM global state */
+ TPM_BOOL writeAllNV = FALSE; /* flag to write back flags */
+
+ if (returnCode == TPM_SUCCESS) {
+ returnCode = TPM_IO_GetLocality(&(tpm_state->tpm_stany_flags.localityModifier),
+ tpm_state->tpm_number);
+ }
+
+ /* 1. Validate the assertion of locality 3 or locality 4 */
+ if (returnCode == TPM_SUCCESS) {
+ returnCode = TPM_Locality_Check(TPM_LOC_THREE | TPM_LOC_FOUR, /* BYTE bitmap */
+ tpm_state->tpm_stany_flags.localityModifier);
+ }
+ /* 2. Set TPM_PERMANENT_FLAGS -> tpmEstablished to FALSE */
+ if (returnCode == TPM_SUCCESS) {
+ TPM_SetCapability_Flag(&writeAllNV, /* altered */
+ &(tpm_state->tpm_permanent_flags.tpmEstablished), /* flag */
+ FALSE); /* value */
+
+ }
+ /* Store the permanent flags back to NVRAM */
+ returnCode = TPM_PermanentAll_NVStore(tpm_state,
+ writeAllNV,
+ returnCode);
+
+ return returnCode;
+}