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(¤tTime);
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, ¤tTime)) {
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 ¤tTicks, &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, ¤tTicks)
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, ¤tTicks, &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, ¤tTicks)
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 ¤tTicks, &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, ¤tTicks, &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, ¤tTicks)
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