1 /* Software-based Trusted Platform Module (TPM) Emulator
2  * Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
3  *
4  * This module is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  *
9  * This module is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * $Id: tpm_cmd_handler.c 467 2011-07-19 17:36:12Z mast $
15  */
16 
17 #include "tpm_marshalling.h"
18 #include "tpm_commands.h"
19 #include "crypto/sha1.h"
20 #include "crypto/hmac.h"
21 #include "tpm_data.h"
22 #include "tpm_handles.h"
23 
24 #ifdef MTM_EMULATOR
25 #include "mtm/mtm_commands.h"
26 #endif
27 
tpm_get_in_param_offset(TPM_COMMAND_CODE ordinal)28 UINT32 tpm_get_in_param_offset(TPM_COMMAND_CODE ordinal)
29 {
30   switch (ordinal) {
31     case TPM_ORD_ActivateIdentity:
32     case TPM_ORD_ChangeAuth:
33     case TPM_ORD_ChangeAuthAsymStart:
34     case TPM_ORD_CMK_ConvertMigration:
35     case TPM_ORD_CMK_CreateBlob:
36     case TPM_ORD_CMK_CreateKey:
37     case TPM_ORD_ConvertMigrationBlob:
38     case TPM_ORD_CreateMigrationBlob:
39     case TPM_ORD_CreateWrapKey:
40     case TPM_ORD_Delegate_CreateKeyDelegation:
41     case TPM_ORD_DSAP:
42     case TPM_ORD_EstablishTransport:
43     case TPM_ORD_EvictKey:
44     case TPM_ORD_FlushSpecific:
45     case TPM_ORD_GetAuditDigestSigned:
46     case TPM_ORD_GetPubKey:
47     case TPM_ORD_KeyControlOwner:
48     case TPM_ORD_LoadKey:
49     case TPM_ORD_LoadKey2:
50     case TPM_ORD_MigrateKey:
51     case TPM_ORD_Quote:
52     case TPM_ORD_Quote2:
53     case TPM_ORD_ReleaseTransportSigned:
54     case TPM_ORD_SaveKeyContext:
55     case TPM_ORD_Seal:
56     case TPM_ORD_Sealx:
57     case TPM_ORD_SetRedirection:
58     case TPM_ORD_Sign:
59     case TPM_ORD_TickStampBlob:
60     case TPM_ORD_UnBind:
61     case TPM_ORD_Unseal:
62     case TPM_ORD_DAA_Join:
63     case TPM_ORD_DAA_Sign:
64       return 4;
65 
66     case TPM_ORD_CertifyKey:
67     case TPM_ORD_CertifyKey2:
68     case TPM_ORD_ChangeAuthAsymFinish:
69       return 8;
70 
71     case TPM_ORD_OSAP:
72       return 26;
73 
74     default:
75       return 0;
76   }
77 }
78 
tpm_get_out_param_offset(TPM_COMMAND_CODE ordinal)79 UINT32 tpm_get_out_param_offset(TPM_COMMAND_CODE ordinal)
80 {
81   switch (ordinal) {
82 
83     case TPM_ORD_EstablishTransport:
84     case TPM_ORD_LoadKey2:
85       return 4;
86 
87     case TPM_ORD_OIAP:
88       return 24;
89 
90     case TPM_ORD_OSAP:
91       return 44;
92 
93     default:
94       return 0;
95   }
96 }
97 
tpm_compute_in_param_digest(TPM_REQUEST * req)98 void tpm_compute_in_param_digest(TPM_REQUEST *req)
99 {
100   tpm_sha1_ctx_t sha1;
101   UINT32 offset = tpm_get_in_param_offset(req->ordinal);
102 
103   /* compute SHA1 hash */
104   if (offset <= req->paramSize) {
105     tpm_sha1_init(&sha1);
106     tpm_sha1_update_be32(&sha1, req->ordinal);
107     /* skip all handles at the beginning */
108     tpm_sha1_update(&sha1, req->param + offset, req->paramSize - offset);
109     tpm_sha1_final(&sha1, req->auth1.digest);
110     memcpy(req->auth2.digest, req->auth1.digest, sizeof(req->auth1.digest));
111   }
112 }
113 
tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal,TPM_RESPONSE * rsp)114 void tpm_compute_out_param_digest(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
115 {
116   tpm_sha1_ctx_t sha1;
117   UINT32 offset = tpm_get_out_param_offset(ordinal);
118 
119   /* compute SHA1 hash */
120   tpm_sha1_init(&sha1);
121   tpm_sha1_update_be32(&sha1, rsp->result);
122   tpm_sha1_update_be32(&sha1, ordinal);
123   tpm_sha1_update(&sha1, rsp->param + offset, rsp->paramSize - offset);
124   tpm_sha1_final(&sha1, rsp->auth1->digest);
125   if (rsp->auth2 != NULL) memcpy(rsp->auth2->digest,
126     rsp->auth1->digest, sizeof(rsp->auth1->digest));
127 }
128 
execute_TPM_Startup(TPM_REQUEST * req,TPM_RESPONSE * rsp)129 static TPM_RESULT execute_TPM_Startup(TPM_REQUEST *req, TPM_RESPONSE *rsp)
130 {
131   BYTE *ptr;
132   UINT32 len;
133   TPM_STARTUP_TYPE startupType;
134   /* unmarshal input */
135   ptr = req->param;
136   len = req->paramSize;
137   if (tpm_unmarshal_TPM_STARTUP_TYPE(&ptr, &len, &startupType)
138       || len != 0) return TPM_BAD_PARAMETER;
139   /* execute command */
140   return TPM_Startup(startupType);
141 }
142 
execute_TPM_SaveState(TPM_REQUEST * req,TPM_RESPONSE * rsp)143 static TPM_RESULT execute_TPM_SaveState(TPM_REQUEST *req, TPM_RESPONSE *rsp)
144 {
145   /* execute command */
146   return TPM_SaveState();
147 }
148 
execute_TPM_SelfTestFull(TPM_REQUEST * req,TPM_RESPONSE * rsp)149 static TPM_RESULT execute_TPM_SelfTestFull(TPM_REQUEST *req, TPM_RESPONSE *rsp)
150 {
151   /* execute command */
152   return TPM_SelfTestFull();
153 }
154 
execute_TPM_ContinueSelfTest(TPM_REQUEST * req,TPM_RESPONSE * rsp)155 static TPM_RESULT execute_TPM_ContinueSelfTest(TPM_REQUEST *req, TPM_RESPONSE *rsp)
156 {
157   /* execute command */
158   return TPM_ContinueSelfTest();
159 }
160 
execute_TPM_GetTestResult(TPM_REQUEST * req,TPM_RESPONSE * rsp)161 static TPM_RESULT execute_TPM_GetTestResult(TPM_REQUEST *req, TPM_RESPONSE *rsp)
162 {
163   BYTE *ptr;
164   UINT32 len;
165   UINT32 outDataSize;
166   BYTE *outData = NULL;
167   TPM_RESULT res;
168   /* execute command */
169   res = TPM_GetTestResult(&outDataSize, &outData);
170   if (res != TPM_SUCCESS) return res;
171   /* marshal output */
172   rsp->paramSize = len = 4 + outDataSize;
173   rsp->param = ptr = tpm_malloc(len);
174   if (ptr == NULL
175       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
176       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) {
177     tpm_free(rsp->param);
178     res = TPM_FAIL;
179   }
180   tpm_free(outData);
181   return res;
182 }
183 
execute_TPM_SetOwnerInstall(TPM_REQUEST * req,TPM_RESPONSE * rsp)184 static TPM_RESULT execute_TPM_SetOwnerInstall(TPM_REQUEST *req, TPM_RESPONSE *rsp)
185 {
186   BYTE *ptr;
187   UINT32 len;
188   BOOL state;
189   /* unmarshal input */
190   ptr = req->param;
191   len = req->paramSize;
192   if (tpm_unmarshal_BOOL(&ptr, &len, &state)
193       || len != 0) return TPM_BAD_PARAMETER;
194   /* execute command */
195   return TPM_SetOwnerInstall(state);
196 }
197 
execute_TPM_OwnerSetDisable(TPM_REQUEST * req,TPM_RESPONSE * rsp)198 static TPM_RESULT execute_TPM_OwnerSetDisable(TPM_REQUEST *req, TPM_RESPONSE *rsp)
199 {
200   BYTE *ptr;
201   UINT32 len;
202   BOOL disableState;
203   /* compute parameter digest */
204   tpm_compute_in_param_digest(req);
205   /* unmarshal input */
206   ptr = req->param;
207   len = req->paramSize;
208   if (tpm_unmarshal_BOOL(&ptr, &len, &disableState)
209       || len != 0) return TPM_BAD_PARAMETER;
210   /* execute command */
211   return TPM_OwnerSetDisable(disableState, &req->auth1);
212 }
213 
execute_TPM_PhysicalEnable(TPM_REQUEST * req,TPM_RESPONSE * rsp)214 static TPM_RESULT execute_TPM_PhysicalEnable(TPM_REQUEST *req, TPM_RESPONSE *rsp)
215 {
216   /* execute command */
217   return TPM_PhysicalEnable();
218 }
219 
execute_TPM_PhysicalDisable(TPM_REQUEST * req,TPM_RESPONSE * rsp)220 static TPM_RESULT execute_TPM_PhysicalDisable(TPM_REQUEST *req, TPM_RESPONSE *rsp)
221 {
222   /* execute command */
223   return TPM_PhysicalDisable();
224 }
225 
execute_TPM_PhysicalSetDeactivated(TPM_REQUEST * req,TPM_RESPONSE * rsp)226 static TPM_RESULT execute_TPM_PhysicalSetDeactivated(TPM_REQUEST *req, TPM_RESPONSE *rsp)
227 {
228   BYTE *ptr;
229   UINT32 len;
230   BOOL state;
231   /* unmarshal input */
232   ptr = req->param;
233   len = req->paramSize;
234   if (tpm_unmarshal_BOOL(&ptr, &len, &state)
235       || len != 0) return TPM_BAD_PARAMETER;
236   /* execute command */
237   return TPM_PhysicalSetDeactivated(state);
238 }
239 
execute_TPM_SetTempDeactivated(TPM_REQUEST * req,TPM_RESPONSE * rsp)240 static TPM_RESULT execute_TPM_SetTempDeactivated(TPM_REQUEST *req, TPM_RESPONSE *rsp)
241 {
242   /* compute parameter digest */
243   tpm_compute_in_param_digest(req);
244   /* execute command */
245   return TPM_SetTempDeactivated(&req->auth1);
246 }
247 
execute_TPM_SetOperatorAuth(TPM_REQUEST * req,TPM_RESPONSE * rsp)248 static TPM_RESULT execute_TPM_SetOperatorAuth(TPM_REQUEST *req, TPM_RESPONSE *rsp)
249 {
250   BYTE *ptr;
251   UINT32 len;
252   TPM_SECRET operatorAuth;
253   /* unmarshal input */
254   ptr = req->param;
255   len = req->paramSize;
256   if (tpm_unmarshal_TPM_SECRET(&ptr, &len, &operatorAuth)
257       || len != 0) return TPM_BAD_PARAMETER;
258   /* execute command */
259   return TPM_SetOperatorAuth(&operatorAuth);
260 }
261 
execute_TPM_TakeOwnership(TPM_REQUEST * req,TPM_RESPONSE * rsp)262 static TPM_RESULT execute_TPM_TakeOwnership(TPM_REQUEST *req, TPM_RESPONSE *rsp)
263 {
264   BYTE *ptr;
265   UINT32 len;
266   TPM_PROTOCOL_ID protocolID;
267   UINT32 encOwnerAuthSize;
268   BYTE *encOwnerAuth;
269   UINT32 encSrkAuthSize;
270   BYTE *encSrkAuth;
271   TPM_KEY srkParams;
272   TPM_KEY srkPub;
273   TPM_RESULT res;
274   /* compute parameter digest */
275   tpm_compute_in_param_digest(req);
276   /* unmarshal input */
277   ptr = req->param;
278   len = req->paramSize;
279   if (tpm_unmarshal_TPM_PROTOCOL_ID(&ptr, &len, &protocolID)
280       || tpm_unmarshal_UINT32(&ptr, &len, &encOwnerAuthSize)
281       || tpm_unmarshal_BLOB(&ptr, &len, &encOwnerAuth, encOwnerAuthSize)
282       || tpm_unmarshal_UINT32(&ptr, &len, &encSrkAuthSize)
283       || tpm_unmarshal_BLOB(&ptr, &len, &encSrkAuth, encSrkAuthSize)
284       || tpm_unmarshal_TPM_KEY(&ptr, &len, &srkParams)
285       || len != 0) return TPM_BAD_PARAMETER;
286   /* execute command */
287   res = TPM_TakeOwnership(protocolID, encOwnerAuthSize, encOwnerAuth,
288     encSrkAuthSize, encSrkAuth, &srkParams, &req->auth1, &srkPub);
289   if (res != TPM_SUCCESS) return res;
290   /* marshal output */
291   rsp->paramSize = len = sizeof_TPM_KEY(srkPub);
292   rsp->param = ptr = tpm_malloc(len);
293   if (ptr == NULL
294       || tpm_marshal_TPM_KEY(&ptr, &len, &srkPub)) {
295     tpm_free(rsp->param);
296     res = TPM_FAIL;
297   }
298   free_TPM_KEY(srkPub);
299   return res;
300 }
301 
execute_TPM_OwnerClear(TPM_REQUEST * req,TPM_RESPONSE * rsp)302 static TPM_RESULT execute_TPM_OwnerClear(TPM_REQUEST *req, TPM_RESPONSE *rsp)
303 {
304   /* compute parameter digest */
305   tpm_compute_in_param_digest(req);
306   /* execute command */
307   return TPM_OwnerClear(&req->auth1);
308 }
309 
execute_TPM_ForceClear(TPM_REQUEST * req,TPM_RESPONSE * rsp)310 static TPM_RESULT execute_TPM_ForceClear(TPM_REQUEST *req, TPM_RESPONSE *rsp)
311 {
312   /* execute command */
313   return TPM_ForceClear();
314 }
315 
execute_TPM_DisableOwnerClear(TPM_REQUEST * req,TPM_RESPONSE * rsp)316 static TPM_RESULT execute_TPM_DisableOwnerClear(TPM_REQUEST *req, TPM_RESPONSE *rsp)
317 {
318   /* compute parameter digest */
319   tpm_compute_in_param_digest(req);
320   /* execute command */
321   return TPM_DisableOwnerClear(&req->auth1);
322 }
323 
execute_TPM_DisableForceClear(TPM_REQUEST * req,TPM_RESPONSE * rsp)324 static TPM_RESULT execute_TPM_DisableForceClear(TPM_REQUEST *req, TPM_RESPONSE *rsp)
325 {
326   /* execute command */
327   return TPM_DisableForceClear();
328 }
329 
execute_TSC_PhysicalPresence(TPM_REQUEST * req,TPM_RESPONSE * rsp)330 static TPM_RESULT execute_TSC_PhysicalPresence(TPM_REQUEST *req, TPM_RESPONSE *rsp)
331 {
332   BYTE *ptr;
333   UINT32 len;
334   TPM_PHYSICAL_PRESENCE physicalPresence;
335   /* unmarshal input */
336   ptr = req->param;
337   len = req->paramSize;
338   if (tpm_unmarshal_TPM_PHYSICAL_PRESENCE(&ptr, &len, &physicalPresence)
339       || len != 0) return TPM_BAD_PARAMETER;
340   /* execute command */
341   return TSC_PhysicalPresence(physicalPresence);
342 }
343 
execute_TSC_ResetEstablishmentBit(TPM_REQUEST * req,TPM_RESPONSE * rsp)344 static TPM_RESULT execute_TSC_ResetEstablishmentBit(TPM_REQUEST *req, TPM_RESPONSE *rsp)
345 {
346   /* execute command */
347   return TSC_ResetEstablishmentBit();
348 }
349 
execute_TPM_GetCapability(TPM_REQUEST * req,TPM_RESPONSE * rsp)350 static TPM_RESULT execute_TPM_GetCapability(TPM_REQUEST *req, TPM_RESPONSE *rsp)
351 {
352   BYTE *ptr;
353   UINT32 len;
354   TPM_CAPABILITY_AREA capArea;
355   UINT32 subCapSize;
356   BYTE *subCap;
357   UINT32 respSize;
358   BYTE *resp = NULL;
359   TPM_RESULT res;
360   /* unmarshal input */
361   ptr = req->param;
362   len = req->paramSize;
363   if (tpm_unmarshal_TPM_CAPABILITY_AREA(&ptr, &len, &capArea)
364       || tpm_unmarshal_UINT32(&ptr, &len, &subCapSize)
365       || tpm_unmarshal_BLOB(&ptr, &len, &subCap, subCapSize)
366       || len != 0) return TPM_BAD_PARAMETER;
367   /* execute command */
368 #ifdef MTM_EMULATOR
369   res = MTM_GetCapability(capArea, subCapSize, subCap, &respSize, &resp);
370 #else
371   res = TPM_GetCapability(capArea, subCapSize, subCap, &respSize, &resp);
372 #endif
373   if (res != TPM_SUCCESS) return res;
374   /* marshal output */
375   rsp->paramSize = len = 4 + respSize;
376   rsp->param = ptr = tpm_malloc(len);
377   if (ptr == NULL
378       || tpm_marshal_UINT32(&ptr, &len, respSize)
379       || tpm_marshal_BLOB(&ptr, &len, resp, respSize)) {
380     tpm_free(rsp->param);
381     res = TPM_FAIL;
382   }
383   tpm_free(resp);
384   return res;
385 }
386 
execute_TPM_SetCapability(TPM_REQUEST * req,TPM_RESPONSE * rsp)387 static TPM_RESULT execute_TPM_SetCapability(TPM_REQUEST *req, TPM_RESPONSE *rsp)
388 {
389   BYTE *ptr;
390   UINT32 len;
391   TPM_CAPABILITY_AREA capArea;
392   UINT32 subCapSize, setValueSize;
393   BYTE *subCap, *setValue;
394   /* compute parameter digest */
395   tpm_compute_in_param_digest(req);
396   /* unmarshal input */
397   ptr = req->param;
398   len = req->paramSize;
399   if (tpm_unmarshal_TPM_CAPABILITY_AREA(&ptr, &len, &capArea)
400       || tpm_unmarshal_UINT32(&ptr, &len, &subCapSize)
401       || tpm_unmarshal_BLOB(&ptr, &len, &subCap, subCapSize)
402       || tpm_unmarshal_UINT32(&ptr, &len, &setValueSize)
403       || tpm_unmarshal_BLOB(&ptr, &len, &setValue, setValueSize)
404       || len != 0) return TPM_BAD_PARAMETER;
405   /* execute command */
406   return TPM_SetCapability(capArea, subCapSize, subCap, setValueSize, setValue, &req->auth1);
407 }
408 
execute_TPM_GetCapabilityOwner(TPM_REQUEST * req,TPM_RESPONSE * rsp)409 static TPM_RESULT execute_TPM_GetCapabilityOwner(TPM_REQUEST *req, TPM_RESPONSE *rsp)
410 {
411   BYTE *ptr;
412   UINT32 len;
413   UINT32 non_volatile_flags, volatile_flags;
414   TPM_VERSION version;
415   BYTE *resp = NULL;
416   TPM_RESULT res;
417   /* compute parameter digest */
418   tpm_compute_in_param_digest(req);
419   /* execute command */
420   res = TPM_GetCapabilityOwner(&req->auth1, &version, &non_volatile_flags, &volatile_flags);
421   if (res != TPM_SUCCESS) return res;
422   /* marshal output */
423   rsp->paramSize = len = 12;
424   rsp->param = ptr = tpm_malloc(len);
425   if (ptr == NULL
426       || tpm_marshal_TPM_VERSION(&ptr, &len, &version)
427       || tpm_marshal_UINT32(&ptr, &len, non_volatile_flags)
428       || tpm_marshal_UINT32(&ptr, &len, volatile_flags)) {
429     tpm_free(rsp->param);
430     res = TPM_FAIL;
431   }
432   tpm_free(resp);
433   return res;
434 }
435 
execute_TPM_GetAuditDigest(TPM_REQUEST * req,TPM_RESPONSE * rsp)436 static TPM_RESULT execute_TPM_GetAuditDigest(TPM_REQUEST *req, TPM_RESPONSE *rsp)
437 {
438   BYTE *ptr;
439   UINT32 len;
440   UINT32 startOrdinal;
441   TPM_COUNTER_VALUE counterValue;
442   TPM_DIGEST auditDigest;
443   BOOL more;
444   UINT32 ordSize;
445   UINT32 *ordList = NULL;
446   TPM_RESULT res;
447   /* unmarshal input */
448   ptr = req->param;
449   len = req->paramSize;
450   if (tpm_unmarshal_UINT32(&ptr, &len, &startOrdinal)
451       || len != 0) return TPM_BAD_PARAMETER;
452   /* execute command */
453   res = TPM_GetAuditDigest(startOrdinal, &counterValue, &auditDigest, &more, &ordSize, &ordList);
454   if (res != TPM_SUCCESS) return res;
455   /* marshal output */
456   rsp->paramSize = len = 10 + 20 + 1 + 4 + ordSize;
457   rsp->param = ptr = tpm_malloc(len);
458   if (ptr == NULL
459       || tpm_marshal_TPM_COUNTER_VALUE(&ptr, &len, &counterValue)
460       || tpm_marshal_TPM_DIGEST(&ptr, &len, &auditDigest)
461       || tpm_marshal_BOOL(&ptr, &len, more)
462       || tpm_marshal_UINT32(&ptr, &len, ordSize)
463       || tpm_marshal_UINT32_ARRAY(&ptr, &len, ordList, ordSize/4)) {
464     tpm_free(rsp->param);
465     res = TPM_FAIL;
466   }
467   tpm_free(ordList);
468   return res;
469 }
470 
execute_TPM_GetAuditDigestSigned(TPM_REQUEST * req,TPM_RESPONSE * rsp)471 static TPM_RESULT execute_TPM_GetAuditDigestSigned(TPM_REQUEST *req, TPM_RESPONSE *rsp)
472 {
473   BYTE *ptr;
474   UINT32 len;
475   TPM_KEY_HANDLE keyHandle;
476   BOOL closeAudit;
477   TPM_NONCE antiReplay;
478   TPM_COUNTER_VALUE counterValue;
479   TPM_DIGEST auditDigest;
480   TPM_DIGEST ordinalDigest;
481   UINT32 sigSize;
482   BYTE *sig = NULL;
483   TPM_RESULT res;
484   /* compute parameter digest */
485   tpm_compute_in_param_digest(req);
486   /* unmarshal input */
487   ptr = req->param;
488   len = req->paramSize;
489   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
490       || tpm_unmarshal_BOOL(&ptr, &len, &closeAudit)
491       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
492       || len != 0) return TPM_BAD_PARAMETER;
493   /* execute command */
494   res = TPM_GetAuditDigestSigned(keyHandle, closeAudit, &antiReplay, &req->auth1,
495     &counterValue, &auditDigest, &ordinalDigest, &sigSize, &sig);
496   if (res != TPM_SUCCESS) return res;
497   /* marshal output */
498   rsp->paramSize = len = 10 + 20 + 20 + 4 + sigSize;
499   rsp->param = ptr = tpm_malloc(len);
500   if (ptr == NULL
501       || tpm_marshal_TPM_COUNTER_VALUE(&ptr, &len, &counterValue)
502       || tpm_marshal_TPM_DIGEST(&ptr, &len, &auditDigest)
503       || tpm_marshal_TPM_DIGEST(&ptr, &len, &ordinalDigest)
504       || tpm_marshal_UINT32(&ptr, &len, sigSize)
505       || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
506     tpm_free(rsp->param);
507     res = TPM_FAIL;
508   }
509   tpm_free(sig);
510   return res;
511 }
512 
execute_TPM_SetOrdinalAuditStatus(TPM_REQUEST * req,TPM_RESPONSE * rsp)513 static TPM_RESULT execute_TPM_SetOrdinalAuditStatus(TPM_REQUEST *req, TPM_RESPONSE *rsp)
514 {
515   BYTE *ptr;
516   UINT32 len;
517   TPM_COMMAND_CODE ordinalToAudit;
518   BOOL auditState;
519   /* compute parameter digest */
520   tpm_compute_in_param_digest(req);
521   /* unmarshal input */
522   ptr = req->param;
523   len = req->paramSize;
524   if (tpm_unmarshal_TPM_COMMAND_CODE(&ptr, &len, &ordinalToAudit)
525       || tpm_unmarshal_BOOL(&ptr, &len, &auditState)
526       || len != 0) return TPM_BAD_PARAMETER;
527   /* execute command */
528   return TPM_SetOrdinalAuditStatus(ordinalToAudit, auditState, &req->auth1);
529 }
530 
execute_TPM_FieldUpgrade(TPM_REQUEST * req,TPM_RESPONSE * rsp)531 static TPM_RESULT execute_TPM_FieldUpgrade(TPM_REQUEST *req, TPM_RESPONSE *rsp)
532 {
533   /* execute command */
534   return TPM_FieldUpgrade();
535 }
536 
execute_TPM_SetRedirection(TPM_REQUEST * req,TPM_RESPONSE * rsp)537 static TPM_RESULT execute_TPM_SetRedirection(TPM_REQUEST *req, TPM_RESPONSE *rsp)
538 {
539   BYTE *ptr;
540   UINT32 len;
541   TPM_KEY_HANDLE keyHandle;
542   TPM_REDIR_COMMAND redirCmd;
543   UINT32 inputDataSize;
544   BYTE *inputData;
545   /* compute parameter digest */
546   tpm_compute_in_param_digest(req);
547   /* unmarshal input */
548   ptr = req->param;
549   len = req->paramSize;
550   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
551       || tpm_unmarshal_TPM_REDIR_COMMAND(&ptr, &len, &redirCmd)
552       || tpm_unmarshal_UINT32(&ptr, &len, &inputDataSize)
553       || tpm_unmarshal_BLOB(&ptr, &len, &inputData, inputDataSize)
554       || len != 0) return TPM_BAD_PARAMETER;
555   /* execute command */
556   return TPM_SetRedirection(keyHandle, redirCmd, inputDataSize, inputData, &req->auth1);
557 }
558 
execute_TPM_ResetLockValue(TPM_REQUEST * req,TPM_RESPONSE * rsp)559 static TPM_RESULT execute_TPM_ResetLockValue(TPM_REQUEST *req, TPM_RESPONSE *rsp)
560 {
561   /* compute parameter digest */
562   tpm_compute_in_param_digest(req);
563   /* execute command */
564   return TPM_ResetLockValue(&req->auth1);
565 }
566 
execute_TPM_Seal(TPM_REQUEST * req,TPM_RESPONSE * rsp)567 static TPM_RESULT execute_TPM_Seal(TPM_REQUEST *req, TPM_RESPONSE *rsp)
568 {
569   BYTE *ptr;
570   UINT32 len;
571   TPM_KEY_HANDLE keyHandle;
572   TPM_ENCAUTH encAuth;
573   UINT32 pcrInfoSize;
574   TPM_PCR_INFO pcrInfo;
575   UINT32 inDataSize;
576   BYTE *inData;
577   TPM_STORED_DATA sealedData;
578   TPM_RESULT res;
579   /* compute parameter digest */
580   tpm_compute_in_param_digest(req);
581   /* unmarshal input */
582   ptr = req->param;
583   len = req->paramSize;
584   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
585       || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &encAuth)
586       || tpm_unmarshal_UINT32(&ptr, &len, &pcrInfoSize)
587       || (pcrInfoSize > 0
588           && tpm_unmarshal_TPM_PCR_INFO(&ptr, &len, &pcrInfo))
589       || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize)
590       || tpm_unmarshal_BLOB(&ptr, &len, &inData, inDataSize)
591       || len != 0) return TPM_BAD_PARAMETER;
592   /* execute command */
593   res = TPM_Seal(keyHandle, &encAuth, pcrInfoSize, &pcrInfo, inDataSize, inData,
594     &req->auth1, &sealedData);
595   if (res != TPM_SUCCESS) return res;
596   /* marshal output */
597   rsp->paramSize = len = sizeof_TPM_STORED_DATA(sealedData);
598   rsp->param = ptr = tpm_malloc(len);
599   if (ptr == NULL
600       || tpm_marshal_TPM_STORED_DATA(&ptr, &len, &sealedData)) {
601     tpm_free(rsp->param);
602     res = TPM_FAIL;
603   }
604   free_TPM_STORED_DATA(sealedData);
605   return res;
606 }
607 
execute_TPM_Unseal(TPM_REQUEST * req,TPM_RESPONSE * rsp)608 static TPM_RESULT execute_TPM_Unseal(TPM_REQUEST *req, TPM_RESPONSE *rsp)
609 {
610   BYTE *ptr;
611   UINT32 len;
612   TPM_KEY_HANDLE parentHandle;
613   TPM_STORED_DATA inData;
614   UINT32 sealedDataSize;
615   BYTE *secret = NULL;
616   TPM_RESULT res;
617   /* compute parameter digest */
618   tpm_compute_in_param_digest(req);
619   /* unmarshal input */
620   ptr = req->param;
621   len = req->paramSize;
622   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
623       || tpm_unmarshal_TPM_STORED_DATA(&ptr, &len, &inData)
624       || len != 0) return TPM_BAD_PARAMETER;
625   /* execute command */
626   res = TPM_Unseal(parentHandle, &inData, &req->auth1, &req->auth2, &sealedDataSize, &secret);
627   if (res != TPM_SUCCESS) return res;
628   /* marshal output */
629   rsp->paramSize = len = 4 + sealedDataSize;
630   rsp->param = ptr = tpm_malloc(len);
631   if (ptr == NULL
632       || tpm_marshal_UINT32(&ptr, &len, sealedDataSize)
633       || tpm_marshal_BLOB(&ptr, &len, secret, sealedDataSize)) {
634     tpm_free(rsp->param);
635     res = TPM_FAIL;
636   }
637   tpm_free(secret);
638   return res;
639 }
640 
execute_TPM_UnBind(TPM_REQUEST * req,TPM_RESPONSE * rsp)641 static TPM_RESULT execute_TPM_UnBind(TPM_REQUEST *req, TPM_RESPONSE *rsp)
642 {
643   BYTE *ptr;
644   UINT32 len;
645   TPM_KEY_HANDLE keyHandle;
646   UINT32 inDataSize;
647   BYTE *inData;
648   UINT32 outDataSize;
649   BYTE *outData = NULL;
650   TPM_RESULT res;
651   /* compute parameter digest */
652   tpm_compute_in_param_digest(req);
653   /* unmarshal input */
654   ptr = req->param;
655   len = req->paramSize;
656   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
657       || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize)
658       || tpm_unmarshal_BLOB(&ptr, &len, &inData, inDataSize)
659       || len != 0) return TPM_BAD_PARAMETER;
660   /* execute command */
661   res = TPM_UnBind(keyHandle, inDataSize, inData, &req->auth1, &outDataSize, &outData);
662   if (res != TPM_SUCCESS) return res;
663   /* marshal output */
664   rsp->paramSize = len = 4 + outDataSize;
665   rsp->param = ptr = tpm_malloc(len);
666   if (ptr == NULL
667       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
668       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) {
669     tpm_free(rsp->param);
670     res = TPM_FAIL;
671   }
672   tpm_free(outData);
673   return res;
674 }
675 
execute_TPM_CreateWrapKey(TPM_REQUEST * req,TPM_RESPONSE * rsp)676 static TPM_RESULT execute_TPM_CreateWrapKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
677 {
678   BYTE *ptr;
679   UINT32 len;
680   TPM_KEY_HANDLE parentHandle;
681   TPM_ENCAUTH dataUsageAuth;
682   TPM_ENCAUTH dataMigrationAuth;
683   TPM_KEY keyInfo;
684   TPM_KEY wrappedKey;
685   TPM_RESULT res;
686   /* compute parameter digest */
687   tpm_compute_in_param_digest(req);
688   /* unmarshal input */
689   ptr = req->param;
690   len = req->paramSize;
691   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
692       || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &dataUsageAuth)
693       || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &dataMigrationAuth)
694       || tpm_unmarshal_TPM_KEY(&ptr, &len, &keyInfo)
695       || len != 0) return TPM_BAD_PARAMETER;
696   /* execute command */
697   res = TPM_CreateWrapKey(parentHandle, &dataUsageAuth, &dataMigrationAuth,
698     &keyInfo, &req->auth1, &wrappedKey);
699   if (res != TPM_SUCCESS) return res;
700   /* marshal output */
701   rsp->paramSize = len = sizeof_TPM_KEY(wrappedKey);
702   rsp->param = ptr = tpm_malloc(len);
703   if (ptr == NULL
704       || tpm_marshal_TPM_KEY(&ptr, &len, &wrappedKey)) {
705     tpm_free(rsp->param);
706     res = TPM_FAIL;
707   }
708   free_TPM_KEY(wrappedKey);
709   return res;
710 }
711 
execute_TPM_LoadKey(TPM_REQUEST * req,TPM_RESPONSE * rsp)712 static TPM_RESULT execute_TPM_LoadKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
713 {
714   BYTE *ptr;
715   UINT32 len;
716   TPM_KEY_HANDLE parentHandle;
717   TPM_KEY inKey;
718   TPM_KEY_HANDLE inkeyHandle;
719   TPM_RESULT res;
720   /* compute parameter digest */
721   tpm_compute_in_param_digest(req);
722   /* unmarshal input */
723   ptr = req->param;
724   len = req->paramSize;
725   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
726       || tpm_unmarshal_TPM_KEY(&ptr, &len, &inKey)
727       || len != 0) return TPM_BAD_PARAMETER;
728   /* execute command */
729   res = TPM_LoadKey(parentHandle, &inKey, &req->auth1, &inkeyHandle);
730   if (res != TPM_SUCCESS) return res;
731   /* marshal output */
732   rsp->paramSize = len = 4;
733   rsp->param = ptr = tpm_malloc(len);
734   if (ptr == NULL
735       || tpm_marshal_TPM_KEY_HANDLE(&ptr, &len, inkeyHandle)) {
736     tpm_free(rsp->param);
737     res = TPM_FAIL;
738   }
739   return res;
740 }
741 
execute_TPM_LoadKey2(TPM_REQUEST * req,TPM_RESPONSE * rsp)742 static TPM_RESULT execute_TPM_LoadKey2(TPM_REQUEST *req, TPM_RESPONSE *rsp)
743 {
744   BYTE *ptr;
745   UINT32 len;
746   TPM_KEY_HANDLE parentHandle;
747   TPM_KEY inKey;
748   TPM_KEY_HANDLE inkeyHandle;
749   TPM_RESULT res;
750   /* compute parameter digest */
751   tpm_compute_in_param_digest(req);
752   /* unmarshal input */
753   ptr = req->param;
754   len = req->paramSize;
755   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
756       || tpm_unmarshal_TPM_KEY(&ptr, &len, &inKey)
757       || len != 0) return TPM_BAD_PARAMETER;
758   /* execute command */
759   res = TPM_LoadKey2(parentHandle, &inKey, &req->auth1, &inkeyHandle);
760   if (res != TPM_SUCCESS) return res;
761   /* marshal output */
762   rsp->paramSize = len = 4;
763   rsp->param = ptr = tpm_malloc(len);
764   if (ptr == NULL
765       || tpm_marshal_TPM_KEY_HANDLE(&ptr, &len, inkeyHandle)) {
766     tpm_free(rsp->param);
767     res = TPM_FAIL;
768   }
769   return res;
770 }
771 
execute_TPM_GetPubKey(TPM_REQUEST * req,TPM_RESPONSE * rsp)772 static TPM_RESULT execute_TPM_GetPubKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
773 {
774   BYTE *ptr;
775   UINT32 len;
776   TPM_KEY_HANDLE keyHandle;
777   TPM_PUBKEY pubKey;
778   TPM_RESULT res;
779   /* compute parameter digest */
780   tpm_compute_in_param_digest(req);
781   /* unmarshal input */
782   ptr = req->param;
783   len = req->paramSize;
784   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
785       || len != 0) return TPM_BAD_PARAMETER;
786   /* execute command */
787   res = TPM_GetPubKey(keyHandle, &req->auth1, &pubKey);
788   if (res != TPM_SUCCESS) return res;
789   /* marshal output */
790   rsp->paramSize = len = sizeof_TPM_PUBKEY(pubKey);
791   rsp->param = ptr = tpm_malloc(len);
792   if (ptr == NULL
793       || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubKey)) {
794     tpm_free(rsp->param);
795     res = TPM_FAIL;
796   }
797   free_TPM_PUBKEY(pubKey);
798   return res;
799 }
800 
execute_TPM_Sealx(TPM_REQUEST * req,TPM_RESPONSE * rsp)801 static TPM_RESULT execute_TPM_Sealx(TPM_REQUEST *req, TPM_RESPONSE *rsp)
802 {
803   BYTE *ptr;
804   UINT32 len;
805   TPM_KEY_HANDLE keyHandle;
806   TPM_ENCAUTH encAuth;
807   UINT32 pcrInfoSize;
808   TPM_PCR_INFO pcrInfo;
809   UINT32 inDataSize;
810   BYTE *inData;
811   TPM_STORED_DATA sealedData;
812   TPM_RESULT res;
813   /* compute parameter digest */
814   tpm_compute_in_param_digest(req);
815   /* unmarshal input */
816   ptr = req->param;
817   len = req->paramSize;
818   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
819       || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &encAuth)
820       || tpm_unmarshal_UINT32(&ptr, &len, &pcrInfoSize)
821       || (pcrInfoSize > 0
822           && tpm_unmarshal_TPM_PCR_INFO(&ptr, &len, &pcrInfo))
823       || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize)
824       || tpm_unmarshal_BLOB(&ptr, &len, &inData, inDataSize)
825       || len != 0) return TPM_BAD_PARAMETER;
826   /* execute command */
827   res = TPM_Sealx(keyHandle, &encAuth, pcrInfoSize, &pcrInfo, inDataSize, inData,
828     &req->auth1, &sealedData);
829   if (res != TPM_SUCCESS) return res;
830   /* marshal output */
831   rsp->paramSize = len = sizeof_TPM_STORED_DATA(sealedData);
832   rsp->param = ptr = tpm_malloc(len);
833   if (ptr == NULL
834       || tpm_marshal_TPM_STORED_DATA(&ptr, &len, &sealedData)) {
835     tpm_free(rsp->param);
836     res = TPM_FAIL;
837   }
838   free_TPM_STORED_DATA(sealedData);
839   return res;
840 }
841 
execute_TPM_CreateMigrationBlob(TPM_REQUEST * req,TPM_RESPONSE * rsp)842 static TPM_RESULT execute_TPM_CreateMigrationBlob(TPM_REQUEST *req, TPM_RESPONSE *rsp)
843 {
844   BYTE *ptr;
845   UINT32 len;
846   TPM_KEY_HANDLE parentHandle;
847   TPM_MIGRATE_SCHEME migrationType;
848   TPM_MIGRATIONKEYAUTH migrationKeyAuth;
849   UINT32 encDataSize;
850   BYTE *encData;
851   UINT32 randomSize;
852   BYTE *random = NULL;
853   UINT32 outDataSize;
854   BYTE *outData = NULL;
855   TPM_RESULT res;
856   /* compute parameter digest */
857   tpm_compute_in_param_digest(req);
858   /* unmarshal input */
859   ptr = req->param;
860   len = req->paramSize;
861   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
862       || tpm_unmarshal_TPM_MIGRATE_SCHEME(&ptr, &len, &migrationType)
863       || tpm_unmarshal_TPM_MIGRATIONKEYAUTH(&ptr, &len, &migrationKeyAuth)
864       || tpm_unmarshal_UINT32(&ptr, &len, &encDataSize)
865       || tpm_unmarshal_BLOB(&ptr, &len, &encData, encDataSize)
866       || len != 0) return TPM_BAD_PARAMETER;
867   /* execute command */
868   res = TPM_CreateMigrationBlob(parentHandle, migrationType, &migrationKeyAuth, encDataSize,
869     encData, &req->auth1, &req->auth2, &randomSize, &random, &outDataSize, &outData);
870   if (res != TPM_SUCCESS) return res;
871   /* marshal output */
872   rsp->paramSize = len = 4 + randomSize + 4 + outDataSize;
873   rsp->param = ptr = tpm_malloc(len);
874   if (ptr == NULL
875       || tpm_marshal_UINT32(&ptr, &len, randomSize)
876       || tpm_marshal_BLOB(&ptr, &len, random, randomSize)
877       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
878       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) {
879     tpm_free(rsp->param);
880     res = TPM_FAIL;
881   }
882   tpm_free(random);
883   tpm_free(outData);
884   return res;
885 }
886 
execute_TPM_ConvertMigrationBlob(TPM_REQUEST * req,TPM_RESPONSE * rsp)887 static TPM_RESULT execute_TPM_ConvertMigrationBlob(TPM_REQUEST *req, TPM_RESPONSE *rsp)
888 {
889   BYTE *ptr;
890   UINT32 len;
891   TPM_KEY_HANDLE parentHandle;
892   UINT32 inDataSize;
893   BYTE *inData;
894   UINT32 randomSize;
895   BYTE *random;
896   UINT32 outDataSize;
897   BYTE *outData = NULL;
898   TPM_RESULT res;
899   /* compute parameter digest */
900   tpm_compute_in_param_digest(req);
901   /* unmarshal input */
902   ptr = req->param;
903   len = req->paramSize;
904   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
905       || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize)
906       || tpm_unmarshal_BLOB(&ptr, &len, &inData, inDataSize)
907       || tpm_unmarshal_UINT32(&ptr, &len, &randomSize)
908       || tpm_unmarshal_BLOB(&ptr, &len, &random, randomSize)
909       || len != 0) return TPM_BAD_PARAMETER;
910   /* execute command */
911   res = TPM_ConvertMigrationBlob(parentHandle, inDataSize, inData, randomSize,
912     random, &req->auth1, &outDataSize, &outData);
913   if (res != TPM_SUCCESS) return res;
914   /* marshal output */
915   rsp->paramSize = len = 4 + outDataSize;
916   rsp->param = ptr = tpm_malloc(len);
917   if (ptr == NULL
918       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
919       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) {
920     tpm_free(rsp->param);
921     res = TPM_FAIL;
922   }
923   tpm_free(outData);
924   return res;
925 }
926 
execute_TPM_AuthorizeMigrationKey(TPM_REQUEST * req,TPM_RESPONSE * rsp)927 static TPM_RESULT execute_TPM_AuthorizeMigrationKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
928 {
929   BYTE *ptr;
930   UINT32 len;
931   TPM_MIGRATE_SCHEME migrateScheme;
932   TPM_PUBKEY migrationKey;
933   TPM_MIGRATIONKEYAUTH outData;
934   TPM_RESULT res;
935   /* compute parameter digest */
936   tpm_compute_in_param_digest(req);
937   /* unmarshal input */
938   ptr = req->param;
939   len = req->paramSize;
940   if (tpm_unmarshal_TPM_MIGRATE_SCHEME(&ptr, &len, &migrateScheme)
941       || tpm_unmarshal_TPM_PUBKEY(&ptr, &len, &migrationKey)
942       || len != 0) return TPM_BAD_PARAMETER;
943   /* execute command */
944   res = TPM_AuthorizeMigrationKey(migrateScheme, &migrationKey, &req->auth1, &outData);
945   if (res != TPM_SUCCESS) return res;
946   /* marshal output */
947   rsp->paramSize = len = sizeof_TPM_MIGRATIONKEYAUTH(outData);
948   rsp->param = ptr = tpm_malloc(len);
949   if (ptr == NULL
950       || tpm_marshal_TPM_MIGRATIONKEYAUTH(&ptr, &len, &outData)) {
951     tpm_free(rsp->param);
952     res = TPM_FAIL;
953   }
954   free_TPM_MIGRATIONKEYAUTH(outData);
955   return res;
956 }
957 
execute_TPM_MigrateKey(TPM_REQUEST * req,TPM_RESPONSE * rsp)958 static TPM_RESULT execute_TPM_MigrateKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
959 {
960   BYTE *ptr;
961   UINT32 len;
962   TPM_KEY_HANDLE maKeyHandle;
963   TPM_PUBKEY pubKey;
964   UINT32 inDataSize;
965   BYTE *inData;
966   UINT32 outDataSize;
967   BYTE *outData = NULL;
968   TPM_RESULT res;
969   /* compute parameter digest */
970   tpm_compute_in_param_digest(req);
971   /* unmarshal input */
972   ptr = req->param;
973   len = req->paramSize;
974   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &maKeyHandle)
975       || tpm_unmarshal_TPM_PUBKEY(&ptr, &len, &pubKey)
976       || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize)
977       || tpm_unmarshal_BLOB(&ptr, &len, &inData, inDataSize)
978       || len != 0) return TPM_BAD_PARAMETER;
979   /* execute command */
980   res = TPM_MigrateKey(maKeyHandle, &pubKey, inDataSize, inData,
981     &req->auth1, &outDataSize, &outData);
982   if (res != TPM_SUCCESS) return res;
983   /* marshal output */
984   rsp->paramSize = len = 4 + outDataSize;
985   rsp->param = ptr = tpm_malloc(len);
986   if (ptr == NULL
987       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
988       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) {
989     tpm_free(rsp->param);
990     res = TPM_FAIL;
991   }
992   tpm_free(outData);
993   return res;
994 }
995 
execute_TPM_CMK_SetRestrictions(TPM_REQUEST * req,TPM_RESPONSE * rsp)996 static TPM_RESULT execute_TPM_CMK_SetRestrictions(TPM_REQUEST *req, TPM_RESPONSE *rsp)
997 {
998   BYTE *ptr;
999   UINT32 len;
1000   TPM_CMK_DELEGATE restriction;
1001   /* compute parameter digest */
1002   tpm_compute_in_param_digest(req);
1003   /* unmarshal input */
1004   ptr = req->param;
1005   len = req->paramSize;
1006   if (tpm_unmarshal_TPM_CMK_DELEGATE(&ptr, &len, &restriction)
1007       || len != 0) return TPM_BAD_PARAMETER;
1008   /* execute command */
1009   return TPM_CMK_SetRestrictions(restriction, &req->auth1);
1010 }
1011 
execute_TPM_CMK_ApproveMA(TPM_REQUEST * req,TPM_RESPONSE * rsp)1012 static TPM_RESULT execute_TPM_CMK_ApproveMA(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1013 {
1014   BYTE *ptr;
1015   UINT32 len;
1016   TPM_DIGEST migrationAuthorityDigest;
1017   TPM_HMAC outData;
1018   TPM_RESULT res;
1019   /* compute parameter digest */
1020   tpm_compute_in_param_digest(req);
1021   /* unmarshal input */
1022   ptr = req->param;
1023   len = req->paramSize;
1024   if (tpm_unmarshal_TPM_DIGEST(&ptr, &len, &migrationAuthorityDigest)
1025       || len != 0) return TPM_BAD_PARAMETER;
1026   /* execute command */
1027   res = TPM_CMK_ApproveMA(&migrationAuthorityDigest, &req->auth1, &outData);
1028   if (res != TPM_SUCCESS) return res;
1029   /* marshal output */
1030   rsp->paramSize = len = 20;
1031   rsp->param = ptr = tpm_malloc(len);
1032   if (ptr == NULL
1033       || tpm_marshal_TPM_HMAC(&ptr, &len, &outData)) {
1034     tpm_free(rsp->param);
1035     res = TPM_FAIL;
1036   }
1037   return res;
1038 }
1039 
execute_TPM_CMK_CreateKey(TPM_REQUEST * req,TPM_RESPONSE * rsp)1040 static TPM_RESULT execute_TPM_CMK_CreateKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1041 {
1042   BYTE *ptr;
1043   UINT32 len;
1044   TPM_KEY_HANDLE parentHandle;
1045   TPM_ENCAUTH dataUsageAuth;
1046   TPM_KEY keyInfo;
1047   TPM_HMAC migrationAuthorityApproval;
1048   TPM_DIGEST migrationAuthorityDigest;
1049   TPM_KEY wrappedKey;
1050   TPM_RESULT res;
1051   /* compute parameter digest */
1052   tpm_compute_in_param_digest(req);
1053   /* unmarshal input */
1054   ptr = req->param;
1055   len = req->paramSize;
1056   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
1057       || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &dataUsageAuth)
1058       || tpm_unmarshal_TPM_KEY(&ptr, &len, &keyInfo)
1059       || tpm_unmarshal_TPM_HMAC(&ptr, &len, &migrationAuthorityApproval)
1060       || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &migrationAuthorityDigest)
1061       || len != 0) return TPM_BAD_PARAMETER;
1062   /* execute command */
1063   res = TPM_CMK_CreateKey(parentHandle, &dataUsageAuth, &keyInfo, &migrationAuthorityApproval,
1064     &migrationAuthorityDigest, &req->auth1, &req->auth2, &wrappedKey);
1065   if (res != TPM_SUCCESS) return res;
1066   /* marshal output */
1067   rsp->paramSize = len = sizeof_TPM_KEY(wrappedKey);
1068   rsp->param = ptr = tpm_malloc(len);
1069   if (ptr == NULL
1070       || tpm_marshal_TPM_KEY(&ptr, &len, &wrappedKey)) {
1071     tpm_free(rsp->param);
1072     res = TPM_FAIL;
1073   }
1074   free_TPM_KEY(wrappedKey);
1075   return res;
1076 }
1077 
execute_TPM_CMK_CreateTicket(TPM_REQUEST * req,TPM_RESPONSE * rsp)1078 static TPM_RESULT execute_TPM_CMK_CreateTicket(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1079 {
1080   BYTE *ptr;
1081   UINT32 len;
1082   TPM_PUBKEY verificationKey;
1083   TPM_DIGEST signedData;
1084   UINT32 signatureValueSize;
1085   BYTE *signatureValue;
1086   TPM_DIGEST sigTicket;
1087   TPM_RESULT res;
1088   /* compute parameter digest */
1089   tpm_compute_in_param_digest(req);
1090   /* unmarshal input */
1091   ptr = req->param;
1092   len = req->paramSize;
1093   if (tpm_unmarshal_TPM_PUBKEY(&ptr, &len, &verificationKey)
1094       || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &signedData)
1095       || tpm_unmarshal_UINT32(&ptr, &len, &signatureValueSize)
1096       || tpm_unmarshal_BLOB(&ptr, &len, &signatureValue, signatureValueSize)
1097       || len != 0) return TPM_BAD_PARAMETER;
1098   /* execute command */
1099   res = TPM_CMK_CreateTicket(&verificationKey, &signedData, signatureValueSize,
1100     signatureValue, &req->auth1, &sigTicket);
1101   if (res != TPM_SUCCESS) return res;
1102   /* marshal output */
1103   rsp->paramSize = len = 20;
1104   rsp->param = ptr = tpm_malloc(len);
1105   if (ptr == NULL
1106       || tpm_marshal_TPM_DIGEST(&ptr, &len, &sigTicket)) {
1107     tpm_free(rsp->param);
1108     res = TPM_FAIL;
1109   }
1110   return res;
1111 }
1112 
execute_TPM_CMK_CreateBlob(TPM_REQUEST * req,TPM_RESPONSE * rsp)1113 static TPM_RESULT execute_TPM_CMK_CreateBlob(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1114 {
1115   BYTE *ptr;
1116   UINT32 len;
1117   TPM_KEY_HANDLE parentHandle;
1118   TPM_MIGRATE_SCHEME migrationType;
1119   TPM_MIGRATIONKEYAUTH migrationKeyAuth;
1120   TPM_DIGEST pubSourceKeyDigest;
1121   UINT32 msaListSize;
1122   TPM_MSA_COMPOSITE msaList;
1123   UINT32 restrictTicketSize;
1124   TPM_CMK_AUTH restrictTicket;
1125   UINT32 sigTicketSize;
1126   TPM_HMAC sigTicket;
1127   UINT32 encDataSize;
1128   BYTE *encData;
1129   UINT32 randomSize;
1130   BYTE *random = NULL;
1131   UINT32 outDataSize;
1132   BYTE *outData = NULL;
1133   TPM_RESULT res;
1134   /* compute parameter digest */
1135   tpm_compute_in_param_digest(req);
1136   /* unmarshal input */
1137   ptr = req->param;
1138   len = req->paramSize;
1139   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
1140       || tpm_unmarshal_TPM_MIGRATE_SCHEME(&ptr, &len, &migrationType)
1141       || tpm_unmarshal_TPM_MIGRATIONKEYAUTH(&ptr, &len, &migrationKeyAuth)
1142       || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &pubSourceKeyDigest)
1143       || tpm_unmarshal_UINT32(&ptr, &len, &msaListSize)
1144       || tpm_unmarshal_TPM_MSA_COMPOSITE(&ptr, &len, &msaList)
1145       || tpm_unmarshal_UINT32(&ptr, &len, &restrictTicketSize)
1146       || (restrictTicketSize > 0
1147           && tpm_unmarshal_TPM_CMK_AUTH(&ptr, &len, &restrictTicket))
1148       || tpm_unmarshal_UINT32(&ptr, &len, &sigTicketSize)
1149       || (sigTicketSize > 0
1150           && tpm_unmarshal_TPM_HMAC(&ptr, &len, &sigTicket))
1151       || tpm_unmarshal_UINT32(&ptr, &len, &encDataSize)
1152       || tpm_unmarshal_BLOB(&ptr, &len, &encData, encDataSize)
1153       || len != 0) return TPM_BAD_PARAMETER;
1154   /* execute command */
1155   res = TPM_CMK_CreateBlob(parentHandle, migrationType, &migrationKeyAuth,
1156     &pubSourceKeyDigest, &msaList,
1157     restrictTicketSize > 0 ? &restrictTicket : NULL,
1158     sigTicketSize > 0 ? &sigTicket : NULL,
1159     encDataSize, encData, &req->auth1, &randomSize, &random, &outDataSize, &outData);
1160   if (res != TPM_SUCCESS) return res;
1161   /* marshal output */
1162   rsp->paramSize = len = 4 + randomSize + 4 + outDataSize;
1163   rsp->param = ptr = tpm_malloc(len);
1164   if (ptr == NULL
1165       || tpm_marshal_UINT32(&ptr, &len, randomSize)
1166       || tpm_marshal_BLOB(&ptr, &len, random, randomSize)
1167       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
1168       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) {
1169     tpm_free(rsp->param);
1170     res = TPM_FAIL;
1171   }
1172   tpm_free(random);
1173   tpm_free(outData);
1174   return res;
1175 }
1176 
execute_TPM_CMK_ConvertMigration(TPM_REQUEST * req,TPM_RESPONSE * rsp)1177 static TPM_RESULT execute_TPM_CMK_ConvertMigration(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1178 {
1179   BYTE *ptr;
1180   UINT32 len;
1181   TPM_KEY_HANDLE parentHandle;
1182   TPM_CMK_AUTH restrictTicket;
1183   TPM_HMAC sigTicket;
1184   TPM_KEY migratedKey;
1185   UINT32 msaListSize;
1186   TPM_MSA_COMPOSITE msaList;
1187   UINT32 randomSize;
1188   BYTE *random;
1189   UINT32 outDataSize;
1190   BYTE *outData = NULL;
1191   TPM_RESULT res;
1192   /* compute parameter digest */
1193   tpm_compute_in_param_digest(req);
1194   /* unmarshal input */
1195   ptr = req->param;
1196   len = req->paramSize;
1197   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
1198       || tpm_unmarshal_TPM_CMK_AUTH(&ptr, &len, &restrictTicket)
1199       || tpm_unmarshal_TPM_HMAC(&ptr, &len, &sigTicket)
1200       || tpm_unmarshal_TPM_KEY(&ptr, &len, &migratedKey)
1201       || tpm_unmarshal_UINT32(&ptr, &len, &msaListSize)
1202       || tpm_unmarshal_TPM_MSA_COMPOSITE(&ptr, &len, &msaList)
1203       || tpm_unmarshal_UINT32(&ptr, &len, &randomSize)
1204       || tpm_unmarshal_BLOB(&ptr, &len, &random, randomSize)
1205       || len != 0) return TPM_BAD_PARAMETER;
1206   /* execute command */
1207   res = TPM_CMK_ConvertMigration(parentHandle, &restrictTicket, &sigTicket,
1208     &migratedKey, &msaList, randomSize, random, &req->auth1, &outDataSize,
1209     &outData);
1210   if (res != TPM_SUCCESS) return res;
1211   /* marshal output */
1212   rsp->paramSize = len = 4 + outDataSize;
1213   rsp->param = ptr = tpm_malloc(len);
1214   if (ptr == NULL
1215       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
1216       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) {
1217     tpm_free(rsp->param);
1218     res = TPM_FAIL;
1219   }
1220   tpm_free(outData);
1221   return res;
1222 }
1223 
execute_TPM_CreateMaintenanceArchive(TPM_REQUEST * req,TPM_RESPONSE * rsp)1224 static TPM_RESULT execute_TPM_CreateMaintenanceArchive(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1225 {
1226   BYTE *ptr;
1227   UINT32 len;
1228   BOOL generateRandom;
1229   UINT32 randomSize;
1230   BYTE *random = NULL;
1231   UINT32 archiveSize;
1232   BYTE *archive = NULL;
1233   TPM_RESULT res;
1234   /* compute parameter digest */
1235   tpm_compute_in_param_digest(req);
1236   /* unmarshal input */
1237   ptr = req->param;
1238   len = req->paramSize;
1239   if (tpm_unmarshal_BOOL(&ptr, &len, &generateRandom)
1240       || len != 0) return TPM_BAD_PARAMETER;
1241   /* execute command */
1242   res = TPM_CreateMaintenanceArchive(generateRandom, &req->auth1, &randomSize,
1243     &random, &archiveSize, &archive);
1244   if (res != TPM_SUCCESS) return res;
1245   /* marshal output */
1246   rsp->paramSize = len = 4 + randomSize + 4 + archiveSize;
1247   rsp->param = ptr = tpm_malloc(len);
1248   if (ptr == NULL
1249       || tpm_marshal_UINT32(&ptr, &len, randomSize)
1250       || tpm_marshal_BLOB(&ptr, &len, random, randomSize)
1251       || tpm_marshal_UINT32(&ptr, &len, archiveSize)
1252       || tpm_marshal_BLOB(&ptr, &len, archive, archiveSize)) {
1253     tpm_free(rsp->param);
1254     res = TPM_FAIL;
1255   }
1256   tpm_free(random);
1257   tpm_free(archive);
1258   return res;
1259 }
1260 
execute_TPM_LoadMaintenanceArchive(TPM_REQUEST * req,TPM_RESPONSE * rsp)1261 static TPM_RESULT execute_TPM_LoadMaintenanceArchive(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1262 {
1263   BYTE *ptr;
1264   UINT32 len;
1265   UINT32 archiveSize;
1266   BYTE *archive;
1267   UINT32 sigSize;
1268   BYTE *sig;
1269   UINT32 randomSize;
1270   BYTE *random;
1271   /* compute parameter digest */
1272   tpm_compute_in_param_digest(req);
1273   /* unmarshal input */
1274   ptr = req->param;
1275   len = req->paramSize;
1276   if (tpm_unmarshal_UINT32(&ptr, &len, &archiveSize)
1277       || tpm_unmarshal_BLOB(&ptr, &len, &archive, archiveSize)
1278       || tpm_unmarshal_UINT32(&ptr, &len, &sigSize)
1279       || tpm_unmarshal_BLOB(&ptr, &len, &sig, sigSize)
1280       || tpm_unmarshal_UINT32(&ptr, &len, &randomSize)
1281       || tpm_unmarshal_BLOB(&ptr, &len, &random, randomSize)
1282       || len != 0) return TPM_BAD_PARAMETER;
1283   /* execute command */
1284   return TPM_LoadMaintenanceArchive(archiveSize, archive, sigSize, sig,
1285    randomSize, random, &req->auth1);
1286 }
1287 
execute_TPM_KillMaintenanceFeature(TPM_REQUEST * req,TPM_RESPONSE * rsp)1288 static TPM_RESULT execute_TPM_KillMaintenanceFeature(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1289 {
1290   /* compute parameter digest */
1291   tpm_compute_in_param_digest(req);
1292   /* execute command */
1293   return TPM_KillMaintenanceFeature(&req->auth1);
1294 }
1295 
execute_TPM_LoadManuMaintPub(TPM_REQUEST * req,TPM_RESPONSE * rsp)1296 static TPM_RESULT execute_TPM_LoadManuMaintPub(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1297 {
1298   BYTE *ptr;
1299   UINT32 len;
1300   TPM_NONCE antiReplay;
1301   TPM_PUBKEY pubKey;
1302   TPM_DIGEST checksum;
1303   TPM_RESULT res;
1304   /* unmarshal input */
1305   ptr = req->param;
1306   len = req->paramSize;
1307   if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
1308       || tpm_unmarshal_TPM_PUBKEY(&ptr, &len, &pubKey)
1309       || len != 0) return TPM_BAD_PARAMETER;
1310   /* execute command */
1311   res = TPM_LoadManuMaintPub(&antiReplay, &pubKey, &checksum);
1312   if (res != TPM_SUCCESS) return res;
1313   /* marshal output */
1314   rsp->paramSize = len = 20;
1315   rsp->param = ptr = tpm_malloc(len);
1316   if (ptr == NULL
1317       || tpm_marshal_TPM_DIGEST(&ptr, &len, &checksum)) {
1318     tpm_free(rsp->param);
1319     res = TPM_FAIL;
1320   }
1321   return res;
1322 }
1323 
execute_TPM_ReadManuMaintPub(TPM_REQUEST * req,TPM_RESPONSE * rsp)1324 static TPM_RESULT execute_TPM_ReadManuMaintPub(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1325 {
1326   BYTE *ptr;
1327   UINT32 len;
1328   TPM_NONCE antiReplay;
1329   TPM_DIGEST checksum;
1330   TPM_RESULT res;
1331   /* unmarshal input */
1332   ptr = req->param;
1333   len = req->paramSize;
1334   if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
1335       || len != 0) return TPM_BAD_PARAMETER;
1336   /* execute command */
1337   res = TPM_ReadManuMaintPub(&antiReplay, &checksum);
1338   if (res != TPM_SUCCESS) return res;
1339   /* marshal output */
1340   rsp->paramSize = len = 20;
1341   rsp->param = ptr = tpm_malloc(len);
1342   if (ptr == NULL
1343       || tpm_marshal_TPM_DIGEST(&ptr, &len, &checksum)) {
1344     tpm_free(rsp->param);
1345     res = TPM_FAIL;
1346   }
1347   return res;
1348 }
1349 
execute_TPM_SHA1Start(TPM_REQUEST * req,TPM_RESPONSE * rsp)1350 static TPM_RESULT execute_TPM_SHA1Start(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1351 {
1352   BYTE *ptr;
1353   UINT32 len;
1354   UINT32 maxNumBytes;
1355   TPM_RESULT res;
1356   /* execute command */
1357   res = TPM_SHA1Start(&maxNumBytes);
1358   if (res != TPM_SUCCESS) return res;
1359   /* marshal output */
1360   rsp->paramSize = len = 4;
1361   rsp->param = ptr = tpm_malloc(len);
1362   if (ptr == NULL
1363       || tpm_marshal_UINT32(&ptr, &len, maxNumBytes)) {
1364     tpm_free(rsp->param);
1365     res = TPM_FAIL;
1366   }
1367   return res;
1368 }
1369 
execute_TPM_SHA1Update(TPM_REQUEST * req,TPM_RESPONSE * rsp)1370 static TPM_RESULT execute_TPM_SHA1Update(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1371 {
1372   BYTE *ptr;
1373   UINT32 len;
1374   UINT32 numBytes;
1375   BYTE *hashData;
1376   /* unmarshal input */
1377   ptr = req->param;
1378   len = req->paramSize;
1379   if (tpm_unmarshal_UINT32(&ptr, &len, &numBytes)
1380       || tpm_unmarshal_BLOB(&ptr, &len, &hashData, numBytes)
1381       || len != 0) return TPM_BAD_PARAMETER;
1382   /* execute command */
1383   return TPM_SHA1Update(numBytes, hashData);
1384 }
1385 
execute_TPM_SHA1Complete(TPM_REQUEST * req,TPM_RESPONSE * rsp)1386 static TPM_RESULT execute_TPM_SHA1Complete(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1387 {
1388   BYTE *ptr;
1389   UINT32 len;
1390   UINT32 hashDataSize;
1391   BYTE *hashData;
1392   TPM_DIGEST hashValue;
1393   TPM_RESULT res;
1394   /* unmarshal input */
1395   ptr = req->param;
1396   len = req->paramSize;
1397   if (tpm_unmarshal_UINT32(&ptr, &len, &hashDataSize)
1398       || tpm_unmarshal_BLOB(&ptr, &len, &hashData, hashDataSize)
1399       || len != 0) return TPM_BAD_PARAMETER;
1400   /* execute command */
1401   res = TPM_SHA1Complete(hashDataSize, hashData, &hashValue);
1402   if (res != TPM_SUCCESS) return res;
1403   /* marshal output */
1404   rsp->paramSize = len = 20;
1405   rsp->param = ptr = tpm_malloc(len);
1406   if (ptr == NULL
1407       || tpm_marshal_TPM_DIGEST(&ptr, &len, &hashValue)) {
1408     tpm_free(rsp->param);
1409     res = TPM_FAIL;
1410   }
1411   return res;
1412 }
1413 
execute_TPM_SHA1CompleteExtend(TPM_REQUEST * req,TPM_RESPONSE * rsp)1414 static TPM_RESULT execute_TPM_SHA1CompleteExtend(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1415 {
1416   BYTE *ptr;
1417   UINT32 len;
1418   TPM_PCRINDEX pcrNum;
1419   UINT32 hashDataSize;
1420   BYTE *hashData;
1421   TPM_DIGEST hashValue;
1422   TPM_PCRVALUE outDigest;
1423   TPM_RESULT res;
1424   /* unmarshal input */
1425   ptr = req->param;
1426   len = req->paramSize;
1427   if (tpm_unmarshal_TPM_PCRINDEX(&ptr, &len, &pcrNum)
1428       || tpm_unmarshal_UINT32(&ptr, &len, &hashDataSize)
1429       || tpm_unmarshal_BLOB(&ptr, &len, &hashData, hashDataSize)
1430       || len != 0) return TPM_BAD_PARAMETER;
1431   /* execute command */
1432   res = TPM_SHA1CompleteExtend(pcrNum, hashDataSize, hashData, &hashValue, &outDigest);
1433   if (res != TPM_SUCCESS) return res;
1434   /* marshal output */
1435   rsp->paramSize = len = 20 + 20;
1436   rsp->param = ptr = tpm_malloc(len);
1437   if (ptr == NULL
1438       || tpm_marshal_TPM_DIGEST(&ptr, &len, &hashValue)
1439       || tpm_marshal_TPM_PCRVALUE(&ptr, &len, &outDigest)) {
1440     tpm_free(rsp->param);
1441     res = TPM_FAIL;
1442   }
1443   return res;
1444 }
1445 
execute_TPM_Sign(TPM_REQUEST * req,TPM_RESPONSE * rsp)1446 static TPM_RESULT execute_TPM_Sign(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1447 {
1448   BYTE *ptr;
1449   UINT32 len;
1450   TPM_KEY_HANDLE keyHandle;
1451   UINT32 areaToSignSize;
1452   BYTE *areaToSign;
1453   UINT32 sigSize;
1454   BYTE *sig = NULL;
1455   TPM_RESULT res;
1456   /* compute parameter digest */
1457   tpm_compute_in_param_digest(req);
1458   /* unmarshal input */
1459   ptr = req->param;
1460   len = req->paramSize;
1461   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
1462       || tpm_unmarshal_UINT32(&ptr, &len, &areaToSignSize)
1463       || tpm_unmarshal_BLOB(&ptr, &len, &areaToSign, areaToSignSize)
1464       || len != 0) return TPM_BAD_PARAMETER;
1465   /* execute command */
1466   res = TPM_Sign(keyHandle, areaToSignSize, areaToSign, &req->auth1, &sigSize, &sig);
1467   if (res != TPM_SUCCESS) return res;
1468   /* marshal output */
1469   rsp->paramSize = len = 4 + sigSize;
1470   rsp->param = ptr = tpm_malloc(len);
1471   if (ptr == NULL
1472       || tpm_marshal_UINT32(&ptr, &len, sigSize)
1473       || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
1474     tpm_free(rsp->param);
1475     res = TPM_FAIL;
1476   }
1477   tpm_free(sig);
1478   return res;
1479 }
1480 
execute_TPM_GetRandom(TPM_REQUEST * req,TPM_RESPONSE * rsp)1481 static TPM_RESULT execute_TPM_GetRandom(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1482 {
1483   BYTE *ptr;
1484   UINT32 len;
1485   UINT32 bytesRequested;
1486   UINT32 randomBytesSize;
1487   BYTE *randomBytes = NULL;
1488   TPM_RESULT res;
1489   /* unmarshal input */
1490   ptr = req->param;
1491   len = req->paramSize;
1492   if (tpm_unmarshal_UINT32(&ptr, &len, &bytesRequested)
1493       || len != 0) return TPM_BAD_PARAMETER;
1494   /* execute command */
1495   res = TPM_GetRandom(bytesRequested, &randomBytesSize, &randomBytes);
1496   if (res != TPM_SUCCESS) return res;
1497   /* marshal output */
1498   rsp->paramSize = len = 4 + randomBytesSize;
1499   rsp->param = ptr = tpm_malloc(len);
1500   if (ptr == NULL
1501       || tpm_marshal_UINT32(&ptr, &len, randomBytesSize)
1502       || tpm_marshal_BLOB(&ptr, &len, randomBytes, randomBytesSize)) {
1503     tpm_free(rsp->param);
1504     res = TPM_FAIL;
1505   }
1506   tpm_free(randomBytes);
1507   return res;
1508 }
1509 
execute_TPM_StirRandom(TPM_REQUEST * req,TPM_RESPONSE * rsp)1510 static TPM_RESULT execute_TPM_StirRandom(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1511 {
1512   BYTE *ptr;
1513   UINT32 len;
1514   UINT32 dataSize;
1515   BYTE *inData;
1516   /* unmarshal input */
1517   ptr = req->param;
1518   len = req->paramSize;
1519   if (tpm_unmarshal_UINT32(&ptr, &len, &dataSize)
1520       || tpm_unmarshal_BLOB(&ptr, &len, &inData, dataSize)
1521       || len != 0) return TPM_BAD_PARAMETER;
1522   /* execute command */
1523   return TPM_StirRandom(dataSize, inData);
1524 }
1525 
execute_TPM_CertifyKey(TPM_REQUEST * req,TPM_RESPONSE * rsp)1526 static TPM_RESULT execute_TPM_CertifyKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1527 {
1528   BYTE *ptr;
1529   UINT32 len;
1530   TPM_KEY_HANDLE certHandle;
1531   TPM_KEY_HANDLE keyHandle;
1532   TPM_NONCE antiReplay;
1533   TPM_CERTIFY_INFO certifyInfo;
1534   UINT32 outDataSize;
1535   BYTE *outData = NULL;
1536   TPM_RESULT res;
1537   /* compute parameter digest */
1538   tpm_compute_in_param_digest(req);
1539   /* unmarshal input */
1540   ptr = req->param;
1541   len = req->paramSize;
1542   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &certHandle)
1543       || tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
1544       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
1545       || len != 0) return TPM_BAD_PARAMETER;
1546   /* execute command */
1547   res = TPM_CertifyKey(certHandle, keyHandle, &antiReplay, &req->auth1,
1548     &req->auth2, &certifyInfo, &outDataSize, &outData);
1549   if (res != TPM_SUCCESS) return res;
1550   /* marshal output */
1551   rsp->paramSize = len = sizeof_TPM_CERTIFY_INFO(certifyInfo) + 4 + outDataSize;
1552   rsp->param = ptr = tpm_malloc(len);
1553   if (ptr == NULL
1554       || tpm_marshal_TPM_CERTIFY_INFO(&ptr, &len, &certifyInfo)
1555       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
1556       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) {
1557     tpm_free(rsp->param);
1558     res = TPM_FAIL;
1559   }
1560   free_TPM_CERTIFY_INFO(certifyInfo);
1561   tpm_free(outData);
1562   return res;
1563 }
1564 
execute_TPM_CertifyKey2(TPM_REQUEST * req,TPM_RESPONSE * rsp)1565 static TPM_RESULT execute_TPM_CertifyKey2(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1566 {
1567   BYTE *ptr;
1568   UINT32 len;
1569   TPM_KEY_HANDLE keyHandle;
1570   TPM_KEY_HANDLE certHandle;
1571   TPM_DIGEST migrationPubDigest;
1572   TPM_NONCE antiReplay;
1573   TPM_CERTIFY_INFO certifyInfo;
1574   UINT32 outDataSize;
1575   BYTE *outData = NULL;
1576   TPM_RESULT res;
1577   /* compute parameter digest */
1578   tpm_compute_in_param_digest(req);
1579   /* unmarshal input */
1580   ptr = req->param;
1581   len = req->paramSize;
1582   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
1583       || tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &certHandle)
1584       || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &migrationPubDigest)
1585       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
1586       || len != 0) return TPM_BAD_PARAMETER;
1587   /* execute command */
1588   res = TPM_CertifyKey2(keyHandle, certHandle, &migrationPubDigest, &antiReplay,
1589     &req->auth1, &req->auth2, &certifyInfo, &outDataSize, &outData);
1590   if (res != TPM_SUCCESS) return res;
1591   /* marshal output */
1592   rsp->paramSize = len = sizeof_TPM_CERTIFY_INFO(certifyInfo) + 4 + outDataSize;
1593   rsp->param = ptr = tpm_malloc(len);
1594   if (ptr == NULL
1595       || tpm_marshal_TPM_CERTIFY_INFO(&ptr, &len, &certifyInfo)
1596       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
1597       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) {
1598     tpm_free(rsp->param);
1599     res = TPM_FAIL;
1600   }
1601   free_TPM_CERTIFY_INFO(certifyInfo);
1602   tpm_free(outData);
1603   return res;
1604 }
1605 
execute_TPM_CreateEndorsementKeyPair(TPM_REQUEST * req,TPM_RESPONSE * rsp)1606 static TPM_RESULT execute_TPM_CreateEndorsementKeyPair(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1607 {
1608   BYTE *ptr;
1609   UINT32 len;
1610   TPM_NONCE antiReplay;
1611   TPM_KEY_PARMS keyInfo;
1612   TPM_PUBKEY pubEndorsementKey;
1613   TPM_DIGEST Checksum;
1614   TPM_RESULT res;
1615   /* unmarshal input */
1616   ptr = req->param;
1617   len = req->paramSize;
1618   if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
1619       || tpm_unmarshal_TPM_KEY_PARMS(&ptr, &len, &keyInfo)
1620       || len != 0) return TPM_BAD_PARAMETER;
1621   /* execute command */
1622   res = TPM_CreateEndorsementKeyPair(&antiReplay, &keyInfo, &pubEndorsementKey, &Checksum);
1623   if (res != TPM_SUCCESS) return res;
1624   /* marshal output */
1625   rsp->paramSize = len = sizeof_TPM_PUBKEY(pubEndorsementKey) + 20;
1626   rsp->param = ptr = tpm_malloc(len);
1627   if (ptr == NULL
1628       || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubEndorsementKey)
1629       || tpm_marshal_TPM_DIGEST(&ptr, &len, &Checksum)) {
1630     tpm_free(rsp->param);
1631     res = TPM_FAIL;
1632   }
1633   free_TPM_PUBKEY(pubEndorsementKey);
1634   return res;
1635 }
1636 
execute_TPM_CreateRevocableEK(TPM_REQUEST * req,TPM_RESPONSE * rsp)1637 static TPM_RESULT execute_TPM_CreateRevocableEK(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1638 {
1639   BYTE *ptr;
1640   UINT32 len;
1641   TPM_NONCE antiReplay;
1642   TPM_KEY_PARMS keyInfo;
1643   BOOL generateReset;
1644   TPM_NONCE inputEKreset;
1645   TPM_PUBKEY pubEndorsementKey;
1646   TPM_DIGEST Checksum;
1647   TPM_NONCE outputEKreset;
1648   TPM_RESULT res;
1649   /* unmarshal input */
1650   ptr = req->param;
1651   len = req->paramSize;
1652   if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
1653       || tpm_unmarshal_TPM_KEY_PARMS(&ptr, &len, &keyInfo)
1654       || tpm_unmarshal_BOOL(&ptr, &len, &generateReset)
1655       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &inputEKreset)
1656       || len != 0) return TPM_BAD_PARAMETER;
1657   /* execute command */
1658   res = TPM_CreateRevocableEK(&antiReplay, &keyInfo, generateReset,
1659     &inputEKreset, &pubEndorsementKey, &Checksum, &outputEKreset);
1660   if (res != TPM_SUCCESS) return res;
1661   /* marshal output */
1662   rsp->paramSize = len = sizeof_TPM_PUBKEY(pubEndorsementKey) + 20 + 20;
1663   rsp->param = ptr = tpm_malloc(len);
1664   if (ptr == NULL
1665       || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubEndorsementKey)
1666       || tpm_marshal_TPM_DIGEST(&ptr, &len, &Checksum)
1667       || tpm_marshal_TPM_NONCE(&ptr, &len, &outputEKreset)) {
1668     tpm_free(rsp->param);
1669     res = TPM_FAIL;
1670   }
1671   free_TPM_PUBKEY(pubEndorsementKey);
1672   return res;
1673 }
1674 
execute_TPM_RevokeTrust(TPM_REQUEST * req,TPM_RESPONSE * rsp)1675 static TPM_RESULT execute_TPM_RevokeTrust(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1676 {
1677   BYTE *ptr;
1678   UINT32 len;
1679   TPM_NONCE EKReset;
1680   /* unmarshal input */
1681   ptr = req->param;
1682   len = req->paramSize;
1683   if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &EKReset)
1684       || len != 0) return TPM_BAD_PARAMETER;
1685   /* execute command */
1686   return TPM_RevokeTrust(&EKReset);
1687 }
1688 
execute_TPM_ReadPubek(TPM_REQUEST * req,TPM_RESPONSE * rsp)1689 static TPM_RESULT execute_TPM_ReadPubek(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1690 {
1691   BYTE *ptr;
1692   UINT32 len;
1693   TPM_NONCE antiReplay;
1694   TPM_PUBKEY pubEndorsementKey;
1695   TPM_DIGEST checksum;
1696   TPM_RESULT res;
1697   /* unmarshal input */
1698   ptr = req->param;
1699   len = req->paramSize;
1700   if (tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
1701       || len != 0) return TPM_BAD_PARAMETER;
1702   /* execute command */
1703   res = TPM_ReadPubek(&antiReplay, &pubEndorsementKey, &checksum);
1704   if (res != TPM_SUCCESS) return res;
1705   /* marshal output */
1706   rsp->paramSize = len = sizeof_TPM_PUBKEY(pubEndorsementKey) + 20;
1707   rsp->param = ptr = tpm_malloc(len);
1708   if (ptr == NULL
1709       || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubEndorsementKey)
1710       || tpm_marshal_TPM_DIGEST(&ptr, &len, &checksum)) {
1711     tpm_free(rsp->param);
1712     res = TPM_FAIL;
1713   }
1714   free_TPM_PUBKEY(pubEndorsementKey);
1715   return res;
1716 }
1717 
execute_TPM_DisablePubekRead(TPM_REQUEST * req,TPM_RESPONSE * rsp)1718 static TPM_RESULT execute_TPM_DisablePubekRead(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1719 {
1720   /* compute parameter digest */
1721   tpm_compute_in_param_digest(req);
1722   /* execute command */
1723   return TPM_DisablePubekRead(&req->auth1);
1724 }
1725 
execute_TPM_OwnerReadInternalPub(TPM_REQUEST * req,TPM_RESPONSE * rsp)1726 static TPM_RESULT execute_TPM_OwnerReadInternalPub(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1727 {
1728   BYTE *ptr;
1729   UINT32 len;
1730   TPM_KEY_HANDLE keyHandle;
1731   TPM_PUBKEY publicPortion;
1732   TPM_RESULT res;
1733   /* compute parameter digest */
1734   tpm_compute_in_param_digest(req);
1735   /* unmarshal input */
1736   ptr = req->param;
1737   len = req->paramSize;
1738   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
1739       || len != 0) return TPM_BAD_PARAMETER;
1740   /* execute command */
1741   res = TPM_OwnerReadInternalPub(keyHandle, &req->auth1, &publicPortion);
1742   if (res != TPM_SUCCESS) return res;
1743   /* marshal output */
1744   rsp->paramSize = len = sizeof_TPM_PUBKEY(publicPortion);
1745   rsp->param = ptr = tpm_malloc(len);
1746   if (ptr == NULL
1747       || tpm_marshal_TPM_PUBKEY(&ptr, &len, &publicPortion)) {
1748     tpm_free(rsp->param);
1749     res = TPM_FAIL;
1750   }
1751   free_TPM_PUBKEY(publicPortion);
1752   return res;
1753 }
1754 
execute_TPM_MakeIdentity(TPM_REQUEST * req,TPM_RESPONSE * rsp)1755 static TPM_RESULT execute_TPM_MakeIdentity(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1756 {
1757   BYTE *ptr;
1758   UINT32 len;
1759   TPM_ENCAUTH identityAuth;
1760   TPM_CHOSENID_HASH labelPrivCADigest;
1761   TPM_KEY idKeyParams;
1762   TPM_KEY idKey;
1763   UINT32 identityBindingSize;
1764   BYTE *identityBinding = NULL;
1765   TPM_RESULT res;
1766   /* compute parameter digest */
1767   tpm_compute_in_param_digest(req);
1768   /* unmarshal input */
1769   ptr = req->param;
1770   len = req->paramSize;
1771   if (tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &identityAuth)
1772       || tpm_unmarshal_TPM_CHOSENID_HASH(&ptr, &len, &labelPrivCADigest)
1773       || tpm_unmarshal_TPM_KEY(&ptr, &len, &idKeyParams)
1774       || len != 0) return TPM_BAD_PARAMETER;
1775   /* execute command */
1776   res = TPM_MakeIdentity(&identityAuth, &labelPrivCADigest, &idKeyParams,
1777     &req->auth1, &req->auth2, &idKey, &identityBindingSize, &identityBinding);
1778   if (res != TPM_SUCCESS) return res;
1779   /* marshal output */
1780   rsp->paramSize = len = sizeof_TPM_KEY(idKey) + 4 + identityBindingSize;
1781   rsp->param = ptr = tpm_malloc(len);
1782   if (ptr == NULL
1783       || tpm_marshal_TPM_KEY(&ptr, &len, &idKey)
1784       || tpm_marshal_UINT32(&ptr, &len, identityBindingSize)
1785       || tpm_marshal_BLOB(&ptr, &len, identityBinding, identityBindingSize)) {
1786     tpm_free(rsp->param);
1787     res = TPM_FAIL;
1788   }
1789   free_TPM_KEY(idKey);
1790   tpm_free(identityBinding);
1791   return res;
1792 }
1793 
execute_TPM_ActivateIdentity(TPM_REQUEST * req,TPM_RESPONSE * rsp)1794 static TPM_RESULT execute_TPM_ActivateIdentity(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1795 {
1796   BYTE *ptr;
1797   UINT32 len;
1798   TPM_KEY_HANDLE idKeyHandle;
1799   UINT32 blobSize;
1800   BYTE *blob;
1801   TPM_SYMMETRIC_KEY symmetricKey;
1802   TPM_RESULT res;
1803   /* compute parameter digest */
1804   tpm_compute_in_param_digest(req);
1805   /* unmarshal input */
1806   ptr = req->param;
1807   len = req->paramSize;
1808   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &idKeyHandle)
1809       || tpm_unmarshal_UINT32(&ptr, &len, &blobSize)
1810       || tpm_unmarshal_BLOB(&ptr, &len, &blob, blobSize)
1811       || len != 0) return TPM_BAD_PARAMETER;
1812   /* allocate memory for the symmetricKey data */
1813   symmetricKey.size = blobSize;
1814   symmetricKey.data = tpm_malloc(blobSize);
1815   if (symmetricKey.data == NULL)
1816     return TPM_NOSPACE;
1817   /* execute command */
1818   res = TPM_ActivateIdentity(idKeyHandle, blobSize, blob, &req->auth1,
1819     &req->auth2, &symmetricKey);
1820   if (res != TPM_SUCCESS) {
1821     free_TPM_SYMMETRIC_KEY(symmetricKey);
1822     return res;
1823   }
1824   /* marshal output */
1825   rsp->paramSize = len = sizeof_TPM_SYMMETRIC_KEY(symmetricKey);
1826   rsp->param = ptr = tpm_malloc(len);
1827   if (ptr == NULL)
1828     res = TPM_NOSPACE;
1829   else if (tpm_marshal_TPM_SYMMETRIC_KEY(&ptr, &len, &symmetricKey)) {
1830     tpm_free(rsp->param);
1831     res = TPM_FAIL;
1832   }
1833   free_TPM_SYMMETRIC_KEY(symmetricKey);
1834   return res;
1835 }
1836 
execute_TPM_Extend(TPM_REQUEST * req,TPM_RESPONSE * rsp)1837 static TPM_RESULT execute_TPM_Extend(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1838 {
1839   BYTE *ptr;
1840   UINT32 len;
1841   TPM_PCRINDEX pcrNum;
1842   TPM_DIGEST inDigest;
1843   TPM_PCRVALUE outDigest;
1844   TPM_RESULT res;
1845   /* unmarshal input */
1846   ptr = req->param;
1847   len = req->paramSize;
1848   if (tpm_unmarshal_TPM_PCRINDEX(&ptr, &len, &pcrNum)
1849       || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &inDigest)
1850       || len != 0) return TPM_BAD_PARAMETER;
1851   /* execute command */
1852 #ifdef MTM_EMULATOR
1853   res = MTM_Extend(pcrNum, &inDigest, &outDigest);
1854 #else
1855   res = TPM_Extend(pcrNum, &inDigest, &outDigest);
1856 #endif
1857   if (res != TPM_SUCCESS) return res;
1858   /* marshal output */
1859   rsp->paramSize = len = 20;
1860   rsp->param = ptr = tpm_malloc(len);
1861   if (ptr == NULL
1862       || tpm_marshal_TPM_PCRVALUE(&ptr, &len, &outDigest)) {
1863     tpm_free(rsp->param);
1864     res = TPM_FAIL;
1865   }
1866   return res;
1867 }
1868 
execute_TPM_PCRRead(TPM_REQUEST * req,TPM_RESPONSE * rsp)1869 static TPM_RESULT execute_TPM_PCRRead(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1870 {
1871   BYTE *ptr;
1872   UINT32 len;
1873   TPM_PCRINDEX pcrIndex;
1874   TPM_PCRVALUE outDigest;
1875   TPM_RESULT res;
1876   /* unmarshal input */
1877   ptr = req->param;
1878   len = req->paramSize;
1879   if (tpm_unmarshal_TPM_PCRINDEX(&ptr, &len, &pcrIndex)
1880       || len != 0) return TPM_BAD_PARAMETER;
1881   /* execute command */
1882   res = TPM_PCRRead(pcrIndex, &outDigest);
1883   if (res != TPM_SUCCESS) return res;
1884   /* marshal output */
1885   rsp->paramSize = len = 20;
1886   rsp->param = ptr = tpm_malloc(len);
1887   if (ptr == NULL
1888       || tpm_marshal_TPM_PCRVALUE(&ptr, &len, &outDigest)) {
1889     tpm_free(rsp->param);
1890     res = TPM_FAIL;
1891   }
1892   return res;
1893 }
1894 
execute_TPM_Quote(TPM_REQUEST * req,TPM_RESPONSE * rsp)1895 static TPM_RESULT execute_TPM_Quote(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1896 {
1897   BYTE *ptr;
1898   UINT32 len;
1899   TPM_KEY_HANDLE keyHandle;
1900   TPM_NONCE extrnalData;
1901   TPM_PCR_SELECTION targetPCR;
1902   TPM_PCR_COMPOSITE pcrData;
1903   UINT32 sigSize;
1904   BYTE *sig = NULL;
1905   TPM_RESULT res;
1906   /* compute parameter digest */
1907   tpm_compute_in_param_digest(req);
1908   /* unmarshal input */
1909   ptr = req->param;
1910   len = req->paramSize;
1911   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
1912       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &extrnalData)
1913       || tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &targetPCR)
1914       || len != 0) return TPM_BAD_PARAMETER;
1915   /* execute command */
1916   res = TPM_Quote(keyHandle, &extrnalData, &targetPCR, &req->auth1, &pcrData, &sigSize, &sig);
1917   if (res != TPM_SUCCESS) return res;
1918   /* marshal output */
1919   rsp->paramSize = len = sizeof_TPM_PCR_COMPOSITE(pcrData) + 4 + sigSize;
1920   rsp->param = ptr = tpm_malloc(len);
1921   if (ptr == NULL
1922       || tpm_marshal_TPM_PCR_COMPOSITE(&ptr, &len, &pcrData)
1923       || tpm_marshal_UINT32(&ptr, &len, sigSize)
1924       || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
1925     tpm_free(rsp->param);
1926     res = TPM_FAIL;
1927   }
1928   tpm_free(sig);
1929   return res;
1930 }
1931 
execute_TPM_PCR_Reset(TPM_REQUEST * req,TPM_RESPONSE * rsp)1932 static TPM_RESULT execute_TPM_PCR_Reset(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1933 {
1934   BYTE *ptr;
1935   UINT32 len;
1936   TPM_PCR_SELECTION pcrSelection;
1937   /* unmarshal input */
1938   ptr = req->param;
1939   len = req->paramSize;
1940   if (tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &pcrSelection)
1941       || len != 0) return TPM_BAD_PARAMETER;
1942   /* execute command */
1943 #ifdef MTM_EMULATOR
1944   return MTM_PCR_Reset(&pcrSelection);
1945 #else
1946   return TPM_PCR_Reset(&pcrSelection);
1947 #endif
1948 }
1949 
execute_TPM_Quote2(TPM_REQUEST * req,TPM_RESPONSE * rsp)1950 static TPM_RESULT execute_TPM_Quote2(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1951 {
1952   BYTE *ptr;
1953   UINT32 len;
1954   TPM_KEY_HANDLE keyHandle;
1955   TPM_NONCE externalData;
1956   TPM_PCR_SELECTION targetPCR;
1957   BOOL addVersion;
1958   TPM_PCR_INFO_SHORT pcrData;
1959   UINT32 versionInfoSize;
1960   TPM_CAP_VERSION_INFO versionInfo;
1961   UINT32 sigSize;
1962   BYTE *sig = NULL;
1963   TPM_RESULT res;
1964   /* compute parameter digest */
1965   tpm_compute_in_param_digest(req);
1966   /* unmarshal input */
1967   ptr = req->param;
1968   len = req->paramSize;
1969   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
1970       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &externalData)
1971       || tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &targetPCR)
1972       || tpm_unmarshal_BOOL(&ptr, &len, &addVersion)
1973       || len != 0) return TPM_BAD_PARAMETER;
1974   /* execute command */
1975   res = TPM_Quote2(keyHandle, &externalData, &targetPCR, addVersion,
1976     &req->auth1, &pcrData, &versionInfoSize, &versionInfo, &sigSize, &sig);
1977   if (res != TPM_SUCCESS) return res;
1978   /* marshal output */
1979   rsp->paramSize = len = sizeof_TPM_PCR_INFO_SHORT(pcrData) + 4
1980     + versionInfoSize + 4 + sigSize;
1981   rsp->param = ptr = tpm_malloc(len);
1982   if (ptr == NULL
1983       || tpm_marshal_TPM_PCR_INFO_SHORT(&ptr, &len, &pcrData)
1984       || tpm_marshal_UINT32(&ptr, &len, versionInfoSize)
1985       || ((addVersion == TRUE)
1986           && tpm_marshal_TPM_CAP_VERSION_INFO(&ptr, &len, &versionInfo))
1987       || tpm_marshal_UINT32(&ptr, &len, sigSize)
1988       || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
1989     tpm_free(rsp->param);
1990     res = TPM_FAIL;
1991   }
1992   tpm_free(sig);
1993   return res;
1994 }
1995 
execute_TPM_ChangeAuth(TPM_REQUEST * req,TPM_RESPONSE * rsp)1996 static TPM_RESULT execute_TPM_ChangeAuth(TPM_REQUEST *req, TPM_RESPONSE *rsp)
1997 {
1998   BYTE *ptr;
1999   UINT32 len;
2000   TPM_KEY_HANDLE parentHandle;
2001   TPM_PROTOCOL_ID protocolID;
2002   TPM_ENCAUTH newAuth;
2003   TPM_ENTITY_TYPE entityType;
2004   UINT32 encDataSize;
2005   BYTE *encData;
2006   UINT32 outDataSize;
2007   BYTE *outData = NULL;
2008   TPM_RESULT res;
2009   /* compute parameter digest */
2010   tpm_compute_in_param_digest(req);
2011   /* unmarshal input */
2012   ptr = req->param;
2013   len = req->paramSize;
2014   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
2015       || tpm_unmarshal_TPM_PROTOCOL_ID(&ptr, &len, &protocolID)
2016       || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &newAuth)
2017       || tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType)
2018       || tpm_unmarshal_UINT32(&ptr, &len, &encDataSize)
2019       || tpm_unmarshal_BLOB(&ptr, &len, &encData, encDataSize)
2020       || len != 0) return TPM_BAD_PARAMETER;
2021   /* execute command */
2022   res = TPM_ChangeAuth(parentHandle, protocolID, &newAuth, entityType, encDataSize,
2023     encData, &req->auth1, &req->auth2, &outDataSize, &outData);
2024   if (res != TPM_SUCCESS) return res;
2025   /* marshal output */
2026   rsp->paramSize = len = 4 + outDataSize;
2027   rsp->param = ptr = tpm_malloc(len);
2028   if (ptr == NULL
2029       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
2030       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)) {
2031     tpm_free(rsp->param);
2032     res = TPM_FAIL;
2033   }
2034   tpm_free(outData);
2035   return res;
2036 }
2037 
execute_TPM_ChangeAuthOwner(TPM_REQUEST * req,TPM_RESPONSE * rsp)2038 static TPM_RESULT execute_TPM_ChangeAuthOwner(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2039 {
2040   BYTE *ptr;
2041   UINT32 len;
2042   TPM_PROTOCOL_ID protocolID;
2043   TPM_ENCAUTH newAuth;
2044   TPM_ENTITY_TYPE entityType;
2045   /* compute parameter digest */
2046   tpm_compute_in_param_digest(req);
2047   /* unmarshal input */
2048   ptr = req->param;
2049   len = req->paramSize;
2050   if (tpm_unmarshal_TPM_PROTOCOL_ID(&ptr, &len, &protocolID)
2051       || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &newAuth)
2052       || tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType)
2053       || len != 0) return TPM_BAD_PARAMETER;
2054   /* execute command */
2055   return TPM_ChangeAuthOwner(protocolID, &newAuth, entityType, &req->auth1);
2056 }
2057 
execute_TPM_OIAP(TPM_REQUEST * req,TPM_RESPONSE * rsp)2058 static TPM_RESULT execute_TPM_OIAP(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2059 {
2060   BYTE *ptr;
2061   UINT32 len;
2062   TPM_AUTHHANDLE authHandle;
2063   TPM_NONCE nonceEven;
2064   TPM_RESULT res;
2065   /* execute command */
2066   res = TPM_OIAP(&authHandle, &nonceEven);
2067   if (res != TPM_SUCCESS) return res;
2068   /* marshal output */
2069   rsp->paramSize = len = 4 + 20;
2070   rsp->param = ptr = tpm_malloc(len);
2071   if (ptr == NULL
2072       || tpm_marshal_TPM_AUTHHANDLE(&ptr, &len, authHandle)
2073       || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEven)) {
2074     tpm_free(rsp->param);
2075     res = TPM_FAIL;
2076   }
2077   return res;
2078 }
2079 
execute_TPM_OSAP(TPM_REQUEST * req,TPM_RESPONSE * rsp)2080 static TPM_RESULT execute_TPM_OSAP(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2081 {
2082   BYTE *ptr;
2083   UINT32 len;
2084   TPM_ENTITY_TYPE entityType;
2085   UINT32 entityValue;
2086   TPM_NONCE nonceOddOSAP;
2087   TPM_AUTHHANDLE authHandle;
2088   TPM_NONCE nonceEven;
2089   TPM_NONCE nonceEvenOSAP;
2090   TPM_RESULT res;
2091   /* unmarshal input */
2092   ptr = req->param;
2093   len = req->paramSize;
2094   if (tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType)
2095       || tpm_unmarshal_UINT32(&ptr, &len, &entityValue)
2096       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &nonceOddOSAP)
2097       || len != 0) return TPM_BAD_PARAMETER;
2098   /* execute command */
2099   res = TPM_OSAP(entityType, entityValue, &nonceOddOSAP, &authHandle,
2100     &nonceEven, &nonceEvenOSAP);
2101   if (res != TPM_SUCCESS) return res;
2102   /* marshal output */
2103   rsp->paramSize = len = 4 + 20 + 20;
2104   rsp->param = ptr = tpm_malloc(len);
2105   if (ptr == NULL
2106       || tpm_marshal_TPM_AUTHHANDLE(&ptr, &len, authHandle)
2107       || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEven)
2108       || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEvenOSAP)) {
2109     tpm_free(rsp->param);
2110     res = TPM_FAIL;
2111   }
2112   return res;
2113 }
2114 
execute_TPM_DSAP(TPM_REQUEST * req,TPM_RESPONSE * rsp)2115 static TPM_RESULT execute_TPM_DSAP(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2116 {
2117   BYTE *ptr;
2118   UINT32 len;
2119   TPM_ENTITY_TYPE entityType;
2120   TPM_KEY_HANDLE keyHandle;
2121   UINT32 entityValueSize;
2122   BYTE *entityValue;
2123   TPM_NONCE nonceOddDSAP;
2124   TPM_AUTHHANDLE authHandle;
2125   TPM_NONCE nonceEven;
2126   TPM_NONCE nonceEvenDSAP;
2127   TPM_RESULT res;
2128   /* unmarshal input */
2129   ptr = req->param;
2130   len = req->paramSize;
2131   if (tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType)
2132       || tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
2133       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &nonceOddDSAP)
2134       || tpm_unmarshal_UINT32(&ptr, &len, &entityValueSize)
2135       || tpm_unmarshal_BLOB(&ptr, &len, &entityValue, entityValueSize)
2136       || len != 0) return TPM_BAD_PARAMETER;
2137   /* execute command */
2138   res = TPM_DSAP(entityType, keyHandle, &nonceOddDSAP, entityValueSize,
2139     entityValue, &authHandle, &nonceEven, &nonceEvenDSAP);
2140   if (res != TPM_SUCCESS) return res;
2141   /* marshal output */
2142   rsp->paramSize = len = 4 + 20 + 20;
2143   rsp->param = ptr = tpm_malloc(len);
2144   if (ptr == NULL
2145       || tpm_marshal_TPM_AUTHHANDLE(&ptr, &len, authHandle)
2146       || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEven)
2147       || tpm_marshal_TPM_NONCE(&ptr, &len, &nonceEvenDSAP)) {
2148     tpm_free(rsp->param);
2149     res = TPM_FAIL;
2150   }
2151   return res;
2152 }
2153 
execute_TPM_SetOwnerPointer(TPM_REQUEST * req,TPM_RESPONSE * rsp)2154 static TPM_RESULT execute_TPM_SetOwnerPointer(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2155 {
2156   BYTE *ptr;
2157   UINT32 len;
2158   TPM_ENTITY_TYPE entityType;
2159   UINT32 entityValue;
2160   /* unmarshal input */
2161   ptr = req->param;
2162   len = req->paramSize;
2163   if (tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType)
2164       || tpm_unmarshal_UINT32(&ptr, &len, &entityValue)
2165       || len != 0) return TPM_BAD_PARAMETER;
2166   /* execute command */
2167   return TPM_SetOwnerPointer(entityType, entityValue);
2168 }
2169 
execute_TPM_Delegate_Manage(TPM_REQUEST * req,TPM_RESPONSE * rsp)2170 static TPM_RESULT execute_TPM_Delegate_Manage(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2171 {
2172   BYTE *ptr;
2173   UINT32 len;
2174   TPM_FAMILY_ID familyID;
2175   TPM_FAMILY_OPERATION opFlag;
2176   UINT32 opDataSize;
2177   BYTE *opData;
2178   UINT32 retDataSize;
2179   BYTE *retData = NULL;
2180   TPM_RESULT res;
2181   /* compute parameter digest */
2182   tpm_compute_in_param_digest(req);
2183   /* unmarshal input */
2184   ptr = req->param;
2185   len = req->paramSize;
2186   if (tpm_unmarshal_TPM_FAMILY_ID(&ptr, &len, &familyID)
2187       || tpm_unmarshal_TPM_FAMILY_OPERATION(&ptr, &len, &opFlag)
2188       || tpm_unmarshal_UINT32(&ptr, &len, &opDataSize)
2189       || tpm_unmarshal_BLOB(&ptr, &len, &opData, opDataSize)
2190       || len != 0) return TPM_BAD_PARAMETER;
2191   /* execute command */
2192   res = TPM_Delegate_Manage(familyID, opFlag, opDataSize, opData,
2193     &req->auth1, &retDataSize, &retData);
2194   if (res != TPM_SUCCESS) return res;
2195   /* marshal output */
2196   rsp->paramSize = len = 4 + retDataSize;
2197   rsp->param = ptr = tpm_malloc(len);
2198   if (ptr == NULL
2199       || tpm_marshal_UINT32(&ptr, &len, retDataSize)
2200       || tpm_marshal_BLOB(&ptr, &len, retData, retDataSize)) {
2201     tpm_free(rsp->param);
2202     res = TPM_FAIL;
2203   }
2204   tpm_free(retData);
2205   return res;
2206 }
2207 
execute_TPM_Delegate_CreateKeyDelegation(TPM_REQUEST * req,TPM_RESPONSE * rsp)2208 static TPM_RESULT execute_TPM_Delegate_CreateKeyDelegation(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2209 {
2210   BYTE *ptr;
2211   UINT32 len;
2212   TPM_KEY_HANDLE keyHandle;
2213   TPM_DELEGATE_PUBLIC publicInfo;
2214   TPM_ENCAUTH delAuth;
2215   UINT32 blobSize;
2216   TPM_DELEGATE_KEY_BLOB blob;
2217   TPM_RESULT res;
2218   /* compute parameter digest */
2219   tpm_compute_in_param_digest(req);
2220   /* unmarshal input */
2221   ptr = req->param;
2222   len = req->paramSize;
2223   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
2224       || tpm_unmarshal_TPM_DELEGATE_PUBLIC(&ptr, &len, &publicInfo)
2225       || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &delAuth)
2226       || len != 0) return TPM_BAD_PARAMETER;
2227   /* execute command */
2228   res = TPM_Delegate_CreateKeyDelegation(keyHandle, &publicInfo, &delAuth,
2229     &req->auth1, &blob);
2230   if (res != TPM_SUCCESS) return res;
2231   /* marshal output */
2232   blobSize = sizeof_TPM_DELEGATE_KEY_BLOB(blob);
2233   rsp->paramSize = len = 4 + blobSize;
2234   rsp->param = ptr = tpm_malloc(len);
2235   if (ptr == NULL
2236       || tpm_marshal_UINT32(&ptr, &len, blobSize)
2237       || tpm_marshal_TPM_DELEGATE_KEY_BLOB(&ptr, &len, &blob)) {
2238     tpm_free(rsp->param);
2239     res = TPM_FAIL;
2240   }
2241   free_TPM_DELEGATE_KEY_BLOB(blob);
2242   return res;
2243 }
2244 
execute_TPM_Delegate_CreateOwnerDelegation(TPM_REQUEST * req,TPM_RESPONSE * rsp)2245 static TPM_RESULT execute_TPM_Delegate_CreateOwnerDelegation(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2246 {
2247   BYTE *ptr;
2248   UINT32 len;
2249   BOOL increment;
2250   TPM_DELEGATE_PUBLIC publicInfo;
2251   TPM_ENCAUTH delAuth;
2252   UINT32 blobSize;
2253   TPM_DELEGATE_OWNER_BLOB blob;
2254   TPM_RESULT res;
2255   /* compute parameter digest */
2256   tpm_compute_in_param_digest(req);
2257   /* unmarshal input */
2258   ptr = req->param;
2259   len = req->paramSize;
2260   if (tpm_unmarshal_BOOL(&ptr, &len, &increment)
2261       || tpm_unmarshal_TPM_DELEGATE_PUBLIC(&ptr, &len, &publicInfo)
2262       || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &delAuth)
2263       || len != 0) return TPM_BAD_PARAMETER;
2264   /* execute command */
2265   res = TPM_Delegate_CreateOwnerDelegation(increment, &publicInfo, &delAuth,
2266     &req->auth1, &blob);
2267   if (res != TPM_SUCCESS) return res;
2268   /* marshal output */
2269   blobSize = sizeof_TPM_DELEGATE_OWNER_BLOB(blob);
2270   rsp->paramSize = len = 4 + blobSize;
2271   rsp->param = ptr = tpm_malloc(len);
2272   if (ptr == NULL
2273       || tpm_marshal_UINT32(&ptr, &len, blobSize)
2274       || tpm_marshal_TPM_DELEGATE_OWNER_BLOB(&ptr, &len, &blob)) {
2275     tpm_free(rsp->param);
2276     res = TPM_FAIL;
2277   }
2278   free_TPM_DELEGATE_OWNER_BLOB(blob);
2279   return res;
2280 }
2281 
execute_TPM_Delegate_LoadOwnerDelegation(TPM_REQUEST * req,TPM_RESPONSE * rsp)2282 static TPM_RESULT execute_TPM_Delegate_LoadOwnerDelegation(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2283 {
2284   BYTE *ptr;
2285   UINT32 len;
2286   TPM_DELEGATE_INDEX index;
2287   UINT32 blobSize;
2288   TPM_DELEGATE_OWNER_BLOB blob;
2289   /* compute parameter digest */
2290   tpm_compute_in_param_digest(req);
2291   /* unmarshal input */
2292   ptr = req->param;
2293   len = req->paramSize;
2294   if (tpm_unmarshal_TPM_DELEGATE_INDEX(&ptr, &len, &index)
2295       || tpm_unmarshal_UINT32(&ptr, &len, &blobSize)
2296       || tpm_unmarshal_TPM_DELEGATE_OWNER_BLOB(&ptr, &len, &blob)
2297       || len != 0) return TPM_BAD_PARAMETER;
2298   /* execute command */
2299   return TPM_Delegate_LoadOwnerDelegation(index, &blob, &req->auth1);
2300 }
2301 
execute_TPM_Delegate_ReadTable(TPM_REQUEST * req,TPM_RESPONSE * rsp)2302 static TPM_RESULT execute_TPM_Delegate_ReadTable(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2303 {
2304   BYTE *ptr;
2305   UINT32 len;
2306   UINT32 familyTableSize;
2307   BYTE *familyTable = NULL;
2308   UINT32 delegateTableSize;
2309   BYTE *delegateTable = NULL;
2310   TPM_RESULT res;
2311   /* execute command */
2312   res = TPM_Delegate_ReadTable(&familyTableSize, &familyTable, &delegateTableSize, &delegateTable);
2313   if (res != TPM_SUCCESS) return res;
2314   /* marshal output */
2315   rsp->paramSize = len = 4 + familyTableSize + 4 + delegateTableSize;
2316   rsp->param = ptr = tpm_malloc(len);
2317   if (ptr == NULL
2318       || tpm_marshal_UINT32(&ptr, &len, familyTableSize)
2319       || tpm_marshal_BLOB(&ptr, &len, familyTable, familyTableSize)
2320       || tpm_marshal_UINT32(&ptr, &len, delegateTableSize)
2321       || tpm_marshal_BLOB(&ptr, &len, delegateTable, delegateTableSize)) {
2322     tpm_free(rsp->param);
2323     res = TPM_FAIL;
2324   }
2325   tpm_free(familyTable);
2326   tpm_free(delegateTable);
2327   return res;
2328 }
2329 
execute_TPM_Delegate_UpdateVerification(TPM_REQUEST * req,TPM_RESPONSE * rsp)2330 static TPM_RESULT execute_TPM_Delegate_UpdateVerification(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2331 {
2332   BYTE *ptr;
2333   UINT32 len;
2334   UINT32 inputSize;
2335   BYTE *inputData;
2336   UINT32 outputSize;
2337   BYTE *outputData = NULL;
2338   TPM_RESULT res;
2339   /* compute parameter digest */
2340   tpm_compute_in_param_digest(req);
2341   /* unmarshal input */
2342   ptr = req->param;
2343   len = req->paramSize;
2344   if (tpm_unmarshal_UINT32(&ptr, &len, &inputSize)
2345       || tpm_unmarshal_BLOB(&ptr, &len, &inputData, inputSize)
2346       || len != 0) return TPM_BAD_PARAMETER;
2347   /* execute command */
2348   res = TPM_Delegate_UpdateVerification(inputSize, inputData,
2349     &req->auth1, &outputSize, &outputData);
2350   if (res != TPM_SUCCESS) return res;
2351   /* marshal output */
2352   rsp->paramSize = len = 4 + outputSize;
2353   rsp->param = ptr = tpm_malloc(len);
2354   if (ptr == NULL
2355       || tpm_marshal_UINT32(&ptr, &len, outputSize)
2356       || tpm_marshal_BLOB(&ptr, &len, outputData, outputSize)) {
2357     tpm_free(rsp->param);
2358     res = TPM_FAIL;
2359   }
2360   tpm_free(outputData);
2361   return res;
2362 }
2363 
execute_TPM_Delegate_VerifyDelegation(TPM_REQUEST * req,TPM_RESPONSE * rsp)2364 static TPM_RESULT execute_TPM_Delegate_VerifyDelegation(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2365 {
2366   BYTE *ptr;
2367   UINT32 len;
2368   UINT32 delegateSize;
2369   BYTE *delegation;
2370   /* unmarshal input */
2371   ptr = req->param;
2372   len = req->paramSize;
2373   if (tpm_unmarshal_UINT32(&ptr, &len, &delegateSize)
2374       || tpm_unmarshal_BLOB(&ptr, &len, &delegation, delegateSize)
2375       || len != 0) return TPM_BAD_PARAMETER;
2376   /* execute command */
2377   return TPM_Delegate_VerifyDelegation(delegateSize, delegation);
2378 }
2379 
execute_TPM_NV_DefineSpace(TPM_REQUEST * req,TPM_RESPONSE * rsp)2380 static TPM_RESULT execute_TPM_NV_DefineSpace(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2381 {
2382   BYTE *ptr;
2383   UINT32 len;
2384   TPM_NV_DATA_PUBLIC pubInfo;
2385   TPM_ENCAUTH encAuth;
2386   /* compute parameter digest */
2387   tpm_compute_in_param_digest(req);
2388   /* unmarshal input */
2389   ptr = req->param;
2390   len = req->paramSize;
2391   if (tpm_unmarshal_TPM_NV_DATA_PUBLIC(&ptr, &len, &pubInfo)
2392       || tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &encAuth)
2393       || len != 0) return TPM_BAD_PARAMETER;
2394   /* execute command */
2395   return TPM_NV_DefineSpace(&pubInfo, &encAuth, &req->auth1);
2396 }
2397 
execute_TPM_NV_WriteValue(TPM_REQUEST * req,TPM_RESPONSE * rsp)2398 static TPM_RESULT execute_TPM_NV_WriteValue(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2399 {
2400   BYTE *ptr;
2401   UINT32 len;
2402   TPM_NV_INDEX nvIndex;
2403   UINT32 offset;
2404   UINT32 dataSize;
2405   BYTE *data;
2406   /* compute parameter digest */
2407   tpm_compute_in_param_digest(req);
2408   /* unmarshal input */
2409   ptr = req->param;
2410   len = req->paramSize;
2411   if (tpm_unmarshal_TPM_NV_INDEX(&ptr, &len, &nvIndex)
2412       || tpm_unmarshal_UINT32(&ptr, &len, &offset)
2413       || tpm_unmarshal_UINT32(&ptr, &len, &dataSize)
2414       || tpm_unmarshal_BLOB(&ptr, &len, &data, dataSize)
2415       || len != 0) return TPM_BAD_PARAMETER;
2416   /* execute command */
2417   return TPM_NV_WriteValue(nvIndex, offset, dataSize, data, &req->auth1);
2418 }
2419 
execute_TPM_NV_WriteValueAuth(TPM_REQUEST * req,TPM_RESPONSE * rsp)2420 static TPM_RESULT execute_TPM_NV_WriteValueAuth(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2421 {
2422   BYTE *ptr;
2423   UINT32 len;
2424   TPM_NV_INDEX nvIndex;
2425   UINT32 offset;
2426   UINT32 dataSize;
2427   BYTE *data;
2428   /* compute parameter digest */
2429   tpm_compute_in_param_digest(req);
2430   /* unmarshal input */
2431   ptr = req->param;
2432   len = req->paramSize;
2433   if (tpm_unmarshal_TPM_NV_INDEX(&ptr, &len, &nvIndex)
2434       || tpm_unmarshal_UINT32(&ptr, &len, &offset)
2435       || tpm_unmarshal_UINT32(&ptr, &len, &dataSize)
2436       || tpm_unmarshal_BLOB(&ptr, &len, &data, dataSize)
2437       || len != 0) return TPM_BAD_PARAMETER;
2438   /* execute command */
2439   return TPM_NV_WriteValueAuth(nvIndex, offset, dataSize, data, &req->auth1);
2440 }
2441 
execute_TPM_NV_ReadValue(TPM_REQUEST * req,TPM_RESPONSE * rsp)2442 static TPM_RESULT execute_TPM_NV_ReadValue(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2443 {
2444   BYTE *ptr;
2445   UINT32 len;
2446   TPM_NV_INDEX nvIndex;
2447   UINT32 offset;
2448   UINT32 inDataSize;
2449   UINT32 outDataSize;
2450   BYTE *data = NULL;
2451   TPM_RESULT res;
2452   /* compute parameter digest */
2453   tpm_compute_in_param_digest(req);
2454   /* unmarshal input */
2455   ptr = req->param;
2456   len = req->paramSize;
2457   if (tpm_unmarshal_TPM_NV_INDEX(&ptr, &len, &nvIndex)
2458       || tpm_unmarshal_UINT32(&ptr, &len, &offset)
2459       || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize)
2460       || len != 0) return TPM_BAD_PARAMETER;
2461   /* execute command */
2462   res = TPM_NV_ReadValue(nvIndex, offset, inDataSize, &req->auth1, &outDataSize, &data);
2463   if (res != TPM_SUCCESS) return res;
2464   /* marshal output */
2465   rsp->paramSize = len = 4 + outDataSize;
2466   rsp->param = ptr = tpm_malloc(len);
2467   if (ptr == NULL
2468       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
2469       || tpm_marshal_BLOB(&ptr, &len, data, outDataSize)) {
2470     tpm_free(rsp->param);
2471     res = TPM_FAIL;
2472   }
2473   tpm_free(data);
2474   return res;
2475 }
2476 
execute_TPM_NV_ReadValueAuth(TPM_REQUEST * req,TPM_RESPONSE * rsp)2477 static TPM_RESULT execute_TPM_NV_ReadValueAuth(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2478 {
2479   BYTE *ptr;
2480   UINT32 len;
2481   TPM_NV_INDEX nvIndex;
2482   UINT32 offset;
2483   UINT32 inDataSize;
2484   UINT32 outDataSize;
2485   BYTE *data = NULL;
2486   TPM_RESULT res;
2487   /* compute parameter digest */
2488   tpm_compute_in_param_digest(req);
2489   /* unmarshal input */
2490   ptr = req->param;
2491   len = req->paramSize;
2492   if (tpm_unmarshal_TPM_NV_INDEX(&ptr, &len, &nvIndex)
2493       || tpm_unmarshal_UINT32(&ptr, &len, &offset)
2494       || tpm_unmarshal_UINT32(&ptr, &len, &inDataSize)
2495       || len != 0) return TPM_BAD_PARAMETER;
2496   /* execute command */
2497   res = TPM_NV_ReadValueAuth(nvIndex, offset, inDataSize, &req->auth1, &outDataSize, &data);
2498   if (res != TPM_SUCCESS) return res;
2499   /* marshal output */
2500   rsp->paramSize = len = 4 + outDataSize;
2501   rsp->param = ptr = tpm_malloc(len);
2502   if (ptr == NULL
2503       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
2504       || tpm_marshal_BLOB(&ptr, &len, data, outDataSize)) {
2505     tpm_free(rsp->param);
2506     res = TPM_FAIL;
2507   }
2508   tpm_free(data);
2509   return res;
2510 }
2511 
execute_TPM_KeyControlOwner(TPM_REQUEST * req,TPM_RESPONSE * rsp)2512 static TPM_RESULT execute_TPM_KeyControlOwner(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2513 {
2514   BYTE *ptr;
2515   UINT32 len;
2516   TPM_KEY_HANDLE keyHandle;
2517   TPM_PUBKEY pubKey;
2518   UINT32 bitName;
2519   BOOL bitValue;
2520   /* compute parameter digest */
2521   tpm_compute_in_param_digest(req);
2522   /* unmarshal input */
2523   ptr = req->param;
2524   len = req->paramSize;
2525   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
2526       || tpm_unmarshal_TPM_PUBKEY(&ptr, &len, &pubKey)
2527       || tpm_unmarshal_UINT32(&ptr, &len, &bitName)
2528       || tpm_unmarshal_BOOL(&ptr, &len, &bitValue)
2529       || len != 0) return TPM_BAD_PARAMETER;
2530   /* execute command */
2531   return TPM_KeyControlOwner(keyHandle, pubKey, bitName, bitValue, &req->auth1);
2532 }
2533 
execute_TPM_SaveContext(TPM_REQUEST * req,TPM_RESPONSE * rsp)2534 static TPM_RESULT execute_TPM_SaveContext(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2535 {
2536   BYTE *ptr;
2537   UINT32 len;
2538   TPM_HANDLE handle;
2539   TPM_RESOURCE_TYPE resourceType;
2540   BYTE label[16];
2541   UINT32 contextSize;
2542   TPM_CONTEXT_BLOB contextBlob;
2543   TPM_RESULT res;
2544   /* unmarshal input */
2545   ptr = req->param;
2546   len = req->paramSize;
2547   if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &handle)
2548       || tpm_unmarshal_TPM_RESOURCE_TYPE(&ptr, &len, &resourceType)
2549       || tpm_unmarshal_BYTE_ARRAY(&ptr, &len, label, 16)
2550       || len != 0) return TPM_BAD_PARAMETER;
2551   /* execute command */
2552   res = TPM_SaveContext(handle, resourceType, label, &contextSize, &contextBlob);
2553   if (res != TPM_SUCCESS) return res;
2554   /* marshal output */
2555   rsp->paramSize = len = 4 + contextSize;
2556   rsp->param = ptr = tpm_malloc(len);
2557   if (ptr == NULL
2558       || tpm_marshal_UINT32(&ptr, &len, contextSize)
2559       || tpm_marshal_TPM_CONTEXT_BLOB(&ptr, &len, &contextBlob)) {
2560     tpm_free(rsp->param);
2561     res = TPM_FAIL;
2562   }
2563   free_TPM_CONTEXT_BLOB(contextBlob);
2564   return res;
2565 }
2566 
execute_TPM_LoadContext(TPM_REQUEST * req,TPM_RESPONSE * rsp)2567 static TPM_RESULT execute_TPM_LoadContext(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2568 {
2569   BYTE *ptr;
2570   UINT32 len;
2571   TPM_HANDLE entityHandle;
2572   BOOL keepHandle;
2573   UINT32 contextSize;
2574   TPM_CONTEXT_BLOB contextBlob;
2575   TPM_HANDLE handle;
2576   TPM_RESULT res;
2577   /* unmarshal input */
2578   ptr = req->param;
2579   len = req->paramSize;
2580   if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &entityHandle)
2581       || tpm_unmarshal_BOOL(&ptr, &len, &keepHandle)
2582       || tpm_unmarshal_UINT32(&ptr, &len, &contextSize)
2583       || tpm_unmarshal_TPM_CONTEXT_BLOB(&ptr, &len, &contextBlob)
2584       || len != 0) return TPM_BAD_PARAMETER;
2585   /* execute command */
2586   res = TPM_LoadContext(entityHandle, keepHandle, contextSize, &contextBlob, &handle);
2587   if (res != TPM_SUCCESS) return res;
2588   /* marshal output */
2589   rsp->paramSize = len = 4;
2590   rsp->param = ptr = tpm_malloc(len);
2591   if (ptr == NULL
2592       || tpm_marshal_TPM_HANDLE(&ptr, &len, handle)) {
2593     tpm_free(rsp->param);
2594     res = TPM_FAIL;
2595   }
2596   return res;
2597 }
2598 
execute_TPM_FlushSpecific(TPM_REQUEST * req,TPM_RESPONSE * rsp)2599 static TPM_RESULT execute_TPM_FlushSpecific(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2600 {
2601   BYTE *ptr;
2602   UINT32 len;
2603   TPM_HANDLE handle;
2604   TPM_RESOURCE_TYPE resourceType;
2605   /* unmarshal input */
2606   ptr = req->param;
2607   len = req->paramSize;
2608   if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &handle)
2609       || tpm_unmarshal_TPM_RESOURCE_TYPE(&ptr, &len, &resourceType)
2610       || len != 0) return TPM_BAD_PARAMETER;
2611   /* execute command */
2612 #ifdef MTM_EMULATOR
2613   return MTM_FlushSpecific(handle, resourceType);
2614 #else
2615   return TPM_FlushSpecific(handle, resourceType);
2616 #endif
2617 }
2618 
execute_TPM_GetTicks(TPM_REQUEST * req,TPM_RESPONSE * rsp)2619 static TPM_RESULT execute_TPM_GetTicks(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2620 {
2621   BYTE *ptr;
2622   UINT32 len;
2623   TPM_CURRENT_TICKS currentTime;
2624   TPM_RESULT res;
2625   /* execute command */
2626   res = TPM_GetTicks(&currentTime);
2627   if (res != TPM_SUCCESS) return res;
2628   /* marshal output */
2629   rsp->paramSize = len = 32;
2630   rsp->param = ptr = tpm_malloc(len);
2631   if (ptr == NULL
2632       || tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, &currentTime)) {
2633     tpm_free(rsp->param);
2634     res = TPM_FAIL;
2635   }
2636   return res;
2637 }
2638 
execute_TPM_TickStampBlob(TPM_REQUEST * req,TPM_RESPONSE * rsp)2639 static TPM_RESULT execute_TPM_TickStampBlob(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2640 {
2641   BYTE *ptr;
2642   UINT32 len;
2643   TPM_KEY_HANDLE keyHandle;
2644   TPM_NONCE antiReplay;
2645   TPM_DIGEST digestToStamp;
2646   TPM_CURRENT_TICKS currentTicks;
2647   UINT32 sigSize;
2648   BYTE *sig = NULL;
2649   TPM_RESULT res;
2650   /* compute parameter digest */
2651   tpm_compute_in_param_digest(req);
2652   /* unmarshal input */
2653   ptr = req->param;
2654   len = req->paramSize;
2655   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
2656       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
2657       || tpm_unmarshal_TPM_DIGEST(&ptr, &len, &digestToStamp)
2658       || len != 0) return TPM_BAD_PARAMETER;
2659   /* execute command */
2660   res = TPM_TickStampBlob(keyHandle, &antiReplay, &digestToStamp, &req->auth1,
2661     &currentTicks, &sigSize, &sig);
2662   if (res != TPM_SUCCESS) return res;
2663   /* marshal output */
2664   rsp->paramSize = len = 32 + 4 + sigSize;
2665   rsp->param = ptr = tpm_malloc(len);
2666   if (ptr == NULL
2667       || tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, &currentTicks)
2668       || tpm_marshal_UINT32(&ptr, &len, sigSize)
2669       || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)) {
2670     tpm_free(rsp->param);
2671     res = TPM_FAIL;
2672   }
2673   tpm_free(sig);
2674   return res;
2675 }
2676 
execute_TPM_EstablishTransport(TPM_REQUEST * req,TPM_RESPONSE * rsp)2677 static TPM_RESULT execute_TPM_EstablishTransport(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2678 {
2679   BYTE *ptr;
2680   UINT32 len;
2681   TPM_KEY_HANDLE encHandle;
2682   TPM_TRANSPORT_PUBLIC transPublic;
2683   UINT32 secretSize;
2684   BYTE *secret;
2685   TPM_TRANSHANDLE transHandle;
2686   TPM_MODIFIER_INDICATOR locality;
2687   TPM_CURRENT_TICKS currentTicks;
2688   TPM_NONCE transNonce;
2689   TPM_RESULT res;
2690   /* compute parameter digest */
2691   tpm_compute_in_param_digest(req);
2692   /* unmarshal input */
2693   ptr = req->param;
2694   len = req->paramSize;
2695   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &encHandle)
2696       || tpm_unmarshal_TPM_TRANSPORT_PUBLIC(&ptr, &len, &transPublic)
2697       || tpm_unmarshal_UINT32(&ptr, &len, &secretSize)
2698       || tpm_unmarshal_BLOB(&ptr, &len, &secret, secretSize)
2699       || len != 0) return TPM_BAD_PARAMETER;
2700   /* execute command */
2701   res = TPM_EstablishTransport(encHandle, &transPublic, secretSize, secret,
2702     &req->auth1, &transHandle, &locality, &currentTicks, &transNonce);
2703   if (res != TPM_SUCCESS) return res;
2704   /* marshal output */
2705   rsp->paramSize = len = 4 + 4 + 32 + 20;
2706   rsp->param = ptr = tpm_malloc(len);
2707   if (ptr == NULL
2708       || tpm_marshal_TPM_TRANSHANDLE(&ptr, &len, transHandle)
2709       || tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len,  locality)
2710       || tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, &currentTicks)
2711       || tpm_marshal_TPM_NONCE(&ptr, &len, &transNonce)) {
2712     tpm_free(rsp->param);
2713     res = TPM_FAIL;
2714   }
2715   return res;
2716 }
2717 
execute_TPM_ExecuteTransport(TPM_REQUEST * req,TPM_RESPONSE * rsp)2718 static TPM_RESULT execute_TPM_ExecuteTransport(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2719 {
2720   BYTE *ptr;
2721   UINT32 len;
2722   UINT32 inWrappedCmdSize;
2723   BYTE *inWrappedCmd;
2724   UINT64 currentTicks;
2725   TPM_MODIFIER_INDICATOR locality;
2726   UINT32 outWrappedCmdSize;
2727   BYTE *outWrappedCmd = NULL;
2728   TPM_RESULT res;
2729   /* compute parameter digest */
2730   tpm_compute_in_param_digest(req);
2731   /* unmarshal input */
2732   ptr = req->param;
2733   len = req->paramSize;
2734   if (tpm_unmarshal_UINT32(&ptr, &len, &inWrappedCmdSize)
2735       || tpm_unmarshal_BLOB(&ptr, &len, &inWrappedCmd, inWrappedCmdSize)
2736       || len != 0) return TPM_BAD_PARAMETER;
2737   /* execute command */
2738   res = TPM_ExecuteTransport(inWrappedCmdSize, inWrappedCmd, &req->auth1,
2739     &currentTicks, &locality, &outWrappedCmdSize, &outWrappedCmd);
2740   if (res != TPM_SUCCESS) return res;
2741   /* marshal output */
2742   rsp->paramSize = len = 8 + 4 + 4 + outWrappedCmdSize;
2743   rsp->param = ptr = tpm_malloc(len);
2744   if (ptr == NULL
2745       || tpm_marshal_UINT64(&ptr, &len, currentTicks)
2746       || tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, locality)
2747       || tpm_marshal_UINT32(&ptr, &len, outWrappedCmdSize)
2748       || tpm_marshal_BLOB(&ptr, &len, outWrappedCmd, outWrappedCmdSize)) {
2749     tpm_free(rsp->param);
2750     res = TPM_FAIL;
2751   }
2752   tpm_free(outWrappedCmd);
2753   return res;
2754 }
2755 
execute_TPM_ReleaseTransportSigned(TPM_REQUEST * req,TPM_RESPONSE * rsp)2756 static TPM_RESULT execute_TPM_ReleaseTransportSigned(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2757 {
2758   BYTE *ptr;
2759   UINT32 len;
2760   TPM_KEY_HANDLE key;
2761   TPM_NONCE antiReplay;
2762   TPM_MODIFIER_INDICATOR locality;
2763   TPM_CURRENT_TICKS currentTicks;
2764   UINT32 signSize;
2765   BYTE *signature = NULL;
2766   TPM_RESULT res;
2767   /* compute parameter digest */
2768   tpm_compute_in_param_digest(req);
2769   /* unmarshal input */
2770   ptr = req->param;
2771   len = req->paramSize;
2772   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &key)
2773       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
2774       || len != 0) return TPM_BAD_PARAMETER;
2775   /* execute command */
2776   res = TPM_ReleaseTransportSigned(key, &antiReplay, &req->auth1, &req->auth2,
2777     &locality, &currentTicks, &signSize, &signature);
2778   if (res != TPM_SUCCESS) return res;
2779   /* marshal output */
2780   rsp->paramSize = len = 4 + 32 + 4 + signSize;
2781   rsp->param = ptr = tpm_malloc(len);
2782   if (ptr == NULL
2783       || tpm_marshal_TPM_MODIFIER_INDICATOR(&ptr, &len, locality)
2784       || tpm_marshal_TPM_CURRENT_TICKS(&ptr, &len, &currentTicks)
2785       || tpm_marshal_UINT32(&ptr, &len, signSize)
2786       || tpm_marshal_BLOB(&ptr, &len, signature, signSize)) {
2787     tpm_free(rsp->param);
2788     res = TPM_FAIL;
2789   }
2790   tpm_free(signature);
2791   return res;
2792 }
2793 
execute_TPM_CreateCounter(TPM_REQUEST * req,TPM_RESPONSE * rsp)2794 static TPM_RESULT execute_TPM_CreateCounter(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2795 {
2796   BYTE *ptr;
2797   UINT32 len;
2798   TPM_ENCAUTH authData;
2799   BYTE label[4];
2800   TPM_COUNT_ID countID;
2801   TPM_COUNTER_VALUE counterValue;
2802   TPM_RESULT res;
2803   /* compute parameter digest */
2804   tpm_compute_in_param_digest(req);
2805   /* unmarshal input */
2806   ptr = req->param;
2807   len = req->paramSize;
2808   if (tpm_unmarshal_TPM_ENCAUTH(&ptr, &len, &authData)
2809       || tpm_unmarshal_BYTE_ARRAY(&ptr, &len, label, 4)
2810       || len != 0) return TPM_BAD_PARAMETER;
2811   /* execute command */
2812   res = TPM_CreateCounter(&authData, label, &req->auth1, &countID, &counterValue);
2813   if (res != TPM_SUCCESS) return res;
2814   /* marshal output */
2815   rsp->paramSize = len = 4 + sizeof_TPM_COUNTER_VALUE(counterValue);
2816   rsp->param = ptr = tpm_malloc(len);
2817   if (ptr == NULL
2818       || tpm_marshal_TPM_COUNT_ID(&ptr, &len, countID)
2819       || tpm_marshal_TPM_COUNTER_VALUE(&ptr, &len, &counterValue)) {
2820     tpm_free(rsp->param);
2821     res = TPM_FAIL;
2822   }
2823   return res;
2824 }
2825 
execute_TPM_IncrementCounter(TPM_REQUEST * req,TPM_RESPONSE * rsp)2826 static TPM_RESULT execute_TPM_IncrementCounter(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2827 {
2828   BYTE *ptr;
2829   UINT32 len;
2830   TPM_COUNT_ID countID;
2831   TPM_COUNTER_VALUE count;
2832   TPM_RESULT res;
2833   /* compute parameter digest */
2834   tpm_compute_in_param_digest(req);
2835   /* unmarshal input */
2836   ptr = req->param;
2837   len = req->paramSize;
2838   if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID)
2839       || len != 0) return TPM_BAD_PARAMETER;
2840   /* execute command */
2841   res = TPM_IncrementCounter(countID, &req->auth1, &count);
2842   if (res != TPM_SUCCESS) return res;
2843   /* marshal output */
2844   rsp->paramSize = len = 10;
2845   rsp->param = ptr = tpm_malloc(len);
2846   if (ptr == NULL
2847       || tpm_marshal_TPM_COUNTER_VALUE(&ptr, &len, &count)) {
2848     tpm_free(rsp->param);
2849     res = TPM_FAIL;
2850   }
2851   return res;
2852 }
2853 
execute_TPM_ReadCounter(TPM_REQUEST * req,TPM_RESPONSE * rsp)2854 static TPM_RESULT execute_TPM_ReadCounter(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2855 {
2856   BYTE *ptr;
2857   UINT32 len;
2858   TPM_COUNT_ID countID;
2859   TPM_COUNTER_VALUE count;
2860   TPM_RESULT res;
2861   /* unmarshal input */
2862   ptr = req->param;
2863   len = req->paramSize;
2864   if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID)
2865       || len != 0) return TPM_BAD_PARAMETER;
2866   /* execute command */
2867   res = TPM_ReadCounter(countID, &count);
2868   if (res != TPM_SUCCESS) return res;
2869   /* marshal output */
2870   rsp->paramSize = len = 10;
2871   rsp->param = ptr = tpm_malloc(len);
2872   if (ptr == NULL
2873       || tpm_marshal_TPM_COUNTER_VALUE(&ptr, &len, &count)) {
2874     tpm_free(rsp->param);
2875     res = TPM_FAIL;
2876   }
2877   return res;
2878 }
2879 
execute_TPM_ReleaseCounter(TPM_REQUEST * req,TPM_RESPONSE * rsp)2880 static TPM_RESULT execute_TPM_ReleaseCounter(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2881 {
2882   BYTE *ptr;
2883   UINT32 len;
2884   TPM_COUNT_ID countID;
2885   /* compute parameter digest */
2886   tpm_compute_in_param_digest(req);
2887   /* unmarshal input */
2888   ptr = req->param;
2889   len = req->paramSize;
2890   if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID)
2891       || len != 0) return TPM_BAD_PARAMETER;
2892   /* execute command */
2893 #ifdef MTM_EMULATOR
2894   return MTM_ReleaseCounter(countID, &req->auth1);
2895 #else
2896   return TPM_ReleaseCounter(countID, &req->auth1);
2897 #endif
2898 }
2899 
execute_TPM_ReleaseCounterOwner(TPM_REQUEST * req,TPM_RESPONSE * rsp)2900 static TPM_RESULT execute_TPM_ReleaseCounterOwner(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2901 {
2902   BYTE *ptr;
2903   UINT32 len;
2904   TPM_COUNT_ID countID;
2905   /* compute parameter digest */
2906   tpm_compute_in_param_digest(req);
2907   /* unmarshal input */
2908   ptr = req->param;
2909   len = req->paramSize;
2910   if (tpm_unmarshal_TPM_COUNT_ID(&ptr, &len, &countID)
2911       || len != 0) return TPM_BAD_PARAMETER;
2912   /* execute command */
2913 #ifdef MTM_EMULATOR
2914   return MTM_ReleaseCounterOwner(countID, &req->auth1);
2915 #else
2916   return TPM_ReleaseCounterOwner(countID, &req->auth1);
2917 #endif
2918 }
2919 
execute_TPM_DAA_Join(TPM_REQUEST * req,TPM_RESPONSE * rsp)2920 static TPM_RESULT execute_TPM_DAA_Join(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2921 {
2922   BYTE *ptr;
2923   UINT32 len;
2924   TPM_HANDLE handle;
2925   BYTE stage;
2926   UINT32 inputSize0;
2927   BYTE *inputData0;
2928   UINT32 inputSize1;
2929   BYTE *inputData1;
2930   TPM_COMMAND_CODE ordinal;
2931   UINT32 outputSize;
2932   BYTE *outputData = NULL;
2933   TPM_RESULT res;
2934   /* compute parameter digest */
2935   tpm_compute_in_param_digest(req);
2936   /* unmarshal input */
2937   ptr = req->param;
2938   len = req->paramSize;
2939   if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &handle)
2940       || tpm_unmarshal_BYTE(&ptr, &len, &stage)
2941       || tpm_unmarshal_UINT32(&ptr, &len, &inputSize0)
2942       || tpm_unmarshal_BLOB(&ptr, &len, &inputData0, inputSize0)
2943       || tpm_unmarshal_UINT32(&ptr, &len, &inputSize1)
2944       || tpm_unmarshal_BLOB(&ptr, &len, &inputData1, inputSize1)
2945       || len != 0) return TPM_BAD_PARAMETER;
2946   /* execute command */
2947   res = TPM_DAA_Join(handle, stage, inputSize0, inputData0, inputSize1,
2948     inputData1, &req->auth1, &ordinal, &outputSize, &outputData);
2949   if (res != TPM_SUCCESS) return res;
2950   /* marshal output */
2951   rsp->paramSize = len = 4 + outputSize;
2952   rsp->param = ptr = tpm_malloc(len);
2953   if (ptr == NULL
2954       || tpm_marshal_UINT32(&ptr, &len, outputSize)
2955       || tpm_marshal_BLOB(&ptr, &len, outputData, outputSize)) {
2956     tpm_free(rsp->param);
2957     res = TPM_FAIL;
2958   }
2959   tpm_free(outputData);
2960   return res;
2961 }
2962 
execute_TPM_DAA_Sign(TPM_REQUEST * req,TPM_RESPONSE * rsp)2963 static TPM_RESULT execute_TPM_DAA_Sign(TPM_REQUEST *req, TPM_RESPONSE *rsp)
2964 {
2965   BYTE *ptr;
2966   UINT32 len;
2967   TPM_HANDLE handle;
2968   BYTE stage;
2969   UINT32 inputSize0;
2970   BYTE *inputData0;
2971   UINT32 inputSize1;
2972   BYTE *inputData1;
2973   TPM_COMMAND_CODE ordinal;
2974   UINT32 outputSize;
2975   BYTE *outputData = NULL;
2976   TPM_RESULT res;
2977   /* compute parameter digest */
2978   tpm_compute_in_param_digest(req);
2979   /* unmarshal input */
2980   ptr = req->param;
2981   len = req->paramSize;
2982   if (tpm_unmarshal_TPM_HANDLE(&ptr, &len, &handle)
2983       || tpm_unmarshal_BYTE(&ptr, &len, &stage)
2984       || tpm_unmarshal_UINT32(&ptr, &len, &inputSize0)
2985       || tpm_unmarshal_BLOB(&ptr, &len, &inputData0, inputSize0)
2986       || tpm_unmarshal_UINT32(&ptr, &len, &inputSize1)
2987       || tpm_unmarshal_BLOB(&ptr, &len, &inputData1, inputSize1)
2988       || len != 0) return TPM_BAD_PARAMETER;
2989   /* execute command */
2990   res = TPM_DAA_Sign(handle, stage, inputSize0, inputData0, inputSize1,
2991     inputData1, &req->auth1, &ordinal, &outputSize, &outputData);
2992   if (res != TPM_SUCCESS) return res;
2993   /* marshal output */
2994   rsp->paramSize = len = 4 + outputSize;
2995   rsp->param = ptr = tpm_malloc(len);
2996   if (ptr == NULL
2997       || tpm_marshal_UINT32(&ptr, &len, outputSize)
2998       || tpm_marshal_BLOB(&ptr, &len, outputData, outputSize)) {
2999     tpm_free(rsp->param);
3000     res = TPM_FAIL;
3001   }
3002   tpm_free(outputData);
3003   return res;
3004 }
3005 
execute_TPM_EvictKey(TPM_REQUEST * req,TPM_RESPONSE * rsp)3006 static TPM_RESULT execute_TPM_EvictKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3007 {
3008   BYTE *ptr;
3009   UINT32 len;
3010   TPM_KEY_HANDLE evictHandle;
3011   /* unmarshal input */
3012   ptr = req->param;
3013   len = req->paramSize;
3014   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &evictHandle)
3015       || len != 0) return TPM_BAD_PARAMETER;
3016   /* execute command */
3017   return TPM_EvictKey(evictHandle);
3018 }
3019 
execute_TPM_Terminate_Handle(TPM_REQUEST * req,TPM_RESPONSE * rsp)3020 static TPM_RESULT execute_TPM_Terminate_Handle(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3021 {
3022   BYTE *ptr;
3023   UINT32 len;
3024   TPM_AUTHHANDLE handle;
3025   /* unmarshal input */
3026   ptr = req->param;
3027   len = req->paramSize;
3028   if (tpm_unmarshal_TPM_AUTHHANDLE(&ptr, &len, &handle)
3029       || len != 0) return TPM_BAD_PARAMETER;
3030   /* execute command */
3031   return TPM_Terminate_Handle(handle);
3032 }
3033 
execute_TPM_SaveKeyContext(TPM_REQUEST * req,TPM_RESPONSE * rsp)3034 static TPM_RESULT execute_TPM_SaveKeyContext(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3035 {
3036   BYTE *ptr;
3037   UINT32 len;
3038   TPM_KEY_HANDLE keyHandle;
3039   UINT32 keyContextSize;
3040   BYTE *keyContextBlob = NULL;
3041   TPM_RESULT res;
3042   /* unmarshal input */
3043   ptr = req->param;
3044   len = req->paramSize;
3045   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &keyHandle)
3046       || len != 0) return TPM_BAD_PARAMETER;
3047   /* execute command */
3048   res = TPM_SaveKeyContext(keyHandle, &keyContextSize, &keyContextBlob);
3049   if (res != TPM_SUCCESS) return res;
3050   /* marshal output */
3051   rsp->paramSize = len = 4 + keyContextSize;
3052   rsp->param = ptr = tpm_malloc(len);
3053   if (ptr == NULL
3054       || tpm_marshal_UINT32(&ptr, &len, keyContextSize)
3055       || tpm_marshal_BLOB(&ptr, &len, keyContextBlob, keyContextSize)) {
3056     tpm_free(rsp->param);
3057     res = TPM_FAIL;
3058   }
3059   tpm_free(keyContextBlob);
3060   return res;
3061 }
3062 
execute_TPM_LoadKeyContext(TPM_REQUEST * req,TPM_RESPONSE * rsp)3063 static TPM_RESULT execute_TPM_LoadKeyContext(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3064 {
3065   BYTE *ptr;
3066   UINT32 len;
3067   UINT32 keyContextSize;
3068   BYTE *keyContextBlob;
3069   TPM_KEY_HANDLE keyHandle;
3070   TPM_RESULT res;
3071   /* unmarshal input */
3072   ptr = req->param;
3073   len = req->paramSize;
3074   if (tpm_unmarshal_UINT32(&ptr, &len, &keyContextSize)
3075       || tpm_unmarshal_BLOB(&ptr, &len, &keyContextBlob, keyContextSize)
3076       || len != 0) return TPM_BAD_PARAMETER;
3077   /* execute command */
3078   res = TPM_LoadKeyContext(keyContextSize, keyContextBlob, &keyHandle);
3079   if (res != TPM_SUCCESS) return res;
3080   /* marshal output */
3081   rsp->paramSize = len = 4;
3082   rsp->param = ptr = tpm_malloc(len);
3083   if (ptr == NULL
3084       || tpm_marshal_TPM_KEY_HANDLE(&ptr, &len, keyHandle)) {
3085     tpm_free(rsp->param);
3086     res = TPM_FAIL;
3087   }
3088   return res;
3089 }
3090 
execute_TPM_SaveAuthContext(TPM_REQUEST * req,TPM_RESPONSE * rsp)3091 static TPM_RESULT execute_TPM_SaveAuthContext(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3092 {
3093   BYTE *ptr;
3094   UINT32 len;
3095   TPM_AUTHHANDLE authandle;
3096   UINT32 authContextSize;
3097   BYTE *authContextBlob = NULL;
3098   TPM_RESULT res;
3099   /* unmarshal input */
3100   ptr = req->param;
3101   len = req->paramSize;
3102   if (tpm_unmarshal_TPM_AUTHHANDLE(&ptr, &len, &authandle)
3103       || len != 0) return TPM_BAD_PARAMETER;
3104   /* execute command */
3105   res = TPM_SaveAuthContext(authandle, &authContextSize, &authContextBlob);
3106   if (res != TPM_SUCCESS) return res;
3107   /* marshal output */
3108   rsp->paramSize = len = 4 + authContextSize;
3109   rsp->param = ptr = tpm_malloc(len);
3110   if (ptr == NULL
3111       || tpm_marshal_UINT32(&ptr, &len, authContextSize)
3112       || tpm_marshal_BLOB(&ptr, &len, authContextBlob, authContextSize)) {
3113     tpm_free(rsp->param);
3114     res = TPM_FAIL;
3115   }
3116   tpm_free(authContextBlob);
3117   return res;
3118 }
3119 
execute_TPM_LoadAuthContext(TPM_REQUEST * req,TPM_RESPONSE * rsp)3120 static TPM_RESULT execute_TPM_LoadAuthContext(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3121 {
3122   BYTE *ptr;
3123   UINT32 len;
3124   UINT32 authContextSize;
3125   BYTE *authContextBlob;
3126   TPM_KEY_HANDLE authHandle;
3127   TPM_RESULT res;
3128   /* unmarshal input */
3129   ptr = req->param;
3130   len = req->paramSize;
3131   if (tpm_unmarshal_UINT32(&ptr, &len, &authContextSize)
3132       || tpm_unmarshal_BLOB(&ptr, &len, &authContextBlob, authContextSize)
3133       || len != 0) return TPM_BAD_PARAMETER;
3134   /* execute command */
3135   res = TPM_LoadAuthContext(authContextSize, authContextBlob, &authHandle);
3136   if (res != TPM_SUCCESS) return res;
3137   /* marshal output */
3138   rsp->paramSize = len = 4;
3139   rsp->param = ptr = tpm_malloc(len);
3140   if (ptr == NULL
3141       || tpm_marshal_TPM_KEY_HANDLE(&ptr, &len, authHandle)) {
3142     tpm_free(rsp->param);
3143     res = TPM_FAIL;
3144   }
3145   return res;
3146 }
3147 
execute_TPM_DirWriteAuth(TPM_REQUEST * req,TPM_RESPONSE * rsp)3148 static TPM_RESULT execute_TPM_DirWriteAuth(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3149 {
3150   BYTE *ptr;
3151   UINT32 len;
3152   TPM_DIRINDEX dirIndex;
3153   TPM_DIRVALUE newContents;
3154   /* compute parameter digest */
3155   tpm_compute_in_param_digest(req);
3156   /* unmarshal input */
3157   ptr = req->param;
3158   len = req->paramSize;
3159   if (tpm_unmarshal_TPM_DIRINDEX(&ptr, &len, &dirIndex)
3160       || tpm_unmarshal_TPM_DIRVALUE(&ptr, &len, &newContents)
3161       || len != 0) return TPM_BAD_PARAMETER;
3162   /* execute command */
3163   return TPM_DirWriteAuth(dirIndex, &newContents, &req->auth1);
3164 }
3165 
execute_TPM_DirRead(TPM_REQUEST * req,TPM_RESPONSE * rsp)3166 static TPM_RESULT execute_TPM_DirRead(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3167 {
3168   BYTE *ptr;
3169   UINT32 len;
3170   TPM_DIRINDEX dirIndex;
3171   TPM_DIRVALUE dirContents;
3172   TPM_RESULT res;
3173   /* unmarshal input */
3174   ptr = req->param;
3175   len = req->paramSize;
3176   if (tpm_unmarshal_TPM_DIRINDEX(&ptr, &len, &dirIndex)
3177       || len != 0) return TPM_BAD_PARAMETER;
3178   /* execute command */
3179   res = TPM_DirRead(dirIndex, &dirContents);
3180   if (res != TPM_SUCCESS) return res;
3181   /* marshal output */
3182   rsp->paramSize = len = 20;
3183   rsp->param = ptr = tpm_malloc(len);
3184   if (ptr == NULL
3185       || tpm_marshal_TPM_DIRVALUE(&ptr, &len, &dirContents)) {
3186     tpm_free(rsp->param);
3187     res = TPM_FAIL;
3188   }
3189   return res;
3190 }
3191 
execute_TPM_ChangeAuthAsymStart(TPM_REQUEST * req,TPM_RESPONSE * rsp)3192 static TPM_RESULT execute_TPM_ChangeAuthAsymStart(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3193 {
3194   BYTE *ptr;
3195   UINT32 len;
3196   TPM_KEY_HANDLE idHandle;
3197   TPM_NONCE antiReplay;
3198   TPM_KEY_PARMS inTempKey;
3199   TPM_CERTIFY_INFO certifyInfo;
3200   UINT32 sigSize;
3201   BYTE *sig = NULL;
3202   TPM_KEY_HANDLE ephHandle;
3203   TPM_KEY outTempKey;
3204   TPM_RESULT res;
3205   /* compute parameter digest */
3206   tpm_compute_in_param_digest(req);
3207   /* unmarshal input */
3208   ptr = req->param;
3209   len = req->paramSize;
3210   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &idHandle)
3211       || tpm_unmarshal_TPM_NONCE(&ptr, &len, &antiReplay)
3212       || tpm_unmarshal_TPM_KEY_PARMS(&ptr, &len, &inTempKey)
3213       || len != 0) return TPM_BAD_PARAMETER;
3214   /* execute command */
3215   res = TPM_ChangeAuthAsymStart(idHandle, &antiReplay, &inTempKey, &req->auth1,
3216     &certifyInfo, &sigSize, &sig, &ephHandle, &outTempKey);
3217   if (res != TPM_SUCCESS) return res;
3218   /* marshal output */
3219   rsp->paramSize = len = 95 + 4 + sigSize + 4 + sizeof_TPM_KEY(outTempKey);
3220   rsp->param = ptr = tpm_malloc(len);
3221   if (ptr == NULL
3222       || tpm_marshal_TPM_CERTIFY_INFO(&ptr, &len, &certifyInfo)
3223       || tpm_marshal_UINT32(&ptr, &len, sigSize)
3224       || tpm_marshal_BLOB(&ptr, &len, sig, sigSize)
3225       || tpm_marshal_TPM_KEY_HANDLE(&ptr, &len, ephHandle)
3226       || tpm_marshal_TPM_KEY(&ptr, &len, &outTempKey)) {
3227     tpm_free(rsp->param);
3228     res = TPM_FAIL;
3229   }
3230   tpm_free(sig);
3231   free_TPM_KEY(outTempKey);
3232   return res;
3233 }
3234 
execute_TPM_ChangeAuthAsymFinish(TPM_REQUEST * req,TPM_RESPONSE * rsp)3235 static TPM_RESULT execute_TPM_ChangeAuthAsymFinish(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3236 {
3237   BYTE *ptr;
3238   UINT32 len;
3239   TPM_KEY_HANDLE parentHandle;
3240   TPM_KEY_HANDLE ephHandle;
3241   TPM_ENTITY_TYPE entityType;
3242   TPM_HMAC newAuthLink;
3243   UINT32 newAuthSize;
3244   BYTE *encNewAuth;
3245   UINT32 encDataSize;
3246   BYTE *encData;
3247   UINT32 outDataSize;
3248   BYTE *outData = NULL;
3249   TPM_NONCE saltNonce;
3250   TPM_DIGEST changeProof;
3251   TPM_RESULT res;
3252   /* compute parameter digest */
3253   tpm_compute_in_param_digest(req);
3254   /* unmarshal input */
3255   ptr = req->param;
3256   len = req->paramSize;
3257   if (tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &parentHandle)
3258       || tpm_unmarshal_TPM_KEY_HANDLE(&ptr, &len, &ephHandle)
3259       || tpm_unmarshal_TPM_ENTITY_TYPE(&ptr, &len, &entityType)
3260       || tpm_unmarshal_TPM_HMAC(&ptr, &len, &newAuthLink)
3261       || tpm_unmarshal_UINT32(&ptr, &len, &newAuthSize)
3262       || tpm_unmarshal_BLOB(&ptr, &len, &encNewAuth, newAuthSize)
3263       || tpm_unmarshal_UINT32(&ptr, &len, &encDataSize)
3264       || tpm_unmarshal_BLOB(&ptr, &len, &encData, encDataSize)
3265       || len != 0) return TPM_BAD_PARAMETER;
3266   /* execute command */
3267   res = TPM_ChangeAuthAsymFinish(parentHandle, ephHandle, entityType,
3268     &newAuthLink, newAuthSize, encNewAuth, encDataSize, encData, &req->auth1,
3269     &outDataSize, &outData, &saltNonce, &changeProof);
3270   if (res != TPM_SUCCESS) return res;
3271   /* marshal output */
3272   rsp->paramSize = len = 4 + outDataSize + 20 + 20;
3273   rsp->param = ptr = tpm_malloc(len);
3274   if (ptr == NULL
3275       || tpm_marshal_UINT32(&ptr, &len, outDataSize)
3276       || tpm_marshal_BLOB(&ptr, &len, outData, outDataSize)
3277       || tpm_marshal_TPM_NONCE(&ptr, &len, &saltNonce)
3278       || tpm_marshal_TPM_DIGEST(&ptr, &len, &changeProof)) {
3279     tpm_free(rsp->param);
3280     res = TPM_FAIL;
3281   }
3282   tpm_free(outData);
3283   return res;
3284 }
3285 
execute_TPM_Reset(TPM_REQUEST * req,TPM_RESPONSE * rsp)3286 static TPM_RESULT execute_TPM_Reset(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3287 {
3288   /* execute command */
3289   return TPM_Reset();
3290 }
3291 
execute_TPM_OwnerReadPubek(TPM_REQUEST * req,TPM_RESPONSE * rsp)3292 static TPM_RESULT execute_TPM_OwnerReadPubek(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3293 {
3294   BYTE *ptr;
3295   UINT32 len;
3296   TPM_PUBKEY pubEndorsementKey;
3297   TPM_RESULT res;
3298   /* compute parameter digest */
3299   tpm_compute_in_param_digest(req);
3300   /* execute command */
3301   res = TPM_OwnerReadPubek(&req->auth1, &pubEndorsementKey);
3302   if (res != TPM_SUCCESS) return res;
3303   /* marshal output */
3304   rsp->paramSize = len = sizeof_TPM_PUBKEY(pubEndorsementKey);
3305   rsp->param = ptr = tpm_malloc(len);
3306   if (ptr == NULL
3307       || tpm_marshal_TPM_PUBKEY(&ptr, &len, &pubEndorsementKey)) {
3308     tpm_free(rsp->param);
3309     res = TPM_FAIL;
3310   }
3311   free_TPM_PUBKEY(pubEndorsementKey);
3312   return res;
3313 }
3314 
tpm_setup_rsp_auth(TPM_COMMAND_CODE ordinal,TPM_RESPONSE * rsp)3315 static void tpm_setup_rsp_auth(TPM_COMMAND_CODE ordinal, TPM_RESPONSE *rsp)
3316 {
3317   tpm_hmac_ctx_t hmac;
3318 
3319   /* compute parameter digest */
3320   if (ordinal != TPM_ORD_ExecuteTransport)
3321     tpm_compute_out_param_digest(ordinal, rsp);
3322   /* compute authorization values */
3323   switch (rsp->tag) {
3324     case TPM_TAG_RSP_AUTH2_COMMAND:
3325       tpm_hmac_init(&hmac, rsp->auth2->secret, sizeof(rsp->auth2->secret));
3326       tpm_hmac_update(&hmac, rsp->auth2->digest, sizeof(rsp->auth2->digest));
3327       tpm_hmac_update(&hmac, rsp->auth2->nonceEven.nonce,
3328                   sizeof(rsp->auth2->nonceEven.nonce));
3329       tpm_hmac_update(&hmac, rsp->auth2->nonceOdd.nonce,
3330                   sizeof(rsp->auth2->nonceOdd.nonce));
3331       tpm_hmac_update(&hmac, (BYTE*)&rsp->auth2->continueAuthSession, 1);
3332       tpm_hmac_final(&hmac, rsp->auth2->auth);
3333     case TPM_TAG_RSP_AUTH1_COMMAND:
3334       tpm_hmac_init(&hmac, rsp->auth1->secret, sizeof(rsp->auth1->secret));
3335       tpm_hmac_update(&hmac, rsp->auth1->digest, sizeof(rsp->auth1->digest));
3336       tpm_hmac_update(&hmac, rsp->auth1->nonceEven.nonce,
3337         sizeof(rsp->auth1->nonceEven.nonce));
3338       tpm_hmac_update(&hmac, rsp->auth1->nonceOdd.nonce,
3339         sizeof(rsp->auth1->nonceOdd.nonce));
3340       tpm_hmac_update(&hmac, (BYTE*)&rsp->auth1->continueAuthSession, 1);
3341       tpm_hmac_final(&hmac, rsp->auth1->auth);
3342       break;
3343   }
3344 }
3345 
tpm_setup_error_response(TPM_RESULT res,TPM_RESPONSE * rsp)3346 static void tpm_setup_error_response(TPM_RESULT res, TPM_RESPONSE *rsp)
3347 {
3348   rsp->tag = TPM_TAG_RSP_COMMAND;
3349   rsp->size = 10;
3350   rsp->result = res;
3351   rsp->param = NULL;
3352   rsp->paramSize = 0;
3353 }
3354 
tpm_check_status_and_mode(TPM_REQUEST * req)3355 static TPM_RESULT tpm_check_status_and_mode(TPM_REQUEST *req)
3356 {
3357   /* verify that self-test succeeded */
3358   if (!tpmData.permanent.flags.selfTestSucceeded) return TPM_FAILEDSELFTEST;
3359   /* initialisation must be finished before we execute any command */
3360   if (tpmData.stany.flags.postInitialise) return TPM_INVALID_POSTINIT;
3361   /* if the TPM is deactivated only a subset of all commands can be performed */
3362   if ((tpmData.permanent.flags.deactivated || tpmData.stclear.flags.deactivated)
3363       && req->ordinal != TPM_ORD_Reset
3364       && req->ordinal != TPM_ORD_Init
3365       && req->ordinal != TPM_ORD_Startup
3366       && req->ordinal != TPM_ORD_SaveState
3367       && req->ordinal != TPM_ORD_SHA1Start
3368       && req->ordinal != TPM_ORD_SHA1Update
3369       && req->ordinal != TPM_ORD_SHA1Complete
3370       && req->ordinal != TPM_ORD_SHA1CompleteExtend
3371       && req->ordinal != TPM_ORD_OIAP
3372       && req->ordinal != TPM_ORD_OSAP
3373       && req->ordinal != TPM_ORD_DSAP
3374       && req->ordinal != TPM_ORD_GetCapability
3375       && req->ordinal != TPM_ORD_SetCapability
3376       && req->ordinal != TPM_ORD_TakeOwnership
3377       && req->ordinal != TPM_ORD_OwnerSetDisable
3378       && req->ordinal != TPM_ORD_PhysicalDisable
3379       && req->ordinal != TPM_ORD_PhysicalEnable
3380       && req->ordinal != TPM_ORD_PhysicalSetDeactivated
3381       && req->ordinal != TPM_ORD_ContinueSelfTest
3382       && req->ordinal != TPM_ORD_SelfTestFull
3383       && req->ordinal != TPM_ORD_GetTestResult
3384       && req->ordinal != TPM_ORD_FlushSpecific
3385       && req->ordinal != TPM_ORD_Terminate_Handle
3386       && req->ordinal != TPM_ORD_Extend
3387       && req->ordinal != TPM_ORD_PCR_Reset
3388       && req->ordinal != TPM_ORD_NV_DefineSpace
3389       && req->ordinal != TPM_ORD_NV_ReadValue
3390       && req->ordinal != TPM_ORD_NV_WriteValue
3391       && req->ordinal != TSC_ORD_PhysicalPresence
3392       && req->ordinal != TSC_ORD_ResetEstablishmentBit
3393       ) return TPM_DEACTIVATED;
3394   /* if the TPM is disabled only a subset of all commands can be performed */
3395   if (tpmData.permanent.flags.disable
3396       && req->ordinal != TPM_ORD_Reset
3397       && req->ordinal != TPM_ORD_Init
3398       && req->ordinal != TPM_ORD_Startup
3399       && req->ordinal != TPM_ORD_SaveState
3400       && req->ordinal != TPM_ORD_SHA1Start
3401       && req->ordinal != TPM_ORD_SHA1Update
3402       && req->ordinal != TPM_ORD_SHA1Complete
3403       && req->ordinal != TPM_ORD_SHA1CompleteExtend
3404       && req->ordinal != TPM_ORD_OIAP
3405       && req->ordinal != TPM_ORD_OSAP
3406       && req->ordinal != TPM_ORD_DSAP
3407       && req->ordinal != TPM_ORD_GetCapability
3408       && req->ordinal != TPM_ORD_SetCapability
3409       && req->ordinal != TPM_ORD_OwnerSetDisable
3410       && req->ordinal != TPM_ORD_PhysicalEnable
3411       && req->ordinal != TPM_ORD_ContinueSelfTest
3412       && req->ordinal != TPM_ORD_SelfTestFull
3413       && req->ordinal != TPM_ORD_GetTestResult
3414       && req->ordinal != TPM_ORD_FlushSpecific
3415       && req->ordinal != TPM_ORD_Terminate_Handle
3416       && req->ordinal != TPM_ORD_Extend
3417       && req->ordinal != TPM_ORD_PCR_Reset
3418       && req->ordinal != TPM_ORD_NV_DefineSpace
3419       && req->ordinal != TPM_ORD_NV_ReadValue
3420       && req->ordinal != TPM_ORD_NV_WriteValue
3421       && req->ordinal != TSC_ORD_PhysicalPresence
3422       && req->ordinal != TSC_ORD_ResetEstablishmentBit
3423       ) return TPM_DISABLED;
3424   return TPM_SUCCESS;
3425 }
3426 
tpm_execute_command(TPM_REQUEST * req,TPM_RESPONSE * rsp)3427 void tpm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
3428 {
3429   TPM_RESULT res;
3430 
3431   /* setup authorisation as well as response tag and size */
3432   memset(rsp, 0, sizeof(*rsp));
3433   switch (req->tag) {
3434     case TPM_TAG_RQU_AUTH2_COMMAND:
3435       debug("[TPM_TAG_RQU_AUTH2_COMMAND]");
3436       rsp->tag = TPM_TAG_RSP_AUTH2_COMMAND;
3437       rsp->size = 10 + 2 * 41;
3438       rsp->auth1 = &req->auth1;
3439       rsp->auth2 = &req->auth2;
3440       break;
3441 
3442     case TPM_TAG_RQU_AUTH1_COMMAND:
3443       debug("[TPM_TAG_RQU_AUTH1_COMMAND]");
3444       rsp->tag = TPM_TAG_RSP_AUTH1_COMMAND;
3445       rsp->size = 10 + 41;
3446       rsp->auth1 = &req->auth1;
3447       break;
3448 
3449     case TPM_TAG_RQU_COMMAND:
3450       debug("[TPM_TAG_RQU_COMMAND]");
3451       rsp->tag = TPM_TAG_RSP_COMMAND;
3452       rsp->size = 10;
3453       break;
3454 
3455     default:
3456       info("The tag value sent to for a command (0x%02x) is invalid", req->tag);
3457       tpm_setup_error_response(TPM_BADTAG, rsp);
3458       return;
3459   }
3460 
3461   /* check whether the command is allowed in the current mode of the TPM */
3462   res = tpm_check_status_and_mode(req);
3463   if (res != TPM_SUCCESS) {
3464     info("tpm_check_status_and_mode(0x%02x) failed: (0x%02x) %s",
3465          req->ordinal, res, tpm_error_to_string(res));
3466     tpm_setup_error_response(res, rsp);
3467     return;
3468   }
3469 
3470   /* handle command ordinal */
3471   switch (req->ordinal) {
3472     case TPM_ORD_Startup:
3473       debug("[TPM_ORD_Startup]");
3474       res = execute_TPM_Startup(req, rsp);
3475     break;
3476 
3477     case TPM_ORD_SaveState:
3478       debug("[TPM_ORD_SaveState]");
3479       res = execute_TPM_SaveState(req, rsp);
3480     break;
3481 
3482     case TPM_ORD_SelfTestFull:
3483       debug("[TPM_ORD_SelfTestFull]");
3484       res = execute_TPM_SelfTestFull(req, rsp);
3485     break;
3486 
3487     case TPM_ORD_ContinueSelfTest:
3488       debug("[TPM_ORD_ContinueSelfTest]");
3489       res = execute_TPM_ContinueSelfTest(req, rsp);
3490     break;
3491 
3492     case TPM_ORD_GetTestResult:
3493       debug("[TPM_ORD_GetTestResult]");
3494       res = execute_TPM_GetTestResult(req, rsp);
3495     break;
3496 
3497     case TPM_ORD_SetOwnerInstall:
3498       debug("[TPM_ORD_SetOwnerInstall]");
3499       res = execute_TPM_SetOwnerInstall(req, rsp);
3500     break;
3501 
3502     case TPM_ORD_OwnerSetDisable:
3503       debug("[TPM_ORD_OwnerSetDisable]");
3504       res = execute_TPM_OwnerSetDisable(req, rsp);
3505     break;
3506 
3507     case TPM_ORD_PhysicalEnable:
3508       debug("[TPM_ORD_PhysicalEnable]");
3509       res = execute_TPM_PhysicalEnable(req, rsp);
3510     break;
3511 
3512     case TPM_ORD_PhysicalDisable:
3513       debug("[TPM_ORD_PhysicalDisable]");
3514       res = execute_TPM_PhysicalDisable(req, rsp);
3515     break;
3516 
3517     case TPM_ORD_PhysicalSetDeactivated:
3518       debug("[TPM_ORD_PhysicalSetDeactivated]");
3519       res = execute_TPM_PhysicalSetDeactivated(req, rsp);
3520     break;
3521 
3522     case TPM_ORD_SetTempDeactivated:
3523       debug("[TPM_ORD_SetTempDeactivated]");
3524       res = execute_TPM_SetTempDeactivated(req, rsp);
3525     break;
3526 
3527     case TPM_ORD_SetOperatorAuth:
3528       debug("[TPM_ORD_SetOperatorAuth]");
3529       res = execute_TPM_SetOperatorAuth(req, rsp);
3530     break;
3531 
3532     case TPM_ORD_TakeOwnership:
3533       debug("[TPM_ORD_TakeOwnership]");
3534       res = execute_TPM_TakeOwnership(req, rsp);
3535     break;
3536 
3537     case TPM_ORD_OwnerClear:
3538       debug("[TPM_ORD_OwnerClear]");
3539       res = execute_TPM_OwnerClear(req, rsp);
3540     break;
3541 
3542     case TPM_ORD_ForceClear:
3543       debug("[TPM_ORD_ForceClear]");
3544       res = execute_TPM_ForceClear(req, rsp);
3545     break;
3546 
3547     case TPM_ORD_DisableOwnerClear:
3548       debug("[TPM_ORD_DisableOwnerClear]");
3549       res = execute_TPM_DisableOwnerClear(req, rsp);
3550     break;
3551 
3552     case TPM_ORD_DisableForceClear:
3553       debug("[TPM_ORD_DisableForceClear]");
3554       res = execute_TPM_DisableForceClear(req, rsp);
3555     break;
3556 
3557     case TSC_ORD_PhysicalPresence:
3558       res = execute_TSC_PhysicalPresence(req, rsp);
3559     break;
3560 
3561     case TSC_ORD_ResetEstablishmentBit:
3562       res = execute_TSC_ResetEstablishmentBit(req, rsp);
3563     break;
3564 
3565     case TPM_ORD_GetCapability:
3566       debug("[TPM_ORD_GetCapability]");
3567       res = execute_TPM_GetCapability(req, rsp);
3568     break;
3569 
3570     case TPM_ORD_SetCapability:
3571       debug("[TPM_ORD_SetCapability]");
3572       res = execute_TPM_SetCapability(req, rsp);
3573     break;
3574 
3575     case TPM_ORD_GetCapabilityOwner:
3576       debug("[TPM_ORD_GetCapabilityOwner]");
3577       res = execute_TPM_GetCapabilityOwner(req, rsp);
3578     break;
3579 
3580     case TPM_ORD_GetAuditDigest:
3581       debug("[TPM_ORD_GetAuditDigest]");
3582       res = execute_TPM_GetAuditDigest(req, rsp);
3583     break;
3584 
3585     case TPM_ORD_GetAuditDigestSigned:
3586       debug("[TPM_ORD_GetAuditDigestSigned]");
3587       res = execute_TPM_GetAuditDigestSigned(req, rsp);
3588     break;
3589 
3590     case TPM_ORD_SetOrdinalAuditStatus:
3591       debug("[TPM_ORD_SetOrdinalAuditStatus]");
3592       res = execute_TPM_SetOrdinalAuditStatus(req, rsp);
3593     break;
3594 
3595     case TPM_ORD_FieldUpgrade:
3596       debug("[TPM_ORD_FieldUpgrade]");
3597       res = execute_TPM_FieldUpgrade(req, rsp);
3598     break;
3599 
3600     case TPM_ORD_SetRedirection:
3601       debug("[TPM_ORD_SetRedirection]");
3602       res = execute_TPM_SetRedirection(req, rsp);
3603     break;
3604 
3605     case TPM_ORD_ResetLockValue:
3606       debug("[TPM_ORD_ResetLockValue]");
3607       res = execute_TPM_ResetLockValue(req, rsp);
3608     break;
3609 
3610     case TPM_ORD_Seal:
3611       debug("[TPM_ORD_Seal]");
3612       res = execute_TPM_Seal(req, rsp);
3613     break;
3614 
3615     case TPM_ORD_Unseal:
3616       debug("[TPM_ORD_Unseal]");
3617       res = execute_TPM_Unseal(req, rsp);
3618     break;
3619 
3620     case TPM_ORD_UnBind:
3621       debug("[TPM_ORD_UnBind]");
3622       res = execute_TPM_UnBind(req, rsp);
3623     break;
3624 
3625     case TPM_ORD_CreateWrapKey:
3626       debug("[TPM_ORD_CreateWrapKey]");
3627       res = execute_TPM_CreateWrapKey(req, rsp);
3628     break;
3629 
3630     case TPM_ORD_LoadKey:
3631       debug("[TPM_ORD_LoadKey]");
3632       res = execute_TPM_LoadKey(req, rsp);
3633     break;
3634 
3635     case TPM_ORD_LoadKey2:
3636       debug("[TPM_ORD_LoadKey2]");
3637       res = execute_TPM_LoadKey2(req, rsp);
3638     break;
3639 
3640     case TPM_ORD_GetPubKey:
3641       debug("[TPM_ORD_GetPubKey]");
3642       res = execute_TPM_GetPubKey(req, rsp);
3643     break;
3644 
3645     case TPM_ORD_Sealx:
3646       debug("[TPM_ORD_Sealx]");
3647       res = execute_TPM_Sealx(req, rsp);
3648     break;
3649 
3650     case TPM_ORD_CreateMigrationBlob:
3651       debug("[TPM_ORD_CreateMigrationBlob]");
3652       res = execute_TPM_CreateMigrationBlob(req, rsp);
3653     break;
3654 
3655     case TPM_ORD_ConvertMigrationBlob:
3656       debug("[TPM_ORD_ConvertMigrationBlob]");
3657       res = execute_TPM_ConvertMigrationBlob(req, rsp);
3658     break;
3659 
3660     case TPM_ORD_AuthorizeMigrationKey:
3661       debug("[TPM_ORD_AuthorizeMigrationKey]");
3662       res = execute_TPM_AuthorizeMigrationKey(req, rsp);
3663     break;
3664 
3665     case TPM_ORD_MigrateKey:
3666       debug("[TPM_ORD_MigrateKey]");
3667       res = execute_TPM_MigrateKey(req, rsp);
3668     break;
3669 
3670     case TPM_ORD_CMK_SetRestrictions:
3671       debug("[TPM_ORD_CMK_SetRestrictions]");
3672       res = execute_TPM_CMK_SetRestrictions(req, rsp);
3673     break;
3674 
3675     case TPM_ORD_CMK_ApproveMA:
3676       debug("[TPM_ORD_CMK_ApproveMA]");
3677       res = execute_TPM_CMK_ApproveMA(req, rsp);
3678     break;
3679 
3680     case TPM_ORD_CMK_CreateKey:
3681       debug("[TPM_ORD_CMK_CreateKey]");
3682       res = execute_TPM_CMK_CreateKey(req, rsp);
3683     break;
3684 
3685     case TPM_ORD_CMK_CreateTicket:
3686       debug("[TPM_ORD_CMK_CreateTicket]");
3687       res = execute_TPM_CMK_CreateTicket(req, rsp);
3688     break;
3689 
3690     case TPM_ORD_CMK_CreateBlob:
3691       debug("[TPM_ORD_CMK_CreateBlob]");
3692       res = execute_TPM_CMK_CreateBlob(req, rsp);
3693     break;
3694 
3695     case TPM_ORD_CMK_ConvertMigration:
3696       debug("[TPM_ORD_CMK_ConvertMigration]");
3697       res = execute_TPM_CMK_ConvertMigration(req, rsp);
3698     break;
3699 
3700     case TPM_ORD_CreateMaintenanceArchive:
3701       debug("[TPM_ORD_CreateMaintenanceArchive]");
3702       res = execute_TPM_CreateMaintenanceArchive(req, rsp);
3703     break;
3704 
3705     case TPM_ORD_LoadMaintenanceArchive:
3706       debug("[TPM_ORD_LoadMaintenanceArchive]");
3707       res = execute_TPM_LoadMaintenanceArchive(req, rsp);
3708     break;
3709 
3710     case TPM_ORD_KillMaintenanceFeature:
3711       debug("[TPM_ORD_KillMaintenanceFeature]");
3712       res = execute_TPM_KillMaintenanceFeature(req, rsp);
3713     break;
3714 
3715     case TPM_ORD_LoadManuMaintPub:
3716       debug("[TPM_ORD_LoadManuMaintPub]");
3717       res = execute_TPM_LoadManuMaintPub(req, rsp);
3718     break;
3719 
3720     case TPM_ORD_ReadManuMaintPub:
3721       debug("[TPM_ORD_ReadManuMaintPub]");
3722       res = execute_TPM_ReadManuMaintPub(req, rsp);
3723     break;
3724 
3725     case TPM_ORD_SHA1Start:
3726       debug("[TPM_ORD_SHA1Start]");
3727       res = execute_TPM_SHA1Start(req, rsp);
3728     break;
3729 
3730     case TPM_ORD_SHA1Update:
3731       debug("[TPM_ORD_SHA1Update]");
3732       res = execute_TPM_SHA1Update(req, rsp);
3733     break;
3734 
3735     case TPM_ORD_SHA1Complete:
3736       debug("[TPM_ORD_SHA1Complete]");
3737       res = execute_TPM_SHA1Complete(req, rsp);
3738     break;
3739 
3740     case TPM_ORD_SHA1CompleteExtend:
3741       debug("[TPM_ORD_SHA1CompleteExtend]");
3742       res = execute_TPM_SHA1CompleteExtend(req, rsp);
3743     break;
3744 
3745     case TPM_ORD_Sign:
3746       debug("[TPM_ORD_Sign]");
3747       res = execute_TPM_Sign(req, rsp);
3748     break;
3749 
3750     case TPM_ORD_GetRandom:
3751       debug("[TPM_ORD_GetRandom]");
3752       res = execute_TPM_GetRandom(req, rsp);
3753     break;
3754 
3755     case TPM_ORD_StirRandom:
3756       debug("[TPM_ORD_StirRandom]");
3757       res = execute_TPM_StirRandom(req, rsp);
3758     break;
3759 
3760     case TPM_ORD_CertifyKey:
3761       debug("[TPM_ORD_CertifyKey]");
3762       res = execute_TPM_CertifyKey(req, rsp);
3763     break;
3764 
3765     case TPM_ORD_CertifyKey2:
3766       debug("[TPM_ORD_CertifyKey2]");
3767       res = execute_TPM_CertifyKey2(req, rsp);
3768     break;
3769 
3770     case TPM_ORD_CreateEndorsementKeyPair:
3771       debug("[TPM_ORD_CreateEndorsementKeyPair]");
3772       res = execute_TPM_CreateEndorsementKeyPair(req, rsp);
3773     break;
3774 
3775     case TPM_ORD_CreateRevocableEK:
3776       debug("[TPM_ORD_CreateRevocableEK]");
3777       res = execute_TPM_CreateRevocableEK(req, rsp);
3778     break;
3779 
3780     case TPM_ORD_RevokeTrust:
3781       debug("[TPM_ORD_RevokeTrust]");
3782       res = execute_TPM_RevokeTrust(req, rsp);
3783     break;
3784 
3785     case TPM_ORD_ReadPubek:
3786       debug("[TPM_ORD_ReadPubek]");
3787       res = execute_TPM_ReadPubek(req, rsp);
3788     break;
3789 
3790     case TPM_ORD_DisablePubekRead:
3791       debug("[TPM_ORD_DisablePubekRead]");
3792       res = execute_TPM_DisablePubekRead(req, rsp);
3793     break;
3794 
3795     case TPM_ORD_OwnerReadInternalPub:
3796       debug("[TPM_ORD_OwnerReadInternalPub]");
3797       res = execute_TPM_OwnerReadInternalPub(req, rsp);
3798     break;
3799 
3800     case TPM_ORD_MakeIdentity:
3801       debug("[TPM_ORD_MakeIdentity]");
3802       res = execute_TPM_MakeIdentity(req, rsp);
3803     break;
3804 
3805     case TPM_ORD_ActivateIdentity:
3806       debug("[TPM_ORD_ActivateIdentity]");
3807       res = execute_TPM_ActivateIdentity(req, rsp);
3808     break;
3809 
3810     case TPM_ORD_Extend:
3811       debug("[TPM_ORD_Extend]");
3812       res = execute_TPM_Extend(req, rsp);
3813     break;
3814 
3815     case TPM_ORD_PCRRead:
3816       debug("[TPM_ORD_PCRRead]");
3817       res = execute_TPM_PCRRead(req, rsp);
3818     break;
3819 
3820     case TPM_ORD_Quote:
3821       debug("[TPM_ORD_Quote]");
3822       res = execute_TPM_Quote(req, rsp);
3823     break;
3824 
3825     case TPM_ORD_PCR_Reset:
3826       debug("[TPM_ORD_PCR_Reset]");
3827       res = execute_TPM_PCR_Reset(req, rsp);
3828     break;
3829 
3830     case TPM_ORD_Quote2:
3831       debug("[TPM_ORD_Quote2]");
3832       res = execute_TPM_Quote2(req, rsp);
3833     break;
3834 
3835     case TPM_ORD_ChangeAuth:
3836       debug("[TPM_ORD_ChangeAuth]");
3837       res = execute_TPM_ChangeAuth(req, rsp);
3838     break;
3839 
3840     case TPM_ORD_ChangeAuthOwner:
3841       debug("[TPM_ORD_ChangeAuthOwner]");
3842       res = execute_TPM_ChangeAuthOwner(req, rsp);
3843     break;
3844 
3845     case TPM_ORD_OIAP:
3846       debug("[TPM_ORD_OIAP]");
3847       res = execute_TPM_OIAP(req, rsp);
3848     break;
3849 
3850     case TPM_ORD_OSAP:
3851       debug("[TPM_ORD_OSAP]");
3852       res = execute_TPM_OSAP(req, rsp);
3853     break;
3854 
3855     case TPM_ORD_DSAP:
3856       debug("[TPM_ORD_DSAP]");
3857       res = execute_TPM_DSAP(req, rsp);
3858     break;
3859 
3860     case TPM_ORD_SetOwnerPointer:
3861       debug("[TPM_ORD_SetOwnerPointer]");
3862       res = execute_TPM_SetOwnerPointer(req, rsp);
3863     break;
3864 
3865     case TPM_ORD_Delegate_Manage:
3866       debug("[TPM_ORD_Delegate_Manage]");
3867       res = execute_TPM_Delegate_Manage(req, rsp);
3868     break;
3869 
3870     case TPM_ORD_Delegate_CreateKeyDelegation:
3871       debug("[TPM_ORD_Delegate_CreateKeyDelegation]");
3872       res = execute_TPM_Delegate_CreateKeyDelegation(req, rsp);
3873     break;
3874 
3875     case TPM_ORD_Delegate_CreateOwnerDelegation:
3876       debug("[TPM_ORD_Delegate_CreateOwnerDelegation]");
3877       res = execute_TPM_Delegate_CreateOwnerDelegation(req, rsp);
3878     break;
3879 
3880     case TPM_ORD_Delegate_LoadOwnerDelegation:
3881       debug("[TPM_ORD_Delegate_LoadOwnerDelegation]");
3882       res = execute_TPM_Delegate_LoadOwnerDelegation(req, rsp);
3883     break;
3884 
3885     case TPM_ORD_Delegate_ReadTable:
3886       debug("[TPM_ORD_Delegate_ReadTable]");
3887       res = execute_TPM_Delegate_ReadTable(req, rsp);
3888     break;
3889 
3890     case TPM_ORD_Delegate_UpdateVerification:
3891       debug("[TPM_ORD_Delegate_UpdateVerification]");
3892       res = execute_TPM_Delegate_UpdateVerification(req, rsp);
3893     break;
3894 
3895     case TPM_ORD_Delegate_VerifyDelegation:
3896       debug("[TPM_ORD_Delegate_VerifyDelegation]");
3897       res = execute_TPM_Delegate_VerifyDelegation(req, rsp);
3898     break;
3899 
3900     case TPM_ORD_NV_DefineSpace:
3901       debug("[TPM_ORD_NV_DefineSpace]");
3902       res = execute_TPM_NV_DefineSpace(req, rsp);
3903     break;
3904 
3905     case TPM_ORD_NV_WriteValue:
3906       debug("[TPM_ORD_NV_WriteValue]");
3907       res = execute_TPM_NV_WriteValue(req, rsp);
3908     break;
3909 
3910     case TPM_ORD_NV_WriteValueAuth:
3911       debug("[TPM_ORD_NV_WriteValueAuth]");
3912       res = execute_TPM_NV_WriteValueAuth(req, rsp);
3913     break;
3914 
3915     case TPM_ORD_NV_ReadValue:
3916       debug("[TPM_ORD_NV_ReadValue]");
3917       res = execute_TPM_NV_ReadValue(req, rsp);
3918     break;
3919 
3920     case TPM_ORD_NV_ReadValueAuth:
3921       debug("[TPM_ORD_NV_ReadValueAuth]");
3922       res = execute_TPM_NV_ReadValueAuth(req, rsp);
3923     break;
3924 
3925     case TPM_ORD_KeyControlOwner:
3926       debug("[TPM_ORD_KeyControlOwner]");
3927       res = execute_TPM_KeyControlOwner(req, rsp);
3928     break;
3929 
3930     case TPM_ORD_SaveContext:
3931       debug("[TPM_ORD_SaveContext]");
3932       res = execute_TPM_SaveContext(req, rsp);
3933     break;
3934 
3935     case TPM_ORD_LoadContext:
3936       debug("[TPM_ORD_LoadContext]");
3937       res = execute_TPM_LoadContext(req, rsp);
3938     break;
3939 
3940     case TPM_ORD_FlushSpecific:
3941       debug("[TPM_ORD_FlushSpecific]");
3942       res = execute_TPM_FlushSpecific(req, rsp);
3943     break;
3944 
3945     case TPM_ORD_GetTicks:
3946       debug("[TPM_ORD_GetTicks]");
3947       res = execute_TPM_GetTicks(req, rsp);
3948     break;
3949 
3950     case TPM_ORD_TickStampBlob:
3951       debug("[TPM_ORD_TickStampBlob]");
3952       res = execute_TPM_TickStampBlob(req, rsp);
3953     break;
3954 
3955     case TPM_ORD_EstablishTransport:
3956       debug("[TPM_ORD_EstablishTransport]");
3957       res = execute_TPM_EstablishTransport(req, rsp);
3958     break;
3959 
3960     case TPM_ORD_ExecuteTransport:
3961       debug("[TPM_ORD_ExecuteTransport]");
3962       res = execute_TPM_ExecuteTransport(req, rsp);
3963     break;
3964 
3965     case TPM_ORD_ReleaseTransportSigned:
3966       debug("[TPM_ORD_ReleaseTransportSigned]");
3967       res = execute_TPM_ReleaseTransportSigned(req, rsp);
3968     break;
3969 
3970     case TPM_ORD_CreateCounter:
3971       debug("[TPM_ORD_CreateCounter]");
3972       res = execute_TPM_CreateCounter(req, rsp);
3973     break;
3974 
3975     case TPM_ORD_IncrementCounter:
3976       debug("[TPM_ORD_IncrementCounter]");
3977       res = execute_TPM_IncrementCounter(req, rsp);
3978     break;
3979 
3980     case TPM_ORD_ReadCounter:
3981       debug("[TPM_ORD_ReadCounter]");
3982       res = execute_TPM_ReadCounter(req, rsp);
3983     break;
3984 
3985     case TPM_ORD_ReleaseCounter:
3986       debug("[TPM_ORD_ReleaseCounter]");
3987       res = execute_TPM_ReleaseCounter(req, rsp);
3988     break;
3989 
3990     case TPM_ORD_ReleaseCounterOwner:
3991       debug("[TPM_ORD_ReleaseCounterOwner]");
3992       res = execute_TPM_ReleaseCounterOwner(req, rsp);
3993     break;
3994 
3995     case TPM_ORD_DAA_Join:
3996       debug("[TPM_ORD_DAA_Join]");
3997       res = execute_TPM_DAA_Join(req, rsp);
3998     break;
3999 
4000     case TPM_ORD_DAA_Sign:
4001       debug("[TPM_ORD_DAA_Sign]");
4002       res = execute_TPM_DAA_Sign(req, rsp);
4003     break;
4004 
4005     case TPM_ORD_EvictKey:
4006       debug("[TPM_ORD_EvictKey]");
4007       res = execute_TPM_EvictKey(req, rsp);
4008     break;
4009 
4010     case TPM_ORD_Terminate_Handle:
4011       debug("[TPM_ORD_Terminate_Handle]");
4012       res = execute_TPM_Terminate_Handle(req, rsp);
4013     break;
4014 
4015     case TPM_ORD_SaveKeyContext:
4016       debug("[TPM_ORD_SaveKeyContext]");
4017       res = execute_TPM_SaveKeyContext(req, rsp);
4018     break;
4019 
4020     case TPM_ORD_LoadKeyContext:
4021       debug("[TPM_ORD_LoadKeyContext]");
4022       res = execute_TPM_LoadKeyContext(req, rsp);
4023     break;
4024 
4025     case TPM_ORD_SaveAuthContext:
4026       debug("[TPM_ORD_SaveAuthContext]");
4027       res = execute_TPM_SaveAuthContext(req, rsp);
4028     break;
4029 
4030     case TPM_ORD_LoadAuthContext:
4031       debug("[TPM_ORD_LoadAuthContext]");
4032       res = execute_TPM_LoadAuthContext(req, rsp);
4033     break;
4034 
4035     case TPM_ORD_DirWriteAuth:
4036       debug("[TPM_ORD_DirWriteAuth]");
4037       res = execute_TPM_DirWriteAuth(req, rsp);
4038     break;
4039 
4040     case TPM_ORD_DirRead:
4041       debug("[TPM_ORD_DirRead]");
4042       res = execute_TPM_DirRead(req, rsp);
4043     break;
4044 
4045     case TPM_ORD_ChangeAuthAsymStart:
4046       debug("[TPM_ORD_ChangeAuthAsymStart]");
4047       res = execute_TPM_ChangeAuthAsymStart(req, rsp);
4048     break;
4049 
4050     case TPM_ORD_ChangeAuthAsymFinish:
4051       debug("[TPM_ORD_ChangeAuthAsymFinish]");
4052       res = execute_TPM_ChangeAuthAsymFinish(req, rsp);
4053     break;
4054 
4055     case TPM_ORD_Reset:
4056       debug("[TPM_ORD_Reset]");
4057       res = execute_TPM_Reset(req, rsp);
4058     break;
4059 
4060     case TPM_ORD_OwnerReadPubek:
4061       debug("[TPM_ORD_OwnerReadPubek]");
4062       res = execute_TPM_OwnerReadPubek(req, rsp);
4063     break;
4064 
4065     default:
4066 #ifdef MTM_EMULATOR
4067       res = mtm_execute_command(req, rsp);
4068       if (res != TPM_BAD_ORDINAL) break;
4069 #endif
4070       info("The ordinal (0x%02x) was unknown or inconsistent", req->ordinal);
4071       tpm_setup_error_response(TPM_BAD_ORDINAL, rsp);
4072       return;
4073   }
4074 
4075   /* setup response */
4076   if (res != TPM_SUCCESS) {
4077     info("TPM command failed: (0x%02x) %s", res, tpm_error_to_string(res));
4078     tpm_setup_error_response(res, rsp);
4079     if (!(res & TPM_NON_FATAL)) {
4080       if (rsp->auth1 != NULL) rsp->auth1->continueAuthSession = FALSE;
4081       if (rsp->auth2 != NULL) rsp->auth2->continueAuthSession = FALSE;
4082     }
4083   } else {
4084     info("TPM command succeeded");
4085     rsp->size += rsp->paramSize;
4086     if (rsp->tag != TPM_TAG_RSP_COMMAND) tpm_setup_rsp_auth(req->ordinal, rsp);
4087     if (tpmConf & TPM_CONF_STRONG_PERSISTENCE) {
4088       if (tpm_store_permanent_data() != 0) {
4089         error("tpm_store_permanent_data() failed");
4090       }
4091     }
4092   }
4093   /* terminate authorization sessions if necessary */
4094   if (rsp->auth1 != NULL && !rsp->auth1->continueAuthSession)
4095     TPM_FlushSpecific(rsp->auth1->authHandle, HANDLE_TO_RT(rsp->auth1->authHandle));
4096   if (rsp->auth2 != NULL && !rsp->auth2->continueAuthSession)
4097     TPM_FlushSpecific(rsp->auth2->authHandle, TPM_RT_AUTH);
4098   /* if transportExclusive is set, only the execution of TPM_ExecuteTransport
4099      and TPM_ReleaseTransportSigned is allowed */
4100   if (tpmData.stany.flags.transportExclusive
4101       && req->ordinal != TPM_ORD_ExecuteTransport
4102       && req->ordinal != TPM_ORD_ReleaseTransportSigned) {
4103     TPM_FlushSpecific(tpmData.stany.data.transExclusive, TPM_RT_TRANS);
4104     tpmData.stany.flags.transportExclusive = FALSE;
4105   }
4106 }
4107 
tpm_emulator_init(uint32_t startup,uint32_t conf)4108 int tpm_emulator_init(uint32_t startup, uint32_t conf)
4109 {
4110   /* initialize external functions and data */
4111   if (tpm_extern_init() != 0) return -1;
4112   /* initialize the emulator */
4113   debug("tpm_emulator_init(%d, 0x%08x)", startup, conf);
4114   tpmConf = conf;
4115 #ifdef MTM_EMULATOR
4116   info("MTM support enabled");
4117 #endif
4118   /* try to restore data, if it fails use default values */
4119   if (tpm_restore_permanent_data() != 0) tpm_init_data();
4120   TPM_Init(startup);
4121   return 0;
4122 }
4123 
tpm_emulator_shutdown()4124 void tpm_emulator_shutdown()
4125 {
4126   debug("tpm_emulator_shutdown()");
4127   if (TPM_SaveState() != TPM_SUCCESS) {
4128     error("TPM_SaveState() failed");
4129   }
4130   tpm_release_data();
4131   /* release external functions and data */
4132   tpm_extern_release();
4133 }
4134 
tpm_handle_command(const uint8_t * in,uint32_t in_size,uint8_t ** out,uint32_t * out_size)4135 int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t **out, uint32_t *out_size)
4136 {
4137   TPM_REQUEST req;
4138   TPM_RESPONSE rsp;
4139   BYTE *ptr;
4140   UINT32 len;
4141   BOOL free_out;
4142 
4143   debug("tpm_handle_command()");
4144 
4145   /* we need the whole packet at once, otherwise unmarshalling will fail */
4146   if (tpm_unmarshal_TPM_REQUEST((uint8_t**)&in, &in_size, &req) != 0) {
4147     error("tpm_unmarshal_TPM_REQUEST() failed");
4148     return -1;
4149   }
4150 
4151   /* update timing ticks */
4152   tpm_update_ticks();
4153 
4154   /* audit request */
4155   tpm_audit_request(req.ordinal, &req);
4156 
4157   /* execute command */
4158   tpm_execute_command(&req, &rsp);
4159 
4160   /* audit response */
4161   tpm_audit_response(req.ordinal, &rsp);
4162 
4163   /* init output and marshal response */
4164   if (*out != NULL) {
4165     if (*out_size < rsp.size) {
4166       error("output buffer to small (%d/%d)", *out_size, rsp.size);
4167       tpm_free(rsp.param);
4168       return -1;
4169     }
4170     *out_size = len = rsp.size;
4171     ptr = *out;
4172     free_out = FALSE;
4173   } else {
4174     *out_size = len = rsp.size;
4175     *out = ptr = tpm_malloc(len);
4176     if (ptr == NULL) {
4177       error("tpm_malloc() failed");
4178       tpm_free(rsp.param);
4179       return -1;
4180     }
4181     free_out = TRUE;
4182   }
4183   if (tpm_marshal_TPM_RESPONSE(&ptr, &len, &rsp) != 0) {
4184     error("tpm_marshal_TPM_RESPONSE() failed");
4185     if (free_out) tpm_free(*out);
4186     tpm_free(rsp.param);
4187     return -1;
4188   }
4189   tpm_free(rsp.param);
4190   return 0;
4191 }
4192 
4193