1 /********************************************************************************/
2 /* */
3 /* TSS Primary API for TPM 2.0 */
4 /* Written by Ken Goldman */
5 /* IBM Thomas J. Watson Research Center */
6 /* */
7 /* (c) Copyright IBM Corporation 2018 - 2020 */
8 /* */
9 /* All rights reserved. */
10 /* */
11 /* Redistribution and use in source and binary forms, with or without */
12 /* modification, are permitted provided that the following conditions are */
13 /* met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright notice, */
16 /* this list of conditions and the following disclaimer. */
17 /* */
18 /* Redistributions in binary form must reproduce the above copyright */
19 /* notice, this list of conditions and the following disclaimer in the */
20 /* documentation and/or other materials provided with the distribution. */
21 /* */
22 /* Neither the names of the IBM Corporation nor the names of its */
23 /* contributors may be used to endorse or promote products derived from */
24 /* this software without specific prior written permission. */
25 /* */
26 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
27 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
28 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
29 /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
30 /* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
31 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
32 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
33 /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */
34 /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
35 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
36 /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
37 /********************************************************************************/
38
39 #include <stdlib.h>
40 #include <string.h>
41 #include <stdarg.h>
42 #include <errno.h>
43
44 #ifdef TPM_POSIX
45 #include <netinet/in.h>
46 #endif
47 #ifdef TPM_WINDOWS
48 #include <winsock2.h>
49 #endif
50
51 #include "tssauth.h"
52 #include "tssauth20.h"
53 #include <ibmtss/tss.h>
54 #include "tssproperties.h"
55 #include <ibmtss/tsstransmit.h>
56 #include <ibmtss/tssutils.h>
57 #include <ibmtss/tssresponsecode.h>
58 #include <ibmtss/tssmarshal.h>
59 #include <ibmtss/Unmarshal_fp.h>
60 #include "tssccattributes.h"
61 #ifndef TPM_TSS_NOCRYPTO
62 #include <ibmtss/tsscrypto.h>
63 #include <ibmtss/tsscryptoh.h>
64 #endif
65 #include <ibmtss/tssprintcmd.h>
66 #include "tss20.h"
67
68 /* Files:
69
70 h01xxxxxx.bin - NV index name
71 h02xxxxxx.bin - hmac session context
72 h03xxxxxx.bin - policy session context
73 h80xxxxxx.bin - transient object name
74
75 cxxxx...xxxx.bin - context blob name
76 */
77
78 /* NOTE Synchronize with
79
80 TSS_HmacSession_InitContext
81 TSS_HmacSession_Unmarshal
82 TSS_HmacSession_Marshal
83 */
84
85 struct TSS_HMAC_CONTEXT {
86 TPMI_SH_AUTH_SESSION sessionHandle; /* the session handle */
87 TPMI_ALG_HASH authHashAlg; /* hash algorithm to use for the session */
88 #ifndef TPM_TSS_NOCRYPTO
89 uint32_t sizeInBytes; /* hash algorithm mapped to size */
90 #endif /* TPM_TSS_NOCRYPTO */
91 TPMT_SYM_DEF symmetric; /* the algorithm and key size for parameter
92 encryption */
93 TPMI_DH_ENTITY bind; /* bind handle */
94 TPM2B_NAME bindName; /* Name corresponding to the the bind
95 handle */
96 TPM2B_AUTH bindAuthValue; /* password corresponding to the bind
97 handle */
98 #ifndef TPM_TSS_NOCRYPTO
99 TPM2B_NONCE nonceTPM; /* from TPM in response */
100 TPM2B_NONCE nonceCaller; /* from caller in command */
101 TPM2B_DIGEST sessionKey; /* from KDFa at session creation */
102 #endif /* TPM_TSS_NOCRYPTO */
103 TPM_SE sessionType; /* HMAC (0), policy (1), or trial policy */
104 uint8_t isPasswordNeeded; /* flag set by policy password */
105 uint8_t isAuthValueNeeded; /* flag set by policy authvalue */
106 /* Items below this line are for the lifetime of one command. They are not saved and loaded. */
107 TPM2B_KEY hmacKey; /* HMAC key calculated for each command */
108 #ifndef TPM_TSS_NOCRYPTO
109 TPM2B_KEY sessionValue; /* KDFa secret for parameter encryption */
110 #endif /* TPM_TSS_NOCRYPTO */
111 } TSS_HMAC_CONTEXT;
112
113 /* functions for command pre- and post- processing */
114
115 typedef TPM_RC (*TSS_PreProcessFunction_t)(TSS_CONTEXT *tssContext,
116 COMMAND_PARAMETERS *in,
117 EXTRA_PARAMETERS *extra);
118 typedef TPM_RC (*TSS_ChangeAuthFunction_t)(TSS_CONTEXT *tssContext,
119 struct TSS_HMAC_CONTEXT *session,
120 size_t handleNumber,
121 COMMAND_PARAMETERS *in);
122 typedef TPM_RC (*TSS_PostProcessFunction_t)(TSS_CONTEXT *tssContext,
123 COMMAND_PARAMETERS *in,
124 RESPONSE_PARAMETERS *out,
125 EXTRA_PARAMETERS *extra);
126
127 static TPM_RC TSS_PR_StartAuthSession(TSS_CONTEXT *tssContext,
128 StartAuthSession_In *in,
129 StartAuthSession_Extra *extra);
130 static TPM_RC TSS_PR_NV_DefineSpace(TSS_CONTEXT *tssContext,
131 NV_DefineSpace_In *in,
132 void *extra);
133
134 static TPM_RC TSS_CA_HierarchyChangeAuth(TSS_CONTEXT *tssContext,
135 struct TSS_HMAC_CONTEXT *session,
136 size_t handleNumber,
137 HierarchyChangeAuth_In *in);
138 static TPM_RC TSS_CA_NV_UndefineSpaceSpecial(TSS_CONTEXT *tssContext,
139 struct TSS_HMAC_CONTEXT *session,
140 size_t handleNumber,
141 NV_UndefineSpaceSpecial_In *in);
142 static TPM_RC TSS_CA_NV_ChangeAuth(TSS_CONTEXT *tssContext,
143 struct TSS_HMAC_CONTEXT *session,
144 size_t handleNumber,
145 NV_ChangeAuth_In *in);
146
147
148 static TPM_RC TSS_PO_StartAuthSession(TSS_CONTEXT *tssContext,
149 StartAuthSession_In *in,
150 StartAuthSession_Out *out,
151 StartAuthSession_Extra *extra);
152 static TPM_RC TSS_PO_ContextSave(TSS_CONTEXT *tssContext,
153 ContextSave_In *in,
154 ContextSave_Out *out,
155 void *extra);
156 static TPM_RC TSS_PO_ContextLoad(TSS_CONTEXT *tssContext,
157 ContextLoad_In *in,
158 ContextLoad_Out *out,
159 void *extra);
160 static TPM_RC TSS_PO_FlushContext(TSS_CONTEXT *tssContext,
161 FlushContext_In *in,
162 void *out,
163 void *extra);
164 static TPM_RC TSS_PO_EvictControl(TSS_CONTEXT *tssContext,
165 EvictControl_In *in,
166 void *out,
167 void *extra);
168 static TPM_RC TSS_PO_Load(TSS_CONTEXT *tssContext,
169 Load_In *in,
170 Load_Out *out,
171 void *extra);
172 static TPM_RC TSS_PO_LoadExternal(TSS_CONTEXT *tssContext,
173 LoadExternal_In *in,
174 LoadExternal_Out *out,
175 void *extra);
176 static TPM_RC TSS_PO_ReadPublic(TSS_CONTEXT *tssContext,
177 ReadPublic_In *in,
178 ReadPublic_Out *out,
179 void *extra);
180 static TPM_RC TSS_PO_CreateLoaded(TSS_CONTEXT *tssContext,
181 CreateLoaded_In *in,
182 CreateLoaded_Out *out,
183 void *extra);
184 static TPM_RC TSS_PO_HMAC_Start(TSS_CONTEXT *tssContext,
185 HMAC_Start_In *in,
186 HMAC_Start_Out *out,
187 void *extra);
188 static TPM_RC TSS_PO_HashSequenceStart(TSS_CONTEXT *tssContext,
189 HashSequenceStart_In *in,
190 HashSequenceStart_Out *out,
191 void *extra);
192 static TPM_RC TSS_PO_SequenceComplete(TSS_CONTEXT *tssContext,
193 SequenceComplete_In *in,
194 SequenceComplete_Out *out,
195 void *extra);
196 static TPM_RC TSS_PO_EventSequenceComplete(TSS_CONTEXT *tssContext,
197 EventSequenceComplete_In *in,
198 EventSequenceComplete_Out *out,
199 void *extra);
200 static TPM_RC TSS_PO_PolicyAuthValue(TSS_CONTEXT *tssContext,
201 PolicyAuthValue_In *in,
202 void *out,
203 void *extra);
204 static TPM_RC TSS_PO_PolicyPassword(TSS_CONTEXT *tssContext,
205 PolicyPassword_In *in,
206 void *out,
207 void *extra);
208 static TPM_RC TSS_PO_CreatePrimary(TSS_CONTEXT *tssContext,
209 CreatePrimary_In *in,
210 CreatePrimary_Out *out,
211 void *extra);
212 static TPM_RC TSS_PO_NV_DefineSpace(TSS_CONTEXT *tssContext,
213 NV_DefineSpace_In *in,
214 void *out,
215 void *extra);
216 static TPM_RC TSS_PO_NV_ReadPublic(TSS_CONTEXT *tssContext,
217 NV_ReadPublic_In *in,
218 NV_ReadPublic_Out *out,
219 void *extra);
220 static TPM_RC TSS_PO_NV_UndefineSpace(TSS_CONTEXT *tssContext,
221 NV_UndefineSpace_In *in,
222 void *out,
223 void *extra);
224 static TPM_RC TSS_PO_NV_UndefineSpaceSpecial(TSS_CONTEXT *tssContext,
225 NV_UndefineSpaceSpecial_In *in,
226 void *out,
227 void *extra);
228 static TPM_RC TSS_PO_NV_Write(TSS_CONTEXT *tssContext,
229 NV_Write_In *in,
230 void *out,
231 void *extra);
232 static TPM_RC TSS_PO_NV_WriteLock(TSS_CONTEXT *tssContext,
233 NV_WriteLock_In *in,
234 void *out,
235 void *extra);
236 static TPM_RC TSS_PO_NV_ReadLock(TSS_CONTEXT *tssContext,
237 NV_ReadLock_In *in,
238 void *out,
239 void *extra);
240
241 typedef struct TSS_TABLE {
242 TPM_CC commandCode;
243 TSS_PreProcessFunction_t preProcessFunction;
244 TSS_ChangeAuthFunction_t changeAuthFunction;
245 TSS_PostProcessFunction_t postProcessFunction;
246 } TSS_TABLE;
247
248 /* This table indexes from the command to pre- and post- processing functions. A missing entry is
249 not an error, and indicates a command with no functions. */
250
251 static const TSS_TABLE tssTable [] = {
252
253 {TPM_CC_Startup, NULL, NULL, NULL},
254 {TPM_CC_Shutdown, NULL, NULL, NULL},
255 {TPM_CC_SelfTest, NULL, NULL, NULL},
256 {TPM_CC_IncrementalSelfTest, NULL, NULL, NULL},
257 {TPM_CC_GetTestResult, NULL, NULL, NULL},
258 {TPM_CC_StartAuthSession, (TSS_PreProcessFunction_t)TSS_PR_StartAuthSession, NULL, (TSS_PostProcessFunction_t)TSS_PO_StartAuthSession},
259 {TPM_CC_PolicyRestart, NULL, NULL, NULL},
260 {TPM_CC_Create, NULL, NULL, NULL},
261 {TPM_CC_Load, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_Load},
262 {TPM_CC_LoadExternal, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_LoadExternal},
263 {TPM_CC_ReadPublic, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_ReadPublic},
264 {TPM_CC_ActivateCredential, NULL, NULL, NULL},
265 {TPM_CC_MakeCredential, NULL, NULL, NULL},
266 {TPM_CC_Unseal, NULL, NULL, NULL},
267 {TPM_CC_ObjectChangeAuth, NULL, NULL, NULL},
268 {TPM_CC_CreateLoaded, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_CreateLoaded},
269 {TPM_CC_Duplicate, NULL, NULL, NULL},
270 {TPM_CC_Rewrap, NULL, NULL, NULL},
271 {TPM_CC_Import, NULL, NULL, NULL},
272 {TPM_CC_RSA_Encrypt, NULL, NULL, NULL},
273 {TPM_CC_RSA_Decrypt, NULL, NULL, NULL},
274 {TPM_CC_ECDH_KeyGen, NULL, NULL, NULL},
275 {TPM_CC_ECDH_ZGen, NULL, NULL, NULL},
276 {TPM_CC_ECC_Parameters, NULL, NULL, NULL},
277 {TPM_CC_ZGen_2Phase, NULL, NULL, NULL},
278 {TPM_CC_EncryptDecrypt, NULL, NULL, NULL},
279 {TPM_CC_EncryptDecrypt2, NULL, NULL, NULL},
280 {TPM_CC_Hash, NULL, NULL, NULL},
281 {TPM_CC_HMAC, NULL, NULL, NULL},
282 {TPM_CC_GetRandom, NULL, NULL, NULL},
283 {TPM_CC_StirRandom, NULL, NULL, NULL},
284 {TPM_CC_HMAC_Start, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_HMAC_Start},
285 {TPM_CC_HashSequenceStart, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_HashSequenceStart},
286 {TPM_CC_SequenceUpdate, NULL, NULL, NULL},
287 {TPM_CC_SequenceComplete, NULL,NULL, (TSS_PostProcessFunction_t)TSS_PO_SequenceComplete},
288 {TPM_CC_EventSequenceComplete, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_EventSequenceComplete},
289 {TPM_CC_Certify, NULL, NULL, NULL},
290 {TPM_CC_CertifyX509, NULL, NULL, NULL},
291 {TPM_CC_CertifyCreation, NULL, NULL, NULL},
292 {TPM_CC_Quote, NULL, NULL, NULL},
293 {TPM_CC_GetSessionAuditDigest, NULL, NULL, NULL},
294 {TPM_CC_GetCommandAuditDigest, NULL, NULL, NULL},
295 {TPM_CC_GetTime, NULL, NULL, NULL},
296 {TPM_CC_Commit, NULL, NULL, NULL},
297 {TPM_CC_EC_Ephemeral, NULL, NULL, NULL},
298 {TPM_CC_VerifySignature, NULL, NULL, NULL},
299 {TPM_CC_Sign, NULL, NULL, NULL},
300 {TPM_CC_SetCommandCodeAuditStatus, NULL, NULL, NULL},
301 {TPM_CC_PCR_Extend, NULL, NULL, NULL},
302 {TPM_CC_PCR_Event, NULL, NULL, NULL},
303 {TPM_CC_PCR_Read, NULL, NULL, NULL},
304 {TPM_CC_PCR_Allocate, NULL, NULL, NULL},
305 {TPM_CC_PCR_SetAuthPolicy, NULL, NULL, NULL},
306 {TPM_CC_PCR_SetAuthValue, NULL, NULL, NULL},
307 {TPM_CC_PCR_Reset, NULL, NULL, NULL},
308 {TPM_CC_PolicySigned, NULL, NULL, NULL},
309 {TPM_CC_PolicySecret, NULL, NULL, NULL},
310 {TPM_CC_PolicyTicket, NULL, NULL, NULL},
311 {TPM_CC_PolicyOR, NULL, NULL, NULL},
312 {TPM_CC_PolicyPCR, NULL, NULL, NULL},
313 {TPM_CC_PolicyLocality, NULL, NULL, NULL},
314 {TPM_CC_PolicyNV, NULL, NULL, NULL},
315 {TPM_CC_PolicyAuthorizeNV, NULL, NULL, NULL},
316 {TPM_CC_PolicyCounterTimer, NULL, NULL, NULL},
317 {TPM_CC_PolicyCommandCode, NULL, NULL, NULL},
318 {TPM_CC_PolicyPhysicalPresence, NULL, NULL, NULL},
319 {TPM_CC_PolicyCpHash, NULL, NULL, NULL},
320 {TPM_CC_PolicyNameHash, NULL, NULL, NULL},
321 {TPM_CC_PolicyDuplicationSelect, NULL, NULL, NULL},
322 {TPM_CC_PolicyAuthorize, NULL, NULL, NULL},
323 {TPM_CC_PolicyAuthValue, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_PolicyAuthValue},
324 {TPM_CC_PolicyPassword, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_PolicyPassword},
325 {TPM_CC_PolicyGetDigest, NULL, NULL, NULL},
326 {TPM_CC_PolicyNvWritten, NULL, NULL, NULL},
327 {TPM_CC_PolicyTemplate, NULL, NULL, NULL},
328 {TPM_CC_CreatePrimary, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_CreatePrimary},
329 {TPM_CC_HierarchyControl, NULL, NULL, NULL},
330 {TPM_CC_SetPrimaryPolicy, NULL, NULL, NULL},
331 {TPM_CC_ChangePPS, NULL, NULL, NULL},
332 {TPM_CC_ChangeEPS, NULL, NULL, NULL},
333 {TPM_CC_Clear, NULL, NULL, NULL},
334 {TPM_CC_ClearControl, NULL, NULL, NULL},
335 {TPM_CC_HierarchyChangeAuth, NULL, (TSS_ChangeAuthFunction_t)TSS_CA_HierarchyChangeAuth, NULL},
336 {TPM_CC_DictionaryAttackLockReset, NULL, NULL, NULL},
337 {TPM_CC_DictionaryAttackParameters, NULL, NULL, NULL},
338 {TPM_CC_PP_Commands, NULL, NULL, NULL},
339 {TPM_CC_SetAlgorithmSet, NULL, NULL, NULL},
340 {TPM_CC_ContextSave, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_ContextSave},
341 {TPM_CC_ContextLoad, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_ContextLoad},
342 {TPM_CC_FlushContext, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_FlushContext},
343 {TPM_CC_EvictControl, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_EvictControl},
344 {TPM_CC_ReadClock, NULL, NULL, NULL},
345 {TPM_CC_ClockSet, NULL, NULL, NULL},
346 {TPM_CC_ClockRateAdjust, NULL, NULL, NULL},
347 {TPM_CC_GetCapability, NULL, NULL, NULL},
348 {TPM_CC_TestParms, NULL, NULL, NULL},
349 {TPM_CC_NV_DefineSpace, (TSS_PreProcessFunction_t)TSS_PR_NV_DefineSpace, NULL, (TSS_PostProcessFunction_t)TSS_PO_NV_DefineSpace},
350 {TPM_CC_NV_UndefineSpace, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_NV_UndefineSpace},
351 {TPM_CC_NV_UndefineSpaceSpecial, NULL, (TSS_ChangeAuthFunction_t)TSS_CA_NV_UndefineSpaceSpecial, (TSS_PostProcessFunction_t)TSS_PO_NV_UndefineSpaceSpecial},
352 {TPM_CC_NV_ReadPublic, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_NV_ReadPublic},
353 {TPM_CC_NV_Write, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_NV_Write},
354 {TPM_CC_NV_Increment, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_NV_Write},
355 {TPM_CC_NV_Extend, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_NV_Write},
356 {TPM_CC_NV_SetBits, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_NV_Write},
357 {TPM_CC_NV_WriteLock, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_NV_WriteLock},
358 {TPM_CC_NV_GlobalWriteLock, NULL, NULL, NULL},
359 {TPM_CC_NV_Read, NULL, NULL, NULL},
360 {TPM_CC_NV_ReadLock, NULL, NULL, (TSS_PostProcessFunction_t)TSS_PO_NV_ReadLock},
361 {TPM_CC_NV_ChangeAuth, NULL, (TSS_ChangeAuthFunction_t)TSS_CA_NV_ChangeAuth, NULL},
362 {TPM_CC_NV_Certify, NULL, NULL, NULL}
363 };
364
365 #ifndef TPM_TSS_NO_PRINT
366
367 typedef void (*TSS_InPrintFunction_t)(COMMAND_PARAMETERS *in, unsigned int indent);
368
369 typedef struct TSS_PRINT_TABLE {
370 TPM_CC commandCode;
371 TSS_InPrintFunction_t inPrintFunction;
372 } TSS_PRINT_TABLE;
373
374 /* This table indexes from the command to print functions. A missing entry is
375 not an error, and indicates a command with no function. */
376
377 static const TSS_PRINT_TABLE tssPrintTable [] = {
378
379 {TPM_CC_Startup, (TSS_InPrintFunction_t)Startup_In_Print},
380 {TPM_CC_Shutdown, (TSS_InPrintFunction_t)Shutdown_In_Print},
381 {TPM_CC_SelfTest, (TSS_InPrintFunction_t)SelfTest_In_Print},
382 {TPM_CC_IncrementalSelfTest, (TSS_InPrintFunction_t)IncrementalSelfTest_In_Print},
383 {TPM_CC_GetTestResult, NULL},
384 {TPM_CC_StartAuthSession, (TSS_InPrintFunction_t)StartAuthSession_In_Print},
385 {TPM_CC_PolicyRestart, (TSS_InPrintFunction_t)PolicyRestart_In_Print},
386 {TPM_CC_Create,(TSS_InPrintFunction_t)Create_In_Print},
387 {TPM_CC_Load, (TSS_InPrintFunction_t)Load_In_Print},
388 {TPM_CC_LoadExternal, (TSS_InPrintFunction_t)LoadExternal_In_Print},
389 {TPM_CC_ReadPublic, (TSS_InPrintFunction_t)ReadPublic_In_Print},
390 {TPM_CC_ActivateCredential, (TSS_InPrintFunction_t)ActivateCredential_In_Print},
391 {TPM_CC_MakeCredential, (TSS_InPrintFunction_t)MakeCredential_In_Print},
392 {TPM_CC_Unseal, (TSS_InPrintFunction_t)Unseal_In_Print},
393 {TPM_CC_ObjectChangeAuth, (TSS_InPrintFunction_t)ObjectChangeAuth_In_Print},
394 {TPM_CC_CreateLoaded, (TSS_InPrintFunction_t)CreateLoaded_In_Print},
395 {TPM_CC_Duplicate, (TSS_InPrintFunction_t)Duplicate_In_Print},
396 {TPM_CC_Rewrap, (TSS_InPrintFunction_t)Rewrap_In_Print},
397 {TPM_CC_Import, (TSS_InPrintFunction_t)Import_In_Print},
398 {TPM_CC_RSA_Encrypt, (TSS_InPrintFunction_t)RSA_Encrypt_In_Print},
399 {TPM_CC_RSA_Decrypt, (TSS_InPrintFunction_t)RSA_Decrypt_In_Print},
400 {TPM_CC_ECDH_KeyGen, (TSS_InPrintFunction_t)ECDH_KeyGen_In_Print},
401 {TPM_CC_ECDH_ZGen, (TSS_InPrintFunction_t)ECDH_ZGen_In_Print},
402 {TPM_CC_ECC_Parameters, (TSS_InPrintFunction_t)ECC_Parameters_In_Print},
403 {TPM_CC_ZGen_2Phase, (TSS_InPrintFunction_t)ZGen_2Phase_In_Print},
404 {TPM_CC_EncryptDecrypt, (TSS_InPrintFunction_t)EncryptDecrypt_In_Print},
405 {TPM_CC_EncryptDecrypt2, (TSS_InPrintFunction_t)EncryptDecrypt2_In_Print},
406 {TPM_CC_Hash, (TSS_InPrintFunction_t)Hash_In_Print},
407 {TPM_CC_HMAC, (TSS_InPrintFunction_t)HMAC_In_Print},
408 {TPM_CC_GetRandom, (TSS_InPrintFunction_t)GetRandom_In_Print},
409 {TPM_CC_StirRandom, (TSS_InPrintFunction_t)StirRandom_In_Print},
410 {TPM_CC_HMAC_Start, (TSS_InPrintFunction_t)HMAC_Start_In_Print},
411 {TPM_CC_HashSequenceStart, (TSS_InPrintFunction_t)HashSequenceStart_In_Print},
412 {TPM_CC_SequenceUpdate, (TSS_InPrintFunction_t)SequenceUpdate_In_Print},
413 {TPM_CC_SequenceComplete, (TSS_InPrintFunction_t)SequenceComplete_In_Print},
414 {TPM_CC_EventSequenceComplete, (TSS_InPrintFunction_t)EventSequenceComplete_In_Print},
415 {TPM_CC_Certify, (TSS_InPrintFunction_t)Certify_In_Print},
416 {TPM_CC_CertifyX509, (TSS_InPrintFunction_t)CertifyX509_In_Print},
417 {TPM_CC_CertifyCreation, (TSS_InPrintFunction_t)CertifyCreation_In_Print},
418 {TPM_CC_Quote, (TSS_InPrintFunction_t)Quote_In_Print},
419 {TPM_CC_GetSessionAuditDigest, (TSS_InPrintFunction_t)GetSessionAuditDigest_In_Print},
420 {TPM_CC_GetCommandAuditDigest, (TSS_InPrintFunction_t)GetCommandAuditDigest_In_Print},
421 {TPM_CC_GetTime, (TSS_InPrintFunction_t)GetTime_In_Print},
422 {TPM_CC_Commit, (TSS_InPrintFunction_t)Commit_In_Print},
423 {TPM_CC_EC_Ephemeral, (TSS_InPrintFunction_t)EC_Ephemeral_In_Print},
424 {TPM_CC_VerifySignature, (TSS_InPrintFunction_t)VerifySignature_In_Print},
425 {TPM_CC_Sign, (TSS_InPrintFunction_t)Sign_In_Print},
426 {TPM_CC_SetCommandCodeAuditStatus, (TSS_InPrintFunction_t)SetCommandCodeAuditStatus_In_Print},
427 {TPM_CC_PCR_Extend, (TSS_InPrintFunction_t)PCR_Extend_In_Print},
428 {TPM_CC_PCR_Event, (TSS_InPrintFunction_t)PCR_Event_In_Print},
429 {TPM_CC_PCR_Read, (TSS_InPrintFunction_t)PCR_Read_In_Print},
430 {TPM_CC_PCR_Allocate, (TSS_InPrintFunction_t)PCR_Allocate_In_Print},
431 {TPM_CC_PCR_SetAuthPolicy, (TSS_InPrintFunction_t)PCR_SetAuthPolicy_In_Print},
432 {TPM_CC_PCR_SetAuthValue, (TSS_InPrintFunction_t)PCR_SetAuthValue_In_Print},
433 {TPM_CC_PCR_Reset, (TSS_InPrintFunction_t)PCR_Reset_In_Print},
434 {TPM_CC_PolicySigned, (TSS_InPrintFunction_t)PolicySigned_In_Print},
435 {TPM_CC_PolicySecret, (TSS_InPrintFunction_t)PolicySecret_In_Print},
436 {TPM_CC_PolicyTicket, (TSS_InPrintFunction_t)PolicyTicket_In_Print},
437 {TPM_CC_PolicyOR, (TSS_InPrintFunction_t)PolicyOR_In_Print},
438 {TPM_CC_PolicyPCR, (TSS_InPrintFunction_t)PolicyPCR_In_Print},
439 {TPM_CC_PolicyLocality, (TSS_InPrintFunction_t)PolicyLocality_In_Print},
440 {TPM_CC_PolicyNV, (TSS_InPrintFunction_t)PolicyNV_In_Print},
441 {TPM_CC_PolicyAuthorizeNV, (TSS_InPrintFunction_t)PolicyAuthorizeNV_In_Print},
442 {TPM_CC_PolicyCounterTimer, (TSS_InPrintFunction_t)PolicyCounterTimer_In_Print},
443 {TPM_CC_PolicyCommandCode, (TSS_InPrintFunction_t)PolicyCommandCode_In_Print},
444 {TPM_CC_PolicyPhysicalPresence, (TSS_InPrintFunction_t)PolicyPhysicalPresence_In_Print},
445 {TPM_CC_PolicyCpHash, (TSS_InPrintFunction_t)PolicyCpHash_In_Print},
446 {TPM_CC_PolicyNameHash, (TSS_InPrintFunction_t)PolicyNameHash_In_Print},
447 {TPM_CC_PolicyDuplicationSelect, (TSS_InPrintFunction_t)PolicyDuplicationSelect_In_Print},
448 {TPM_CC_PolicyAuthorize, (TSS_InPrintFunction_t)PolicyAuthorize_In_Print},
449 {TPM_CC_PolicyAuthValue, (TSS_InPrintFunction_t)PolicyAuthValue_In_Print},
450 {TPM_CC_PolicyPassword, (TSS_InPrintFunction_t)PolicyPassword_In_Print},
451 {TPM_CC_PolicyGetDigest, (TSS_InPrintFunction_t)PolicyGetDigest_In_Print},
452 {TPM_CC_PolicyNvWritten, (TSS_InPrintFunction_t)PolicyNvWritten_In_Print},
453 {TPM_CC_PolicyTemplate, (TSS_InPrintFunction_t)PolicyTemplate_In_Print},
454 {TPM_CC_CreatePrimary, (TSS_InPrintFunction_t)CreatePrimary_In_Print},
455 {TPM_CC_HierarchyControl, (TSS_InPrintFunction_t)HierarchyControl_In_Print},
456 {TPM_CC_SetPrimaryPolicy, (TSS_InPrintFunction_t)SetPrimaryPolicy_In_Print},
457 {TPM_CC_ChangePPS, (TSS_InPrintFunction_t)ChangePPS_In_Print},
458 {TPM_CC_ChangeEPS, (TSS_InPrintFunction_t)ChangeEPS_In_Print},
459 {TPM_CC_Clear, (TSS_InPrintFunction_t)Clear_In_Print},
460 {TPM_CC_ClearControl, (TSS_InPrintFunction_t)ClearControl_In_Print},
461 {TPM_CC_HierarchyChangeAuth, (TSS_InPrintFunction_t)HierarchyChangeAuth_In_Print},
462 {TPM_CC_DictionaryAttackLockReset, (TSS_InPrintFunction_t)DictionaryAttackLockReset_In_Print},
463 {TPM_CC_DictionaryAttackParameters, (TSS_InPrintFunction_t)DictionaryAttackParameters_In_Print},
464 {TPM_CC_PP_Commands, (TSS_InPrintFunction_t)PP_Commands_In_Print},
465 {TPM_CC_SetAlgorithmSet, (TSS_InPrintFunction_t)SetAlgorithmSet_In_Print},
466 {TPM_CC_ContextSave, (TSS_InPrintFunction_t)ContextSave_In_Print},
467 {TPM_CC_ContextLoad, (TSS_InPrintFunction_t)ContextLoad_In_Print},
468 {TPM_CC_FlushContext, (TSS_InPrintFunction_t)FlushContext_In_Print},
469 {TPM_CC_EvictControl, (TSS_InPrintFunction_t)EvictControl_In_Print},
470 {TPM_CC_ReadClock, (TSS_InPrintFunction_t)NULL},
471 {TPM_CC_ClockSet, (TSS_InPrintFunction_t)ClockSet_In_Print},
472 {TPM_CC_ClockRateAdjust, (TSS_InPrintFunction_t)ClockRateAdjust_In_Print},
473 {TPM_CC_GetCapability, (TSS_InPrintFunction_t)GetCapability_In_Print},
474 {TPM_CC_TestParms, (TSS_InPrintFunction_t)TestParms_In_Print},
475 {TPM_CC_NV_DefineSpace, (TSS_InPrintFunction_t)NV_DefineSpace_In_Print},
476 {TPM_CC_NV_UndefineSpace, (TSS_InPrintFunction_t)NV_UndefineSpace_In_Print},
477 {TPM_CC_NV_UndefineSpaceSpecial, (TSS_InPrintFunction_t)NV_UndefineSpaceSpecial_In_Print},
478 {TPM_CC_NV_ReadPublic, (TSS_InPrintFunction_t)NV_ReadPublic_In_Print},
479 {TPM_CC_NV_Write, (TSS_InPrintFunction_t)NV_Write_In_Print},
480 {TPM_CC_NV_Increment, (TSS_InPrintFunction_t)NV_Increment_In_Print},
481 {TPM_CC_NV_Extend, (TSS_InPrintFunction_t)NV_Extend_In_Print},
482 {TPM_CC_NV_SetBits, (TSS_InPrintFunction_t)NV_SetBits_In_Print},
483 {TPM_CC_NV_WriteLock, (TSS_InPrintFunction_t)NV_WriteLock_In_Print},
484 {TPM_CC_NV_GlobalWriteLock, (TSS_InPrintFunction_t)NV_GlobalWriteLock_In_Print},
485 {TPM_CC_NV_Read, (TSS_InPrintFunction_t)NV_Read_In_Print},
486 {TPM_CC_NV_ReadLock, (TSS_InPrintFunction_t)NV_ReadLock_In_Print},
487 {TPM_CC_NV_ChangeAuth, (TSS_InPrintFunction_t)NV_ChangeAuth_In_Print},
488 {TPM_CC_NV_Certify, (TSS_InPrintFunction_t)NV_Certify_In_Print}
489 };
490
491 #endif /* TPM_TSS_NO_PRINT */
492
493 /* local prototypes */
494
495 static TPM_RC TSS_Execute_valist(TSS_CONTEXT *tssContext,
496 COMMAND_PARAMETERS *in,
497 va_list ap);
498
499
500 static TPM_RC TSS_PwapSession_Set(TPMS_AUTH_COMMAND *authCommand,
501 const char *password);
502 static TPM_RC TSS_PwapSession_Verify(TPMS_AUTH_RESPONSE *authResponse);
503
504 static TPM_RC TSS_HmacSession_GetContext(struct TSS_HMAC_CONTEXT **session);
505 static void TSS_HmacSession_InitContext(struct TSS_HMAC_CONTEXT *session);
506 static void TSS_HmacSession_FreeContext(struct TSS_HMAC_CONTEXT *session);
507
508 #ifndef TPM_TSS_NOCRYPTO
509 static TPM_RC TSS_HmacSession_SetSessionKey(TSS_CONTEXT *tssContext,
510 struct TSS_HMAC_CONTEXT *session,
511 TPM2B_DIGEST *salt,
512 TPMI_DH_ENTITY bind,
513 TPM2B_AUTH *bindAuthValue);
514 static TPM_RC TSS_HmacSession_SetNonceCaller(struct TSS_HMAC_CONTEXT *session,
515 TPMS_AUTH_COMMAND *authC);
516 static TPM_RC TSS_HmacSession_SetHmacKey(TSS_CONTEXT *tssContext,
517 struct TSS_HMAC_CONTEXT *session,
518 size_t handleNumber,
519 const char *password);
520 #endif /* TPM_TSS_NOCRYPTO */
521 static TPM_RC TSS_HmacSession_SetHMAC(TSS_AUTH_CONTEXT *tssAuthContext,
522 struct TSS_HMAC_CONTEXT *session[],
523 TPMS_AUTH_COMMAND *authCommand[],
524 TPMI_SH_AUTH_SESSION sessionHandle[],
525 unsigned int sessionAttributes[],
526 const char *password[],
527 TPM2B_NAME *name0,
528 TPM2B_NAME *name1,
529 TPM2B_NAME *name2);
530 #ifndef TPM_TSS_NOCRYPTO
531 static TPM_RC TSS_HmacSession_Verify(TSS_AUTH_CONTEXT *tssAuthContext,
532 struct TSS_HMAC_CONTEXT *session,
533 TPMS_AUTH_RESPONSE *authResponse);
534 #endif /* TPM_TSS_NOCRYPTO */
535 static TPM_RC TSS_HmacSession_Continue(TSS_CONTEXT *tssContext,
536 struct TSS_HMAC_CONTEXT *session,
537 TPMS_AUTH_RESPONSE *authR);
538
539
540 static TPM_RC TSS_HmacSession_SaveSession(TSS_CONTEXT *tssContext,
541 struct TSS_HMAC_CONTEXT *session);
542 static TPM_RC TSS_HmacSession_LoadSession(TSS_CONTEXT *tssContext,
543 struct TSS_HMAC_CONTEXT *session,
544 TPMI_SH_AUTH_SESSION sessionHandle);
545 #ifdef TPM_TSS_NOFILE
546 static TPM_RC TSS_HmacSession_SaveData(TSS_CONTEXT *tssContext,
547 TPMI_SH_AUTH_SESSION sessionHandle,
548 uint32_t outLength,
549 uint8_t *outBuffer);
550 static TPM_RC TSS_HmacSession_LoadData(TSS_CONTEXT *tssContext,
551 uint32_t *inLength, uint8_t **inData,
552 TPMI_SH_AUTH_SESSION sessionHandle);
553 static TPM_RC TSS_HmacSession_DeleteData(TSS_CONTEXT *tssContext,
554 TPMI_SH_AUTH_SESSION sessionHandle);
555 static TPM_RC TSS_HmacSession_GetSlotForHandle(TSS_CONTEXT *tssContext,
556 size_t *slotIndex,
557 TPMI_SH_AUTH_SESSION sessionHandle);
558 #endif
559 static TPM_RC TSS_HmacSession_Marshal(struct TSS_HMAC_CONTEXT *source,
560 uint16_t *written, uint8_t **buffer, uint32_t *size);
561 static TPM_RC TSS_HmacSession_Unmarshal(struct TSS_HMAC_CONTEXT *target,
562 uint8_t **buffer, uint32_t *size);
563
564 static TPM_RC TSS_Name_GetAllNames(TSS_CONTEXT *tssContext,
565 TPM2B_NAME **names);
566 static TPM_RC TSS_Name_GetName(TSS_CONTEXT *tssContext,
567 TPM2B_NAME *name,
568 TPM_HANDLE handle);
569 static TPM_RC TSS_Name_Store(TSS_CONTEXT *tssContext,
570 TPM2B_NAME *name,
571 TPM_HANDLE handle,
572 const char *string);
573 static TPM_RC TSS_Name_Load(TSS_CONTEXT *tssContext,
574 TPM2B_NAME *name,
575 TPM_HANDLE handle,
576 const char *string);
577 static TPM_RC TSS_Name_Copy(TSS_CONTEXT *tssContext,
578 TPM_HANDLE outHandle,
579 const char *outString,
580 TPM_HANDLE inHandle,
581 const char *inString);
582 static TPM_RC TSS_Public_Store(TSS_CONTEXT *tssContext,
583 TPM2B_PUBLIC *public,
584 TPM_HANDLE handle,
585 const char *string);
586 static TPM_RC TSS_Public_Load(TSS_CONTEXT *tssContext,
587 TPM2B_PUBLIC *public,
588 TPM_HANDLE handle,
589 const char *string);
590 static TPM_RC TSS_Public_Copy(TSS_CONTEXT *tssContext,
591 TPM_HANDLE outHandle,
592 const char *outString,
593 TPM_HANDLE inHandle,
594 const char *inString);
595 #ifdef TPM_TSS_NOFILE
596 static TPM_RC TSS_ObjectPublic_GetSlotForHandle(TSS_CONTEXT *tssContext,
597 size_t *slotIndex,
598 TPM_HANDLE handle);
599 static TPM_RC TSS_ObjectPublic_DeleteData(TSS_CONTEXT *tssContext, TPM_HANDLE handle);
600 #endif
601 static TPM_RC TSS_DeleteHandle(TSS_CONTEXT *tssContext,
602 TPM_HANDLE handle);
603 #ifndef TPM_TSS_NOCRYPTO
604 static TPM_RC TSS_ObjectPublic_GetName(TPM2B_NAME *name,
605 TPMT_PUBLIC *tpmtPublic);
606
607 static TPM_RC TSS_NVPublic_Store(TSS_CONTEXT *tssContext,
608 TPMS_NV_PUBLIC *nvPublic,
609 TPMI_RH_NV_INDEX handle);
610 static TPM_RC TSS_NVPublic_Load(TSS_CONTEXT *tssContext,
611 TPMS_NV_PUBLIC *nvPublic,
612 TPMI_RH_NV_INDEX handle);
613 #endif
614 static TPM_RC TSS_NVPublic_Delete(TSS_CONTEXT *tssContext,
615 TPMI_RH_NV_INDEX nvIndex);
616 #ifdef TPM_TSS_NOFILE
617 static TPM_RC TSS_NvPublic_GetSlotForHandle(TSS_CONTEXT *tssContext,
618 size_t *slotIndex,
619 TPMI_RH_NV_INDEX nvIndex);
620 #endif
621
622 static TPM_RC TSS_Command_Decrypt(TSS_AUTH_CONTEXT *tssAuthContext,
623 struct TSS_HMAC_CONTEXT *session[],
624 TPMI_SH_AUTH_SESSION sessionHandle[],
625 unsigned int sessionAttributes[]);
626 #ifndef TPM_TSS_NOCRYPTO
627 static TPM_RC TSS_Command_DecryptXor(TSS_AUTH_CONTEXT *tssAuthContext,
628 struct TSS_HMAC_CONTEXT *session);
629 static TPM_RC TSS_Command_DecryptAes(TSS_AUTH_CONTEXT *tssAuthContext,
630 struct TSS_HMAC_CONTEXT *session);
631
632 #endif /* TPM_TSS_NOCRYPTO */
633 static TPM_RC TSS_Response_Encrypt(TSS_AUTH_CONTEXT *tssAuthContext,
634 struct TSS_HMAC_CONTEXT *session[],
635 TPMI_SH_AUTH_SESSION sessionHandle[],
636 unsigned int sessionAttributes[]);
637 #ifndef TPM_TSS_NOCRYPTO
638 static TPM_RC TSS_Response_EncryptXor(TSS_AUTH_CONTEXT *tssAuthContext,
639 struct TSS_HMAC_CONTEXT *session);
640 static TPM_RC TSS_Response_EncryptAes(TSS_AUTH_CONTEXT *tssAuthContext,
641 struct TSS_HMAC_CONTEXT *session);
642
643 static TPM_RC TSS_Command_ChangeAuthProcessor(TSS_CONTEXT *tssContext,
644 struct TSS_HMAC_CONTEXT *session,
645 size_t handleNumber,
646 COMMAND_PARAMETERS *in);
647 #endif /* TPM_TSS_NOCRYPTO */
648
649 static TPM_RC TSS_Command_PreProcessor(TSS_CONTEXT *tssContext,
650 TPM_CC commandCode,
651 COMMAND_PARAMETERS *in,
652 EXTRA_PARAMETERS *extra);
653 static TPM_RC TSS_Response_PostProcessor(TSS_CONTEXT *tssContext,
654 COMMAND_PARAMETERS *in,
655 RESPONSE_PARAMETERS *out,
656 EXTRA_PARAMETERS *extra);
657
658 static TPM_RC TSS_Sessions_GetDecryptSession(unsigned int *isDecrypt,
659 unsigned int *decryptSession,
660 TPMI_SH_AUTH_SESSION sessionHandle[],
661 unsigned int sessionAttributes[]);
662 static TPM_RC TSS_Sessions_GetEncryptSession(unsigned int *isEncrypt,
663 unsigned int *encryptSession,
664 TPMI_SH_AUTH_SESSION sessionHandle[],
665 unsigned int sessionAttributes[]);
666
667 #ifndef TPM_TSS_NOFILE
668 static TPM_RC TSS_HashToString(char *str, uint8_t *digest);
669 #endif
670 #ifndef TPM_TSS_NOCRYPTO
671 #ifndef TPM_TSS_NORSA
672 static TPM_RC TSS_RSA_Salt(TPM2B_DIGEST *salt,
673 TPM2B_ENCRYPTED_SECRET *encryptedSalt,
674 TPMT_PUBLIC *publicArea);
675 #endif /* TPM_TSS_NORSA */
676 #endif /* TPM_TSS_NOCRYPTO */
677 extern int tssVerbose;
678 extern int tssVverbose;
679 extern int tssFirstCall;
680
681
TSS_Execute20(TSS_CONTEXT * tssContext,RESPONSE_PARAMETERS * out,COMMAND_PARAMETERS * in,EXTRA_PARAMETERS * extra,TPM_CC commandCode,va_list ap)682 TPM_RC TSS_Execute20(TSS_CONTEXT *tssContext,
683 RESPONSE_PARAMETERS *out,
684 COMMAND_PARAMETERS *in,
685 EXTRA_PARAMETERS *extra,
686 TPM_CC commandCode,
687 va_list ap)
688 {
689 TPM_RC rc = 0;
690
691 /* create a TSS authorization context */
692 if (rc == 0) {
693 TSS_InitAuthContext(tssContext->tssAuthContext);
694 }
695 /* handle any command specific command pre-processing */
696 if (rc == 0) {
697 rc = TSS_Command_PreProcessor(tssContext,
698 commandCode,
699 in,
700 extra);
701 }
702 /* marshal input parameters */
703 if (rc == 0) {
704 if (tssVverbose) printf("TSS_Execute20: Command %08x marshal\n", commandCode);
705 rc = TSS_Marshal(tssContext->tssAuthContext,
706 in,
707 commandCode);
708 }
709 /* execute the command */
710 if (rc == 0) {
711 rc = TSS_Execute_valist(tssContext, in, ap);
712 }
713 /* unmarshal the response parameters */
714 if (rc == 0) {
715 if (tssVverbose) printf("TSS_Execute20: Command %08x unmarshal\n", commandCode);
716 rc = TSS_Unmarshal(tssContext->tssAuthContext, out);
717 }
718 /* handle any command specific response post-processing */
719 if (rc == 0) {
720 if (tssVverbose) printf("TSS_Execute20: Command %08x post processor\n", commandCode);
721 rc = TSS_Response_PostProcessor(tssContext,
722 in,
723 out,
724 extra);
725 }
726 return rc;
727 }
728
729 /* TSS_Execute_valist() transmits the marshaled command and receives the marshaled response.
730
731 varargs are TPMI_SH_AUTH_SESSION sessionHandle, const char *password, unsigned int
732 sessionAttributes
733
734 Terminates with sessionHandle TPM_RH_NULL
735
736 Processes up to MAX_SESSION_NUM sessions. It handles HMAC generation and command and response
737 parameter encryption. It loads each session context, rolls nonces, and saves or deletes the
738 session context.
739 */
740
TSS_Execute_valist(TSS_CONTEXT * tssContext,COMMAND_PARAMETERS * in,va_list ap)741 static TPM_RC TSS_Execute_valist(TSS_CONTEXT *tssContext,
742 COMMAND_PARAMETERS *in,
743 va_list ap)
744 {
745 TPM_RC rc = 0;
746 int done;
747 int haveNames = FALSE; /* names are common to all HMAC sessions */
748 size_t i = 0;
749
750 /* the vararg parameters */
751 TPMI_SH_AUTH_SESSION sessionHandle[MAX_SESSION_NUM];
752 const char *password[MAX_SESSION_NUM];
753 unsigned int sessionAttributes[MAX_SESSION_NUM];
754
755 /* structures filled in */
756 TPMS_AUTH_COMMAND *authCommand[MAX_SESSION_NUM];
757 TPMS_AUTH_RESPONSE *authResponse[MAX_SESSION_NUM];
758
759 /* pointer to the above structures as used */
760 TPMS_AUTH_COMMAND *authC[MAX_SESSION_NUM];
761 TPMS_AUTH_RESPONSE *authR[MAX_SESSION_NUM];
762
763 /* TSS sessions */
764 struct TSS_HMAC_CONTEXT *session[MAX_SESSION_NUM];
765 TPM2B_NAME *names[MAX_SESSION_NUM];
766
767
768 for (i = 0 ; i < MAX_SESSION_NUM ; i++) {
769 authCommand[i] = NULL; /* for safe free */
770 authResponse[i] = NULL; /* for safe free */
771 names[i] = NULL; /* for safe free */
772 authC[i] = NULL; /* array of TPMS_AUTH_COMMAND structures, NULL for
773 TSS_SetCmdAuths */
774 authR[i] = NULL; /* array of TPMS_AUTH_RESPONSE structures, NULL for
775 TSS_GetRspAuths */
776 session[i] = NULL; /* for free, used for HMAC and encrypt/decrypt sessions */
777 /* the varargs list inputs */
778 sessionHandle[i] = TPM_RH_NULL;
779 password[i] = NULL;
780 sessionAttributes[i] = 0;
781 }
782 /* Step 1: initialization */
783 if (tssVverbose) printf("TSS_Execute_valist: Step 1: initialization\n");
784 for (i = 0 ; (rc == 0) && (i < MAX_SESSION_NUM) ; i++) {
785 if (rc == 0) {
786 rc = TSS_Malloc((unsigned char **)&authCommand[i], /* freed @1 */
787 sizeof(TPMS_AUTH_COMMAND));
788 }
789 if (rc == 0) {
790 rc = TSS_Malloc((unsigned char **)&authResponse[i], /* freed @2 */
791 sizeof(TPMS_AUTH_RESPONSE));
792 }
793 if (rc == 0) {
794 rc = TSS_Malloc((unsigned char **)&names[i], /* freed @3 */
795 sizeof(TPM2B_NAME));
796 }
797 if (rc == 0) {
798 names[i]->b.size = 0; /* to ignore unused names in cpHash calculation */
799 }
800 }
801 /* Step 2: gather the command authorizations
802
803 Process PWAP immediately
804 For HMAC, get the session context
805 */
806 done = FALSE;
807 for (i = 0 ; (rc == 0) && !done && (i < MAX_SESSION_NUM) ; i++) {
808 sessionHandle[i] = va_arg(ap, TPMI_SH_AUTH_SESSION); /* first vararg is the session
809 handle */
810 password[i]= va_arg(ap, const char *); /* second vararg is the password */
811 sessionAttributes[i] = va_arg(ap, unsigned int); /* third argument is
812 sessionAttributes */
813 sessionAttributes[i] &= 0xff; /* is uint8_t */
814
815 if (sessionHandle[i] != TPM_RH_NULL) { /* varargs termination value */
816
817 if (tssVverbose) printf("TSS_Execute_valist: Step 2: authorization %u\n",
818 (unsigned int)i);
819 if (tssVverbose) printf("TSS_Execute_valist: session %u handle %08x\n",
820 (unsigned int)i, sessionHandle[i]);
821 /* make used, non-NULL for command and response varargs */
822 authC[i] = authCommand[i];
823 authR[i] = authResponse[i];
824
825 /* if password session, populate authC with password, etc. immediately */
826 if (sessionHandle[i] == TPM_RS_PW) {
827 rc = TSS_PwapSession_Set(authC[i], password[i]);
828 }
829 /* if HMAC or encrypt/decrypt session */
830 else {
831 /* initialize a TSS HMAC session */
832 if (rc == 0) {
833 rc = TSS_HmacSession_GetContext(&session[i]);
834 }
835 /* load the session created by startauthsession */
836 if (rc == 0) {
837 rc = TSS_HmacSession_LoadSession(tssContext, session[i], sessionHandle[i]);
838 }
839 /* if there is at least one HMAC session, get the names corresponding to the
840 handles */
841 if ((session[i]->sessionType == TPM_SE_HMAC) || /* HMAC session. OR */
842 ((session[i]->sessionType == TPM_SE_POLICY) && /* Policy session AND */
843
844 #ifndef TPM_TSS_NOCRYPTO
845 ((session[i]->isAuthValueNeeded) || /* PolicyAuthValue ran, OR */
846 (session[i]->sessionKey.b.size != 0))) /* Already session key (bind or salt) */
847 #else
848 (session[i]->isAuthValueNeeded)) /* PolicyAuthValue ran, OR */
849 #endif /* TPM_TSS_NOCRYPTO */
850 ) {
851 if ((rc == 0) && !haveNames) {
852 rc = TSS_Name_GetAllNames(tssContext, names);
853 haveNames = TRUE; /* get only once, minor optimization */
854 }
855 }
856 }
857 }
858 else {
859 done = TRUE;
860 }
861 }
862 /* Step 3: Roll nonceCaller, save in the session context for the response */
863 for (i = 0 ; (rc == 0) && (i < MAX_SESSION_NUM) && (sessionHandle[i] != TPM_RH_NULL) ; i++) {
864 if (sessionHandle[i] != TPM_RS_PW) { /* no nonce for password sessions */
865 if (tssVverbose)
866 printf("TSS_Execute_valist: Step 3: nonceCaller %08x\n", sessionHandle[i]);
867 #ifndef TPM_TSS_NOCRYPTO
868 rc = TSS_HmacSession_SetNonceCaller(session[i], authC[i]);
869 #else
870 authC[i]->nonce.b.size = 16;
871 memset(&authC[i]->nonce.b.buffer, 0, 16);
872 #endif /* TPM_TSS_NOCRYPTO */
873 }
874 }
875
876 #ifndef TPM_TSS_NOCRYPTO
877 /* Step 4: Calculate the HMAC key */
878 for (i = 0 ; (rc == 0) && (i < MAX_SESSION_NUM) && (sessionHandle[i] != TPM_RH_NULL) ; i++) {
879 if (sessionHandle[i] != TPM_RS_PW) { /* no HMAC key for password sessions */
880 if (tssVverbose) printf("TSS_Execute_valist: Step 4: Session %u HMAC key for %08x\n",
881 (unsigned int)i, sessionHandle[i]);
882 rc = TSS_HmacSession_SetHmacKey(tssContext, session[i], i, password[i]);
883 }
884 }
885 #endif /* TPM_TSS_NOCRYPTO */
886 /* Step 5: command parameter encryption */
887 if (rc == 0) {
888 if (tssVverbose) printf("TSS_Execute_valist: Step 5: command encrypt\n");
889 rc = TSS_Command_Decrypt(tssContext->tssAuthContext,
890 session,
891 sessionHandle,
892 sessionAttributes);
893 }
894 /* Step 6: for each HMAC session, calculate cpHash, calculate the HMAC, and set it in
895 TPMS_AUTH_COMMAND */
896 if (rc == 0) {
897 if (tssVverbose) printf("TSS_Execute_valist: Step 6 calculate HMACs\n");
898 rc = TSS_HmacSession_SetHMAC(tssContext->tssAuthContext, /* TSS auth context */
899 session, /* TSS session contexts */
900 authC, /* output: command authorizations */
901 sessionHandle, /* list of session handles for the command */
902 sessionAttributes, /* attributes for this command */
903 password, /* for plaintext password sessions */
904 names[0], /* Name */
905 names[1], /* Name */
906 names[2]); /* Name */
907 }
908 /* Step 7: set the command authorizations in the TSS command stream */
909 if (rc == 0) {
910 if (tssVverbose) printf("TSS_Execute_valist: Step 7 set command authorizations\n");
911 rc = TSS_SetCmdAuths(tssContext->tssAuthContext,
912 authC[0],
913 authC[1],
914 authC[2],
915 NULL);
916 }
917 /* Step 8: process the command. Normally returns the TPM response code. */
918 if (rc == 0) {
919 if (tssVverbose) printf("TSS_Execute_valist: Step 8: process the command\n");
920 rc = TSS_AuthExecute(tssContext);
921 }
922 /* Step 9: get the response authorizations from the TSS response stream */
923 if (rc == 0) {
924 if (tssVverbose) printf("TSS_Execute_valist: Step 9 get response authorizations\n");
925 rc = TSS_GetRspAuths(tssContext->tssAuthContext,
926 authR[0],
927 authR[1],
928 authR[2],
929 NULL);
930 }
931 /* Step 10: process the response authorizations, validate the HMAC */
932 for (i = 0 ; (rc == 0) && (i < MAX_SESSION_NUM) && (sessionHandle[i] != TPM_RH_NULL) ; i++) {
933 if (tssVverbose)
934 printf("TSS_Execute_valist: Step 10: process response authorization %08x\n",
935 sessionHandle[i]);
936 if (sessionHandle[i] == TPM_RS_PW) {
937 rc = TSS_PwapSession_Verify(authR[i]);
938 }
939 /* HMAC session */
940 else {
941 #ifndef TPM_TSS_NOCRYPTO
942 /* save nonceTPM in the session context */
943 if (rc == 0) {
944 rc = TSS_TPM2B_Copy(&session[i]->nonceTPM.b, &authR[i]->nonce.b, sizeof(TPMU_HA));
945 }
946 #endif /* TPM_TSS_NOCRYPTO */
947 /* the HMAC key is already part of the TSS session context. For policy sessions with
948 policy password, the response hmac is empty. */
949 if ((session[i]->sessionType == TPM_SE_HMAC) ||
950 ((session[i]->sessionType == TPM_SE_POLICY) && (session[i]->isAuthValueNeeded))) {
951 #ifndef TPM_TSS_NOCRYPTO
952 if (rc == 0) {
953 rc = TSS_Command_ChangeAuthProcessor(tssContext, session[i], i, in);
954 }
955 if (rc == 0) {
956 rc = TSS_HmacSession_Verify(tssContext->tssAuthContext, /* authorization
957 context */
958 session[i], /* TSS session context */
959 authR[i]); /* input: response authorization */
960 }
961 #else
962 in = in;
963 if (tssVerbose)
964 printf("TSS_Execute_valist: "
965 "Error, HMAC verify with no crypto not implemented\n");
966 rc = TSS_RC_NOT_IMPLEMENTED;
967 #endif /* TPM_TSS_NOCRYPTO */
968 }
969 }
970 }
971 /* Step 11: process the audit flag */
972 for (i = 0 ; (rc == 0) && (i < MAX_SESSION_NUM) && (sessionHandle[i] != TPM_RH_NULL) ; i++) {
973 if ((sessionHandle[i] != TPM_RS_PW) &&
974 (session[i]->bind != TPM_RH_NULL) &&
975 (authR[i]->sessionAttributes.val & TPMA_SESSION_AUDIT)) {
976 if (tssVverbose) printf("TSS_Execute_valist: Step 11: process bind audit flag %08x\n",
977 sessionHandle[i]);
978 /* if bind audit session, bind value is lost and further use requires authValue */
979 session[i]->bind = TPM_RH_NULL;
980 }
981 }
982 /* Step 12: process the response continue flag */
983 for (i = 0 ; (rc == 0) && (i < MAX_SESSION_NUM) && (sessionHandle[i] != TPM_RH_NULL) ; i++) {
984 if (sessionHandle[i] != TPM_RS_PW) {
985 if (tssVverbose) printf("TSS_Execute_valist: Step 12: process continue flag %08x\n",
986 sessionHandle[i]);
987 rc = TSS_HmacSession_Continue(tssContext, session[i], authR[i]);
988 }
989 }
990 /* Step 13: response parameter decryption */
991 if (rc == 0) {
992 if (tssVverbose) printf("TSS_Execute_valist: Step 13: response decryption\n");
993 rc = TSS_Response_Encrypt(tssContext->tssAuthContext,
994 session,
995 sessionHandle,
996 sessionAttributes);
997 }
998 /* cleanup */
999 for (i = 0 ; i < MAX_SESSION_NUM ; i++) {
1000 TSS_HmacSession_FreeContext(session[i]);
1001 free(authCommand[i]); /* @1 */
1002 free(authResponse[i]); /* @2 */
1003 free(names[i]); /* @3 */
1004 }
1005 return rc;
1006 }
1007
1008 /*
1009 PWAP - Password Session
1010 */
1011
1012 /* TSS_PwapSession_Set() sets all members of the TPMS_AUTH_COMMAND structure for a PWAP session.
1013 */
1014
TSS_PwapSession_Set(TPMS_AUTH_COMMAND * authCommand,const char * password)1015 static TPM_RC TSS_PwapSession_Set(TPMS_AUTH_COMMAND *authCommand,
1016 const char *password)
1017 {
1018 TPM_RC rc = 0;
1019
1020 if (rc == 0) {
1021 authCommand->sessionHandle = TPM_RS_PW;
1022 authCommand->nonce.t.size = 0;
1023 authCommand->sessionAttributes.val = 0;
1024 }
1025 if (password != NULL) {
1026 rc = TSS_TPM2B_StringCopy(&authCommand->hmac.b,
1027 password, sizeof(authCommand->hmac.t.buffer));
1028 }
1029 else {
1030 authCommand->hmac.t.size = 0;
1031 }
1032 return rc;
1033 }
1034
1035 /* TSS_PwapSession_Verify() verifies the PWAP session response. */
1036
TSS_PwapSession_Verify(TPMS_AUTH_RESPONSE * authResponse)1037 static TPM_RC TSS_PwapSession_Verify(TPMS_AUTH_RESPONSE *authResponse)
1038 {
1039 TPM_RC rc = 0;
1040
1041 if (rc == 0) {
1042 if (authResponse->nonce.t.size != 0) {
1043 if (tssVerbose) printf("TSS_PwapSession_Verify: nonce size %u not zero\n",
1044 authResponse->nonce.t.size);
1045 rc = TSS_RC_BAD_PWAP_NONCE;
1046 }
1047 }
1048 if (rc == 0) {
1049 if (authResponse->sessionAttributes.val != TPMA_SESSION_CONTINUESESSION) {
1050 if (tssVerbose) printf("TSS_PwapSession_Verify: continue %02x not set\n",
1051 authResponse->sessionAttributes.val);
1052 rc = TSS_RC_BAD_PWAP_ATTRIBUTES;
1053 }
1054 }
1055 if (rc == 0) {
1056 if (authResponse->hmac.t.size != 0) {
1057 if (tssVerbose) printf("TSS_PwapSession_Verify: HMAC size %u not zero\n",
1058 authResponse->hmac.t.size);
1059 rc = TSS_RC_BAD_PWAP_HMAC;
1060 }
1061 }
1062 return rc;
1063 }
1064
1065 /*
1066 HMAC Session
1067 */
1068
TSS_HmacSession_GetContext(struct TSS_HMAC_CONTEXT ** session)1069 static TPM_RC TSS_HmacSession_GetContext(struct TSS_HMAC_CONTEXT **session)
1070 {
1071 TPM_RC rc = 0;
1072
1073 if (rc == 0) {
1074 rc = TSS_Malloc((uint8_t **)session, sizeof(TSS_HMAC_CONTEXT));
1075 }
1076 if (rc == 0) {
1077 TSS_HmacSession_InitContext(*session);
1078 }
1079 return rc;
1080 }
1081
TSS_HmacSession_InitContext(struct TSS_HMAC_CONTEXT * session)1082 static void TSS_HmacSession_InitContext(struct TSS_HMAC_CONTEXT *session)
1083 {
1084 session->sessionHandle = TPM_RH_NULL;
1085 session->authHashAlg = TPM_ALG_NULL;
1086 #ifndef TPM_TSS_NOCRYPTO
1087 session->sizeInBytes = 0;
1088 #endif
1089 session->symmetric.algorithm = TPM_ALG_NULL;
1090 session->bind = TPM_RH_NULL;
1091 session->bindName.b.size = 0;
1092 session->bindAuthValue.t.size = 0;
1093 #ifndef TPM_TSS_NOCRYPTO
1094 memset(session->nonceTPM.t.buffer, 0, sizeof(TPMU_HA));
1095 session->nonceTPM.b.size = 0;
1096 memset(session->nonceCaller.t.buffer, 0, sizeof(TPMU_HA));
1097 session->nonceCaller.b.size = 0;
1098 memset(session->sessionKey.t.buffer, 0, sizeof(TPMU_HA));
1099 session->sessionKey.b.size = 0;
1100 #endif
1101 session->sessionType = 0;
1102 session->isPasswordNeeded = FALSE;
1103 session->isAuthValueNeeded = FALSE;
1104 memset(session->hmacKey.t.buffer, 0, sizeof(TPMU_HA) + sizeof(TPMU_HA));
1105 session->hmacKey.b.size = 0;
1106 #ifndef TPM_TSS_NOCRYPTO
1107 memset(session->sessionValue.t.buffer, 0, sizeof(TPMU_HA) + sizeof(TPMU_HA));
1108 session->sessionValue.b.size = 0;
1109 #endif
1110 }
1111
TSS_HmacSession_FreeContext(struct TSS_HMAC_CONTEXT * session)1112 void TSS_HmacSession_FreeContext(struct TSS_HMAC_CONTEXT *session)
1113 {
1114 if (session != NULL) {
1115 TSS_HmacSession_InitContext(session);
1116 free(session);
1117 }
1118 return;
1119 }
1120
1121 /* TSS_HmacSession_SetSessionKey() is called by the StartAuthSession post processor to calculate and
1122 store the session key
1123
1124 19.6.8 sessionKey Creation
1125 */
1126
1127 #ifndef TPM_TSS_NOCRYPTO
1128
TSS_HmacSession_SetSessionKey(TSS_CONTEXT * tssContext,struct TSS_HMAC_CONTEXT * session,TPM2B_DIGEST * salt,TPMI_DH_ENTITY bind,TPM2B_AUTH * bindAuthValue)1129 static TPM_RC TSS_HmacSession_SetSessionKey(TSS_CONTEXT *tssContext,
1130 struct TSS_HMAC_CONTEXT *session,
1131 TPM2B_DIGEST *salt,
1132 TPMI_DH_ENTITY bind,
1133 TPM2B_AUTH *bindAuthValue)
1134 {
1135 TPM_RC rc = 0;
1136 TPM2B_KEY key; /* HMAC key for the KDFa */
1137
1138 if (rc == 0) {
1139 /* save the bind handle, non-null indicates a bound session */
1140 session->bind = bind;
1141 /* if bind, save the bind Name in the session context. The handle might change, but the
1142 name will not */
1143 if ((rc == 0) && (bind != TPM_RH_NULL)) {
1144 rc = TSS_Name_GetName(tssContext, &session->bindName, bind);
1145 }
1146 }
1147 if (rc == 0) {
1148 if ((bind != TPM_RH_NULL) ||
1149 (salt->b.size != 0)) {
1150
1151 /* session key is bindAuthValue || salt */
1152 /* copy bindAuthValue. This is set during the post processor to either the supplied
1153 bind password or Empty */
1154 if (rc == 0) {
1155 rc = TSS_TPM2B_Copy(&key.b, &bindAuthValue->b, sizeof(TPMU_HA) + sizeof(TPMT_HA));
1156 }
1157 /* copy salt. This is set during the postprocessor to either the salt from the
1158 preprocessor or empty. */
1159 if (rc == 0) {
1160 rc = TSS_TPM2B_Append(&key.b, &salt->b, sizeof(TPMU_HA) + sizeof(TPMT_HA));
1161 }
1162 if (rc == 0) {
1163 if (tssVverbose) TSS_PrintAll("TSS_HmacSession_SetSessionKey: KDFa HMAC key",
1164 key.b.buffer, key.b.size);
1165 }
1166 /* KDFa for the session key */
1167 if (rc == 0) {
1168 rc = TSS_KDFA(session->sessionKey.b.buffer,
1169 session->authHashAlg,
1170 &key.b,
1171 "ATH",
1172 &session->nonceTPM.b,
1173 &session->nonceCaller.b,
1174 session->sizeInBytes * 8);
1175 }
1176 if (rc == 0) {
1177 session->sessionKey.b.size = session->sizeInBytes;
1178 if (tssVverbose)
1179 TSS_PrintAll("TSS_HmacSession_SetSessionKey: Session key",
1180 session->sessionKey.b.buffer, session->sessionKey.b.size);
1181 }
1182 }
1183 else {
1184 session->sessionKey.b.size = 0;
1185 }
1186 }
1187 return rc;
1188 }
1189
1190 #endif /* TPM_TSS_NOCRYPTO */
1191
1192 /* TSS_HmacSession_SaveSession() saves a session in two cases:
1193
1194 The initial session from startauthsession
1195 The updated session a TPM response
1196 */
1197
1198
TSS_HmacSession_SaveSession(TSS_CONTEXT * tssContext,struct TSS_HMAC_CONTEXT * session)1199 static TPM_RC TSS_HmacSession_SaveSession(TSS_CONTEXT *tssContext,
1200 struct TSS_HMAC_CONTEXT *session)
1201 {
1202 TPM_RC rc = 0;
1203 uint8_t *buffer = NULL; /* marshaled TSS_HMAC_CONTEXT */
1204 uint16_t written = 0;
1205 #ifndef TPM_TSS_NOFILE
1206 char sessionFilename[TPM_DATA_DIR_PATH_LENGTH];
1207 uint8_t *outBuffer = NULL;
1208 uint32_t outLength;
1209 #endif
1210
1211 if (tssVverbose) printf("TSS_HmacSession_SaveSession: handle %08x\n", session->sessionHandle);
1212 if (rc == 0) {
1213 rc = TSS_Structure_Marshal(&buffer, /* freed @1 */
1214 &written,
1215 session,
1216 (MarshalFunction_t)TSS_HmacSession_Marshal);
1217 }
1218 #ifndef TPM_TSS_NOFILE
1219 if (rc == 0) {
1220 #ifndef TPM_TSS_NOCRYPTO
1221 /* if the flag is set, encrypt the session state before store */
1222 if (tssContext->tssEncryptSessions) {
1223 rc = TSS_AES_Encrypt(tssContext->tssSessionEncKey,
1224 &outBuffer, /* output, freed @2 */
1225 &outLength, /* output */
1226 buffer, /* input */
1227 written); /* input */
1228 }
1229 /* else store the session state in plaintext */
1230 else {
1231 #endif /* TPM_TSS_NOCRYPTO */
1232 outBuffer = buffer;
1233 outLength = written;
1234 #ifndef TPM_TSS_NOCRYPTO
1235 }
1236 #endif /* TPM_TSS_NOCRYPTO */
1237 }
1238 /* save the session in a hard coded file name hxxxxxxxx.bin where xxxxxxxx is the session
1239 handle */
1240 if (rc == 0) {
1241 sprintf(sessionFilename, "%s/h%08x.bin",
1242 tssContext->tssDataDirectory, session->sessionHandle);
1243 }
1244 if (rc == 0) {
1245 rc = TSS_File_WriteBinaryFile(outBuffer,
1246 outLength,
1247 sessionFilename);
1248 }
1249 if (tssContext->tssEncryptSessions) {
1250 free(outBuffer); /* @2 */
1251 }
1252 #else /* no file support, save to context */
1253 if (rc == 0) {
1254 rc = TSS_HmacSession_SaveData(tssContext,
1255 session->sessionHandle,
1256 written, buffer);
1257 }
1258 #endif
1259 free(buffer); /* @1 */
1260 return rc;
1261 }
1262
1263 /* TSS_HmacSession_LoadSession() loads an existing HMAC session context saved by:
1264
1265 startauthsession
1266 an update after a TPM response
1267 */
1268
TSS_HmacSession_LoadSession(TSS_CONTEXT * tssContext,struct TSS_HMAC_CONTEXT * session,TPMI_SH_AUTH_SESSION sessionHandle)1269 static TPM_RC TSS_HmacSession_LoadSession(TSS_CONTEXT *tssContext,
1270 struct TSS_HMAC_CONTEXT *session,
1271 TPMI_SH_AUTH_SESSION sessionHandle)
1272 {
1273 TPM_RC rc = 0;
1274 uint8_t *buffer = NULL;
1275 uint8_t *buffer1 = NULL;
1276 #ifndef TPM_TSS_NOFILE
1277 size_t length = 0;
1278 char sessionFilename[TPM_DATA_DIR_PATH_LENGTH];
1279 #endif
1280 unsigned char *inData = NULL; /* output */
1281 uint32_t inLength; /* output */
1282
1283 if (tssVverbose) printf("TSS_HmacSession_LoadSession: handle %08x\n", sessionHandle);
1284 #ifndef TPM_TSS_NOFILE
1285 /* load the session from a hard coded file name hxxxxxxxx.bin where xxxxxxxx is the session
1286 handle */
1287 if (rc == 0) {
1288 sprintf(sessionFilename, "%s/h%08x.bin", tssContext->tssDataDirectory, sessionHandle);
1289 rc = TSS_File_ReadBinaryFile(&buffer, /* freed @1 */
1290 &length,
1291 sessionFilename);
1292 }
1293 if (rc == 0) {
1294 #ifndef TPM_TSS_NOCRYPTO
1295 /* if the flag is set, decrypt the session state before unmarshal */
1296 if (tssContext->tssEncryptSessions) {
1297 rc = TSS_AES_Decrypt(tssContext->tssSessionDecKey,
1298 &inData, /* output, freed @2 */
1299 &inLength, /* output */
1300 buffer, /* input */
1301 length); /* input */
1302 }
1303 /* else the session was loaded in plaintext */
1304 else {
1305 #endif /* TPM_TSS_NOCRYPTO */
1306 inData = buffer;
1307 inLength = length;
1308 #ifndef TPM_TSS_NOCRYPTO
1309 }
1310 #endif /* TPM_TSS_NOCRYPTO */
1311 }
1312 #else /* no file support, load from context */
1313 if (rc == 0) {
1314 rc = TSS_HmacSession_LoadData(tssContext,
1315 &inLength, &inData,
1316 sessionHandle);
1317 }
1318 #endif
1319 if (rc == 0) {
1320 uint32_t ilength = inLength;
1321 buffer1 = inData;
1322 rc = TSS_HmacSession_Unmarshal(session, &buffer1, &ilength);
1323 }
1324 #ifndef TPM_TSS_NOFILE
1325 if (tssContext->tssEncryptSessions) {
1326 free(inData); /* @2 */
1327 }
1328 #endif
1329 free(buffer); /* @1 */
1330 return rc;
1331 }
1332
1333 #ifdef TPM_TSS_NOFILE
1334
TSS_HmacSession_SaveData(TSS_CONTEXT * tssContext,TPMI_SH_AUTH_SESSION sessionHandle,uint32_t outLength,uint8_t * outBuffer)1335 static TPM_RC TSS_HmacSession_SaveData(TSS_CONTEXT *tssContext,
1336 TPMI_SH_AUTH_SESSION sessionHandle,
1337 uint32_t outLength,
1338 uint8_t *outBuffer)
1339 {
1340 TPM_RC rc = 0;
1341 size_t slotIndex;
1342
1343 /* if this handle is already used, overwrite the slot */
1344 if (rc == 0) {
1345 rc = TSS_HmacSession_GetSlotForHandle(tssContext, &slotIndex, sessionHandle);
1346 if (rc != 0) {
1347 rc = TSS_HmacSession_GetSlotForHandle(tssContext, &slotIndex, TPM_RH_NULL);
1348 if (rc == 0) {
1349 tssContext->sessions[slotIndex].sessionHandle = sessionHandle;
1350 }
1351 else {
1352 if (tssVerbose)
1353 printf("TSS_HmacSession_SaveData: Error, no slot available for handle %08x\n",
1354 sessionHandle);
1355 }
1356 }
1357 }
1358 /* reallocate memory and adjust the size */
1359 if (rc == 0) {
1360 rc = TSS_Realloc(&tssContext->sessions[slotIndex].sessionData, outLength);
1361 }
1362 if (rc == 0) {
1363 tssContext->sessions[slotIndex].sessionDataLength = outLength;
1364 memcpy(tssContext->sessions[slotIndex].sessionData, outBuffer, outLength);
1365 }
1366 return rc;
1367 }
1368
TSS_HmacSession_LoadData(TSS_CONTEXT * tssContext,uint32_t * inLength,uint8_t ** inData,TPMI_SH_AUTH_SESSION sessionHandle)1369 static TPM_RC TSS_HmacSession_LoadData(TSS_CONTEXT *tssContext,
1370 uint32_t *inLength, uint8_t **inData,
1371 TPMI_SH_AUTH_SESSION sessionHandle)
1372 {
1373 TPM_RC rc = 0;
1374 size_t slotIndex;
1375
1376 if (rc == 0) {
1377 rc = TSS_HmacSession_GetSlotForHandle(tssContext, &slotIndex, sessionHandle);
1378 if (rc != 0) {
1379 if (tssVerbose)
1380 printf("TSS_HmacSession_LoadData: Error, no slot found for handle %08x\n",
1381 sessionHandle);
1382 }
1383 }
1384 if (rc == 0) {
1385 *inLength = tssContext->sessions[slotIndex].sessionDataLength;
1386 *inData = tssContext->sessions[slotIndex].sessionData;
1387 }
1388 return rc;
1389 }
1390
TSS_HmacSession_DeleteData(TSS_CONTEXT * tssContext,TPMI_SH_AUTH_SESSION sessionHandle)1391 static TPM_RC TSS_HmacSession_DeleteData(TSS_CONTEXT *tssContext,
1392 TPMI_SH_AUTH_SESSION sessionHandle)
1393 {
1394 TPM_RC rc = 0;
1395 size_t slotIndex;
1396
1397 if (rc == 0) {
1398 rc = TSS_HmacSession_GetSlotForHandle(tssContext, &slotIndex, sessionHandle);
1399 if (rc != 0) {
1400 if (tssVerbose)
1401 printf("TSS_HmacSession_DeleteData: Error, no slot found for handle %08x\n",
1402 sessionHandle);
1403 }
1404 }
1405 if (rc == 0) {
1406 tssContext->sessions[slotIndex].sessionHandle = TPM_RH_NULL;
1407 /* erase any secrets */
1408 memset(tssContext->sessions[slotIndex].sessionData, 0,
1409 tssContext->sessions[slotIndex].sessionDataLength);
1410 free(tssContext->sessions[slotIndex].sessionData);
1411 tssContext->sessions[slotIndex].sessionData = NULL;
1412 tssContext->sessions[slotIndex].sessionDataLength = 0;
1413 }
1414 return rc;
1415 }
1416
1417 /* TSS_HmacSession_GetSlotForHandle() finds the session slot corresponding to the session handle.
1418
1419 Returns non-zero if no slot is found.
1420 */
1421
TSS_HmacSession_GetSlotForHandle(TSS_CONTEXT * tssContext,size_t * slotIndex,TPMI_SH_AUTH_SESSION sessionHandle)1422 static TPM_RC TSS_HmacSession_GetSlotForHandle(TSS_CONTEXT *tssContext,
1423 size_t *slotIndex,
1424 TPMI_SH_AUTH_SESSION sessionHandle)
1425 {
1426 size_t i;
1427
1428 /* search all slots for handle */
1429 for (i = 0 ; i < (sizeof(tssContext->sessions) / sizeof(TSS_SESSIONS)) ; i++) {
1430 if (tssContext->sessions[i].sessionHandle == sessionHandle) {
1431 *slotIndex = i;
1432 return 0;
1433 }
1434 }
1435 return TSS_RC_NO_SESSION_SLOT;
1436 }
1437
1438 #endif
1439
TSS_HmacSession_Marshal(struct TSS_HMAC_CONTEXT * source,uint16_t * written,uint8_t ** buffer,uint32_t * size)1440 static TPM_RC TSS_HmacSession_Marshal(struct TSS_HMAC_CONTEXT *source,
1441 uint16_t *written,
1442 uint8_t **buffer,
1443 uint32_t *size)
1444 {
1445 TPM_RC rc = 0;
1446
1447 if (rc == 0) {
1448 rc = TSS_TPMI_SH_AUTH_SESSION_Marshalu(&source->sessionHandle, written, buffer, size);
1449 }
1450 if (rc == 0) {
1451 rc = TSS_TPMI_ALG_HASH_Marshalu(&source->authHashAlg, written, buffer, size);
1452 }
1453 #ifndef TPM_TSS_NOCRYPTO
1454 if (rc == 0) {
1455 rc = TSS_UINT32_Marshalu(&source->sizeInBytes, written, buffer, size);
1456 }
1457 #endif
1458 if (rc == 0) {
1459 rc = TSS_TPMT_SYM_DEF_Marshalu(&source->symmetric, written, buffer, size);
1460 }
1461 if (rc == 0) {
1462 rc = TSS_TPMI_DH_ENTITY_Marshalu(&source->bind, written, buffer, size);
1463 }
1464 if (rc == 0) {
1465 rc = TSS_TPM2B_NAME_Marshalu(&source->bindName, written, buffer, size);
1466 }
1467 #ifdef TPM_WINDOWS
1468 /* FIXME Why does a VS release build need a printf here? */
1469 if (tssVverbose) printf("");
1470 #endif
1471 if (rc == 0) {
1472 rc = TSS_TPM2B_AUTH_Marshalu(&source->bindAuthValue, written, buffer, size);
1473 }
1474 #ifndef TPM_TSS_NOCRYPTO
1475 if (rc == 0) {
1476 rc = TSS_TPM2B_NONCE_Marshalu(&source->nonceTPM, written, buffer, size);
1477 }
1478 if (rc == 0) {
1479 rc = TSS_TPM2B_NONCE_Marshalu(&source->nonceCaller, written, buffer, size);
1480 }
1481 if (rc == 0) {
1482 rc = TSS_TPM2B_DIGEST_Marshalu(&source->sessionKey, written, buffer, size);
1483 }
1484 #endif
1485 if (rc == 0) {
1486 rc = TSS_TPM_SE_Marshalu(&source->sessionType, written, buffer, size);
1487 }
1488 if (rc == 0) {
1489 rc = TSS_UINT8_Marshalu(&source->isPasswordNeeded, written, buffer, size);
1490 }
1491 if (rc == 0) {
1492 rc = TSS_UINT8_Marshalu(&source->isAuthValueNeeded, written, buffer, size);
1493 }
1494 return rc;
1495 }
1496
TSS_HmacSession_Unmarshal(struct TSS_HMAC_CONTEXT * target,uint8_t ** buffer,uint32_t * size)1497 static TPM_RC TSS_HmacSession_Unmarshal(struct TSS_HMAC_CONTEXT *target,
1498 uint8_t **buffer, uint32_t *size)
1499 {
1500 TPM_RC rc = 0;
1501
1502 if (rc == 0) {
1503 rc = TSS_TPMI_SH_AUTH_SESSION_Unmarshalu(&target->sessionHandle, buffer, size, NO);
1504 }
1505 if (rc == 0) {
1506 rc = TSS_TPMI_ALG_HASH_Unmarshalu(&target->authHashAlg, buffer, size, NO);
1507 }
1508 #ifndef TPM_TSS_NOCRYPTO
1509 if (rc == 0) {
1510 rc = TSS_UINT32_Unmarshalu(&target->sizeInBytes, buffer, size);
1511 }
1512 #endif
1513 if (rc == 0) {
1514 rc = TSS_TPMT_SYM_DEF_Unmarshalu(&target->symmetric, buffer, size, YES);
1515 }
1516 if (rc == 0) {
1517 rc = TSS_TPMI_DH_ENTITY_Unmarshalu(&target->bind, buffer, size, YES);
1518 }
1519 if (rc == 0) {
1520 rc = TSS_TPM2B_NAME_Unmarshalu(&target->bindName, buffer, size);
1521 }
1522 if (rc == 0) {
1523 rc = TSS_TPM2B_AUTH_Unmarshalu(&target->bindAuthValue, buffer, size);
1524 }
1525 #ifndef TPM_TSS_NOCRYPTO
1526 if (rc == 0) {
1527 rc = TSS_TPM2B_NONCE_Unmarshalu(&target->nonceTPM, buffer, size);
1528 }
1529 if (rc == 0) {
1530 rc = TSS_TPM2B_NONCE_Unmarshalu(&target->nonceCaller, buffer, size);
1531 }
1532 if (rc == 0) {
1533 rc = TSS_TPM2B_DIGEST_Unmarshalu(&target->sessionKey, buffer, size);
1534 }
1535 #endif
1536 if (rc == 0) {
1537 rc = TSS_TPM_SE_Unmarshalu(&target->sessionType, buffer, size);
1538 }
1539 if (rc == 0) {
1540 rc = TSS_UINT8_Unmarshalu(&target->isPasswordNeeded, buffer, size);
1541 }
1542 if (rc == 0) {
1543 rc = TSS_UINT8_Unmarshalu(&target->isAuthValueNeeded, buffer, size);
1544 }
1545 return rc;
1546 }
1547
1548 /*
1549 Name handling
1550 */
1551
1552 /* TSS_Name_GetAllNames() files in the names array based on the handles marshaled into the TSS
1553 context command stream. */
1554
TSS_Name_GetAllNames(TSS_CONTEXT * tssContext,TPM2B_NAME ** names)1555 static TPM_RC TSS_Name_GetAllNames(TSS_CONTEXT *tssContext,
1556 TPM2B_NAME **names)
1557 {
1558 TPM_RC rc = 0;
1559 size_t i;
1560 size_t commandHandleCount; /* number of handles in the command stream */
1561 TPM_HANDLE commandHandle;
1562
1563 /* get the number of handles in the command stream */
1564 if (rc == 0) {
1565 rc = TSS_GetCommandHandleCount(tssContext->tssAuthContext, &commandHandleCount);
1566 if (tssVverbose) printf("TSS_Name_GetAllNames: commandHandleCount %u\n",
1567 (unsigned int)commandHandleCount);
1568 }
1569 for (i = 0 ; (rc == 0) && (i < commandHandleCount) ; i++) {
1570 /* get a handle from the command stream */
1571 if (rc == 0) {
1572 rc = TSS_GetCommandHandle(tssContext->tssAuthContext,
1573 &commandHandle,
1574 i);
1575 }
1576 /* get the Name corresponding to the handle */
1577 if (rc == 0) {
1578 if (tssVverbose) printf("TSS_Name_GetAllNames: commandHandle %u %08x\n",
1579 (unsigned int)i, commandHandle);
1580 rc = TSS_Name_GetName(tssContext, names[i], commandHandle);
1581 }
1582 }
1583 return rc;
1584 }
1585
1586 /* TSS_Name_GetName() gets the Name associated with the handle */
1587
TSS_Name_GetName(TSS_CONTEXT * tssContext,TPM2B_NAME * name,TPM_HANDLE handle)1588 static TPM_RC TSS_Name_GetName(TSS_CONTEXT *tssContext,
1589 TPM2B_NAME *name,
1590 TPM_HANDLE handle)
1591 {
1592 TPM_RC rc = 0;
1593 TPM_HT handleType;
1594
1595 if (tssVverbose) printf("TSS_Name_GetName: Handle %08x\n", handle);
1596 handleType = (TPM_HT) ((handle & HR_RANGE_MASK) >> HR_SHIFT);
1597
1598 /* Table 3 - Equations for Computing Entity Names */
1599 switch (handleType) {
1600 /* for these, the Name is simply the handle value */
1601 case TPM_HT_PCR:
1602 case TPM_HT_HMAC_SESSION:
1603 case TPM_HT_POLICY_SESSION:
1604 case TPM_HT_PERMANENT:
1605 rc = TSS_TPM2B_CreateUint32(&name->b, handle, sizeof(name->t.name));
1606 break;
1607 /* for NV, the Names was calculated at NV read public */
1608 case TPM_HT_NV_INDEX:
1609 /* for objects, the Name was returned at creation or load */
1610 case TPM_HT_TRANSIENT:
1611 case TPM_HT_PERSISTENT:
1612 rc = TSS_Name_Load(tssContext, name, handle, NULL);
1613 break;
1614 default:
1615 if (tssVerbose) printf("TSS_Name_GetName: not implemented for handle %08x\n", handle);
1616 rc = TSS_RC_NAME_NOT_IMPLEMENTED;
1617 break;
1618 }
1619 if (rc == 0) {
1620 if (tssVverbose)
1621 TSS_PrintAll("TSS_Name_GetName: ",
1622 name->t.name, name->t.size);
1623 }
1624
1625 return rc;
1626 }
1627
1628 /* TSS_Name_Store() stores the 'name' parameter in a file.
1629
1630 If handle is not 0, the handle is used as the file name.
1631
1632 If 'string' is not NULL, the string is used as the file name.
1633 */
1634
1635 #ifndef TPM_TSS_NOFILE
1636
TSS_Name_Store(TSS_CONTEXT * tssContext,TPM2B_NAME * name,TPM_HANDLE handle,const char * string)1637 static TPM_RC TSS_Name_Store(TSS_CONTEXT *tssContext,
1638 TPM2B_NAME *name,
1639 TPM_HANDLE handle,
1640 const char *string)
1641 {
1642 TPM_RC rc = 0;
1643 char nameFilename[TPM_DATA_DIR_PATH_LENGTH];
1644
1645 if (rc == 0) {
1646 if (string == NULL) {
1647 if (handle != 0) {
1648 sprintf(nameFilename, "%s/h%08x.bin", tssContext->tssDataDirectory, handle);
1649 }
1650 else {
1651 if (tssVerbose) printf("TSS_Name_Store: handle and string are both null");
1652 rc = TSS_RC_NAME_FILENAME;
1653 }
1654 }
1655 else {
1656 if (handle == 0) {
1657 sprintf(nameFilename, "%s/h%s.bin", tssContext->tssDataDirectory, string);
1658 }
1659 else {
1660 if (tssVerbose) printf("TSS_Name_Store: handle and string are both not null");
1661 rc = TSS_RC_NAME_FILENAME;
1662 }
1663 }
1664 }
1665 if (rc == 0) {
1666 if (tssVverbose) printf("TSS_Name_Store: File %s\n", nameFilename);
1667 rc = TSS_File_WriteBinaryFile(name->b.buffer, name->b.size, nameFilename);
1668 }
1669 return rc;
1670 }
1671
1672 #endif
1673
1674 /* TSS_Name_Load() loads the 'name' from a file.
1675
1676 If handle is not 0, the handle is used as the file name.
1677
1678 If 'string' is not NULL, the string is used as the file name.
1679 */
1680
1681 #ifndef TPM_TSS_NOFILE
1682
TSS_Name_Load(TSS_CONTEXT * tssContext,TPM2B_NAME * name,TPM_HANDLE handle,const char * string)1683 static TPM_RC TSS_Name_Load(TSS_CONTEXT *tssContext,
1684 TPM2B_NAME *name,
1685 TPM_HANDLE handle,
1686 const char *string)
1687 {
1688 TPM_RC rc = 0;
1689 char nameFilename[TPM_DATA_DIR_PATH_LENGTH];
1690
1691 if (rc == 0) {
1692 if (string == NULL) {
1693 if (handle != 0) {
1694 sprintf(nameFilename, "%s/h%08x.bin", tssContext->tssDataDirectory, handle);
1695 }
1696 else {
1697 if (tssVerbose) printf("TSS_Name_Load: handle and string are both null\n");
1698 rc = TSS_RC_NAME_FILENAME;
1699 }
1700 }
1701 else {
1702 if (handle == 0) {
1703 sprintf(nameFilename, "%s/h%s.bin", tssContext->tssDataDirectory, string);
1704 }
1705 else {
1706 if (tssVerbose) printf("TSS_Name_Load: handle and string are both not null\n");
1707 rc = TSS_RC_NAME_FILENAME;
1708 }
1709 }
1710 }
1711 if (rc == 0) {
1712 if (tssVverbose) printf("TSS_Name_Load: File %s\n", nameFilename);
1713 rc = TSS_File_Read2B(&name->b,
1714 sizeof(name->t.name),
1715 nameFilename);
1716 }
1717 return rc;
1718 }
1719
1720 #endif
1721
1722 /* TSS_Name_Store() stores the 'name' parameter the TSS context.
1723
1724 */
1725
1726 #ifdef TPM_TSS_NOFILE
1727
TSS_Name_Store(TSS_CONTEXT * tssContext,TPM2B_NAME * name,TPM_HANDLE handle,const char * string)1728 static TPM_RC TSS_Name_Store(TSS_CONTEXT *tssContext,
1729 TPM2B_NAME *name,
1730 TPM_HANDLE handle,
1731 const char *string)
1732 {
1733 TPM_RC rc = 0;
1734 TPM_HT handleType;
1735 size_t slotIndex;
1736
1737 if (tssVverbose) printf("TSS_Name_Store: Handle %08x\n", handle);
1738 handleType = (TPM_HT) ((handle & HR_RANGE_MASK) >> HR_SHIFT);
1739
1740 switch (handleType) {
1741 case TPM_HT_NV_INDEX:
1742 /* for NV, the Name was returned at creation */
1743 rc = TSS_NvPublic_GetSlotForHandle(tssContext, &slotIndex, handle);
1744 if (rc != 0) {
1745 rc = TSS_NvPublic_GetSlotForHandle(tssContext, &slotIndex, TPM_RH_NULL);
1746 if (rc == 0) {
1747 tssContext->nvPublic[slotIndex].nvIndex = handle;
1748 }
1749 else {
1750 if (tssVerbose)
1751 printf("TSS_Name_Store: Error, no slot available for handle %08x\n", handle);
1752 }
1753 }
1754 if (rc == 0) {
1755 tssContext->nvPublic[slotIndex].name = *name;
1756 }
1757 break;
1758 case TPM_HT_TRANSIENT:
1759 case TPM_HT_PERSISTENT:
1760 if (rc == 0) {
1761 if (string == NULL) {
1762 if (handle != 0) {
1763 /* if this handle is already used, overwrite the slot */
1764 rc = TSS_ObjectPublic_GetSlotForHandle(tssContext, &slotIndex, handle);
1765 if (rc != 0) {
1766 rc = TSS_ObjectPublic_GetSlotForHandle(tssContext, &slotIndex, TPM_RH_NULL);
1767 if (rc == 0) {
1768 tssContext->objectPublic[slotIndex].objectHandle = handle;
1769 }
1770 else {
1771 if (tssVerbose)
1772 printf("TSS_Name_Store: "
1773 "Error, no slot available for handle %08x\n",
1774 handle);
1775 }
1776 }
1777 }
1778 else {
1779 if (tssVerbose) printf("TSS_Name_Store: handle and string are both null");
1780 rc = TSS_RC_NAME_FILENAME;
1781 }
1782 }
1783 else {
1784 if (handle == 0) {
1785 if (tssVerbose) printf("TSS_Name_Store: string unimplemented");
1786 rc = TSS_RC_NAME_FILENAME;
1787 }
1788 else {
1789 if (tssVerbose) printf("TSS_Name_Store: handle and string are both not null");
1790 rc = TSS_RC_NAME_FILENAME;
1791 }
1792 }
1793 }
1794 if (rc == 0) {
1795 tssContext->objectPublic[slotIndex].name = *name;
1796 }
1797 break;
1798 default:
1799 if (tssVerbose) printf("TSS_Name_Store: handle type %02x unimplemented", handleType);
1800 rc = TSS_RC_NAME_FILENAME;
1801 }
1802 return rc;
1803 }
1804
1805 #endif
1806
1807 /* TSS_Name_Load() loads the 'name' from the TSS context.
1808
1809 */
1810
1811 #ifdef TPM_TSS_NOFILE
1812
TSS_Name_Load(TSS_CONTEXT * tssContext,TPM2B_NAME * name,TPM_HANDLE handle,const char * string)1813 static TPM_RC TSS_Name_Load(TSS_CONTEXT *tssContext,
1814 TPM2B_NAME *name,
1815 TPM_HANDLE handle,
1816 const char *string)
1817 {
1818 TPM_RC rc = 0;
1819 TPM_HT handleType;
1820 size_t slotIndex;
1821
1822 string = string;
1823
1824 if (tssVverbose) printf("TSS_Name_Load: Handle %08x\n", handle);
1825 handleType = (TPM_HT) ((handle & HR_RANGE_MASK) >> HR_SHIFT);
1826
1827 switch (handleType) {
1828 case TPM_HT_NV_INDEX:
1829 rc = TSS_NvPublic_GetSlotForHandle(tssContext, &slotIndex, handle);
1830 if (rc != 0) {
1831 if (tssVerbose)
1832 printf("TSS_Name_Load: Error, no slot found for handle %08x\n", handle);
1833 }
1834 if (rc == 0) {
1835 *name = tssContext->nvPublic[slotIndex].name;
1836 }
1837 break;
1838 case TPM_HT_TRANSIENT:
1839 case TPM_HT_PERSISTENT:
1840 rc = TSS_ObjectPublic_GetSlotForHandle(tssContext, &slotIndex, handle);
1841 if (rc != 0) {
1842 if (tssVerbose)
1843 printf("TSS_Name_Load: Error, no slot found for handle %08x\n", handle);
1844 }
1845 if (rc == 0) {
1846 *name = tssContext->objectPublic[slotIndex].name;
1847 }
1848 break;
1849 default:
1850 if (tssVerbose) printf("TSS_Name_Load: handle type %02x unimplemented", handleType);
1851 rc = TSS_RC_NAME_FILENAME;
1852
1853 }
1854 return rc;
1855 }
1856
1857 #endif
1858
1859 /* TSS_Name_Copy() copies the name from either inHandle or inString to either outHandle or
1860 outString */
1861
TSS_Name_Copy(TSS_CONTEXT * tssContext,TPM_HANDLE outHandle,const char * outString,TPM_HANDLE inHandle,const char * inString)1862 static TPM_RC TSS_Name_Copy(TSS_CONTEXT *tssContext,
1863 TPM_HANDLE outHandle,
1864 const char *outString,
1865 TPM_HANDLE inHandle,
1866 const char *inString)
1867 {
1868 TPM_RC rc = 0;
1869 TPM2B_NAME name;
1870
1871 if (rc == 0) {
1872 rc = TSS_Name_Load(tssContext, &name, inHandle, inString);
1873 }
1874 if (rc == 0) {
1875 rc = TSS_Name_Store(tssContext, &name, outHandle, outString);
1876 }
1877 return rc;
1878 }
1879
1880 /* TSS_Public_Store() stores the 'public' parameter in a file.
1881
1882 If handle is not 0, the handle is used as the file name.
1883
1884 If 'string' is not NULL, the string is used as the file name.
1885 */
1886
1887 #ifndef TPM_TSS_NOFILE
1888
TSS_Public_Store(TSS_CONTEXT * tssContext,TPM2B_PUBLIC * public,TPM_HANDLE handle,const char * string)1889 static TPM_RC TSS_Public_Store(TSS_CONTEXT *tssContext,
1890 TPM2B_PUBLIC *public,
1891 TPM_HANDLE handle,
1892 const char *string)
1893 {
1894 TPM_RC rc = 0;
1895 char publicFilename[TPM_DATA_DIR_PATH_LENGTH];
1896
1897 if (rc == 0) {
1898 if (string == NULL) {
1899 if (handle != 0) { /* store by handle */
1900 sprintf(publicFilename, "%s/hp%08x.bin", tssContext->tssDataDirectory, handle);
1901 }
1902 else {
1903 if (tssVerbose) printf("TSS_Public_Store: handle and string are both null");
1904 rc = TSS_RC_NAME_FILENAME;
1905 }
1906 }
1907 else {
1908 if (handle == 0) { /* store by string */
1909 sprintf(publicFilename, "%s/hp%s.bin", tssContext->tssDataDirectory, string);
1910 }
1911 else {
1912 if (tssVerbose) printf("TSS_Public_Store: handle and string are both not null");
1913 rc = TSS_RC_NAME_FILENAME;
1914 }
1915 }
1916 }
1917 if (rc == 0) {
1918 if (tssVverbose) printf("TSS_Public_Store: File %s\n", publicFilename);
1919 rc = TSS_File_WriteStructure(public,
1920 (MarshalFunction_t)TSS_TPM2B_PUBLIC_Marshalu,
1921 publicFilename);
1922 }
1923 return rc;
1924 }
1925
1926 #endif
1927
1928 /* TSS_Public_Load() loads the 'public' parameter from a file.
1929
1930 If handle is not 0, the handle is used as the file name.
1931
1932 If 'string' is not NULL, the string is used as the file name.
1933 */
1934
1935 #ifndef TPM_TSS_NOFILE
1936
TSS_Public_Load(TSS_CONTEXT * tssContext,TPM2B_PUBLIC * public,TPM_HANDLE handle,const char * string)1937 static TPM_RC TSS_Public_Load(TSS_CONTEXT *tssContext,
1938 TPM2B_PUBLIC *public,
1939 TPM_HANDLE handle,
1940 const char *string)
1941 {
1942 TPM_RC rc = 0;
1943 char publicFilename[TPM_DATA_DIR_PATH_LENGTH];
1944
1945 if (rc == 0) {
1946 if (string == NULL) {
1947 if (handle != 0) {
1948 sprintf(publicFilename, "%s/hp%08x.bin", tssContext->tssDataDirectory, handle);
1949 }
1950 else {
1951 if (tssVerbose) printf("TSS_Public_Load: handle and string are both null\n");
1952 rc = TSS_RC_NAME_FILENAME;
1953 }
1954 }
1955 else {
1956 if (handle == 0) {
1957 sprintf(publicFilename, "%s/hp%s.bin", tssContext->tssDataDirectory, string);
1958 }
1959 else {
1960 if (tssVerbose) printf("TSS_Public_Load: handle and string are both not null\n");
1961 rc = TSS_RC_NAME_FILENAME;
1962 }
1963 }
1964 }
1965 if (rc == 0) {
1966 if (tssVverbose) printf("TSS_Public_Load: File %s\n", publicFilename);
1967 rc = TSS_File_ReadStructureFlag(public,
1968 (UnmarshalFunctionFlag_t)TSS_TPM2B_PUBLIC_Unmarshalu,
1969 TRUE, /* NULL permitted */
1970 publicFilename);
1971 }
1972 return rc;
1973 }
1974
1975 #endif /* TPM_TSS_NOFILE */
1976
1977 /* TSS_Public_Copy() copies the TPM2B_PUBLIC from either inHandle or inString to either outHandle or
1978 outString */
1979
TSS_Public_Copy(TSS_CONTEXT * tssContext,TPM_HANDLE outHandle,const char * outString,TPM_HANDLE inHandle,const char * inString)1980 static TPM_RC TSS_Public_Copy(TSS_CONTEXT *tssContext,
1981 TPM_HANDLE outHandle,
1982 const char *outString,
1983 TPM_HANDLE inHandle,
1984 const char *inString)
1985 {
1986 TPM_RC rc = 0;
1987 TPM2B_PUBLIC public;
1988
1989 if (rc == 0) {
1990 rc = TSS_Public_Load(tssContext, &public, inHandle, inString);
1991 }
1992 if (rc == 0) {
1993 rc = TSS_Public_Store(tssContext, &public, outHandle, outString);
1994 }
1995 return rc;
1996 }
1997
1998 /* TSS_Public_Store() stores the 'public' parameter in the TSS context.
1999 */
2000
2001 #ifdef TPM_TSS_NOFILE
2002
TSS_Public_Store(TSS_CONTEXT * tssContext,TPM2B_PUBLIC * public,TPM_HANDLE handle,const char * string)2003 static TPM_RC TSS_Public_Store(TSS_CONTEXT *tssContext,
2004 TPM2B_PUBLIC *public,
2005 TPM_HANDLE handle,
2006 const char *string)
2007 {
2008 TPM_RC rc = 0;
2009 size_t slotIndex;
2010
2011 if (rc == 0) {
2012 if (string == NULL) {
2013 if (handle != 0) {
2014 /* if this handle is already used, overwrite the slot */
2015 rc = TSS_ObjectPublic_GetSlotForHandle(tssContext, &slotIndex, handle);
2016 if (rc != 0) {
2017 rc = TSS_ObjectPublic_GetSlotForHandle(tssContext, &slotIndex, TPM_RH_NULL);
2018 if (rc == 0) {
2019 tssContext->objectPublic[slotIndex].objectHandle = handle;
2020 }
2021 else {
2022 if (tssVerbose)
2023 printf("TSS_Public_Store: Error, no slot available for handle %08x\n",
2024 handle);
2025 }
2026 }
2027 }
2028 else {
2029 if (tssVerbose) printf("TSS_Public_Store: handle and string are both null");
2030 rc = TSS_RC_NAME_FILENAME;
2031 }
2032 }
2033 else {
2034 if (handle == 0) {
2035 if (tssVerbose) printf("TSS_Public_Store: string not implemented yet");
2036 rc = TSS_RC_NAME_FILENAME;
2037 }
2038 else {
2039 if (tssVerbose) printf("TSS_Public_Store: handle and string are both not null");
2040 rc = TSS_RC_NAME_FILENAME;
2041 }
2042 }
2043 }
2044 if (rc == 0) {
2045 tssContext->objectPublic[slotIndex].objectPublic = *public;
2046 }
2047 return rc;
2048 }
2049
2050 #endif
2051
2052 /* TSS_Public_Load() loaded the object public from the TSS context.
2053
2054 */
2055
2056 #ifdef TPM_TSS_NOFILE
2057
TSS_Public_Load(TSS_CONTEXT * tssContext,TPM2B_PUBLIC * public,TPM_HANDLE handle,const char * string)2058 static TPM_RC TSS_Public_Load(TSS_CONTEXT *tssContext,
2059 TPM2B_PUBLIC *public,
2060 TPM_HANDLE handle,
2061 const char *string)
2062 {
2063 TPM_RC rc = 0;
2064 size_t slotIndex;
2065
2066 if (rc == 0) {
2067 if (string == NULL) {
2068 if (handle != 0) {
2069 rc = TSS_ObjectPublic_GetSlotForHandle(tssContext, &slotIndex, handle);
2070 if (rc != 0) {
2071 if (tssVerbose)
2072 printf("TSS_Public_Load: Error, no slot found for handle %08x\n",
2073 handle);
2074 }
2075 }
2076 else {
2077 if (tssVerbose) printf("TSS_Public_Load: handle and string are both null\n");
2078 rc = TSS_RC_NAME_FILENAME;
2079 }
2080 }
2081 else {
2082 if (handle == 0) {
2083 if (tssVerbose) printf("TSS_Public_Load: string not implemented yet");
2084 rc = TSS_RC_NAME_FILENAME;
2085 }
2086 else {
2087 if (tssVerbose) printf("TSS_Public_Load: handle and string are both not null\n");
2088 rc = TSS_RC_NAME_FILENAME;
2089 }
2090 }
2091 }
2092 if (rc == 0) {
2093 *public = tssContext->objectPublic[slotIndex].objectPublic;
2094 }
2095 return rc;
2096 }
2097
2098 #endif /* TPM_TSS_NOFILE */
2099
2100 #ifdef TPM_TSS_NOFILE
2101
2102 /* TSS_ObjectPublic_GetSlotForHandle() finds the object public slot corresponding to the handle.
2103
2104 Returns non-zero if no slot is found.
2105 */
2106
TSS_ObjectPublic_GetSlotForHandle(TSS_CONTEXT * tssContext,size_t * slotIndex,TPM_HANDLE handle)2107 static TPM_RC TSS_ObjectPublic_GetSlotForHandle(TSS_CONTEXT *tssContext,
2108 size_t *slotIndex,
2109 TPM_HANDLE handle)
2110 {
2111 size_t i;
2112
2113 /* search all slots for handle */
2114 for (i = 0 ; i < (sizeof(tssContext->sessions) / sizeof(TSS_SESSIONS)) ; i++) {
2115 if (tssContext->objectPublic[i].objectHandle == handle) {
2116 *slotIndex = i;
2117 return 0;
2118 }
2119 }
2120 return TSS_RC_NO_OBJECTPUBLIC_SLOT;
2121 }
2122
2123 #endif
2124
2125 #ifdef TPM_TSS_NOFILE
2126
TSS_ObjectPublic_DeleteData(TSS_CONTEXT * tssContext,TPM_HANDLE handle)2127 static TPM_RC TSS_ObjectPublic_DeleteData(TSS_CONTEXT *tssContext, TPM_HANDLE handle)
2128 {
2129 TPM_RC rc = 0;
2130 size_t slotIndex;
2131
2132 if (rc == 0) {
2133 rc = TSS_ObjectPublic_GetSlotForHandle(tssContext, &slotIndex, handle);
2134 if (rc != 0) {
2135 if (tssVerbose)
2136 printf("TSS_ObjectPublic_DeleteData: Error, no slot found for handle %08x\n",
2137 handle);
2138 }
2139 }
2140 if (rc == 0) {
2141 tssContext->objectPublic[slotIndex].objectHandle = TPM_RH_NULL;
2142 }
2143 return rc;
2144 }
2145
2146 #endif
2147
2148
2149 /* TSS_DeleteHandle() removes retained state stored by the TSS for a handle
2150 */
2151
TSS_DeleteHandle(TSS_CONTEXT * tssContext,TPM_HANDLE handle)2152 static TPM_RC TSS_DeleteHandle(TSS_CONTEXT *tssContext,
2153 TPM_HANDLE handle)
2154 {
2155 TPM_RC rc = 0;
2156 TPM_HT handleType;
2157 #ifndef TPM_TSS_NOFILE
2158 char filename[TPM_DATA_DIR_PATH_LENGTH];
2159 #endif
2160
2161 handleType = (TPM_HT) ((handle & HR_RANGE_MASK) >> HR_SHIFT);
2162 #ifndef TPM_TSS_NOFILE
2163 /* delete the Name */
2164 if (rc == 0) {
2165 sprintf(filename, "%s/h%08x.bin", tssContext->tssDataDirectory, handle);
2166 if (tssVverbose) printf("TSS_DeleteHandle: delete Name file %s\n", filename);
2167 rc = TSS_File_DeleteFile(filename);
2168 }
2169 /* delete the public if it exists */
2170 if (rc == 0) {
2171 if ((handleType == TPM_HT_TRANSIENT) ||
2172 (handleType == TPM_HT_PERSISTENT)) {
2173 sprintf(filename, "%s/hp%08x.bin", tssContext->tssDataDirectory, handle);
2174 if (tssVverbose) printf("TSS_DeleteHandle: delete public file %s\n", filename);
2175 TSS_File_DeleteFile(filename);
2176 }
2177 }
2178 #else
2179 /* sessions persist in the context and can be deleted */
2180 if (rc == 0) {
2181 switch (handleType) {
2182 case TPM_HT_NV_INDEX:
2183 rc = TSS_RC_NOT_IMPLEMENTED;
2184 break;
2185 case TPM_HT_HMAC_SESSION:
2186 case TPM_HT_POLICY_SESSION:
2187 if (tssVverbose) printf("TSS_DeleteHandle: delete session state %08x\n", handle);
2188 rc = TSS_HmacSession_DeleteData(tssContext, handle);
2189 break;
2190 case TPM_HT_TRANSIENT:
2191 case TPM_HT_PERSISTENT:
2192 rc = TSS_ObjectPublic_DeleteData(tssContext, handle);
2193 break;
2194 }
2195 }
2196 #endif
2197 return rc;
2198 }
2199
2200 #ifndef TPM_TSS_NOCRYPTO
2201
2202 /* TSS_ObjectPublic_GetName() calculates the Name from the TPMT_PUBLIC. The Name provides security,
2203 because the Name returned from the TPM2_ReadPublic cannot be trusted.
2204 */
2205
TSS_ObjectPublic_GetName(TPM2B_NAME * name,TPMT_PUBLIC * tpmtPublic)2206 static TPM_RC TSS_ObjectPublic_GetName(TPM2B_NAME *name,
2207 TPMT_PUBLIC *tpmtPublic)
2208 {
2209 TPM_RC rc = 0;
2210
2211 uint16_t written = 0;
2212 TPMT_HA digest;
2213 uint32_t sizeInBytes = 0;
2214 uint8_t *buffer = NULL;
2215
2216 if (rc == 0) {
2217 rc = TSS_Malloc(&buffer, MAX_RESPONSE_SIZE); /* freed @1 */
2218 }
2219 /* marshal the TPMT_PUBLIC */
2220 if (rc == 0) {
2221 uint32_t size = MAX_RESPONSE_SIZE;
2222 uint8_t *buffer1 = buffer;
2223 rc = TSS_TPMT_PUBLIC_Marshalu(tpmtPublic, &written, &buffer1, &size);
2224 }
2225 /* hash the public area */
2226 if (rc == 0) {
2227 sizeInBytes = TSS_GetDigestSize(tpmtPublic->nameAlg);
2228 digest.hashAlg = tpmtPublic->nameAlg; /* Name digest algorithm */
2229 /* generate the TPMT_HA */
2230 rc = TSS_Hash_Generate(&digest,
2231 written, buffer,
2232 0, NULL);
2233 }
2234 if (rc == 0) {
2235 TPMI_ALG_HASH nameAlgNbo;
2236 /* copy the digest */
2237 memcpy(name->t.name + sizeof(TPMI_ALG_HASH), (uint8_t *)&digest.digest, sizeInBytes);
2238 /* copy the hash algorithm */
2239 nameAlgNbo = htons(tpmtPublic->nameAlg);
2240 memcpy(name->t.name, (uint8_t *)&nameAlgNbo, sizeof(TPMI_ALG_HASH));
2241 /* set the size */
2242 name->t.size = sizeInBytes + sizeof(TPMI_ALG_HASH);
2243 }
2244 free(buffer); /* @1 */
2245 return rc;
2246 }
2247
2248 #endif /* TPM_TSS_NOCRYPTO */
2249
2250
2251 /* TSS_NVPublic_Store() stores the NV public data in a file.
2252
2253 */
2254
2255 #ifndef TPM_TSS_NOFILE
2256 #ifndef TPM_TSS_NOCRYPTO
2257
TSS_NVPublic_Store(TSS_CONTEXT * tssContext,TPMS_NV_PUBLIC * nvPublic,TPMI_RH_NV_INDEX nvIndex)2258 static TPM_RC TSS_NVPublic_Store(TSS_CONTEXT *tssContext,
2259 TPMS_NV_PUBLIC *nvPublic,
2260 TPMI_RH_NV_INDEX nvIndex)
2261 {
2262 TPM_RC rc = 0;
2263 char nvpFilename[TPM_DATA_DIR_PATH_LENGTH];
2264
2265 if (rc == 0) {
2266 sprintf(nvpFilename, "%s/nvp%08x.bin", tssContext->tssDataDirectory, nvIndex);
2267 rc = TSS_File_WriteStructure(nvPublic,
2268 (MarshalFunction_t)TSS_TPMS_NV_PUBLIC_Marshalu,
2269 nvpFilename);
2270 }
2271 return rc;
2272 }
2273
2274 #endif
2275 #endif
2276
2277 /* TSS_NVPublic_Load() loads the NV public from a file.
2278
2279 */
2280
2281 #ifndef TPM_TSS_NOFILE
2282 #ifndef TPM_TSS_NOCRYPTO
2283
TSS_NVPublic_Load(TSS_CONTEXT * tssContext,TPMS_NV_PUBLIC * nvPublic,TPMI_RH_NV_INDEX nvIndex)2284 static TPM_RC TSS_NVPublic_Load(TSS_CONTEXT *tssContext,
2285 TPMS_NV_PUBLIC *nvPublic,
2286 TPMI_RH_NV_INDEX nvIndex)
2287 {
2288 TPM_RC rc = 0;
2289 char nvpFilename[TPM_DATA_DIR_PATH_LENGTH];
2290
2291 if (rc == 0) {
2292 sprintf(nvpFilename, "%s/nvp%08x.bin", tssContext->tssDataDirectory, nvIndex);
2293 rc = TSS_File_ReadStructure(nvPublic,
2294 (UnmarshalFunction_t)TSS_TPMS_NV_PUBLIC_Unmarshalu,
2295 nvpFilename);
2296 }
2297 return rc;
2298 }
2299
2300 #endif
2301 #endif
2302
2303 #ifndef TPM_TSS_NOFILE
2304
TSS_NVPublic_Delete(TSS_CONTEXT * tssContext,TPMI_RH_NV_INDEX nvIndex)2305 static TPM_RC TSS_NVPublic_Delete(TSS_CONTEXT *tssContext,
2306 TPMI_RH_NV_INDEX nvIndex)
2307 {
2308 TPM_RC rc = 0;
2309 char nvpFilename[TPM_DATA_DIR_PATH_LENGTH];
2310
2311 if (rc == 0) {
2312 sprintf(nvpFilename, "%s/nvp%08x.bin", tssContext->tssDataDirectory, nvIndex);
2313 rc = TSS_File_DeleteFile(nvpFilename);
2314 }
2315 return rc;
2316 }
2317
2318 #endif
2319
2320 #ifdef TPM_TSS_NOFILE
2321 #ifndef TPM_TSS_NOCRYPTO
2322
2323 /* TSS_NVPublic_Store() stores the NV public data in a file.
2324
2325 */
2326
TSS_NVPublic_Store(TSS_CONTEXT * tssContext,TPMS_NV_PUBLIC * nvPublic,TPMI_RH_NV_INDEX nvIndex)2327 static TPM_RC TSS_NVPublic_Store(TSS_CONTEXT *tssContext,
2328 TPMS_NV_PUBLIC *nvPublic,
2329 TPMI_RH_NV_INDEX nvIndex)
2330 {
2331 TPM_RC rc = 0;
2332 size_t slotIndex;
2333
2334 if (rc == 0) {
2335 rc = TSS_NvPublic_GetSlotForHandle(tssContext, &slotIndex, nvIndex);
2336 if (rc != 0) {
2337 rc = TSS_NvPublic_GetSlotForHandle(tssContext, &slotIndex, TPM_RH_NULL);
2338 if (rc == 0) {
2339 tssContext->nvPublic[slotIndex].nvIndex = nvIndex;
2340 }
2341 else {
2342 if (tssVerbose)
2343 printf("TSS_NVPublic_Store: Error, no slot available for handle %08x\n",
2344 nvIndex);
2345 }
2346 }
2347 }
2348 if (rc == 0) {
2349 tssContext->nvPublic[slotIndex].nvPublic = *nvPublic;
2350 }
2351 return rc;
2352 }
2353
2354 #endif
2355 #endif
2356
2357 #ifdef TPM_TSS_NOFILE
2358 #ifndef TPM_TSS_NOCRYPTO
2359
2360 /* TSS_NVPublic_Load() loads the NV public from a file.
2361
2362 */
2363
TSS_NVPublic_Load(TSS_CONTEXT * tssContext,TPMS_NV_PUBLIC * nvPublic,TPMI_RH_NV_INDEX nvIndex)2364 static TPM_RC TSS_NVPublic_Load(TSS_CONTEXT *tssContext,
2365 TPMS_NV_PUBLIC *nvPublic,
2366 TPMI_RH_NV_INDEX nvIndex)
2367 {
2368 TPM_RC rc = 0;
2369 size_t slotIndex;
2370
2371 if (rc == 0) {
2372 rc = TSS_NvPublic_GetSlotForHandle(tssContext, &slotIndex, nvIndex);
2373 if (rc != 0) {
2374 if (tssVerbose)
2375 printf("TSS_NVPublic_Load: Error, no slot found for handle %08x\n",
2376 nvIndex);
2377 }
2378 }
2379 if (rc == 0) {
2380 *nvPublic = tssContext->nvPublic[slotIndex].nvPublic;
2381 }
2382 return rc;
2383 }
2384
2385 #endif
2386 #endif
2387
2388 #ifdef TPM_TSS_NOFILE
2389
TSS_NVPublic_Delete(TSS_CONTEXT * tssContext,TPMI_RH_NV_INDEX nvIndex)2390 static TPM_RC TSS_NVPublic_Delete(TSS_CONTEXT *tssContext,
2391 TPMI_RH_NV_INDEX nvIndex)
2392 {
2393 TPM_RC rc = 0;
2394 size_t slotIndex;
2395
2396 if (rc == 0) {
2397 rc = TSS_NvPublic_GetSlotForHandle(tssContext, &slotIndex, nvIndex);
2398 if (rc != 0) {
2399 if (tssVerbose)
2400 printf("TSS_NVPublic_Delete: Error, no slot found for handle %08x\n",
2401 nvIndex);
2402 }
2403 }
2404 if (rc == 0) {
2405 tssContext->nvPublic[slotIndex].nvIndex = TPM_RH_NULL;
2406 }
2407 return rc;
2408 }
2409
2410 #endif
2411
2412 #ifdef TPM_TSS_NOFILE
2413
2414 /* TSS_NvPublic_GetSlotForHandle() finds the object public slot corresponding to the handle.
2415
2416 Returns non-zero if no slot is found.
2417 */
2418
TSS_NvPublic_GetSlotForHandle(TSS_CONTEXT * tssContext,size_t * slotIndex,TPMI_RH_NV_INDEX nvIndex)2419 static TPM_RC TSS_NvPublic_GetSlotForHandle(TSS_CONTEXT *tssContext,
2420 size_t *slotIndex,
2421 TPMI_RH_NV_INDEX nvIndex)
2422 {
2423 size_t i;
2424
2425 /* search all slots for handle */
2426 for (i = 0 ; i < (sizeof(tssContext->nvPublic) / sizeof(TSS_NVPUBLIC)) ; i++) {
2427 if (tssContext->nvPublic[i].nvIndex == nvIndex) {
2428 *slotIndex = i;
2429 return 0;
2430 }
2431 }
2432 return TSS_RC_NO_NVPUBLIC_SLOT;
2433 }
2434
2435 #endif
2436
2437 /* TSS_NVPublic_GetName() calculates the Name from the TPMS_NV_PUBLIC. The Name provides security,
2438 because the Name returned from the TPM2_NV_ReadPublic cannot be trusted.
2439 */
2440
2441 #ifndef TPM_TSS_NOCRYPTO
2442
TSS_NVPublic_GetName(TPM2B_NAME * name,TPMS_NV_PUBLIC * nvPublic)2443 static TPM_RC TSS_NVPublic_GetName(TPM2B_NAME *name,
2444 TPMS_NV_PUBLIC *nvPublic)
2445 {
2446 TPM_RC rc = 0;
2447
2448 uint16_t written = 0;
2449 TPMT_HA digest;
2450 uint32_t sizeInBytes = 0;
2451 uint8_t *buffer = NULL;
2452
2453 if (rc == 0) {
2454 rc = TSS_Malloc(&buffer, MAX_RESPONSE_SIZE); /* freed @1 */
2455 }
2456 /* marshal the TPMS_NV_PUBLIC */
2457 if (rc == 0) {
2458 uint32_t size = MAX_RESPONSE_SIZE;
2459 uint8_t *buffer1 = buffer;
2460 rc = TSS_TPMS_NV_PUBLIC_Marshalu(nvPublic, &written, &buffer1, &size);
2461 }
2462 /* hash the public area */
2463 if (rc == 0) {
2464 sizeInBytes = TSS_GetDigestSize(nvPublic->nameAlg);
2465 digest.hashAlg = nvPublic->nameAlg; /* Name digest algorithm */
2466 /* generate the TPMT_HA */
2467 rc = TSS_Hash_Generate(&digest,
2468 written, buffer,
2469 0, NULL);
2470 }
2471 if (rc == 0) {
2472 TPMI_ALG_HASH nameAlgNbo;
2473 /* copy the digest */
2474 memcpy(name->t.name + sizeof(TPMI_ALG_HASH), (uint8_t *)&digest.digest, sizeInBytes);
2475 /* copy the hash algorithm */
2476 nameAlgNbo = htons(nvPublic->nameAlg);
2477 memcpy(name->t.name, (uint8_t *)&nameAlgNbo, sizeof(TPMI_ALG_HASH));
2478 /* set the size */
2479 name->t.size = sizeInBytes + sizeof(TPMI_ALG_HASH);
2480 }
2481 free(buffer); /* @1 */
2482 return rc;
2483 }
2484
2485 #endif
2486
2487 #ifndef TPM_TSS_NOCRYPTO
2488
TSS_HmacSession_SetNonceCaller(struct TSS_HMAC_CONTEXT * session,TPMS_AUTH_COMMAND * authC)2489 static TPM_RC TSS_HmacSession_SetNonceCaller(struct TSS_HMAC_CONTEXT *session,
2490 TPMS_AUTH_COMMAND *authC)
2491 {
2492 TPM_RC rc = 0;
2493
2494 /* generate a new nonceCaller */
2495 if (rc == 0) {
2496 session->nonceCaller.b.size = session->sizeInBytes;
2497 rc = TSS_RandBytes(session->nonceCaller.t.buffer, session->sizeInBytes);
2498 }
2499 /* nonceCaller for the command */
2500 if (rc == 0) {
2501 rc = TSS_TPM2B_Copy(&authC->nonce.b, &session->nonceCaller.b, sizeof(TPMU_HA));
2502 }
2503 return rc;
2504 }
2505
2506 #endif /* TPM_TSS_NOCRYPTO */
2507
2508 #ifndef TPM_TSS_NOCRYPTO
2509
2510 /* TSS_HmacSession_SetHmacKey() calculates the session HMAC key.
2511
2512 handleNumber is index into the session area. The first sessions, the authorization sessions,
2513 have a corresponding handle in the command handle.
2514 */
2515
TSS_HmacSession_SetHmacKey(TSS_CONTEXT * tssContext,struct TSS_HMAC_CONTEXT * session,size_t handleNumber,const char * password)2516 static TPM_RC TSS_HmacSession_SetHmacKey(TSS_CONTEXT *tssContext,
2517 struct TSS_HMAC_CONTEXT *session,
2518 size_t handleNumber, /* index into the handle area */
2519 const char *password)
2520 {
2521 TPM_RC rc = 0;
2522 TPM_HANDLE commandHandle; /* from handle area, for bound session */
2523 TPM2B_NAME name;
2524 TPM2B_AUTH authValue;
2525 int bindMatch = FALSE;
2526 int done = FALSE; /* done with authorization sessions */
2527
2528 /*
2529 authHMAC = HMAC sessionAlg ((sessionKey || authValue),
2530 (pHash || nonceNewer || nonceOlder
2531 { || nonceTPMdecrypt } { || nonceTPMencrypt }
2532 || sessionAttributes))
2533 */
2534 /* HMAC key is sessionKey || authValue */
2535 /* copy the session key to HMAC key */
2536 if (rc == 0) {
2537 if (tssVverbose) TSS_PrintAll("TSS_HmacSession_SetHmacKey: sessionKey",
2538 session->sessionKey.b.buffer, session->sessionKey.b.size);
2539 rc = TSS_TPM2B_Copy(&session->hmacKey.b,
2540 &session->sessionKey.b, sizeof(TPMU_HA) + sizeof(TPMT_HA));
2541 }
2542 /* copy the session key to sessionValue */
2543 if (rc == 0) {
2544 rc = TSS_TPM2B_Copy(&session->sessionValue.b,
2545 &session->sessionKey.b, sizeof(TPMU_HA) + sizeof(TPMT_HA));
2546 }
2547 if (rc == 0) {
2548 if (tssVverbose)
2549 TSS_PrintAll("TSS_HmacSession_SetHmacKey: preliminary sessionValue",
2550 session->sessionValue.b.buffer, session->sessionValue.b.size);
2551 }
2552 /* This value is an EmptyAuth if the HMAC is being computed to authorize an action on the
2553 object to which the session is bound.
2554 */
2555 /* The first sessions are authorization sessions. They can have a bind entity. All others can
2556 be encrypt or decrypt sessions, but the authValue is not included in the session key.
2557 */
2558 if (rc == 0) {
2559 AUTH_ROLE authRole = TSS_GetAuthRole(tssContext->tssAuthContext, handleNumber);
2560 if (authRole == AUTH_NONE) {
2561 if (tssVverbose) printf("TSS_HmacSession_SetHmacKey: Done, not auth session\n");
2562 done = TRUE; /* not an authorization session, could be audit or
2563 encrypt/decrypt */
2564 }
2565 }
2566 /* If not an authorization session, there is no authValue to append to the HMAC key or encrypt
2567 sessionValue, regardless of the binding. Below is for auth sessions. */
2568 if (!done) {
2569 /* First, if there was a bind handle, check if the name matches. Else bindMatch remains
2570 FALSE. */
2571 if (session->bind != TPM_RH_NULL) {
2572 /* get the handle for this session */
2573 if (tssVverbose)
2574 printf("TSS_HmacSession_SetHmacKey: Processing bind handle %08x\n", session->bind);
2575 if (rc == 0) {
2576 rc = TSS_GetCommandHandle(tssContext->tssAuthContext,
2577 &commandHandle,
2578 handleNumber);
2579 }
2580 /* get the Name corresponding to the handle */
2581 if (rc == 0) {
2582 if (tssVverbose)
2583 printf("TSS_HmacSession_SetHmacKey: commandHandle %08x bindHandle %08x\n",
2584 commandHandle, session->bind);
2585 rc = TSS_Name_GetName(tssContext, &name, commandHandle);
2586 }
2587 /* compare the authorized object name to the bind object name */
2588 if (rc == 0) {
2589 bindMatch = TSS_TPM2B_Compare(&name.b, &session->bindName.b);
2590 if (tssVverbose) printf("TSS_HmacSession_SetHmacKey: bind match %u\n", bindMatch);
2591 }
2592 }
2593 /* Second, append password to session key for HMAC key if required */
2594
2595 /* When performing an HMAC for authorization, the HMAC key is normally the concatenation of
2596 the entity's authValue to the sessions sessionKey (created at
2597 TPM2_StartAuthSession(). However, if the authorization is for the entity to
2598 which the session is bound, the authValue is not included in the HMAC key. When
2599 a policy requires that an HMAC be computed, it is always concatenated.
2600 */
2601 if ((rc == 0) &&
2602 /* append if HMAC session and not bind match */
2603 (((session->sessionType == TPM_SE_HMAC) && !bindMatch) ||
2604 /* append if policy and policy authvalue */
2605 ((session->sessionType == TPM_SE_POLICY) && session->isAuthValueNeeded)) &&
2606 (password != NULL) /* if password is NULL, nothing to append. */
2607
2608 ) {
2609
2610 if (tssVverbose)
2611 printf("TSS_HmacSession_SetHmacKey: Appending authValue to HMAC key\n");
2612 /* convert the password to an authvalue */
2613 if (rc == 0) {
2614 rc = TSS_TPM2B_StringCopy(&authValue.b, password, sizeof(authValue.t.buffer));
2615 }
2616 /* append the authvalue to the session key to create the hmac key */
2617 if (rc == 0) {
2618 rc = TSS_TPM2B_Append(&session->hmacKey.b, &authValue.b,
2619 sizeof(TPMU_HA) + sizeof(TPMT_HA));
2620 }
2621 }
2622 /* Third, append password to session key for sessionValue
2623
2624 If a session is also being used for authorization, sessionValue (see 21.2 and 21.3) is
2625 sessionKey || authValue. The binding of the session is ignored. If the session is not
2626 being used for authorization, sessionValue is sessionKey.
2627 */
2628 /* NOTE This step occurs even if there is a bind match. That is, the password is effectively
2629 appended twice. */
2630 if (rc == 0) {
2631 /* if not bind, sessionValue is sessionKey || authValue (same as HMAC key) */
2632 if (!bindMatch) {
2633 if (tssVverbose)
2634 printf("TSS_HmacSession_SetHmacKey: "
2635 "No bind, appending authValue to sessionValue\n");
2636 /* convert the password to an authvalue */
2637 if (rc == 0) {
2638 rc = TSS_TPM2B_StringCopy(&authValue.b, password, sizeof(authValue.t.buffer));
2639 }
2640 if (rc == 0) {
2641 rc = TSS_TPM2B_Append(&session->sessionValue.b, &authValue.b,
2642 sizeof(TPMU_HA) + sizeof(TPMT_HA));
2643 }
2644 }
2645 /* if bind, sessionValue is sessionKey || bindAuthValue */
2646 else {
2647 if (tssVverbose)
2648 printf("TSS_HmacSession_SetHmacKey: "
2649 "Bind, appending bind authValue to sessionValue\n");
2650 if (rc == 0) {
2651 rc = TSS_TPM2B_Append(&session->sessionValue.b, &session->bindAuthValue.b,
2652 sizeof(TPMU_HA) + sizeof(TPMT_HA));
2653 }
2654 }
2655 if (rc == 0) {
2656 if (tssVverbose)
2657 TSS_PrintAll("TSS_HmacSession_SetHmacKey: bindAuthValue",
2658 session->bindAuthValue.b.buffer, session->bindAuthValue.b.size);
2659 }
2660 }
2661 }
2662 if (rc == 0) {
2663 if (tssVverbose)
2664 TSS_PrintAll("TSS_HmacSession_SetHmacKey: hmacKey",
2665 session->hmacKey.b.buffer, session->hmacKey.b.size);
2666 if (tssVverbose)
2667 TSS_PrintAll("TSS_HmacSession_SetHmacKey: sessionValue",
2668 session->sessionValue.b.buffer, session->sessionValue.b.size);
2669 }
2670 return rc;
2671 }
2672
2673 #endif /* TPM_TSS_NOCRYPTO */
2674
2675 /* TSS_HmacSession_SetHMAC() is used for a command. It sets all the values in one
2676 TPMS_AUTH_COMMAND, ready for marshaling into the command packet.
2677
2678 - gets cpBuffer
2679 - generates cpHash
2680 - generates the HMAC
2681 - copies the result into authCommand
2682
2683 Unused names must have size 0.
2684
2685 The HMAC key is already in the session structure.
2686 */
2687
TSS_HmacSession_SetHMAC(TSS_AUTH_CONTEXT * tssAuthContext,struct TSS_HMAC_CONTEXT * session[],TPMS_AUTH_COMMAND * authCommand[],TPMI_SH_AUTH_SESSION sessionHandle[],unsigned int sessionAttributes[],const char * password[],TPM2B_NAME * name0,TPM2B_NAME * name1,TPM2B_NAME * name2)2688 static TPM_RC TSS_HmacSession_SetHMAC(TSS_AUTH_CONTEXT *tssAuthContext, /* authorization context */
2689 struct TSS_HMAC_CONTEXT *session[],
2690 TPMS_AUTH_COMMAND *authCommand[], /* output: command
2691 authorization */
2692 TPMI_SH_AUTH_SESSION sessionHandle[], /* session handles in
2693 command */
2694 unsigned int sessionAttributes[], /* attributes for this
2695 command */
2696 const char *password[],
2697 TPM2B_NAME *name0, /* up to 3 names */
2698 TPM2B_NAME *name1, /* unused names have length 0 */
2699 TPM2B_NAME *name2)
2700 {
2701 TPM_RC rc = 0;
2702 unsigned int i = 0;
2703 #ifndef TPM_TSS_NOCRYPTO
2704 TPMT_HA cpHash;
2705 TPMT_HA hmac;
2706 TPM2B_NONCE nonceTPMDecrypt;
2707 TPM2B_NONCE nonceTPMEncrypt;
2708 cpHash.hashAlg = TPM_ALG_NULL; /* for cpHash calculation optimization */
2709 #endif /* TPM_TSS_NOCRYPTO */
2710
2711
2712 for (i = 0 ; (rc == 0) && (i < MAX_SESSION_NUM) && (sessionHandle[i] != TPM_RH_NULL) ; i++) {
2713 uint8_t sessionAttr8;
2714 if (tssVverbose) printf("TSS_HmacSession_SetHMAC: Step 6 session %08x\n", sessionHandle[i]);
2715 /* password sessions were serviced in step 2. */
2716 if (sessionHandle[i] == TPM_RS_PW) {
2717 continue;
2718 }
2719 if (tssVverbose) printf("TSS_HmacSession_SetHMAC: sessionType %02x\n",
2720 session[i]->sessionType);
2721 if (tssVverbose) printf("TSS_HmacSession_SetHMAC: isPasswordNeeded %02x\n",
2722 session[i]->isPasswordNeeded);
2723 if (tssVverbose) printf("TSS_HmacSession_SetHMAC: isAuthValueNeeded %02x\n",
2724 session[i]->isAuthValueNeeded);
2725 /* sessionHandle */
2726 authCommand[i]->sessionHandle = session[i]->sessionHandle;
2727 /* attributes come from command */
2728 sessionAttr8 = (uint8_t)sessionAttributes[i];
2729 authCommand[i]->sessionAttributes.val = sessionAttr8;
2730
2731 /* policy session with policy password handled below, no hmac. isPasswordNeeded is never
2732 true for an HMAC session, so don't need to test session type here. */
2733 if (!(session[i]->isPasswordNeeded)) {
2734 /* HMAC session */
2735 if ((session[i]->sessionType == TPM_SE_HMAC) ||
2736 /* policy session with TPM2_PolicyAuthValue */
2737 ((session[i]->sessionType == TPM_SE_POLICY) && (session[i]->isAuthValueNeeded)) ||
2738 /* salted session */
2739 (session[i]->hmacKey.t.size != 0)
2740 ) {
2741 /* needs HMAC */
2742 #ifndef TPM_TSS_NOCRYPTO
2743 if (tssVverbose) printf("TSS_HmacSession_SetHMAC: calculate HMAC\n");
2744 /* calculate cpHash. Performance optimization: If there is more than one session,
2745 and the hash algorithm is the same, use the previously calculated version. */
2746 if ((rc == 0) && (cpHash.hashAlg != session[i]->authHashAlg)) {
2747 uint32_t cpBufferSize;
2748 uint8_t *cpBuffer;
2749 TPM_CC commandCode;
2750 TPM_CC commandCodeNbo;
2751
2752 rc = TSS_GetCpBuffer(tssAuthContext,
2753 &cpBufferSize,
2754 &cpBuffer);
2755 if (tssVverbose) TSS_PrintAll("TSS_HmacSession_SetHMAC: cpBuffer",
2756 cpBuffer, cpBufferSize);
2757 cpHash.hashAlg = session[i]->authHashAlg;
2758
2759 /* cpHash = hash(commandCode [ || authName1 */
2760 /* [ || authName2 */
2761 /* [ || authName3 ]]] */
2762 /* [ || parameters]) */
2763 /* A cpHash can contain just a commandCode only if the lone session is */
2764 /* an audit session. */
2765
2766 commandCode = TSS_GetCommandCode(tssAuthContext);
2767 commandCodeNbo = htonl(commandCode);
2768 rc = TSS_Hash_Generate(&cpHash, /* largest size of a digest */
2769 sizeof(TPM_CC), &commandCodeNbo,
2770 name0->b.size, &name0->b.buffer,
2771 name1->b.size, &name1->b.buffer,
2772 name2->b.size, &name2->b.buffer,
2773 cpBufferSize, cpBuffer,
2774 0, NULL);
2775 }
2776 if (i == 0) {
2777 unsigned int isDecrypt = 0; /* count number of sessions with decrypt
2778 set */
2779 unsigned int decryptSession = 0; /* which one is decrypt */
2780 unsigned int isEncrypt = 0; /* count number of sessions with decrypt
2781 set */
2782 unsigned int encryptSession = 0; /* which one is decrypt */
2783 nonceTPMDecrypt.t.size = 0;
2784 nonceTPMEncrypt.t.size = 0;
2785 /* if a different session is being used for parameter decryption, then the
2786 nonceTPM for that session is included in the HMAC of the first authorization
2787 session */
2788 if (rc == 0) {
2789 rc = TSS_Sessions_GetDecryptSession(&isDecrypt,
2790 &decryptSession,
2791 sessionHandle,
2792 sessionAttributes);
2793 }
2794 if ((rc == 0) && isDecrypt && (decryptSession != 0)) {
2795 rc = TSS_TPM2B_Copy(&nonceTPMDecrypt.b,
2796 &session[decryptSession]->nonceTPM.b, sizeof(TPMU_HA));
2797 }
2798 /* if a different session is being used for parameter encryption, then the
2799 nonceTPM for that session is included in the HMAC of the first authorization
2800 session */
2801 if (rc == 0) {
2802 rc = TSS_Sessions_GetEncryptSession(&isEncrypt,
2803 &encryptSession,
2804 sessionHandle,
2805 sessionAttributes);
2806 }
2807 /* Don't include the same nonce twice */
2808 if ((rc == 0) && isEncrypt && (encryptSession != 0)) {
2809 if (!isDecrypt || (encryptSession != decryptSession)) {
2810 rc = TSS_TPM2B_Copy(&nonceTPMEncrypt.b,
2811 &session[encryptSession]->nonceTPM.b,
2812 sizeof(TPMU_HA));
2813 }
2814 }
2815 }
2816 /* for other than the first session, those nonces are not used */
2817 else {
2818 nonceTPMDecrypt.t.size = 0;
2819 nonceTPMEncrypt.t.size = 0;
2820 }
2821 /* */
2822 if (rc == 0) {
2823 hmac.hashAlg = session[i]->authHashAlg;
2824 rc = TSS_HMAC_Generate(&hmac, /* output hmac */
2825 &session[i]->hmacKey, /* input key */
2826 session[i]->sizeInBytes, (uint8_t *)&cpHash.digest,
2827 /* new is nonceCaller */
2828 session[i]->nonceCaller.b.size,
2829 &session[i]->nonceCaller.b.buffer,
2830 /* old is previous nonceTPM */
2831 session[i]->nonceTPM.b.size,
2832 &session[i]->nonceTPM.b.buffer,
2833 /* nonceTPMDecrypt */
2834 nonceTPMDecrypt.b.size, nonceTPMDecrypt.b.buffer,
2835 /* nonceTPMEncrypt */
2836 nonceTPMEncrypt.b.size, nonceTPMEncrypt.b.buffer,
2837 /* 1 byte, no endian conversion */
2838 sizeof(uint8_t), &sessionAttr8,
2839 0, NULL);
2840 if (tssVverbose) {
2841 TSS_PrintAll("TSS_HmacSession_SetHMAC: HMAC key",
2842 session[i]->hmacKey.t.buffer, session[i]->hmacKey.t.size);
2843 TSS_PrintAll("TSS_HmacSession_SetHMAC: cpHash",
2844 (uint8_t *)&cpHash.digest, session[i]->sizeInBytes);
2845 TSS_PrintAll("TSS_HmacSession_Set: nonceCaller",
2846 session[i]->nonceCaller.b.buffer,
2847 session[i]->nonceCaller.b.size);
2848 TSS_PrintAll("TSS_HmacSession_SetHMAC: nonceTPM",
2849 session[i]->nonceTPM.b.buffer, session[i]->nonceTPM.b.size);
2850 TSS_PrintAll("TSS_HmacSession_SetHMAC: nonceTPMDecrypt",
2851 nonceTPMDecrypt.b.buffer, nonceTPMDecrypt.b.size);
2852 TSS_PrintAll("TSS_HmacSession_SetHMAC: nonceTPMEncrypt",
2853 nonceTPMEncrypt.b.buffer, nonceTPMEncrypt.b.size);
2854 TSS_PrintAll("TSS_HmacSession_SetHMAC: sessionAttributes",
2855 &sessionAttr8, sizeof(uint8_t));
2856 TSS_PrintAll("TSS_HmacSession_SetHMAC: HMAC",
2857 (uint8_t *)&hmac.digest, session[i]->sizeInBytes);
2858 }
2859 }
2860 /* copy HMAC into authCommand TPM2B_AUTH hmac */
2861 if (rc == 0) {
2862 rc = TSS_TPM2B_Create(&authCommand[i]->hmac.b,
2863 (uint8_t *)&hmac.digest,
2864 session[i]->sizeInBytes,
2865 sizeof(authCommand[i]->hmac.t.buffer));
2866 }
2867 #else
2868 tssAuthContext = tssAuthContext;
2869 name0 = name0;
2870 name1 = name1;
2871 name2 = name2;
2872 if (tssVerbose)
2873 printf("TSS_HmacSession_SetHMAC: Error, with no crypto not implemented\n");
2874 rc = TSS_RC_NOT_IMPLEMENTED;
2875 #endif /* TPM_TSS_NOCRYPTO */
2876 }
2877 /* not HMAC, not policy requiring password or hmac */
2878 else {
2879 authCommand[i]->hmac.b.size = 0;
2880 }
2881 }
2882 /* For a policy session that contains TPM2_PolicyPassword(), the password takes precedence
2883 and must be present in hmac. */
2884 else { /* isPasswordNeeded true */
2885 if (tssVverbose) printf("TSS_HmacSession_SetHMAC: use password\n");
2886 /* nonce has already been set */
2887 rc = TSS_TPM2B_StringCopy(&authCommand[i]->hmac.b,
2888 password[i], sizeof(authCommand[i]->hmac.t.buffer));
2889 }
2890 }
2891 return rc;
2892 }
2893
2894
2895 #ifndef TPM_TSS_NOCRYPTO
2896
2897 /* TSS_HmacSession_Verify() is used for a response. It uses the values in TPMS_AUTH_RESPONSE to
2898 validate the response HMAC
2899 */
2900
TSS_HmacSession_Verify(TSS_AUTH_CONTEXT * tssAuthContext,struct TSS_HMAC_CONTEXT * session,TPMS_AUTH_RESPONSE * authResponse)2901 static TPM_RC TSS_HmacSession_Verify(TSS_AUTH_CONTEXT *tssAuthContext, /* authorization context */
2902 struct TSS_HMAC_CONTEXT *session, /* TSS session context */
2903 TPMS_AUTH_RESPONSE *authResponse) /* input: response authorization */
2904 {
2905 TPM_RC rc = 0;
2906 uint32_t rpBufferSize;
2907 uint8_t *rpBuffer;
2908 TPMT_HA rpHash;
2909 TPMT_HA actualHmac;
2910
2911 /* get the rpBuffer */
2912 if (rc == 0) {
2913 rc = TSS_GetRpBuffer(tssAuthContext, &rpBufferSize, &rpBuffer);
2914 if (tssVverbose) TSS_PrintAll("TSS_HmacSession_Verify: rpBuffer",
2915 rpBuffer, rpBufferSize);
2916 }
2917 /* calculate rpHash */
2918 if (rc == 0) {
2919 TPM_CC commandCode;
2920 TPM_CC commandCodeNbo;
2921 rpHash.hashAlg = session->authHashAlg;
2922
2923 commandCode = TSS_GetCommandCode(tssAuthContext);
2924 commandCodeNbo = htonl(commandCode);
2925
2926 /* rpHash = HsessionAlg (responseCode || commandCode {|| parameters }) */
2927 rc = TSS_Hash_Generate(&rpHash, /* largest size of a digest */
2928 sizeof(TPM_RC), &rc, /* RC is always 0, no need to endian
2929 convert */
2930 sizeof(TPM_CC), &commandCodeNbo,
2931 rpBufferSize, rpBuffer,
2932 0, NULL);
2933 }
2934 /* construct the actual HMAC as TPMT_HA */
2935 if (rc == 0) {
2936 actualHmac.hashAlg = session->authHashAlg;
2937 if (authResponse->hmac.t.size != session->sizeInBytes) {
2938 if (tssVerbose)
2939 printf("TSS_HmacSession_Verify: HMAC size %u inconsistent with algorithm %u\n",
2940 authResponse->hmac.t.size, session->sizeInBytes);
2941 rc = TSS_RC_HMAC_SIZE;
2942 }
2943 }
2944 if (rc == 0) {
2945 memcpy((uint8_t *)&actualHmac.digest, &authResponse->hmac.t.buffer,
2946 authResponse->hmac.t.size);
2947 }
2948 /* verify the HMAC */
2949 if (rc == 0) {
2950 if (tssVverbose) {
2951 TSS_PrintAll("TSS_HmacSession_Verify: HMAC key",
2952 session->hmacKey.t.buffer, session->hmacKey.t.size);
2953 TSS_PrintAll("TSS_HmacSession_Verify: rpHash",
2954 (uint8_t *)&rpHash.digest, session->sizeInBytes);
2955 TSS_PrintAll("TSS_HmacSession_Verify: nonceTPM",
2956 session->nonceTPM.b.buffer, session->nonceTPM.b.size);
2957 TSS_PrintAll("TSS_HmacSession_Verify: nonceCaller",
2958 session->nonceCaller.b.buffer, session->nonceCaller.b.size);
2959 TSS_PrintAll("TSS_HmacSession_Verify: sessionAttributes",
2960 &authResponse->sessionAttributes.val, sizeof(uint8_t));
2961 TSS_PrintAll("TSS_HmacSession_Verify: response HMAC",
2962 (uint8_t *)&authResponse->hmac.t.buffer, session->sizeInBytes);
2963 }
2964 rc = TSS_HMAC_Verify(&actualHmac, /* input response hmac */
2965 &session->hmacKey, /* input HMAC key */
2966 session->sizeInBytes,
2967 /* rpHash */
2968 session->sizeInBytes, (uint8_t *)&rpHash.digest,
2969 /* new is nonceTPM */
2970 session->nonceTPM.b.size, &session->nonceTPM.b.buffer,
2971 /* old is nonceCaller */
2972 session->nonceCaller.b.size, &session->nonceCaller.b.buffer,
2973 /* 1 byte, no endian conversion */
2974 sizeof(uint8_t), &authResponse->sessionAttributes.val,
2975 0, NULL);
2976 }
2977 return rc;
2978 }
2979
2980 #endif /* TPM_TSS_NOCRYPTO */
2981
2982 /* TSS_HmacSession_Continue() handles the response continueSession flag. It either saves the
2983 updated session or deletes the session state. */
2984
TSS_HmacSession_Continue(TSS_CONTEXT * tssContext,struct TSS_HMAC_CONTEXT * session,TPMS_AUTH_RESPONSE * authR)2985 static TPM_RC TSS_HmacSession_Continue(TSS_CONTEXT *tssContext,
2986 struct TSS_HMAC_CONTEXT *session,
2987 TPMS_AUTH_RESPONSE *authR)
2988 {
2989 TPM_RC rc = 0;
2990
2991 if (rc == 0) {
2992 /* if continue set */
2993 if (authR->sessionAttributes.val & TPMA_SESSION_CONTINUESESSION) {
2994 /* clear the policy flags in preparation for the next use */
2995 session->isPasswordNeeded = FALSE;
2996 session->isAuthValueNeeded = FALSE;
2997 /* save the session */
2998 rc = TSS_HmacSession_SaveSession(tssContext, session);
2999 }
3000 else { /* continue clear */
3001 /* delete the session state */
3002 rc = TSS_DeleteHandle(tssContext, session->sessionHandle);
3003 }
3004 }
3005 return rc;
3006 }
3007
3008 /* TSS_Sessions_GetDecryptSession() searches for a command decrypt session. If found, returns
3009 isDecrypt TRUE, and the session number in decryptSession.
3010
3011 */
3012
TSS_Sessions_GetDecryptSession(unsigned int * isDecrypt,unsigned int * decryptSession,TPMI_SH_AUTH_SESSION sessionHandle[],unsigned int sessionAttributes[])3013 static TPM_RC TSS_Sessions_GetDecryptSession(unsigned int *isDecrypt,
3014 unsigned int *decryptSession,
3015 TPMI_SH_AUTH_SESSION sessionHandle[],
3016 unsigned int sessionAttributes[])
3017 {
3018 TPM_RC rc = 0;
3019 unsigned int i = 0;
3020
3021 /* count the number of command decrypt sessions */
3022 *isDecrypt = 0; /* number of sessions with decrypt set */
3023 for (i = 0 ; (rc == 0) && (i < MAX_SESSION_NUM) &&
3024 (sessionHandle[i] != TPM_RH_NULL) &&
3025 (sessionHandle[i] != TPM_RS_PW) ;
3026 i++) {
3027 if (sessionAttributes[i] & TPMA_SESSION_DECRYPT) {
3028 (*isDecrypt)++; /* count number of decrypt sessions */
3029 *decryptSession = i; /* record which one it was */
3030 }
3031 }
3032 /* how many decrypt sessions were found */
3033 if (rc == 0) {
3034 if (tssVverbose) printf("TSS_Sessions_GetDecryptSession: Found %u decrypt sessions at %u\n",
3035 *isDecrypt, *decryptSession);
3036 if (*isDecrypt > 1) {
3037 if (tssVerbose)
3038 printf("TSS_Sessions_GetDecryptSession: Error, found %u decrypt sessions\n",
3039 *isDecrypt);
3040 rc = TSS_RC_DECRYPT_SESSIONS;
3041 }
3042 }
3043 return rc;
3044 }
3045
3046 /* TSS_Sessions_GetEncryptSession() searches for a response encrypt session. If found, returns
3047 isEncrypt TRUE, and the session number in encryptSession.
3048
3049 */
3050
TSS_Sessions_GetEncryptSession(unsigned int * isEncrypt,unsigned int * encryptSession,TPMI_SH_AUTH_SESSION sessionHandle[],unsigned int sessionAttributes[])3051 static TPM_RC TSS_Sessions_GetEncryptSession(unsigned int *isEncrypt,
3052 unsigned int *encryptSession,
3053 TPMI_SH_AUTH_SESSION sessionHandle[],
3054 unsigned int sessionAttributes[])
3055 {
3056 TPM_RC rc = 0;
3057 unsigned int i = 0;
3058
3059 /* count the number of command encrypt sessions */
3060 *isEncrypt = 0; /* number of sessions with encrypt set */
3061 for (i = 0 ; (rc == 0) && (i < MAX_SESSION_NUM) &&
3062 (sessionHandle[i] != TPM_RH_NULL) &&
3063 (sessionHandle[i] != TPM_RS_PW) ;
3064 i++) {
3065 if (sessionAttributes[i] & TPMA_SESSION_ENCRYPT) {
3066 (*isEncrypt)++; /* count number of encrypt sessions */
3067 *encryptSession = i; /* record which one it was */
3068 }
3069 }
3070 /* how many encrypt sessions were found */
3071 if (rc == 0) {
3072 if (tssVverbose) printf("TSS_Sessions_GetEncryptSession: Found %u encrypt sessions at %u\n",
3073 *isEncrypt, *encryptSession);
3074 if (*isEncrypt > 1) {
3075 if (tssVerbose)
3076 printf("TSS_Sessions_GetEncryptSession: Error, found %u encrypt sessions\n",
3077 *isEncrypt);
3078 rc = TSS_RC_ENCRYPT_SESSIONS;
3079 }
3080 }
3081 return rc;
3082 }
3083
3084 /* TSS_Command_Decrypt() determines whether any sessions are command decrypt sessions. If so, it
3085 encrypts the first command parameter.
3086
3087 It does common error checking, then calls algorithm specific functions.
3088
3089 */
3090
TSS_Command_Decrypt(TSS_AUTH_CONTEXT * tssAuthContext,struct TSS_HMAC_CONTEXT * session[],TPMI_SH_AUTH_SESSION sessionHandle[],unsigned int sessionAttributes[])3091 static TPM_RC TSS_Command_Decrypt(TSS_AUTH_CONTEXT *tssAuthContext,
3092 struct TSS_HMAC_CONTEXT *session[],
3093 TPMI_SH_AUTH_SESSION sessionHandle[],
3094 unsigned int sessionAttributes[])
3095 {
3096 TPM_RC rc = 0;
3097 unsigned int isDecrypt = 0; /* count number of sessions with decrypt set */
3098 unsigned int decryptSession = 0; /* which session is decrypt */
3099
3100 /* determine if there is a decrypt session */
3101 if (rc == 0) {
3102 rc = TSS_Sessions_GetDecryptSession(&isDecrypt,
3103 &decryptSession,
3104 sessionHandle,
3105 sessionAttributes);
3106 }
3107 #ifndef TPM_TSS_NOCRYPTO
3108 {
3109 COMMAND_INDEX tpmCommandIndex; /* index into TPM table */
3110 TPM_CC commandCode;
3111 int decryptSize; /* size of TPM2B size, 2 if there is a TPM2B, 0 if
3112 not */
3113 uint32_t paramSize; /* size of the parameter to encrypt */
3114 uint8_t *decryptParamBuffer;
3115 /* can the command parameter be encrypted */
3116 if ((rc == 0) && isDecrypt) {
3117 /* get the commandCode, stored in TSS during marshal */
3118 commandCode = TSS_GetCommandCode(tssAuthContext);
3119 /* get the index into the TPM command attributes table */
3120 tpmCommandIndex = CommandCodeToCommandIndex(commandCode);
3121 /* can this be a decrypt command (this is size of TPM2B size, not size of parameter) */
3122 decryptSize = getDecryptSize(tpmCommandIndex);
3123 if (decryptSize != 2) { /* only handle TPM2B */
3124 printf("TSS_Command_Decrypt: Error, command cannot be encrypted\n");
3125 rc = TSS_RC_NO_DECRYPT_PARAMETER;
3126 }
3127 }
3128 /* get the TPM2B parameter to encrypt */
3129 if ((rc == 0) && isDecrypt) {
3130 rc = TSS_GetCommandDecryptParam(tssAuthContext, ¶mSize, &decryptParamBuffer);
3131 }
3132 /* if the size of the parameter to encrypt is zero, nothing to encrypt */
3133 if ((rc == 0) && isDecrypt) {
3134 if (paramSize == 0) {
3135 isDecrypt = FALSE; /* none, done with this function */
3136 }
3137 }
3138 /* error checking complete, do the encryption */
3139 if ((rc == 0) && isDecrypt) {
3140 switch (session[decryptSession]->symmetric.algorithm) {
3141 case TPM_ALG_XOR:
3142 rc = TSS_Command_DecryptXor(tssAuthContext, session[decryptSession]);
3143 break;
3144 case TPM_ALG_AES:
3145 rc = TSS_Command_DecryptAes(tssAuthContext, session[decryptSession]);
3146 break;
3147 default:
3148 if (tssVerbose) printf("TSS_Command_Decrypt: Error, algorithm %04x not implemented\n",
3149 session[decryptSession]->symmetric.algorithm);
3150 rc = TSS_RC_BAD_DECRYPT_ALGORITHM;
3151 break;
3152 }
3153 }
3154 }
3155 #else
3156 tssAuthContext = tssAuthContext;
3157 session = session;
3158 if ((rc == 0) && isDecrypt) {
3159 if (tssVerbose)
3160 printf("TSS_Command_Decrypt: Error, with no crypto not implemented\n");
3161 rc = TSS_RC_NOT_IMPLEMENTED;
3162 }
3163 #endif
3164 return rc;
3165 }
3166
3167 #ifndef TPM_TSS_NOCRYPTO
3168
3169 /* NOTE: if AES also works, do in place encryption */
3170
TSS_Command_DecryptXor(TSS_AUTH_CONTEXT * tssAuthContext,struct TSS_HMAC_CONTEXT * session)3171 static TPM_RC TSS_Command_DecryptXor(TSS_AUTH_CONTEXT *tssAuthContext,
3172 struct TSS_HMAC_CONTEXT *session)
3173 {
3174 TPM_RC rc = 0;
3175 unsigned int i;
3176 uint32_t paramSize;
3177 uint8_t *decryptParamBuffer;
3178 uint8_t *mask = NULL;
3179 uint8_t *encryptParamBuffer = NULL;
3180
3181 /* get the TPM2B parameter to encrypt */
3182 if (rc == 0) {
3183 rc = TSS_GetCommandDecryptParam(tssAuthContext, ¶mSize, &decryptParamBuffer);
3184 }
3185 if (rc == 0) {
3186 if (tssVverbose) TSS_PrintAll("TSS_Command_DecryptXor: decrypt in",
3187 decryptParamBuffer, paramSize);
3188 }
3189 if (rc == 0) {
3190 rc = TSS_Malloc(&mask, paramSize);
3191 }
3192 if (rc == 0) {
3193 rc = TSS_Malloc(&encryptParamBuffer, paramSize);
3194 }
3195 /* generate the XOR pad */
3196 /* 21.2 XOR Parameter Obfuscation
3197
3198 XOR(parameter, hashAlg, sessionValue, nonceNewer, nonceOlder)
3199
3200 parameter a variable sized buffer containing the parameter to be obfuscated
3201 hashAlg the hash algorithm associated with the session
3202 sessionValue the session-specific HMAC key
3203 nonceNewer for commands, this will be nonceCaller and for responses it will be nonceTPM
3204 nonceOlder for commands, this will be nonceTPM and for responses it will be nonceCaller
3205
3206 11.4.6.3 XOR Obfuscation
3207
3208 XOR(data, hashAlg, key, contextU, contextV)
3209
3210 mask = KDFa (hashAlg, key, "XOR", contextU, contextV, data.size * 8)
3211 */
3212 /* KDFa for the XOR mask */
3213 if (rc == 0) {
3214 if (tssVverbose) printf("TSS_Command_DecryptXor: hashAlg %04x\n", session->authHashAlg);
3215 if (tssVverbose) printf("TSS_Command_DecryptXor: sizeInBits %04x\n", paramSize * 8);
3216 if (tssVverbose)
3217 TSS_PrintAll("TSS_Command_DecryptXor: sessionKey",
3218 session->sessionKey.b.buffer, session->sessionKey.b.size);
3219 if (tssVverbose)
3220 TSS_PrintAll("TSS_Command_DecryptXor: sessionValue",
3221 session->sessionValue.b.buffer, session->sessionValue.b.size);
3222 rc = TSS_KDFA(mask,
3223 session->authHashAlg,
3224 &session->sessionValue.b,
3225 "XOR",
3226 &session->nonceCaller.b,
3227 &session->nonceTPM.b,
3228 paramSize * 8);
3229 }
3230 if (rc == 0) {
3231 if (tssVverbose) TSS_PrintAll("TSS_Command_DecryptXor: mask",
3232 mask, paramSize);
3233 }
3234 /* XOR */
3235 for (i = 0 ; (rc == 0) && (i < paramSize ) ; i++) {
3236 encryptParamBuffer[i] = decryptParamBuffer[i] ^ mask[i];
3237 }
3238 if (rc == 0) {
3239 rc = TSS_SetCommandDecryptParam(tssAuthContext, paramSize, encryptParamBuffer);
3240 }
3241 if (rc == 0) {
3242 if (tssVverbose) TSS_PrintAll("TSS_Command_DecryptXor: encrypt out",
3243 encryptParamBuffer, paramSize);
3244 }
3245 free(mask);
3246 free(encryptParamBuffer);
3247 return rc;
3248 }
3249
3250 #endif /* TPM_TSS_NOCRYPTO */
3251
3252 #ifndef TPM_TSS_NOCRYPTO
3253
3254 /* NOTE: if AES also works, do in place encryption */
3255
TSS_Command_DecryptAes(TSS_AUTH_CONTEXT * tssAuthContext,struct TSS_HMAC_CONTEXT * session)3256 static TPM_RC TSS_Command_DecryptAes(TSS_AUTH_CONTEXT *tssAuthContext,
3257 struct TSS_HMAC_CONTEXT *session)
3258 {
3259 TPM_RC rc = 0;
3260 uint32_t paramSize;
3261 uint8_t *decryptParamBuffer;
3262 uint8_t *encryptParamBuffer = NULL;
3263 TPM2B_IV iv;
3264 uint32_t kdfaBits;
3265 uint16_t keySizeinBytes;
3266 uint8_t symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE]; /* AES key + IV */
3267
3268 /* get the TPM2B parameter to encrypt */
3269 if (rc == 0) {
3270 rc = TSS_GetCommandDecryptParam(tssAuthContext, ¶mSize, &decryptParamBuffer);
3271 }
3272 if (rc == 0) {
3273 if (tssVverbose) TSS_PrintAll("TSS_Command_DecryptAes: decrypt in",
3274 decryptParamBuffer, paramSize);
3275 }
3276 if (rc == 0) {
3277 rc = TSS_Malloc(&encryptParamBuffer, paramSize); /* free @1 */
3278 }
3279 /* generate the encryption key and IV */
3280 /* 21.3 CFB Mode Parameter Encryption
3281
3282 KDFa (hashAlg, sessionValue, "CFB", nonceNewer, nonceOlder, bits) (34)
3283
3284 hashAlg the hash algorithm associated with the session
3285 sessionValue the session-specific HMAC key
3286 "CFB" label to differentiate use of KDFa() (see 4.2)
3287 nonceNewer nonceCaller for a command and nonceTPM for a response
3288 nonceOlder nonceTPM for a command and nonceCaller for a response
3289 bits the number of bits required for the symmetric key plus an IV
3290 */
3291 if (rc == 0) {
3292 iv.t.size = TSS_Sym_GetBlockSize(session->symmetric.algorithm,
3293 session->symmetric.keyBits.aes);
3294 /* generate random values for both the AES key and the IV */
3295 kdfaBits = session->symmetric.keyBits.aes + (iv.t.size * 8);
3296
3297 if (tssVverbose) printf("TSS_Command_DecryptAes: hashAlg %04x\n",
3298 session->authHashAlg);
3299 if (tssVverbose) printf("TSS_Command_DecryptAes: AES key bits %u\n",
3300 session->symmetric.keyBits.aes);
3301 if (tssVverbose) printf("TSS_Command_DecryptAes: kdfaBits %04x\n",
3302 kdfaBits);
3303 if (tssVverbose) TSS_PrintAll("TSS_Command_DecryptAes: session key",
3304 session->sessionKey.b.buffer, session->sessionKey.b.size);
3305
3306 rc = TSS_KDFA(&symParmString[0],
3307 session->authHashAlg,
3308 &session->sessionValue.b,
3309 "CFB",
3310 &session->nonceCaller.b,
3311 &session->nonceTPM.b,
3312 kdfaBits);
3313 }
3314 /* copy the latter part of the kdf output to the IV */
3315 if (rc == 0) {
3316 keySizeinBytes = session->symmetric.keyBits.aes / 8;
3317 memcpy(iv.t.buffer, &symParmString[keySizeinBytes], iv.t.size);
3318 if (tssVverbose) TSS_PrintAll("TSS_Command_DecryptAes: IV",
3319 iv.t.buffer, iv.t.size);
3320 }
3321 /* AES CFB encrypt the command */
3322 if (rc == 0) {
3323 TPM_RC crc;
3324 crc = TSS_AES_EncryptCFB(encryptParamBuffer, /* output */
3325 session->symmetric.keyBits.aes, /* 128 */
3326 symParmString, /* key */
3327 iv.t.buffer, /* IV */
3328 paramSize, /* length */
3329 (uint8_t *)decryptParamBuffer); /* input */
3330 if (crc != 0) {
3331 if (tssVerbose) printf("TSS_Command_DecryptAes: AES encrypt failed\n");
3332 rc = TSS_RC_AES_ENCRYPT_FAILURE;
3333 }
3334 }
3335 if (rc == 0) {
3336 if (tssVverbose) TSS_PrintAll("TSS_Command_DecryptAes: encrypt out",
3337 encryptParamBuffer, paramSize);
3338 }
3339 if (rc == 0) {
3340 rc = TSS_SetCommandDecryptParam(tssAuthContext, paramSize, encryptParamBuffer);
3341 }
3342 free(encryptParamBuffer); /* @1 */
3343 return rc;
3344 }
3345
3346 #endif /* TPM_TSS_NOCRYPTO */
3347
TSS_Response_Encrypt(TSS_AUTH_CONTEXT * tssAuthContext,struct TSS_HMAC_CONTEXT * session[],TPMI_SH_AUTH_SESSION sessionHandle[],unsigned int sessionAttributes[])3348 static TPM_RC TSS_Response_Encrypt(TSS_AUTH_CONTEXT *tssAuthContext,
3349 struct TSS_HMAC_CONTEXT *session[],
3350 TPMI_SH_AUTH_SESSION sessionHandle[],
3351 unsigned int sessionAttributes[])
3352 {
3353 TPM_RC rc = 0;
3354 unsigned int isEncrypt = 0; /* count number of sessions with decrypt set */
3355 unsigned int encryptSession = 0; /* which one is decrypt */
3356
3357 /* determine if there is an encrypt session */
3358 if (rc == 0) {
3359 rc = TSS_Sessions_GetEncryptSession(&isEncrypt,
3360 &encryptSession,
3361 sessionHandle,
3362 sessionAttributes);
3363 }
3364 #ifndef TPM_TSS_NOCRYPTO
3365 {
3366 COMMAND_INDEX tpmCommandIndex; /* index into TPM table */
3367 TPM_CC commandCode;
3368 int encryptSize; /* size of TPM2B size, 2 if there is a TPM2B, 0 if
3369 not */
3370 uint32_t paramSize; /* size of the parameter to decrypt */
3371 uint8_t *encryptParamBuffer;
3372 /* can the response parameter be decrypted */
3373 if ((rc == 0) && isEncrypt) {
3374 /* get the commandCode, stored in TSS during marshal */
3375 commandCode = TSS_GetCommandCode(tssAuthContext);
3376 /* get the index into the TPM command attributes table */
3377 tpmCommandIndex = CommandCodeToCommandIndex(commandCode);
3378 /* can this be a decrypt command */
3379 encryptSize = getEncryptSize(tpmCommandIndex);
3380 if (encryptSize == 0) {
3381 if (tssVerbose) printf("TSS_Response_Encrypt: "
3382 "Error, response cannot be encrypted\n");
3383 rc = TSS_RC_NO_ENCRYPT_PARAMETER;
3384 }
3385 }
3386 /* get the TPM2B parameter to decrypt */
3387 if ((rc == 0) && isEncrypt) {
3388 rc = TSS_GetResponseEncryptParam(tssAuthContext, ¶mSize, &encryptParamBuffer);
3389 }
3390 /* if the size of the parameter to decrypt is zero, nothing to decrypt */
3391 if ((rc == 0) && isEncrypt) {
3392 if (paramSize == 0) {
3393 isEncrypt = FALSE; /* none, done with this function */
3394 }
3395 }
3396 /* error checking complete, do the decryption */
3397 if ((rc == 0) && isEncrypt) {
3398 switch (session[encryptSession]->symmetric.algorithm) {
3399 case TPM_ALG_XOR:
3400 rc = TSS_Response_EncryptXor(tssAuthContext, session[encryptSession]);
3401 break;
3402 case TPM_ALG_AES:
3403 rc = TSS_Response_EncryptAes(tssAuthContext, session[encryptSession]);
3404 break;
3405 default:
3406 if (tssVerbose) printf("TSS_Response_Encrypt: "
3407 "Error, algorithm %04x not implemented\n",
3408 session[encryptSession]->symmetric.algorithm);
3409 rc = TSS_RC_BAD_ENCRYPT_ALGORITHM;
3410 break;
3411 }
3412 }
3413 }
3414 #else
3415 tssAuthContext = tssAuthContext;
3416 session = session;
3417 if ((rc == 0) && isEncrypt) {
3418 if (tssVerbose)
3419 printf("TSS_Response_Encrypt: Error, with no crypto not implemented\n");
3420 rc = TSS_RC_NOT_IMPLEMENTED;
3421 }
3422 #endif
3423 return rc;
3424 }
3425
3426 #ifndef TPM_TSS_NOCRYPTO
3427
3428 /* NOTE: if CFB also works, do in place decryption */
3429
TSS_Response_EncryptXor(TSS_AUTH_CONTEXT * tssAuthContext,struct TSS_HMAC_CONTEXT * session)3430 static TPM_RC TSS_Response_EncryptXor(TSS_AUTH_CONTEXT *tssAuthContext,
3431 struct TSS_HMAC_CONTEXT *session)
3432 {
3433 TPM_RC rc = 0;
3434 unsigned int i;
3435 uint32_t paramSize;
3436 uint8_t *encryptParamBuffer;
3437 uint8_t *mask = NULL;
3438 uint8_t *decryptParamBuffer = NULL;
3439
3440 /* get the TPM2B parameter to decrypt */
3441 if (rc == 0) {
3442 rc = TSS_GetResponseEncryptParam(tssAuthContext,
3443 ¶mSize, &encryptParamBuffer);
3444 }
3445 if (rc == 0) {
3446 if (tssVverbose) TSS_PrintAll("TSS_Response_EncryptXor: encrypt in",
3447 encryptParamBuffer, paramSize);
3448 }
3449 if (rc == 0) {
3450 rc = TSS_Malloc(&mask, paramSize); /* freed @1 */
3451 }
3452 if (rc == 0) {
3453 rc = TSS_Malloc(&decryptParamBuffer, paramSize); /* freed @2 */
3454 }
3455 /* generate the XOR pad */
3456 /* 21.2 XOR Parameter Obfuscation
3457
3458 XOR(parameter, hashAlg, sessionValue, nonceNewer, nonceOlder)
3459
3460 parameter a variable sized buffer containing the parameter to be obfuscated
3461 hashAlg the hash algorithm associated with the session
3462 sessionValue the session-specific HMAC key
3463 nonceNewer for commands, this will be nonceCaller and for responses it will be nonceTPM
3464 nonceOlder for commands, this will be nonceTPM and for responses it will be nonceCaller
3465
3466
3467 11.4.6.3 XOR Obfuscation
3468
3469 XOR(data, hashAlg, key, contextU, contextV)
3470
3471 mask = KDFa (hashAlg, key, "XOR", contextU, contextV, data.size * 8)
3472 */
3473 /* KDFa for the XOR mask */
3474 if (rc == 0) {
3475 if (tssVverbose) printf("TSS_Response_EncryptXor: hashAlg %04x\n", session->authHashAlg);
3476 if (tssVverbose) printf("TSS_Response_EncryptXor: sizeInBits %04x\n", paramSize * 8);
3477 if (tssVverbose) TSS_PrintAll("TSS_Response_EncryptXor: session key",
3478 session->sessionKey.b.buffer, session->sessionKey.b.size);
3479 rc = TSS_KDFA(mask,
3480 session->authHashAlg,
3481 &session->sessionValue.b,
3482 "XOR",
3483 &session->nonceTPM.b,
3484 &session->nonceCaller.b,
3485 paramSize * 8);
3486 }
3487 if (rc == 0) {
3488 if (tssVverbose) TSS_PrintAll("TSS_Response_EncryptXor: mask",
3489 mask, paramSize);
3490 }
3491 /* XOR */
3492 for (i = 0 ; (rc == 0) && (i < paramSize ) ; i++) {
3493 decryptParamBuffer[i] = encryptParamBuffer[i] ^ mask[i];
3494 }
3495 if (rc == 0) {
3496 if (tssVverbose) TSS_PrintAll("TSS_Response_EncryptXor: decrypt out",
3497 decryptParamBuffer, paramSize);
3498 }
3499 if (rc == 0) {
3500 rc = TSS_SetResponseDecryptParam(tssAuthContext,
3501 paramSize, decryptParamBuffer);
3502 }
3503 free(mask); /* @1 */
3504 free(decryptParamBuffer); /* @2 */
3505 return rc;
3506 }
3507
3508 #endif /* TPM_TSS_NOCRYPTO */
3509
3510 #ifndef TPM_TSS_NOCRYPTO
3511
3512 /* NOTE: if CFB also works, do in place decryption */
3513
TSS_Response_EncryptAes(TSS_AUTH_CONTEXT * tssAuthContext,struct TSS_HMAC_CONTEXT * session)3514 static TPM_RC TSS_Response_EncryptAes(TSS_AUTH_CONTEXT *tssAuthContext,
3515 struct TSS_HMAC_CONTEXT *session)
3516 {
3517 TPM_RC rc = 0;
3518 uint32_t paramSize;
3519 uint8_t *encryptParamBuffer;
3520 uint8_t *decryptParamBuffer = NULL;
3521 TPM2B_IV iv;
3522 uint32_t kdfaBits;
3523 uint16_t keySizeinBytes;
3524 uint8_t symParmString[MAX_SYM_KEY_BYTES + MAX_SYM_BLOCK_SIZE]; /* AES key + IV */
3525
3526 /* get the TPM2B parameter to decrypt */
3527 if (rc == 0) {
3528 rc = TSS_GetResponseEncryptParam(tssAuthContext,
3529 ¶mSize, &encryptParamBuffer);
3530 }
3531 if (rc == 0) {
3532 if (tssVverbose) TSS_PrintAll("TSS_Response_EncryptAes: encrypt in",
3533 encryptParamBuffer, paramSize);
3534 }
3535 if (rc == 0) {
3536 rc = TSS_Malloc(&decryptParamBuffer, paramSize); /* freed @1 */
3537 }
3538 /* generate the encryption key and IV */
3539 /* 21.3 CFB Mode Parameter Encryption
3540
3541 KDFa (hashAlg, sessionValue, "CFB", nonceNewer, nonceOlder, bits) (34)
3542 */
3543 if (rc == 0) {
3544
3545 iv.t.size = TSS_Sym_GetBlockSize(session->symmetric.algorithm,
3546 session->symmetric.keyBits.aes);
3547 /* generate random values for both the AES key and the IV */
3548 kdfaBits = session->symmetric.keyBits.aes + (iv.t.size * 8);
3549
3550 if (tssVverbose) printf("TSS_Response_EncryptAes: hashAlg %04x\n",
3551 session->authHashAlg);
3552 if (tssVverbose) printf("TSS_Response_EncryptAes: AES key bits %u\n",
3553 session->symmetric.keyBits.aes);
3554 if (tssVverbose) printf("TSS_Response_EncryptAes: kdfaBits %04x\n",
3555 kdfaBits);
3556 if (tssVverbose) TSS_PrintAll("TSS_Response_EncryptAes: session key",
3557 session->sessionKey.b.buffer, session->sessionKey.b.size);
3558
3559 rc = TSS_KDFA(&symParmString[0],
3560 session->authHashAlg,
3561 &session->sessionValue.b,
3562 "CFB",
3563 &session->nonceTPM.b,
3564 &session->nonceCaller.b,
3565 kdfaBits);
3566 }
3567 /* copy the latter part of the kdf output to the IV */
3568 if (rc == 0) {
3569 keySizeinBytes = session->symmetric.keyBits.aes / 8;
3570 memcpy(iv.t.buffer, &symParmString[keySizeinBytes], iv.t.size);
3571 if (tssVverbose) TSS_PrintAll("TSS_Response_EncryptAes: IV",
3572 iv.t.buffer, iv.t.size);
3573 }
3574 /* AES CFB decrypt the response */
3575 if (rc == 0) {
3576 TPM_RC crc;
3577 crc = TSS_AES_DecryptCFB(decryptParamBuffer, /* output */
3578 session->symmetric.keyBits.aes, /* 128 */
3579 symParmString, /* key */
3580 iv.t.buffer, /* IV */
3581 paramSize, /* length */
3582 (uint8_t *)encryptParamBuffer); /* input */
3583 if (crc != 0) {
3584 if (tssVerbose) printf("TSS_Response_EncryptAes: AES decrypt failed\n");
3585 rc = TSS_RC_AES_DECRYPT_FAILURE;
3586 }
3587 }
3588 if (rc == 0) {
3589 if (tssVverbose) TSS_PrintAll("TSS_Response_EncryptAes: decrypt out",
3590 decryptParamBuffer, paramSize);
3591 }
3592 if (rc == 0) {
3593 rc = TSS_SetResponseDecryptParam(tssAuthContext,
3594 paramSize, decryptParamBuffer);
3595 }
3596 free(decryptParamBuffer); /* @1 */
3597 return rc;
3598 }
3599
3600 #endif /* TPM_TSS_NOCRYPTO */
3601
3602 /*
3603 Command Change Authorization Processor
3604 */
3605
3606 #ifndef TPM_TSS_NOCRYPTO
3607
TSS_Command_ChangeAuthProcessor(TSS_CONTEXT * tssContext,struct TSS_HMAC_CONTEXT * session,size_t handleNumber,COMMAND_PARAMETERS * in)3608 static TPM_RC TSS_Command_ChangeAuthProcessor(TSS_CONTEXT *tssContext,
3609 struct TSS_HMAC_CONTEXT *session,
3610 size_t handleNumber,
3611 COMMAND_PARAMETERS *in)
3612 {
3613 TPM_RC rc = 0;
3614 size_t index;
3615 int found;
3616 TSS_ChangeAuthFunction_t changeAuthFunction = NULL;
3617
3618 TPM_CC commandCode = TSS_GetCommandCode(tssContext->tssAuthContext);
3619
3620 /* search the table for a change authorization processing function */
3621 if (rc == 0) {
3622 found = FALSE;
3623 for (index = 0 ; (index < (sizeof(tssTable) / sizeof(TSS_TABLE))) && !found ; index++) {
3624 if (tssTable[index].commandCode == commandCode) {
3625 found = TRUE;
3626 break; /* don't increment index if found */
3627 }
3628 }
3629 }
3630 /* found false means there is no change authorization function. This permits the table to be
3631 smaller if desired. */
3632 if ((rc == 0) && found) {
3633 changeAuthFunction = tssTable[index].changeAuthFunction;
3634 /* there could also be an entry that is currently NULL, nothing to do */
3635 if (changeAuthFunction == NULL) {
3636 found = FALSE;
3637 }
3638 }
3639 /* call the processing function */
3640 if ((rc == 0) && found) {
3641 rc = changeAuthFunction(tssContext, session, handleNumber, in);
3642 }
3643 return rc;
3644 }
3645
3646 #endif /* TPM_TSS_NOCRYPTO */
3647
TSS_CA_HierarchyChangeAuth(TSS_CONTEXT * tssContext,struct TSS_HMAC_CONTEXT * session,size_t handleNumber,HierarchyChangeAuth_In * in)3648 static TPM_RC TSS_CA_HierarchyChangeAuth(TSS_CONTEXT *tssContext,
3649 struct TSS_HMAC_CONTEXT *session,
3650 size_t handleNumber,
3651 HierarchyChangeAuth_In *in)
3652 {
3653 TPM_RC rc = 0;
3654 char *password = NULL;
3655
3656 if (tssVverbose) printf("TSS_CA_HierarchyChangeAuth\n");
3657 if (in->newAuth.t.size == 0) {
3658 password = NULL;
3659 }
3660 else {
3661 if (rc == 0) {
3662 rc = TSS_Malloc((uint8_t **)&password, /* freed @1 */
3663 in->newAuth.t.size + 1);
3664 }
3665 if (rc == 0) {
3666 /* copy the password */
3667 memcpy(password, in->newAuth.t.buffer, in->newAuth.t.size);
3668 password[in->newAuth.t.size] = '\0'; /* nul terminate string */
3669 }
3670 }
3671 #ifndef TPM_TSS_NOCRYPTO
3672 if (rc == 0) {
3673 rc = TSS_HmacSession_SetHmacKey(tssContext,
3674 session,
3675 handleNumber,
3676 password);
3677 }
3678 #else
3679 tssContext = tssContext;
3680 session = session;
3681 handleNumber = handleNumber;
3682 #endif /* TPM_TSS_NOCRYPTO */
3683 free(password); /* @1 */
3684 return rc;
3685 }
3686
TSS_CA_NV_ChangeAuth(TSS_CONTEXT * tssContext,struct TSS_HMAC_CONTEXT * session,size_t handleNumber,NV_ChangeAuth_In * in)3687 static TPM_RC TSS_CA_NV_ChangeAuth(TSS_CONTEXT *tssContext,
3688 struct TSS_HMAC_CONTEXT *session,
3689 size_t handleNumber,
3690 NV_ChangeAuth_In *in)
3691 {
3692 TPM_RC rc = 0;
3693 char *password = NULL;
3694
3695 if (tssVverbose) printf("TSS_CA_NV_ChangeAuth\n");
3696 if (in->newAuth.t.size == 0) {
3697 password = NULL;
3698 }
3699 else {
3700 if (rc == 0) {
3701 rc = TSS_Malloc((uint8_t **)&password, /* freed @1 */
3702 in->newAuth.t.size + 1);
3703 }
3704 if (rc == 0) {
3705 /* copy the password */
3706 memcpy(password, in->newAuth.t.buffer, in->newAuth.t.size);
3707 password[in->newAuth.t.size] = '\0'; /* nul terminate string */
3708 }
3709 }
3710 #ifndef TPM_TSS_NOCRYPTO
3711 if (rc == 0) {
3712 rc = TSS_HmacSession_SetHmacKey(tssContext,
3713 session,
3714 handleNumber,
3715 password);
3716 }
3717 #else
3718 tssContext = tssContext;
3719 session = session;
3720 handleNumber = handleNumber;
3721 #endif /* TPM_TSS_NOCRYPTO */
3722 free(password); /* @1 */
3723 return rc;
3724 }
3725
TSS_CA_NV_UndefineSpaceSpecial(TSS_CONTEXT * tssContext,struct TSS_HMAC_CONTEXT * session,size_t handleNumber,NV_UndefineSpaceSpecial_In * in)3726 static TPM_RC TSS_CA_NV_UndefineSpaceSpecial(TSS_CONTEXT *tssContext,
3727 struct TSS_HMAC_CONTEXT *session,
3728 size_t handleNumber,
3729 NV_UndefineSpaceSpecial_In *in)
3730 {
3731 TPM_RC rc = 0;
3732
3733 in = in;
3734 if (tssVverbose) printf("TSS_CA_NV_UndefineSpaceSpecial\n");
3735 #ifndef TPM_TSS_NOCRYPTO
3736 if (rc == 0) {
3737 /* the nvIndex authorization, the zeroth authorization, has special handling */
3738 if (handleNumber == 0) {
3739 /* the Empty Buffer is used as the authValue when generating the response HMAC */
3740 rc = TSS_HmacSession_SetHmacKey(tssContext,
3741 session,
3742 handleNumber,
3743 NULL); /* password */
3744 }
3745 }
3746 #else
3747 tssContext = tssContext;
3748 session = session;
3749 handleNumber = handleNumber;
3750 #endif /* TPM_TSS_NOCRYPTO */
3751 return rc;
3752 }
3753
3754 /*
3755 Command Pre-Processor
3756 */
3757
TSS_Command_PreProcessor(TSS_CONTEXT * tssContext,TPM_CC commandCode,COMMAND_PARAMETERS * in,EXTRA_PARAMETERS * extra)3758 static TPM_RC TSS_Command_PreProcessor(TSS_CONTEXT *tssContext,
3759 TPM_CC commandCode,
3760 COMMAND_PARAMETERS *in,
3761 EXTRA_PARAMETERS *extra)
3762 {
3763 TPM_RC rc = 0;
3764 size_t index;
3765 int found;
3766 TSS_PreProcessFunction_t preProcessFunction = NULL;
3767
3768 /* search the table for a pre-processing function */
3769 if (rc == 0) {
3770 found = FALSE;
3771 for (index = 0 ; (index < (sizeof(tssTable) / sizeof(TSS_TABLE))) && !found ; index++) {
3772 if (tssTable[index].commandCode == commandCode) {
3773 found = TRUE;
3774 break; /* don't increment index if found */
3775 }
3776 }
3777 }
3778 /* found false means there is no pre-processing function. This permits the table to be smaller
3779 if desired. */
3780 if ((rc == 0) && found) {
3781 preProcessFunction = tssTable[index].preProcessFunction;
3782 /* call the pre processing function if there is one */
3783 if (preProcessFunction != NULL) {
3784 rc = preProcessFunction(tssContext, in, extra);
3785 }
3786 }
3787 #ifndef TPM_TSS_NO_PRINT
3788 if ((rc == 0) && tssVverbose) {
3789 found = FALSE;
3790 for (index = 0 ;
3791 (index < (sizeof(tssPrintTable) / sizeof(TSS_PRINT_TABLE))) && !found ;
3792 index++) {
3793 if (tssPrintTable[index].commandCode == commandCode) {
3794 found = TRUE;
3795 break; /* don't increment index if found */
3796 }
3797 }
3798 }
3799 /* found false means there is no print function. This permits the table to be smaller
3800 if desired. */
3801 if ((rc == 0) && tssVverbose && found) {
3802 TSS_InPrintFunction_t inPrintFunction = tssPrintTable[index].inPrintFunction;
3803 /* call the pre processing function if there is one */
3804 if (inPrintFunction != NULL) {
3805 printf("TSS_Command_PreProcessor: Input parameters\n");
3806 inPrintFunction(in, 8); /* hard code indent 8 */
3807 }
3808 }
3809 #endif /* TPM_TSS_NO_PRINT */
3810 return rc;
3811 }
3812
3813 /*
3814 Command specific pre processing functions
3815 */
3816
3817 /* TSS_PR_StartAuthSession handles StartAuthSession pre processing.
3818
3819 If the salt key in->tpmKey is not NULL and an RSA key, the preprocessor supplies the encrypted
3820 salt. It passes the unencrypted salt to the post processor for session key processing.
3821
3822 An input salt (encrypted or unencrypted) is ignored.
3823
3824 Returns an error if the key is not an RSA key.
3825 */
3826
TSS_PR_StartAuthSession(TSS_CONTEXT * tssContext,StartAuthSession_In * in,StartAuthSession_Extra * extra)3827 static TPM_RC TSS_PR_StartAuthSession(TSS_CONTEXT *tssContext,
3828 StartAuthSession_In *in,
3829 StartAuthSession_Extra *extra)
3830 {
3831 TPM_RC rc = 0;
3832
3833 if (tssVverbose) printf("TSS_PR_StartAuthSession\n");
3834
3835 /* if (tssVverbose) StartAuthSession_In_Print(in, 8); */
3836
3837 #ifndef TPM_TSS_NOCRYPTO
3838 /* generate nonceCaller */
3839 if (rc == 0) {
3840 /* the size is determined by the session hash algorithm */
3841 in->nonceCaller.t.size = TSS_GetDigestSize(in->authHash);
3842 if (in->nonceCaller.t.size == 0) {
3843 if (tssVerbose) printf("TSS_PR_StartAuthSession: hash algorithm %04x not implemented\n",
3844 in->authHash);
3845 rc = TSS_RC_BAD_HASH_ALGORITHM;
3846 }
3847 }
3848 if (rc == 0) {
3849 rc = TSS_RandBytes((unsigned char *)&in->nonceCaller.t.buffer, in->nonceCaller.t.size);
3850 }
3851 #else
3852 in->nonceCaller.t.size = 16;
3853 memset(&in->nonceCaller.t.buffer, 0, 16);
3854 #endif /* TPM_TSS_NOCRYPTO */
3855 /* initialize to handle unsalted session */
3856 in->encryptedSalt.t.size = 0;
3857 if (extra != NULL) { /* extra NULL is handled at the port processor */
3858 extra->salt.t.size = 0;
3859 }
3860 /* if the caller requests a salted session */
3861 if (in->tpmKey != TPM_RH_NULL) {
3862 #ifndef TPM_TSS_NOCRYPTO
3863 TPM2B_PUBLIC bPublic;
3864
3865 if (rc == 0) {
3866 if (extra == NULL) {
3867 if (tssVerbose)
3868 printf("TSS_PR_StartAuthSession: salt session requires extra parameter\n");
3869 rc = TSS_RC_NULL_PARAMETER;
3870 }
3871 }
3872 /* get the tpmKey public key */
3873 if (rc == 0) {
3874 rc = TSS_Public_Load(tssContext, &bPublic, in->tpmKey, NULL);
3875 }
3876 /* generate the salt and encrypted salt based on the asymmetric key type */
3877 if (rc == 0) {
3878 switch (bPublic.publicArea.type) {
3879 #ifndef TPM_TSS_NOECC
3880 case TPM_ALG_ECC:
3881 rc = TSS_ECC_Salt(&extra->salt,
3882 &in->encryptedSalt,
3883 &bPublic.publicArea);
3884 break;
3885 #endif /* TPM_TSS_NOECC */
3886 #ifndef TPM_TSS_NORSA
3887 case TPM_ALG_RSA:
3888 rc = TSS_RSA_Salt(&extra->salt,
3889 &in->encryptedSalt,
3890 &bPublic.publicArea);
3891 break;
3892 #endif /* TPM_TSS_NORSA */
3893 default:
3894 if (tssVerbose)
3895 printf("TSS_PR_StartAuthSession: public key type %04x not supported\n",
3896 bPublic.publicArea.type);
3897 rc = TSS_RC_BAD_SALT_KEY;
3898 }
3899 }
3900 #else
3901 tssContext = tssContext;
3902 rc = TSS_RC_NOT_IMPLEMENTED;
3903 #endif /* TPM_TSS_NOCRYPTO */
3904 }
3905 return rc;
3906 }
3907
3908 #ifndef TPM_TSS_NOCRYPTO
3909 #ifndef TPM_TSS_NORSA
3910
3911 /* TSS_RSA_Salt() returns both the plaintext and excrypted salt, based on the salt key bPublic. */
3912
TSS_RSA_Salt(TPM2B_DIGEST * salt,TPM2B_ENCRYPTED_SECRET * encryptedSalt,TPMT_PUBLIC * publicArea)3913 static TPM_RC TSS_RSA_Salt(TPM2B_DIGEST *salt,
3914 TPM2B_ENCRYPTED_SECRET *encryptedSalt,
3915 TPMT_PUBLIC *publicArea)
3916 {
3917 TPM_RC rc = 0;
3918
3919 if (rc == 0) {
3920 {
3921 /* error conditions when true */
3922 int b1 = publicArea->type != TPM_ALG_RSA;
3923 int b2 = publicArea->objectAttributes.val & TPMA_OBJECT_SIGN;
3924 int b3 = !(publicArea->objectAttributes.val & TPMA_OBJECT_DECRYPT);
3925 int b4 = (publicArea->parameters.rsaDetail.exponent != 0) &&
3926 /* some HW TPMs return 010001 for the RSA EK with the default IWG template */
3927 (publicArea->parameters.rsaDetail.exponent != RSA_DEFAULT_PUBLIC_EXPONENT);
3928 /* TSS support checks */
3929 if (b1 || b2 || b3 || b4) {
3930 if (tssVerbose)
3931 printf("TSS_RSA_Salt: public key attributes not supported\n");
3932 rc = TSS_RC_BAD_SALT_KEY;
3933 }
3934 }
3935 }
3936 if (rc == 0) {
3937 if (tssVverbose) TSS_PrintAll("TSS_RSA_Salt: public key",
3938 publicArea->unique.rsa.t.buffer,
3939 publicArea->unique.rsa.t.size);
3940 }
3941 /* generate a salt */
3942 if (rc == 0) {
3943 /* The size of the secret value is limited to the size of the digest produced by the
3944 nameAlg of the object that is associated with the public key used for OAEP
3945 encryption. */
3946 salt->t.size = TSS_GetDigestSize(publicArea->nameAlg);
3947 if (tssVverbose) printf("TSS_RSA_Salt: "
3948 "Hash algorithm %04x Salt size %u\n",
3949 publicArea->nameAlg, salt->t.size);
3950 /* place the salt in extra so that it can be retrieved by post processor */
3951 rc = TSS_RandBytes((uint8_t *)&salt->t.buffer, salt->t.size);
3952 }
3953 /* In TPM2_StartAuthSession(), when tpmKey is an RSA key, the secret value (salt) is
3954 encrypted using OAEP as described in B.4. The string "SECRET" (see 4.5) is used as
3955 the L value and the nameAlg of the encrypting key is used for the hash algorithm. The
3956 data value in OAEP-encrypted blob (salt) is used to compute sessionKey. */
3957 if (rc == 0) {
3958 if (tssVverbose) TSS_PrintAll("TSS_RSA_Salt: salt",
3959 (uint8_t *)&salt->t.buffer,
3960 salt->t.size);
3961 }
3962 /* encrypt the salt */
3963 if (rc == 0) {
3964 /* public exponent */
3965 unsigned char earr[3] = {0x01, 0x00, 0x01};
3966 /* encrypt the salt with the tpmKey public key */
3967 rc = TSS_RSAPublicEncrypt((uint8_t *)&encryptedSalt->t.secret, /* encrypted data */
3968 publicArea->unique.rsa.t.size, /* size of encrypted data buffer */
3969 (uint8_t *)&salt->t.buffer, /* decrypted data */
3970 salt->t.size,
3971 publicArea->unique.rsa.t.buffer, /* public modulus */
3972 publicArea->unique.rsa.t.size,
3973 earr, /* public exponent */
3974 sizeof(earr),
3975 (unsigned char *)"SECRET", /* encoding parameter */
3976 sizeof("SECRET"),
3977 publicArea->nameAlg);
3978 }
3979 if (rc == 0) {
3980 encryptedSalt->t.size = publicArea->unique.rsa.t.size;
3981 if (tssVverbose) TSS_PrintAll("TSS_RSA_Salt: RSA encrypted salt",
3982 encryptedSalt->t.secret,
3983 encryptedSalt->t.size);
3984 }
3985 return rc;
3986 }
3987
3988 #endif /* TPM_TSS_NORSA */
3989 #endif /* TPM_TSS_NOCRYPTO */
3990
TSS_PR_NV_DefineSpace(TSS_CONTEXT * tssContext,NV_DefineSpace_In * in,void * extra)3991 static TPM_RC TSS_PR_NV_DefineSpace(TSS_CONTEXT *tssContext,
3992 NV_DefineSpace_In *in,
3993 void *extra)
3994 {
3995 TPM_RC rc = 0;
3996 tssContext = tssContext;
3997 extra = extra;
3998
3999 if (tssVverbose) printf("TSS_PR_NV_DefineSpace\n");
4000 /* Test that TPMA_NVA_POLICY_DELETE is only set when a policy is also set. Otherwise, the index
4001 cannot ever be deleted, even with Platform Authorization. If the application really wants to
4002 do this, set the policy to one that cannot be satisfied, e.g., all 0xff's. */
4003 if (rc == 0) {
4004 if (in->publicInfo.nvPublic.attributes.val & TPMA_NVA_POLICY_DELETE) {
4005 if (in->publicInfo.nvPublic.authPolicy.b.size == 0) {
4006 if (tssVverbose) printf("TSS_PR_NV_DefineSpace POLICY_DELETE requires a policy\n");
4007 rc = TSS_RC_IN_PARAMETER;
4008 }
4009 }
4010 }
4011 return rc;
4012 }
4013
4014 /*
4015 Response Post Processor
4016 */
4017
4018 /* TSS_Response_PostProcessor() handles any response specific post processing
4019 */
4020
TSS_Response_PostProcessor(TSS_CONTEXT * tssContext,COMMAND_PARAMETERS * in,RESPONSE_PARAMETERS * out,EXTRA_PARAMETERS * extra)4021 static TPM_RC TSS_Response_PostProcessor(TSS_CONTEXT *tssContext,
4022 COMMAND_PARAMETERS *in,
4023 RESPONSE_PARAMETERS *out,
4024 EXTRA_PARAMETERS *extra)
4025 {
4026 TPM_RC rc = 0;
4027 size_t index;
4028 int found;
4029 TSS_PostProcessFunction_t postProcessFunction = NULL;
4030
4031 /* search the table for a post processing function */
4032 if (rc == 0) {
4033 TPM_CC commandCode = TSS_GetCommandCode(tssContext->tssAuthContext);
4034 found = FALSE;
4035 for (index = 0 ; (index < (sizeof(tssTable) / sizeof(TSS_TABLE))) && !found ; index++) {
4036 if (tssTable[index].commandCode == commandCode) {
4037 found = TRUE;
4038 break; /* don't increment index if found */
4039 }
4040 }
4041 }
4042 /* found false means there is no post processing function. This permits the table to be smaller
4043 if desired. */
4044 if ((rc == 0) && found) {
4045 postProcessFunction = tssTable[index].postProcessFunction;
4046 /* there could also be an entry that it currently NULL, nothing to do */
4047 if (postProcessFunction == NULL) {
4048 found = FALSE;
4049 }
4050 }
4051 /* call the function */
4052 if ((rc == 0) && found) {
4053 rc = postProcessFunction(tssContext, in, out, extra);
4054 }
4055 return rc;
4056 }
4057
4058 /*
4059 Command specific post processing functions
4060 */
4061
4062 /* TSS_PO_StartAuthSession handles StartAuthSession post processing. It:
4063
4064 creates a TSS HMAC session
4065
4066 saves the session handle, hash algorithm, and symmetric algorithm, nonceCaller and nonceTPM
4067
4068 It calculates the session key and saves it
4069
4070 Finally, it marshals the session and stores it
4071 */
4072
TSS_PO_StartAuthSession(TSS_CONTEXT * tssContext,StartAuthSession_In * in,StartAuthSession_Out * out,StartAuthSession_Extra * extra)4073 static TPM_RC TSS_PO_StartAuthSession(TSS_CONTEXT *tssContext,
4074 StartAuthSession_In *in,
4075 StartAuthSession_Out *out,
4076 StartAuthSession_Extra *extra)
4077 {
4078 TPM_RC rc = 0;
4079 struct TSS_HMAC_CONTEXT *session = NULL;
4080 TPM2B_DIGEST salt;
4081
4082 if (tssVverbose) printf("TSS_PO_StartAuthSession\n");
4083 /* allocate a TSS_HMAC_CONTEXT session context */
4084 if (rc == 0) {
4085 rc = TSS_HmacSession_GetContext(&session);
4086 }
4087 if (rc == 0) {
4088 session->sessionHandle = out->sessionHandle;
4089 session->authHashAlg = in->authHash;
4090 #ifndef TPM_TSS_NOCRYPTO
4091 session->sizeInBytes = TSS_GetDigestSize(session->authHashAlg);
4092 #endif
4093 session->symmetric = in->symmetric;
4094 session->sessionType = in->sessionType;
4095 }
4096 /* if not a bind session or if no bind password was supplied */
4097 if (rc == 0) {
4098 if ((extra == NULL) || (in->bind == TPM_RH_NULL) || (extra->bindPassword == NULL)) {
4099 session->bindAuthValue.b.size = 0;
4100 }
4101 else {
4102 rc = TSS_TPM2B_StringCopy(&session->bindAuthValue.b,
4103 extra->bindPassword, sizeof(session->bindAuthValue.t.buffer));
4104 }
4105 }
4106 if (rc == 0) {
4107 /* if the caller did not supply extra, the salt must be empty */
4108 if (extra == NULL) {
4109 salt.b.size = 0;
4110 }
4111 /* if the caller supplied extra, the preprocessor sets salt to empty (unsalted) or the
4112 plaintext salt value */
4113 else {
4114 rc = TSS_TPM2B_Copy(&salt.b, &extra->salt.b, sizeof(TPMT_HA));
4115 }
4116 }
4117 #ifndef TPM_TSS_NOCRYPTO
4118 if (rc == 0) {
4119 rc = TSS_TPM2B_Copy(&session->nonceTPM.b, &out->nonceTPM.b, sizeof(TPMT_HA));
4120 }
4121 if (rc == 0) {
4122 rc = TSS_TPM2B_Copy(&session->nonceCaller.b, &in->nonceCaller.b, sizeof(TPMT_HA));
4123 }
4124 if (rc == 0) {
4125 rc = TSS_HmacSession_SetSessionKey(tssContext, session,
4126 &salt,
4127 in->bind, &session->bindAuthValue);
4128 }
4129 #endif /* TPM_TSS_NOCRYPTO */
4130 if (rc == 0) {
4131 rc = TSS_HmacSession_SaveSession(tssContext, session);
4132 }
4133 TSS_HmacSession_FreeContext(session);
4134 return rc;
4135 }
4136
4137 /* TSS_PO_ContextSave() saves the name of an object in a filename that is a hash of the contextBlob.
4138
4139 This permits the name to be found during ContextLoad.
4140 */
4141
TSS_PO_ContextSave(TSS_CONTEXT * tssContext,ContextSave_In * in,ContextSave_Out * out,void * extra)4142 static TPM_RC TSS_PO_ContextSave(TSS_CONTEXT *tssContext,
4143 ContextSave_In *in,
4144 ContextSave_Out *out,
4145 void *extra)
4146 {
4147 TPM_RC rc = 0;
4148 #ifndef TPM_TSS_NOFILE
4149 TPMT_HA cpHash; /* largest size of a digest */
4150 char string[65]; /* sha256 hash * 2 + 1 */
4151 TPM_HT handleType;
4152 int done = FALSE;
4153 #endif
4154
4155 in = in;
4156 extra = extra;
4157
4158 #ifndef TPM_TSS_NOFILE
4159 if (tssVverbose) printf("TSS_PO_ContextSave: handle %08x\n", in->saveHandle);
4160 /* only for objects and sequence objects, not sessions */
4161 if (rc == 0) {
4162 handleType = (TPM_HT) ((in->saveHandle & HR_RANGE_MASK) >> HR_SHIFT);
4163 if (handleType != TPM_HT_TRANSIENT) {
4164 done = TRUE;
4165 }
4166 }
4167 if ((rc == 0) && !done) {
4168 cpHash.hashAlg = TPM_ALG_SHA256; /* arbitrary choice */
4169 rc = TSS_Hash_Generate(&cpHash,
4170 out->context.contextBlob.b.size, out->context.contextBlob.b.buffer,
4171 0, NULL);
4172 }
4173 /* convert a hash of the context blob to a string */
4174 if ((rc == 0) && !done) {
4175 rc = TSS_HashToString(string, cpHash.digest.sha256);
4176 }
4177 if ((rc == 0) && !done) {
4178 rc = TSS_Name_Copy(tssContext,
4179 0, string, /* to context */
4180 in->saveHandle, NULL); /* from handle */
4181 }
4182 /* get the public key of the object being context saved */
4183 /* save the public key under the context */
4184 if ((rc == 0) && !done) {
4185 rc = TSS_Public_Copy(tssContext,
4186 0,
4187 string,
4188 in->saveHandle,
4189 NULL);
4190 }
4191 #else
4192 tssContext = tssContext;
4193 out = out;
4194 #endif
4195 return rc;
4196 }
4197
TSS_PO_ContextLoad(TSS_CONTEXT * tssContext,ContextLoad_In * in,ContextLoad_Out * out,void * extra)4198 static TPM_RC TSS_PO_ContextLoad(TSS_CONTEXT *tssContext,
4199 ContextLoad_In *in,
4200 ContextLoad_Out *out,
4201 void *extra)
4202 {
4203 TPM_RC rc = 0;
4204 #ifndef TPM_TSS_NOFILE
4205 TPMT_HA cpHash; /* largest size of a digest */
4206 char string[65]; /* sha256 hash * 2 + 1 */
4207 TPM_HT handleType;
4208 int done = FALSE;
4209 #endif
4210
4211 out = out;
4212 extra = extra;
4213
4214 #ifndef TPM_TSS_NOFILE
4215 if (tssVverbose) printf("TSS_PO_ContextLoad: handle %08x\n", out->loadedHandle);
4216 /* only for objects and sequence objects, not sessions */
4217 if (rc == 0) {
4218 handleType = (TPM_HT) ((out->loadedHandle & HR_RANGE_MASK) >> HR_SHIFT);
4219 if (handleType != TPM_HT_TRANSIENT) {
4220 done = TRUE;
4221 }
4222 }
4223 if ((rc == 0) && !done) {
4224 cpHash.hashAlg = TPM_ALG_SHA256; /* arbitrary choice */
4225 rc = TSS_Hash_Generate(&cpHash,
4226 in->context.contextBlob.b.size, in->context.contextBlob.b.buffer,
4227 0, NULL);
4228 }
4229 /* convert a hash of the context blob to a string */
4230 if ((rc == 0) && !done) {
4231 rc = TSS_HashToString(string, cpHash.digest.sha256);
4232 }
4233 /* get the Name of the object being context loaded */
4234 /* write the name with the loaded context's handle */
4235 if ((rc == 0) && !done) {
4236 rc = TSS_Name_Copy(tssContext,
4237 out->loadedHandle, NULL, /* to handle */
4238 0, string); /* from context */
4239 }
4240 /* get the public key of the object being context loaded */
4241 /* write the public key with the loaded context's handle */
4242 if ((rc == 0) && !done) {
4243 rc = TSS_Public_Copy(tssContext,
4244 out->loadedHandle,
4245 NULL,
4246 0,
4247 string);
4248 }
4249 #else
4250 tssContext = tssContext;
4251 in = in;
4252 #endif
4253 return rc;
4254 }
4255
4256 /* TSS_HashToString() converts a SHA-256 binary hash (really any 32-byte value) to a string
4257
4258 string must be 65 bytes: 32*2 + 1
4259
4260 NOTE: Hard coded to SHA256
4261 */
4262
4263 #ifndef TPM_TSS_NOFILE
4264
TSS_HashToString(char * str,uint8_t * digest)4265 static TPM_RC TSS_HashToString(char *str, uint8_t *digest)
4266 {
4267 size_t i;
4268
4269 for (i = 0 ; i < SHA256_DIGEST_SIZE ; i++) {
4270 sprintf(str +(i*2), "%02x", digest[i]);
4271 }
4272 if (tssVverbose) printf("TSS_HashToString: %s\n", str);
4273 return 0;
4274 }
4275
4276 #endif
4277
4278 /* TSS_PO_FlushContext() removes persistent state associated with the handle */
4279
TSS_PO_FlushContext(TSS_CONTEXT * tssContext,FlushContext_In * in,void * out,void * extra)4280 static TPM_RC TSS_PO_FlushContext(TSS_CONTEXT *tssContext,
4281 FlushContext_In *in,
4282 void *out,
4283 void *extra)
4284 {
4285 TPM_RC rc = 0;
4286
4287 out = out;
4288 extra = extra;
4289 if (tssVverbose) printf("TSS_PO_FlushContext: flushHandle %08x\n", in->flushHandle);
4290 if (rc == 0) {
4291 rc = TSS_DeleteHandle(tssContext, in->flushHandle);
4292 }
4293 return rc;
4294 }
4295
4296 /* TSS_PO_EvictControl() removes persistent state associated with the handle */
4297
TSS_PO_EvictControl(TSS_CONTEXT * tssContext,EvictControl_In * in,void * out,void * extra)4298 static TPM_RC TSS_PO_EvictControl(TSS_CONTEXT *tssContext,
4299 EvictControl_In *in,
4300 void *out,
4301 void *extra)
4302 {
4303 TPM_RC rc = 0;
4304
4305 out = out;
4306 extra = extra;
4307
4308 if (tssVverbose) printf("TSS_PO_EvictControl: object %08x persistent %08x\n",
4309 in->objectHandle, in->persistentHandle);
4310 /* if it successfully made a persistent copy */
4311 if (in->objectHandle != in->persistentHandle) {
4312 /* TPM2B_PUBLIC bPublic; */
4313 if (rc == 0) {
4314 rc = TSS_Name_Copy(tssContext,
4315 in->persistentHandle, NULL, /* to persistent handle */
4316 in->objectHandle, NULL); /* from transient handle */
4317 }
4318 /* get the transient object public key */
4319 /* copy it to the persistent object public key */
4320 if (rc == 0) {
4321 rc = TSS_Public_Copy(tssContext,
4322 in->persistentHandle,
4323 NULL,
4324 in->objectHandle,
4325 NULL);
4326 }
4327 }
4328 /* if it successfully evicted the persistent object */
4329 else {
4330 if (rc == 0) {
4331 rc = TSS_DeleteHandle(tssContext, in->persistentHandle);
4332 }
4333 }
4334 return rc;
4335 }
4336
4337 /* TSS_PO_Load() saves the Name returned for the loaded object. It saves the TPM2B_PUBLIC */
4338
TSS_PO_Load(TSS_CONTEXT * tssContext,Load_In * in,Load_Out * out,void * extra)4339 static TPM_RC TSS_PO_Load(TSS_CONTEXT *tssContext,
4340 Load_In *in,
4341 Load_Out *out,
4342 void *extra)
4343 {
4344 TPM_RC rc = 0;
4345
4346 in = in;
4347 extra = extra;
4348 if (tssVverbose) printf("TSS_PO_Load: handle %08x\n", out->objectHandle);
4349 /* use handle as file name */
4350 if (rc == 0) {
4351 rc = TSS_Name_Store(tssContext, &out->name, out->objectHandle, NULL);
4352 }
4353 if (rc == 0) {
4354 rc = TSS_Public_Store(tssContext, &in->inPublic, out->objectHandle, NULL);
4355 }
4356 return rc;
4357 }
4358
4359 /* TSS_PO_LoadExternal() saves the Name returned for the loaded object */
4360
TSS_PO_LoadExternal(TSS_CONTEXT * tssContext,LoadExternal_In * in,LoadExternal_Out * out,void * extra)4361 static TPM_RC TSS_PO_LoadExternal(TSS_CONTEXT *tssContext,
4362 LoadExternal_In *in,
4363 LoadExternal_Out *out,
4364 void *extra)
4365 {
4366 TPM_RC rc = 0;
4367
4368 in = in;
4369 extra = extra;
4370 if (tssVverbose) printf("TSS_PO_LoadExternal: handle %08x\n", out->objectHandle);
4371 /* use handle as file name */
4372 if (rc == 0) {
4373 rc = TSS_Name_Store(tssContext, &out->name, out->objectHandle, NULL);
4374 }
4375 if (rc == 0) {
4376 rc = TSS_Public_Store(tssContext, &in->inPublic, out->objectHandle, NULL);
4377 }
4378 return rc;
4379 }
4380
4381 /* TSS_PO_ReadPublic() saves the Name returned for the loaded object */
4382
TSS_PO_ReadPublic(TSS_CONTEXT * tssContext,ReadPublic_In * in,ReadPublic_Out * out,void * extra)4383 static TPM_RC TSS_PO_ReadPublic(TSS_CONTEXT *tssContext,
4384 ReadPublic_In *in,
4385 ReadPublic_Out *out,
4386 void *extra)
4387 {
4388 TPM_RC rc = 0;
4389
4390 in = in;
4391 extra = extra;
4392 if (tssVverbose) printf("TSS_PO_ReadPublic: handle %08x\n", in->objectHandle);
4393 /* if the TSS is compiled without crypto support, it cannot recalculate the Name from the public
4394 area. It has to trust the response from the TPM. This should be OK since a 'no crypto' TSS
4395 is used when there is a tructed path to the TPM. */
4396 #ifndef TPM_TSS_NOCRYPTO
4397 /* validate the Name against the public area */
4398 /* Name = nameAlg || HnameAlg (handle->publicArea)
4399 where
4400 nameAlg algorithm used to compute Name
4401 HnameAlg hash using the nameAlg parameter in the object associated with handle
4402 publicArea contents of the TPMT_PUBLIC associated with handle
4403 */
4404 {
4405 TPM2B_NAME name;
4406 if (rc == 0) {
4407 rc = TSS_ObjectPublic_GetName(&name, &out->outPublic.publicArea);
4408 }
4409 if (rc == 0) {
4410 if (name.t.size != out->name.t.size) {
4411 if (tssVerbose)
4412 printf("TSS_PO_ReadPublic: TPMT_PUBLIC does not match TPM2B_NAME\n");
4413 rc = TSS_RC_MALFORMED_PUBLIC;
4414 }
4415 else {
4416 int irc;
4417 irc = memcmp(name.t.name, out->name.t.name, out->name.t.size);
4418 if (irc != 0) {
4419 if (tssVerbose)
4420 printf("TSS_PO_ReadPublic: TPMT_PUBLIC does not match TPM2B_NAME\n");
4421 rc = TSS_RC_MALFORMED_PUBLIC;
4422 }
4423 }
4424 }
4425 }
4426 #endif
4427 /* use handle as file name */
4428 if (rc == 0) {
4429 rc = TSS_Name_Store(tssContext, &out->name, in->objectHandle, NULL);
4430 }
4431 if (rc == 0) {
4432 rc = TSS_Public_Store(tssContext, &out->outPublic, in->objectHandle, NULL);
4433 }
4434 return rc;
4435 }
4436
4437 /* TSS_PO_Load() saves the Name returned for the loaded object. It saves the TPM2B_PUBLIC */
4438
TSS_PO_CreateLoaded(TSS_CONTEXT * tssContext,CreateLoaded_In * in,CreateLoaded_Out * out,void * extra)4439 static TPM_RC TSS_PO_CreateLoaded(TSS_CONTEXT *tssContext,
4440 CreateLoaded_In *in,
4441 CreateLoaded_Out *out,
4442 void *extra)
4443 {
4444 TPM_RC rc = 0;
4445
4446 in = in;
4447 extra = extra;
4448 if (tssVverbose) printf("TSS_PO_CreateLoaded: handle %08x\n", out->objectHandle);
4449 /* use handle as file name */
4450 if (rc == 0) {
4451 rc = TSS_Name_Store(tssContext, &out->name, out->objectHandle, NULL);
4452 }
4453 if (rc == 0) {
4454 rc = TSS_Public_Store(tssContext, &out->outPublic, out->objectHandle, NULL);
4455 }
4456 return rc;
4457 }
4458
4459 /* TSS_PO_HashSequenceStart() saves the Name returned for the started sequence object */
4460
TSS_PO_HashSequenceStart(TSS_CONTEXT * tssContext,HashSequenceStart_In * in,HashSequenceStart_Out * out,void * extra)4461 static TPM_RC TSS_PO_HashSequenceStart(TSS_CONTEXT *tssContext,
4462 HashSequenceStart_In *in,
4463 HashSequenceStart_Out *out,
4464 void *extra)
4465 {
4466 TPM_RC rc = 0;
4467 TPM2B_NAME name;
4468
4469 in = in;
4470 extra = extra;
4471
4472 if (tssVverbose) printf("TSS_PO_HashSequenceStart\n");
4473 /* Part 1 Table 3 The Name of a sequence object is an Empty Buffer */
4474 if (rc == 0) {
4475 name.b.size = 0;
4476 /* use handle as file name */
4477 rc = TSS_Name_Store(tssContext, &name, out->sequenceHandle, NULL);
4478 }
4479 return rc;
4480 }
4481
4482
4483 /* TSS_PO_HMAC_Start() saves the Name returned for the started sequence object */
4484
TSS_PO_HMAC_Start(TSS_CONTEXT * tssContext,HMAC_Start_In * in,HMAC_Start_Out * out,void * extra)4485 static TPM_RC TSS_PO_HMAC_Start(TSS_CONTEXT *tssContext,
4486 HMAC_Start_In *in,
4487 HMAC_Start_Out *out,
4488 void *extra)
4489 {
4490 TPM_RC rc = 0;
4491 TPM2B_NAME name;
4492
4493 in = in;
4494 extra = extra;
4495
4496 if (tssVverbose) printf("TSS_PO_HMAC_Start\n");
4497 /* Part 1 Table 3 The Name of a sequence object is an Empty Buffer */
4498 if (rc == 0) {
4499 name.b.size = 0;
4500 /* use handle as file name */
4501 rc = TSS_Name_Store(tssContext, &name, out->sequenceHandle, NULL);
4502 }
4503 return rc;
4504 }
4505
TSS_PO_SequenceComplete(TSS_CONTEXT * tssContext,SequenceComplete_In * in,SequenceComplete_Out * out,void * extra)4506 static TPM_RC TSS_PO_SequenceComplete(TSS_CONTEXT *tssContext,
4507 SequenceComplete_In *in,
4508 SequenceComplete_Out *out,
4509 void *extra)
4510 {
4511 TPM_RC rc = 0;
4512
4513 out = out;
4514 extra = extra;
4515
4516 if (tssVverbose) printf("TSS_PO_SequenceComplete: sequenceHandle %08x\n", in->sequenceHandle);
4517 if (rc == 0) {
4518 rc = TSS_DeleteHandle(tssContext, in->sequenceHandle);
4519 }
4520 return rc;
4521 }
TSS_PO_EventSequenceComplete(TSS_CONTEXT * tssContext,EventSequenceComplete_In * in,EventSequenceComplete_Out * out,void * extra)4522 static TPM_RC TSS_PO_EventSequenceComplete(TSS_CONTEXT *tssContext,
4523 EventSequenceComplete_In *in,
4524 EventSequenceComplete_Out *out,
4525 void *extra)
4526 {
4527 TPM_RC rc = 0;
4528 out = out;
4529 extra = extra;
4530 if (tssVverbose)
4531 printf("TSS_PO_EventSequenceComplete: sequenceHandle %08x\n", in->sequenceHandle);
4532 if (rc == 0) {
4533 rc = TSS_DeleteHandle(tssContext, in->sequenceHandle);
4534 }
4535 return rc;
4536 }
4537
TSS_PO_PolicyAuthValue(TSS_CONTEXT * tssContext,PolicyAuthValue_In * in,void * out,void * extra)4538 static TPM_RC TSS_PO_PolicyAuthValue(TSS_CONTEXT *tssContext,
4539 PolicyAuthValue_In *in,
4540 void *out,
4541 void *extra)
4542 {
4543 TPM_RC rc = 0;
4544 struct TSS_HMAC_CONTEXT *session = NULL;
4545
4546 out = out;
4547 extra = extra;
4548 if (tssVverbose) printf("TSS_PO_PolicyAuthValue\n");
4549 if (rc == 0) {
4550 rc = TSS_Malloc((unsigned char **)&session, sizeof(TSS_HMAC_CONTEXT)); /* freed @1 */
4551 }
4552 if (rc == 0) {
4553 rc = TSS_HmacSession_LoadSession(tssContext, session, in->policySession);
4554 }
4555 if (rc == 0) {
4556 session->isPasswordNeeded = FALSE;
4557 session->isAuthValueNeeded = TRUE;
4558 rc = TSS_HmacSession_SaveSession(tssContext, session);
4559 }
4560 free(session); /* @1 */
4561 return rc;
4562 }
4563
TSS_PO_PolicyPassword(TSS_CONTEXT * tssContext,PolicyPassword_In * in,void * out,void * extra)4564 static TPM_RC TSS_PO_PolicyPassword(TSS_CONTEXT *tssContext,
4565 PolicyPassword_In *in,
4566 void *out,
4567 void *extra)
4568 {
4569 TPM_RC rc = 0;
4570 struct TSS_HMAC_CONTEXT *session = NULL;
4571
4572 out = out;
4573 extra = extra;
4574 if (tssVverbose) printf("TSS_PO_PolicyPassword\n");
4575 if (rc == 0) {
4576 rc = TSS_Malloc((unsigned char **)&session, sizeof(TSS_HMAC_CONTEXT)); /* freed @1 */
4577 }
4578 if (rc == 0) {
4579 rc = TSS_HmacSession_LoadSession(tssContext, session, in->policySession);
4580 }
4581 if (rc == 0) {
4582 session->isPasswordNeeded = TRUE;
4583 session->isAuthValueNeeded = FALSE;
4584 rc = TSS_HmacSession_SaveSession(tssContext, session);
4585 }
4586 free(session); /* @1 */
4587 return rc;
4588 }
4589
TSS_PO_CreatePrimary(TSS_CONTEXT * tssContext,CreatePrimary_In * in,CreatePrimary_Out * out,void * extra)4590 static TPM_RC TSS_PO_CreatePrimary(TSS_CONTEXT *tssContext,
4591 CreatePrimary_In *in,
4592 CreatePrimary_Out *out,
4593 void *extra)
4594 {
4595 TPM_RC rc = 0;
4596
4597 in = in;
4598 extra = extra;
4599 if (tssVverbose) printf("TSS_PO_CreatePrimary: handle %08x\n", out->objectHandle);
4600 /* use handle as file name */
4601 if (rc == 0) {
4602 rc = TSS_Name_Store(tssContext, &out->name, out->objectHandle, NULL);
4603 }
4604 if (rc == 0) {
4605 rc = TSS_Public_Store(tssContext, &out->outPublic, out->objectHandle, NULL);
4606 }
4607 return rc;
4608 }
4609
TSS_PO_NV_DefineSpace(TSS_CONTEXT * tssContext,NV_DefineSpace_In * in,void * out,void * extra)4610 static TPM_RC TSS_PO_NV_DefineSpace(TSS_CONTEXT *tssContext,
4611 NV_DefineSpace_In *in,
4612 void *out,
4613 void *extra)
4614 {
4615 TPM_RC rc = 0;
4616
4617 if (tssVverbose) printf("TSS_PO_NV_DefineSpace\n");
4618 #ifndef TPM_TSS_NOCRYPTO
4619 {
4620 TPM2B_NAME name;
4621 /* calculate the Name from the input public area */
4622 /* Name = nameAlg || HnameAlg (handle->nvPublicArea)
4623 where
4624 nameAlg algorithm used to compute Name
4625 HnameAlg hash using the nameAlg parameter in the NV Index location associated with handle
4626 nvPublicArea contents of the TPMS_NV_PUBLIC associated with handle
4627 */
4628 /* calculate the Name from the input TPMS_NV_PUBLIC */
4629 if (rc == 0) {
4630 rc = TSS_NVPublic_GetName(&name, &in->publicInfo.nvPublic);
4631 }
4632 /* use handle as file name */
4633 if (rc == 0) {
4634 rc = TSS_Name_Store(tssContext, &name, in->publicInfo.nvPublic.nvIndex, NULL);
4635 }
4636 if (rc == 0) {
4637 rc = TSS_NVPublic_Store(tssContext, &in->publicInfo.nvPublic,
4638 in->publicInfo.nvPublic.nvIndex);
4639 }
4640 }
4641 #else
4642 tssContext = tssContext;
4643 in = in;
4644 #endif
4645 out = out;
4646 extra = extra;
4647 return rc;
4648 }
4649
4650
TSS_PO_NV_ReadPublic(TSS_CONTEXT * tssContext,NV_ReadPublic_In * in,NV_ReadPublic_Out * out,void * extra)4651 static TPM_RC TSS_PO_NV_ReadPublic(TSS_CONTEXT *tssContext,
4652 NV_ReadPublic_In *in,
4653 NV_ReadPublic_Out *out,
4654 void *extra)
4655 {
4656 TPM_RC rc = 0;
4657
4658 if (tssVverbose) printf("TSS_PO_NV_ReadPublic\n");
4659
4660 /* validate the Name against the public area */
4661 /* Name = nameAlg || HnameAlg (handle->nvPublicArea)
4662 where
4663 nameAlg algorithm used to compute Name
4664 HnameAlg hash using the nameAlg parameter in the NV Index location associated with handle
4665 nvPublicArea contents of the TPMS_NV_PUBLIC associated with handle
4666 */
4667 #ifndef TPM_TSS_NOCRYPTO
4668 {
4669 TPM2B_NAME name;
4670 /* calculate the Name from the TPMS_NV_PUBLIC */
4671 if (rc == 0) {
4672 rc = TSS_NVPublic_GetName(&name, &out->nvPublic.nvPublic);
4673 }
4674 if (rc == 0) {
4675 if (name.t.size != out->nvName.t.size) {
4676 if (tssVerbose)
4677 printf("TSS_PO_NV_ReadPublic: TPMT_NV_PUBLIC does not match TPM2B_NAME\n");
4678 rc = TSS_RC_MALFORMED_NV_PUBLIC;
4679 }
4680 else {
4681 int irc;
4682 irc = memcmp(name.t.name, out->nvName.t.name, out->nvName.t.size);
4683 if (irc != 0) {
4684 if (tssVerbose)
4685 printf("TSS_PO_NV_ReadPublic: TPMT_NV_PUBLIC does not match TPM2B_NAME\n");
4686 rc = TSS_RC_MALFORMED_NV_PUBLIC;
4687 }
4688 }
4689 }
4690 /* use handle as file name */
4691 if (rc == 0) {
4692 rc = TSS_Name_Store(tssContext, &out->nvName, in->nvIndex, NULL);
4693 }
4694 if (rc == 0) {
4695 rc = TSS_NVPublic_Store(tssContext, &out->nvPublic.nvPublic, in->nvIndex);
4696 }
4697 }
4698 #else
4699 tssContext = tssContext;
4700 in = in;
4701 out = out;
4702 #endif
4703 extra = extra;
4704 return rc;
4705 }
4706
TSS_PO_NV_UndefineSpace(TSS_CONTEXT * tssContext,NV_UndefineSpace_In * in,void * out,void * extra)4707 static TPM_RC TSS_PO_NV_UndefineSpace(TSS_CONTEXT *tssContext,
4708 NV_UndefineSpace_In *in,
4709 void *out,
4710 void *extra)
4711 {
4712 TPM_RC rc = 0;
4713
4714 out = out;
4715 extra = extra;
4716 if (tssVverbose) printf("TSS_PO_NV_UndefineSpace\n");
4717 #ifndef TPM_TSS_NOCRYPTO
4718 /* Don't check return code. */
4719 TSS_DeleteHandle(tssContext, in->nvIndex);
4720 TSS_NVPublic_Delete(tssContext, in->nvIndex);
4721 #else
4722 tssContext = tssContext;
4723 in = in;
4724 #endif
4725 return rc;
4726 }
4727
TSS_PO_NV_UndefineSpaceSpecial(TSS_CONTEXT * tssContext,NV_UndefineSpaceSpecial_In * in,void * out,void * extra)4728 static TPM_RC TSS_PO_NV_UndefineSpaceSpecial(TSS_CONTEXT *tssContext,
4729 NV_UndefineSpaceSpecial_In *in,
4730 void *out,
4731 void *extra)
4732 {
4733 TPM_RC rc = 0;
4734
4735 out = out;
4736 extra = extra;
4737 if (tssVverbose) printf("TSS_PO_NV_UndefineSpaceSpecial\n");
4738 /* Don't check return code. The name will only exist if NV_ReadPublic has been issued */
4739 TSS_DeleteHandle(tssContext, in->nvIndex);
4740 TSS_NVPublic_Delete(tssContext, in->nvIndex);
4741 return rc;
4742 }
4743
4744 /* TSS_PO_NV_Write() handles the Name and NVPublic update for the 4 NV write commands: write,
4745 increment, extend, and setbits */
4746
TSS_PO_NV_Write(TSS_CONTEXT * tssContext,NV_Write_In * in,void * out,void * extra)4747 static TPM_RC TSS_PO_NV_Write(TSS_CONTEXT *tssContext,
4748 NV_Write_In *in,
4749 void *out,
4750 void *extra)
4751 {
4752 TPM_RC rc = 0;
4753
4754 if (tssVverbose) printf("TSS_PO_NV_Write, Increment, Extend, SetBits:\n");
4755
4756 #ifndef TPM_TSS_NOCRYPTO
4757 {
4758 TPMS_NV_PUBLIC nvPublic;
4759 TPM2B_NAME name; /* new name */
4760
4761 if (rc == 0) {
4762 rc = TSS_NVPublic_Load(tssContext, &nvPublic, in->nvIndex);
4763 }
4764 /* if the previous store had written clear */
4765 if (!(nvPublic.attributes.val & TPMA_NVA_WRITTEN)) {
4766 if (rc == 0) {
4767 /* set the written bit */
4768 nvPublic.attributes.val |= TPMA_NVA_WRITTEN;
4769 /* save the TPMS_NV_PUBLIC */
4770 rc = TSS_NVPublic_Store(tssContext, &nvPublic, in->nvIndex);
4771 }
4772 /* calculate the name */
4773 if (rc == 0) {
4774 rc = TSS_NVPublic_GetName(&name, &nvPublic);
4775 }
4776 /* save the name */
4777 if (rc == 0) {
4778 /* use handle as file name */
4779 rc = TSS_Name_Store(tssContext, &name, in->nvIndex, NULL);
4780 }
4781 /* if there is a failure. delete the name and NVPublic */
4782 if (rc != 0) {
4783 TSS_DeleteHandle(tssContext, in->nvIndex);
4784 TSS_NVPublic_Delete(tssContext, in->nvIndex);
4785 }
4786 }
4787 }
4788 #else
4789 tssContext = tssContext;
4790 in = in;
4791 #endif
4792 out = out;
4793 extra = extra;
4794 return rc;
4795 }
4796
4797 /* TSS_PO_NV_WriteLock() handles the Name and NVPublic update for the write lock command */
4798
TSS_PO_NV_WriteLock(TSS_CONTEXT * tssContext,NV_WriteLock_In * in,void * out,void * extra)4799 static TPM_RC TSS_PO_NV_WriteLock(TSS_CONTEXT *tssContext,
4800 NV_WriteLock_In *in,
4801 void *out,
4802 void *extra)
4803 {
4804 TPM_RC rc = 0;
4805
4806 if (tssVverbose) printf("TSS_PO_NV_WriteLock:\n");
4807
4808 #ifndef TPM_TSS_NOCRYPTO
4809 {
4810 TPMS_NV_PUBLIC nvPublic;
4811 TPM2B_NAME name; /* new name */
4812
4813 if (rc == 0) {
4814 rc = TSS_NVPublic_Load(tssContext, &nvPublic, in->nvIndex);
4815 }
4816 /* if the previous store had write lock clear */
4817 if (!(nvPublic.attributes.val & TPMA_NVA_WRITELOCKED)) {
4818 if (rc == 0) {
4819 /* set the write lock bit */
4820 nvPublic.attributes.val |= TPMA_NVA_WRITELOCKED;
4821 /* save the TPMS_NV_PUBLIC */
4822 rc = TSS_NVPublic_Store(tssContext, &nvPublic, in->nvIndex);
4823 }
4824 /* calculate the name */
4825 if (rc == 0) {
4826 rc = TSS_NVPublic_GetName(&name, &nvPublic);
4827 }
4828 /* save the name */
4829 if (rc == 0) {
4830 /* use handle as file name */
4831 rc = TSS_Name_Store(tssContext, &name, in->nvIndex, NULL);
4832 }
4833 /* if there is a failure. delete the name and NVPublic */
4834 if (rc != 0) {
4835 TSS_DeleteHandle(tssContext, in->nvIndex);
4836 TSS_NVPublic_Delete(tssContext, in->nvIndex);
4837 }
4838 }
4839 }
4840 #else
4841 tssContext = tssContext;
4842 in = in;
4843 #endif
4844 out = out;
4845 extra = extra;
4846 return rc;
4847 }
4848
4849 /* TSS_PO_NV_WriteLock() handles the Name and NVPublic update for the read lock command */
4850
TSS_PO_NV_ReadLock(TSS_CONTEXT * tssContext,NV_ReadLock_In * in,void * out,void * extra)4851 static TPM_RC TSS_PO_NV_ReadLock(TSS_CONTEXT *tssContext,
4852 NV_ReadLock_In *in,
4853 void *out,
4854 void *extra)
4855 {
4856 TPM_RC rc = 0;
4857
4858 if (tssVverbose) printf("TSS_PO_NV_ReadLock:");
4859
4860 #ifndef TPM_TSS_NOCRYPTO
4861 {
4862 TPMS_NV_PUBLIC nvPublic;
4863 TPM2B_NAME name; /* new name */
4864
4865 if (rc == 0) {
4866 rc = TSS_NVPublic_Load(tssContext, &nvPublic, in->nvIndex);
4867 }
4868 /* if the previous store had read lock clear */
4869 if (!(nvPublic.attributes.val & TPMA_NVA_READLOCKED)) {
4870 if (rc == 0) {
4871 /* set the read lock bit */
4872 nvPublic.attributes.val |= TPMA_NVA_READLOCKED;
4873 /* save the TPMS_NV_PUBLIC */
4874 rc = TSS_NVPublic_Store(tssContext, &nvPublic, in->nvIndex);
4875 }
4876 /* calculate the name */
4877 if (rc == 0) {
4878 rc = TSS_NVPublic_GetName(&name, &nvPublic);
4879 }
4880 /* save the name */
4881 if (rc == 0) {
4882 /* use handle as file name */
4883 rc = TSS_Name_Store(tssContext, &name, in->nvIndex, NULL);
4884 }
4885 /* if there is a failure. delete the name and NVPublic */
4886 if (rc != 0) {
4887 TSS_DeleteHandle(tssContext, in->nvIndex);
4888 TSS_NVPublic_Delete(tssContext, in->nvIndex);
4889 }
4890 }
4891 }
4892 #else
4893 tssContext = tssContext;
4894 in = in;
4895 #endif
4896 out = out;
4897 extra = extra;
4898 return rc;
4899 }
4900
4901