1 /********************************************************************************/
4 /* Written by Ken Goldman */
5 /* IBM Thomas J. Watson Research Center */
6 /* $Id: tpm_tis.c 4505 2011-03-20 17:43:27Z kgoldman $ */
8 /* (c) Copyright IBM Corporation 2006, 2011. */
10 /* All rights reserved. */
12 /* Redistribution and use in source and binary forms, with or without */
13 /* modification, are permitted provided that the following conditions are */
16 /* Redistributions of source code must retain the above copyright notice, */
17 /* this list of conditions and the following disclaimer. */
19 /* Redistributions in binary form must reproduce the above copyright */
20 /* notice, this list of conditions and the following disclaimer in the */
21 /* documentation and/or other materials provided with the distribution. */
23 /* Neither the names of the IBM Corporation nor the names of its */
24 /* contributors may be used to endorse or promote products derived from */
25 /* this software without specific prior written permission. */
27 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
28 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
29 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
30 /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
31 /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
32 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
33 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
34 /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
35 /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
36 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
37 /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
38 /********************************************************************************/
41 This file implements the TPM TIS interface out-of-band commands.
47 #include "tpm12/tpm_crypto.h"
48 #include "tpm12/tpm_cryptoh.h"
49 #include "tpm12/tpm_debug.h"
50 #include "tpm_error.h"
51 #include "tpm12/tpm_digest.h"
52 #include "tpm12/tpm_global.h"
53 #include "tpm12/tpm_pcr.h"
54 #include "tpm12/tpm_permanent.h"
55 #include "tpm12/tpm_platform.h"
56 #include "tpm12/tpm_process.h"
57 #include "tpm12/tpm_transport.h"
61 /* These commands do not test for TPM_ContinueSelfTest:
63 The following operations MUST be available after TPM_Init and before a call to
64 TPM_ContinueSelfTest 1.9. TPM_HASH_START / TPM_HASH_DATA / TPM_HASH_END */
66 /* TPM_IO_Hash_Start() implements the LPC bus TPM_HASH_START command
68 TPM_RESULT
TPM12_IO_Hash_Start(void)
71 tpm_state_t
*tpm_state
= tpm_instances
[0]; /* TPM global state */
73 TPM_BOOL altered
= FALSE
; /* TRUE if the structure has been changed */
75 printf("\nTPM_IO_Hash_Start: Ordinal Entry\n");
76 TPM_Digest_Init(zeroPCR
);
78 /* Prior to receiving the TPM_HASH_START command the TPM must have received a TPM_Startup
79 command. If the TPM receives a TPM_HASH_START after a TPM_Init but before a startup command,
80 the TPM treats this as an error */
82 if (tpm_state
->tpm_stany_flags
.postInitialise
) {
83 printf("TPM_IO_Hash_Start: Error, postInitialise is TRUE\n");
84 rc
= TPM_INVALID_POSTINIT
;
87 /* NOTE: Done by caller
88 (1) If no TPM_ACCESS_x.activeLocality field is set, the TPM MUST set the
89 TPM_ACCESS_x.activeLocality field to indicate Locality 4. Any currently executing command
90 MUST be aborted per and subject to Section 11.2.3. */
91 /* NOTE: Done by caller
92 (2) If TPM_ACCESS_x.activeLocality is set, and if the TPM_ACCESS_x.activeLocality field is
93 not 4, the TPM MUST ignore this command. */
94 /* NOTE: Done by caller
95 (3) The TPM MUST clear the write FIFO. */
97 /* (4) If there is an exclusive transport session, it MUST be invalidated. */
98 if (tpm_state
->tpm_stany_flags
.transportExclusive
!= 0) { /* active exclusive */
99 rc
= TPM_TransportSessions_TerminateHandle
100 (tpm_state
->tpm_stclear_data
.transSessions
,
101 tpm_state
->tpm_stany_flags
.transportExclusive
,
102 &(tpm_state
->tpm_stany_flags
.transportExclusive
));
106 /* (5) Set the TPM_PERMANENT_FLAGS->tpmEstablished flag to TRUE (1). Note: see description of
107 Bit Field: tpmEstablishment in 11.2.11 Access Register. */
108 TPM_SetCapability_Flag(&altered
,
109 &(tpm_state
->tpm_permanent_flags
.tpmEstablished
),
113 /* (6) Set the TPM_STANY_FLAGS->TOSPresent flag to TRUE (1). */
114 tpm_state
->tpm_stany_flags
.TOSPresent
= TRUE
;
115 /* (7) Set PCRs per column labeled TPM_HASH_START in Table 5: PCR Initial and Reset Values.
116 (PCR 17-22 to zero, others unchanged */
117 TPM_PCR_Store(tpm_state
->tpm_stclear_data
.PCRS
, 17, zeroPCR
);
118 TPM_PCR_Store(tpm_state
->tpm_stclear_data
.PCRS
, 18, zeroPCR
);
119 TPM_PCR_Store(tpm_state
->tpm_stclear_data
.PCRS
, 19, zeroPCR
);
120 TPM_PCR_Store(tpm_state
->tpm_stclear_data
.PCRS
, 20, zeroPCR
);
121 TPM_PCR_Store(tpm_state
->tpm_stclear_data
.PCRS
, 21, zeroPCR
);
122 TPM_PCR_Store(tpm_state
->tpm_stclear_data
.PCRS
, 22, zeroPCR
);
123 /* (8) Ignore any data component of the TPM_HASH_START LPC command. */
124 /* (9) Allocate tempLocation of a size required to perform the SHA-1 operation. */
125 /* (10) Initialize tempLocation per SHA-1. */
126 rc
= TPM_SHA1InitCmd(&(tpm_state
->sha1_context_tis
));
128 rc
= TPM_PermanentAll_NVStore(tpm_state
,
132 1) Upon any error in the above steps the TPM:
133 a) MUST enter Failure Mode.
135 b) MUST release locality.
138 printf("TPM_IO_Hash_Start: Error, (fatal)\n");
139 printf(" TPM_IO_Hash_Start: Set testState to %u \n", TPM_TEST_STATE_FAILURE
);
140 tpm_state
->testState
= TPM_TEST_STATE_FAILURE
;
145 /* TPM_IO_Hash_Data() implements the LPC bus TPM_HASH_DATA command
147 TPM_RESULT
TPM12_IO_Hash_Data(const unsigned char *data
,
148 uint32_t data_length
)
151 tpm_state_t
*tpm_state
= tpm_instances
[0]; /* TPM global state */
153 printf("\nTPM_IO_Hash_Data: Ordinal Entry\n");
154 /* (1) Transform tempLocation per SHA-1 with data received from this command. */
155 /* (2) Repeat for each TPM_HASH_DATA LPC command received. */
157 if (tpm_state
->sha1_context_tis
== NULL
) {
158 printf("TPM_IO_Hash_Data: Error, no existing SHA1 thread\n");
163 rc
= TPM_SHA1UpdateCmd(tpm_state
->sha1_context_tis
, data
, data_length
);
166 1) Upon any error in the above steps the TPM:
167 a) MUST enter Failure Mode.
169 b) MUST release locality.
172 printf("TPM_IO_Hash_Data: Error, (fatal)\n");
173 printf(" TPM_IO_Hash_Data: Set testState to %u \n", TPM_TEST_STATE_FAILURE
);
174 tpm_state
->testState
= TPM_TEST_STATE_FAILURE
;
179 /* TPM_IO_Hash_End() implements the LPC bus TPM_HASH_END command
181 TPM_RESULT
TPM12_IO_Hash_End(void)
184 TPM_PCRVALUE zeroPCR
;
185 TPM_DIGEST extendDigest
;
186 tpm_state_t
*tpm_state
= tpm_instances
[0]; /* TPM global state */
188 printf("\nTPM_IO_Hash_End: Ordinal Entry\n");
190 if (tpm_state
->sha1_context_tis
== NULL
) {
191 printf("TPM_IO_Hash_End: Error, no existing SHA1 thread\n");
195 /* (1) Ignore any data sent with the command. */
196 /* (2) Perform finalize operation on tempLocation per SHA-1. */
198 rc
= TPM_SHA1FinalCmd(extendDigest
, tpm_state
->sha1_context_tis
);
200 /* (3) Perform an “extend” operation, as defined in the TPM_Extend command, of the value within
201 tempLocation into PCR[Locality 4]. */
203 /* In the previous line above, “PCR[Locality 4]” within and before the SHA-1 function is
204 TPM_PCRVALUE = 0 (i.e., 20 bytes of all zeros). */
205 TPM_Digest_Init(zeroPCR
); /* initial PCR value */
206 /* PCR[Locality 4] = SHA-1( PCR[Locality 4] || tempLoc) */
207 rc
= TPM_SHA1(tpm_state
->tpm_stclear_data
.PCRS
[TPM_LOCALITY_4_PCR
],
208 TPM_DIGEST_SIZE
, zeroPCR
,
209 TPM_DIGEST_SIZE
, extendDigest
,
212 /* NOTE: Done by caller
213 (4) Clear TPM_ACCESS_x.activeLocality for Locality 4. */
215 1) Upon any error in the above steps the TPM:
216 a) MUST enter Failure Mode.
218 b) MUST release locality.
221 printf("TPM_IO_Hash_End: Error, (fatal)\n");
222 printf(" TPM_IO_Hash_End: Set testState to %u \n", TPM_TEST_STATE_FAILURE
);
223 tpm_state
->testState
= TPM_TEST_STATE_FAILURE
;
225 TPM_SHA1Delete(&(tpm_state
->sha1_context_tis
));
229 TPM_RESULT
TPM12_IO_TpmEstablished_Get(TPM_BOOL
*tpmEstablished
)
232 tpm_state_t
*tpm_state
= tpm_instances
[0]; /* TPM global state */
235 *tpmEstablished
= tpm_state
->tpm_permanent_flags
.tpmEstablished
;
238 1) Upon any error in the above steps the TPM:
239 a) MUST enter Failure Mode.
241 b) MUST release locality.
244 printf("TPM_IO_TpmEstablished_Get: Error, (fatal)\n");
245 printf(" TPM_IO_TpmEstablished_Get: Set testState to %u \n", TPM_TEST_STATE_FAILURE
);
246 tpm_state
->testState
= TPM_TEST_STATE_FAILURE
;
251 TPM_RESULT
TPM12_IO_TpmEstablished_Reset(void)
253 TPM_RESULT returnCode
= 0;
254 tpm_state_t
*tpm_state
= tpm_instances
[0]; /* TPM global state */
255 TPM_BOOL writeAllNV
= FALSE
; /* flag to write back flags */
257 if (returnCode
== TPM_SUCCESS
) {
258 returnCode
= TPM_IO_GetLocality(&(tpm_state
->tpm_stany_flags
.localityModifier
),
259 tpm_state
->tpm_number
);
262 /* 1. Validate the assertion of locality 3 or locality 4 */
263 if (returnCode
== TPM_SUCCESS
) {
264 returnCode
= TPM_Locality_Check(TPM_LOC_THREE
| TPM_LOC_FOUR
, /* BYTE bitmap */
265 tpm_state
->tpm_stany_flags
.localityModifier
);
267 /* 2. Set TPM_PERMANENT_FLAGS -> tpmEstablished to FALSE */
268 if (returnCode
== TPM_SUCCESS
) {
269 TPM_SetCapability_Flag(&writeAllNV
, /* altered */
270 &(tpm_state
->tpm_permanent_flags
.tpmEstablished
), /* flag */
274 /* Store the permanent flags back to NVRAM */
275 returnCode
= TPM_PermanentAll_NVStore(tpm_state
,