1 // Copyright 2015 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // THIS CODE IS GENERATED - DO NOT MODIFY!
6
7 #include "tpm_generated.h"
8
9 #include <iterator>
10 #include <memory>
11 #include <string>
12
13 #include <android-base/endian.h>
14 #include <android-base/logging.h>
15 #include <secure_hash.h>
16
17 #include "authorization_delegate.h"
18 #include "callback.h"
19 #include "command_transceiver.h"
20 #include "error_codes.h"
21
22 // Redirect VLOG invocations written for libchrome to android-base's LOG macro.
23 #define VLOG(x) LOG(INFO)
24
25 namespace trunks {
26
GetNumberOfRequestHandles(TPM_CC command_code)27 size_t GetNumberOfRequestHandles(TPM_CC command_code) {
28 switch (command_code) {
29 case TPM_CC_Startup:
30 return 0;
31 case TPM_CC_Shutdown:
32 return 0;
33 case TPM_CC_SelfTest:
34 return 0;
35 case TPM_CC_IncrementalSelfTest:
36 return 0;
37 case TPM_CC_GetTestResult:
38 return 0;
39 case TPM_CC_StartAuthSession:
40 return 2;
41 case TPM_CC_PolicyRestart:
42 return 1;
43 case TPM_CC_Create:
44 return 1;
45 case TPM_CC_Load:
46 return 1;
47 case TPM_CC_LoadExternal:
48 return 0;
49 case TPM_CC_ReadPublic:
50 return 1;
51 case TPM_CC_ActivateCredential:
52 return 2;
53 case TPM_CC_MakeCredential:
54 return 1;
55 case TPM_CC_Unseal:
56 return 1;
57 case TPM_CC_ObjectChangeAuth:
58 return 2;
59 case TPM_CC_Duplicate:
60 return 2;
61 case TPM_CC_Rewrap:
62 return 2;
63 case TPM_CC_Import:
64 return 1;
65 case TPM_CC_RSA_Encrypt:
66 return 1;
67 case TPM_CC_RSA_Decrypt:
68 return 1;
69 case TPM_CC_ECDH_KeyGen:
70 return 1;
71 case TPM_CC_ECDH_ZGen:
72 return 1;
73 case TPM_CC_ECC_Parameters:
74 return 0;
75 case TPM_CC_ZGen_2Phase:
76 return 1;
77 case TPM_CC_EncryptDecrypt:
78 return 1;
79 case TPM_CC_Hash:
80 return 0;
81 case TPM_CC_HMAC:
82 return 1;
83 case TPM_CC_GetRandom:
84 return 0;
85 case TPM_CC_StirRandom:
86 return 0;
87 case TPM_CC_HMAC_Start:
88 return 1;
89 case TPM_CC_HashSequenceStart:
90 return 0;
91 case TPM_CC_SequenceUpdate:
92 return 1;
93 case TPM_CC_SequenceComplete:
94 return 1;
95 case TPM_CC_EventSequenceComplete:
96 return 2;
97 case TPM_CC_Certify:
98 return 2;
99 case TPM_CC_CertifyCreation:
100 return 2;
101 case TPM_CC_Quote:
102 return 1;
103 case TPM_CC_GetSessionAuditDigest:
104 return 3;
105 case TPM_CC_GetCommandAuditDigest:
106 return 2;
107 case TPM_CC_GetTime:
108 return 2;
109 case TPM_CC_Commit:
110 return 1;
111 case TPM_CC_EC_Ephemeral:
112 return 0;
113 case TPM_CC_VerifySignature:
114 return 1;
115 case TPM_CC_Sign:
116 return 1;
117 case TPM_CC_SetCommandCodeAuditStatus:
118 return 1;
119 case TPM_CC_PCR_Extend:
120 return 1;
121 case TPM_CC_PCR_Event:
122 return 1;
123 case TPM_CC_PCR_Read:
124 return 0;
125 case TPM_CC_PCR_Allocate:
126 return 1;
127 case TPM_CC_PCR_SetAuthPolicy:
128 return 2;
129 case TPM_CC_PCR_SetAuthValue:
130 return 1;
131 case TPM_CC_PCR_Reset:
132 return 1;
133 case TPM_CC_PolicySigned:
134 return 2;
135 case TPM_CC_PolicySecret:
136 return 2;
137 case TPM_CC_PolicyTicket:
138 return 1;
139 case TPM_CC_PolicyOR:
140 return 1;
141 case TPM_CC_PolicyPCR:
142 return 1;
143 case TPM_CC_PolicyLocality:
144 return 1;
145 case TPM_CC_PolicyNV:
146 return 3;
147 case TPM_CC_PolicyCounterTimer:
148 return 1;
149 case TPM_CC_PolicyCommandCode:
150 return 1;
151 case TPM_CC_PolicyPhysicalPresence:
152 return 1;
153 case TPM_CC_PolicyCpHash:
154 return 1;
155 case TPM_CC_PolicyNameHash:
156 return 1;
157 case TPM_CC_PolicyDuplicationSelect:
158 return 1;
159 case TPM_CC_PolicyAuthorize:
160 return 1;
161 case TPM_CC_PolicyAuthValue:
162 return 1;
163 case TPM_CC_PolicyPassword:
164 return 1;
165 case TPM_CC_PolicyGetDigest:
166 return 1;
167 case TPM_CC_PolicyNvWritten:
168 return 1;
169 case TPM_CC_CreatePrimary:
170 return 1;
171 case TPM_CC_HierarchyControl:
172 return 1;
173 case TPM_CC_SetPrimaryPolicy:
174 return 1;
175 case TPM_CC_ChangePPS:
176 return 1;
177 case TPM_CC_ChangeEPS:
178 return 1;
179 case TPM_CC_Clear:
180 return 1;
181 case TPM_CC_ClearControl:
182 return 1;
183 case TPM_CC_HierarchyChangeAuth:
184 return 1;
185 case TPM_CC_DictionaryAttackLockReset:
186 return 1;
187 case TPM_CC_DictionaryAttackParameters:
188 return 1;
189 case TPM_CC_PP_Commands:
190 return 1;
191 case TPM_CC_SetAlgorithmSet:
192 return 1;
193 case TPM_CC_FieldUpgradeStart:
194 return 2;
195 case TPM_CC_FieldUpgradeData:
196 return 0;
197 case TPM_CC_FirmwareRead:
198 return 0;
199 case TPM_CC_ContextSave:
200 return 1;
201 case TPM_CC_ContextLoad:
202 return 0;
203 case TPM_CC_FlushContext:
204 return 0;
205 case TPM_CC_EvictControl:
206 return 2;
207 case TPM_CC_ReadClock:
208 return 0;
209 case TPM_CC_ClockSet:
210 return 1;
211 case TPM_CC_ClockRateAdjust:
212 return 1;
213 case TPM_CC_GetCapability:
214 return 0;
215 case TPM_CC_TestParms:
216 return 0;
217 case TPM_CC_NV_DefineSpace:
218 return 1;
219 case TPM_CC_NV_UndefineSpace:
220 return 2;
221 case TPM_CC_NV_UndefineSpaceSpecial:
222 return 2;
223 case TPM_CC_NV_ReadPublic:
224 return 1;
225 case TPM_CC_NV_Write:
226 return 2;
227 case TPM_CC_NV_Increment:
228 return 2;
229 case TPM_CC_NV_Extend:
230 return 2;
231 case TPM_CC_NV_SetBits:
232 return 2;
233 case TPM_CC_NV_WriteLock:
234 return 2;
235 case TPM_CC_NV_GlobalWriteLock:
236 return 1;
237 case TPM_CC_NV_Read:
238 return 2;
239 case TPM_CC_NV_ReadLock:
240 return 2;
241 case TPM_CC_NV_ChangeAuth:
242 return 1;
243 case TPM_CC_NV_Certify:
244 return 3;
245 case TPM_CCE_PolicyFidoSigned:
246 return 2;
247 default:
248 LOG(WARNING) << "Unknown command code: " << command_code;
249 }
250 return 0;
251 }
252
GetNumberOfResponseHandles(TPM_CC command_code)253 size_t GetNumberOfResponseHandles(TPM_CC command_code) {
254 switch (command_code) {
255 case TPM_CC_Startup:
256 return 0;
257 case TPM_CC_Shutdown:
258 return 0;
259 case TPM_CC_SelfTest:
260 return 0;
261 case TPM_CC_IncrementalSelfTest:
262 return 0;
263 case TPM_CC_GetTestResult:
264 return 0;
265 case TPM_CC_StartAuthSession:
266 return 1;
267 case TPM_CC_PolicyRestart:
268 return 0;
269 case TPM_CC_Create:
270 return 0;
271 case TPM_CC_Load:
272 return 1;
273 case TPM_CC_LoadExternal:
274 return 1;
275 case TPM_CC_ReadPublic:
276 return 0;
277 case TPM_CC_ActivateCredential:
278 return 0;
279 case TPM_CC_MakeCredential:
280 return 0;
281 case TPM_CC_Unseal:
282 return 0;
283 case TPM_CC_ObjectChangeAuth:
284 return 0;
285 case TPM_CC_Duplicate:
286 return 0;
287 case TPM_CC_Rewrap:
288 return 0;
289 case TPM_CC_Import:
290 return 0;
291 case TPM_CC_RSA_Encrypt:
292 return 0;
293 case TPM_CC_RSA_Decrypt:
294 return 0;
295 case TPM_CC_ECDH_KeyGen:
296 return 0;
297 case TPM_CC_ECDH_ZGen:
298 return 0;
299 case TPM_CC_ECC_Parameters:
300 return 0;
301 case TPM_CC_ZGen_2Phase:
302 return 0;
303 case TPM_CC_EncryptDecrypt:
304 return 0;
305 case TPM_CC_Hash:
306 return 0;
307 case TPM_CC_HMAC:
308 return 0;
309 case TPM_CC_GetRandom:
310 return 0;
311 case TPM_CC_StirRandom:
312 return 0;
313 case TPM_CC_HMAC_Start:
314 return 1;
315 case TPM_CC_HashSequenceStart:
316 return 1;
317 case TPM_CC_SequenceUpdate:
318 return 0;
319 case TPM_CC_SequenceComplete:
320 return 0;
321 case TPM_CC_EventSequenceComplete:
322 return 0;
323 case TPM_CC_Certify:
324 return 0;
325 case TPM_CC_CertifyCreation:
326 return 0;
327 case TPM_CC_Quote:
328 return 0;
329 case TPM_CC_GetSessionAuditDigest:
330 return 0;
331 case TPM_CC_GetCommandAuditDigest:
332 return 0;
333 case TPM_CC_GetTime:
334 return 0;
335 case TPM_CC_Commit:
336 return 0;
337 case TPM_CC_EC_Ephemeral:
338 return 0;
339 case TPM_CC_VerifySignature:
340 return 0;
341 case TPM_CC_Sign:
342 return 0;
343 case TPM_CC_SetCommandCodeAuditStatus:
344 return 0;
345 case TPM_CC_PCR_Extend:
346 return 0;
347 case TPM_CC_PCR_Event:
348 return 0;
349 case TPM_CC_PCR_Read:
350 return 0;
351 case TPM_CC_PCR_Allocate:
352 return 0;
353 case TPM_CC_PCR_SetAuthPolicy:
354 return 0;
355 case TPM_CC_PCR_SetAuthValue:
356 return 0;
357 case TPM_CC_PCR_Reset:
358 return 0;
359 case TPM_CC_PolicySigned:
360 return 0;
361 case TPM_CC_PolicySecret:
362 return 0;
363 case TPM_CC_PolicyTicket:
364 return 0;
365 case TPM_CC_PolicyOR:
366 return 0;
367 case TPM_CC_PolicyPCR:
368 return 0;
369 case TPM_CC_PolicyLocality:
370 return 0;
371 case TPM_CC_PolicyNV:
372 return 0;
373 case TPM_CC_PolicyCounterTimer:
374 return 0;
375 case TPM_CC_PolicyCommandCode:
376 return 0;
377 case TPM_CC_PolicyPhysicalPresence:
378 return 0;
379 case TPM_CC_PolicyCpHash:
380 return 0;
381 case TPM_CC_PolicyNameHash:
382 return 0;
383 case TPM_CC_PolicyDuplicationSelect:
384 return 0;
385 case TPM_CC_PolicyAuthorize:
386 return 0;
387 case TPM_CC_PolicyAuthValue:
388 return 0;
389 case TPM_CC_PolicyPassword:
390 return 0;
391 case TPM_CC_PolicyGetDigest:
392 return 0;
393 case TPM_CC_PolicyNvWritten:
394 return 0;
395 case TPM_CC_CreatePrimary:
396 return 1;
397 case TPM_CC_HierarchyControl:
398 return 0;
399 case TPM_CC_SetPrimaryPolicy:
400 return 0;
401 case TPM_CC_ChangePPS:
402 return 0;
403 case TPM_CC_ChangeEPS:
404 return 0;
405 case TPM_CC_Clear:
406 return 0;
407 case TPM_CC_ClearControl:
408 return 0;
409 case TPM_CC_HierarchyChangeAuth:
410 return 0;
411 case TPM_CC_DictionaryAttackLockReset:
412 return 0;
413 case TPM_CC_DictionaryAttackParameters:
414 return 0;
415 case TPM_CC_PP_Commands:
416 return 0;
417 case TPM_CC_SetAlgorithmSet:
418 return 0;
419 case TPM_CC_FieldUpgradeStart:
420 return 0;
421 case TPM_CC_FieldUpgradeData:
422 return 0;
423 case TPM_CC_FirmwareRead:
424 return 0;
425 case TPM_CC_ContextSave:
426 return 0;
427 case TPM_CC_ContextLoad:
428 return 1;
429 case TPM_CC_FlushContext:
430 return 0;
431 case TPM_CC_EvictControl:
432 return 0;
433 case TPM_CC_ReadClock:
434 return 0;
435 case TPM_CC_ClockSet:
436 return 0;
437 case TPM_CC_ClockRateAdjust:
438 return 0;
439 case TPM_CC_GetCapability:
440 return 0;
441 case TPM_CC_TestParms:
442 return 0;
443 case TPM_CC_NV_DefineSpace:
444 return 0;
445 case TPM_CC_NV_UndefineSpace:
446 return 0;
447 case TPM_CC_NV_UndefineSpaceSpecial:
448 return 0;
449 case TPM_CC_NV_ReadPublic:
450 return 0;
451 case TPM_CC_NV_Write:
452 return 0;
453 case TPM_CC_NV_Increment:
454 return 0;
455 case TPM_CC_NV_Extend:
456 return 0;
457 case TPM_CC_NV_SetBits:
458 return 0;
459 case TPM_CC_NV_WriteLock:
460 return 0;
461 case TPM_CC_NV_GlobalWriteLock:
462 return 0;
463 case TPM_CC_NV_Read:
464 return 0;
465 case TPM_CC_NV_ReadLock:
466 return 0;
467 case TPM_CC_NV_ChangeAuth:
468 return 0;
469 case TPM_CC_NV_Certify:
470 return 0;
471 case TPM_CCE_PolicyFidoSigned:
472 return 0;
473 default:
474 LOG(WARNING) << "Unknown command code: " << command_code;
475 }
476 return 0;
477 }
478
Serialize_uint8_t(const uint8_t & value,std::string * buffer)479 TPM_RC Serialize_uint8_t(const uint8_t& value, std::string* buffer) {
480 VLOG(3) << __func__;
481 uint8_t value_net = value;
482 switch (sizeof(uint8_t)) {
483 case 2:
484 value_net = htons(value);
485 break;
486 case 4:
487 value_net = htonl(value);
488 break;
489 case 8:
490 value_net = htonq(value);
491 break;
492 default:
493 break;
494 }
495 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
496 buffer->append(value_bytes, sizeof(uint8_t));
497 return TPM_RC_SUCCESS;
498 }
499
Parse_uint8_t(std::string * buffer,uint8_t * value,std::string * value_bytes)500 TPM_RC Parse_uint8_t(std::string* buffer,
501 uint8_t* value,
502 std::string* value_bytes) {
503 VLOG(3) << __func__;
504 if (buffer->size() < sizeof(uint8_t))
505 return TPM_RC_INSUFFICIENT;
506 uint8_t value_net = 0;
507 memcpy(&value_net, buffer->data(), sizeof(uint8_t));
508 switch (sizeof(uint8_t)) {
509 case 2:
510 *value = ntohs(value_net);
511 break;
512 case 4:
513 *value = ntohl(value_net);
514 break;
515 case 8:
516 *value = ntohq(value_net);
517 break;
518 default:
519 *value = value_net;
520 }
521 if (value_bytes) {
522 value_bytes->append(buffer->substr(0, sizeof(uint8_t)));
523 }
524 buffer->erase(0, sizeof(uint8_t));
525 return TPM_RC_SUCCESS;
526 }
527
Serialize_int8_t(const int8_t & value,std::string * buffer)528 TPM_RC Serialize_int8_t(const int8_t& value, std::string* buffer) {
529 VLOG(3) << __func__;
530 int8_t value_net = value;
531 switch (sizeof(int8_t)) {
532 case 2:
533 value_net = htons(value);
534 break;
535 case 4:
536 value_net = htonl(value);
537 break;
538 case 8:
539 value_net = htonq(value);
540 break;
541 default:
542 break;
543 }
544 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
545 buffer->append(value_bytes, sizeof(int8_t));
546 return TPM_RC_SUCCESS;
547 }
548
Parse_int8_t(std::string * buffer,int8_t * value,std::string * value_bytes)549 TPM_RC Parse_int8_t(std::string* buffer,
550 int8_t* value,
551 std::string* value_bytes) {
552 VLOG(3) << __func__;
553 if (buffer->size() < sizeof(int8_t))
554 return TPM_RC_INSUFFICIENT;
555 int8_t value_net = 0;
556 memcpy(&value_net, buffer->data(), sizeof(int8_t));
557 switch (sizeof(int8_t)) {
558 case 2:
559 *value = ntohs(value_net);
560 break;
561 case 4:
562 *value = ntohl(value_net);
563 break;
564 case 8:
565 *value = ntohq(value_net);
566 break;
567 default:
568 *value = value_net;
569 }
570 if (value_bytes) {
571 value_bytes->append(buffer->substr(0, sizeof(int8_t)));
572 }
573 buffer->erase(0, sizeof(int8_t));
574 return TPM_RC_SUCCESS;
575 }
576
Serialize_int(const int & value,std::string * buffer)577 TPM_RC Serialize_int(const int& value, std::string* buffer) {
578 VLOG(3) << __func__;
579 int value_net = value;
580 switch (sizeof(int)) {
581 case 2:
582 value_net = htons(value);
583 break;
584 case 4:
585 value_net = htonl(value);
586 break;
587 case 8:
588 value_net = htonq(value);
589 break;
590 default:
591 break;
592 }
593 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
594 buffer->append(value_bytes, sizeof(int));
595 return TPM_RC_SUCCESS;
596 }
597
Parse_int(std::string * buffer,int * value,std::string * value_bytes)598 TPM_RC Parse_int(std::string* buffer, int* value, std::string* value_bytes) {
599 VLOG(3) << __func__;
600 if (buffer->size() < sizeof(int))
601 return TPM_RC_INSUFFICIENT;
602 int value_net = 0;
603 memcpy(&value_net, buffer->data(), sizeof(int));
604 switch (sizeof(int)) {
605 case 2:
606 *value = ntohs(value_net);
607 break;
608 case 4:
609 *value = ntohl(value_net);
610 break;
611 case 8:
612 *value = ntohq(value_net);
613 break;
614 default:
615 *value = value_net;
616 }
617 if (value_bytes) {
618 value_bytes->append(buffer->substr(0, sizeof(int)));
619 }
620 buffer->erase(0, sizeof(int));
621 return TPM_RC_SUCCESS;
622 }
623
Serialize_uint16_t(const uint16_t & value,std::string * buffer)624 TPM_RC Serialize_uint16_t(const uint16_t& value, std::string* buffer) {
625 VLOG(3) << __func__;
626 uint16_t value_net = value;
627 switch (sizeof(uint16_t)) {
628 case 2:
629 value_net = htons(value);
630 break;
631 case 4:
632 value_net = htonl(value);
633 break;
634 case 8:
635 value_net = htonq(value);
636 break;
637 default:
638 break;
639 }
640 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
641 buffer->append(value_bytes, sizeof(uint16_t));
642 return TPM_RC_SUCCESS;
643 }
644
Parse_uint16_t(std::string * buffer,uint16_t * value,std::string * value_bytes)645 TPM_RC Parse_uint16_t(std::string* buffer,
646 uint16_t* value,
647 std::string* value_bytes) {
648 VLOG(3) << __func__;
649 if (buffer->size() < sizeof(uint16_t))
650 return TPM_RC_INSUFFICIENT;
651 uint16_t value_net = 0;
652 memcpy(&value_net, buffer->data(), sizeof(uint16_t));
653 switch (sizeof(uint16_t)) {
654 case 2:
655 *value = ntohs(value_net);
656 break;
657 case 4:
658 *value = ntohl(value_net);
659 break;
660 case 8:
661 *value = ntohq(value_net);
662 break;
663 default:
664 *value = value_net;
665 }
666 if (value_bytes) {
667 value_bytes->append(buffer->substr(0, sizeof(uint16_t)));
668 }
669 buffer->erase(0, sizeof(uint16_t));
670 return TPM_RC_SUCCESS;
671 }
672
Serialize_int16_t(const int16_t & value,std::string * buffer)673 TPM_RC Serialize_int16_t(const int16_t& value, std::string* buffer) {
674 VLOG(3) << __func__;
675 int16_t value_net = value;
676 switch (sizeof(int16_t)) {
677 case 2:
678 value_net = htons(value);
679 break;
680 case 4:
681 value_net = htonl(value);
682 break;
683 case 8:
684 value_net = htonq(value);
685 break;
686 default:
687 break;
688 }
689 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
690 buffer->append(value_bytes, sizeof(int16_t));
691 return TPM_RC_SUCCESS;
692 }
693
Parse_int16_t(std::string * buffer,int16_t * value,std::string * value_bytes)694 TPM_RC Parse_int16_t(std::string* buffer,
695 int16_t* value,
696 std::string* value_bytes) {
697 VLOG(3) << __func__;
698 if (buffer->size() < sizeof(int16_t))
699 return TPM_RC_INSUFFICIENT;
700 int16_t value_net = 0;
701 memcpy(&value_net, buffer->data(), sizeof(int16_t));
702 switch (sizeof(int16_t)) {
703 case 2:
704 *value = ntohs(value_net);
705 break;
706 case 4:
707 *value = ntohl(value_net);
708 break;
709 case 8:
710 *value = ntohq(value_net);
711 break;
712 default:
713 *value = value_net;
714 }
715 if (value_bytes) {
716 value_bytes->append(buffer->substr(0, sizeof(int16_t)));
717 }
718 buffer->erase(0, sizeof(int16_t));
719 return TPM_RC_SUCCESS;
720 }
721
Serialize_uint32_t(const uint32_t & value,std::string * buffer)722 TPM_RC Serialize_uint32_t(const uint32_t& value, std::string* buffer) {
723 VLOG(3) << __func__;
724 uint32_t value_net = value;
725 switch (sizeof(uint32_t)) {
726 case 2:
727 value_net = htons(value);
728 break;
729 case 4:
730 value_net = htonl(value);
731 break;
732 case 8:
733 value_net = htonq(value);
734 break;
735 default:
736 break;
737 }
738 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
739 buffer->append(value_bytes, sizeof(uint32_t));
740 return TPM_RC_SUCCESS;
741 }
742
Parse_uint32_t(std::string * buffer,uint32_t * value,std::string * value_bytes)743 TPM_RC Parse_uint32_t(std::string* buffer,
744 uint32_t* value,
745 std::string* value_bytes) {
746 VLOG(3) << __func__;
747 if (buffer->size() < sizeof(uint32_t))
748 return TPM_RC_INSUFFICIENT;
749 uint32_t value_net = 0;
750 memcpy(&value_net, buffer->data(), sizeof(uint32_t));
751 switch (sizeof(uint32_t)) {
752 case 2:
753 *value = ntohs(value_net);
754 break;
755 case 4:
756 *value = ntohl(value_net);
757 break;
758 case 8:
759 *value = ntohq(value_net);
760 break;
761 default:
762 *value = value_net;
763 }
764 if (value_bytes) {
765 value_bytes->append(buffer->substr(0, sizeof(uint32_t)));
766 }
767 buffer->erase(0, sizeof(uint32_t));
768 return TPM_RC_SUCCESS;
769 }
770
Serialize_int32_t(const int32_t & value,std::string * buffer)771 TPM_RC Serialize_int32_t(const int32_t& value, std::string* buffer) {
772 VLOG(3) << __func__;
773 int32_t value_net = value;
774 switch (sizeof(int32_t)) {
775 case 2:
776 value_net = htons(value);
777 break;
778 case 4:
779 value_net = htonl(value);
780 break;
781 case 8:
782 value_net = htonq(value);
783 break;
784 default:
785 break;
786 }
787 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
788 buffer->append(value_bytes, sizeof(int32_t));
789 return TPM_RC_SUCCESS;
790 }
791
Parse_int32_t(std::string * buffer,int32_t * value,std::string * value_bytes)792 TPM_RC Parse_int32_t(std::string* buffer,
793 int32_t* value,
794 std::string* value_bytes) {
795 VLOG(3) << __func__;
796 if (buffer->size() < sizeof(int32_t))
797 return TPM_RC_INSUFFICIENT;
798 int32_t value_net = 0;
799 memcpy(&value_net, buffer->data(), sizeof(int32_t));
800 switch (sizeof(int32_t)) {
801 case 2:
802 *value = ntohs(value_net);
803 break;
804 case 4:
805 *value = ntohl(value_net);
806 break;
807 case 8:
808 *value = ntohq(value_net);
809 break;
810 default:
811 *value = value_net;
812 }
813 if (value_bytes) {
814 value_bytes->append(buffer->substr(0, sizeof(int32_t)));
815 }
816 buffer->erase(0, sizeof(int32_t));
817 return TPM_RC_SUCCESS;
818 }
819
Serialize_uint64_t(const uint64_t & value,std::string * buffer)820 TPM_RC Serialize_uint64_t(const uint64_t& value, std::string* buffer) {
821 VLOG(3) << __func__;
822 uint64_t value_net = value;
823 switch (sizeof(uint64_t)) {
824 case 2:
825 value_net = htons(value);
826 break;
827 case 4:
828 value_net = htonl(value);
829 break;
830 case 8:
831 value_net = htonq(value);
832 break;
833 default:
834 break;
835 }
836 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
837 buffer->append(value_bytes, sizeof(uint64_t));
838 return TPM_RC_SUCCESS;
839 }
840
Parse_uint64_t(std::string * buffer,uint64_t * value,std::string * value_bytes)841 TPM_RC Parse_uint64_t(std::string* buffer,
842 uint64_t* value,
843 std::string* value_bytes) {
844 VLOG(3) << __func__;
845 if (buffer->size() < sizeof(uint64_t))
846 return TPM_RC_INSUFFICIENT;
847 uint64_t value_net = 0;
848 memcpy(&value_net, buffer->data(), sizeof(uint64_t));
849 switch (sizeof(uint64_t)) {
850 case 2:
851 *value = ntohs(value_net);
852 break;
853 case 4:
854 *value = ntohl(value_net);
855 break;
856 case 8:
857 *value = ntohq(value_net);
858 break;
859 default:
860 *value = value_net;
861 }
862 if (value_bytes) {
863 value_bytes->append(buffer->substr(0, sizeof(uint64_t)));
864 }
865 buffer->erase(0, sizeof(uint64_t));
866 return TPM_RC_SUCCESS;
867 }
868
Serialize_int64_t(const int64_t & value,std::string * buffer)869 TPM_RC Serialize_int64_t(const int64_t& value, std::string* buffer) {
870 VLOG(3) << __func__;
871 int64_t value_net = value;
872 switch (sizeof(int64_t)) {
873 case 2:
874 value_net = htons(value);
875 break;
876 case 4:
877 value_net = htonl(value);
878 break;
879 case 8:
880 value_net = htonq(value);
881 break;
882 default:
883 break;
884 }
885 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
886 buffer->append(value_bytes, sizeof(int64_t));
887 return TPM_RC_SUCCESS;
888 }
889
Parse_int64_t(std::string * buffer,int64_t * value,std::string * value_bytes)890 TPM_RC Parse_int64_t(std::string* buffer,
891 int64_t* value,
892 std::string* value_bytes) {
893 VLOG(3) << __func__;
894 if (buffer->size() < sizeof(int64_t))
895 return TPM_RC_INSUFFICIENT;
896 int64_t value_net = 0;
897 memcpy(&value_net, buffer->data(), sizeof(int64_t));
898 switch (sizeof(int64_t)) {
899 case 2:
900 *value = ntohs(value_net);
901 break;
902 case 4:
903 *value = ntohl(value_net);
904 break;
905 case 8:
906 *value = ntohq(value_net);
907 break;
908 default:
909 *value = value_net;
910 }
911 if (value_bytes) {
912 value_bytes->append(buffer->substr(0, sizeof(int64_t)));
913 }
914 buffer->erase(0, sizeof(int64_t));
915 return TPM_RC_SUCCESS;
916 }
917
Serialize_UINT8(const UINT8 & value,std::string * buffer)918 TPM_RC Serialize_UINT8(const UINT8& value, std::string* buffer) {
919 VLOG(3) << __func__;
920 return Serialize_uint8_t(value, buffer);
921 }
922
Parse_UINT8(std::string * buffer,UINT8 * value,std::string * value_bytes)923 TPM_RC Parse_UINT8(std::string* buffer,
924 UINT8* value,
925 std::string* value_bytes) {
926 VLOG(3) << __func__;
927 return Parse_uint8_t(buffer, value, value_bytes);
928 }
929
Serialize_BYTE(const BYTE & value,std::string * buffer)930 TPM_RC Serialize_BYTE(const BYTE& value, std::string* buffer) {
931 VLOG(3) << __func__;
932 return Serialize_uint8_t(value, buffer);
933 }
934
Parse_BYTE(std::string * buffer,BYTE * value,std::string * value_bytes)935 TPM_RC Parse_BYTE(std::string* buffer, BYTE* value, std::string* value_bytes) {
936 VLOG(3) << __func__;
937 return Parse_uint8_t(buffer, value, value_bytes);
938 }
939
Serialize_INT8(const INT8 & value,std::string * buffer)940 TPM_RC Serialize_INT8(const INT8& value, std::string* buffer) {
941 VLOG(3) << __func__;
942 return Serialize_int8_t(value, buffer);
943 }
944
Parse_INT8(std::string * buffer,INT8 * value,std::string * value_bytes)945 TPM_RC Parse_INT8(std::string* buffer, INT8* value, std::string* value_bytes) {
946 VLOG(3) << __func__;
947 return Parse_int8_t(buffer, value, value_bytes);
948 }
949
Serialize_BOOL(const BOOL & value,std::string * buffer)950 TPM_RC Serialize_BOOL(const BOOL& value, std::string* buffer) {
951 VLOG(3) << __func__;
952 return Serialize_int(value, buffer);
953 }
954
Parse_BOOL(std::string * buffer,BOOL * value,std::string * value_bytes)955 TPM_RC Parse_BOOL(std::string* buffer, BOOL* value, std::string* value_bytes) {
956 VLOG(3) << __func__;
957 return Parse_int(buffer, value, value_bytes);
958 }
959
Serialize_UINT16(const UINT16 & value,std::string * buffer)960 TPM_RC Serialize_UINT16(const UINT16& value, std::string* buffer) {
961 VLOG(3) << __func__;
962 return Serialize_uint16_t(value, buffer);
963 }
964
Parse_UINT16(std::string * buffer,UINT16 * value,std::string * value_bytes)965 TPM_RC Parse_UINT16(std::string* buffer,
966 UINT16* value,
967 std::string* value_bytes) {
968 VLOG(3) << __func__;
969 return Parse_uint16_t(buffer, value, value_bytes);
970 }
971
Serialize_INT16(const INT16 & value,std::string * buffer)972 TPM_RC Serialize_INT16(const INT16& value, std::string* buffer) {
973 VLOG(3) << __func__;
974 return Serialize_int16_t(value, buffer);
975 }
976
Parse_INT16(std::string * buffer,INT16 * value,std::string * value_bytes)977 TPM_RC Parse_INT16(std::string* buffer,
978 INT16* value,
979 std::string* value_bytes) {
980 VLOG(3) << __func__;
981 return Parse_int16_t(buffer, value, value_bytes);
982 }
983
Serialize_UINT32(const UINT32 & value,std::string * buffer)984 TPM_RC Serialize_UINT32(const UINT32& value, std::string* buffer) {
985 VLOG(3) << __func__;
986 return Serialize_uint32_t(value, buffer);
987 }
988
Parse_UINT32(std::string * buffer,UINT32 * value,std::string * value_bytes)989 TPM_RC Parse_UINT32(std::string* buffer,
990 UINT32* value,
991 std::string* value_bytes) {
992 VLOG(3) << __func__;
993 return Parse_uint32_t(buffer, value, value_bytes);
994 }
995
Serialize_INT32(const INT32 & value,std::string * buffer)996 TPM_RC Serialize_INT32(const INT32& value, std::string* buffer) {
997 VLOG(3) << __func__;
998 return Serialize_int32_t(value, buffer);
999 }
1000
Parse_INT32(std::string * buffer,INT32 * value,std::string * value_bytes)1001 TPM_RC Parse_INT32(std::string* buffer,
1002 INT32* value,
1003 std::string* value_bytes) {
1004 VLOG(3) << __func__;
1005 return Parse_int32_t(buffer, value, value_bytes);
1006 }
1007
Serialize_UINT64(const UINT64 & value,std::string * buffer)1008 TPM_RC Serialize_UINT64(const UINT64& value, std::string* buffer) {
1009 VLOG(3) << __func__;
1010 return Serialize_uint64_t(value, buffer);
1011 }
1012
Parse_UINT64(std::string * buffer,UINT64 * value,std::string * value_bytes)1013 TPM_RC Parse_UINT64(std::string* buffer,
1014 UINT64* value,
1015 std::string* value_bytes) {
1016 VLOG(3) << __func__;
1017 return Parse_uint64_t(buffer, value, value_bytes);
1018 }
1019
Serialize_INT64(const INT64 & value,std::string * buffer)1020 TPM_RC Serialize_INT64(const INT64& value, std::string* buffer) {
1021 VLOG(3) << __func__;
1022 return Serialize_int64_t(value, buffer);
1023 }
1024
Parse_INT64(std::string * buffer,INT64 * value,std::string * value_bytes)1025 TPM_RC Parse_INT64(std::string* buffer,
1026 INT64* value,
1027 std::string* value_bytes) {
1028 VLOG(3) << __func__;
1029 return Parse_int64_t(buffer, value, value_bytes);
1030 }
1031
Serialize_TPM_ALGORITHM_ID(const TPM_ALGORITHM_ID & value,std::string * buffer)1032 TPM_RC Serialize_TPM_ALGORITHM_ID(const TPM_ALGORITHM_ID& value,
1033 std::string* buffer) {
1034 VLOG(3) << __func__;
1035 return Serialize_UINT32(value, buffer);
1036 }
1037
Parse_TPM_ALGORITHM_ID(std::string * buffer,TPM_ALGORITHM_ID * value,std::string * value_bytes)1038 TPM_RC Parse_TPM_ALGORITHM_ID(std::string* buffer,
1039 TPM_ALGORITHM_ID* value,
1040 std::string* value_bytes) {
1041 VLOG(3) << __func__;
1042 return Parse_UINT32(buffer, value, value_bytes);
1043 }
1044
Serialize_TPM_MODIFIER_INDICATOR(const TPM_MODIFIER_INDICATOR & value,std::string * buffer)1045 TPM_RC Serialize_TPM_MODIFIER_INDICATOR(const TPM_MODIFIER_INDICATOR& value,
1046 std::string* buffer) {
1047 VLOG(3) << __func__;
1048 return Serialize_UINT32(value, buffer);
1049 }
1050
Parse_TPM_MODIFIER_INDICATOR(std::string * buffer,TPM_MODIFIER_INDICATOR * value,std::string * value_bytes)1051 TPM_RC Parse_TPM_MODIFIER_INDICATOR(std::string* buffer,
1052 TPM_MODIFIER_INDICATOR* value,
1053 std::string* value_bytes) {
1054 VLOG(3) << __func__;
1055 return Parse_UINT32(buffer, value, value_bytes);
1056 }
1057
Serialize_TPM_AUTHORIZATION_SIZE(const TPM_AUTHORIZATION_SIZE & value,std::string * buffer)1058 TPM_RC Serialize_TPM_AUTHORIZATION_SIZE(const TPM_AUTHORIZATION_SIZE& value,
1059 std::string* buffer) {
1060 VLOG(3) << __func__;
1061 return Serialize_UINT32(value, buffer);
1062 }
1063
Parse_TPM_AUTHORIZATION_SIZE(std::string * buffer,TPM_AUTHORIZATION_SIZE * value,std::string * value_bytes)1064 TPM_RC Parse_TPM_AUTHORIZATION_SIZE(std::string* buffer,
1065 TPM_AUTHORIZATION_SIZE* value,
1066 std::string* value_bytes) {
1067 VLOG(3) << __func__;
1068 return Parse_UINT32(buffer, value, value_bytes);
1069 }
1070
Serialize_TPM_PARAMETER_SIZE(const TPM_PARAMETER_SIZE & value,std::string * buffer)1071 TPM_RC Serialize_TPM_PARAMETER_SIZE(const TPM_PARAMETER_SIZE& value,
1072 std::string* buffer) {
1073 VLOG(3) << __func__;
1074 return Serialize_UINT32(value, buffer);
1075 }
1076
Parse_TPM_PARAMETER_SIZE(std::string * buffer,TPM_PARAMETER_SIZE * value,std::string * value_bytes)1077 TPM_RC Parse_TPM_PARAMETER_SIZE(std::string* buffer,
1078 TPM_PARAMETER_SIZE* value,
1079 std::string* value_bytes) {
1080 VLOG(3) << __func__;
1081 return Parse_UINT32(buffer, value, value_bytes);
1082 }
1083
Serialize_TPM_KEY_SIZE(const TPM_KEY_SIZE & value,std::string * buffer)1084 TPM_RC Serialize_TPM_KEY_SIZE(const TPM_KEY_SIZE& value, std::string* buffer) {
1085 VLOG(3) << __func__;
1086 return Serialize_UINT16(value, buffer);
1087 }
1088
Parse_TPM_KEY_SIZE(std::string * buffer,TPM_KEY_SIZE * value,std::string * value_bytes)1089 TPM_RC Parse_TPM_KEY_SIZE(std::string* buffer,
1090 TPM_KEY_SIZE* value,
1091 std::string* value_bytes) {
1092 VLOG(3) << __func__;
1093 return Parse_UINT16(buffer, value, value_bytes);
1094 }
1095
Serialize_TPM_KEY_BITS(const TPM_KEY_BITS & value,std::string * buffer)1096 TPM_RC Serialize_TPM_KEY_BITS(const TPM_KEY_BITS& value, std::string* buffer) {
1097 VLOG(3) << __func__;
1098 return Serialize_UINT16(value, buffer);
1099 }
1100
Parse_TPM_KEY_BITS(std::string * buffer,TPM_KEY_BITS * value,std::string * value_bytes)1101 TPM_RC Parse_TPM_KEY_BITS(std::string* buffer,
1102 TPM_KEY_BITS* value,
1103 std::string* value_bytes) {
1104 VLOG(3) << __func__;
1105 return Parse_UINT16(buffer, value, value_bytes);
1106 }
1107
Serialize_TPM_HANDLE(const TPM_HANDLE & value,std::string * buffer)1108 TPM_RC Serialize_TPM_HANDLE(const TPM_HANDLE& value, std::string* buffer) {
1109 VLOG(3) << __func__;
1110 return Serialize_UINT32(value, buffer);
1111 }
1112
Parse_TPM_HANDLE(std::string * buffer,TPM_HANDLE * value,std::string * value_bytes)1113 TPM_RC Parse_TPM_HANDLE(std::string* buffer,
1114 TPM_HANDLE* value,
1115 std::string* value_bytes) {
1116 VLOG(3) << __func__;
1117 return Parse_UINT32(buffer, value, value_bytes);
1118 }
1119
Serialize_TPM2B_DIGEST(const TPM2B_DIGEST & value,std::string * buffer)1120 TPM_RC Serialize_TPM2B_DIGEST(const TPM2B_DIGEST& value, std::string* buffer) {
1121 TPM_RC result = TPM_RC_SUCCESS;
1122 VLOG(3) << __func__;
1123
1124 result = Serialize_UINT16(value.size, buffer);
1125 if (result) {
1126 return result;
1127 }
1128
1129 if (std::size(value.buffer) < value.size) {
1130 return TPM_RC_INSUFFICIENT;
1131 }
1132 for (uint32_t i = 0; i < value.size; ++i) {
1133 result = Serialize_BYTE(value.buffer[i], buffer);
1134 if (result) {
1135 return result;
1136 }
1137 }
1138 return result;
1139 }
1140
Parse_TPM2B_DIGEST(std::string * buffer,TPM2B_DIGEST * value,std::string * value_bytes)1141 TPM_RC Parse_TPM2B_DIGEST(std::string* buffer,
1142 TPM2B_DIGEST* value,
1143 std::string* value_bytes) {
1144 TPM_RC result = TPM_RC_SUCCESS;
1145 VLOG(3) << __func__;
1146
1147 result = Parse_UINT16(buffer, &value->size, value_bytes);
1148 if (result) {
1149 return result;
1150 }
1151
1152 if (std::size(value->buffer) < value->size) {
1153 return TPM_RC_INSUFFICIENT;
1154 }
1155 for (uint32_t i = 0; i < value->size; ++i) {
1156 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
1157 if (result) {
1158 return result;
1159 }
1160 }
1161 return result;
1162 }
1163
Make_TPM2B_DIGEST(const std::string & bytes)1164 TPM2B_DIGEST Make_TPM2B_DIGEST(const std::string& bytes) {
1165 TPM2B_DIGEST tpm2b;
1166 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
1167 memset(&tpm2b, 0, sizeof(TPM2B_DIGEST));
1168 tpm2b.size = bytes.size();
1169 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
1170 return tpm2b;
1171 }
1172
StringFrom_TPM2B_DIGEST(const TPM2B_DIGEST & tpm2b)1173 std::string StringFrom_TPM2B_DIGEST(const TPM2B_DIGEST& tpm2b) {
1174 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
1175 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
1176 return std::string(char_buffer, tpm2b.size);
1177 }
1178
Serialize_TPM2B_NONCE(const TPM2B_NONCE & value,std::string * buffer)1179 TPM_RC Serialize_TPM2B_NONCE(const TPM2B_NONCE& value, std::string* buffer) {
1180 VLOG(3) << __func__;
1181 return Serialize_TPM2B_DIGEST(value, buffer);
1182 }
1183
Parse_TPM2B_NONCE(std::string * buffer,TPM2B_NONCE * value,std::string * value_bytes)1184 TPM_RC Parse_TPM2B_NONCE(std::string* buffer,
1185 TPM2B_NONCE* value,
1186 std::string* value_bytes) {
1187 VLOG(3) << __func__;
1188 return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1189 }
1190
Serialize_TPM2B_AUTH(const TPM2B_AUTH & value,std::string * buffer)1191 TPM_RC Serialize_TPM2B_AUTH(const TPM2B_AUTH& value, std::string* buffer) {
1192 VLOG(3) << __func__;
1193 return Serialize_TPM2B_DIGEST(value, buffer);
1194 }
1195
Parse_TPM2B_AUTH(std::string * buffer,TPM2B_AUTH * value,std::string * value_bytes)1196 TPM_RC Parse_TPM2B_AUTH(std::string* buffer,
1197 TPM2B_AUTH* value,
1198 std::string* value_bytes) {
1199 VLOG(3) << __func__;
1200 return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1201 }
1202
Serialize_TPM2B_OPERAND(const TPM2B_OPERAND & value,std::string * buffer)1203 TPM_RC Serialize_TPM2B_OPERAND(const TPM2B_OPERAND& value,
1204 std::string* buffer) {
1205 VLOG(3) << __func__;
1206 return Serialize_TPM2B_DIGEST(value, buffer);
1207 }
1208
Parse_TPM2B_OPERAND(std::string * buffer,TPM2B_OPERAND * value,std::string * value_bytes)1209 TPM_RC Parse_TPM2B_OPERAND(std::string* buffer,
1210 TPM2B_OPERAND* value,
1211 std::string* value_bytes) {
1212 VLOG(3) << __func__;
1213 return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1214 }
1215
Serialize_TPM_ALG_ID(const TPM_ALG_ID & value,std::string * buffer)1216 TPM_RC Serialize_TPM_ALG_ID(const TPM_ALG_ID& value, std::string* buffer) {
1217 VLOG(3) << __func__;
1218 return Serialize_UINT16(value, buffer);
1219 }
1220
Parse_TPM_ALG_ID(std::string * buffer,TPM_ALG_ID * value,std::string * value_bytes)1221 TPM_RC Parse_TPM_ALG_ID(std::string* buffer,
1222 TPM_ALG_ID* value,
1223 std::string* value_bytes) {
1224 VLOG(3) << __func__;
1225 return Parse_UINT16(buffer, value, value_bytes);
1226 }
1227
Serialize_TPMI_ALG_HASH(const TPMI_ALG_HASH & value,std::string * buffer)1228 TPM_RC Serialize_TPMI_ALG_HASH(const TPMI_ALG_HASH& value,
1229 std::string* buffer) {
1230 VLOG(3) << __func__;
1231 return Serialize_TPM_ALG_ID(value, buffer);
1232 }
1233
Parse_TPMI_ALG_HASH(std::string * buffer,TPMI_ALG_HASH * value,std::string * value_bytes)1234 TPM_RC Parse_TPMI_ALG_HASH(std::string* buffer,
1235 TPMI_ALG_HASH* value,
1236 std::string* value_bytes) {
1237 VLOG(3) << __func__;
1238 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1239 }
1240
Serialize_TPMS_SCHEME_SIGHASH(const TPMS_SCHEME_SIGHASH & value,std::string * buffer)1241 TPM_RC Serialize_TPMS_SCHEME_SIGHASH(const TPMS_SCHEME_SIGHASH& value,
1242 std::string* buffer) {
1243 TPM_RC result = TPM_RC_SUCCESS;
1244 VLOG(3) << __func__;
1245
1246 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
1247 if (result) {
1248 return result;
1249 }
1250 return result;
1251 }
1252
Parse_TPMS_SCHEME_SIGHASH(std::string * buffer,TPMS_SCHEME_SIGHASH * value,std::string * value_bytes)1253 TPM_RC Parse_TPMS_SCHEME_SIGHASH(std::string* buffer,
1254 TPMS_SCHEME_SIGHASH* value,
1255 std::string* value_bytes) {
1256 TPM_RC result = TPM_RC_SUCCESS;
1257 VLOG(3) << __func__;
1258
1259 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
1260 if (result) {
1261 return result;
1262 }
1263 return result;
1264 }
1265
Serialize_TPMS_SCHEME_HMAC(const TPMS_SCHEME_HMAC & value,std::string * buffer)1266 TPM_RC Serialize_TPMS_SCHEME_HMAC(const TPMS_SCHEME_HMAC& value,
1267 std::string* buffer) {
1268 VLOG(3) << __func__;
1269 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1270 }
1271
Parse_TPMS_SCHEME_HMAC(std::string * buffer,TPMS_SCHEME_HMAC * value,std::string * value_bytes)1272 TPM_RC Parse_TPMS_SCHEME_HMAC(std::string* buffer,
1273 TPMS_SCHEME_HMAC* value,
1274 std::string* value_bytes) {
1275 VLOG(3) << __func__;
1276 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1277 }
1278
Serialize_TPMS_SCHEME_RSASSA(const TPMS_SCHEME_RSASSA & value,std::string * buffer)1279 TPM_RC Serialize_TPMS_SCHEME_RSASSA(const TPMS_SCHEME_RSASSA& value,
1280 std::string* buffer) {
1281 VLOG(3) << __func__;
1282 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1283 }
1284
Parse_TPMS_SCHEME_RSASSA(std::string * buffer,TPMS_SCHEME_RSASSA * value,std::string * value_bytes)1285 TPM_RC Parse_TPMS_SCHEME_RSASSA(std::string* buffer,
1286 TPMS_SCHEME_RSASSA* value,
1287 std::string* value_bytes) {
1288 VLOG(3) << __func__;
1289 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1290 }
1291
Serialize_TPMS_SCHEME_RSAPSS(const TPMS_SCHEME_RSAPSS & value,std::string * buffer)1292 TPM_RC Serialize_TPMS_SCHEME_RSAPSS(const TPMS_SCHEME_RSAPSS& value,
1293 std::string* buffer) {
1294 VLOG(3) << __func__;
1295 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1296 }
1297
Parse_TPMS_SCHEME_RSAPSS(std::string * buffer,TPMS_SCHEME_RSAPSS * value,std::string * value_bytes)1298 TPM_RC Parse_TPMS_SCHEME_RSAPSS(std::string* buffer,
1299 TPMS_SCHEME_RSAPSS* value,
1300 std::string* value_bytes) {
1301 VLOG(3) << __func__;
1302 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1303 }
1304
Serialize_TPMS_SCHEME_ECDSA(const TPMS_SCHEME_ECDSA & value,std::string * buffer)1305 TPM_RC Serialize_TPMS_SCHEME_ECDSA(const TPMS_SCHEME_ECDSA& value,
1306 std::string* buffer) {
1307 VLOG(3) << __func__;
1308 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1309 }
1310
Parse_TPMS_SCHEME_ECDSA(std::string * buffer,TPMS_SCHEME_ECDSA * value,std::string * value_bytes)1311 TPM_RC Parse_TPMS_SCHEME_ECDSA(std::string* buffer,
1312 TPMS_SCHEME_ECDSA* value,
1313 std::string* value_bytes) {
1314 VLOG(3) << __func__;
1315 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1316 }
1317
Serialize_TPMS_SCHEME_SM2(const TPMS_SCHEME_SM2 & value,std::string * buffer)1318 TPM_RC Serialize_TPMS_SCHEME_SM2(const TPMS_SCHEME_SM2& value,
1319 std::string* buffer) {
1320 VLOG(3) << __func__;
1321 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1322 }
1323
Parse_TPMS_SCHEME_SM2(std::string * buffer,TPMS_SCHEME_SM2 * value,std::string * value_bytes)1324 TPM_RC Parse_TPMS_SCHEME_SM2(std::string* buffer,
1325 TPMS_SCHEME_SM2* value,
1326 std::string* value_bytes) {
1327 VLOG(3) << __func__;
1328 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1329 }
1330
Serialize_TPMS_SCHEME_ECSCHNORR(const TPMS_SCHEME_ECSCHNORR & value,std::string * buffer)1331 TPM_RC Serialize_TPMS_SCHEME_ECSCHNORR(const TPMS_SCHEME_ECSCHNORR& value,
1332 std::string* buffer) {
1333 VLOG(3) << __func__;
1334 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1335 }
1336
Parse_TPMS_SCHEME_ECSCHNORR(std::string * buffer,TPMS_SCHEME_ECSCHNORR * value,std::string * value_bytes)1337 TPM_RC Parse_TPMS_SCHEME_ECSCHNORR(std::string* buffer,
1338 TPMS_SCHEME_ECSCHNORR* value,
1339 std::string* value_bytes) {
1340 VLOG(3) << __func__;
1341 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1342 }
1343
Serialize_TPMI_YES_NO(const TPMI_YES_NO & value,std::string * buffer)1344 TPM_RC Serialize_TPMI_YES_NO(const TPMI_YES_NO& value, std::string* buffer) {
1345 VLOG(3) << __func__;
1346 return Serialize_BYTE(value, buffer);
1347 }
1348
Parse_TPMI_YES_NO(std::string * buffer,TPMI_YES_NO * value,std::string * value_bytes)1349 TPM_RC Parse_TPMI_YES_NO(std::string* buffer,
1350 TPMI_YES_NO* value,
1351 std::string* value_bytes) {
1352 VLOG(3) << __func__;
1353 return Parse_BYTE(buffer, value, value_bytes);
1354 }
1355
Serialize_TPMI_DH_OBJECT(const TPMI_DH_OBJECT & value,std::string * buffer)1356 TPM_RC Serialize_TPMI_DH_OBJECT(const TPMI_DH_OBJECT& value,
1357 std::string* buffer) {
1358 VLOG(3) << __func__;
1359 return Serialize_TPM_HANDLE(value, buffer);
1360 }
1361
Parse_TPMI_DH_OBJECT(std::string * buffer,TPMI_DH_OBJECT * value,std::string * value_bytes)1362 TPM_RC Parse_TPMI_DH_OBJECT(std::string* buffer,
1363 TPMI_DH_OBJECT* value,
1364 std::string* value_bytes) {
1365 VLOG(3) << __func__;
1366 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1367 }
1368
Serialize_TPMI_DH_PERSISTENT(const TPMI_DH_PERSISTENT & value,std::string * buffer)1369 TPM_RC Serialize_TPMI_DH_PERSISTENT(const TPMI_DH_PERSISTENT& value,
1370 std::string* buffer) {
1371 VLOG(3) << __func__;
1372 return Serialize_TPM_HANDLE(value, buffer);
1373 }
1374
Parse_TPMI_DH_PERSISTENT(std::string * buffer,TPMI_DH_PERSISTENT * value,std::string * value_bytes)1375 TPM_RC Parse_TPMI_DH_PERSISTENT(std::string* buffer,
1376 TPMI_DH_PERSISTENT* value,
1377 std::string* value_bytes) {
1378 VLOG(3) << __func__;
1379 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1380 }
1381
Serialize_TPMI_DH_ENTITY(const TPMI_DH_ENTITY & value,std::string * buffer)1382 TPM_RC Serialize_TPMI_DH_ENTITY(const TPMI_DH_ENTITY& value,
1383 std::string* buffer) {
1384 VLOG(3) << __func__;
1385 return Serialize_TPM_HANDLE(value, buffer);
1386 }
1387
Parse_TPMI_DH_ENTITY(std::string * buffer,TPMI_DH_ENTITY * value,std::string * value_bytes)1388 TPM_RC Parse_TPMI_DH_ENTITY(std::string* buffer,
1389 TPMI_DH_ENTITY* value,
1390 std::string* value_bytes) {
1391 VLOG(3) << __func__;
1392 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1393 }
1394
Serialize_TPMI_DH_PCR(const TPMI_DH_PCR & value,std::string * buffer)1395 TPM_RC Serialize_TPMI_DH_PCR(const TPMI_DH_PCR& value, std::string* buffer) {
1396 VLOG(3) << __func__;
1397 return Serialize_TPM_HANDLE(value, buffer);
1398 }
1399
Parse_TPMI_DH_PCR(std::string * buffer,TPMI_DH_PCR * value,std::string * value_bytes)1400 TPM_RC Parse_TPMI_DH_PCR(std::string* buffer,
1401 TPMI_DH_PCR* value,
1402 std::string* value_bytes) {
1403 VLOG(3) << __func__;
1404 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1405 }
1406
Serialize_TPMI_SH_AUTH_SESSION(const TPMI_SH_AUTH_SESSION & value,std::string * buffer)1407 TPM_RC Serialize_TPMI_SH_AUTH_SESSION(const TPMI_SH_AUTH_SESSION& value,
1408 std::string* buffer) {
1409 VLOG(3) << __func__;
1410 return Serialize_TPM_HANDLE(value, buffer);
1411 }
1412
Parse_TPMI_SH_AUTH_SESSION(std::string * buffer,TPMI_SH_AUTH_SESSION * value,std::string * value_bytes)1413 TPM_RC Parse_TPMI_SH_AUTH_SESSION(std::string* buffer,
1414 TPMI_SH_AUTH_SESSION* value,
1415 std::string* value_bytes) {
1416 VLOG(3) << __func__;
1417 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1418 }
1419
Serialize_TPMI_SH_HMAC(const TPMI_SH_HMAC & value,std::string * buffer)1420 TPM_RC Serialize_TPMI_SH_HMAC(const TPMI_SH_HMAC& value, std::string* buffer) {
1421 VLOG(3) << __func__;
1422 return Serialize_TPM_HANDLE(value, buffer);
1423 }
1424
Parse_TPMI_SH_HMAC(std::string * buffer,TPMI_SH_HMAC * value,std::string * value_bytes)1425 TPM_RC Parse_TPMI_SH_HMAC(std::string* buffer,
1426 TPMI_SH_HMAC* value,
1427 std::string* value_bytes) {
1428 VLOG(3) << __func__;
1429 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1430 }
1431
Serialize_TPMI_SH_POLICY(const TPMI_SH_POLICY & value,std::string * buffer)1432 TPM_RC Serialize_TPMI_SH_POLICY(const TPMI_SH_POLICY& value,
1433 std::string* buffer) {
1434 VLOG(3) << __func__;
1435 return Serialize_TPM_HANDLE(value, buffer);
1436 }
1437
Parse_TPMI_SH_POLICY(std::string * buffer,TPMI_SH_POLICY * value,std::string * value_bytes)1438 TPM_RC Parse_TPMI_SH_POLICY(std::string* buffer,
1439 TPMI_SH_POLICY* value,
1440 std::string* value_bytes) {
1441 VLOG(3) << __func__;
1442 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1443 }
1444
Serialize_TPMI_DH_CONTEXT(const TPMI_DH_CONTEXT & value,std::string * buffer)1445 TPM_RC Serialize_TPMI_DH_CONTEXT(const TPMI_DH_CONTEXT& value,
1446 std::string* buffer) {
1447 VLOG(3) << __func__;
1448 return Serialize_TPM_HANDLE(value, buffer);
1449 }
1450
Parse_TPMI_DH_CONTEXT(std::string * buffer,TPMI_DH_CONTEXT * value,std::string * value_bytes)1451 TPM_RC Parse_TPMI_DH_CONTEXT(std::string* buffer,
1452 TPMI_DH_CONTEXT* value,
1453 std::string* value_bytes) {
1454 VLOG(3) << __func__;
1455 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1456 }
1457
Serialize_TPMI_RH_HIERARCHY(const TPMI_RH_HIERARCHY & value,std::string * buffer)1458 TPM_RC Serialize_TPMI_RH_HIERARCHY(const TPMI_RH_HIERARCHY& value,
1459 std::string* buffer) {
1460 VLOG(3) << __func__;
1461 return Serialize_TPM_HANDLE(value, buffer);
1462 }
1463
Parse_TPMI_RH_HIERARCHY(std::string * buffer,TPMI_RH_HIERARCHY * value,std::string * value_bytes)1464 TPM_RC Parse_TPMI_RH_HIERARCHY(std::string* buffer,
1465 TPMI_RH_HIERARCHY* value,
1466 std::string* value_bytes) {
1467 VLOG(3) << __func__;
1468 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1469 }
1470
Serialize_TPMI_RH_ENABLES(const TPMI_RH_ENABLES & value,std::string * buffer)1471 TPM_RC Serialize_TPMI_RH_ENABLES(const TPMI_RH_ENABLES& value,
1472 std::string* buffer) {
1473 VLOG(3) << __func__;
1474 return Serialize_TPM_HANDLE(value, buffer);
1475 }
1476
Parse_TPMI_RH_ENABLES(std::string * buffer,TPMI_RH_ENABLES * value,std::string * value_bytes)1477 TPM_RC Parse_TPMI_RH_ENABLES(std::string* buffer,
1478 TPMI_RH_ENABLES* value,
1479 std::string* value_bytes) {
1480 VLOG(3) << __func__;
1481 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1482 }
1483
Serialize_TPMI_RH_HIERARCHY_AUTH(const TPMI_RH_HIERARCHY_AUTH & value,std::string * buffer)1484 TPM_RC Serialize_TPMI_RH_HIERARCHY_AUTH(const TPMI_RH_HIERARCHY_AUTH& value,
1485 std::string* buffer) {
1486 VLOG(3) << __func__;
1487 return Serialize_TPM_HANDLE(value, buffer);
1488 }
1489
Parse_TPMI_RH_HIERARCHY_AUTH(std::string * buffer,TPMI_RH_HIERARCHY_AUTH * value,std::string * value_bytes)1490 TPM_RC Parse_TPMI_RH_HIERARCHY_AUTH(std::string* buffer,
1491 TPMI_RH_HIERARCHY_AUTH* value,
1492 std::string* value_bytes) {
1493 VLOG(3) << __func__;
1494 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1495 }
1496
Serialize_TPMI_RH_PLATFORM(const TPMI_RH_PLATFORM & value,std::string * buffer)1497 TPM_RC Serialize_TPMI_RH_PLATFORM(const TPMI_RH_PLATFORM& value,
1498 std::string* buffer) {
1499 VLOG(3) << __func__;
1500 return Serialize_TPM_HANDLE(value, buffer);
1501 }
1502
Parse_TPMI_RH_PLATFORM(std::string * buffer,TPMI_RH_PLATFORM * value,std::string * value_bytes)1503 TPM_RC Parse_TPMI_RH_PLATFORM(std::string* buffer,
1504 TPMI_RH_PLATFORM* value,
1505 std::string* value_bytes) {
1506 VLOG(3) << __func__;
1507 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1508 }
1509
Serialize_TPMI_RH_OWNER(const TPMI_RH_OWNER & value,std::string * buffer)1510 TPM_RC Serialize_TPMI_RH_OWNER(const TPMI_RH_OWNER& value,
1511 std::string* buffer) {
1512 VLOG(3) << __func__;
1513 return Serialize_TPM_HANDLE(value, buffer);
1514 }
1515
Parse_TPMI_RH_OWNER(std::string * buffer,TPMI_RH_OWNER * value,std::string * value_bytes)1516 TPM_RC Parse_TPMI_RH_OWNER(std::string* buffer,
1517 TPMI_RH_OWNER* value,
1518 std::string* value_bytes) {
1519 VLOG(3) << __func__;
1520 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1521 }
1522
Serialize_TPMI_RH_ENDORSEMENT(const TPMI_RH_ENDORSEMENT & value,std::string * buffer)1523 TPM_RC Serialize_TPMI_RH_ENDORSEMENT(const TPMI_RH_ENDORSEMENT& value,
1524 std::string* buffer) {
1525 VLOG(3) << __func__;
1526 return Serialize_TPM_HANDLE(value, buffer);
1527 }
1528
Parse_TPMI_RH_ENDORSEMENT(std::string * buffer,TPMI_RH_ENDORSEMENT * value,std::string * value_bytes)1529 TPM_RC Parse_TPMI_RH_ENDORSEMENT(std::string* buffer,
1530 TPMI_RH_ENDORSEMENT* value,
1531 std::string* value_bytes) {
1532 VLOG(3) << __func__;
1533 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1534 }
1535
Serialize_TPMI_RH_PROVISION(const TPMI_RH_PROVISION & value,std::string * buffer)1536 TPM_RC Serialize_TPMI_RH_PROVISION(const TPMI_RH_PROVISION& value,
1537 std::string* buffer) {
1538 VLOG(3) << __func__;
1539 return Serialize_TPM_HANDLE(value, buffer);
1540 }
1541
Parse_TPMI_RH_PROVISION(std::string * buffer,TPMI_RH_PROVISION * value,std::string * value_bytes)1542 TPM_RC Parse_TPMI_RH_PROVISION(std::string* buffer,
1543 TPMI_RH_PROVISION* value,
1544 std::string* value_bytes) {
1545 VLOG(3) << __func__;
1546 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1547 }
1548
Serialize_TPMI_RH_CLEAR(const TPMI_RH_CLEAR & value,std::string * buffer)1549 TPM_RC Serialize_TPMI_RH_CLEAR(const TPMI_RH_CLEAR& value,
1550 std::string* buffer) {
1551 VLOG(3) << __func__;
1552 return Serialize_TPM_HANDLE(value, buffer);
1553 }
1554
Parse_TPMI_RH_CLEAR(std::string * buffer,TPMI_RH_CLEAR * value,std::string * value_bytes)1555 TPM_RC Parse_TPMI_RH_CLEAR(std::string* buffer,
1556 TPMI_RH_CLEAR* value,
1557 std::string* value_bytes) {
1558 VLOG(3) << __func__;
1559 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1560 }
1561
Serialize_TPMI_RH_NV_AUTH(const TPMI_RH_NV_AUTH & value,std::string * buffer)1562 TPM_RC Serialize_TPMI_RH_NV_AUTH(const TPMI_RH_NV_AUTH& value,
1563 std::string* buffer) {
1564 VLOG(3) << __func__;
1565 return Serialize_TPM_HANDLE(value, buffer);
1566 }
1567
Parse_TPMI_RH_NV_AUTH(std::string * buffer,TPMI_RH_NV_AUTH * value,std::string * value_bytes)1568 TPM_RC Parse_TPMI_RH_NV_AUTH(std::string* buffer,
1569 TPMI_RH_NV_AUTH* value,
1570 std::string* value_bytes) {
1571 VLOG(3) << __func__;
1572 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1573 }
1574
Serialize_TPMI_RH_LOCKOUT(const TPMI_RH_LOCKOUT & value,std::string * buffer)1575 TPM_RC Serialize_TPMI_RH_LOCKOUT(const TPMI_RH_LOCKOUT& value,
1576 std::string* buffer) {
1577 VLOG(3) << __func__;
1578 return Serialize_TPM_HANDLE(value, buffer);
1579 }
1580
Parse_TPMI_RH_LOCKOUT(std::string * buffer,TPMI_RH_LOCKOUT * value,std::string * value_bytes)1581 TPM_RC Parse_TPMI_RH_LOCKOUT(std::string* buffer,
1582 TPMI_RH_LOCKOUT* value,
1583 std::string* value_bytes) {
1584 VLOG(3) << __func__;
1585 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1586 }
1587
Serialize_TPMI_RH_NV_INDEX(const TPMI_RH_NV_INDEX & value,std::string * buffer)1588 TPM_RC Serialize_TPMI_RH_NV_INDEX(const TPMI_RH_NV_INDEX& value,
1589 std::string* buffer) {
1590 VLOG(3) << __func__;
1591 return Serialize_TPM_HANDLE(value, buffer);
1592 }
1593
Parse_TPMI_RH_NV_INDEX(std::string * buffer,TPMI_RH_NV_INDEX * value,std::string * value_bytes)1594 TPM_RC Parse_TPMI_RH_NV_INDEX(std::string* buffer,
1595 TPMI_RH_NV_INDEX* value,
1596 std::string* value_bytes) {
1597 VLOG(3) << __func__;
1598 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1599 }
1600
Serialize_TPMI_ALG_ASYM(const TPMI_ALG_ASYM & value,std::string * buffer)1601 TPM_RC Serialize_TPMI_ALG_ASYM(const TPMI_ALG_ASYM& value,
1602 std::string* buffer) {
1603 VLOG(3) << __func__;
1604 return Serialize_TPM_ALG_ID(value, buffer);
1605 }
1606
Parse_TPMI_ALG_ASYM(std::string * buffer,TPMI_ALG_ASYM * value,std::string * value_bytes)1607 TPM_RC Parse_TPMI_ALG_ASYM(std::string* buffer,
1608 TPMI_ALG_ASYM* value,
1609 std::string* value_bytes) {
1610 VLOG(3) << __func__;
1611 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1612 }
1613
Serialize_TPMI_ALG_SYM(const TPMI_ALG_SYM & value,std::string * buffer)1614 TPM_RC Serialize_TPMI_ALG_SYM(const TPMI_ALG_SYM& value, std::string* buffer) {
1615 VLOG(3) << __func__;
1616 return Serialize_TPM_ALG_ID(value, buffer);
1617 }
1618
Parse_TPMI_ALG_SYM(std::string * buffer,TPMI_ALG_SYM * value,std::string * value_bytes)1619 TPM_RC Parse_TPMI_ALG_SYM(std::string* buffer,
1620 TPMI_ALG_SYM* value,
1621 std::string* value_bytes) {
1622 VLOG(3) << __func__;
1623 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1624 }
1625
Serialize_TPMI_ALG_SYM_OBJECT(const TPMI_ALG_SYM_OBJECT & value,std::string * buffer)1626 TPM_RC Serialize_TPMI_ALG_SYM_OBJECT(const TPMI_ALG_SYM_OBJECT& value,
1627 std::string* buffer) {
1628 VLOG(3) << __func__;
1629 return Serialize_TPM_ALG_ID(value, buffer);
1630 }
1631
Parse_TPMI_ALG_SYM_OBJECT(std::string * buffer,TPMI_ALG_SYM_OBJECT * value,std::string * value_bytes)1632 TPM_RC Parse_TPMI_ALG_SYM_OBJECT(std::string* buffer,
1633 TPMI_ALG_SYM_OBJECT* value,
1634 std::string* value_bytes) {
1635 VLOG(3) << __func__;
1636 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1637 }
1638
Serialize_TPMI_ALG_SYM_MODE(const TPMI_ALG_SYM_MODE & value,std::string * buffer)1639 TPM_RC Serialize_TPMI_ALG_SYM_MODE(const TPMI_ALG_SYM_MODE& value,
1640 std::string* buffer) {
1641 VLOG(3) << __func__;
1642 return Serialize_TPM_ALG_ID(value, buffer);
1643 }
1644
Parse_TPMI_ALG_SYM_MODE(std::string * buffer,TPMI_ALG_SYM_MODE * value,std::string * value_bytes)1645 TPM_RC Parse_TPMI_ALG_SYM_MODE(std::string* buffer,
1646 TPMI_ALG_SYM_MODE* value,
1647 std::string* value_bytes) {
1648 VLOG(3) << __func__;
1649 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1650 }
1651
Serialize_TPMI_ALG_KDF(const TPMI_ALG_KDF & value,std::string * buffer)1652 TPM_RC Serialize_TPMI_ALG_KDF(const TPMI_ALG_KDF& value, std::string* buffer) {
1653 VLOG(3) << __func__;
1654 return Serialize_TPM_ALG_ID(value, buffer);
1655 }
1656
Parse_TPMI_ALG_KDF(std::string * buffer,TPMI_ALG_KDF * value,std::string * value_bytes)1657 TPM_RC Parse_TPMI_ALG_KDF(std::string* buffer,
1658 TPMI_ALG_KDF* value,
1659 std::string* value_bytes) {
1660 VLOG(3) << __func__;
1661 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1662 }
1663
Serialize_TPMI_ALG_SIG_SCHEME(const TPMI_ALG_SIG_SCHEME & value,std::string * buffer)1664 TPM_RC Serialize_TPMI_ALG_SIG_SCHEME(const TPMI_ALG_SIG_SCHEME& value,
1665 std::string* buffer) {
1666 VLOG(3) << __func__;
1667 return Serialize_TPM_ALG_ID(value, buffer);
1668 }
1669
Parse_TPMI_ALG_SIG_SCHEME(std::string * buffer,TPMI_ALG_SIG_SCHEME * value,std::string * value_bytes)1670 TPM_RC Parse_TPMI_ALG_SIG_SCHEME(std::string* buffer,
1671 TPMI_ALG_SIG_SCHEME* value,
1672 std::string* value_bytes) {
1673 VLOG(3) << __func__;
1674 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1675 }
1676
Serialize_TPMI_ECC_KEY_EXCHANGE(const TPMI_ECC_KEY_EXCHANGE & value,std::string * buffer)1677 TPM_RC Serialize_TPMI_ECC_KEY_EXCHANGE(const TPMI_ECC_KEY_EXCHANGE& value,
1678 std::string* buffer) {
1679 VLOG(3) << __func__;
1680 return Serialize_TPM_ALG_ID(value, buffer);
1681 }
1682
Parse_TPMI_ECC_KEY_EXCHANGE(std::string * buffer,TPMI_ECC_KEY_EXCHANGE * value,std::string * value_bytes)1683 TPM_RC Parse_TPMI_ECC_KEY_EXCHANGE(std::string* buffer,
1684 TPMI_ECC_KEY_EXCHANGE* value,
1685 std::string* value_bytes) {
1686 VLOG(3) << __func__;
1687 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1688 }
1689
Serialize_TPM_ST(const TPM_ST & value,std::string * buffer)1690 TPM_RC Serialize_TPM_ST(const TPM_ST& value, std::string* buffer) {
1691 VLOG(3) << __func__;
1692 return Serialize_UINT16(value, buffer);
1693 }
1694
Parse_TPM_ST(std::string * buffer,TPM_ST * value,std::string * value_bytes)1695 TPM_RC Parse_TPM_ST(std::string* buffer,
1696 TPM_ST* value,
1697 std::string* value_bytes) {
1698 VLOG(3) << __func__;
1699 return Parse_UINT16(buffer, value, value_bytes);
1700 }
1701
Serialize_TPMI_ST_COMMAND_TAG(const TPMI_ST_COMMAND_TAG & value,std::string * buffer)1702 TPM_RC Serialize_TPMI_ST_COMMAND_TAG(const TPMI_ST_COMMAND_TAG& value,
1703 std::string* buffer) {
1704 VLOG(3) << __func__;
1705 return Serialize_TPM_ST(value, buffer);
1706 }
1707
Parse_TPMI_ST_COMMAND_TAG(std::string * buffer,TPMI_ST_COMMAND_TAG * value,std::string * value_bytes)1708 TPM_RC Parse_TPMI_ST_COMMAND_TAG(std::string* buffer,
1709 TPMI_ST_COMMAND_TAG* value,
1710 std::string* value_bytes) {
1711 VLOG(3) << __func__;
1712 return Parse_TPM_ST(buffer, value, value_bytes);
1713 }
1714
Serialize_TPMI_ST_ATTEST(const TPMI_ST_ATTEST & value,std::string * buffer)1715 TPM_RC Serialize_TPMI_ST_ATTEST(const TPMI_ST_ATTEST& value,
1716 std::string* buffer) {
1717 VLOG(3) << __func__;
1718 return Serialize_TPM_ST(value, buffer);
1719 }
1720
Parse_TPMI_ST_ATTEST(std::string * buffer,TPMI_ST_ATTEST * value,std::string * value_bytes)1721 TPM_RC Parse_TPMI_ST_ATTEST(std::string* buffer,
1722 TPMI_ST_ATTEST* value,
1723 std::string* value_bytes) {
1724 VLOG(3) << __func__;
1725 return Parse_TPM_ST(buffer, value, value_bytes);
1726 }
1727
Serialize_TPMI_AES_KEY_BITS(const TPMI_AES_KEY_BITS & value,std::string * buffer)1728 TPM_RC Serialize_TPMI_AES_KEY_BITS(const TPMI_AES_KEY_BITS& value,
1729 std::string* buffer) {
1730 VLOG(3) << __func__;
1731 return Serialize_TPM_KEY_BITS(value, buffer);
1732 }
1733
Parse_TPMI_AES_KEY_BITS(std::string * buffer,TPMI_AES_KEY_BITS * value,std::string * value_bytes)1734 TPM_RC Parse_TPMI_AES_KEY_BITS(std::string* buffer,
1735 TPMI_AES_KEY_BITS* value,
1736 std::string* value_bytes) {
1737 VLOG(3) << __func__;
1738 return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1739 }
1740
Serialize_TPMI_SM4_KEY_BITS(const TPMI_SM4_KEY_BITS & value,std::string * buffer)1741 TPM_RC Serialize_TPMI_SM4_KEY_BITS(const TPMI_SM4_KEY_BITS& value,
1742 std::string* buffer) {
1743 VLOG(3) << __func__;
1744 return Serialize_TPM_KEY_BITS(value, buffer);
1745 }
1746
Parse_TPMI_SM4_KEY_BITS(std::string * buffer,TPMI_SM4_KEY_BITS * value,std::string * value_bytes)1747 TPM_RC Parse_TPMI_SM4_KEY_BITS(std::string* buffer,
1748 TPMI_SM4_KEY_BITS* value,
1749 std::string* value_bytes) {
1750 VLOG(3) << __func__;
1751 return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1752 }
1753
Serialize_TPMI_ALG_KEYEDHASH_SCHEME(const TPMI_ALG_KEYEDHASH_SCHEME & value,std::string * buffer)1754 TPM_RC Serialize_TPMI_ALG_KEYEDHASH_SCHEME(
1755 const TPMI_ALG_KEYEDHASH_SCHEME& value, std::string* buffer) {
1756 VLOG(3) << __func__;
1757 return Serialize_TPM_ALG_ID(value, buffer);
1758 }
1759
Parse_TPMI_ALG_KEYEDHASH_SCHEME(std::string * buffer,TPMI_ALG_KEYEDHASH_SCHEME * value,std::string * value_bytes)1760 TPM_RC Parse_TPMI_ALG_KEYEDHASH_SCHEME(std::string* buffer,
1761 TPMI_ALG_KEYEDHASH_SCHEME* value,
1762 std::string* value_bytes) {
1763 VLOG(3) << __func__;
1764 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1765 }
1766
Serialize_TPMI_ALG_ASYM_SCHEME(const TPMI_ALG_ASYM_SCHEME & value,std::string * buffer)1767 TPM_RC Serialize_TPMI_ALG_ASYM_SCHEME(const TPMI_ALG_ASYM_SCHEME& value,
1768 std::string* buffer) {
1769 VLOG(3) << __func__;
1770 return Serialize_TPM_ALG_ID(value, buffer);
1771 }
1772
Parse_TPMI_ALG_ASYM_SCHEME(std::string * buffer,TPMI_ALG_ASYM_SCHEME * value,std::string * value_bytes)1773 TPM_RC Parse_TPMI_ALG_ASYM_SCHEME(std::string* buffer,
1774 TPMI_ALG_ASYM_SCHEME* value,
1775 std::string* value_bytes) {
1776 VLOG(3) << __func__;
1777 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1778 }
1779
Serialize_TPMI_ALG_RSA_SCHEME(const TPMI_ALG_RSA_SCHEME & value,std::string * buffer)1780 TPM_RC Serialize_TPMI_ALG_RSA_SCHEME(const TPMI_ALG_RSA_SCHEME& value,
1781 std::string* buffer) {
1782 VLOG(3) << __func__;
1783 return Serialize_TPM_ALG_ID(value, buffer);
1784 }
1785
Parse_TPMI_ALG_RSA_SCHEME(std::string * buffer,TPMI_ALG_RSA_SCHEME * value,std::string * value_bytes)1786 TPM_RC Parse_TPMI_ALG_RSA_SCHEME(std::string* buffer,
1787 TPMI_ALG_RSA_SCHEME* value,
1788 std::string* value_bytes) {
1789 VLOG(3) << __func__;
1790 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1791 }
1792
Serialize_TPMI_ALG_RSA_DECRYPT(const TPMI_ALG_RSA_DECRYPT & value,std::string * buffer)1793 TPM_RC Serialize_TPMI_ALG_RSA_DECRYPT(const TPMI_ALG_RSA_DECRYPT& value,
1794 std::string* buffer) {
1795 VLOG(3) << __func__;
1796 return Serialize_TPM_ALG_ID(value, buffer);
1797 }
1798
Parse_TPMI_ALG_RSA_DECRYPT(std::string * buffer,TPMI_ALG_RSA_DECRYPT * value,std::string * value_bytes)1799 TPM_RC Parse_TPMI_ALG_RSA_DECRYPT(std::string* buffer,
1800 TPMI_ALG_RSA_DECRYPT* value,
1801 std::string* value_bytes) {
1802 VLOG(3) << __func__;
1803 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1804 }
1805
Serialize_TPMI_RSA_KEY_BITS(const TPMI_RSA_KEY_BITS & value,std::string * buffer)1806 TPM_RC Serialize_TPMI_RSA_KEY_BITS(const TPMI_RSA_KEY_BITS& value,
1807 std::string* buffer) {
1808 VLOG(3) << __func__;
1809 return Serialize_TPM_KEY_BITS(value, buffer);
1810 }
1811
Parse_TPMI_RSA_KEY_BITS(std::string * buffer,TPMI_RSA_KEY_BITS * value,std::string * value_bytes)1812 TPM_RC Parse_TPMI_RSA_KEY_BITS(std::string* buffer,
1813 TPMI_RSA_KEY_BITS* value,
1814 std::string* value_bytes) {
1815 VLOG(3) << __func__;
1816 return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1817 }
1818
Serialize_TPMI_ALG_ECC_SCHEME(const TPMI_ALG_ECC_SCHEME & value,std::string * buffer)1819 TPM_RC Serialize_TPMI_ALG_ECC_SCHEME(const TPMI_ALG_ECC_SCHEME& value,
1820 std::string* buffer) {
1821 VLOG(3) << __func__;
1822 return Serialize_TPM_ALG_ID(value, buffer);
1823 }
1824
Parse_TPMI_ALG_ECC_SCHEME(std::string * buffer,TPMI_ALG_ECC_SCHEME * value,std::string * value_bytes)1825 TPM_RC Parse_TPMI_ALG_ECC_SCHEME(std::string* buffer,
1826 TPMI_ALG_ECC_SCHEME* value,
1827 std::string* value_bytes) {
1828 VLOG(3) << __func__;
1829 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1830 }
1831
Serialize_TPM_ECC_CURVE(const TPM_ECC_CURVE & value,std::string * buffer)1832 TPM_RC Serialize_TPM_ECC_CURVE(const TPM_ECC_CURVE& value,
1833 std::string* buffer) {
1834 VLOG(3) << __func__;
1835 return Serialize_UINT16(value, buffer);
1836 }
1837
Parse_TPM_ECC_CURVE(std::string * buffer,TPM_ECC_CURVE * value,std::string * value_bytes)1838 TPM_RC Parse_TPM_ECC_CURVE(std::string* buffer,
1839 TPM_ECC_CURVE* value,
1840 std::string* value_bytes) {
1841 VLOG(3) << __func__;
1842 return Parse_UINT16(buffer, value, value_bytes);
1843 }
1844
Serialize_TPMI_ECC_CURVE(const TPMI_ECC_CURVE & value,std::string * buffer)1845 TPM_RC Serialize_TPMI_ECC_CURVE(const TPMI_ECC_CURVE& value,
1846 std::string* buffer) {
1847 VLOG(3) << __func__;
1848 return Serialize_TPM_ECC_CURVE(value, buffer);
1849 }
1850
Parse_TPMI_ECC_CURVE(std::string * buffer,TPMI_ECC_CURVE * value,std::string * value_bytes)1851 TPM_RC Parse_TPMI_ECC_CURVE(std::string* buffer,
1852 TPMI_ECC_CURVE* value,
1853 std::string* value_bytes) {
1854 VLOG(3) << __func__;
1855 return Parse_TPM_ECC_CURVE(buffer, value, value_bytes);
1856 }
1857
Serialize_TPMI_ALG_PUBLIC(const TPMI_ALG_PUBLIC & value,std::string * buffer)1858 TPM_RC Serialize_TPMI_ALG_PUBLIC(const TPMI_ALG_PUBLIC& value,
1859 std::string* buffer) {
1860 VLOG(3) << __func__;
1861 return Serialize_TPM_ALG_ID(value, buffer);
1862 }
1863
Parse_TPMI_ALG_PUBLIC(std::string * buffer,TPMI_ALG_PUBLIC * value,std::string * value_bytes)1864 TPM_RC Parse_TPMI_ALG_PUBLIC(std::string* buffer,
1865 TPMI_ALG_PUBLIC* value,
1866 std::string* value_bytes) {
1867 VLOG(3) << __func__;
1868 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1869 }
1870
Serialize_TPMA_ALGORITHM(const TPMA_ALGORITHM & value,std::string * buffer)1871 TPM_RC Serialize_TPMA_ALGORITHM(const TPMA_ALGORITHM& value,
1872 std::string* buffer) {
1873 VLOG(3) << __func__;
1874 return Serialize_UINT32(value, buffer);
1875 }
1876
Parse_TPMA_ALGORITHM(std::string * buffer,TPMA_ALGORITHM * value,std::string * value_bytes)1877 TPM_RC Parse_TPMA_ALGORITHM(std::string* buffer,
1878 TPMA_ALGORITHM* value,
1879 std::string* value_bytes) {
1880 VLOG(3) << __func__;
1881 return Parse_UINT32(buffer, value, value_bytes);
1882 }
1883
Serialize_TPMA_OBJECT(const TPMA_OBJECT & value,std::string * buffer)1884 TPM_RC Serialize_TPMA_OBJECT(const TPMA_OBJECT& value, std::string* buffer) {
1885 VLOG(3) << __func__;
1886 return Serialize_UINT32(value, buffer);
1887 }
1888
Parse_TPMA_OBJECT(std::string * buffer,TPMA_OBJECT * value,std::string * value_bytes)1889 TPM_RC Parse_TPMA_OBJECT(std::string* buffer,
1890 TPMA_OBJECT* value,
1891 std::string* value_bytes) {
1892 VLOG(3) << __func__;
1893 return Parse_UINT32(buffer, value, value_bytes);
1894 }
1895
Serialize_TPMA_SESSION(const TPMA_SESSION & value,std::string * buffer)1896 TPM_RC Serialize_TPMA_SESSION(const TPMA_SESSION& value, std::string* buffer) {
1897 VLOG(3) << __func__;
1898 return Serialize_UINT8(value, buffer);
1899 }
1900
Parse_TPMA_SESSION(std::string * buffer,TPMA_SESSION * value,std::string * value_bytes)1901 TPM_RC Parse_TPMA_SESSION(std::string* buffer,
1902 TPMA_SESSION* value,
1903 std::string* value_bytes) {
1904 VLOG(3) << __func__;
1905 return Parse_UINT8(buffer, value, value_bytes);
1906 }
1907
Serialize_TPMA_LOCALITY(const TPMA_LOCALITY & value,std::string * buffer)1908 TPM_RC Serialize_TPMA_LOCALITY(const TPMA_LOCALITY& value,
1909 std::string* buffer) {
1910 VLOG(3) << __func__;
1911 return Serialize_UINT8(value, buffer);
1912 }
1913
Parse_TPMA_LOCALITY(std::string * buffer,TPMA_LOCALITY * value,std::string * value_bytes)1914 TPM_RC Parse_TPMA_LOCALITY(std::string* buffer,
1915 TPMA_LOCALITY* value,
1916 std::string* value_bytes) {
1917 VLOG(3) << __func__;
1918 return Parse_UINT8(buffer, value, value_bytes);
1919 }
1920
Serialize_TPMA_PERMANENT(const TPMA_PERMANENT & value,std::string * buffer)1921 TPM_RC Serialize_TPMA_PERMANENT(const TPMA_PERMANENT& value,
1922 std::string* buffer) {
1923 VLOG(3) << __func__;
1924 return Serialize_UINT32(value, buffer);
1925 }
1926
Parse_TPMA_PERMANENT(std::string * buffer,TPMA_PERMANENT * value,std::string * value_bytes)1927 TPM_RC Parse_TPMA_PERMANENT(std::string* buffer,
1928 TPMA_PERMANENT* value,
1929 std::string* value_bytes) {
1930 VLOG(3) << __func__;
1931 return Parse_UINT32(buffer, value, value_bytes);
1932 }
1933
Serialize_TPMA_STARTUP_CLEAR(const TPMA_STARTUP_CLEAR & value,std::string * buffer)1934 TPM_RC Serialize_TPMA_STARTUP_CLEAR(const TPMA_STARTUP_CLEAR& value,
1935 std::string* buffer) {
1936 VLOG(3) << __func__;
1937 return Serialize_UINT32(value, buffer);
1938 }
1939
Parse_TPMA_STARTUP_CLEAR(std::string * buffer,TPMA_STARTUP_CLEAR * value,std::string * value_bytes)1940 TPM_RC Parse_TPMA_STARTUP_CLEAR(std::string* buffer,
1941 TPMA_STARTUP_CLEAR* value,
1942 std::string* value_bytes) {
1943 VLOG(3) << __func__;
1944 return Parse_UINT32(buffer, value, value_bytes);
1945 }
1946
Serialize_TPMA_MEMORY(const TPMA_MEMORY & value,std::string * buffer)1947 TPM_RC Serialize_TPMA_MEMORY(const TPMA_MEMORY& value, std::string* buffer) {
1948 VLOG(3) << __func__;
1949 return Serialize_UINT32(value, buffer);
1950 }
1951
Parse_TPMA_MEMORY(std::string * buffer,TPMA_MEMORY * value,std::string * value_bytes)1952 TPM_RC Parse_TPMA_MEMORY(std::string* buffer,
1953 TPMA_MEMORY* value,
1954 std::string* value_bytes) {
1955 VLOG(3) << __func__;
1956 return Parse_UINT32(buffer, value, value_bytes);
1957 }
1958
Serialize_TPM_CC(const TPM_CC & value,std::string * buffer)1959 TPM_RC Serialize_TPM_CC(const TPM_CC& value, std::string* buffer) {
1960 VLOG(3) << __func__;
1961 return Serialize_UINT32(value, buffer);
1962 }
1963
Parse_TPM_CC(std::string * buffer,TPM_CC * value,std::string * value_bytes)1964 TPM_RC Parse_TPM_CC(std::string* buffer,
1965 TPM_CC* value,
1966 std::string* value_bytes) {
1967 VLOG(3) << __func__;
1968 return Parse_UINT32(buffer, value, value_bytes);
1969 }
1970
Serialize_TPMA_CC(const TPMA_CC & value,std::string * buffer)1971 TPM_RC Serialize_TPMA_CC(const TPMA_CC& value, std::string* buffer) {
1972 VLOG(3) << __func__;
1973 return Serialize_TPM_CC(value, buffer);
1974 }
1975
Parse_TPMA_CC(std::string * buffer,TPMA_CC * value,std::string * value_bytes)1976 TPM_RC Parse_TPMA_CC(std::string* buffer,
1977 TPMA_CC* value,
1978 std::string* value_bytes) {
1979 VLOG(3) << __func__;
1980 return Parse_TPM_CC(buffer, value, value_bytes);
1981 }
1982
Serialize_TPM_NV_INDEX(const TPM_NV_INDEX & value,std::string * buffer)1983 TPM_RC Serialize_TPM_NV_INDEX(const TPM_NV_INDEX& value, std::string* buffer) {
1984 VLOG(3) << __func__;
1985 return Serialize_UINT32(value, buffer);
1986 }
1987
Parse_TPM_NV_INDEX(std::string * buffer,TPM_NV_INDEX * value,std::string * value_bytes)1988 TPM_RC Parse_TPM_NV_INDEX(std::string* buffer,
1989 TPM_NV_INDEX* value,
1990 std::string* value_bytes) {
1991 VLOG(3) << __func__;
1992 return Parse_UINT32(buffer, value, value_bytes);
1993 }
1994
Serialize_TPMA_NV(const TPMA_NV & value,std::string * buffer)1995 TPM_RC Serialize_TPMA_NV(const TPMA_NV& value, std::string* buffer) {
1996 VLOG(3) << __func__;
1997 return Serialize_UINT32(value, buffer);
1998 }
1999
Parse_TPMA_NV(std::string * buffer,TPMA_NV * value,std::string * value_bytes)2000 TPM_RC Parse_TPMA_NV(std::string* buffer,
2001 TPMA_NV* value,
2002 std::string* value_bytes) {
2003 VLOG(3) << __func__;
2004 return Parse_UINT32(buffer, value, value_bytes);
2005 }
2006
Serialize_TPM_SPEC(const TPM_SPEC & value,std::string * buffer)2007 TPM_RC Serialize_TPM_SPEC(const TPM_SPEC& value, std::string* buffer) {
2008 VLOG(3) << __func__;
2009 return Serialize_UINT32(value, buffer);
2010 }
2011
Parse_TPM_SPEC(std::string * buffer,TPM_SPEC * value,std::string * value_bytes)2012 TPM_RC Parse_TPM_SPEC(std::string* buffer,
2013 TPM_SPEC* value,
2014 std::string* value_bytes) {
2015 VLOG(3) << __func__;
2016 return Parse_UINT32(buffer, value, value_bytes);
2017 }
2018
Serialize_TPM_GENERATED(const TPM_GENERATED & value,std::string * buffer)2019 TPM_RC Serialize_TPM_GENERATED(const TPM_GENERATED& value,
2020 std::string* buffer) {
2021 VLOG(3) << __func__;
2022 return Serialize_UINT32(value, buffer);
2023 }
2024
Parse_TPM_GENERATED(std::string * buffer,TPM_GENERATED * value,std::string * value_bytes)2025 TPM_RC Parse_TPM_GENERATED(std::string* buffer,
2026 TPM_GENERATED* value,
2027 std::string* value_bytes) {
2028 VLOG(3) << __func__;
2029 return Parse_UINT32(buffer, value, value_bytes);
2030 }
2031
Serialize_TPM_RC(const TPM_RC & value,std::string * buffer)2032 TPM_RC Serialize_TPM_RC(const TPM_RC& value, std::string* buffer) {
2033 VLOG(3) << __func__;
2034 return Serialize_UINT32(value, buffer);
2035 }
2036
Parse_TPM_RC(std::string * buffer,TPM_RC * value,std::string * value_bytes)2037 TPM_RC Parse_TPM_RC(std::string* buffer,
2038 TPM_RC* value,
2039 std::string* value_bytes) {
2040 VLOG(3) << __func__;
2041 return Parse_UINT32(buffer, value, value_bytes);
2042 }
2043
Serialize_TPM_CLOCK_ADJUST(const TPM_CLOCK_ADJUST & value,std::string * buffer)2044 TPM_RC Serialize_TPM_CLOCK_ADJUST(const TPM_CLOCK_ADJUST& value,
2045 std::string* buffer) {
2046 VLOG(3) << __func__;
2047 return Serialize_INT8(value, buffer);
2048 }
2049
Parse_TPM_CLOCK_ADJUST(std::string * buffer,TPM_CLOCK_ADJUST * value,std::string * value_bytes)2050 TPM_RC Parse_TPM_CLOCK_ADJUST(std::string* buffer,
2051 TPM_CLOCK_ADJUST* value,
2052 std::string* value_bytes) {
2053 VLOG(3) << __func__;
2054 return Parse_INT8(buffer, value, value_bytes);
2055 }
2056
Serialize_TPM_EO(const TPM_EO & value,std::string * buffer)2057 TPM_RC Serialize_TPM_EO(const TPM_EO& value, std::string* buffer) {
2058 VLOG(3) << __func__;
2059 return Serialize_UINT16(value, buffer);
2060 }
2061
Parse_TPM_EO(std::string * buffer,TPM_EO * value,std::string * value_bytes)2062 TPM_RC Parse_TPM_EO(std::string* buffer,
2063 TPM_EO* value,
2064 std::string* value_bytes) {
2065 VLOG(3) << __func__;
2066 return Parse_UINT16(buffer, value, value_bytes);
2067 }
2068
Serialize_TPM_SU(const TPM_SU & value,std::string * buffer)2069 TPM_RC Serialize_TPM_SU(const TPM_SU& value, std::string* buffer) {
2070 VLOG(3) << __func__;
2071 return Serialize_UINT16(value, buffer);
2072 }
2073
Parse_TPM_SU(std::string * buffer,TPM_SU * value,std::string * value_bytes)2074 TPM_RC Parse_TPM_SU(std::string* buffer,
2075 TPM_SU* value,
2076 std::string* value_bytes) {
2077 VLOG(3) << __func__;
2078 return Parse_UINT16(buffer, value, value_bytes);
2079 }
2080
Serialize_TPM_SE(const TPM_SE & value,std::string * buffer)2081 TPM_RC Serialize_TPM_SE(const TPM_SE& value, std::string* buffer) {
2082 VLOG(3) << __func__;
2083 return Serialize_UINT8(value, buffer);
2084 }
2085
Parse_TPM_SE(std::string * buffer,TPM_SE * value,std::string * value_bytes)2086 TPM_RC Parse_TPM_SE(std::string* buffer,
2087 TPM_SE* value,
2088 std::string* value_bytes) {
2089 VLOG(3) << __func__;
2090 return Parse_UINT8(buffer, value, value_bytes);
2091 }
2092
Serialize_TPM_CAP(const TPM_CAP & value,std::string * buffer)2093 TPM_RC Serialize_TPM_CAP(const TPM_CAP& value, std::string* buffer) {
2094 VLOG(3) << __func__;
2095 return Serialize_UINT32(value, buffer);
2096 }
2097
Parse_TPM_CAP(std::string * buffer,TPM_CAP * value,std::string * value_bytes)2098 TPM_RC Parse_TPM_CAP(std::string* buffer,
2099 TPM_CAP* value,
2100 std::string* value_bytes) {
2101 VLOG(3) << __func__;
2102 return Parse_UINT32(buffer, value, value_bytes);
2103 }
2104
Serialize_TPM_PT(const TPM_PT & value,std::string * buffer)2105 TPM_RC Serialize_TPM_PT(const TPM_PT& value, std::string* buffer) {
2106 VLOG(3) << __func__;
2107 return Serialize_UINT32(value, buffer);
2108 }
2109
Parse_TPM_PT(std::string * buffer,TPM_PT * value,std::string * value_bytes)2110 TPM_RC Parse_TPM_PT(std::string* buffer,
2111 TPM_PT* value,
2112 std::string* value_bytes) {
2113 VLOG(3) << __func__;
2114 return Parse_UINT32(buffer, value, value_bytes);
2115 }
2116
Serialize_TPM_PT_PCR(const TPM_PT_PCR & value,std::string * buffer)2117 TPM_RC Serialize_TPM_PT_PCR(const TPM_PT_PCR& value, std::string* buffer) {
2118 VLOG(3) << __func__;
2119 return Serialize_UINT32(value, buffer);
2120 }
2121
Parse_TPM_PT_PCR(std::string * buffer,TPM_PT_PCR * value,std::string * value_bytes)2122 TPM_RC Parse_TPM_PT_PCR(std::string* buffer,
2123 TPM_PT_PCR* value,
2124 std::string* value_bytes) {
2125 VLOG(3) << __func__;
2126 return Parse_UINT32(buffer, value, value_bytes);
2127 }
2128
Serialize_TPM_PS(const TPM_PS & value,std::string * buffer)2129 TPM_RC Serialize_TPM_PS(const TPM_PS& value, std::string* buffer) {
2130 VLOG(3) << __func__;
2131 return Serialize_UINT32(value, buffer);
2132 }
2133
Parse_TPM_PS(std::string * buffer,TPM_PS * value,std::string * value_bytes)2134 TPM_RC Parse_TPM_PS(std::string* buffer,
2135 TPM_PS* value,
2136 std::string* value_bytes) {
2137 VLOG(3) << __func__;
2138 return Parse_UINT32(buffer, value, value_bytes);
2139 }
2140
Serialize_TPM_HT(const TPM_HT & value,std::string * buffer)2141 TPM_RC Serialize_TPM_HT(const TPM_HT& value, std::string* buffer) {
2142 VLOG(3) << __func__;
2143 return Serialize_UINT8(value, buffer);
2144 }
2145
Parse_TPM_HT(std::string * buffer,TPM_HT * value,std::string * value_bytes)2146 TPM_RC Parse_TPM_HT(std::string* buffer,
2147 TPM_HT* value,
2148 std::string* value_bytes) {
2149 VLOG(3) << __func__;
2150 return Parse_UINT8(buffer, value, value_bytes);
2151 }
2152
Serialize_TPM_RH(const TPM_RH & value,std::string * buffer)2153 TPM_RC Serialize_TPM_RH(const TPM_RH& value, std::string* buffer) {
2154 VLOG(3) << __func__;
2155 return Serialize_UINT32(value, buffer);
2156 }
2157
Parse_TPM_RH(std::string * buffer,TPM_RH * value,std::string * value_bytes)2158 TPM_RC Parse_TPM_RH(std::string* buffer,
2159 TPM_RH* value,
2160 std::string* value_bytes) {
2161 VLOG(3) << __func__;
2162 return Parse_UINT32(buffer, value, value_bytes);
2163 }
2164
Serialize_TPM_HC(const TPM_HC & value,std::string * buffer)2165 TPM_RC Serialize_TPM_HC(const TPM_HC& value, std::string* buffer) {
2166 VLOG(3) << __func__;
2167 return Serialize_TPM_HANDLE(value, buffer);
2168 }
2169
Parse_TPM_HC(std::string * buffer,TPM_HC * value,std::string * value_bytes)2170 TPM_RC Parse_TPM_HC(std::string* buffer,
2171 TPM_HC* value,
2172 std::string* value_bytes) {
2173 VLOG(3) << __func__;
2174 return Parse_TPM_HANDLE(buffer, value, value_bytes);
2175 }
2176
Serialize_TPMS_ALGORITHM_DESCRIPTION(const TPMS_ALGORITHM_DESCRIPTION & value,std::string * buffer)2177 TPM_RC Serialize_TPMS_ALGORITHM_DESCRIPTION(
2178 const TPMS_ALGORITHM_DESCRIPTION& value, std::string* buffer) {
2179 TPM_RC result = TPM_RC_SUCCESS;
2180 VLOG(3) << __func__;
2181
2182 result = Serialize_TPM_ALG_ID(value.alg, buffer);
2183 if (result) {
2184 return result;
2185 }
2186
2187 result = Serialize_TPMA_ALGORITHM(value.attributes, buffer);
2188 if (result) {
2189 return result;
2190 }
2191 return result;
2192 }
2193
Parse_TPMS_ALGORITHM_DESCRIPTION(std::string * buffer,TPMS_ALGORITHM_DESCRIPTION * value,std::string * value_bytes)2194 TPM_RC Parse_TPMS_ALGORITHM_DESCRIPTION(std::string* buffer,
2195 TPMS_ALGORITHM_DESCRIPTION* value,
2196 std::string* value_bytes) {
2197 TPM_RC result = TPM_RC_SUCCESS;
2198 VLOG(3) << __func__;
2199
2200 result = Parse_TPM_ALG_ID(buffer, &value->alg, value_bytes);
2201 if (result) {
2202 return result;
2203 }
2204
2205 result = Parse_TPMA_ALGORITHM(buffer, &value->attributes, value_bytes);
2206 if (result) {
2207 return result;
2208 }
2209 return result;
2210 }
2211
Serialize_TPMU_HA(const TPMU_HA & value,TPMI_ALG_HASH selector,std::string * buffer)2212 TPM_RC Serialize_TPMU_HA(const TPMU_HA& value,
2213 TPMI_ALG_HASH selector,
2214 std::string* buffer) {
2215 TPM_RC result = TPM_RC_SUCCESS;
2216 VLOG(3) << __func__;
2217
2218 if (selector == TPM_ALG_SHA384) {
2219 if (std::size(value.sha384) < SHA384_DIGEST_SIZE) {
2220 return TPM_RC_INSUFFICIENT;
2221 }
2222 for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) {
2223 result = Serialize_BYTE(value.sha384[i], buffer);
2224 if (result) {
2225 return result;
2226 }
2227 }
2228 }
2229
2230 if (selector == TPM_ALG_SHA1) {
2231 if (std::size(value.sha1) < SHA1_DIGEST_SIZE) {
2232 return TPM_RC_INSUFFICIENT;
2233 }
2234 for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) {
2235 result = Serialize_BYTE(value.sha1[i], buffer);
2236 if (result) {
2237 return result;
2238 }
2239 }
2240 }
2241
2242 if (selector == TPM_ALG_SM3_256) {
2243 if (std::size(value.sm3_256) < SM3_256_DIGEST_SIZE) {
2244 return TPM_RC_INSUFFICIENT;
2245 }
2246 for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) {
2247 result = Serialize_BYTE(value.sm3_256[i], buffer);
2248 if (result) {
2249 return result;
2250 }
2251 }
2252 }
2253
2254 if (selector == TPM_ALG_NULL) {
2255 // Do nothing.
2256 }
2257
2258 if (selector == TPM_ALG_SHA256) {
2259 if (std::size(value.sha256) < SHA256_DIGEST_SIZE) {
2260 return TPM_RC_INSUFFICIENT;
2261 }
2262 for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) {
2263 result = Serialize_BYTE(value.sha256[i], buffer);
2264 if (result) {
2265 return result;
2266 }
2267 }
2268 }
2269
2270 if (selector == TPM_ALG_SHA512) {
2271 if (std::size(value.sha512) < SHA512_DIGEST_SIZE) {
2272 return TPM_RC_INSUFFICIENT;
2273 }
2274 for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) {
2275 result = Serialize_BYTE(value.sha512[i], buffer);
2276 if (result) {
2277 return result;
2278 }
2279 }
2280 }
2281 return result;
2282 }
2283
Parse_TPMU_HA(std::string * buffer,TPMI_ALG_HASH selector,TPMU_HA * value,std::string * value_bytes)2284 TPM_RC Parse_TPMU_HA(std::string* buffer,
2285 TPMI_ALG_HASH selector,
2286 TPMU_HA* value,
2287 std::string* value_bytes) {
2288 TPM_RC result = TPM_RC_SUCCESS;
2289 VLOG(3) << __func__;
2290
2291 if (selector == TPM_ALG_SHA384) {
2292 if (std::size(value->sha384) < SHA384_DIGEST_SIZE) {
2293 return TPM_RC_INSUFFICIENT;
2294 }
2295 for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) {
2296 result = Parse_BYTE(buffer, &value->sha384[i], value_bytes);
2297 if (result) {
2298 return result;
2299 }
2300 }
2301 }
2302
2303 if (selector == TPM_ALG_SHA1) {
2304 if (std::size(value->sha1) < SHA1_DIGEST_SIZE) {
2305 return TPM_RC_INSUFFICIENT;
2306 }
2307 for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) {
2308 result = Parse_BYTE(buffer, &value->sha1[i], value_bytes);
2309 if (result) {
2310 return result;
2311 }
2312 }
2313 }
2314
2315 if (selector == TPM_ALG_SM3_256) {
2316 if (std::size(value->sm3_256) < SM3_256_DIGEST_SIZE) {
2317 return TPM_RC_INSUFFICIENT;
2318 }
2319 for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) {
2320 result = Parse_BYTE(buffer, &value->sm3_256[i], value_bytes);
2321 if (result) {
2322 return result;
2323 }
2324 }
2325 }
2326
2327 if (selector == TPM_ALG_NULL) {
2328 // Do nothing.
2329 }
2330
2331 if (selector == TPM_ALG_SHA256) {
2332 if (std::size(value->sha256) < SHA256_DIGEST_SIZE) {
2333 return TPM_RC_INSUFFICIENT;
2334 }
2335 for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) {
2336 result = Parse_BYTE(buffer, &value->sha256[i], value_bytes);
2337 if (result) {
2338 return result;
2339 }
2340 }
2341 }
2342
2343 if (selector == TPM_ALG_SHA512) {
2344 if (std::size(value->sha512) < SHA512_DIGEST_SIZE) {
2345 return TPM_RC_INSUFFICIENT;
2346 }
2347 for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) {
2348 result = Parse_BYTE(buffer, &value->sha512[i], value_bytes);
2349 if (result) {
2350 return result;
2351 }
2352 }
2353 }
2354 return result;
2355 }
2356
Serialize_TPMT_HA(const TPMT_HA & value,std::string * buffer)2357 TPM_RC Serialize_TPMT_HA(const TPMT_HA& value, std::string* buffer) {
2358 TPM_RC result = TPM_RC_SUCCESS;
2359 VLOG(3) << __func__;
2360
2361 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
2362 if (result) {
2363 return result;
2364 }
2365
2366 result = Serialize_TPMU_HA(value.digest, value.hash_alg, buffer);
2367 if (result) {
2368 return result;
2369 }
2370 return result;
2371 }
2372
Parse_TPMT_HA(std::string * buffer,TPMT_HA * value,std::string * value_bytes)2373 TPM_RC Parse_TPMT_HA(std::string* buffer,
2374 TPMT_HA* value,
2375 std::string* value_bytes) {
2376 TPM_RC result = TPM_RC_SUCCESS;
2377 VLOG(3) << __func__;
2378
2379 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
2380 if (result) {
2381 return result;
2382 }
2383
2384 result = Parse_TPMU_HA(buffer, value->hash_alg, &value->digest, value_bytes);
2385 if (result) {
2386 return result;
2387 }
2388 return result;
2389 }
2390
Serialize_TPM2B_DATA(const TPM2B_DATA & value,std::string * buffer)2391 TPM_RC Serialize_TPM2B_DATA(const TPM2B_DATA& value, std::string* buffer) {
2392 TPM_RC result = TPM_RC_SUCCESS;
2393 VLOG(3) << __func__;
2394
2395 result = Serialize_UINT16(value.size, buffer);
2396 if (result) {
2397 return result;
2398 }
2399
2400 if (std::size(value.buffer) < value.size) {
2401 return TPM_RC_INSUFFICIENT;
2402 }
2403 for (uint32_t i = 0; i < value.size; ++i) {
2404 result = Serialize_BYTE(value.buffer[i], buffer);
2405 if (result) {
2406 return result;
2407 }
2408 }
2409 return result;
2410 }
2411
Parse_TPM2B_DATA(std::string * buffer,TPM2B_DATA * value,std::string * value_bytes)2412 TPM_RC Parse_TPM2B_DATA(std::string* buffer,
2413 TPM2B_DATA* value,
2414 std::string* value_bytes) {
2415 TPM_RC result = TPM_RC_SUCCESS;
2416 VLOG(3) << __func__;
2417
2418 result = Parse_UINT16(buffer, &value->size, value_bytes);
2419 if (result) {
2420 return result;
2421 }
2422
2423 if (std::size(value->buffer) < value->size) {
2424 return TPM_RC_INSUFFICIENT;
2425 }
2426 for (uint32_t i = 0; i < value->size; ++i) {
2427 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2428 if (result) {
2429 return result;
2430 }
2431 }
2432 return result;
2433 }
2434
Make_TPM2B_DATA(const std::string & bytes)2435 TPM2B_DATA Make_TPM2B_DATA(const std::string& bytes) {
2436 TPM2B_DATA tpm2b;
2437 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2438 memset(&tpm2b, 0, sizeof(TPM2B_DATA));
2439 tpm2b.size = bytes.size();
2440 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2441 return tpm2b;
2442 }
2443
StringFrom_TPM2B_DATA(const TPM2B_DATA & tpm2b)2444 std::string StringFrom_TPM2B_DATA(const TPM2B_DATA& tpm2b) {
2445 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2446 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2447 return std::string(char_buffer, tpm2b.size);
2448 }
2449
Serialize_TPM2B_EVENT(const TPM2B_EVENT & value,std::string * buffer)2450 TPM_RC Serialize_TPM2B_EVENT(const TPM2B_EVENT& value, std::string* buffer) {
2451 TPM_RC result = TPM_RC_SUCCESS;
2452 VLOG(3) << __func__;
2453
2454 result = Serialize_UINT16(value.size, buffer);
2455 if (result) {
2456 return result;
2457 }
2458
2459 if (std::size(value.buffer) < value.size) {
2460 return TPM_RC_INSUFFICIENT;
2461 }
2462 for (uint32_t i = 0; i < value.size; ++i) {
2463 result = Serialize_BYTE(value.buffer[i], buffer);
2464 if (result) {
2465 return result;
2466 }
2467 }
2468 return result;
2469 }
2470
Parse_TPM2B_EVENT(std::string * buffer,TPM2B_EVENT * value,std::string * value_bytes)2471 TPM_RC Parse_TPM2B_EVENT(std::string* buffer,
2472 TPM2B_EVENT* value,
2473 std::string* value_bytes) {
2474 TPM_RC result = TPM_RC_SUCCESS;
2475 VLOG(3) << __func__;
2476
2477 result = Parse_UINT16(buffer, &value->size, value_bytes);
2478 if (result) {
2479 return result;
2480 }
2481
2482 if (std::size(value->buffer) < value->size) {
2483 return TPM_RC_INSUFFICIENT;
2484 }
2485 for (uint32_t i = 0; i < value->size; ++i) {
2486 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2487 if (result) {
2488 return result;
2489 }
2490 }
2491 return result;
2492 }
2493
Make_TPM2B_EVENT(const std::string & bytes)2494 TPM2B_EVENT Make_TPM2B_EVENT(const std::string& bytes) {
2495 TPM2B_EVENT tpm2b;
2496 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2497 memset(&tpm2b, 0, sizeof(TPM2B_EVENT));
2498 tpm2b.size = bytes.size();
2499 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2500 return tpm2b;
2501 }
2502
StringFrom_TPM2B_EVENT(const TPM2B_EVENT & tpm2b)2503 std::string StringFrom_TPM2B_EVENT(const TPM2B_EVENT& tpm2b) {
2504 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2505 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2506 return std::string(char_buffer, tpm2b.size);
2507 }
2508
Serialize_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER & value,std::string * buffer)2509 TPM_RC Serialize_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER& value,
2510 std::string* buffer) {
2511 TPM_RC result = TPM_RC_SUCCESS;
2512 VLOG(3) << __func__;
2513
2514 result = Serialize_UINT16(value.size, buffer);
2515 if (result) {
2516 return result;
2517 }
2518
2519 if (std::size(value.buffer) < value.size) {
2520 return TPM_RC_INSUFFICIENT;
2521 }
2522 for (uint32_t i = 0; i < value.size; ++i) {
2523 result = Serialize_BYTE(value.buffer[i], buffer);
2524 if (result) {
2525 return result;
2526 }
2527 }
2528 return result;
2529 }
2530
Parse_TPM2B_MAX_BUFFER(std::string * buffer,TPM2B_MAX_BUFFER * value,std::string * value_bytes)2531 TPM_RC Parse_TPM2B_MAX_BUFFER(std::string* buffer,
2532 TPM2B_MAX_BUFFER* value,
2533 std::string* value_bytes) {
2534 TPM_RC result = TPM_RC_SUCCESS;
2535 VLOG(3) << __func__;
2536
2537 result = Parse_UINT16(buffer, &value->size, value_bytes);
2538 if (result) {
2539 return result;
2540 }
2541
2542 if (std::size(value->buffer) < value->size) {
2543 return TPM_RC_INSUFFICIENT;
2544 }
2545 for (uint32_t i = 0; i < value->size; ++i) {
2546 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2547 if (result) {
2548 return result;
2549 }
2550 }
2551 return result;
2552 }
2553
Make_TPM2B_MAX_BUFFER(const std::string & bytes)2554 TPM2B_MAX_BUFFER Make_TPM2B_MAX_BUFFER(const std::string& bytes) {
2555 TPM2B_MAX_BUFFER tpm2b;
2556 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2557 memset(&tpm2b, 0, sizeof(TPM2B_MAX_BUFFER));
2558 tpm2b.size = bytes.size();
2559 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2560 return tpm2b;
2561 }
2562
StringFrom_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER & tpm2b)2563 std::string StringFrom_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER& tpm2b) {
2564 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2565 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2566 return std::string(char_buffer, tpm2b.size);
2567 }
2568
Serialize_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER & value,std::string * buffer)2569 TPM_RC Serialize_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER& value,
2570 std::string* buffer) {
2571 TPM_RC result = TPM_RC_SUCCESS;
2572 VLOG(3) << __func__;
2573
2574 result = Serialize_UINT16(value.size, buffer);
2575 if (result) {
2576 return result;
2577 }
2578
2579 if (std::size(value.buffer) < value.size) {
2580 return TPM_RC_INSUFFICIENT;
2581 }
2582 for (uint32_t i = 0; i < value.size; ++i) {
2583 result = Serialize_BYTE(value.buffer[i], buffer);
2584 if (result) {
2585 return result;
2586 }
2587 }
2588 return result;
2589 }
2590
Parse_TPM2B_MAX_NV_BUFFER(std::string * buffer,TPM2B_MAX_NV_BUFFER * value,std::string * value_bytes)2591 TPM_RC Parse_TPM2B_MAX_NV_BUFFER(std::string* buffer,
2592 TPM2B_MAX_NV_BUFFER* value,
2593 std::string* value_bytes) {
2594 TPM_RC result = TPM_RC_SUCCESS;
2595 VLOG(3) << __func__;
2596
2597 result = Parse_UINT16(buffer, &value->size, value_bytes);
2598 if (result) {
2599 return result;
2600 }
2601
2602 if (std::size(value->buffer) < value->size) {
2603 return TPM_RC_INSUFFICIENT;
2604 }
2605 for (uint32_t i = 0; i < value->size; ++i) {
2606 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2607 if (result) {
2608 return result;
2609 }
2610 }
2611 return result;
2612 }
2613
Make_TPM2B_MAX_NV_BUFFER(const std::string & bytes)2614 TPM2B_MAX_NV_BUFFER Make_TPM2B_MAX_NV_BUFFER(const std::string& bytes) {
2615 TPM2B_MAX_NV_BUFFER tpm2b;
2616 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2617 memset(&tpm2b, 0, sizeof(TPM2B_MAX_NV_BUFFER));
2618 tpm2b.size = bytes.size();
2619 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2620 return tpm2b;
2621 }
2622
StringFrom_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER & tpm2b)2623 std::string StringFrom_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER& tpm2b) {
2624 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2625 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2626 return std::string(char_buffer, tpm2b.size);
2627 }
2628
Serialize_TPM2B_TIMEOUT(const TPM2B_TIMEOUT & value,std::string * buffer)2629 TPM_RC Serialize_TPM2B_TIMEOUT(const TPM2B_TIMEOUT& value,
2630 std::string* buffer) {
2631 TPM_RC result = TPM_RC_SUCCESS;
2632 VLOG(3) << __func__;
2633
2634 result = Serialize_UINT16(value.size, buffer);
2635 if (result) {
2636 return result;
2637 }
2638
2639 if (std::size(value.buffer) < value.size) {
2640 return TPM_RC_INSUFFICIENT;
2641 }
2642 for (uint32_t i = 0; i < value.size; ++i) {
2643 result = Serialize_BYTE(value.buffer[i], buffer);
2644 if (result) {
2645 return result;
2646 }
2647 }
2648 return result;
2649 }
2650
Parse_TPM2B_TIMEOUT(std::string * buffer,TPM2B_TIMEOUT * value,std::string * value_bytes)2651 TPM_RC Parse_TPM2B_TIMEOUT(std::string* buffer,
2652 TPM2B_TIMEOUT* value,
2653 std::string* value_bytes) {
2654 TPM_RC result = TPM_RC_SUCCESS;
2655 VLOG(3) << __func__;
2656
2657 result = Parse_UINT16(buffer, &value->size, value_bytes);
2658 if (result) {
2659 return result;
2660 }
2661
2662 if (std::size(value->buffer) < value->size) {
2663 return TPM_RC_INSUFFICIENT;
2664 }
2665 for (uint32_t i = 0; i < value->size; ++i) {
2666 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2667 if (result) {
2668 return result;
2669 }
2670 }
2671 return result;
2672 }
2673
Make_TPM2B_TIMEOUT(const std::string & bytes)2674 TPM2B_TIMEOUT Make_TPM2B_TIMEOUT(const std::string& bytes) {
2675 TPM2B_TIMEOUT tpm2b;
2676 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2677 memset(&tpm2b, 0, sizeof(TPM2B_TIMEOUT));
2678 tpm2b.size = bytes.size();
2679 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2680 return tpm2b;
2681 }
2682
StringFrom_TPM2B_TIMEOUT(const TPM2B_TIMEOUT & tpm2b)2683 std::string StringFrom_TPM2B_TIMEOUT(const TPM2B_TIMEOUT& tpm2b) {
2684 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2685 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2686 return std::string(char_buffer, tpm2b.size);
2687 }
2688
Serialize_TPM2B_IV(const TPM2B_IV & value,std::string * buffer)2689 TPM_RC Serialize_TPM2B_IV(const TPM2B_IV& value, std::string* buffer) {
2690 TPM_RC result = TPM_RC_SUCCESS;
2691 VLOG(3) << __func__;
2692
2693 result = Serialize_UINT16(value.size, buffer);
2694 if (result) {
2695 return result;
2696 }
2697
2698 if (std::size(value.buffer) < value.size) {
2699 return TPM_RC_INSUFFICIENT;
2700 }
2701 for (uint32_t i = 0; i < value.size; ++i) {
2702 result = Serialize_BYTE(value.buffer[i], buffer);
2703 if (result) {
2704 return result;
2705 }
2706 }
2707 return result;
2708 }
2709
Parse_TPM2B_IV(std::string * buffer,TPM2B_IV * value,std::string * value_bytes)2710 TPM_RC Parse_TPM2B_IV(std::string* buffer,
2711 TPM2B_IV* value,
2712 std::string* value_bytes) {
2713 TPM_RC result = TPM_RC_SUCCESS;
2714 VLOG(3) << __func__;
2715
2716 result = Parse_UINT16(buffer, &value->size, value_bytes);
2717 if (result) {
2718 return result;
2719 }
2720
2721 if (std::size(value->buffer) < value->size) {
2722 return TPM_RC_INSUFFICIENT;
2723 }
2724 for (uint32_t i = 0; i < value->size; ++i) {
2725 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2726 if (result) {
2727 return result;
2728 }
2729 }
2730 return result;
2731 }
2732
Make_TPM2B_IV(const std::string & bytes)2733 TPM2B_IV Make_TPM2B_IV(const std::string& bytes) {
2734 TPM2B_IV tpm2b;
2735 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2736 memset(&tpm2b, 0, sizeof(TPM2B_IV));
2737 tpm2b.size = bytes.size();
2738 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2739 return tpm2b;
2740 }
2741
StringFrom_TPM2B_IV(const TPM2B_IV & tpm2b)2742 std::string StringFrom_TPM2B_IV(const TPM2B_IV& tpm2b) {
2743 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2744 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2745 return std::string(char_buffer, tpm2b.size);
2746 }
2747
Serialize_TPM2B_NAME(const TPM2B_NAME & value,std::string * buffer)2748 TPM_RC Serialize_TPM2B_NAME(const TPM2B_NAME& value, std::string* buffer) {
2749 TPM_RC result = TPM_RC_SUCCESS;
2750 VLOG(3) << __func__;
2751
2752 result = Serialize_UINT16(value.size, buffer);
2753 if (result) {
2754 return result;
2755 }
2756
2757 if (std::size(value.name) < value.size) {
2758 return TPM_RC_INSUFFICIENT;
2759 }
2760 for (uint32_t i = 0; i < value.size; ++i) {
2761 result = Serialize_BYTE(value.name[i], buffer);
2762 if (result) {
2763 return result;
2764 }
2765 }
2766 return result;
2767 }
2768
Parse_TPM2B_NAME(std::string * buffer,TPM2B_NAME * value,std::string * value_bytes)2769 TPM_RC Parse_TPM2B_NAME(std::string* buffer,
2770 TPM2B_NAME* value,
2771 std::string* value_bytes) {
2772 TPM_RC result = TPM_RC_SUCCESS;
2773 VLOG(3) << __func__;
2774
2775 result = Parse_UINT16(buffer, &value->size, value_bytes);
2776 if (result) {
2777 return result;
2778 }
2779
2780 if (std::size(value->name) < value->size) {
2781 return TPM_RC_INSUFFICIENT;
2782 }
2783 for (uint32_t i = 0; i < value->size; ++i) {
2784 result = Parse_BYTE(buffer, &value->name[i], value_bytes);
2785 if (result) {
2786 return result;
2787 }
2788 }
2789 return result;
2790 }
2791
Make_TPM2B_NAME(const std::string & bytes)2792 TPM2B_NAME Make_TPM2B_NAME(const std::string& bytes) {
2793 TPM2B_NAME tpm2b;
2794 CHECK(bytes.size() <= sizeof(tpm2b.name));
2795 memset(&tpm2b, 0, sizeof(TPM2B_NAME));
2796 tpm2b.size = bytes.size();
2797 memcpy(tpm2b.name, bytes.data(), bytes.size());
2798 return tpm2b;
2799 }
2800
StringFrom_TPM2B_NAME(const TPM2B_NAME & tpm2b)2801 std::string StringFrom_TPM2B_NAME(const TPM2B_NAME& tpm2b) {
2802 CHECK(tpm2b.size <= std::size(tpm2b.name));
2803 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.name);
2804 return std::string(char_buffer, tpm2b.size);
2805 }
2806
Serialize_TPMS_PCR_SELECT(const TPMS_PCR_SELECT & value,std::string * buffer)2807 TPM_RC Serialize_TPMS_PCR_SELECT(const TPMS_PCR_SELECT& value,
2808 std::string* buffer) {
2809 TPM_RC result = TPM_RC_SUCCESS;
2810 VLOG(3) << __func__;
2811
2812 result = Serialize_UINT8(value.sizeof_select, buffer);
2813 if (result) {
2814 return result;
2815 }
2816
2817 if (std::size(value.pcr_select) < value.sizeof_select) {
2818 return TPM_RC_INSUFFICIENT;
2819 }
2820 for (uint32_t i = 0; i < value.sizeof_select; ++i) {
2821 result = Serialize_BYTE(value.pcr_select[i], buffer);
2822 if (result) {
2823 return result;
2824 }
2825 }
2826 return result;
2827 }
2828
Parse_TPMS_PCR_SELECT(std::string * buffer,TPMS_PCR_SELECT * value,std::string * value_bytes)2829 TPM_RC Parse_TPMS_PCR_SELECT(std::string* buffer,
2830 TPMS_PCR_SELECT* value,
2831 std::string* value_bytes) {
2832 TPM_RC result = TPM_RC_SUCCESS;
2833 VLOG(3) << __func__;
2834
2835 result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
2836 if (result) {
2837 return result;
2838 }
2839
2840 if (std::size(value->pcr_select) < value->sizeof_select) {
2841 return TPM_RC_INSUFFICIENT;
2842 }
2843 for (uint32_t i = 0; i < value->sizeof_select; ++i) {
2844 result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
2845 if (result) {
2846 return result;
2847 }
2848 }
2849 return result;
2850 }
2851
Serialize_TPMS_PCR_SELECTION(const TPMS_PCR_SELECTION & value,std::string * buffer)2852 TPM_RC Serialize_TPMS_PCR_SELECTION(const TPMS_PCR_SELECTION& value,
2853 std::string* buffer) {
2854 TPM_RC result = TPM_RC_SUCCESS;
2855 VLOG(3) << __func__;
2856
2857 result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
2858 if (result) {
2859 return result;
2860 }
2861
2862 result = Serialize_UINT8(value.sizeof_select, buffer);
2863 if (result) {
2864 return result;
2865 }
2866
2867 if (std::size(value.pcr_select) < value.sizeof_select) {
2868 return TPM_RC_INSUFFICIENT;
2869 }
2870 for (uint32_t i = 0; i < value.sizeof_select; ++i) {
2871 result = Serialize_BYTE(value.pcr_select[i], buffer);
2872 if (result) {
2873 return result;
2874 }
2875 }
2876 return result;
2877 }
2878
Parse_TPMS_PCR_SELECTION(std::string * buffer,TPMS_PCR_SELECTION * value,std::string * value_bytes)2879 TPM_RC Parse_TPMS_PCR_SELECTION(std::string* buffer,
2880 TPMS_PCR_SELECTION* value,
2881 std::string* value_bytes) {
2882 TPM_RC result = TPM_RC_SUCCESS;
2883 VLOG(3) << __func__;
2884
2885 result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
2886 if (result) {
2887 return result;
2888 }
2889
2890 result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
2891 if (result) {
2892 return result;
2893 }
2894
2895 if (std::size(value->pcr_select) < value->sizeof_select) {
2896 return TPM_RC_INSUFFICIENT;
2897 }
2898 for (uint32_t i = 0; i < value->sizeof_select; ++i) {
2899 result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
2900 if (result) {
2901 return result;
2902 }
2903 }
2904 return result;
2905 }
2906
Serialize_TPMT_TK_CREATION(const TPMT_TK_CREATION & value,std::string * buffer)2907 TPM_RC Serialize_TPMT_TK_CREATION(const TPMT_TK_CREATION& value,
2908 std::string* buffer) {
2909 TPM_RC result = TPM_RC_SUCCESS;
2910 VLOG(3) << __func__;
2911
2912 result = Serialize_TPM_ST(value.tag, buffer);
2913 if (result) {
2914 return result;
2915 }
2916
2917 result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
2918 if (result) {
2919 return result;
2920 }
2921
2922 result = Serialize_TPM2B_DIGEST(value.digest, buffer);
2923 if (result) {
2924 return result;
2925 }
2926 return result;
2927 }
2928
Parse_TPMT_TK_CREATION(std::string * buffer,TPMT_TK_CREATION * value,std::string * value_bytes)2929 TPM_RC Parse_TPMT_TK_CREATION(std::string* buffer,
2930 TPMT_TK_CREATION* value,
2931 std::string* value_bytes) {
2932 TPM_RC result = TPM_RC_SUCCESS;
2933 VLOG(3) << __func__;
2934
2935 result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
2936 if (result) {
2937 return result;
2938 }
2939
2940 result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
2941 if (result) {
2942 return result;
2943 }
2944
2945 result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
2946 if (result) {
2947 return result;
2948 }
2949 return result;
2950 }
2951
Serialize_TPMT_TK_VERIFIED(const TPMT_TK_VERIFIED & value,std::string * buffer)2952 TPM_RC Serialize_TPMT_TK_VERIFIED(const TPMT_TK_VERIFIED& value,
2953 std::string* buffer) {
2954 TPM_RC result = TPM_RC_SUCCESS;
2955 VLOG(3) << __func__;
2956
2957 result = Serialize_TPM_ST(value.tag, buffer);
2958 if (result) {
2959 return result;
2960 }
2961
2962 result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
2963 if (result) {
2964 return result;
2965 }
2966
2967 result = Serialize_TPM2B_DIGEST(value.digest, buffer);
2968 if (result) {
2969 return result;
2970 }
2971 return result;
2972 }
2973
Parse_TPMT_TK_VERIFIED(std::string * buffer,TPMT_TK_VERIFIED * value,std::string * value_bytes)2974 TPM_RC Parse_TPMT_TK_VERIFIED(std::string* buffer,
2975 TPMT_TK_VERIFIED* value,
2976 std::string* value_bytes) {
2977 TPM_RC result = TPM_RC_SUCCESS;
2978 VLOG(3) << __func__;
2979
2980 result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
2981 if (result) {
2982 return result;
2983 }
2984
2985 result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
2986 if (result) {
2987 return result;
2988 }
2989
2990 result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
2991 if (result) {
2992 return result;
2993 }
2994 return result;
2995 }
2996
Serialize_TPMT_TK_AUTH(const TPMT_TK_AUTH & value,std::string * buffer)2997 TPM_RC Serialize_TPMT_TK_AUTH(const TPMT_TK_AUTH& value, std::string* buffer) {
2998 TPM_RC result = TPM_RC_SUCCESS;
2999 VLOG(3) << __func__;
3000
3001 result = Serialize_TPM_ST(value.tag, buffer);
3002 if (result) {
3003 return result;
3004 }
3005
3006 result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
3007 if (result) {
3008 return result;
3009 }
3010
3011 result = Serialize_TPM2B_DIGEST(value.digest, buffer);
3012 if (result) {
3013 return result;
3014 }
3015 return result;
3016 }
3017
Parse_TPMT_TK_AUTH(std::string * buffer,TPMT_TK_AUTH * value,std::string * value_bytes)3018 TPM_RC Parse_TPMT_TK_AUTH(std::string* buffer,
3019 TPMT_TK_AUTH* value,
3020 std::string* value_bytes) {
3021 TPM_RC result = TPM_RC_SUCCESS;
3022 VLOG(3) << __func__;
3023
3024 result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
3025 if (result) {
3026 return result;
3027 }
3028
3029 result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
3030 if (result) {
3031 return result;
3032 }
3033
3034 result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
3035 if (result) {
3036 return result;
3037 }
3038 return result;
3039 }
3040
Serialize_TPMT_TK_HASHCHECK(const TPMT_TK_HASHCHECK & value,std::string * buffer)3041 TPM_RC Serialize_TPMT_TK_HASHCHECK(const TPMT_TK_HASHCHECK& value,
3042 std::string* buffer) {
3043 TPM_RC result = TPM_RC_SUCCESS;
3044 VLOG(3) << __func__;
3045
3046 result = Serialize_TPM_ST(value.tag, buffer);
3047 if (result) {
3048 return result;
3049 }
3050
3051 result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
3052 if (result) {
3053 return result;
3054 }
3055
3056 result = Serialize_TPM2B_DIGEST(value.digest, buffer);
3057 if (result) {
3058 return result;
3059 }
3060 return result;
3061 }
3062
Parse_TPMT_TK_HASHCHECK(std::string * buffer,TPMT_TK_HASHCHECK * value,std::string * value_bytes)3063 TPM_RC Parse_TPMT_TK_HASHCHECK(std::string* buffer,
3064 TPMT_TK_HASHCHECK* value,
3065 std::string* value_bytes) {
3066 TPM_RC result = TPM_RC_SUCCESS;
3067 VLOG(3) << __func__;
3068
3069 result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
3070 if (result) {
3071 return result;
3072 }
3073
3074 result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
3075 if (result) {
3076 return result;
3077 }
3078
3079 result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
3080 if (result) {
3081 return result;
3082 }
3083 return result;
3084 }
3085
Serialize_TPMS_ALG_PROPERTY(const TPMS_ALG_PROPERTY & value,std::string * buffer)3086 TPM_RC Serialize_TPMS_ALG_PROPERTY(const TPMS_ALG_PROPERTY& value,
3087 std::string* buffer) {
3088 TPM_RC result = TPM_RC_SUCCESS;
3089 VLOG(3) << __func__;
3090
3091 result = Serialize_TPM_ALG_ID(value.alg, buffer);
3092 if (result) {
3093 return result;
3094 }
3095
3096 result = Serialize_TPMA_ALGORITHM(value.alg_properties, buffer);
3097 if (result) {
3098 return result;
3099 }
3100 return result;
3101 }
3102
Parse_TPMS_ALG_PROPERTY(std::string * buffer,TPMS_ALG_PROPERTY * value,std::string * value_bytes)3103 TPM_RC Parse_TPMS_ALG_PROPERTY(std::string* buffer,
3104 TPMS_ALG_PROPERTY* value,
3105 std::string* value_bytes) {
3106 TPM_RC result = TPM_RC_SUCCESS;
3107 VLOG(3) << __func__;
3108
3109 result = Parse_TPM_ALG_ID(buffer, &value->alg, value_bytes);
3110 if (result) {
3111 return result;
3112 }
3113
3114 result = Parse_TPMA_ALGORITHM(buffer, &value->alg_properties, value_bytes);
3115 if (result) {
3116 return result;
3117 }
3118 return result;
3119 }
3120
Serialize_TPMS_TAGGED_PROPERTY(const TPMS_TAGGED_PROPERTY & value,std::string * buffer)3121 TPM_RC Serialize_TPMS_TAGGED_PROPERTY(const TPMS_TAGGED_PROPERTY& value,
3122 std::string* buffer) {
3123 TPM_RC result = TPM_RC_SUCCESS;
3124 VLOG(3) << __func__;
3125
3126 result = Serialize_TPM_PT(value.property, buffer);
3127 if (result) {
3128 return result;
3129 }
3130
3131 result = Serialize_UINT32(value.value, buffer);
3132 if (result) {
3133 return result;
3134 }
3135 return result;
3136 }
3137
Parse_TPMS_TAGGED_PROPERTY(std::string * buffer,TPMS_TAGGED_PROPERTY * value,std::string * value_bytes)3138 TPM_RC Parse_TPMS_TAGGED_PROPERTY(std::string* buffer,
3139 TPMS_TAGGED_PROPERTY* value,
3140 std::string* value_bytes) {
3141 TPM_RC result = TPM_RC_SUCCESS;
3142 VLOG(3) << __func__;
3143
3144 result = Parse_TPM_PT(buffer, &value->property, value_bytes);
3145 if (result) {
3146 return result;
3147 }
3148
3149 result = Parse_UINT32(buffer, &value->value, value_bytes);
3150 if (result) {
3151 return result;
3152 }
3153 return result;
3154 }
3155
Serialize_TPMS_TAGGED_PCR_SELECT(const TPMS_TAGGED_PCR_SELECT & value,std::string * buffer)3156 TPM_RC Serialize_TPMS_TAGGED_PCR_SELECT(const TPMS_TAGGED_PCR_SELECT& value,
3157 std::string* buffer) {
3158 TPM_RC result = TPM_RC_SUCCESS;
3159 VLOG(3) << __func__;
3160
3161 result = Serialize_TPM_PT(value.tag, buffer);
3162 if (result) {
3163 return result;
3164 }
3165
3166 result = Serialize_UINT8(value.sizeof_select, buffer);
3167 if (result) {
3168 return result;
3169 }
3170
3171 if (std::size(value.pcr_select) < value.sizeof_select) {
3172 return TPM_RC_INSUFFICIENT;
3173 }
3174 for (uint32_t i = 0; i < value.sizeof_select; ++i) {
3175 result = Serialize_BYTE(value.pcr_select[i], buffer);
3176 if (result) {
3177 return result;
3178 }
3179 }
3180 return result;
3181 }
3182
Parse_TPMS_TAGGED_PCR_SELECT(std::string * buffer,TPMS_TAGGED_PCR_SELECT * value,std::string * value_bytes)3183 TPM_RC Parse_TPMS_TAGGED_PCR_SELECT(std::string* buffer,
3184 TPMS_TAGGED_PCR_SELECT* value,
3185 std::string* value_bytes) {
3186 TPM_RC result = TPM_RC_SUCCESS;
3187 VLOG(3) << __func__;
3188
3189 result = Parse_TPM_PT(buffer, &value->tag, value_bytes);
3190 if (result) {
3191 return result;
3192 }
3193
3194 result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
3195 if (result) {
3196 return result;
3197 }
3198
3199 if (std::size(value->pcr_select) < value->sizeof_select) {
3200 return TPM_RC_INSUFFICIENT;
3201 }
3202 for (uint32_t i = 0; i < value->sizeof_select; ++i) {
3203 result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
3204 if (result) {
3205 return result;
3206 }
3207 }
3208 return result;
3209 }
3210
Serialize_TPML_CC(const TPML_CC & value,std::string * buffer)3211 TPM_RC Serialize_TPML_CC(const TPML_CC& value, std::string* buffer) {
3212 TPM_RC result = TPM_RC_SUCCESS;
3213 VLOG(3) << __func__;
3214
3215 result = Serialize_UINT32(value.count, buffer);
3216 if (result) {
3217 return result;
3218 }
3219
3220 if (std::size(value.command_codes) < value.count) {
3221 return TPM_RC_INSUFFICIENT;
3222 }
3223 for (uint32_t i = 0; i < value.count; ++i) {
3224 result = Serialize_TPM_CC(value.command_codes[i], buffer);
3225 if (result) {
3226 return result;
3227 }
3228 }
3229 return result;
3230 }
3231
Parse_TPML_CC(std::string * buffer,TPML_CC * value,std::string * value_bytes)3232 TPM_RC Parse_TPML_CC(std::string* buffer,
3233 TPML_CC* value,
3234 std::string* value_bytes) {
3235 TPM_RC result = TPM_RC_SUCCESS;
3236 VLOG(3) << __func__;
3237
3238 result = Parse_UINT32(buffer, &value->count, value_bytes);
3239 if (result) {
3240 return result;
3241 }
3242
3243 if (std::size(value->command_codes) < value->count) {
3244 return TPM_RC_INSUFFICIENT;
3245 }
3246 for (uint32_t i = 0; i < value->count; ++i) {
3247 result = Parse_TPM_CC(buffer, &value->command_codes[i], value_bytes);
3248 if (result) {
3249 return result;
3250 }
3251 }
3252 return result;
3253 }
3254
Serialize_TPML_CCA(const TPML_CCA & value,std::string * buffer)3255 TPM_RC Serialize_TPML_CCA(const TPML_CCA& value, std::string* buffer) {
3256 TPM_RC result = TPM_RC_SUCCESS;
3257 VLOG(3) << __func__;
3258
3259 result = Serialize_UINT32(value.count, buffer);
3260 if (result) {
3261 return result;
3262 }
3263
3264 if (std::size(value.command_attributes) < value.count) {
3265 return TPM_RC_INSUFFICIENT;
3266 }
3267 for (uint32_t i = 0; i < value.count; ++i) {
3268 result = Serialize_TPMA_CC(value.command_attributes[i], buffer);
3269 if (result) {
3270 return result;
3271 }
3272 }
3273 return result;
3274 }
3275
Parse_TPML_CCA(std::string * buffer,TPML_CCA * value,std::string * value_bytes)3276 TPM_RC Parse_TPML_CCA(std::string* buffer,
3277 TPML_CCA* value,
3278 std::string* value_bytes) {
3279 TPM_RC result = TPM_RC_SUCCESS;
3280 VLOG(3) << __func__;
3281
3282 result = Parse_UINT32(buffer, &value->count, value_bytes);
3283 if (result) {
3284 return result;
3285 }
3286
3287 if (std::size(value->command_attributes) < value->count) {
3288 return TPM_RC_INSUFFICIENT;
3289 }
3290 for (uint32_t i = 0; i < value->count; ++i) {
3291 result = Parse_TPMA_CC(buffer, &value->command_attributes[i], value_bytes);
3292 if (result) {
3293 return result;
3294 }
3295 }
3296 return result;
3297 }
3298
Serialize_TPML_ALG(const TPML_ALG & value,std::string * buffer)3299 TPM_RC Serialize_TPML_ALG(const TPML_ALG& value, std::string* buffer) {
3300 TPM_RC result = TPM_RC_SUCCESS;
3301 VLOG(3) << __func__;
3302
3303 result = Serialize_UINT32(value.count, buffer);
3304 if (result) {
3305 return result;
3306 }
3307
3308 if (std::size(value.algorithms) < value.count) {
3309 return TPM_RC_INSUFFICIENT;
3310 }
3311 for (uint32_t i = 0; i < value.count; ++i) {
3312 result = Serialize_TPM_ALG_ID(value.algorithms[i], buffer);
3313 if (result) {
3314 return result;
3315 }
3316 }
3317 return result;
3318 }
3319
Parse_TPML_ALG(std::string * buffer,TPML_ALG * value,std::string * value_bytes)3320 TPM_RC Parse_TPML_ALG(std::string* buffer,
3321 TPML_ALG* value,
3322 std::string* value_bytes) {
3323 TPM_RC result = TPM_RC_SUCCESS;
3324 VLOG(3) << __func__;
3325
3326 result = Parse_UINT32(buffer, &value->count, value_bytes);
3327 if (result) {
3328 return result;
3329 }
3330
3331 if (std::size(value->algorithms) < value->count) {
3332 return TPM_RC_INSUFFICIENT;
3333 }
3334 for (uint32_t i = 0; i < value->count; ++i) {
3335 result = Parse_TPM_ALG_ID(buffer, &value->algorithms[i], value_bytes);
3336 if (result) {
3337 return result;
3338 }
3339 }
3340 return result;
3341 }
3342
Serialize_TPML_HANDLE(const TPML_HANDLE & value,std::string * buffer)3343 TPM_RC Serialize_TPML_HANDLE(const TPML_HANDLE& value, std::string* buffer) {
3344 TPM_RC result = TPM_RC_SUCCESS;
3345 VLOG(3) << __func__;
3346
3347 result = Serialize_UINT32(value.count, buffer);
3348 if (result) {
3349 return result;
3350 }
3351
3352 if (std::size(value.handle) < value.count) {
3353 return TPM_RC_INSUFFICIENT;
3354 }
3355 for (uint32_t i = 0; i < value.count; ++i) {
3356 result = Serialize_TPM_HANDLE(value.handle[i], buffer);
3357 if (result) {
3358 return result;
3359 }
3360 }
3361 return result;
3362 }
3363
Parse_TPML_HANDLE(std::string * buffer,TPML_HANDLE * value,std::string * value_bytes)3364 TPM_RC Parse_TPML_HANDLE(std::string* buffer,
3365 TPML_HANDLE* value,
3366 std::string* value_bytes) {
3367 TPM_RC result = TPM_RC_SUCCESS;
3368 VLOG(3) << __func__;
3369
3370 result = Parse_UINT32(buffer, &value->count, value_bytes);
3371 if (result) {
3372 return result;
3373 }
3374
3375 if (std::size(value->handle) < value->count) {
3376 return TPM_RC_INSUFFICIENT;
3377 }
3378 for (uint32_t i = 0; i < value->count; ++i) {
3379 result = Parse_TPM_HANDLE(buffer, &value->handle[i], value_bytes);
3380 if (result) {
3381 return result;
3382 }
3383 }
3384 return result;
3385 }
3386
Serialize_TPML_DIGEST(const TPML_DIGEST & value,std::string * buffer)3387 TPM_RC Serialize_TPML_DIGEST(const TPML_DIGEST& value, std::string* buffer) {
3388 TPM_RC result = TPM_RC_SUCCESS;
3389 VLOG(3) << __func__;
3390
3391 result = Serialize_UINT32(value.count, buffer);
3392 if (result) {
3393 return result;
3394 }
3395
3396 if (std::size(value.digests) < value.count) {
3397 return TPM_RC_INSUFFICIENT;
3398 }
3399 for (uint32_t i = 0; i < value.count; ++i) {
3400 result = Serialize_TPM2B_DIGEST(value.digests[i], buffer);
3401 if (result) {
3402 return result;
3403 }
3404 }
3405 return result;
3406 }
3407
Parse_TPML_DIGEST(std::string * buffer,TPML_DIGEST * value,std::string * value_bytes)3408 TPM_RC Parse_TPML_DIGEST(std::string* buffer,
3409 TPML_DIGEST* value,
3410 std::string* value_bytes) {
3411 TPM_RC result = TPM_RC_SUCCESS;
3412 VLOG(3) << __func__;
3413
3414 result = Parse_UINT32(buffer, &value->count, value_bytes);
3415 if (result) {
3416 return result;
3417 }
3418
3419 if (std::size(value->digests) < value->count) {
3420 return TPM_RC_INSUFFICIENT;
3421 }
3422 for (uint32_t i = 0; i < value->count; ++i) {
3423 result = Parse_TPM2B_DIGEST(buffer, &value->digests[i], value_bytes);
3424 if (result) {
3425 return result;
3426 }
3427 }
3428 return result;
3429 }
3430
Serialize_TPML_DIGEST_VALUES(const TPML_DIGEST_VALUES & value,std::string * buffer)3431 TPM_RC Serialize_TPML_DIGEST_VALUES(const TPML_DIGEST_VALUES& value,
3432 std::string* buffer) {
3433 TPM_RC result = TPM_RC_SUCCESS;
3434 VLOG(3) << __func__;
3435
3436 result = Serialize_UINT32(value.count, buffer);
3437 if (result) {
3438 return result;
3439 }
3440
3441 if (std::size(value.digests) < value.count) {
3442 return TPM_RC_INSUFFICIENT;
3443 }
3444 for (uint32_t i = 0; i < value.count; ++i) {
3445 result = Serialize_TPMT_HA(value.digests[i], buffer);
3446 if (result) {
3447 return result;
3448 }
3449 }
3450 return result;
3451 }
3452
Parse_TPML_DIGEST_VALUES(std::string * buffer,TPML_DIGEST_VALUES * value,std::string * value_bytes)3453 TPM_RC Parse_TPML_DIGEST_VALUES(std::string* buffer,
3454 TPML_DIGEST_VALUES* value,
3455 std::string* value_bytes) {
3456 TPM_RC result = TPM_RC_SUCCESS;
3457 VLOG(3) << __func__;
3458
3459 result = Parse_UINT32(buffer, &value->count, value_bytes);
3460 if (result) {
3461 return result;
3462 }
3463
3464 if (std::size(value->digests) < value->count) {
3465 return TPM_RC_INSUFFICIENT;
3466 }
3467 for (uint32_t i = 0; i < value->count; ++i) {
3468 result = Parse_TPMT_HA(buffer, &value->digests[i], value_bytes);
3469 if (result) {
3470 return result;
3471 }
3472 }
3473 return result;
3474 }
3475
Serialize_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES & value,std::string * buffer)3476 TPM_RC Serialize_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES& value,
3477 std::string* buffer) {
3478 TPM_RC result = TPM_RC_SUCCESS;
3479 VLOG(3) << __func__;
3480
3481 result = Serialize_UINT16(value.size, buffer);
3482 if (result) {
3483 return result;
3484 }
3485
3486 if (std::size(value.buffer) < value.size) {
3487 return TPM_RC_INSUFFICIENT;
3488 }
3489 for (uint32_t i = 0; i < value.size; ++i) {
3490 result = Serialize_BYTE(value.buffer[i], buffer);
3491 if (result) {
3492 return result;
3493 }
3494 }
3495 return result;
3496 }
3497
Parse_TPM2B_DIGEST_VALUES(std::string * buffer,TPM2B_DIGEST_VALUES * value,std::string * value_bytes)3498 TPM_RC Parse_TPM2B_DIGEST_VALUES(std::string* buffer,
3499 TPM2B_DIGEST_VALUES* value,
3500 std::string* value_bytes) {
3501 TPM_RC result = TPM_RC_SUCCESS;
3502 VLOG(3) << __func__;
3503
3504 result = Parse_UINT16(buffer, &value->size, value_bytes);
3505 if (result) {
3506 return result;
3507 }
3508
3509 if (std::size(value->buffer) < value->size) {
3510 return TPM_RC_INSUFFICIENT;
3511 }
3512 for (uint32_t i = 0; i < value->size; ++i) {
3513 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
3514 if (result) {
3515 return result;
3516 }
3517 }
3518 return result;
3519 }
3520
Make_TPM2B_DIGEST_VALUES(const std::string & bytes)3521 TPM2B_DIGEST_VALUES Make_TPM2B_DIGEST_VALUES(const std::string& bytes) {
3522 TPM2B_DIGEST_VALUES tpm2b;
3523 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
3524 memset(&tpm2b, 0, sizeof(TPM2B_DIGEST_VALUES));
3525 tpm2b.size = bytes.size();
3526 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
3527 return tpm2b;
3528 }
3529
StringFrom_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES & tpm2b)3530 std::string StringFrom_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES& tpm2b) {
3531 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
3532 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
3533 return std::string(char_buffer, tpm2b.size);
3534 }
3535
Serialize_TPML_PCR_SELECTION(const TPML_PCR_SELECTION & value,std::string * buffer)3536 TPM_RC Serialize_TPML_PCR_SELECTION(const TPML_PCR_SELECTION& value,
3537 std::string* buffer) {
3538 TPM_RC result = TPM_RC_SUCCESS;
3539 VLOG(3) << __func__;
3540
3541 result = Serialize_UINT32(value.count, buffer);
3542 if (result) {
3543 return result;
3544 }
3545
3546 if (std::size(value.pcr_selections) < value.count) {
3547 return TPM_RC_INSUFFICIENT;
3548 }
3549 for (uint32_t i = 0; i < value.count; ++i) {
3550 result = Serialize_TPMS_PCR_SELECTION(value.pcr_selections[i], buffer);
3551 if (result) {
3552 return result;
3553 }
3554 }
3555 return result;
3556 }
3557
Parse_TPML_PCR_SELECTION(std::string * buffer,TPML_PCR_SELECTION * value,std::string * value_bytes)3558 TPM_RC Parse_TPML_PCR_SELECTION(std::string* buffer,
3559 TPML_PCR_SELECTION* value,
3560 std::string* value_bytes) {
3561 TPM_RC result = TPM_RC_SUCCESS;
3562 VLOG(3) << __func__;
3563
3564 result = Parse_UINT32(buffer, &value->count, value_bytes);
3565 if (result) {
3566 return result;
3567 }
3568
3569 if (std::size(value->pcr_selections) < value->count) {
3570 return TPM_RC_INSUFFICIENT;
3571 }
3572 for (uint32_t i = 0; i < value->count; ++i) {
3573 result = Parse_TPMS_PCR_SELECTION(buffer, &value->pcr_selections[i],
3574 value_bytes);
3575 if (result) {
3576 return result;
3577 }
3578 }
3579 return result;
3580 }
3581
Serialize_TPML_ALG_PROPERTY(const TPML_ALG_PROPERTY & value,std::string * buffer)3582 TPM_RC Serialize_TPML_ALG_PROPERTY(const TPML_ALG_PROPERTY& value,
3583 std::string* buffer) {
3584 TPM_RC result = TPM_RC_SUCCESS;
3585 VLOG(3) << __func__;
3586
3587 result = Serialize_UINT32(value.count, buffer);
3588 if (result) {
3589 return result;
3590 }
3591
3592 if (std::size(value.alg_properties) < value.count) {
3593 return TPM_RC_INSUFFICIENT;
3594 }
3595 for (uint32_t i = 0; i < value.count; ++i) {
3596 result = Serialize_TPMS_ALG_PROPERTY(value.alg_properties[i], buffer);
3597 if (result) {
3598 return result;
3599 }
3600 }
3601 return result;
3602 }
3603
Parse_TPML_ALG_PROPERTY(std::string * buffer,TPML_ALG_PROPERTY * value,std::string * value_bytes)3604 TPM_RC Parse_TPML_ALG_PROPERTY(std::string* buffer,
3605 TPML_ALG_PROPERTY* value,
3606 std::string* value_bytes) {
3607 TPM_RC result = TPM_RC_SUCCESS;
3608 VLOG(3) << __func__;
3609
3610 result = Parse_UINT32(buffer, &value->count, value_bytes);
3611 if (result) {
3612 return result;
3613 }
3614
3615 if (std::size(value->alg_properties) < value->count) {
3616 return TPM_RC_INSUFFICIENT;
3617 }
3618 for (uint32_t i = 0; i < value->count; ++i) {
3619 result =
3620 Parse_TPMS_ALG_PROPERTY(buffer, &value->alg_properties[i], value_bytes);
3621 if (result) {
3622 return result;
3623 }
3624 }
3625 return result;
3626 }
3627
Serialize_TPML_TAGGED_TPM_PROPERTY(const TPML_TAGGED_TPM_PROPERTY & value,std::string * buffer)3628 TPM_RC Serialize_TPML_TAGGED_TPM_PROPERTY(const TPML_TAGGED_TPM_PROPERTY& value,
3629 std::string* buffer) {
3630 TPM_RC result = TPM_RC_SUCCESS;
3631 VLOG(3) << __func__;
3632
3633 result = Serialize_UINT32(value.count, buffer);
3634 if (result) {
3635 return result;
3636 }
3637
3638 if (std::size(value.tpm_property) < value.count) {
3639 return TPM_RC_INSUFFICIENT;
3640 }
3641 for (uint32_t i = 0; i < value.count; ++i) {
3642 result = Serialize_TPMS_TAGGED_PROPERTY(value.tpm_property[i], buffer);
3643 if (result) {
3644 return result;
3645 }
3646 }
3647 return result;
3648 }
3649
Parse_TPML_TAGGED_TPM_PROPERTY(std::string * buffer,TPML_TAGGED_TPM_PROPERTY * value,std::string * value_bytes)3650 TPM_RC Parse_TPML_TAGGED_TPM_PROPERTY(std::string* buffer,
3651 TPML_TAGGED_TPM_PROPERTY* value,
3652 std::string* value_bytes) {
3653 TPM_RC result = TPM_RC_SUCCESS;
3654 VLOG(3) << __func__;
3655
3656 result = Parse_UINT32(buffer, &value->count, value_bytes);
3657 if (result) {
3658 return result;
3659 }
3660
3661 if (std::size(value->tpm_property) < value->count) {
3662 return TPM_RC_INSUFFICIENT;
3663 }
3664 for (uint32_t i = 0; i < value->count; ++i) {
3665 result = Parse_TPMS_TAGGED_PROPERTY(buffer, &value->tpm_property[i],
3666 value_bytes);
3667 if (result) {
3668 return result;
3669 }
3670 }
3671 return result;
3672 }
3673
Serialize_TPML_TAGGED_PCR_PROPERTY(const TPML_TAGGED_PCR_PROPERTY & value,std::string * buffer)3674 TPM_RC Serialize_TPML_TAGGED_PCR_PROPERTY(const TPML_TAGGED_PCR_PROPERTY& value,
3675 std::string* buffer) {
3676 TPM_RC result = TPM_RC_SUCCESS;
3677 VLOG(3) << __func__;
3678
3679 result = Serialize_UINT32(value.count, buffer);
3680 if (result) {
3681 return result;
3682 }
3683
3684 if (std::size(value.pcr_property) < value.count) {
3685 return TPM_RC_INSUFFICIENT;
3686 }
3687 for (uint32_t i = 0; i < value.count; ++i) {
3688 result = Serialize_TPMS_TAGGED_PCR_SELECT(value.pcr_property[i], buffer);
3689 if (result) {
3690 return result;
3691 }
3692 }
3693 return result;
3694 }
3695
Parse_TPML_TAGGED_PCR_PROPERTY(std::string * buffer,TPML_TAGGED_PCR_PROPERTY * value,std::string * value_bytes)3696 TPM_RC Parse_TPML_TAGGED_PCR_PROPERTY(std::string* buffer,
3697 TPML_TAGGED_PCR_PROPERTY* value,
3698 std::string* value_bytes) {
3699 TPM_RC result = TPM_RC_SUCCESS;
3700 VLOG(3) << __func__;
3701
3702 result = Parse_UINT32(buffer, &value->count, value_bytes);
3703 if (result) {
3704 return result;
3705 }
3706
3707 if (std::size(value->pcr_property) < value->count) {
3708 return TPM_RC_INSUFFICIENT;
3709 }
3710 for (uint32_t i = 0; i < value->count; ++i) {
3711 result = Parse_TPMS_TAGGED_PCR_SELECT(buffer, &value->pcr_property[i],
3712 value_bytes);
3713 if (result) {
3714 return result;
3715 }
3716 }
3717 return result;
3718 }
3719
Serialize_TPML_ECC_CURVE(const TPML_ECC_CURVE & value,std::string * buffer)3720 TPM_RC Serialize_TPML_ECC_CURVE(const TPML_ECC_CURVE& value,
3721 std::string* buffer) {
3722 TPM_RC result = TPM_RC_SUCCESS;
3723 VLOG(3) << __func__;
3724
3725 result = Serialize_UINT32(value.count, buffer);
3726 if (result) {
3727 return result;
3728 }
3729
3730 if (std::size(value.ecc_curves) < value.count) {
3731 return TPM_RC_INSUFFICIENT;
3732 }
3733 for (uint32_t i = 0; i < value.count; ++i) {
3734 result = Serialize_TPM_ECC_CURVE(value.ecc_curves[i], buffer);
3735 if (result) {
3736 return result;
3737 }
3738 }
3739 return result;
3740 }
3741
Parse_TPML_ECC_CURVE(std::string * buffer,TPML_ECC_CURVE * value,std::string * value_bytes)3742 TPM_RC Parse_TPML_ECC_CURVE(std::string* buffer,
3743 TPML_ECC_CURVE* value,
3744 std::string* value_bytes) {
3745 TPM_RC result = TPM_RC_SUCCESS;
3746 VLOG(3) << __func__;
3747
3748 result = Parse_UINT32(buffer, &value->count, value_bytes);
3749 if (result) {
3750 return result;
3751 }
3752
3753 if (std::size(value->ecc_curves) < value->count) {
3754 return TPM_RC_INSUFFICIENT;
3755 }
3756 for (uint32_t i = 0; i < value->count; ++i) {
3757 result = Parse_TPM_ECC_CURVE(buffer, &value->ecc_curves[i], value_bytes);
3758 if (result) {
3759 return result;
3760 }
3761 }
3762 return result;
3763 }
3764
Serialize_TPMU_CAPABILITIES(const TPMU_CAPABILITIES & value,TPM_CAP selector,std::string * buffer)3765 TPM_RC Serialize_TPMU_CAPABILITIES(const TPMU_CAPABILITIES& value,
3766 TPM_CAP selector,
3767 std::string* buffer) {
3768 TPM_RC result = TPM_RC_SUCCESS;
3769 VLOG(3) << __func__;
3770
3771 if (selector == TPM_CAP_PCRS) {
3772 result = Serialize_TPML_PCR_SELECTION(value.assigned_pcr, buffer);
3773 if (result) {
3774 return result;
3775 }
3776 }
3777
3778 if (selector == TPM_CAP_TPM_PROPERTIES) {
3779 result = Serialize_TPML_TAGGED_TPM_PROPERTY(value.tpm_properties, buffer);
3780 if (result) {
3781 return result;
3782 }
3783 }
3784
3785 if (selector == TPM_CAP_PP_COMMANDS) {
3786 result = Serialize_TPML_CC(value.pp_commands, buffer);
3787 if (result) {
3788 return result;
3789 }
3790 }
3791
3792 if (selector == TPM_CAP_AUDIT_COMMANDS) {
3793 result = Serialize_TPML_CC(value.audit_commands, buffer);
3794 if (result) {
3795 return result;
3796 }
3797 }
3798
3799 if (selector == TPM_CAP_COMMANDS) {
3800 result = Serialize_TPML_CCA(value.command, buffer);
3801 if (result) {
3802 return result;
3803 }
3804 }
3805
3806 if (selector == TPM_CAP_ECC_CURVES) {
3807 result = Serialize_TPML_ECC_CURVE(value.ecc_curves, buffer);
3808 if (result) {
3809 return result;
3810 }
3811 }
3812
3813 if (selector == TPM_CAP_PCR_PROPERTIES) {
3814 result = Serialize_TPML_TAGGED_PCR_PROPERTY(value.pcr_properties, buffer);
3815 if (result) {
3816 return result;
3817 }
3818 }
3819
3820 if (selector == TPM_CAP_HANDLES) {
3821 result = Serialize_TPML_HANDLE(value.handles, buffer);
3822 if (result) {
3823 return result;
3824 }
3825 }
3826
3827 if (selector == TPM_CAP_ALGS) {
3828 result = Serialize_TPML_ALG_PROPERTY(value.algorithms, buffer);
3829 if (result) {
3830 return result;
3831 }
3832 }
3833 return result;
3834 }
3835
Parse_TPMU_CAPABILITIES(std::string * buffer,TPM_CAP selector,TPMU_CAPABILITIES * value,std::string * value_bytes)3836 TPM_RC Parse_TPMU_CAPABILITIES(std::string* buffer,
3837 TPM_CAP selector,
3838 TPMU_CAPABILITIES* value,
3839 std::string* value_bytes) {
3840 TPM_RC result = TPM_RC_SUCCESS;
3841 VLOG(3) << __func__;
3842
3843 if (selector == TPM_CAP_PCRS) {
3844 result =
3845 Parse_TPML_PCR_SELECTION(buffer, &value->assigned_pcr, value_bytes);
3846 if (result) {
3847 return result;
3848 }
3849 }
3850
3851 if (selector == TPM_CAP_TPM_PROPERTIES) {
3852 result = Parse_TPML_TAGGED_TPM_PROPERTY(buffer, &value->tpm_properties,
3853 value_bytes);
3854 if (result) {
3855 return result;
3856 }
3857 }
3858
3859 if (selector == TPM_CAP_PP_COMMANDS) {
3860 result = Parse_TPML_CC(buffer, &value->pp_commands, value_bytes);
3861 if (result) {
3862 return result;
3863 }
3864 }
3865
3866 if (selector == TPM_CAP_AUDIT_COMMANDS) {
3867 result = Parse_TPML_CC(buffer, &value->audit_commands, value_bytes);
3868 if (result) {
3869 return result;
3870 }
3871 }
3872
3873 if (selector == TPM_CAP_COMMANDS) {
3874 result = Parse_TPML_CCA(buffer, &value->command, value_bytes);
3875 if (result) {
3876 return result;
3877 }
3878 }
3879
3880 if (selector == TPM_CAP_ECC_CURVES) {
3881 result = Parse_TPML_ECC_CURVE(buffer, &value->ecc_curves, value_bytes);
3882 if (result) {
3883 return result;
3884 }
3885 }
3886
3887 if (selector == TPM_CAP_PCR_PROPERTIES) {
3888 result = Parse_TPML_TAGGED_PCR_PROPERTY(buffer, &value->pcr_properties,
3889 value_bytes);
3890 if (result) {
3891 return result;
3892 }
3893 }
3894
3895 if (selector == TPM_CAP_HANDLES) {
3896 result = Parse_TPML_HANDLE(buffer, &value->handles, value_bytes);
3897 if (result) {
3898 return result;
3899 }
3900 }
3901
3902 if (selector == TPM_CAP_ALGS) {
3903 result = Parse_TPML_ALG_PROPERTY(buffer, &value->algorithms, value_bytes);
3904 if (result) {
3905 return result;
3906 }
3907 }
3908 return result;
3909 }
3910
Serialize_TPMS_CAPABILITY_DATA(const TPMS_CAPABILITY_DATA & value,std::string * buffer)3911 TPM_RC Serialize_TPMS_CAPABILITY_DATA(const TPMS_CAPABILITY_DATA& value,
3912 std::string* buffer) {
3913 TPM_RC result = TPM_RC_SUCCESS;
3914 VLOG(3) << __func__;
3915
3916 result = Serialize_TPM_CAP(value.capability, buffer);
3917 if (result) {
3918 return result;
3919 }
3920
3921 result = Serialize_TPMU_CAPABILITIES(value.data, value.capability, buffer);
3922 if (result) {
3923 return result;
3924 }
3925 return result;
3926 }
3927
Parse_TPMS_CAPABILITY_DATA(std::string * buffer,TPMS_CAPABILITY_DATA * value,std::string * value_bytes)3928 TPM_RC Parse_TPMS_CAPABILITY_DATA(std::string* buffer,
3929 TPMS_CAPABILITY_DATA* value,
3930 std::string* value_bytes) {
3931 TPM_RC result = TPM_RC_SUCCESS;
3932 VLOG(3) << __func__;
3933
3934 result = Parse_TPM_CAP(buffer, &value->capability, value_bytes);
3935 if (result) {
3936 return result;
3937 }
3938
3939 result = Parse_TPMU_CAPABILITIES(buffer, value->capability, &value->data,
3940 value_bytes);
3941 if (result) {
3942 return result;
3943 }
3944 return result;
3945 }
3946
Serialize_TPMS_CLOCK_INFO(const TPMS_CLOCK_INFO & value,std::string * buffer)3947 TPM_RC Serialize_TPMS_CLOCK_INFO(const TPMS_CLOCK_INFO& value,
3948 std::string* buffer) {
3949 TPM_RC result = TPM_RC_SUCCESS;
3950 VLOG(3) << __func__;
3951
3952 result = Serialize_UINT64(value.clock, buffer);
3953 if (result) {
3954 return result;
3955 }
3956
3957 result = Serialize_UINT32(value.reset_count, buffer);
3958 if (result) {
3959 return result;
3960 }
3961
3962 result = Serialize_UINT32(value.restart_count, buffer);
3963 if (result) {
3964 return result;
3965 }
3966
3967 result = Serialize_TPMI_YES_NO(value.safe, buffer);
3968 if (result) {
3969 return result;
3970 }
3971 return result;
3972 }
3973
Parse_TPMS_CLOCK_INFO(std::string * buffer,TPMS_CLOCK_INFO * value,std::string * value_bytes)3974 TPM_RC Parse_TPMS_CLOCK_INFO(std::string* buffer,
3975 TPMS_CLOCK_INFO* value,
3976 std::string* value_bytes) {
3977 TPM_RC result = TPM_RC_SUCCESS;
3978 VLOG(3) << __func__;
3979
3980 result = Parse_UINT64(buffer, &value->clock, value_bytes);
3981 if (result) {
3982 return result;
3983 }
3984
3985 result = Parse_UINT32(buffer, &value->reset_count, value_bytes);
3986 if (result) {
3987 return result;
3988 }
3989
3990 result = Parse_UINT32(buffer, &value->restart_count, value_bytes);
3991 if (result) {
3992 return result;
3993 }
3994
3995 result = Parse_TPMI_YES_NO(buffer, &value->safe, value_bytes);
3996 if (result) {
3997 return result;
3998 }
3999 return result;
4000 }
4001
Serialize_TPMS_TIME_INFO(const TPMS_TIME_INFO & value,std::string * buffer)4002 TPM_RC Serialize_TPMS_TIME_INFO(const TPMS_TIME_INFO& value,
4003 std::string* buffer) {
4004 TPM_RC result = TPM_RC_SUCCESS;
4005 VLOG(3) << __func__;
4006
4007 result = Serialize_UINT64(value.time, buffer);
4008 if (result) {
4009 return result;
4010 }
4011
4012 result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer);
4013 if (result) {
4014 return result;
4015 }
4016 return result;
4017 }
4018
Parse_TPMS_TIME_INFO(std::string * buffer,TPMS_TIME_INFO * value,std::string * value_bytes)4019 TPM_RC Parse_TPMS_TIME_INFO(std::string* buffer,
4020 TPMS_TIME_INFO* value,
4021 std::string* value_bytes) {
4022 TPM_RC result = TPM_RC_SUCCESS;
4023 VLOG(3) << __func__;
4024
4025 result = Parse_UINT64(buffer, &value->time, value_bytes);
4026 if (result) {
4027 return result;
4028 }
4029
4030 result = Parse_TPMS_CLOCK_INFO(buffer, &value->clock_info, value_bytes);
4031 if (result) {
4032 return result;
4033 }
4034 return result;
4035 }
4036
Serialize_TPMS_TIME_ATTEST_INFO(const TPMS_TIME_ATTEST_INFO & value,std::string * buffer)4037 TPM_RC Serialize_TPMS_TIME_ATTEST_INFO(const TPMS_TIME_ATTEST_INFO& value,
4038 std::string* buffer) {
4039 TPM_RC result = TPM_RC_SUCCESS;
4040 VLOG(3) << __func__;
4041
4042 result = Serialize_TPMS_TIME_INFO(value.time, buffer);
4043 if (result) {
4044 return result;
4045 }
4046
4047 result = Serialize_UINT64(value.firmware_version, buffer);
4048 if (result) {
4049 return result;
4050 }
4051 return result;
4052 }
4053
Parse_TPMS_TIME_ATTEST_INFO(std::string * buffer,TPMS_TIME_ATTEST_INFO * value,std::string * value_bytes)4054 TPM_RC Parse_TPMS_TIME_ATTEST_INFO(std::string* buffer,
4055 TPMS_TIME_ATTEST_INFO* value,
4056 std::string* value_bytes) {
4057 TPM_RC result = TPM_RC_SUCCESS;
4058 VLOG(3) << __func__;
4059
4060 result = Parse_TPMS_TIME_INFO(buffer, &value->time, value_bytes);
4061 if (result) {
4062 return result;
4063 }
4064
4065 result = Parse_UINT64(buffer, &value->firmware_version, value_bytes);
4066 if (result) {
4067 return result;
4068 }
4069 return result;
4070 }
4071
Serialize_TPMS_CERTIFY_INFO(const TPMS_CERTIFY_INFO & value,std::string * buffer)4072 TPM_RC Serialize_TPMS_CERTIFY_INFO(const TPMS_CERTIFY_INFO& value,
4073 std::string* buffer) {
4074 TPM_RC result = TPM_RC_SUCCESS;
4075 VLOG(3) << __func__;
4076
4077 result = Serialize_TPM2B_NAME(value.name, buffer);
4078 if (result) {
4079 return result;
4080 }
4081
4082 result = Serialize_TPM2B_NAME(value.qualified_name, buffer);
4083 if (result) {
4084 return result;
4085 }
4086 return result;
4087 }
4088
Parse_TPMS_CERTIFY_INFO(std::string * buffer,TPMS_CERTIFY_INFO * value,std::string * value_bytes)4089 TPM_RC Parse_TPMS_CERTIFY_INFO(std::string* buffer,
4090 TPMS_CERTIFY_INFO* value,
4091 std::string* value_bytes) {
4092 TPM_RC result = TPM_RC_SUCCESS;
4093 VLOG(3) << __func__;
4094
4095 result = Parse_TPM2B_NAME(buffer, &value->name, value_bytes);
4096 if (result) {
4097 return result;
4098 }
4099
4100 result = Parse_TPM2B_NAME(buffer, &value->qualified_name, value_bytes);
4101 if (result) {
4102 return result;
4103 }
4104 return result;
4105 }
4106
Serialize_TPMS_QUOTE_INFO(const TPMS_QUOTE_INFO & value,std::string * buffer)4107 TPM_RC Serialize_TPMS_QUOTE_INFO(const TPMS_QUOTE_INFO& value,
4108 std::string* buffer) {
4109 TPM_RC result = TPM_RC_SUCCESS;
4110 VLOG(3) << __func__;
4111
4112 result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer);
4113 if (result) {
4114 return result;
4115 }
4116
4117 result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer);
4118 if (result) {
4119 return result;
4120 }
4121 return result;
4122 }
4123
Parse_TPMS_QUOTE_INFO(std::string * buffer,TPMS_QUOTE_INFO * value,std::string * value_bytes)4124 TPM_RC Parse_TPMS_QUOTE_INFO(std::string* buffer,
4125 TPMS_QUOTE_INFO* value,
4126 std::string* value_bytes) {
4127 TPM_RC result = TPM_RC_SUCCESS;
4128 VLOG(3) << __func__;
4129
4130 result = Parse_TPML_PCR_SELECTION(buffer, &value->pcr_select, value_bytes);
4131 if (result) {
4132 return result;
4133 }
4134
4135 result = Parse_TPM2B_DIGEST(buffer, &value->pcr_digest, value_bytes);
4136 if (result) {
4137 return result;
4138 }
4139 return result;
4140 }
4141
Serialize_TPMS_COMMAND_AUDIT_INFO(const TPMS_COMMAND_AUDIT_INFO & value,std::string * buffer)4142 TPM_RC Serialize_TPMS_COMMAND_AUDIT_INFO(const TPMS_COMMAND_AUDIT_INFO& value,
4143 std::string* buffer) {
4144 TPM_RC result = TPM_RC_SUCCESS;
4145 VLOG(3) << __func__;
4146
4147 result = Serialize_UINT64(value.audit_counter, buffer);
4148 if (result) {
4149 return result;
4150 }
4151
4152 result = Serialize_TPM_ALG_ID(value.digest_alg, buffer);
4153 if (result) {
4154 return result;
4155 }
4156
4157 result = Serialize_TPM2B_DIGEST(value.audit_digest, buffer);
4158 if (result) {
4159 return result;
4160 }
4161
4162 result = Serialize_TPM2B_DIGEST(value.command_digest, buffer);
4163 if (result) {
4164 return result;
4165 }
4166 return result;
4167 }
4168
Parse_TPMS_COMMAND_AUDIT_INFO(std::string * buffer,TPMS_COMMAND_AUDIT_INFO * value,std::string * value_bytes)4169 TPM_RC Parse_TPMS_COMMAND_AUDIT_INFO(std::string* buffer,
4170 TPMS_COMMAND_AUDIT_INFO* value,
4171 std::string* value_bytes) {
4172 TPM_RC result = TPM_RC_SUCCESS;
4173 VLOG(3) << __func__;
4174
4175 result = Parse_UINT64(buffer, &value->audit_counter, value_bytes);
4176 if (result) {
4177 return result;
4178 }
4179
4180 result = Parse_TPM_ALG_ID(buffer, &value->digest_alg, value_bytes);
4181 if (result) {
4182 return result;
4183 }
4184
4185 result = Parse_TPM2B_DIGEST(buffer, &value->audit_digest, value_bytes);
4186 if (result) {
4187 return result;
4188 }
4189
4190 result = Parse_TPM2B_DIGEST(buffer, &value->command_digest, value_bytes);
4191 if (result) {
4192 return result;
4193 }
4194 return result;
4195 }
4196
Serialize_TPMS_SESSION_AUDIT_INFO(const TPMS_SESSION_AUDIT_INFO & value,std::string * buffer)4197 TPM_RC Serialize_TPMS_SESSION_AUDIT_INFO(const TPMS_SESSION_AUDIT_INFO& value,
4198 std::string* buffer) {
4199 TPM_RC result = TPM_RC_SUCCESS;
4200 VLOG(3) << __func__;
4201
4202 result = Serialize_TPMI_YES_NO(value.exclusive_session, buffer);
4203 if (result) {
4204 return result;
4205 }
4206
4207 result = Serialize_TPM2B_DIGEST(value.session_digest, buffer);
4208 if (result) {
4209 return result;
4210 }
4211 return result;
4212 }
4213
Parse_TPMS_SESSION_AUDIT_INFO(std::string * buffer,TPMS_SESSION_AUDIT_INFO * value,std::string * value_bytes)4214 TPM_RC Parse_TPMS_SESSION_AUDIT_INFO(std::string* buffer,
4215 TPMS_SESSION_AUDIT_INFO* value,
4216 std::string* value_bytes) {
4217 TPM_RC result = TPM_RC_SUCCESS;
4218 VLOG(3) << __func__;
4219
4220 result = Parse_TPMI_YES_NO(buffer, &value->exclusive_session, value_bytes);
4221 if (result) {
4222 return result;
4223 }
4224
4225 result = Parse_TPM2B_DIGEST(buffer, &value->session_digest, value_bytes);
4226 if (result) {
4227 return result;
4228 }
4229 return result;
4230 }
4231
Serialize_TPMS_CREATION_INFO(const TPMS_CREATION_INFO & value,std::string * buffer)4232 TPM_RC Serialize_TPMS_CREATION_INFO(const TPMS_CREATION_INFO& value,
4233 std::string* buffer) {
4234 TPM_RC result = TPM_RC_SUCCESS;
4235 VLOG(3) << __func__;
4236
4237 result = Serialize_TPM2B_NAME(value.object_name, buffer);
4238 if (result) {
4239 return result;
4240 }
4241
4242 result = Serialize_TPM2B_DIGEST(value.creation_hash, buffer);
4243 if (result) {
4244 return result;
4245 }
4246 return result;
4247 }
4248
Parse_TPMS_CREATION_INFO(std::string * buffer,TPMS_CREATION_INFO * value,std::string * value_bytes)4249 TPM_RC Parse_TPMS_CREATION_INFO(std::string* buffer,
4250 TPMS_CREATION_INFO* value,
4251 std::string* value_bytes) {
4252 TPM_RC result = TPM_RC_SUCCESS;
4253 VLOG(3) << __func__;
4254
4255 result = Parse_TPM2B_NAME(buffer, &value->object_name, value_bytes);
4256 if (result) {
4257 return result;
4258 }
4259
4260 result = Parse_TPM2B_DIGEST(buffer, &value->creation_hash, value_bytes);
4261 if (result) {
4262 return result;
4263 }
4264 return result;
4265 }
4266
Serialize_TPMS_NV_CERTIFY_INFO(const TPMS_NV_CERTIFY_INFO & value,std::string * buffer)4267 TPM_RC Serialize_TPMS_NV_CERTIFY_INFO(const TPMS_NV_CERTIFY_INFO& value,
4268 std::string* buffer) {
4269 TPM_RC result = TPM_RC_SUCCESS;
4270 VLOG(3) << __func__;
4271
4272 result = Serialize_TPM2B_NAME(value.index_name, buffer);
4273 if (result) {
4274 return result;
4275 }
4276
4277 result = Serialize_UINT16(value.offset, buffer);
4278 if (result) {
4279 return result;
4280 }
4281
4282 result = Serialize_TPM2B_MAX_NV_BUFFER(value.nv_contents, buffer);
4283 if (result) {
4284 return result;
4285 }
4286 return result;
4287 }
4288
Parse_TPMS_NV_CERTIFY_INFO(std::string * buffer,TPMS_NV_CERTIFY_INFO * value,std::string * value_bytes)4289 TPM_RC Parse_TPMS_NV_CERTIFY_INFO(std::string* buffer,
4290 TPMS_NV_CERTIFY_INFO* value,
4291 std::string* value_bytes) {
4292 TPM_RC result = TPM_RC_SUCCESS;
4293 VLOG(3) << __func__;
4294
4295 result = Parse_TPM2B_NAME(buffer, &value->index_name, value_bytes);
4296 if (result) {
4297 return result;
4298 }
4299
4300 result = Parse_UINT16(buffer, &value->offset, value_bytes);
4301 if (result) {
4302 return result;
4303 }
4304
4305 result = Parse_TPM2B_MAX_NV_BUFFER(buffer, &value->nv_contents, value_bytes);
4306 if (result) {
4307 return result;
4308 }
4309 return result;
4310 }
4311
Serialize_TPMU_ATTEST(const TPMU_ATTEST & value,TPMI_ST_ATTEST selector,std::string * buffer)4312 TPM_RC Serialize_TPMU_ATTEST(const TPMU_ATTEST& value,
4313 TPMI_ST_ATTEST selector,
4314 std::string* buffer) {
4315 TPM_RC result = TPM_RC_SUCCESS;
4316 VLOG(3) << __func__;
4317
4318 if (selector == TPM_ST_ATTEST_SESSION_AUDIT) {
4319 result = Serialize_TPMS_SESSION_AUDIT_INFO(value.session_audit, buffer);
4320 if (result) {
4321 return result;
4322 }
4323 }
4324
4325 if (selector == TPM_ST_ATTEST_QUOTE) {
4326 result = Serialize_TPMS_QUOTE_INFO(value.quote, buffer);
4327 if (result) {
4328 return result;
4329 }
4330 }
4331
4332 if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) {
4333 result = Serialize_TPMS_COMMAND_AUDIT_INFO(value.command_audit, buffer);
4334 if (result) {
4335 return result;
4336 }
4337 }
4338
4339 if (selector == TPM_ST_ATTEST_CERTIFY) {
4340 result = Serialize_TPMS_CERTIFY_INFO(value.certify, buffer);
4341 if (result) {
4342 return result;
4343 }
4344 }
4345
4346 if (selector == TPM_ST_ATTEST_NV) {
4347 result = Serialize_TPMS_NV_CERTIFY_INFO(value.nv, buffer);
4348 if (result) {
4349 return result;
4350 }
4351 }
4352
4353 if (selector == TPM_ST_ATTEST_TIME) {
4354 result = Serialize_TPMS_TIME_ATTEST_INFO(value.time, buffer);
4355 if (result) {
4356 return result;
4357 }
4358 }
4359
4360 if (selector == TPM_ST_ATTEST_CREATION) {
4361 result = Serialize_TPMS_CREATION_INFO(value.creation, buffer);
4362 if (result) {
4363 return result;
4364 }
4365 }
4366 return result;
4367 }
4368
Parse_TPMU_ATTEST(std::string * buffer,TPMI_ST_ATTEST selector,TPMU_ATTEST * value,std::string * value_bytes)4369 TPM_RC Parse_TPMU_ATTEST(std::string* buffer,
4370 TPMI_ST_ATTEST selector,
4371 TPMU_ATTEST* value,
4372 std::string* value_bytes) {
4373 TPM_RC result = TPM_RC_SUCCESS;
4374 VLOG(3) << __func__;
4375
4376 if (selector == TPM_ST_ATTEST_SESSION_AUDIT) {
4377 result = Parse_TPMS_SESSION_AUDIT_INFO(buffer, &value->session_audit,
4378 value_bytes);
4379 if (result) {
4380 return result;
4381 }
4382 }
4383
4384 if (selector == TPM_ST_ATTEST_QUOTE) {
4385 result = Parse_TPMS_QUOTE_INFO(buffer, &value->quote, value_bytes);
4386 if (result) {
4387 return result;
4388 }
4389 }
4390
4391 if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) {
4392 result = Parse_TPMS_COMMAND_AUDIT_INFO(buffer, &value->command_audit,
4393 value_bytes);
4394 if (result) {
4395 return result;
4396 }
4397 }
4398
4399 if (selector == TPM_ST_ATTEST_CERTIFY) {
4400 result = Parse_TPMS_CERTIFY_INFO(buffer, &value->certify, value_bytes);
4401 if (result) {
4402 return result;
4403 }
4404 }
4405
4406 if (selector == TPM_ST_ATTEST_NV) {
4407 result = Parse_TPMS_NV_CERTIFY_INFO(buffer, &value->nv, value_bytes);
4408 if (result) {
4409 return result;
4410 }
4411 }
4412
4413 if (selector == TPM_ST_ATTEST_TIME) {
4414 result = Parse_TPMS_TIME_ATTEST_INFO(buffer, &value->time, value_bytes);
4415 if (result) {
4416 return result;
4417 }
4418 }
4419
4420 if (selector == TPM_ST_ATTEST_CREATION) {
4421 result = Parse_TPMS_CREATION_INFO(buffer, &value->creation, value_bytes);
4422 if (result) {
4423 return result;
4424 }
4425 }
4426 return result;
4427 }
4428
Serialize_TPMS_ATTEST(const TPMS_ATTEST & value,std::string * buffer)4429 TPM_RC Serialize_TPMS_ATTEST(const TPMS_ATTEST& value, std::string* buffer) {
4430 TPM_RC result = TPM_RC_SUCCESS;
4431 VLOG(3) << __func__;
4432
4433 result = Serialize_TPM_GENERATED(value.magic, buffer);
4434 if (result) {
4435 return result;
4436 }
4437
4438 result = Serialize_TPMI_ST_ATTEST(value.type, buffer);
4439 if (result) {
4440 return result;
4441 }
4442
4443 result = Serialize_TPM2B_NAME(value.qualified_signer, buffer);
4444 if (result) {
4445 return result;
4446 }
4447
4448 result = Serialize_TPM2B_DATA(value.extra_data, buffer);
4449 if (result) {
4450 return result;
4451 }
4452
4453 result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer);
4454 if (result) {
4455 return result;
4456 }
4457
4458 result = Serialize_UINT64(value.firmware_version, buffer);
4459 if (result) {
4460 return result;
4461 }
4462
4463 result = Serialize_TPMU_ATTEST(value.attested, value.type, buffer);
4464 if (result) {
4465 return result;
4466 }
4467 return result;
4468 }
4469
Parse_TPMS_ATTEST(std::string * buffer,TPMS_ATTEST * value,std::string * value_bytes)4470 TPM_RC Parse_TPMS_ATTEST(std::string* buffer,
4471 TPMS_ATTEST* value,
4472 std::string* value_bytes) {
4473 TPM_RC result = TPM_RC_SUCCESS;
4474 VLOG(3) << __func__;
4475
4476 result = Parse_TPM_GENERATED(buffer, &value->magic, value_bytes);
4477 if (result) {
4478 return result;
4479 }
4480
4481 result = Parse_TPMI_ST_ATTEST(buffer, &value->type, value_bytes);
4482 if (result) {
4483 return result;
4484 }
4485
4486 result = Parse_TPM2B_NAME(buffer, &value->qualified_signer, value_bytes);
4487 if (result) {
4488 return result;
4489 }
4490
4491 result = Parse_TPM2B_DATA(buffer, &value->extra_data, value_bytes);
4492 if (result) {
4493 return result;
4494 }
4495
4496 result = Parse_TPMS_CLOCK_INFO(buffer, &value->clock_info, value_bytes);
4497 if (result) {
4498 return result;
4499 }
4500
4501 result = Parse_UINT64(buffer, &value->firmware_version, value_bytes);
4502 if (result) {
4503 return result;
4504 }
4505
4506 result =
4507 Parse_TPMU_ATTEST(buffer, value->type, &value->attested, value_bytes);
4508 if (result) {
4509 return result;
4510 }
4511 return result;
4512 }
4513
Serialize_TPM2B_ATTEST(const TPM2B_ATTEST & value,std::string * buffer)4514 TPM_RC Serialize_TPM2B_ATTEST(const TPM2B_ATTEST& value, std::string* buffer) {
4515 TPM_RC result = TPM_RC_SUCCESS;
4516 VLOG(3) << __func__;
4517
4518 result = Serialize_UINT16(value.size, buffer);
4519 if (result) {
4520 return result;
4521 }
4522
4523 if (std::size(value.attestation_data) < value.size) {
4524 return TPM_RC_INSUFFICIENT;
4525 }
4526 for (uint32_t i = 0; i < value.size; ++i) {
4527 result = Serialize_BYTE(value.attestation_data[i], buffer);
4528 if (result) {
4529 return result;
4530 }
4531 }
4532 return result;
4533 }
4534
Parse_TPM2B_ATTEST(std::string * buffer,TPM2B_ATTEST * value,std::string * value_bytes)4535 TPM_RC Parse_TPM2B_ATTEST(std::string* buffer,
4536 TPM2B_ATTEST* value,
4537 std::string* value_bytes) {
4538 TPM_RC result = TPM_RC_SUCCESS;
4539 VLOG(3) << __func__;
4540
4541 result = Parse_UINT16(buffer, &value->size, value_bytes);
4542 if (result) {
4543 return result;
4544 }
4545
4546 if (std::size(value->attestation_data) < value->size) {
4547 return TPM_RC_INSUFFICIENT;
4548 }
4549 for (uint32_t i = 0; i < value->size; ++i) {
4550 result = Parse_BYTE(buffer, &value->attestation_data[i], value_bytes);
4551 if (result) {
4552 return result;
4553 }
4554 }
4555 return result;
4556 }
4557
Make_TPM2B_ATTEST(const std::string & bytes)4558 TPM2B_ATTEST Make_TPM2B_ATTEST(const std::string& bytes) {
4559 TPM2B_ATTEST tpm2b;
4560 CHECK(bytes.size() <= sizeof(tpm2b.attestation_data));
4561 memset(&tpm2b, 0, sizeof(TPM2B_ATTEST));
4562 tpm2b.size = bytes.size();
4563 memcpy(tpm2b.attestation_data, bytes.data(), bytes.size());
4564 return tpm2b;
4565 }
4566
StringFrom_TPM2B_ATTEST(const TPM2B_ATTEST & tpm2b)4567 std::string StringFrom_TPM2B_ATTEST(const TPM2B_ATTEST& tpm2b) {
4568 CHECK(tpm2b.size <= std::size(tpm2b.attestation_data));
4569 const char* char_buffer =
4570 reinterpret_cast<const char*>(tpm2b.attestation_data);
4571 return std::string(char_buffer, tpm2b.size);
4572 }
4573
Serialize_TPMS_AUTH_COMMAND(const TPMS_AUTH_COMMAND & value,std::string * buffer)4574 TPM_RC Serialize_TPMS_AUTH_COMMAND(const TPMS_AUTH_COMMAND& value,
4575 std::string* buffer) {
4576 TPM_RC result = TPM_RC_SUCCESS;
4577 VLOG(3) << __func__;
4578
4579 result = Serialize_TPMI_SH_AUTH_SESSION(value.session_handle, buffer);
4580 if (result) {
4581 return result;
4582 }
4583
4584 result = Serialize_TPM2B_NONCE(value.nonce, buffer);
4585 if (result) {
4586 return result;
4587 }
4588
4589 result = Serialize_TPMA_SESSION(value.session_attributes, buffer);
4590 if (result) {
4591 return result;
4592 }
4593
4594 result = Serialize_TPM2B_AUTH(value.hmac, buffer);
4595 if (result) {
4596 return result;
4597 }
4598 return result;
4599 }
4600
Parse_TPMS_AUTH_COMMAND(std::string * buffer,TPMS_AUTH_COMMAND * value,std::string * value_bytes)4601 TPM_RC Parse_TPMS_AUTH_COMMAND(std::string* buffer,
4602 TPMS_AUTH_COMMAND* value,
4603 std::string* value_bytes) {
4604 TPM_RC result = TPM_RC_SUCCESS;
4605 VLOG(3) << __func__;
4606
4607 result =
4608 Parse_TPMI_SH_AUTH_SESSION(buffer, &value->session_handle, value_bytes);
4609 if (result) {
4610 return result;
4611 }
4612
4613 result = Parse_TPM2B_NONCE(buffer, &value->nonce, value_bytes);
4614 if (result) {
4615 return result;
4616 }
4617
4618 result = Parse_TPMA_SESSION(buffer, &value->session_attributes, value_bytes);
4619 if (result) {
4620 return result;
4621 }
4622
4623 result = Parse_TPM2B_AUTH(buffer, &value->hmac, value_bytes);
4624 if (result) {
4625 return result;
4626 }
4627 return result;
4628 }
4629
Serialize_TPMS_AUTH_RESPONSE(const TPMS_AUTH_RESPONSE & value,std::string * buffer)4630 TPM_RC Serialize_TPMS_AUTH_RESPONSE(const TPMS_AUTH_RESPONSE& value,
4631 std::string* buffer) {
4632 TPM_RC result = TPM_RC_SUCCESS;
4633 VLOG(3) << __func__;
4634
4635 result = Serialize_TPM2B_NONCE(value.nonce, buffer);
4636 if (result) {
4637 return result;
4638 }
4639
4640 result = Serialize_TPMA_SESSION(value.session_attributes, buffer);
4641 if (result) {
4642 return result;
4643 }
4644
4645 result = Serialize_TPM2B_AUTH(value.hmac, buffer);
4646 if (result) {
4647 return result;
4648 }
4649 return result;
4650 }
4651
Parse_TPMS_AUTH_RESPONSE(std::string * buffer,TPMS_AUTH_RESPONSE * value,std::string * value_bytes)4652 TPM_RC Parse_TPMS_AUTH_RESPONSE(std::string* buffer,
4653 TPMS_AUTH_RESPONSE* value,
4654 std::string* value_bytes) {
4655 TPM_RC result = TPM_RC_SUCCESS;
4656 VLOG(3) << __func__;
4657
4658 result = Parse_TPM2B_NONCE(buffer, &value->nonce, value_bytes);
4659 if (result) {
4660 return result;
4661 }
4662
4663 result = Parse_TPMA_SESSION(buffer, &value->session_attributes, value_bytes);
4664 if (result) {
4665 return result;
4666 }
4667
4668 result = Parse_TPM2B_AUTH(buffer, &value->hmac, value_bytes);
4669 if (result) {
4670 return result;
4671 }
4672 return result;
4673 }
4674
Serialize_TPMU_SYM_KEY_BITS(const TPMU_SYM_KEY_BITS & value,TPMI_ALG_SYM selector,std::string * buffer)4675 TPM_RC Serialize_TPMU_SYM_KEY_BITS(const TPMU_SYM_KEY_BITS& value,
4676 TPMI_ALG_SYM selector,
4677 std::string* buffer) {
4678 TPM_RC result = TPM_RC_SUCCESS;
4679 VLOG(3) << __func__;
4680
4681 if (selector == TPM_ALG_NULL) {
4682 // Do nothing.
4683 }
4684
4685 if (selector == TPM_ALG_SM4) {
4686 result = Serialize_TPMI_SM4_KEY_BITS(value.sm4, buffer);
4687 if (result) {
4688 return result;
4689 }
4690 }
4691
4692 if (selector == TPM_ALG_AES) {
4693 result = Serialize_TPMI_AES_KEY_BITS(value.aes, buffer);
4694 if (result) {
4695 return result;
4696 }
4697 }
4698
4699 if (selector == TPM_ALG_XOR) {
4700 result = Serialize_TPMI_ALG_HASH(value.xor_, buffer);
4701 if (result) {
4702 return result;
4703 }
4704 }
4705 return result;
4706 }
4707
Parse_TPMU_SYM_KEY_BITS(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_KEY_BITS * value,std::string * value_bytes)4708 TPM_RC Parse_TPMU_SYM_KEY_BITS(std::string* buffer,
4709 TPMI_ALG_SYM selector,
4710 TPMU_SYM_KEY_BITS* value,
4711 std::string* value_bytes) {
4712 TPM_RC result = TPM_RC_SUCCESS;
4713 VLOG(3) << __func__;
4714
4715 if (selector == TPM_ALG_NULL) {
4716 // Do nothing.
4717 }
4718
4719 if (selector == TPM_ALG_SM4) {
4720 result = Parse_TPMI_SM4_KEY_BITS(buffer, &value->sm4, value_bytes);
4721 if (result) {
4722 return result;
4723 }
4724 }
4725
4726 if (selector == TPM_ALG_AES) {
4727 result = Parse_TPMI_AES_KEY_BITS(buffer, &value->aes, value_bytes);
4728 if (result) {
4729 return result;
4730 }
4731 }
4732
4733 if (selector == TPM_ALG_XOR) {
4734 result = Parse_TPMI_ALG_HASH(buffer, &value->xor_, value_bytes);
4735 if (result) {
4736 return result;
4737 }
4738 }
4739 return result;
4740 }
4741
Serialize_TPMU_SYM_MODE(const TPMU_SYM_MODE & value,TPMI_ALG_SYM selector,std::string * buffer)4742 TPM_RC Serialize_TPMU_SYM_MODE(const TPMU_SYM_MODE& value,
4743 TPMI_ALG_SYM selector,
4744 std::string* buffer) {
4745 TPM_RC result = TPM_RC_SUCCESS;
4746 VLOG(3) << __func__;
4747
4748 if (selector == TPM_ALG_NULL) {
4749 // Do nothing.
4750 }
4751
4752 if (selector == TPM_ALG_SM4) {
4753 result = Serialize_TPMI_ALG_SYM_MODE(value.sm4, buffer);
4754 if (result) {
4755 return result;
4756 }
4757 }
4758
4759 if (selector == TPM_ALG_AES) {
4760 result = Serialize_TPMI_ALG_SYM_MODE(value.aes, buffer);
4761 if (result) {
4762 return result;
4763 }
4764 }
4765
4766 if (selector == TPM_ALG_XOR) {
4767 // Do nothing.
4768 }
4769 return result;
4770 }
4771
Parse_TPMU_SYM_MODE(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_MODE * value,std::string * value_bytes)4772 TPM_RC Parse_TPMU_SYM_MODE(std::string* buffer,
4773 TPMI_ALG_SYM selector,
4774 TPMU_SYM_MODE* value,
4775 std::string* value_bytes) {
4776 TPM_RC result = TPM_RC_SUCCESS;
4777 VLOG(3) << __func__;
4778
4779 if (selector == TPM_ALG_NULL) {
4780 // Do nothing.
4781 }
4782
4783 if (selector == TPM_ALG_SM4) {
4784 result = Parse_TPMI_ALG_SYM_MODE(buffer, &value->sm4, value_bytes);
4785 if (result) {
4786 return result;
4787 }
4788 }
4789
4790 if (selector == TPM_ALG_AES) {
4791 result = Parse_TPMI_ALG_SYM_MODE(buffer, &value->aes, value_bytes);
4792 if (result) {
4793 return result;
4794 }
4795 }
4796
4797 if (selector == TPM_ALG_XOR) {
4798 // Do nothing.
4799 }
4800 return result;
4801 }
4802
Serialize_TPMU_SYM_DETAILS(const TPMU_SYM_DETAILS & value,TPMI_ALG_SYM selector,std::string * buffer)4803 TPM_RC Serialize_TPMU_SYM_DETAILS(const TPMU_SYM_DETAILS& value,
4804 TPMI_ALG_SYM selector,
4805 std::string* buffer) {
4806 TPM_RC result = TPM_RC_SUCCESS;
4807 VLOG(3) << __func__;
4808 return result;
4809 }
4810
Parse_TPMU_SYM_DETAILS(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_DETAILS * value,std::string * value_bytes)4811 TPM_RC Parse_TPMU_SYM_DETAILS(std::string* buffer,
4812 TPMI_ALG_SYM selector,
4813 TPMU_SYM_DETAILS* value,
4814 std::string* value_bytes) {
4815 TPM_RC result = TPM_RC_SUCCESS;
4816 VLOG(3) << __func__;
4817 return result;
4818 }
4819
Serialize_TPMT_SYM_DEF(const TPMT_SYM_DEF & value,std::string * buffer)4820 TPM_RC Serialize_TPMT_SYM_DEF(const TPMT_SYM_DEF& value, std::string* buffer) {
4821 TPM_RC result = TPM_RC_SUCCESS;
4822 VLOG(3) << __func__;
4823
4824 result = Serialize_TPMI_ALG_SYM(value.algorithm, buffer);
4825 if (result) {
4826 return result;
4827 }
4828
4829 result = Serialize_TPMU_SYM_KEY_BITS(value.key_bits, value.algorithm, buffer);
4830 if (result) {
4831 return result;
4832 }
4833
4834 result = Serialize_TPMU_SYM_MODE(value.mode, value.algorithm, buffer);
4835 if (result) {
4836 return result;
4837 }
4838
4839 result = Serialize_TPMU_SYM_DETAILS(value.details, value.algorithm, buffer);
4840 if (result) {
4841 return result;
4842 }
4843 return result;
4844 }
4845
Parse_TPMT_SYM_DEF(std::string * buffer,TPMT_SYM_DEF * value,std::string * value_bytes)4846 TPM_RC Parse_TPMT_SYM_DEF(std::string* buffer,
4847 TPMT_SYM_DEF* value,
4848 std::string* value_bytes) {
4849 TPM_RC result = TPM_RC_SUCCESS;
4850 VLOG(3) << __func__;
4851
4852 result = Parse_TPMI_ALG_SYM(buffer, &value->algorithm, value_bytes);
4853 if (result) {
4854 return result;
4855 }
4856
4857 result = Parse_TPMU_SYM_KEY_BITS(buffer, value->algorithm, &value->key_bits,
4858 value_bytes);
4859 if (result) {
4860 return result;
4861 }
4862
4863 result =
4864 Parse_TPMU_SYM_MODE(buffer, value->algorithm, &value->mode, value_bytes);
4865 if (result) {
4866 return result;
4867 }
4868
4869 result = Parse_TPMU_SYM_DETAILS(buffer, value->algorithm, &value->details,
4870 value_bytes);
4871 if (result) {
4872 return result;
4873 }
4874 return result;
4875 }
4876
Serialize_TPMT_SYM_DEF_OBJECT(const TPMT_SYM_DEF_OBJECT & value,std::string * buffer)4877 TPM_RC Serialize_TPMT_SYM_DEF_OBJECT(const TPMT_SYM_DEF_OBJECT& value,
4878 std::string* buffer) {
4879 TPM_RC result = TPM_RC_SUCCESS;
4880 VLOG(3) << __func__;
4881
4882 result = Serialize_TPMI_ALG_SYM_OBJECT(value.algorithm, buffer);
4883 if (result) {
4884 return result;
4885 }
4886
4887 result = Serialize_TPMU_SYM_KEY_BITS(value.key_bits, value.algorithm, buffer);
4888 if (result) {
4889 return result;
4890 }
4891
4892 result = Serialize_TPMU_SYM_MODE(value.mode, value.algorithm, buffer);
4893 if (result) {
4894 return result;
4895 }
4896
4897 result = Serialize_TPMU_SYM_DETAILS(value.details, value.algorithm, buffer);
4898 if (result) {
4899 return result;
4900 }
4901 return result;
4902 }
4903
Parse_TPMT_SYM_DEF_OBJECT(std::string * buffer,TPMT_SYM_DEF_OBJECT * value,std::string * value_bytes)4904 TPM_RC Parse_TPMT_SYM_DEF_OBJECT(std::string* buffer,
4905 TPMT_SYM_DEF_OBJECT* value,
4906 std::string* value_bytes) {
4907 TPM_RC result = TPM_RC_SUCCESS;
4908 VLOG(3) << __func__;
4909
4910 result = Parse_TPMI_ALG_SYM_OBJECT(buffer, &value->algorithm, value_bytes);
4911 if (result) {
4912 return result;
4913 }
4914
4915 result = Parse_TPMU_SYM_KEY_BITS(buffer, value->algorithm, &value->key_bits,
4916 value_bytes);
4917 if (result) {
4918 return result;
4919 }
4920
4921 result =
4922 Parse_TPMU_SYM_MODE(buffer, value->algorithm, &value->mode, value_bytes);
4923 if (result) {
4924 return result;
4925 }
4926
4927 result = Parse_TPMU_SYM_DETAILS(buffer, value->algorithm, &value->details,
4928 value_bytes);
4929 if (result) {
4930 return result;
4931 }
4932 return result;
4933 }
4934
Serialize_TPM2B_SYM_KEY(const TPM2B_SYM_KEY & value,std::string * buffer)4935 TPM_RC Serialize_TPM2B_SYM_KEY(const TPM2B_SYM_KEY& value,
4936 std::string* buffer) {
4937 TPM_RC result = TPM_RC_SUCCESS;
4938 VLOG(3) << __func__;
4939
4940 result = Serialize_UINT16(value.size, buffer);
4941 if (result) {
4942 return result;
4943 }
4944
4945 if (std::size(value.buffer) < value.size) {
4946 return TPM_RC_INSUFFICIENT;
4947 }
4948 for (uint32_t i = 0; i < value.size; ++i) {
4949 result = Serialize_BYTE(value.buffer[i], buffer);
4950 if (result) {
4951 return result;
4952 }
4953 }
4954 return result;
4955 }
4956
Parse_TPM2B_SYM_KEY(std::string * buffer,TPM2B_SYM_KEY * value,std::string * value_bytes)4957 TPM_RC Parse_TPM2B_SYM_KEY(std::string* buffer,
4958 TPM2B_SYM_KEY* value,
4959 std::string* value_bytes) {
4960 TPM_RC result = TPM_RC_SUCCESS;
4961 VLOG(3) << __func__;
4962
4963 result = Parse_UINT16(buffer, &value->size, value_bytes);
4964 if (result) {
4965 return result;
4966 }
4967
4968 if (std::size(value->buffer) < value->size) {
4969 return TPM_RC_INSUFFICIENT;
4970 }
4971 for (uint32_t i = 0; i < value->size; ++i) {
4972 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
4973 if (result) {
4974 return result;
4975 }
4976 }
4977 return result;
4978 }
4979
Make_TPM2B_SYM_KEY(const std::string & bytes)4980 TPM2B_SYM_KEY Make_TPM2B_SYM_KEY(const std::string& bytes) {
4981 TPM2B_SYM_KEY tpm2b;
4982 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
4983 memset(&tpm2b, 0, sizeof(TPM2B_SYM_KEY));
4984 tpm2b.size = bytes.size();
4985 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
4986 return tpm2b;
4987 }
4988
StringFrom_TPM2B_SYM_KEY(const TPM2B_SYM_KEY & tpm2b)4989 std::string StringFrom_TPM2B_SYM_KEY(const TPM2B_SYM_KEY& tpm2b) {
4990 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
4991 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
4992 return std::string(char_buffer, tpm2b.size);
4993 }
4994
Serialize_TPMS_SYMCIPHER_PARMS(const TPMS_SYMCIPHER_PARMS & value,std::string * buffer)4995 TPM_RC Serialize_TPMS_SYMCIPHER_PARMS(const TPMS_SYMCIPHER_PARMS& value,
4996 std::string* buffer) {
4997 TPM_RC result = TPM_RC_SUCCESS;
4998 VLOG(3) << __func__;
4999
5000 result = Serialize_TPMT_SYM_DEF_OBJECT(value.sym, buffer);
5001 if (result) {
5002 return result;
5003 }
5004 return result;
5005 }
5006
Parse_TPMS_SYMCIPHER_PARMS(std::string * buffer,TPMS_SYMCIPHER_PARMS * value,std::string * value_bytes)5007 TPM_RC Parse_TPMS_SYMCIPHER_PARMS(std::string* buffer,
5008 TPMS_SYMCIPHER_PARMS* value,
5009 std::string* value_bytes) {
5010 TPM_RC result = TPM_RC_SUCCESS;
5011 VLOG(3) << __func__;
5012
5013 result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->sym, value_bytes);
5014 if (result) {
5015 return result;
5016 }
5017 return result;
5018 }
5019
Serialize_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA & value,std::string * buffer)5020 TPM_RC Serialize_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA& value,
5021 std::string* buffer) {
5022 TPM_RC result = TPM_RC_SUCCESS;
5023 VLOG(3) << __func__;
5024
5025 result = Serialize_UINT16(value.size, buffer);
5026 if (result) {
5027 return result;
5028 }
5029
5030 if (std::size(value.buffer) < value.size) {
5031 return TPM_RC_INSUFFICIENT;
5032 }
5033 for (uint32_t i = 0; i < value.size; ++i) {
5034 result = Serialize_BYTE(value.buffer[i], buffer);
5035 if (result) {
5036 return result;
5037 }
5038 }
5039 return result;
5040 }
5041
Parse_TPM2B_SENSITIVE_DATA(std::string * buffer,TPM2B_SENSITIVE_DATA * value,std::string * value_bytes)5042 TPM_RC Parse_TPM2B_SENSITIVE_DATA(std::string* buffer,
5043 TPM2B_SENSITIVE_DATA* value,
5044 std::string* value_bytes) {
5045 TPM_RC result = TPM_RC_SUCCESS;
5046 VLOG(3) << __func__;
5047
5048 result = Parse_UINT16(buffer, &value->size, value_bytes);
5049 if (result) {
5050 return result;
5051 }
5052
5053 if (std::size(value->buffer) < value->size) {
5054 return TPM_RC_INSUFFICIENT;
5055 }
5056 for (uint32_t i = 0; i < value->size; ++i) {
5057 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
5058 if (result) {
5059 return result;
5060 }
5061 }
5062 return result;
5063 }
5064
Make_TPM2B_SENSITIVE_DATA(const std::string & bytes)5065 TPM2B_SENSITIVE_DATA Make_TPM2B_SENSITIVE_DATA(const std::string& bytes) {
5066 TPM2B_SENSITIVE_DATA tpm2b;
5067 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
5068 memset(&tpm2b, 0, sizeof(TPM2B_SENSITIVE_DATA));
5069 tpm2b.size = bytes.size();
5070 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
5071 return tpm2b;
5072 }
5073
StringFrom_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA & tpm2b)5074 std::string StringFrom_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA& tpm2b) {
5075 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
5076 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
5077 return std::string(char_buffer, tpm2b.size);
5078 }
5079
Serialize_TPMS_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE & value,std::string * buffer)5080 TPM_RC Serialize_TPMS_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE& value,
5081 std::string* buffer) {
5082 TPM_RC result = TPM_RC_SUCCESS;
5083 VLOG(3) << __func__;
5084
5085 result = Serialize_TPM2B_AUTH(value.user_auth, buffer);
5086 if (result) {
5087 return result;
5088 }
5089
5090 result = Serialize_TPM2B_SENSITIVE_DATA(value.data, buffer);
5091 if (result) {
5092 return result;
5093 }
5094 return result;
5095 }
5096
Parse_TPMS_SENSITIVE_CREATE(std::string * buffer,TPMS_SENSITIVE_CREATE * value,std::string * value_bytes)5097 TPM_RC Parse_TPMS_SENSITIVE_CREATE(std::string* buffer,
5098 TPMS_SENSITIVE_CREATE* value,
5099 std::string* value_bytes) {
5100 TPM_RC result = TPM_RC_SUCCESS;
5101 VLOG(3) << __func__;
5102
5103 result = Parse_TPM2B_AUTH(buffer, &value->user_auth, value_bytes);
5104 if (result) {
5105 return result;
5106 }
5107
5108 result = Parse_TPM2B_SENSITIVE_DATA(buffer, &value->data, value_bytes);
5109 if (result) {
5110 return result;
5111 }
5112 return result;
5113 }
5114
Serialize_TPM2B_SENSITIVE_CREATE(const TPM2B_SENSITIVE_CREATE & value,std::string * buffer)5115 TPM_RC Serialize_TPM2B_SENSITIVE_CREATE(const TPM2B_SENSITIVE_CREATE& value,
5116 std::string* buffer) {
5117 TPM_RC result = TPM_RC_SUCCESS;
5118 VLOG(3) << __func__;
5119
5120 std::string field_bytes;
5121 if (value.size) {
5122 if (value.size != sizeof(TPMS_SENSITIVE_CREATE)) {
5123 return TPM_RC_SIZE;
5124 }
5125 result = Serialize_TPMS_SENSITIVE_CREATE(value.sensitive, &field_bytes);
5126 if (result) {
5127 return result;
5128 }
5129 }
5130 std::string size_bytes;
5131 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
5132 if (result) {
5133 return result;
5134 }
5135 buffer->append(size_bytes + field_bytes);
5136 return result;
5137 }
5138
Parse_TPM2B_SENSITIVE_CREATE(std::string * buffer,TPM2B_SENSITIVE_CREATE * value,std::string * value_bytes)5139 TPM_RC Parse_TPM2B_SENSITIVE_CREATE(std::string* buffer,
5140 TPM2B_SENSITIVE_CREATE* value,
5141 std::string* value_bytes) {
5142 TPM_RC result = TPM_RC_SUCCESS;
5143 VLOG(3) << __func__;
5144
5145 UINT16 parsed_size = 0;
5146 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
5147 if (result) {
5148 return result;
5149 }
5150 if (!parsed_size) {
5151 value->size = 0;
5152 } else {
5153 value->size = sizeof(TPMS_SENSITIVE_CREATE);
5154 result =
5155 Parse_TPMS_SENSITIVE_CREATE(buffer, &value->sensitive, value_bytes);
5156 if (result) {
5157 return result;
5158 }
5159 }
5160 return result;
5161 }
5162
Make_TPM2B_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE & inner)5163 TPM2B_SENSITIVE_CREATE Make_TPM2B_SENSITIVE_CREATE(
5164 const TPMS_SENSITIVE_CREATE& inner) {
5165 TPM2B_SENSITIVE_CREATE tpm2b;
5166 tpm2b.size = sizeof(TPMS_SENSITIVE_CREATE);
5167 tpm2b.sensitive = inner;
5168 return tpm2b;
5169 }
5170
Serialize_TPMS_SCHEME_XOR(const TPMS_SCHEME_XOR & value,std::string * buffer)5171 TPM_RC Serialize_TPMS_SCHEME_XOR(const TPMS_SCHEME_XOR& value,
5172 std::string* buffer) {
5173 TPM_RC result = TPM_RC_SUCCESS;
5174 VLOG(3) << __func__;
5175
5176 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5177 if (result) {
5178 return result;
5179 }
5180
5181 result = Serialize_TPMI_ALG_KDF(value.kdf, buffer);
5182 if (result) {
5183 return result;
5184 }
5185 return result;
5186 }
5187
Parse_TPMS_SCHEME_XOR(std::string * buffer,TPMS_SCHEME_XOR * value,std::string * value_bytes)5188 TPM_RC Parse_TPMS_SCHEME_XOR(std::string* buffer,
5189 TPMS_SCHEME_XOR* value,
5190 std::string* value_bytes) {
5191 TPM_RC result = TPM_RC_SUCCESS;
5192 VLOG(3) << __func__;
5193
5194 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5195 if (result) {
5196 return result;
5197 }
5198
5199 result = Parse_TPMI_ALG_KDF(buffer, &value->kdf, value_bytes);
5200 if (result) {
5201 return result;
5202 }
5203 return result;
5204 }
5205
Serialize_TPMU_SCHEME_KEYEDHASH(const TPMU_SCHEME_KEYEDHASH & value,TPMI_ALG_KEYEDHASH_SCHEME selector,std::string * buffer)5206 TPM_RC Serialize_TPMU_SCHEME_KEYEDHASH(const TPMU_SCHEME_KEYEDHASH& value,
5207 TPMI_ALG_KEYEDHASH_SCHEME selector,
5208 std::string* buffer) {
5209 TPM_RC result = TPM_RC_SUCCESS;
5210 VLOG(3) << __func__;
5211
5212 if (selector == TPM_ALG_NULL) {
5213 // Do nothing.
5214 }
5215
5216 if (selector == TPM_ALG_HMAC) {
5217 result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer);
5218 if (result) {
5219 return result;
5220 }
5221 }
5222
5223 if (selector == TPM_ALG_XOR) {
5224 result = Serialize_TPMS_SCHEME_XOR(value.xor_, buffer);
5225 if (result) {
5226 return result;
5227 }
5228 }
5229 return result;
5230 }
5231
Parse_TPMU_SCHEME_KEYEDHASH(std::string * buffer,TPMI_ALG_KEYEDHASH_SCHEME selector,TPMU_SCHEME_KEYEDHASH * value,std::string * value_bytes)5232 TPM_RC Parse_TPMU_SCHEME_KEYEDHASH(std::string* buffer,
5233 TPMI_ALG_KEYEDHASH_SCHEME selector,
5234 TPMU_SCHEME_KEYEDHASH* value,
5235 std::string* value_bytes) {
5236 TPM_RC result = TPM_RC_SUCCESS;
5237 VLOG(3) << __func__;
5238
5239 if (selector == TPM_ALG_NULL) {
5240 // Do nothing.
5241 }
5242
5243 if (selector == TPM_ALG_HMAC) {
5244 result = Parse_TPMS_SCHEME_HMAC(buffer, &value->hmac, value_bytes);
5245 if (result) {
5246 return result;
5247 }
5248 }
5249
5250 if (selector == TPM_ALG_XOR) {
5251 result = Parse_TPMS_SCHEME_XOR(buffer, &value->xor_, value_bytes);
5252 if (result) {
5253 return result;
5254 }
5255 }
5256 return result;
5257 }
5258
Serialize_TPMT_KEYEDHASH_SCHEME(const TPMT_KEYEDHASH_SCHEME & value,std::string * buffer)5259 TPM_RC Serialize_TPMT_KEYEDHASH_SCHEME(const TPMT_KEYEDHASH_SCHEME& value,
5260 std::string* buffer) {
5261 TPM_RC result = TPM_RC_SUCCESS;
5262 VLOG(3) << __func__;
5263
5264 result = Serialize_TPMI_ALG_KEYEDHASH_SCHEME(value.scheme, buffer);
5265 if (result) {
5266 return result;
5267 }
5268
5269 result = Serialize_TPMU_SCHEME_KEYEDHASH(value.details, value.scheme, buffer);
5270 if (result) {
5271 return result;
5272 }
5273 return result;
5274 }
5275
Parse_TPMT_KEYEDHASH_SCHEME(std::string * buffer,TPMT_KEYEDHASH_SCHEME * value,std::string * value_bytes)5276 TPM_RC Parse_TPMT_KEYEDHASH_SCHEME(std::string* buffer,
5277 TPMT_KEYEDHASH_SCHEME* value,
5278 std::string* value_bytes) {
5279 TPM_RC result = TPM_RC_SUCCESS;
5280 VLOG(3) << __func__;
5281
5282 result = Parse_TPMI_ALG_KEYEDHASH_SCHEME(buffer, &value->scheme, value_bytes);
5283 if (result) {
5284 return result;
5285 }
5286
5287 result = Parse_TPMU_SCHEME_KEYEDHASH(buffer, value->scheme, &value->details,
5288 value_bytes);
5289 if (result) {
5290 return result;
5291 }
5292 return result;
5293 }
5294
Serialize_TPMS_SCHEME_ECDAA(const TPMS_SCHEME_ECDAA & value,std::string * buffer)5295 TPM_RC Serialize_TPMS_SCHEME_ECDAA(const TPMS_SCHEME_ECDAA& value,
5296 std::string* buffer) {
5297 TPM_RC result = TPM_RC_SUCCESS;
5298 VLOG(3) << __func__;
5299
5300 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5301 if (result) {
5302 return result;
5303 }
5304
5305 result = Serialize_UINT16(value.count, buffer);
5306 if (result) {
5307 return result;
5308 }
5309 return result;
5310 }
5311
Parse_TPMS_SCHEME_ECDAA(std::string * buffer,TPMS_SCHEME_ECDAA * value,std::string * value_bytes)5312 TPM_RC Parse_TPMS_SCHEME_ECDAA(std::string* buffer,
5313 TPMS_SCHEME_ECDAA* value,
5314 std::string* value_bytes) {
5315 TPM_RC result = TPM_RC_SUCCESS;
5316 VLOG(3) << __func__;
5317
5318 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5319 if (result) {
5320 return result;
5321 }
5322
5323 result = Parse_UINT16(buffer, &value->count, value_bytes);
5324 if (result) {
5325 return result;
5326 }
5327 return result;
5328 }
5329
Serialize_TPMU_SIG_SCHEME(const TPMU_SIG_SCHEME & value,TPMI_ALG_SIG_SCHEME selector,std::string * buffer)5330 TPM_RC Serialize_TPMU_SIG_SCHEME(const TPMU_SIG_SCHEME& value,
5331 TPMI_ALG_SIG_SCHEME selector,
5332 std::string* buffer) {
5333 TPM_RC result = TPM_RC_SUCCESS;
5334 VLOG(3) << __func__;
5335
5336 if (selector == TPM_ALG_HMAC) {
5337 result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer);
5338 if (result) {
5339 return result;
5340 }
5341 }
5342
5343 if (selector == TPM_ALG_ECSCHNORR) {
5344 result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer);
5345 if (result) {
5346 return result;
5347 }
5348 }
5349
5350 if (selector == TPM_ALG_RSAPSS) {
5351 result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer);
5352 if (result) {
5353 return result;
5354 }
5355 }
5356
5357 if (selector == TPM_ALG_ECDAA) {
5358 result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer);
5359 if (result) {
5360 return result;
5361 }
5362 }
5363
5364 if (selector == TPM_ALG_RSASSA) {
5365 result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer);
5366 if (result) {
5367 return result;
5368 }
5369 }
5370
5371 if (selector == TPM_ALG_SM2) {
5372 result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer);
5373 if (result) {
5374 return result;
5375 }
5376 }
5377
5378 if (selector == TPM_ALG_ECDSA) {
5379 result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer);
5380 if (result) {
5381 return result;
5382 }
5383 }
5384
5385 if (selector == TPM_ALG_NULL) {
5386 // Do nothing.
5387 }
5388 return result;
5389 }
5390
Parse_TPMU_SIG_SCHEME(std::string * buffer,TPMI_ALG_SIG_SCHEME selector,TPMU_SIG_SCHEME * value,std::string * value_bytes)5391 TPM_RC Parse_TPMU_SIG_SCHEME(std::string* buffer,
5392 TPMI_ALG_SIG_SCHEME selector,
5393 TPMU_SIG_SCHEME* value,
5394 std::string* value_bytes) {
5395 TPM_RC result = TPM_RC_SUCCESS;
5396 VLOG(3) << __func__;
5397
5398 if (selector == TPM_ALG_HMAC) {
5399 result = Parse_TPMS_SCHEME_HMAC(buffer, &value->hmac, value_bytes);
5400 if (result) {
5401 return result;
5402 }
5403 }
5404
5405 if (selector == TPM_ALG_ECSCHNORR) {
5406 result =
5407 Parse_TPMS_SCHEME_ECSCHNORR(buffer, &value->ec_schnorr, value_bytes);
5408 if (result) {
5409 return result;
5410 }
5411 }
5412
5413 if (selector == TPM_ALG_RSAPSS) {
5414 result = Parse_TPMS_SCHEME_RSAPSS(buffer, &value->rsapss, value_bytes);
5415 if (result) {
5416 return result;
5417 }
5418 }
5419
5420 if (selector == TPM_ALG_ECDAA) {
5421 result = Parse_TPMS_SCHEME_ECDAA(buffer, &value->ecdaa, value_bytes);
5422 if (result) {
5423 return result;
5424 }
5425 }
5426
5427 if (selector == TPM_ALG_RSASSA) {
5428 result = Parse_TPMS_SCHEME_RSASSA(buffer, &value->rsassa, value_bytes);
5429 if (result) {
5430 return result;
5431 }
5432 }
5433
5434 if (selector == TPM_ALG_SM2) {
5435 result = Parse_TPMS_SCHEME_SM2(buffer, &value->sm2, value_bytes);
5436 if (result) {
5437 return result;
5438 }
5439 }
5440
5441 if (selector == TPM_ALG_ECDSA) {
5442 result = Parse_TPMS_SCHEME_ECDSA(buffer, &value->ecdsa, value_bytes);
5443 if (result) {
5444 return result;
5445 }
5446 }
5447
5448 if (selector == TPM_ALG_NULL) {
5449 // Do nothing.
5450 }
5451 return result;
5452 }
5453
Serialize_TPMT_SIG_SCHEME(const TPMT_SIG_SCHEME & value,std::string * buffer)5454 TPM_RC Serialize_TPMT_SIG_SCHEME(const TPMT_SIG_SCHEME& value,
5455 std::string* buffer) {
5456 TPM_RC result = TPM_RC_SUCCESS;
5457 VLOG(3) << __func__;
5458
5459 result = Serialize_TPMI_ALG_SIG_SCHEME(value.scheme, buffer);
5460 if (result) {
5461 return result;
5462 }
5463
5464 result = Serialize_TPMU_SIG_SCHEME(value.details, value.scheme, buffer);
5465 if (result) {
5466 return result;
5467 }
5468 return result;
5469 }
5470
Parse_TPMT_SIG_SCHEME(std::string * buffer,TPMT_SIG_SCHEME * value,std::string * value_bytes)5471 TPM_RC Parse_TPMT_SIG_SCHEME(std::string* buffer,
5472 TPMT_SIG_SCHEME* value,
5473 std::string* value_bytes) {
5474 TPM_RC result = TPM_RC_SUCCESS;
5475 VLOG(3) << __func__;
5476
5477 result = Parse_TPMI_ALG_SIG_SCHEME(buffer, &value->scheme, value_bytes);
5478 if (result) {
5479 return result;
5480 }
5481
5482 result = Parse_TPMU_SIG_SCHEME(buffer, value->scheme, &value->details,
5483 value_bytes);
5484 if (result) {
5485 return result;
5486 }
5487 return result;
5488 }
5489
Serialize_TPMS_SCHEME_OAEP(const TPMS_SCHEME_OAEP & value,std::string * buffer)5490 TPM_RC Serialize_TPMS_SCHEME_OAEP(const TPMS_SCHEME_OAEP& value,
5491 std::string* buffer) {
5492 TPM_RC result = TPM_RC_SUCCESS;
5493 VLOG(3) << __func__;
5494
5495 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5496 if (result) {
5497 return result;
5498 }
5499 return result;
5500 }
5501
Parse_TPMS_SCHEME_OAEP(std::string * buffer,TPMS_SCHEME_OAEP * value,std::string * value_bytes)5502 TPM_RC Parse_TPMS_SCHEME_OAEP(std::string* buffer,
5503 TPMS_SCHEME_OAEP* value,
5504 std::string* value_bytes) {
5505 TPM_RC result = TPM_RC_SUCCESS;
5506 VLOG(3) << __func__;
5507
5508 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5509 if (result) {
5510 return result;
5511 }
5512 return result;
5513 }
5514
Serialize_TPMS_SCHEME_ECDH(const TPMS_SCHEME_ECDH & value,std::string * buffer)5515 TPM_RC Serialize_TPMS_SCHEME_ECDH(const TPMS_SCHEME_ECDH& value,
5516 std::string* buffer) {
5517 TPM_RC result = TPM_RC_SUCCESS;
5518 VLOG(3) << __func__;
5519
5520 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5521 if (result) {
5522 return result;
5523 }
5524 return result;
5525 }
5526
Parse_TPMS_SCHEME_ECDH(std::string * buffer,TPMS_SCHEME_ECDH * value,std::string * value_bytes)5527 TPM_RC Parse_TPMS_SCHEME_ECDH(std::string* buffer,
5528 TPMS_SCHEME_ECDH* value,
5529 std::string* value_bytes) {
5530 TPM_RC result = TPM_RC_SUCCESS;
5531 VLOG(3) << __func__;
5532
5533 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5534 if (result) {
5535 return result;
5536 }
5537 return result;
5538 }
5539
Serialize_TPMS_SCHEME_MGF1(const TPMS_SCHEME_MGF1 & value,std::string * buffer)5540 TPM_RC Serialize_TPMS_SCHEME_MGF1(const TPMS_SCHEME_MGF1& value,
5541 std::string* buffer) {
5542 TPM_RC result = TPM_RC_SUCCESS;
5543 VLOG(3) << __func__;
5544
5545 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5546 if (result) {
5547 return result;
5548 }
5549 return result;
5550 }
5551
Parse_TPMS_SCHEME_MGF1(std::string * buffer,TPMS_SCHEME_MGF1 * value,std::string * value_bytes)5552 TPM_RC Parse_TPMS_SCHEME_MGF1(std::string* buffer,
5553 TPMS_SCHEME_MGF1* value,
5554 std::string* value_bytes) {
5555 TPM_RC result = TPM_RC_SUCCESS;
5556 VLOG(3) << __func__;
5557
5558 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5559 if (result) {
5560 return result;
5561 }
5562 return result;
5563 }
5564
Serialize_TPMS_SCHEME_KDF1_SP800_56a(const TPMS_SCHEME_KDF1_SP800_56a & value,std::string * buffer)5565 TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_56a(
5566 const TPMS_SCHEME_KDF1_SP800_56a& value, std::string* buffer) {
5567 TPM_RC result = TPM_RC_SUCCESS;
5568 VLOG(3) << __func__;
5569
5570 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5571 if (result) {
5572 return result;
5573 }
5574 return result;
5575 }
5576
Parse_TPMS_SCHEME_KDF1_SP800_56a(std::string * buffer,TPMS_SCHEME_KDF1_SP800_56a * value,std::string * value_bytes)5577 TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_56a(std::string* buffer,
5578 TPMS_SCHEME_KDF1_SP800_56a* value,
5579 std::string* value_bytes) {
5580 TPM_RC result = TPM_RC_SUCCESS;
5581 VLOG(3) << __func__;
5582
5583 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5584 if (result) {
5585 return result;
5586 }
5587 return result;
5588 }
5589
Serialize_TPMS_SCHEME_KDF2(const TPMS_SCHEME_KDF2 & value,std::string * buffer)5590 TPM_RC Serialize_TPMS_SCHEME_KDF2(const TPMS_SCHEME_KDF2& value,
5591 std::string* buffer) {
5592 TPM_RC result = TPM_RC_SUCCESS;
5593 VLOG(3) << __func__;
5594
5595 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5596 if (result) {
5597 return result;
5598 }
5599 return result;
5600 }
5601
Parse_TPMS_SCHEME_KDF2(std::string * buffer,TPMS_SCHEME_KDF2 * value,std::string * value_bytes)5602 TPM_RC Parse_TPMS_SCHEME_KDF2(std::string* buffer,
5603 TPMS_SCHEME_KDF2* value,
5604 std::string* value_bytes) {
5605 TPM_RC result = TPM_RC_SUCCESS;
5606 VLOG(3) << __func__;
5607
5608 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5609 if (result) {
5610 return result;
5611 }
5612 return result;
5613 }
5614
Serialize_TPMS_SCHEME_KDF1_SP800_108(const TPMS_SCHEME_KDF1_SP800_108 & value,std::string * buffer)5615 TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_108(
5616 const TPMS_SCHEME_KDF1_SP800_108& value, std::string* buffer) {
5617 TPM_RC result = TPM_RC_SUCCESS;
5618 VLOG(3) << __func__;
5619
5620 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5621 if (result) {
5622 return result;
5623 }
5624 return result;
5625 }
5626
Parse_TPMS_SCHEME_KDF1_SP800_108(std::string * buffer,TPMS_SCHEME_KDF1_SP800_108 * value,std::string * value_bytes)5627 TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_108(std::string* buffer,
5628 TPMS_SCHEME_KDF1_SP800_108* value,
5629 std::string* value_bytes) {
5630 TPM_RC result = TPM_RC_SUCCESS;
5631 VLOG(3) << __func__;
5632
5633 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5634 if (result) {
5635 return result;
5636 }
5637 return result;
5638 }
5639
Serialize_TPMU_KDF_SCHEME(const TPMU_KDF_SCHEME & value,TPMI_ALG_KDF selector,std::string * buffer)5640 TPM_RC Serialize_TPMU_KDF_SCHEME(const TPMU_KDF_SCHEME& value,
5641 TPMI_ALG_KDF selector,
5642 std::string* buffer) {
5643 TPM_RC result = TPM_RC_SUCCESS;
5644 VLOG(3) << __func__;
5645
5646 if (selector == TPM_ALG_KDF1_SP800_56a) {
5647 result = Serialize_TPMS_SCHEME_KDF1_SP800_56a(value.kdf1_sp800_56a, buffer);
5648 if (result) {
5649 return result;
5650 }
5651 }
5652
5653 if (selector == TPM_ALG_MGF1) {
5654 result = Serialize_TPMS_SCHEME_MGF1(value.mgf1, buffer);
5655 if (result) {
5656 return result;
5657 }
5658 }
5659
5660 if (selector == TPM_ALG_KDF1_SP800_108) {
5661 result = Serialize_TPMS_SCHEME_KDF1_SP800_108(value.kdf1_sp800_108, buffer);
5662 if (result) {
5663 return result;
5664 }
5665 }
5666
5667 if (selector == TPM_ALG_KDF2) {
5668 result = Serialize_TPMS_SCHEME_KDF2(value.kdf2, buffer);
5669 if (result) {
5670 return result;
5671 }
5672 }
5673
5674 if (selector == TPM_ALG_NULL) {
5675 // Do nothing.
5676 }
5677 return result;
5678 }
5679
Parse_TPMU_KDF_SCHEME(std::string * buffer,TPMI_ALG_KDF selector,TPMU_KDF_SCHEME * value,std::string * value_bytes)5680 TPM_RC Parse_TPMU_KDF_SCHEME(std::string* buffer,
5681 TPMI_ALG_KDF selector,
5682 TPMU_KDF_SCHEME* value,
5683 std::string* value_bytes) {
5684 TPM_RC result = TPM_RC_SUCCESS;
5685 VLOG(3) << __func__;
5686
5687 if (selector == TPM_ALG_KDF1_SP800_56a) {
5688 result = Parse_TPMS_SCHEME_KDF1_SP800_56a(buffer, &value->kdf1_sp800_56a,
5689 value_bytes);
5690 if (result) {
5691 return result;
5692 }
5693 }
5694
5695 if (selector == TPM_ALG_MGF1) {
5696 result = Parse_TPMS_SCHEME_MGF1(buffer, &value->mgf1, value_bytes);
5697 if (result) {
5698 return result;
5699 }
5700 }
5701
5702 if (selector == TPM_ALG_KDF1_SP800_108) {
5703 result = Parse_TPMS_SCHEME_KDF1_SP800_108(buffer, &value->kdf1_sp800_108,
5704 value_bytes);
5705 if (result) {
5706 return result;
5707 }
5708 }
5709
5710 if (selector == TPM_ALG_KDF2) {
5711 result = Parse_TPMS_SCHEME_KDF2(buffer, &value->kdf2, value_bytes);
5712 if (result) {
5713 return result;
5714 }
5715 }
5716
5717 if (selector == TPM_ALG_NULL) {
5718 // Do nothing.
5719 }
5720 return result;
5721 }
5722
Serialize_TPMT_KDF_SCHEME(const TPMT_KDF_SCHEME & value,std::string * buffer)5723 TPM_RC Serialize_TPMT_KDF_SCHEME(const TPMT_KDF_SCHEME& value,
5724 std::string* buffer) {
5725 TPM_RC result = TPM_RC_SUCCESS;
5726 VLOG(3) << __func__;
5727
5728 result = Serialize_TPMI_ALG_KDF(value.scheme, buffer);
5729 if (result) {
5730 return result;
5731 }
5732
5733 result = Serialize_TPMU_KDF_SCHEME(value.details, value.scheme, buffer);
5734 if (result) {
5735 return result;
5736 }
5737 return result;
5738 }
5739
Parse_TPMT_KDF_SCHEME(std::string * buffer,TPMT_KDF_SCHEME * value,std::string * value_bytes)5740 TPM_RC Parse_TPMT_KDF_SCHEME(std::string* buffer,
5741 TPMT_KDF_SCHEME* value,
5742 std::string* value_bytes) {
5743 TPM_RC result = TPM_RC_SUCCESS;
5744 VLOG(3) << __func__;
5745
5746 result = Parse_TPMI_ALG_KDF(buffer, &value->scheme, value_bytes);
5747 if (result) {
5748 return result;
5749 }
5750
5751 result = Parse_TPMU_KDF_SCHEME(buffer, value->scheme, &value->details,
5752 value_bytes);
5753 if (result) {
5754 return result;
5755 }
5756 return result;
5757 }
5758
Serialize_TPMU_ASYM_SCHEME(const TPMU_ASYM_SCHEME & value,TPMI_ALG_ASYM_SCHEME selector,std::string * buffer)5759 TPM_RC Serialize_TPMU_ASYM_SCHEME(const TPMU_ASYM_SCHEME& value,
5760 TPMI_ALG_ASYM_SCHEME selector,
5761 std::string* buffer) {
5762 TPM_RC result = TPM_RC_SUCCESS;
5763 VLOG(3) << __func__;
5764
5765 if (selector == TPM_ALG_RSAES) {
5766 // Do nothing.
5767 }
5768
5769 if (selector == TPM_ALG_ECSCHNORR) {
5770 result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer);
5771 if (result) {
5772 return result;
5773 }
5774 }
5775
5776 if (selector == TPM_ALG_NULL) {
5777 // Do nothing.
5778 }
5779
5780 if (selector == TPM_ALG_ECDH) {
5781 result = Serialize_TPMS_SCHEME_ECDH(value.ecdh, buffer);
5782 if (result) {
5783 return result;
5784 }
5785 }
5786
5787 if (selector == TPM_ALG_OAEP) {
5788 result = Serialize_TPMS_SCHEME_OAEP(value.oaep, buffer);
5789 if (result) {
5790 return result;
5791 }
5792 }
5793
5794 if (selector == TPM_ALG_RSAPSS) {
5795 result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer);
5796 if (result) {
5797 return result;
5798 }
5799 }
5800
5801 if (selector == TPM_ALG_ECDAA) {
5802 result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer);
5803 if (result) {
5804 return result;
5805 }
5806 }
5807
5808 if (selector == TPM_ALG_RSASSA) {
5809 result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer);
5810 if (result) {
5811 return result;
5812 }
5813 }
5814
5815 if (selector == TPM_ALG_SM2) {
5816 result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer);
5817 if (result) {
5818 return result;
5819 }
5820 }
5821
5822 if (selector == TPM_ALG_ECDSA) {
5823 result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer);
5824 if (result) {
5825 return result;
5826 }
5827 }
5828 return result;
5829 }
5830
Parse_TPMU_ASYM_SCHEME(std::string * buffer,TPMI_ALG_ASYM_SCHEME selector,TPMU_ASYM_SCHEME * value,std::string * value_bytes)5831 TPM_RC Parse_TPMU_ASYM_SCHEME(std::string* buffer,
5832 TPMI_ALG_ASYM_SCHEME selector,
5833 TPMU_ASYM_SCHEME* value,
5834 std::string* value_bytes) {
5835 TPM_RC result = TPM_RC_SUCCESS;
5836 VLOG(3) << __func__;
5837
5838 if (selector == TPM_ALG_RSAES) {
5839 // Do nothing.
5840 }
5841
5842 if (selector == TPM_ALG_ECSCHNORR) {
5843 result =
5844 Parse_TPMS_SCHEME_ECSCHNORR(buffer, &value->ec_schnorr, value_bytes);
5845 if (result) {
5846 return result;
5847 }
5848 }
5849
5850 if (selector == TPM_ALG_NULL) {
5851 // Do nothing.
5852 }
5853
5854 if (selector == TPM_ALG_ECDH) {
5855 result = Parse_TPMS_SCHEME_ECDH(buffer, &value->ecdh, value_bytes);
5856 if (result) {
5857 return result;
5858 }
5859 }
5860
5861 if (selector == TPM_ALG_OAEP) {
5862 result = Parse_TPMS_SCHEME_OAEP(buffer, &value->oaep, value_bytes);
5863 if (result) {
5864 return result;
5865 }
5866 }
5867
5868 if (selector == TPM_ALG_RSAPSS) {
5869 result = Parse_TPMS_SCHEME_RSAPSS(buffer, &value->rsapss, value_bytes);
5870 if (result) {
5871 return result;
5872 }
5873 }
5874
5875 if (selector == TPM_ALG_ECDAA) {
5876 result = Parse_TPMS_SCHEME_ECDAA(buffer, &value->ecdaa, value_bytes);
5877 if (result) {
5878 return result;
5879 }
5880 }
5881
5882 if (selector == TPM_ALG_RSASSA) {
5883 result = Parse_TPMS_SCHEME_RSASSA(buffer, &value->rsassa, value_bytes);
5884 if (result) {
5885 return result;
5886 }
5887 }
5888
5889 if (selector == TPM_ALG_SM2) {
5890 result = Parse_TPMS_SCHEME_SM2(buffer, &value->sm2, value_bytes);
5891 if (result) {
5892 return result;
5893 }
5894 }
5895
5896 if (selector == TPM_ALG_ECDSA) {
5897 result = Parse_TPMS_SCHEME_ECDSA(buffer, &value->ecdsa, value_bytes);
5898 if (result) {
5899 return result;
5900 }
5901 }
5902 return result;
5903 }
5904
Serialize_TPMT_ASYM_SCHEME(const TPMT_ASYM_SCHEME & value,std::string * buffer)5905 TPM_RC Serialize_TPMT_ASYM_SCHEME(const TPMT_ASYM_SCHEME& value,
5906 std::string* buffer) {
5907 TPM_RC result = TPM_RC_SUCCESS;
5908 VLOG(3) << __func__;
5909
5910 result = Serialize_TPMI_ALG_ASYM_SCHEME(value.scheme, buffer);
5911 if (result) {
5912 return result;
5913 }
5914
5915 result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5916 if (result) {
5917 return result;
5918 }
5919 return result;
5920 }
5921
Parse_TPMT_ASYM_SCHEME(std::string * buffer,TPMT_ASYM_SCHEME * value,std::string * value_bytes)5922 TPM_RC Parse_TPMT_ASYM_SCHEME(std::string* buffer,
5923 TPMT_ASYM_SCHEME* value,
5924 std::string* value_bytes) {
5925 TPM_RC result = TPM_RC_SUCCESS;
5926 VLOG(3) << __func__;
5927
5928 result = Parse_TPMI_ALG_ASYM_SCHEME(buffer, &value->scheme, value_bytes);
5929 if (result) {
5930 return result;
5931 }
5932
5933 result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5934 value_bytes);
5935 if (result) {
5936 return result;
5937 }
5938 return result;
5939 }
5940
Serialize_TPMT_RSA_SCHEME(const TPMT_RSA_SCHEME & value,std::string * buffer)5941 TPM_RC Serialize_TPMT_RSA_SCHEME(const TPMT_RSA_SCHEME& value,
5942 std::string* buffer) {
5943 TPM_RC result = TPM_RC_SUCCESS;
5944 VLOG(3) << __func__;
5945
5946 result = Serialize_TPMI_ALG_RSA_SCHEME(value.scheme, buffer);
5947 if (result) {
5948 return result;
5949 }
5950
5951 result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5952 if (result) {
5953 return result;
5954 }
5955 return result;
5956 }
5957
Parse_TPMT_RSA_SCHEME(std::string * buffer,TPMT_RSA_SCHEME * value,std::string * value_bytes)5958 TPM_RC Parse_TPMT_RSA_SCHEME(std::string* buffer,
5959 TPMT_RSA_SCHEME* value,
5960 std::string* value_bytes) {
5961 TPM_RC result = TPM_RC_SUCCESS;
5962 VLOG(3) << __func__;
5963
5964 result = Parse_TPMI_ALG_RSA_SCHEME(buffer, &value->scheme, value_bytes);
5965 if (result) {
5966 return result;
5967 }
5968
5969 result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5970 value_bytes);
5971 if (result) {
5972 return result;
5973 }
5974 return result;
5975 }
5976
Serialize_TPMT_RSA_DECRYPT(const TPMT_RSA_DECRYPT & value,std::string * buffer)5977 TPM_RC Serialize_TPMT_RSA_DECRYPT(const TPMT_RSA_DECRYPT& value,
5978 std::string* buffer) {
5979 TPM_RC result = TPM_RC_SUCCESS;
5980 VLOG(3) << __func__;
5981
5982 result = Serialize_TPMI_ALG_RSA_DECRYPT(value.scheme, buffer);
5983 if (result) {
5984 return result;
5985 }
5986
5987 result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5988 if (result) {
5989 return result;
5990 }
5991 return result;
5992 }
5993
Parse_TPMT_RSA_DECRYPT(std::string * buffer,TPMT_RSA_DECRYPT * value,std::string * value_bytes)5994 TPM_RC Parse_TPMT_RSA_DECRYPT(std::string* buffer,
5995 TPMT_RSA_DECRYPT* value,
5996 std::string* value_bytes) {
5997 TPM_RC result = TPM_RC_SUCCESS;
5998 VLOG(3) << __func__;
5999
6000 result = Parse_TPMI_ALG_RSA_DECRYPT(buffer, &value->scheme, value_bytes);
6001 if (result) {
6002 return result;
6003 }
6004
6005 result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
6006 value_bytes);
6007 if (result) {
6008 return result;
6009 }
6010 return result;
6011 }
6012
Serialize_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA & value,std::string * buffer)6013 TPM_RC Serialize_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA& value,
6014 std::string* buffer) {
6015 TPM_RC result = TPM_RC_SUCCESS;
6016 VLOG(3) << __func__;
6017
6018 result = Serialize_UINT16(value.size, buffer);
6019 if (result) {
6020 return result;
6021 }
6022
6023 if (std::size(value.buffer) < value.size) {
6024 return TPM_RC_INSUFFICIENT;
6025 }
6026 for (uint32_t i = 0; i < value.size; ++i) {
6027 result = Serialize_BYTE(value.buffer[i], buffer);
6028 if (result) {
6029 return result;
6030 }
6031 }
6032 return result;
6033 }
6034
Parse_TPM2B_PUBLIC_KEY_RSA(std::string * buffer,TPM2B_PUBLIC_KEY_RSA * value,std::string * value_bytes)6035 TPM_RC Parse_TPM2B_PUBLIC_KEY_RSA(std::string* buffer,
6036 TPM2B_PUBLIC_KEY_RSA* value,
6037 std::string* value_bytes) {
6038 TPM_RC result = TPM_RC_SUCCESS;
6039 VLOG(3) << __func__;
6040
6041 result = Parse_UINT16(buffer, &value->size, value_bytes);
6042 if (result) {
6043 return result;
6044 }
6045
6046 if (std::size(value->buffer) < value->size) {
6047 return TPM_RC_INSUFFICIENT;
6048 }
6049 for (uint32_t i = 0; i < value->size; ++i) {
6050 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6051 if (result) {
6052 return result;
6053 }
6054 }
6055 return result;
6056 }
6057
Make_TPM2B_PUBLIC_KEY_RSA(const std::string & bytes)6058 TPM2B_PUBLIC_KEY_RSA Make_TPM2B_PUBLIC_KEY_RSA(const std::string& bytes) {
6059 TPM2B_PUBLIC_KEY_RSA tpm2b;
6060 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6061 memset(&tpm2b, 0, sizeof(TPM2B_PUBLIC_KEY_RSA));
6062 tpm2b.size = bytes.size();
6063 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6064 return tpm2b;
6065 }
6066
StringFrom_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA & tpm2b)6067 std::string StringFrom_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA& tpm2b) {
6068 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6069 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6070 return std::string(char_buffer, tpm2b.size);
6071 }
6072
Serialize_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA & value,std::string * buffer)6073 TPM_RC Serialize_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA& value,
6074 std::string* buffer) {
6075 TPM_RC result = TPM_RC_SUCCESS;
6076 VLOG(3) << __func__;
6077
6078 result = Serialize_UINT16(value.size, buffer);
6079 if (result) {
6080 return result;
6081 }
6082
6083 if (std::size(value.buffer) < value.size) {
6084 return TPM_RC_INSUFFICIENT;
6085 }
6086 for (uint32_t i = 0; i < value.size; ++i) {
6087 result = Serialize_BYTE(value.buffer[i], buffer);
6088 if (result) {
6089 return result;
6090 }
6091 }
6092 return result;
6093 }
6094
Parse_TPM2B_PRIVATE_KEY_RSA(std::string * buffer,TPM2B_PRIVATE_KEY_RSA * value,std::string * value_bytes)6095 TPM_RC Parse_TPM2B_PRIVATE_KEY_RSA(std::string* buffer,
6096 TPM2B_PRIVATE_KEY_RSA* value,
6097 std::string* value_bytes) {
6098 TPM_RC result = TPM_RC_SUCCESS;
6099 VLOG(3) << __func__;
6100
6101 result = Parse_UINT16(buffer, &value->size, value_bytes);
6102 if (result) {
6103 return result;
6104 }
6105
6106 if (std::size(value->buffer) < value->size) {
6107 return TPM_RC_INSUFFICIENT;
6108 }
6109 for (uint32_t i = 0; i < value->size; ++i) {
6110 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6111 if (result) {
6112 return result;
6113 }
6114 }
6115 return result;
6116 }
6117
Make_TPM2B_PRIVATE_KEY_RSA(const std::string & bytes)6118 TPM2B_PRIVATE_KEY_RSA Make_TPM2B_PRIVATE_KEY_RSA(const std::string& bytes) {
6119 TPM2B_PRIVATE_KEY_RSA tpm2b;
6120 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6121 memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_KEY_RSA));
6122 tpm2b.size = bytes.size();
6123 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6124 return tpm2b;
6125 }
6126
StringFrom_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA & tpm2b)6127 std::string StringFrom_TPM2B_PRIVATE_KEY_RSA(
6128 const TPM2B_PRIVATE_KEY_RSA& tpm2b) {
6129 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6130 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6131 return std::string(char_buffer, tpm2b.size);
6132 }
6133
Serialize_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER & value,std::string * buffer)6134 TPM_RC Serialize_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER& value,
6135 std::string* buffer) {
6136 TPM_RC result = TPM_RC_SUCCESS;
6137 VLOG(3) << __func__;
6138
6139 result = Serialize_UINT16(value.size, buffer);
6140 if (result) {
6141 return result;
6142 }
6143
6144 if (std::size(value.buffer) < value.size) {
6145 return TPM_RC_INSUFFICIENT;
6146 }
6147 for (uint32_t i = 0; i < value.size; ++i) {
6148 result = Serialize_BYTE(value.buffer[i], buffer);
6149 if (result) {
6150 return result;
6151 }
6152 }
6153 return result;
6154 }
6155
Parse_TPM2B_ECC_PARAMETER(std::string * buffer,TPM2B_ECC_PARAMETER * value,std::string * value_bytes)6156 TPM_RC Parse_TPM2B_ECC_PARAMETER(std::string* buffer,
6157 TPM2B_ECC_PARAMETER* value,
6158 std::string* value_bytes) {
6159 TPM_RC result = TPM_RC_SUCCESS;
6160 VLOG(3) << __func__;
6161
6162 result = Parse_UINT16(buffer, &value->size, value_bytes);
6163 if (result) {
6164 return result;
6165 }
6166
6167 if (std::size(value->buffer) < value->size) {
6168 return TPM_RC_INSUFFICIENT;
6169 }
6170 for (uint32_t i = 0; i < value->size; ++i) {
6171 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6172 if (result) {
6173 return result;
6174 }
6175 }
6176 return result;
6177 }
6178
Make_TPM2B_ECC_PARAMETER(const std::string & bytes)6179 TPM2B_ECC_PARAMETER Make_TPM2B_ECC_PARAMETER(const std::string& bytes) {
6180 TPM2B_ECC_PARAMETER tpm2b;
6181 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6182 memset(&tpm2b, 0, sizeof(TPM2B_ECC_PARAMETER));
6183 tpm2b.size = bytes.size();
6184 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6185 return tpm2b;
6186 }
6187
StringFrom_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER & tpm2b)6188 std::string StringFrom_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER& tpm2b) {
6189 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6190 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6191 return std::string(char_buffer, tpm2b.size);
6192 }
6193
Serialize_TPMS_ECC_POINT(const TPMS_ECC_POINT & value,std::string * buffer)6194 TPM_RC Serialize_TPMS_ECC_POINT(const TPMS_ECC_POINT& value,
6195 std::string* buffer) {
6196 TPM_RC result = TPM_RC_SUCCESS;
6197 VLOG(3) << __func__;
6198
6199 result = Serialize_TPM2B_ECC_PARAMETER(value.x, buffer);
6200 if (result) {
6201 return result;
6202 }
6203
6204 result = Serialize_TPM2B_ECC_PARAMETER(value.y, buffer);
6205 if (result) {
6206 return result;
6207 }
6208 return result;
6209 }
6210
Parse_TPMS_ECC_POINT(std::string * buffer,TPMS_ECC_POINT * value,std::string * value_bytes)6211 TPM_RC Parse_TPMS_ECC_POINT(std::string* buffer,
6212 TPMS_ECC_POINT* value,
6213 std::string* value_bytes) {
6214 TPM_RC result = TPM_RC_SUCCESS;
6215 VLOG(3) << __func__;
6216
6217 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->x, value_bytes);
6218 if (result) {
6219 return result;
6220 }
6221
6222 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->y, value_bytes);
6223 if (result) {
6224 return result;
6225 }
6226 return result;
6227 }
6228
Serialize_TPM2B_ECC_POINT(const TPM2B_ECC_POINT & value,std::string * buffer)6229 TPM_RC Serialize_TPM2B_ECC_POINT(const TPM2B_ECC_POINT& value,
6230 std::string* buffer) {
6231 TPM_RC result = TPM_RC_SUCCESS;
6232 VLOG(3) << __func__;
6233
6234 std::string field_bytes;
6235 if (value.size) {
6236 if (value.size != sizeof(TPMS_ECC_POINT)) {
6237 return TPM_RC_SIZE;
6238 }
6239 result = Serialize_TPMS_ECC_POINT(value.point, &field_bytes);
6240 if (result) {
6241 return result;
6242 }
6243 }
6244 std::string size_bytes;
6245 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
6246 if (result) {
6247 return result;
6248 }
6249 buffer->append(size_bytes + field_bytes);
6250 return result;
6251 }
6252
Parse_TPM2B_ECC_POINT(std::string * buffer,TPM2B_ECC_POINT * value,std::string * value_bytes)6253 TPM_RC Parse_TPM2B_ECC_POINT(std::string* buffer,
6254 TPM2B_ECC_POINT* value,
6255 std::string* value_bytes) {
6256 TPM_RC result = TPM_RC_SUCCESS;
6257 VLOG(3) << __func__;
6258
6259 UINT16 parsed_size = 0;
6260 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
6261 if (result) {
6262 return result;
6263 }
6264 if (!parsed_size) {
6265 value->size = 0;
6266 } else {
6267 value->size = sizeof(TPMS_ECC_POINT);
6268 result = Parse_TPMS_ECC_POINT(buffer, &value->point, value_bytes);
6269 if (result) {
6270 return result;
6271 }
6272 }
6273 return result;
6274 }
6275
Make_TPM2B_ECC_POINT(const TPMS_ECC_POINT & inner)6276 TPM2B_ECC_POINT Make_TPM2B_ECC_POINT(const TPMS_ECC_POINT& inner) {
6277 TPM2B_ECC_POINT tpm2b;
6278 tpm2b.size = sizeof(TPMS_ECC_POINT);
6279 tpm2b.point = inner;
6280 return tpm2b;
6281 }
6282
Serialize_TPMT_ECC_SCHEME(const TPMT_ECC_SCHEME & value,std::string * buffer)6283 TPM_RC Serialize_TPMT_ECC_SCHEME(const TPMT_ECC_SCHEME& value,
6284 std::string* buffer) {
6285 TPM_RC result = TPM_RC_SUCCESS;
6286 VLOG(3) << __func__;
6287
6288 result = Serialize_TPMI_ALG_ECC_SCHEME(value.scheme, buffer);
6289 if (result) {
6290 return result;
6291 }
6292
6293 result = Serialize_TPMU_SIG_SCHEME(value.details, value.scheme, buffer);
6294 if (result) {
6295 return result;
6296 }
6297 return result;
6298 }
6299
Parse_TPMT_ECC_SCHEME(std::string * buffer,TPMT_ECC_SCHEME * value,std::string * value_bytes)6300 TPM_RC Parse_TPMT_ECC_SCHEME(std::string* buffer,
6301 TPMT_ECC_SCHEME* value,
6302 std::string* value_bytes) {
6303 TPM_RC result = TPM_RC_SUCCESS;
6304 VLOG(3) << __func__;
6305
6306 result = Parse_TPMI_ALG_ECC_SCHEME(buffer, &value->scheme, value_bytes);
6307 if (result) {
6308 return result;
6309 }
6310
6311 result = Parse_TPMU_SIG_SCHEME(buffer, value->scheme, &value->details,
6312 value_bytes);
6313 if (result) {
6314 return result;
6315 }
6316 return result;
6317 }
6318
Serialize_TPMS_ALGORITHM_DETAIL_ECC(const TPMS_ALGORITHM_DETAIL_ECC & value,std::string * buffer)6319 TPM_RC Serialize_TPMS_ALGORITHM_DETAIL_ECC(
6320 const TPMS_ALGORITHM_DETAIL_ECC& value, std::string* buffer) {
6321 TPM_RC result = TPM_RC_SUCCESS;
6322 VLOG(3) << __func__;
6323
6324 result = Serialize_TPM_ECC_CURVE(value.curve_id, buffer);
6325 if (result) {
6326 return result;
6327 }
6328
6329 result = Serialize_UINT16(value.key_size, buffer);
6330 if (result) {
6331 return result;
6332 }
6333
6334 result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer);
6335 if (result) {
6336 return result;
6337 }
6338
6339 result = Serialize_TPMT_ECC_SCHEME(value.sign, buffer);
6340 if (result) {
6341 return result;
6342 }
6343
6344 result = Serialize_TPM2B_ECC_PARAMETER(value.p, buffer);
6345 if (result) {
6346 return result;
6347 }
6348
6349 result = Serialize_TPM2B_ECC_PARAMETER(value.a, buffer);
6350 if (result) {
6351 return result;
6352 }
6353
6354 result = Serialize_TPM2B_ECC_PARAMETER(value.b, buffer);
6355 if (result) {
6356 return result;
6357 }
6358
6359 result = Serialize_TPM2B_ECC_PARAMETER(value.g_x, buffer);
6360 if (result) {
6361 return result;
6362 }
6363
6364 result = Serialize_TPM2B_ECC_PARAMETER(value.g_y, buffer);
6365 if (result) {
6366 return result;
6367 }
6368
6369 result = Serialize_TPM2B_ECC_PARAMETER(value.n, buffer);
6370 if (result) {
6371 return result;
6372 }
6373
6374 result = Serialize_TPM2B_ECC_PARAMETER(value.h, buffer);
6375 if (result) {
6376 return result;
6377 }
6378 return result;
6379 }
6380
Parse_TPMS_ALGORITHM_DETAIL_ECC(std::string * buffer,TPMS_ALGORITHM_DETAIL_ECC * value,std::string * value_bytes)6381 TPM_RC Parse_TPMS_ALGORITHM_DETAIL_ECC(std::string* buffer,
6382 TPMS_ALGORITHM_DETAIL_ECC* value,
6383 std::string* value_bytes) {
6384 TPM_RC result = TPM_RC_SUCCESS;
6385 VLOG(3) << __func__;
6386
6387 result = Parse_TPM_ECC_CURVE(buffer, &value->curve_id, value_bytes);
6388 if (result) {
6389 return result;
6390 }
6391
6392 result = Parse_UINT16(buffer, &value->key_size, value_bytes);
6393 if (result) {
6394 return result;
6395 }
6396
6397 result = Parse_TPMT_KDF_SCHEME(buffer, &value->kdf, value_bytes);
6398 if (result) {
6399 return result;
6400 }
6401
6402 result = Parse_TPMT_ECC_SCHEME(buffer, &value->sign, value_bytes);
6403 if (result) {
6404 return result;
6405 }
6406
6407 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->p, value_bytes);
6408 if (result) {
6409 return result;
6410 }
6411
6412 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->a, value_bytes);
6413 if (result) {
6414 return result;
6415 }
6416
6417 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->b, value_bytes);
6418 if (result) {
6419 return result;
6420 }
6421
6422 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->g_x, value_bytes);
6423 if (result) {
6424 return result;
6425 }
6426
6427 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->g_y, value_bytes);
6428 if (result) {
6429 return result;
6430 }
6431
6432 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->n, value_bytes);
6433 if (result) {
6434 return result;
6435 }
6436
6437 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->h, value_bytes);
6438 if (result) {
6439 return result;
6440 }
6441 return result;
6442 }
6443
Serialize_TPMS_SIGNATURE_RSASSA(const TPMS_SIGNATURE_RSASSA & value,std::string * buffer)6444 TPM_RC Serialize_TPMS_SIGNATURE_RSASSA(const TPMS_SIGNATURE_RSASSA& value,
6445 std::string* buffer) {
6446 TPM_RC result = TPM_RC_SUCCESS;
6447 VLOG(3) << __func__;
6448
6449 result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6450 if (result) {
6451 return result;
6452 }
6453
6454 result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer);
6455 if (result) {
6456 return result;
6457 }
6458 return result;
6459 }
6460
Parse_TPMS_SIGNATURE_RSASSA(std::string * buffer,TPMS_SIGNATURE_RSASSA * value,std::string * value_bytes)6461 TPM_RC Parse_TPMS_SIGNATURE_RSASSA(std::string* buffer,
6462 TPMS_SIGNATURE_RSASSA* value,
6463 std::string* value_bytes) {
6464 TPM_RC result = TPM_RC_SUCCESS;
6465 VLOG(3) << __func__;
6466
6467 result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6468 if (result) {
6469 return result;
6470 }
6471
6472 result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->sig, value_bytes);
6473 if (result) {
6474 return result;
6475 }
6476 return result;
6477 }
6478
Serialize_TPMS_SIGNATURE_RSAPSS(const TPMS_SIGNATURE_RSAPSS & value,std::string * buffer)6479 TPM_RC Serialize_TPMS_SIGNATURE_RSAPSS(const TPMS_SIGNATURE_RSAPSS& value,
6480 std::string* buffer) {
6481 TPM_RC result = TPM_RC_SUCCESS;
6482 VLOG(3) << __func__;
6483
6484 result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6485 if (result) {
6486 return result;
6487 }
6488
6489 result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer);
6490 if (result) {
6491 return result;
6492 }
6493 return result;
6494 }
6495
Parse_TPMS_SIGNATURE_RSAPSS(std::string * buffer,TPMS_SIGNATURE_RSAPSS * value,std::string * value_bytes)6496 TPM_RC Parse_TPMS_SIGNATURE_RSAPSS(std::string* buffer,
6497 TPMS_SIGNATURE_RSAPSS* value,
6498 std::string* value_bytes) {
6499 TPM_RC result = TPM_RC_SUCCESS;
6500 VLOG(3) << __func__;
6501
6502 result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6503 if (result) {
6504 return result;
6505 }
6506
6507 result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->sig, value_bytes);
6508 if (result) {
6509 return result;
6510 }
6511 return result;
6512 }
6513
Serialize_TPMS_SIGNATURE_ECDSA(const TPMS_SIGNATURE_ECDSA & value,std::string * buffer)6514 TPM_RC Serialize_TPMS_SIGNATURE_ECDSA(const TPMS_SIGNATURE_ECDSA& value,
6515 std::string* buffer) {
6516 TPM_RC result = TPM_RC_SUCCESS;
6517 VLOG(3) << __func__;
6518
6519 result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6520 if (result) {
6521 return result;
6522 }
6523
6524 result = Serialize_TPM2B_ECC_PARAMETER(value.signature_r, buffer);
6525 if (result) {
6526 return result;
6527 }
6528
6529 result = Serialize_TPM2B_ECC_PARAMETER(value.signature_s, buffer);
6530 if (result) {
6531 return result;
6532 }
6533 return result;
6534 }
6535
Parse_TPMS_SIGNATURE_ECDSA(std::string * buffer,TPMS_SIGNATURE_ECDSA * value,std::string * value_bytes)6536 TPM_RC Parse_TPMS_SIGNATURE_ECDSA(std::string* buffer,
6537 TPMS_SIGNATURE_ECDSA* value,
6538 std::string* value_bytes) {
6539 TPM_RC result = TPM_RC_SUCCESS;
6540 VLOG(3) << __func__;
6541
6542 result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6543 if (result) {
6544 return result;
6545 }
6546
6547 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->signature_r, value_bytes);
6548 if (result) {
6549 return result;
6550 }
6551
6552 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->signature_s, value_bytes);
6553 if (result) {
6554 return result;
6555 }
6556 return result;
6557 }
6558
Serialize_TPMU_SIGNATURE(const TPMU_SIGNATURE & value,TPMI_ALG_SIG_SCHEME selector,std::string * buffer)6559 TPM_RC Serialize_TPMU_SIGNATURE(const TPMU_SIGNATURE& value,
6560 TPMI_ALG_SIG_SCHEME selector,
6561 std::string* buffer) {
6562 TPM_RC result = TPM_RC_SUCCESS;
6563 VLOG(3) << __func__;
6564
6565 if (selector == TPM_ALG_HMAC) {
6566 result = Serialize_TPMT_HA(value.hmac, buffer);
6567 if (result) {
6568 return result;
6569 }
6570 }
6571
6572 if (selector == TPM_ALG_ECSCHNORR) {
6573 result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecschnorr, buffer);
6574 if (result) {
6575 return result;
6576 }
6577 }
6578
6579 if (selector == TPM_ALG_RSAPSS) {
6580 result = Serialize_TPMS_SIGNATURE_RSAPSS(value.rsapss, buffer);
6581 if (result) {
6582 return result;
6583 }
6584 }
6585
6586 if (selector == TPM_ALG_ECDAA) {
6587 result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdaa, buffer);
6588 if (result) {
6589 return result;
6590 }
6591 }
6592
6593 if (selector == TPM_ALG_RSASSA) {
6594 result = Serialize_TPMS_SIGNATURE_RSASSA(value.rsassa, buffer);
6595 if (result) {
6596 return result;
6597 }
6598 }
6599
6600 if (selector == TPM_ALG_SM2) {
6601 result = Serialize_TPMS_SIGNATURE_ECDSA(value.sm2, buffer);
6602 if (result) {
6603 return result;
6604 }
6605 }
6606
6607 if (selector == TPM_ALG_ECDSA) {
6608 result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdsa, buffer);
6609 if (result) {
6610 return result;
6611 }
6612 }
6613
6614 if (selector == TPM_ALG_NULL) {
6615 // Do nothing.
6616 }
6617 return result;
6618 }
6619
Parse_TPMU_SIGNATURE(std::string * buffer,TPMI_ALG_SIG_SCHEME selector,TPMU_SIGNATURE * value,std::string * value_bytes)6620 TPM_RC Parse_TPMU_SIGNATURE(std::string* buffer,
6621 TPMI_ALG_SIG_SCHEME selector,
6622 TPMU_SIGNATURE* value,
6623 std::string* value_bytes) {
6624 TPM_RC result = TPM_RC_SUCCESS;
6625 VLOG(3) << __func__;
6626
6627 if (selector == TPM_ALG_HMAC) {
6628 result = Parse_TPMT_HA(buffer, &value->hmac, value_bytes);
6629 if (result) {
6630 return result;
6631 }
6632 }
6633
6634 if (selector == TPM_ALG_ECSCHNORR) {
6635 result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecschnorr, value_bytes);
6636 if (result) {
6637 return result;
6638 }
6639 }
6640
6641 if (selector == TPM_ALG_RSAPSS) {
6642 result = Parse_TPMS_SIGNATURE_RSAPSS(buffer, &value->rsapss, value_bytes);
6643 if (result) {
6644 return result;
6645 }
6646 }
6647
6648 if (selector == TPM_ALG_ECDAA) {
6649 result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecdaa, value_bytes);
6650 if (result) {
6651 return result;
6652 }
6653 }
6654
6655 if (selector == TPM_ALG_RSASSA) {
6656 result = Parse_TPMS_SIGNATURE_RSASSA(buffer, &value->rsassa, value_bytes);
6657 if (result) {
6658 return result;
6659 }
6660 }
6661
6662 if (selector == TPM_ALG_SM2) {
6663 result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->sm2, value_bytes);
6664 if (result) {
6665 return result;
6666 }
6667 }
6668
6669 if (selector == TPM_ALG_ECDSA) {
6670 result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecdsa, value_bytes);
6671 if (result) {
6672 return result;
6673 }
6674 }
6675
6676 if (selector == TPM_ALG_NULL) {
6677 // Do nothing.
6678 }
6679 return result;
6680 }
6681
Serialize_TPMT_SIGNATURE(const TPMT_SIGNATURE & value,std::string * buffer)6682 TPM_RC Serialize_TPMT_SIGNATURE(const TPMT_SIGNATURE& value,
6683 std::string* buffer) {
6684 TPM_RC result = TPM_RC_SUCCESS;
6685 VLOG(3) << __func__;
6686
6687 result = Serialize_TPMI_ALG_SIG_SCHEME(value.sig_alg, buffer);
6688 if (result) {
6689 return result;
6690 }
6691
6692 result = Serialize_TPMU_SIGNATURE(value.signature, value.sig_alg, buffer);
6693 if (result) {
6694 return result;
6695 }
6696 return result;
6697 }
6698
Parse_TPMT_SIGNATURE(std::string * buffer,TPMT_SIGNATURE * value,std::string * value_bytes)6699 TPM_RC Parse_TPMT_SIGNATURE(std::string* buffer,
6700 TPMT_SIGNATURE* value,
6701 std::string* value_bytes) {
6702 TPM_RC result = TPM_RC_SUCCESS;
6703 VLOG(3) << __func__;
6704
6705 result = Parse_TPMI_ALG_SIG_SCHEME(buffer, &value->sig_alg, value_bytes);
6706 if (result) {
6707 return result;
6708 }
6709
6710 result = Parse_TPMU_SIGNATURE(buffer, value->sig_alg, &value->signature,
6711 value_bytes);
6712 if (result) {
6713 return result;
6714 }
6715 return result;
6716 }
6717
Serialize_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET & value,std::string * buffer)6718 TPM_RC Serialize_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET& value,
6719 std::string* buffer) {
6720 TPM_RC result = TPM_RC_SUCCESS;
6721 VLOG(3) << __func__;
6722
6723 result = Serialize_UINT16(value.size, buffer);
6724 if (result) {
6725 return result;
6726 }
6727
6728 if (std::size(value.secret) < value.size) {
6729 return TPM_RC_INSUFFICIENT;
6730 }
6731 for (uint32_t i = 0; i < value.size; ++i) {
6732 result = Serialize_BYTE(value.secret[i], buffer);
6733 if (result) {
6734 return result;
6735 }
6736 }
6737 return result;
6738 }
6739
Parse_TPM2B_ENCRYPTED_SECRET(std::string * buffer,TPM2B_ENCRYPTED_SECRET * value,std::string * value_bytes)6740 TPM_RC Parse_TPM2B_ENCRYPTED_SECRET(std::string* buffer,
6741 TPM2B_ENCRYPTED_SECRET* value,
6742 std::string* value_bytes) {
6743 TPM_RC result = TPM_RC_SUCCESS;
6744 VLOG(3) << __func__;
6745
6746 result = Parse_UINT16(buffer, &value->size, value_bytes);
6747 if (result) {
6748 return result;
6749 }
6750
6751 if (std::size(value->secret) < value->size) {
6752 return TPM_RC_INSUFFICIENT;
6753 }
6754 for (uint32_t i = 0; i < value->size; ++i) {
6755 result = Parse_BYTE(buffer, &value->secret[i], value_bytes);
6756 if (result) {
6757 return result;
6758 }
6759 }
6760 return result;
6761 }
6762
Make_TPM2B_ENCRYPTED_SECRET(const std::string & bytes)6763 TPM2B_ENCRYPTED_SECRET Make_TPM2B_ENCRYPTED_SECRET(const std::string& bytes) {
6764 TPM2B_ENCRYPTED_SECRET tpm2b;
6765 CHECK(bytes.size() <= sizeof(tpm2b.secret));
6766 memset(&tpm2b, 0, sizeof(TPM2B_ENCRYPTED_SECRET));
6767 tpm2b.size = bytes.size();
6768 memcpy(tpm2b.secret, bytes.data(), bytes.size());
6769 return tpm2b;
6770 }
6771
StringFrom_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET & tpm2b)6772 std::string StringFrom_TPM2B_ENCRYPTED_SECRET(
6773 const TPM2B_ENCRYPTED_SECRET& tpm2b) {
6774 CHECK(tpm2b.size <= std::size(tpm2b.secret));
6775 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.secret);
6776 return std::string(char_buffer, tpm2b.size);
6777 }
6778
Serialize_TPMS_KEYEDHASH_PARMS(const TPMS_KEYEDHASH_PARMS & value,std::string * buffer)6779 TPM_RC Serialize_TPMS_KEYEDHASH_PARMS(const TPMS_KEYEDHASH_PARMS& value,
6780 std::string* buffer) {
6781 TPM_RC result = TPM_RC_SUCCESS;
6782 VLOG(3) << __func__;
6783
6784 result = Serialize_TPMT_KEYEDHASH_SCHEME(value.scheme, buffer);
6785 if (result) {
6786 return result;
6787 }
6788 return result;
6789 }
6790
Parse_TPMS_KEYEDHASH_PARMS(std::string * buffer,TPMS_KEYEDHASH_PARMS * value,std::string * value_bytes)6791 TPM_RC Parse_TPMS_KEYEDHASH_PARMS(std::string* buffer,
6792 TPMS_KEYEDHASH_PARMS* value,
6793 std::string* value_bytes) {
6794 TPM_RC result = TPM_RC_SUCCESS;
6795 VLOG(3) << __func__;
6796
6797 result = Parse_TPMT_KEYEDHASH_SCHEME(buffer, &value->scheme, value_bytes);
6798 if (result) {
6799 return result;
6800 }
6801 return result;
6802 }
6803
Serialize_TPMS_ASYM_PARMS(const TPMS_ASYM_PARMS & value,std::string * buffer)6804 TPM_RC Serialize_TPMS_ASYM_PARMS(const TPMS_ASYM_PARMS& value,
6805 std::string* buffer) {
6806 TPM_RC result = TPM_RC_SUCCESS;
6807 VLOG(3) << __func__;
6808
6809 result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6810 if (result) {
6811 return result;
6812 }
6813
6814 result = Serialize_TPMT_ASYM_SCHEME(value.scheme, buffer);
6815 if (result) {
6816 return result;
6817 }
6818 return result;
6819 }
6820
Parse_TPMS_ASYM_PARMS(std::string * buffer,TPMS_ASYM_PARMS * value,std::string * value_bytes)6821 TPM_RC Parse_TPMS_ASYM_PARMS(std::string* buffer,
6822 TPMS_ASYM_PARMS* value,
6823 std::string* value_bytes) {
6824 TPM_RC result = TPM_RC_SUCCESS;
6825 VLOG(3) << __func__;
6826
6827 result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6828 if (result) {
6829 return result;
6830 }
6831
6832 result = Parse_TPMT_ASYM_SCHEME(buffer, &value->scheme, value_bytes);
6833 if (result) {
6834 return result;
6835 }
6836 return result;
6837 }
6838
Serialize_TPMS_RSA_PARMS(const TPMS_RSA_PARMS & value,std::string * buffer)6839 TPM_RC Serialize_TPMS_RSA_PARMS(const TPMS_RSA_PARMS& value,
6840 std::string* buffer) {
6841 TPM_RC result = TPM_RC_SUCCESS;
6842 VLOG(3) << __func__;
6843
6844 result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6845 if (result) {
6846 return result;
6847 }
6848
6849 result = Serialize_TPMT_RSA_SCHEME(value.scheme, buffer);
6850 if (result) {
6851 return result;
6852 }
6853
6854 result = Serialize_TPMI_RSA_KEY_BITS(value.key_bits, buffer);
6855 if (result) {
6856 return result;
6857 }
6858
6859 result = Serialize_UINT32(value.exponent, buffer);
6860 if (result) {
6861 return result;
6862 }
6863 return result;
6864 }
6865
Parse_TPMS_RSA_PARMS(std::string * buffer,TPMS_RSA_PARMS * value,std::string * value_bytes)6866 TPM_RC Parse_TPMS_RSA_PARMS(std::string* buffer,
6867 TPMS_RSA_PARMS* value,
6868 std::string* value_bytes) {
6869 TPM_RC result = TPM_RC_SUCCESS;
6870 VLOG(3) << __func__;
6871
6872 result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6873 if (result) {
6874 return result;
6875 }
6876
6877 result = Parse_TPMT_RSA_SCHEME(buffer, &value->scheme, value_bytes);
6878 if (result) {
6879 return result;
6880 }
6881
6882 result = Parse_TPMI_RSA_KEY_BITS(buffer, &value->key_bits, value_bytes);
6883 if (result) {
6884 return result;
6885 }
6886
6887 result = Parse_UINT32(buffer, &value->exponent, value_bytes);
6888 if (result) {
6889 return result;
6890 }
6891 return result;
6892 }
6893
Serialize_TPMS_ECC_PARMS(const TPMS_ECC_PARMS & value,std::string * buffer)6894 TPM_RC Serialize_TPMS_ECC_PARMS(const TPMS_ECC_PARMS& value,
6895 std::string* buffer) {
6896 TPM_RC result = TPM_RC_SUCCESS;
6897 VLOG(3) << __func__;
6898
6899 result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6900 if (result) {
6901 return result;
6902 }
6903
6904 result = Serialize_TPMT_ECC_SCHEME(value.scheme, buffer);
6905 if (result) {
6906 return result;
6907 }
6908
6909 result = Serialize_TPMI_ECC_CURVE(value.curve_id, buffer);
6910 if (result) {
6911 return result;
6912 }
6913
6914 result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer);
6915 if (result) {
6916 return result;
6917 }
6918 return result;
6919 }
6920
Parse_TPMS_ECC_PARMS(std::string * buffer,TPMS_ECC_PARMS * value,std::string * value_bytes)6921 TPM_RC Parse_TPMS_ECC_PARMS(std::string* buffer,
6922 TPMS_ECC_PARMS* value,
6923 std::string* value_bytes) {
6924 TPM_RC result = TPM_RC_SUCCESS;
6925 VLOG(3) << __func__;
6926
6927 result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6928 if (result) {
6929 return result;
6930 }
6931
6932 result = Parse_TPMT_ECC_SCHEME(buffer, &value->scheme, value_bytes);
6933 if (result) {
6934 return result;
6935 }
6936
6937 result = Parse_TPMI_ECC_CURVE(buffer, &value->curve_id, value_bytes);
6938 if (result) {
6939 return result;
6940 }
6941
6942 result = Parse_TPMT_KDF_SCHEME(buffer, &value->kdf, value_bytes);
6943 if (result) {
6944 return result;
6945 }
6946 return result;
6947 }
6948
Serialize_TPMU_PUBLIC_PARMS(const TPMU_PUBLIC_PARMS & value,TPMI_ALG_PUBLIC selector,std::string * buffer)6949 TPM_RC Serialize_TPMU_PUBLIC_PARMS(const TPMU_PUBLIC_PARMS& value,
6950 TPMI_ALG_PUBLIC selector,
6951 std::string* buffer) {
6952 TPM_RC result = TPM_RC_SUCCESS;
6953 VLOG(3) << __func__;
6954
6955 if (selector == TPM_ALG_KEYEDHASH) {
6956 result = Serialize_TPMS_KEYEDHASH_PARMS(value.keyed_hash_detail, buffer);
6957 if (result) {
6958 return result;
6959 }
6960 }
6961
6962 if (selector == TPM_ALG_RSA) {
6963 result = Serialize_TPMS_RSA_PARMS(value.rsa_detail, buffer);
6964 if (result) {
6965 return result;
6966 }
6967 }
6968
6969 if (selector == TPM_ALG_SYMCIPHER) {
6970 result = Serialize_TPMS_SYMCIPHER_PARMS(value.sym_detail, buffer);
6971 if (result) {
6972 return result;
6973 }
6974 }
6975
6976 if (selector == TPM_ALG_ECC) {
6977 result = Serialize_TPMS_ECC_PARMS(value.ecc_detail, buffer);
6978 if (result) {
6979 return result;
6980 }
6981 }
6982 return result;
6983 }
6984
Parse_TPMU_PUBLIC_PARMS(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_PUBLIC_PARMS * value,std::string * value_bytes)6985 TPM_RC Parse_TPMU_PUBLIC_PARMS(std::string* buffer,
6986 TPMI_ALG_PUBLIC selector,
6987 TPMU_PUBLIC_PARMS* value,
6988 std::string* value_bytes) {
6989 TPM_RC result = TPM_RC_SUCCESS;
6990 VLOG(3) << __func__;
6991
6992 if (selector == TPM_ALG_KEYEDHASH) {
6993 result = Parse_TPMS_KEYEDHASH_PARMS(buffer, &value->keyed_hash_detail,
6994 value_bytes);
6995 if (result) {
6996 return result;
6997 }
6998 }
6999
7000 if (selector == TPM_ALG_RSA) {
7001 result = Parse_TPMS_RSA_PARMS(buffer, &value->rsa_detail, value_bytes);
7002 if (result) {
7003 return result;
7004 }
7005 }
7006
7007 if (selector == TPM_ALG_SYMCIPHER) {
7008 result =
7009 Parse_TPMS_SYMCIPHER_PARMS(buffer, &value->sym_detail, value_bytes);
7010 if (result) {
7011 return result;
7012 }
7013 }
7014
7015 if (selector == TPM_ALG_ECC) {
7016 result = Parse_TPMS_ECC_PARMS(buffer, &value->ecc_detail, value_bytes);
7017 if (result) {
7018 return result;
7019 }
7020 }
7021 return result;
7022 }
7023
Serialize_TPMT_PUBLIC_PARMS(const TPMT_PUBLIC_PARMS & value,std::string * buffer)7024 TPM_RC Serialize_TPMT_PUBLIC_PARMS(const TPMT_PUBLIC_PARMS& value,
7025 std::string* buffer) {
7026 TPM_RC result = TPM_RC_SUCCESS;
7027 VLOG(3) << __func__;
7028
7029 result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer);
7030 if (result) {
7031 return result;
7032 }
7033
7034 result = Serialize_TPMU_PUBLIC_PARMS(value.parameters, value.type, buffer);
7035 if (result) {
7036 return result;
7037 }
7038 return result;
7039 }
7040
Parse_TPMT_PUBLIC_PARMS(std::string * buffer,TPMT_PUBLIC_PARMS * value,std::string * value_bytes)7041 TPM_RC Parse_TPMT_PUBLIC_PARMS(std::string* buffer,
7042 TPMT_PUBLIC_PARMS* value,
7043 std::string* value_bytes) {
7044 TPM_RC result = TPM_RC_SUCCESS;
7045 VLOG(3) << __func__;
7046
7047 result = Parse_TPMI_ALG_PUBLIC(buffer, &value->type, value_bytes);
7048 if (result) {
7049 return result;
7050 }
7051
7052 result = Parse_TPMU_PUBLIC_PARMS(buffer, value->type, &value->parameters,
7053 value_bytes);
7054 if (result) {
7055 return result;
7056 }
7057 return result;
7058 }
7059
Serialize_TPMU_PUBLIC_ID(const TPMU_PUBLIC_ID & value,TPMI_ALG_PUBLIC selector,std::string * buffer)7060 TPM_RC Serialize_TPMU_PUBLIC_ID(const TPMU_PUBLIC_ID& value,
7061 TPMI_ALG_PUBLIC selector,
7062 std::string* buffer) {
7063 TPM_RC result = TPM_RC_SUCCESS;
7064 VLOG(3) << __func__;
7065
7066 if (selector == TPM_ALG_KEYEDHASH) {
7067 result = Serialize_TPM2B_DIGEST(value.keyed_hash, buffer);
7068 if (result) {
7069 return result;
7070 }
7071 }
7072
7073 if (selector == TPM_ALG_RSA) {
7074 result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.rsa, buffer);
7075 if (result) {
7076 return result;
7077 }
7078 }
7079
7080 if (selector == TPM_ALG_SYMCIPHER) {
7081 result = Serialize_TPM2B_DIGEST(value.sym, buffer);
7082 if (result) {
7083 return result;
7084 }
7085 }
7086
7087 if (selector == TPM_ALG_ECC) {
7088 result = Serialize_TPMS_ECC_POINT(value.ecc, buffer);
7089 if (result) {
7090 return result;
7091 }
7092 }
7093 return result;
7094 }
7095
Parse_TPMU_PUBLIC_ID(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_PUBLIC_ID * value,std::string * value_bytes)7096 TPM_RC Parse_TPMU_PUBLIC_ID(std::string* buffer,
7097 TPMI_ALG_PUBLIC selector,
7098 TPMU_PUBLIC_ID* value,
7099 std::string* value_bytes) {
7100 TPM_RC result = TPM_RC_SUCCESS;
7101 VLOG(3) << __func__;
7102
7103 if (selector == TPM_ALG_KEYEDHASH) {
7104 result = Parse_TPM2B_DIGEST(buffer, &value->keyed_hash, value_bytes);
7105 if (result) {
7106 return result;
7107 }
7108 }
7109
7110 if (selector == TPM_ALG_RSA) {
7111 result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->rsa, value_bytes);
7112 if (result) {
7113 return result;
7114 }
7115 }
7116
7117 if (selector == TPM_ALG_SYMCIPHER) {
7118 result = Parse_TPM2B_DIGEST(buffer, &value->sym, value_bytes);
7119 if (result) {
7120 return result;
7121 }
7122 }
7123
7124 if (selector == TPM_ALG_ECC) {
7125 result = Parse_TPMS_ECC_POINT(buffer, &value->ecc, value_bytes);
7126 if (result) {
7127 return result;
7128 }
7129 }
7130 return result;
7131 }
7132
Serialize_TPMT_PUBLIC(const TPMT_PUBLIC & value,std::string * buffer)7133 TPM_RC Serialize_TPMT_PUBLIC(const TPMT_PUBLIC& value, std::string* buffer) {
7134 TPM_RC result = TPM_RC_SUCCESS;
7135 VLOG(3) << __func__;
7136
7137 result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer);
7138 if (result) {
7139 return result;
7140 }
7141
7142 result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer);
7143 if (result) {
7144 return result;
7145 }
7146
7147 result = Serialize_TPMA_OBJECT(value.object_attributes, buffer);
7148 if (result) {
7149 return result;
7150 }
7151
7152 result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer);
7153 if (result) {
7154 return result;
7155 }
7156
7157 result = Serialize_TPMU_PUBLIC_PARMS(value.parameters, value.type, buffer);
7158 if (result) {
7159 return result;
7160 }
7161
7162 result = Serialize_TPMU_PUBLIC_ID(value.unique, value.type, buffer);
7163 if (result) {
7164 return result;
7165 }
7166 return result;
7167 }
7168
Parse_TPMT_PUBLIC(std::string * buffer,TPMT_PUBLIC * value,std::string * value_bytes)7169 TPM_RC Parse_TPMT_PUBLIC(std::string* buffer,
7170 TPMT_PUBLIC* value,
7171 std::string* value_bytes) {
7172 TPM_RC result = TPM_RC_SUCCESS;
7173 VLOG(3) << __func__;
7174
7175 result = Parse_TPMI_ALG_PUBLIC(buffer, &value->type, value_bytes);
7176 if (result) {
7177 return result;
7178 }
7179
7180 result = Parse_TPMI_ALG_HASH(buffer, &value->name_alg, value_bytes);
7181 if (result) {
7182 return result;
7183 }
7184
7185 result = Parse_TPMA_OBJECT(buffer, &value->object_attributes, value_bytes);
7186 if (result) {
7187 return result;
7188 }
7189
7190 result = Parse_TPM2B_DIGEST(buffer, &value->auth_policy, value_bytes);
7191 if (result) {
7192 return result;
7193 }
7194
7195 result = Parse_TPMU_PUBLIC_PARMS(buffer, value->type, &value->parameters,
7196 value_bytes);
7197 if (result) {
7198 return result;
7199 }
7200
7201 result =
7202 Parse_TPMU_PUBLIC_ID(buffer, value->type, &value->unique, value_bytes);
7203 if (result) {
7204 return result;
7205 }
7206 return result;
7207 }
7208
Serialize_TPM2B_PUBLIC(const TPM2B_PUBLIC & value,std::string * buffer)7209 TPM_RC Serialize_TPM2B_PUBLIC(const TPM2B_PUBLIC& value, std::string* buffer) {
7210 TPM_RC result = TPM_RC_SUCCESS;
7211 VLOG(3) << __func__;
7212
7213 std::string field_bytes;
7214 if (value.size) {
7215 if (value.size != sizeof(TPMT_PUBLIC)) {
7216 return TPM_RC_SIZE;
7217 }
7218 result = Serialize_TPMT_PUBLIC(value.public_area, &field_bytes);
7219 if (result) {
7220 return result;
7221 }
7222 }
7223 std::string size_bytes;
7224 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7225 if (result) {
7226 return result;
7227 }
7228 buffer->append(size_bytes + field_bytes);
7229 return result;
7230 }
7231
Parse_TPM2B_PUBLIC(std::string * buffer,TPM2B_PUBLIC * value,std::string * value_bytes)7232 TPM_RC Parse_TPM2B_PUBLIC(std::string* buffer,
7233 TPM2B_PUBLIC* value,
7234 std::string* value_bytes) {
7235 TPM_RC result = TPM_RC_SUCCESS;
7236 VLOG(3) << __func__;
7237
7238 UINT16 parsed_size = 0;
7239 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7240 if (result) {
7241 return result;
7242 }
7243 if (!parsed_size) {
7244 value->size = 0;
7245 } else {
7246 value->size = sizeof(TPMT_PUBLIC);
7247 result = Parse_TPMT_PUBLIC(buffer, &value->public_area, value_bytes);
7248 if (result) {
7249 return result;
7250 }
7251 }
7252 return result;
7253 }
7254
Make_TPM2B_PUBLIC(const TPMT_PUBLIC & inner)7255 TPM2B_PUBLIC Make_TPM2B_PUBLIC(const TPMT_PUBLIC& inner) {
7256 TPM2B_PUBLIC tpm2b;
7257 tpm2b.size = sizeof(TPMT_PUBLIC);
7258 tpm2b.public_area = inner;
7259 return tpm2b;
7260 }
7261
Serialize_TPM2B_PRIVATE_VENDOR_SPECIFIC(const TPM2B_PRIVATE_VENDOR_SPECIFIC & value,std::string * buffer)7262 TPM_RC Serialize_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7263 const TPM2B_PRIVATE_VENDOR_SPECIFIC& value, std::string* buffer) {
7264 TPM_RC result = TPM_RC_SUCCESS;
7265 VLOG(3) << __func__;
7266
7267 result = Serialize_UINT16(value.size, buffer);
7268 if (result) {
7269 return result;
7270 }
7271
7272 if (std::size(value.buffer) < value.size) {
7273 return TPM_RC_INSUFFICIENT;
7274 }
7275 for (uint32_t i = 0; i < value.size; ++i) {
7276 result = Serialize_BYTE(value.buffer[i], buffer);
7277 if (result) {
7278 return result;
7279 }
7280 }
7281 return result;
7282 }
7283
Parse_TPM2B_PRIVATE_VENDOR_SPECIFIC(std::string * buffer,TPM2B_PRIVATE_VENDOR_SPECIFIC * value,std::string * value_bytes)7284 TPM_RC Parse_TPM2B_PRIVATE_VENDOR_SPECIFIC(std::string* buffer,
7285 TPM2B_PRIVATE_VENDOR_SPECIFIC* value,
7286 std::string* value_bytes) {
7287 TPM_RC result = TPM_RC_SUCCESS;
7288 VLOG(3) << __func__;
7289
7290 result = Parse_UINT16(buffer, &value->size, value_bytes);
7291 if (result) {
7292 return result;
7293 }
7294
7295 if (std::size(value->buffer) < value->size) {
7296 return TPM_RC_INSUFFICIENT;
7297 }
7298 for (uint32_t i = 0; i < value->size; ++i) {
7299 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7300 if (result) {
7301 return result;
7302 }
7303 }
7304 return result;
7305 }
7306
Make_TPM2B_PRIVATE_VENDOR_SPECIFIC(const std::string & bytes)7307 TPM2B_PRIVATE_VENDOR_SPECIFIC Make_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7308 const std::string& bytes) {
7309 TPM2B_PRIVATE_VENDOR_SPECIFIC tpm2b;
7310 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7311 memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_VENDOR_SPECIFIC));
7312 tpm2b.size = bytes.size();
7313 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7314 return tpm2b;
7315 }
7316
StringFrom_TPM2B_PRIVATE_VENDOR_SPECIFIC(const TPM2B_PRIVATE_VENDOR_SPECIFIC & tpm2b)7317 std::string StringFrom_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7318 const TPM2B_PRIVATE_VENDOR_SPECIFIC& tpm2b) {
7319 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7320 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7321 return std::string(char_buffer, tpm2b.size);
7322 }
7323
Serialize_TPMU_SENSITIVE_COMPOSITE(const TPMU_SENSITIVE_COMPOSITE & value,TPMI_ALG_PUBLIC selector,std::string * buffer)7324 TPM_RC Serialize_TPMU_SENSITIVE_COMPOSITE(const TPMU_SENSITIVE_COMPOSITE& value,
7325 TPMI_ALG_PUBLIC selector,
7326 std::string* buffer) {
7327 TPM_RC result = TPM_RC_SUCCESS;
7328 VLOG(3) << __func__;
7329
7330 if (selector == TPM_ALG_KEYEDHASH) {
7331 result = Serialize_TPM2B_SENSITIVE_DATA(value.bits, buffer);
7332 if (result) {
7333 return result;
7334 }
7335 }
7336
7337 if (selector == TPM_ALG_RSA) {
7338 result = Serialize_TPM2B_PRIVATE_KEY_RSA(value.rsa, buffer);
7339 if (result) {
7340 return result;
7341 }
7342 }
7343
7344 if (selector == TPM_ALG_SYMCIPHER) {
7345 result = Serialize_TPM2B_SYM_KEY(value.sym, buffer);
7346 if (result) {
7347 return result;
7348 }
7349 }
7350
7351 if (selector == TPM_ALG_ECC) {
7352 result = Serialize_TPM2B_ECC_PARAMETER(value.ecc, buffer);
7353 if (result) {
7354 return result;
7355 }
7356 }
7357 return result;
7358 }
7359
Parse_TPMU_SENSITIVE_COMPOSITE(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_SENSITIVE_COMPOSITE * value,std::string * value_bytes)7360 TPM_RC Parse_TPMU_SENSITIVE_COMPOSITE(std::string* buffer,
7361 TPMI_ALG_PUBLIC selector,
7362 TPMU_SENSITIVE_COMPOSITE* value,
7363 std::string* value_bytes) {
7364 TPM_RC result = TPM_RC_SUCCESS;
7365 VLOG(3) << __func__;
7366
7367 if (selector == TPM_ALG_KEYEDHASH) {
7368 result = Parse_TPM2B_SENSITIVE_DATA(buffer, &value->bits, value_bytes);
7369 if (result) {
7370 return result;
7371 }
7372 }
7373
7374 if (selector == TPM_ALG_RSA) {
7375 result = Parse_TPM2B_PRIVATE_KEY_RSA(buffer, &value->rsa, value_bytes);
7376 if (result) {
7377 return result;
7378 }
7379 }
7380
7381 if (selector == TPM_ALG_SYMCIPHER) {
7382 result = Parse_TPM2B_SYM_KEY(buffer, &value->sym, value_bytes);
7383 if (result) {
7384 return result;
7385 }
7386 }
7387
7388 if (selector == TPM_ALG_ECC) {
7389 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->ecc, value_bytes);
7390 if (result) {
7391 return result;
7392 }
7393 }
7394 return result;
7395 }
7396
Serialize_TPMT_SENSITIVE(const TPMT_SENSITIVE & value,std::string * buffer)7397 TPM_RC Serialize_TPMT_SENSITIVE(const TPMT_SENSITIVE& value,
7398 std::string* buffer) {
7399 TPM_RC result = TPM_RC_SUCCESS;
7400 VLOG(3) << __func__;
7401
7402 result = Serialize_TPMI_ALG_PUBLIC(value.sensitive_type, buffer);
7403 if (result) {
7404 return result;
7405 }
7406
7407 result = Serialize_TPM2B_AUTH(value.auth_value, buffer);
7408 if (result) {
7409 return result;
7410 }
7411
7412 result = Serialize_TPM2B_DIGEST(value.seed_value, buffer);
7413 if (result) {
7414 return result;
7415 }
7416
7417 result = Serialize_TPMU_SENSITIVE_COMPOSITE(value.sensitive,
7418 value.sensitive_type, buffer);
7419 if (result) {
7420 return result;
7421 }
7422 return result;
7423 }
7424
Parse_TPMT_SENSITIVE(std::string * buffer,TPMT_SENSITIVE * value,std::string * value_bytes)7425 TPM_RC Parse_TPMT_SENSITIVE(std::string* buffer,
7426 TPMT_SENSITIVE* value,
7427 std::string* value_bytes) {
7428 TPM_RC result = TPM_RC_SUCCESS;
7429 VLOG(3) << __func__;
7430
7431 result = Parse_TPMI_ALG_PUBLIC(buffer, &value->sensitive_type, value_bytes);
7432 if (result) {
7433 return result;
7434 }
7435
7436 result = Parse_TPM2B_AUTH(buffer, &value->auth_value, value_bytes);
7437 if (result) {
7438 return result;
7439 }
7440
7441 result = Parse_TPM2B_DIGEST(buffer, &value->seed_value, value_bytes);
7442 if (result) {
7443 return result;
7444 }
7445
7446 result = Parse_TPMU_SENSITIVE_COMPOSITE(buffer, value->sensitive_type,
7447 &value->sensitive, value_bytes);
7448 if (result) {
7449 return result;
7450 }
7451 return result;
7452 }
7453
Serialize_TPM2B_SENSITIVE(const TPM2B_SENSITIVE & value,std::string * buffer)7454 TPM_RC Serialize_TPM2B_SENSITIVE(const TPM2B_SENSITIVE& value,
7455 std::string* buffer) {
7456 TPM_RC result = TPM_RC_SUCCESS;
7457 VLOG(3) << __func__;
7458
7459 std::string field_bytes;
7460 if (value.size) {
7461 if (value.size != sizeof(TPMT_SENSITIVE)) {
7462 return TPM_RC_SIZE;
7463 }
7464 result = Serialize_TPMT_SENSITIVE(value.sensitive_area, &field_bytes);
7465 if (result) {
7466 return result;
7467 }
7468 }
7469 std::string size_bytes;
7470 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7471 if (result) {
7472 return result;
7473 }
7474 buffer->append(size_bytes + field_bytes);
7475 return result;
7476 }
7477
Parse_TPM2B_SENSITIVE(std::string * buffer,TPM2B_SENSITIVE * value,std::string * value_bytes)7478 TPM_RC Parse_TPM2B_SENSITIVE(std::string* buffer,
7479 TPM2B_SENSITIVE* value,
7480 std::string* value_bytes) {
7481 TPM_RC result = TPM_RC_SUCCESS;
7482 VLOG(3) << __func__;
7483
7484 UINT16 parsed_size = 0;
7485 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7486 if (result) {
7487 return result;
7488 }
7489 if (!parsed_size) {
7490 value->size = 0;
7491 } else {
7492 value->size = sizeof(TPMT_SENSITIVE);
7493 result = Parse_TPMT_SENSITIVE(buffer, &value->sensitive_area, value_bytes);
7494 if (result) {
7495 return result;
7496 }
7497 }
7498 return result;
7499 }
7500
Make_TPM2B_SENSITIVE(const TPMT_SENSITIVE & inner)7501 TPM2B_SENSITIVE Make_TPM2B_SENSITIVE(const TPMT_SENSITIVE& inner) {
7502 TPM2B_SENSITIVE tpm2b;
7503 tpm2b.size = sizeof(TPMT_SENSITIVE);
7504 tpm2b.sensitive_area = inner;
7505 return tpm2b;
7506 }
7507
Serialize_TPM2B_PRIVATE(const TPM2B_PRIVATE & value,std::string * buffer)7508 TPM_RC Serialize_TPM2B_PRIVATE(const TPM2B_PRIVATE& value,
7509 std::string* buffer) {
7510 TPM_RC result = TPM_RC_SUCCESS;
7511 VLOG(3) << __func__;
7512
7513 result = Serialize_UINT16(value.size, buffer);
7514 if (result) {
7515 return result;
7516 }
7517
7518 if (std::size(value.buffer) < value.size) {
7519 return TPM_RC_INSUFFICIENT;
7520 }
7521 for (uint32_t i = 0; i < value.size; ++i) {
7522 result = Serialize_BYTE(value.buffer[i], buffer);
7523 if (result) {
7524 return result;
7525 }
7526 }
7527 return result;
7528 }
7529
Parse_TPM2B_PRIVATE(std::string * buffer,TPM2B_PRIVATE * value,std::string * value_bytes)7530 TPM_RC Parse_TPM2B_PRIVATE(std::string* buffer,
7531 TPM2B_PRIVATE* value,
7532 std::string* value_bytes) {
7533 TPM_RC result = TPM_RC_SUCCESS;
7534 VLOG(3) << __func__;
7535
7536 result = Parse_UINT16(buffer, &value->size, value_bytes);
7537 if (result) {
7538 return result;
7539 }
7540
7541 if (std::size(value->buffer) < value->size) {
7542 return TPM_RC_INSUFFICIENT;
7543 }
7544 for (uint32_t i = 0; i < value->size; ++i) {
7545 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7546 if (result) {
7547 return result;
7548 }
7549 }
7550 return result;
7551 }
7552
Make_TPM2B_PRIVATE(const std::string & bytes)7553 TPM2B_PRIVATE Make_TPM2B_PRIVATE(const std::string& bytes) {
7554 TPM2B_PRIVATE tpm2b;
7555 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7556 memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE));
7557 tpm2b.size = bytes.size();
7558 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7559 return tpm2b;
7560 }
7561
StringFrom_TPM2B_PRIVATE(const TPM2B_PRIVATE & tpm2b)7562 std::string StringFrom_TPM2B_PRIVATE(const TPM2B_PRIVATE& tpm2b) {
7563 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7564 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7565 return std::string(char_buffer, tpm2b.size);
7566 }
7567
Serialize_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT & value,std::string * buffer)7568 TPM_RC Serialize_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT& value,
7569 std::string* buffer) {
7570 TPM_RC result = TPM_RC_SUCCESS;
7571 VLOG(3) << __func__;
7572
7573 result = Serialize_UINT16(value.size, buffer);
7574 if (result) {
7575 return result;
7576 }
7577
7578 if (std::size(value.credential) < value.size) {
7579 return TPM_RC_INSUFFICIENT;
7580 }
7581 for (uint32_t i = 0; i < value.size; ++i) {
7582 result = Serialize_BYTE(value.credential[i], buffer);
7583 if (result) {
7584 return result;
7585 }
7586 }
7587 return result;
7588 }
7589
Parse_TPM2B_ID_OBJECT(std::string * buffer,TPM2B_ID_OBJECT * value,std::string * value_bytes)7590 TPM_RC Parse_TPM2B_ID_OBJECT(std::string* buffer,
7591 TPM2B_ID_OBJECT* value,
7592 std::string* value_bytes) {
7593 TPM_RC result = TPM_RC_SUCCESS;
7594 VLOG(3) << __func__;
7595
7596 result = Parse_UINT16(buffer, &value->size, value_bytes);
7597 if (result) {
7598 return result;
7599 }
7600
7601 if (std::size(value->credential) < value->size) {
7602 return TPM_RC_INSUFFICIENT;
7603 }
7604 for (uint32_t i = 0; i < value->size; ++i) {
7605 result = Parse_BYTE(buffer, &value->credential[i], value_bytes);
7606 if (result) {
7607 return result;
7608 }
7609 }
7610 return result;
7611 }
7612
Make_TPM2B_ID_OBJECT(const std::string & bytes)7613 TPM2B_ID_OBJECT Make_TPM2B_ID_OBJECT(const std::string& bytes) {
7614 TPM2B_ID_OBJECT tpm2b;
7615 CHECK(bytes.size() <= sizeof(tpm2b.credential));
7616 memset(&tpm2b, 0, sizeof(TPM2B_ID_OBJECT));
7617 tpm2b.size = bytes.size();
7618 memcpy(tpm2b.credential, bytes.data(), bytes.size());
7619 return tpm2b;
7620 }
7621
StringFrom_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT & tpm2b)7622 std::string StringFrom_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT& tpm2b) {
7623 CHECK(tpm2b.size <= std::size(tpm2b.credential));
7624 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.credential);
7625 return std::string(char_buffer, tpm2b.size);
7626 }
7627
Serialize_TPMS_NV_PUBLIC(const TPMS_NV_PUBLIC & value,std::string * buffer)7628 TPM_RC Serialize_TPMS_NV_PUBLIC(const TPMS_NV_PUBLIC& value,
7629 std::string* buffer) {
7630 TPM_RC result = TPM_RC_SUCCESS;
7631 VLOG(3) << __func__;
7632
7633 result = Serialize_TPMI_RH_NV_INDEX(value.nv_index, buffer);
7634 if (result) {
7635 return result;
7636 }
7637
7638 result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer);
7639 if (result) {
7640 return result;
7641 }
7642
7643 result = Serialize_TPMA_NV(value.attributes, buffer);
7644 if (result) {
7645 return result;
7646 }
7647
7648 result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer);
7649 if (result) {
7650 return result;
7651 }
7652
7653 result = Serialize_UINT16(value.data_size, buffer);
7654 if (result) {
7655 return result;
7656 }
7657 return result;
7658 }
7659
Parse_TPMS_NV_PUBLIC(std::string * buffer,TPMS_NV_PUBLIC * value,std::string * value_bytes)7660 TPM_RC Parse_TPMS_NV_PUBLIC(std::string* buffer,
7661 TPMS_NV_PUBLIC* value,
7662 std::string* value_bytes) {
7663 TPM_RC result = TPM_RC_SUCCESS;
7664 VLOG(3) << __func__;
7665
7666 result = Parse_TPMI_RH_NV_INDEX(buffer, &value->nv_index, value_bytes);
7667 if (result) {
7668 return result;
7669 }
7670
7671 result = Parse_TPMI_ALG_HASH(buffer, &value->name_alg, value_bytes);
7672 if (result) {
7673 return result;
7674 }
7675
7676 result = Parse_TPMA_NV(buffer, &value->attributes, value_bytes);
7677 if (result) {
7678 return result;
7679 }
7680
7681 result = Parse_TPM2B_DIGEST(buffer, &value->auth_policy, value_bytes);
7682 if (result) {
7683 return result;
7684 }
7685
7686 result = Parse_UINT16(buffer, &value->data_size, value_bytes);
7687 if (result) {
7688 return result;
7689 }
7690 return result;
7691 }
7692
Serialize_TPM2B_NV_PUBLIC(const TPM2B_NV_PUBLIC & value,std::string * buffer)7693 TPM_RC Serialize_TPM2B_NV_PUBLIC(const TPM2B_NV_PUBLIC& value,
7694 std::string* buffer) {
7695 TPM_RC result = TPM_RC_SUCCESS;
7696 VLOG(3) << __func__;
7697
7698 std::string field_bytes;
7699 if (value.size) {
7700 if (value.size != sizeof(TPMS_NV_PUBLIC)) {
7701 return TPM_RC_SIZE;
7702 }
7703 result = Serialize_TPMS_NV_PUBLIC(value.nv_public, &field_bytes);
7704 if (result) {
7705 return result;
7706 }
7707 }
7708 std::string size_bytes;
7709 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7710 if (result) {
7711 return result;
7712 }
7713 buffer->append(size_bytes + field_bytes);
7714 return result;
7715 }
7716
Parse_TPM2B_NV_PUBLIC(std::string * buffer,TPM2B_NV_PUBLIC * value,std::string * value_bytes)7717 TPM_RC Parse_TPM2B_NV_PUBLIC(std::string* buffer,
7718 TPM2B_NV_PUBLIC* value,
7719 std::string* value_bytes) {
7720 TPM_RC result = TPM_RC_SUCCESS;
7721 VLOG(3) << __func__;
7722
7723 UINT16 parsed_size = 0;
7724 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7725 if (result) {
7726 return result;
7727 }
7728 if (!parsed_size) {
7729 value->size = 0;
7730 } else {
7731 value->size = sizeof(TPMS_NV_PUBLIC);
7732 result = Parse_TPMS_NV_PUBLIC(buffer, &value->nv_public, value_bytes);
7733 if (result) {
7734 return result;
7735 }
7736 }
7737 return result;
7738 }
7739
Make_TPM2B_NV_PUBLIC(const TPMS_NV_PUBLIC & inner)7740 TPM2B_NV_PUBLIC Make_TPM2B_NV_PUBLIC(const TPMS_NV_PUBLIC& inner) {
7741 TPM2B_NV_PUBLIC tpm2b;
7742 tpm2b.size = sizeof(TPMS_NV_PUBLIC);
7743 tpm2b.nv_public = inner;
7744 return tpm2b;
7745 }
7746
Serialize_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE & value,std::string * buffer)7747 TPM_RC Serialize_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE& value,
7748 std::string* buffer) {
7749 TPM_RC result = TPM_RC_SUCCESS;
7750 VLOG(3) << __func__;
7751
7752 result = Serialize_UINT16(value.size, buffer);
7753 if (result) {
7754 return result;
7755 }
7756
7757 if (std::size(value.buffer) < value.size) {
7758 return TPM_RC_INSUFFICIENT;
7759 }
7760 for (uint32_t i = 0; i < value.size; ++i) {
7761 result = Serialize_BYTE(value.buffer[i], buffer);
7762 if (result) {
7763 return result;
7764 }
7765 }
7766 return result;
7767 }
7768
Parse_TPM2B_CONTEXT_SENSITIVE(std::string * buffer,TPM2B_CONTEXT_SENSITIVE * value,std::string * value_bytes)7769 TPM_RC Parse_TPM2B_CONTEXT_SENSITIVE(std::string* buffer,
7770 TPM2B_CONTEXT_SENSITIVE* value,
7771 std::string* value_bytes) {
7772 TPM_RC result = TPM_RC_SUCCESS;
7773 VLOG(3) << __func__;
7774
7775 result = Parse_UINT16(buffer, &value->size, value_bytes);
7776 if (result) {
7777 return result;
7778 }
7779
7780 if (std::size(value->buffer) < value->size) {
7781 return TPM_RC_INSUFFICIENT;
7782 }
7783 for (uint32_t i = 0; i < value->size; ++i) {
7784 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7785 if (result) {
7786 return result;
7787 }
7788 }
7789 return result;
7790 }
7791
Make_TPM2B_CONTEXT_SENSITIVE(const std::string & bytes)7792 TPM2B_CONTEXT_SENSITIVE Make_TPM2B_CONTEXT_SENSITIVE(const std::string& bytes) {
7793 TPM2B_CONTEXT_SENSITIVE tpm2b;
7794 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7795 memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_SENSITIVE));
7796 tpm2b.size = bytes.size();
7797 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7798 return tpm2b;
7799 }
7800
StringFrom_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE & tpm2b)7801 std::string StringFrom_TPM2B_CONTEXT_SENSITIVE(
7802 const TPM2B_CONTEXT_SENSITIVE& tpm2b) {
7803 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7804 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7805 return std::string(char_buffer, tpm2b.size);
7806 }
7807
Serialize_TPMS_CONTEXT_DATA(const TPMS_CONTEXT_DATA & value,std::string * buffer)7808 TPM_RC Serialize_TPMS_CONTEXT_DATA(const TPMS_CONTEXT_DATA& value,
7809 std::string* buffer) {
7810 TPM_RC result = TPM_RC_SUCCESS;
7811 VLOG(3) << __func__;
7812
7813 result = Serialize_TPM2B_DIGEST(value.integrity, buffer);
7814 if (result) {
7815 return result;
7816 }
7817
7818 result = Serialize_TPM2B_CONTEXT_SENSITIVE(value.encrypted, buffer);
7819 if (result) {
7820 return result;
7821 }
7822 return result;
7823 }
7824
Parse_TPMS_CONTEXT_DATA(std::string * buffer,TPMS_CONTEXT_DATA * value,std::string * value_bytes)7825 TPM_RC Parse_TPMS_CONTEXT_DATA(std::string* buffer,
7826 TPMS_CONTEXT_DATA* value,
7827 std::string* value_bytes) {
7828 TPM_RC result = TPM_RC_SUCCESS;
7829 VLOG(3) << __func__;
7830
7831 result = Parse_TPM2B_DIGEST(buffer, &value->integrity, value_bytes);
7832 if (result) {
7833 return result;
7834 }
7835
7836 result =
7837 Parse_TPM2B_CONTEXT_SENSITIVE(buffer, &value->encrypted, value_bytes);
7838 if (result) {
7839 return result;
7840 }
7841 return result;
7842 }
7843
Serialize_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA & value,std::string * buffer)7844 TPM_RC Serialize_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA& value,
7845 std::string* buffer) {
7846 TPM_RC result = TPM_RC_SUCCESS;
7847 VLOG(3) << __func__;
7848
7849 result = Serialize_UINT16(value.size, buffer);
7850 if (result) {
7851 return result;
7852 }
7853
7854 if (std::size(value.buffer) < value.size) {
7855 return TPM_RC_INSUFFICIENT;
7856 }
7857 for (uint32_t i = 0; i < value.size; ++i) {
7858 result = Serialize_BYTE(value.buffer[i], buffer);
7859 if (result) {
7860 return result;
7861 }
7862 }
7863 return result;
7864 }
7865
Parse_TPM2B_CONTEXT_DATA(std::string * buffer,TPM2B_CONTEXT_DATA * value,std::string * value_bytes)7866 TPM_RC Parse_TPM2B_CONTEXT_DATA(std::string* buffer,
7867 TPM2B_CONTEXT_DATA* value,
7868 std::string* value_bytes) {
7869 TPM_RC result = TPM_RC_SUCCESS;
7870 VLOG(3) << __func__;
7871
7872 result = Parse_UINT16(buffer, &value->size, value_bytes);
7873 if (result) {
7874 return result;
7875 }
7876
7877 if (std::size(value->buffer) < value->size) {
7878 return TPM_RC_INSUFFICIENT;
7879 }
7880 for (uint32_t i = 0; i < value->size; ++i) {
7881 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7882 if (result) {
7883 return result;
7884 }
7885 }
7886 return result;
7887 }
7888
Make_TPM2B_CONTEXT_DATA(const std::string & bytes)7889 TPM2B_CONTEXT_DATA Make_TPM2B_CONTEXT_DATA(const std::string& bytes) {
7890 TPM2B_CONTEXT_DATA tpm2b;
7891 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7892 memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_DATA));
7893 tpm2b.size = bytes.size();
7894 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7895 return tpm2b;
7896 }
7897
StringFrom_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA & tpm2b)7898 std::string StringFrom_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA& tpm2b) {
7899 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7900 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7901 return std::string(char_buffer, tpm2b.size);
7902 }
7903
Serialize_TPMS_CONTEXT(const TPMS_CONTEXT & value,std::string * buffer)7904 TPM_RC Serialize_TPMS_CONTEXT(const TPMS_CONTEXT& value, std::string* buffer) {
7905 TPM_RC result = TPM_RC_SUCCESS;
7906 VLOG(3) << __func__;
7907
7908 result = Serialize_UINT64(value.sequence, buffer);
7909 if (result) {
7910 return result;
7911 }
7912
7913 result = Serialize_TPMI_DH_CONTEXT(value.saved_handle, buffer);
7914 if (result) {
7915 return result;
7916 }
7917
7918 result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
7919 if (result) {
7920 return result;
7921 }
7922
7923 result = Serialize_TPM2B_CONTEXT_DATA(value.context_blob, buffer);
7924 if (result) {
7925 return result;
7926 }
7927 return result;
7928 }
7929
Parse_TPMS_CONTEXT(std::string * buffer,TPMS_CONTEXT * value,std::string * value_bytes)7930 TPM_RC Parse_TPMS_CONTEXT(std::string* buffer,
7931 TPMS_CONTEXT* value,
7932 std::string* value_bytes) {
7933 TPM_RC result = TPM_RC_SUCCESS;
7934 VLOG(3) << __func__;
7935
7936 result = Parse_UINT64(buffer, &value->sequence, value_bytes);
7937 if (result) {
7938 return result;
7939 }
7940
7941 result = Parse_TPMI_DH_CONTEXT(buffer, &value->saved_handle, value_bytes);
7942 if (result) {
7943 return result;
7944 }
7945
7946 result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
7947 if (result) {
7948 return result;
7949 }
7950
7951 result = Parse_TPM2B_CONTEXT_DATA(buffer, &value->context_blob, value_bytes);
7952 if (result) {
7953 return result;
7954 }
7955 return result;
7956 }
7957
Serialize_TPMS_CREATION_DATA(const TPMS_CREATION_DATA & value,std::string * buffer)7958 TPM_RC Serialize_TPMS_CREATION_DATA(const TPMS_CREATION_DATA& value,
7959 std::string* buffer) {
7960 TPM_RC result = TPM_RC_SUCCESS;
7961 VLOG(3) << __func__;
7962
7963 result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer);
7964 if (result) {
7965 return result;
7966 }
7967
7968 result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer);
7969 if (result) {
7970 return result;
7971 }
7972
7973 result = Serialize_TPMA_LOCALITY(value.locality, buffer);
7974 if (result) {
7975 return result;
7976 }
7977
7978 result = Serialize_TPM_ALG_ID(value.parent_name_alg, buffer);
7979 if (result) {
7980 return result;
7981 }
7982
7983 result = Serialize_TPM2B_NAME(value.parent_name, buffer);
7984 if (result) {
7985 return result;
7986 }
7987
7988 result = Serialize_TPM2B_NAME(value.parent_qualified_name, buffer);
7989 if (result) {
7990 return result;
7991 }
7992
7993 result = Serialize_TPM2B_DATA(value.outside_info, buffer);
7994 if (result) {
7995 return result;
7996 }
7997 return result;
7998 }
7999
Parse_TPMS_CREATION_DATA(std::string * buffer,TPMS_CREATION_DATA * value,std::string * value_bytes)8000 TPM_RC Parse_TPMS_CREATION_DATA(std::string* buffer,
8001 TPMS_CREATION_DATA* value,
8002 std::string* value_bytes) {
8003 TPM_RC result = TPM_RC_SUCCESS;
8004 VLOG(3) << __func__;
8005
8006 result = Parse_TPML_PCR_SELECTION(buffer, &value->pcr_select, value_bytes);
8007 if (result) {
8008 return result;
8009 }
8010
8011 result = Parse_TPM2B_DIGEST(buffer, &value->pcr_digest, value_bytes);
8012 if (result) {
8013 return result;
8014 }
8015
8016 result = Parse_TPMA_LOCALITY(buffer, &value->locality, value_bytes);
8017 if (result) {
8018 return result;
8019 }
8020
8021 result = Parse_TPM_ALG_ID(buffer, &value->parent_name_alg, value_bytes);
8022 if (result) {
8023 return result;
8024 }
8025
8026 result = Parse_TPM2B_NAME(buffer, &value->parent_name, value_bytes);
8027 if (result) {
8028 return result;
8029 }
8030
8031 result = Parse_TPM2B_NAME(buffer, &value->parent_qualified_name, value_bytes);
8032 if (result) {
8033 return result;
8034 }
8035
8036 result = Parse_TPM2B_DATA(buffer, &value->outside_info, value_bytes);
8037 if (result) {
8038 return result;
8039 }
8040 return result;
8041 }
8042
Serialize_TPM2B_CREATION_DATA(const TPM2B_CREATION_DATA & value,std::string * buffer)8043 TPM_RC Serialize_TPM2B_CREATION_DATA(const TPM2B_CREATION_DATA& value,
8044 std::string* buffer) {
8045 TPM_RC result = TPM_RC_SUCCESS;
8046 VLOG(3) << __func__;
8047
8048 std::string field_bytes;
8049 if (value.size) {
8050 if (value.size != sizeof(TPMS_CREATION_DATA)) {
8051 return TPM_RC_SIZE;
8052 }
8053 result = Serialize_TPMS_CREATION_DATA(value.creation_data, &field_bytes);
8054 if (result) {
8055 return result;
8056 }
8057 }
8058 std::string size_bytes;
8059 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
8060 if (result) {
8061 return result;
8062 }
8063 buffer->append(size_bytes + field_bytes);
8064 return result;
8065 }
8066
Parse_TPM2B_CREATION_DATA(std::string * buffer,TPM2B_CREATION_DATA * value,std::string * value_bytes)8067 TPM_RC Parse_TPM2B_CREATION_DATA(std::string* buffer,
8068 TPM2B_CREATION_DATA* value,
8069 std::string* value_bytes) {
8070 TPM_RC result = TPM_RC_SUCCESS;
8071 VLOG(3) << __func__;
8072
8073 UINT16 parsed_size = 0;
8074 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
8075 if (result) {
8076 return result;
8077 }
8078 if (!parsed_size) {
8079 value->size = 0;
8080 } else {
8081 value->size = sizeof(TPMS_CREATION_DATA);
8082 result =
8083 Parse_TPMS_CREATION_DATA(buffer, &value->creation_data, value_bytes);
8084 if (result) {
8085 return result;
8086 }
8087 }
8088 return result;
8089 }
8090
Make_TPM2B_CREATION_DATA(const TPMS_CREATION_DATA & inner)8091 TPM2B_CREATION_DATA Make_TPM2B_CREATION_DATA(const TPMS_CREATION_DATA& inner) {
8092 TPM2B_CREATION_DATA tpm2b;
8093 tpm2b.size = sizeof(TPMS_CREATION_DATA);
8094 tpm2b.creation_data = inner;
8095 return tpm2b;
8096 }
8097
SerializeCommand_Startup(const TPM_SU & startup_type,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8098 TPM_RC Tpm::SerializeCommand_Startup(
8099 const TPM_SU& startup_type,
8100 std::string* serialized_command,
8101 AuthorizationDelegate* authorization_delegate) {
8102 VLOG(3) << __func__;
8103 TPM_RC rc = TPM_RC_SUCCESS;
8104 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8105 UINT32 command_size = 10; // Header size.
8106 std::string handle_section_bytes;
8107 std::string parameter_section_bytes;
8108 TPM_CC command_code = TPM_CC_Startup;
8109 bool is_command_parameter_encryption_possible = false;
8110 bool is_response_parameter_encryption_possible = false;
8111 std::string command_code_bytes;
8112 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8113 if (rc != TPM_RC_SUCCESS) {
8114 return rc;
8115 }
8116 std::string startup_type_bytes;
8117 rc = Serialize_TPM_SU(startup_type, &startup_type_bytes);
8118 if (rc != TPM_RC_SUCCESS) {
8119 return rc;
8120 }
8121 std::unique_ptr<crypto::SecureHash> hash(
8122 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8123 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8124 hash->Update(startup_type_bytes.data(), startup_type_bytes.size());
8125 parameter_section_bytes += startup_type_bytes;
8126 command_size += startup_type_bytes.size();
8127 std::string command_hash(32, 0);
8128 hash->Finish(std::data(command_hash), command_hash.size());
8129 std::string authorization_section_bytes;
8130 std::string authorization_size_bytes;
8131 if (authorization_delegate) {
8132 if (!authorization_delegate->GetCommandAuthorization(
8133 command_hash, is_command_parameter_encryption_possible,
8134 is_response_parameter_encryption_possible,
8135 &authorization_section_bytes)) {
8136 return TRUNKS_RC_AUTHORIZATION_FAILED;
8137 }
8138 if (!authorization_section_bytes.empty()) {
8139 tag = TPM_ST_SESSIONS;
8140 std::string tmp;
8141 rc = Serialize_UINT32(authorization_section_bytes.size(),
8142 &authorization_size_bytes);
8143 if (rc != TPM_RC_SUCCESS) {
8144 return rc;
8145 }
8146 command_size +=
8147 authorization_size_bytes.size() + authorization_section_bytes.size();
8148 }
8149 }
8150 std::string tag_bytes;
8151 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8152 if (rc != TPM_RC_SUCCESS) {
8153 return rc;
8154 }
8155 std::string command_size_bytes;
8156 rc = Serialize_UINT32(command_size, &command_size_bytes);
8157 if (rc != TPM_RC_SUCCESS) {
8158 return rc;
8159 }
8160 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8161 handle_section_bytes + authorization_size_bytes +
8162 authorization_section_bytes + parameter_section_bytes;
8163 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8164 VLOG(2) << "Command: "
8165 << base::HexEncode(serialized_command->data(),
8166 serialized_command->size());
8167 return TPM_RC_SUCCESS;
8168 }
8169
ParseResponse_Startup(const std::string & response,AuthorizationDelegate * authorization_delegate)8170 TPM_RC Tpm::ParseResponse_Startup(
8171 const std::string& response,
8172 AuthorizationDelegate* authorization_delegate) {
8173 VLOG(3) << __func__;
8174 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8175 TPM_RC rc = TPM_RC_SUCCESS;
8176 std::string buffer(response);
8177 TPM_ST tag;
8178 std::string tag_bytes;
8179 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8180 if (rc != TPM_RC_SUCCESS) {
8181 return rc;
8182 }
8183 UINT32 response_size;
8184 std::string response_size_bytes;
8185 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8186 if (rc != TPM_RC_SUCCESS) {
8187 return rc;
8188 }
8189 TPM_RC response_code;
8190 std::string response_code_bytes;
8191 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8192 if (rc != TPM_RC_SUCCESS) {
8193 return rc;
8194 }
8195 if (response_size != response.size()) {
8196 return TPM_RC_SIZE;
8197 }
8198 if (response_code != TPM_RC_SUCCESS) {
8199 return response_code;
8200 }
8201 TPM_CC command_code = TPM_CC_Startup;
8202 std::string command_code_bytes;
8203 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8204 if (rc != TPM_RC_SUCCESS) {
8205 return rc;
8206 }
8207 std::string authorization_section_bytes;
8208 if (tag == TPM_ST_SESSIONS) {
8209 UINT32 parameter_section_size = buffer.size();
8210 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
8211 if (rc != TPM_RC_SUCCESS) {
8212 return rc;
8213 }
8214 if (parameter_section_size > buffer.size()) {
8215 return TPM_RC_INSUFFICIENT;
8216 }
8217 authorization_section_bytes = buffer.substr(parameter_section_size);
8218 // Keep the parameter section in |buffer|.
8219 buffer.erase(parameter_section_size);
8220 }
8221 std::unique_ptr<crypto::SecureHash> hash(
8222 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8223 hash->Update(response_code_bytes.data(), response_code_bytes.size());
8224 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8225 hash->Update(buffer.data(), buffer.size());
8226 std::string response_hash(32, 0);
8227 hash->Finish(std::data(response_hash), response_hash.size());
8228 if (tag == TPM_ST_SESSIONS) {
8229 if (!authorization_delegate)
8230 return TRUNKS_RC_AUTHORIZATION_FAILED;
8231 if (!authorization_delegate->CheckResponseAuthorization(
8232 response_hash, authorization_section_bytes)) {
8233 return TRUNKS_RC_AUTHORIZATION_FAILED;
8234 }
8235 }
8236 return TPM_RC_SUCCESS;
8237 }
8238
StartupErrorCallback(Tpm::StartupResponse callback,TPM_RC response_code)8239 void StartupErrorCallback(Tpm::StartupResponse callback, TPM_RC response_code) {
8240 VLOG(1) << __func__;
8241 std::move(callback).Run(response_code);
8242 }
8243
StartupResponseParser(Tpm::StartupResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8244 void StartupResponseParser(Tpm::StartupResponse callback,
8245 AuthorizationDelegate* authorization_delegate,
8246 const std::string& response) {
8247 VLOG(1) << __func__;
8248 TPM_RC rc = Tpm::ParseResponse_Startup(response, authorization_delegate);
8249 if (rc != TPM_RC_SUCCESS) {
8250 base::OnceCallback<void(TPM_RC)> error_reporter =
8251 base::BindOnce(StartupErrorCallback, std::move(callback));
8252 std::move(error_reporter).Run(rc);
8253 return;
8254 }
8255 std::move(callback).Run(rc);
8256 }
8257
Startup(const TPM_SU & startup_type,AuthorizationDelegate * authorization_delegate,StartupResponse callback)8258 void Tpm::Startup(const TPM_SU& startup_type,
8259 AuthorizationDelegate* authorization_delegate,
8260 StartupResponse callback) {
8261 VLOG(1) << __func__;
8262 std::string command;
8263 TPM_RC rc =
8264 SerializeCommand_Startup(startup_type, &command, authorization_delegate);
8265 if (rc != TPM_RC_SUCCESS) {
8266 base::OnceCallback<void(TPM_RC)> error_reporter =
8267 base::BindOnce(StartupErrorCallback, std::move(callback));
8268 std::move(error_reporter).Run(rc);
8269 return;
8270 }
8271 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8272 StartupResponseParser, std::move(callback), authorization_delegate);
8273 transceiver_->SendCommand(command, std::move(parser));
8274 }
8275
StartupSync(const TPM_SU & startup_type,AuthorizationDelegate * authorization_delegate)8276 TPM_RC Tpm::StartupSync(const TPM_SU& startup_type,
8277 AuthorizationDelegate* authorization_delegate) {
8278 VLOG(1) << __func__;
8279 std::string command;
8280 TPM_RC rc =
8281 SerializeCommand_Startup(startup_type, &command, authorization_delegate);
8282 if (rc != TPM_RC_SUCCESS) {
8283 return rc;
8284 }
8285 std::string response = transceiver_->SendCommandAndWait(command);
8286 rc = ParseResponse_Startup(response, authorization_delegate);
8287 return rc;
8288 }
8289
SerializeCommand_Shutdown(const TPM_SU & shutdown_type,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8290 TPM_RC Tpm::SerializeCommand_Shutdown(
8291 const TPM_SU& shutdown_type,
8292 std::string* serialized_command,
8293 AuthorizationDelegate* authorization_delegate) {
8294 VLOG(3) << __func__;
8295 TPM_RC rc = TPM_RC_SUCCESS;
8296 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8297 UINT32 command_size = 10; // Header size.
8298 std::string handle_section_bytes;
8299 std::string parameter_section_bytes;
8300 TPM_CC command_code = TPM_CC_Shutdown;
8301 bool is_command_parameter_encryption_possible = false;
8302 bool is_response_parameter_encryption_possible = false;
8303 std::string command_code_bytes;
8304 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8305 if (rc != TPM_RC_SUCCESS) {
8306 return rc;
8307 }
8308 std::string shutdown_type_bytes;
8309 rc = Serialize_TPM_SU(shutdown_type, &shutdown_type_bytes);
8310 if (rc != TPM_RC_SUCCESS) {
8311 return rc;
8312 }
8313 std::unique_ptr<crypto::SecureHash> hash(
8314 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8315 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8316 hash->Update(shutdown_type_bytes.data(), shutdown_type_bytes.size());
8317 parameter_section_bytes += shutdown_type_bytes;
8318 command_size += shutdown_type_bytes.size();
8319 std::string command_hash(32, 0);
8320 hash->Finish(std::data(command_hash), command_hash.size());
8321 std::string authorization_section_bytes;
8322 std::string authorization_size_bytes;
8323 if (authorization_delegate) {
8324 if (!authorization_delegate->GetCommandAuthorization(
8325 command_hash, is_command_parameter_encryption_possible,
8326 is_response_parameter_encryption_possible,
8327 &authorization_section_bytes)) {
8328 return TRUNKS_RC_AUTHORIZATION_FAILED;
8329 }
8330 if (!authorization_section_bytes.empty()) {
8331 tag = TPM_ST_SESSIONS;
8332 std::string tmp;
8333 rc = Serialize_UINT32(authorization_section_bytes.size(),
8334 &authorization_size_bytes);
8335 if (rc != TPM_RC_SUCCESS) {
8336 return rc;
8337 }
8338 command_size +=
8339 authorization_size_bytes.size() + authorization_section_bytes.size();
8340 }
8341 }
8342 std::string tag_bytes;
8343 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8344 if (rc != TPM_RC_SUCCESS) {
8345 return rc;
8346 }
8347 std::string command_size_bytes;
8348 rc = Serialize_UINT32(command_size, &command_size_bytes);
8349 if (rc != TPM_RC_SUCCESS) {
8350 return rc;
8351 }
8352 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8353 handle_section_bytes + authorization_size_bytes +
8354 authorization_section_bytes + parameter_section_bytes;
8355 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8356 VLOG(2) << "Command: "
8357 << base::HexEncode(serialized_command->data(),
8358 serialized_command->size());
8359 return TPM_RC_SUCCESS;
8360 }
8361
ParseResponse_Shutdown(const std::string & response,AuthorizationDelegate * authorization_delegate)8362 TPM_RC Tpm::ParseResponse_Shutdown(
8363 const std::string& response,
8364 AuthorizationDelegate* authorization_delegate) {
8365 VLOG(3) << __func__;
8366 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8367 TPM_RC rc = TPM_RC_SUCCESS;
8368 std::string buffer(response);
8369 TPM_ST tag;
8370 std::string tag_bytes;
8371 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8372 if (rc != TPM_RC_SUCCESS) {
8373 return rc;
8374 }
8375 UINT32 response_size;
8376 std::string response_size_bytes;
8377 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8378 if (rc != TPM_RC_SUCCESS) {
8379 return rc;
8380 }
8381 TPM_RC response_code;
8382 std::string response_code_bytes;
8383 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8384 if (rc != TPM_RC_SUCCESS) {
8385 return rc;
8386 }
8387 if (response_size != response.size()) {
8388 return TPM_RC_SIZE;
8389 }
8390 if (response_code != TPM_RC_SUCCESS) {
8391 return response_code;
8392 }
8393 TPM_CC command_code = TPM_CC_Shutdown;
8394 std::string command_code_bytes;
8395 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8396 if (rc != TPM_RC_SUCCESS) {
8397 return rc;
8398 }
8399 std::string authorization_section_bytes;
8400 if (tag == TPM_ST_SESSIONS) {
8401 UINT32 parameter_section_size = buffer.size();
8402 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
8403 if (rc != TPM_RC_SUCCESS) {
8404 return rc;
8405 }
8406 if (parameter_section_size > buffer.size()) {
8407 return TPM_RC_INSUFFICIENT;
8408 }
8409 authorization_section_bytes = buffer.substr(parameter_section_size);
8410 // Keep the parameter section in |buffer|.
8411 buffer.erase(parameter_section_size);
8412 }
8413 std::unique_ptr<crypto::SecureHash> hash(
8414 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8415 hash->Update(response_code_bytes.data(), response_code_bytes.size());
8416 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8417 hash->Update(buffer.data(), buffer.size());
8418 std::string response_hash(32, 0);
8419 hash->Finish(std::data(response_hash), response_hash.size());
8420 if (tag == TPM_ST_SESSIONS) {
8421 if (!authorization_delegate)
8422 return TRUNKS_RC_AUTHORIZATION_FAILED;
8423 if (!authorization_delegate->CheckResponseAuthorization(
8424 response_hash, authorization_section_bytes)) {
8425 return TRUNKS_RC_AUTHORIZATION_FAILED;
8426 }
8427 }
8428 return TPM_RC_SUCCESS;
8429 }
8430
ShutdownErrorCallback(Tpm::ShutdownResponse callback,TPM_RC response_code)8431 void ShutdownErrorCallback(Tpm::ShutdownResponse callback,
8432 TPM_RC response_code) {
8433 VLOG(1) << __func__;
8434 std::move(callback).Run(response_code);
8435 }
8436
ShutdownResponseParser(Tpm::ShutdownResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8437 void ShutdownResponseParser(Tpm::ShutdownResponse callback,
8438 AuthorizationDelegate* authorization_delegate,
8439 const std::string& response) {
8440 VLOG(1) << __func__;
8441 TPM_RC rc = Tpm::ParseResponse_Shutdown(response, authorization_delegate);
8442 if (rc != TPM_RC_SUCCESS) {
8443 base::OnceCallback<void(TPM_RC)> error_reporter =
8444 base::BindOnce(ShutdownErrorCallback, std::move(callback));
8445 std::move(error_reporter).Run(rc);
8446 return;
8447 }
8448 std::move(callback).Run(rc);
8449 }
8450
Shutdown(const TPM_SU & shutdown_type,AuthorizationDelegate * authorization_delegate,ShutdownResponse callback)8451 void Tpm::Shutdown(const TPM_SU& shutdown_type,
8452 AuthorizationDelegate* authorization_delegate,
8453 ShutdownResponse callback) {
8454 VLOG(1) << __func__;
8455 std::string command;
8456 TPM_RC rc = SerializeCommand_Shutdown(shutdown_type, &command,
8457 authorization_delegate);
8458 if (rc != TPM_RC_SUCCESS) {
8459 base::OnceCallback<void(TPM_RC)> error_reporter =
8460 base::BindOnce(ShutdownErrorCallback, std::move(callback));
8461 std::move(error_reporter).Run(rc);
8462 return;
8463 }
8464 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8465 ShutdownResponseParser, std::move(callback), authorization_delegate);
8466 transceiver_->SendCommand(command, std::move(parser));
8467 }
8468
ShutdownSync(const TPM_SU & shutdown_type,AuthorizationDelegate * authorization_delegate)8469 TPM_RC Tpm::ShutdownSync(const TPM_SU& shutdown_type,
8470 AuthorizationDelegate* authorization_delegate) {
8471 VLOG(1) << __func__;
8472 std::string command;
8473 TPM_RC rc = SerializeCommand_Shutdown(shutdown_type, &command,
8474 authorization_delegate);
8475 if (rc != TPM_RC_SUCCESS) {
8476 return rc;
8477 }
8478 std::string response = transceiver_->SendCommandAndWait(command);
8479 rc = ParseResponse_Shutdown(response, authorization_delegate);
8480 return rc;
8481 }
8482
SerializeCommand_SelfTest(const TPMI_YES_NO & full_test,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8483 TPM_RC Tpm::SerializeCommand_SelfTest(
8484 const TPMI_YES_NO& full_test,
8485 std::string* serialized_command,
8486 AuthorizationDelegate* authorization_delegate) {
8487 VLOG(3) << __func__;
8488 TPM_RC rc = TPM_RC_SUCCESS;
8489 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8490 UINT32 command_size = 10; // Header size.
8491 std::string handle_section_bytes;
8492 std::string parameter_section_bytes;
8493 TPM_CC command_code = TPM_CC_SelfTest;
8494 bool is_command_parameter_encryption_possible = false;
8495 bool is_response_parameter_encryption_possible = false;
8496 std::string command_code_bytes;
8497 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8498 if (rc != TPM_RC_SUCCESS) {
8499 return rc;
8500 }
8501 std::string full_test_bytes;
8502 rc = Serialize_TPMI_YES_NO(full_test, &full_test_bytes);
8503 if (rc != TPM_RC_SUCCESS) {
8504 return rc;
8505 }
8506 std::unique_ptr<crypto::SecureHash> hash(
8507 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8508 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8509 hash->Update(full_test_bytes.data(), full_test_bytes.size());
8510 parameter_section_bytes += full_test_bytes;
8511 command_size += full_test_bytes.size();
8512 std::string command_hash(32, 0);
8513 hash->Finish(std::data(command_hash), command_hash.size());
8514 std::string authorization_section_bytes;
8515 std::string authorization_size_bytes;
8516 if (authorization_delegate) {
8517 if (!authorization_delegate->GetCommandAuthorization(
8518 command_hash, is_command_parameter_encryption_possible,
8519 is_response_parameter_encryption_possible,
8520 &authorization_section_bytes)) {
8521 return TRUNKS_RC_AUTHORIZATION_FAILED;
8522 }
8523 if (!authorization_section_bytes.empty()) {
8524 tag = TPM_ST_SESSIONS;
8525 std::string tmp;
8526 rc = Serialize_UINT32(authorization_section_bytes.size(),
8527 &authorization_size_bytes);
8528 if (rc != TPM_RC_SUCCESS) {
8529 return rc;
8530 }
8531 command_size +=
8532 authorization_size_bytes.size() + authorization_section_bytes.size();
8533 }
8534 }
8535 std::string tag_bytes;
8536 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8537 if (rc != TPM_RC_SUCCESS) {
8538 return rc;
8539 }
8540 std::string command_size_bytes;
8541 rc = Serialize_UINT32(command_size, &command_size_bytes);
8542 if (rc != TPM_RC_SUCCESS) {
8543 return rc;
8544 }
8545 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8546 handle_section_bytes + authorization_size_bytes +
8547 authorization_section_bytes + parameter_section_bytes;
8548 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8549 VLOG(2) << "Command: "
8550 << base::HexEncode(serialized_command->data(),
8551 serialized_command->size());
8552 return TPM_RC_SUCCESS;
8553 }
8554
ParseResponse_SelfTest(const std::string & response,AuthorizationDelegate * authorization_delegate)8555 TPM_RC Tpm::ParseResponse_SelfTest(
8556 const std::string& response,
8557 AuthorizationDelegate* authorization_delegate) {
8558 VLOG(3) << __func__;
8559 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8560 TPM_RC rc = TPM_RC_SUCCESS;
8561 std::string buffer(response);
8562 TPM_ST tag;
8563 std::string tag_bytes;
8564 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8565 if (rc != TPM_RC_SUCCESS) {
8566 return rc;
8567 }
8568 UINT32 response_size;
8569 std::string response_size_bytes;
8570 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8571 if (rc != TPM_RC_SUCCESS) {
8572 return rc;
8573 }
8574 TPM_RC response_code;
8575 std::string response_code_bytes;
8576 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8577 if (rc != TPM_RC_SUCCESS) {
8578 return rc;
8579 }
8580 if (response_size != response.size()) {
8581 return TPM_RC_SIZE;
8582 }
8583 if (response_code != TPM_RC_SUCCESS) {
8584 return response_code;
8585 }
8586 TPM_CC command_code = TPM_CC_SelfTest;
8587 std::string command_code_bytes;
8588 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8589 if (rc != TPM_RC_SUCCESS) {
8590 return rc;
8591 }
8592 std::string authorization_section_bytes;
8593 if (tag == TPM_ST_SESSIONS) {
8594 UINT32 parameter_section_size = buffer.size();
8595 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
8596 if (rc != TPM_RC_SUCCESS) {
8597 return rc;
8598 }
8599 if (parameter_section_size > buffer.size()) {
8600 return TPM_RC_INSUFFICIENT;
8601 }
8602 authorization_section_bytes = buffer.substr(parameter_section_size);
8603 // Keep the parameter section in |buffer|.
8604 buffer.erase(parameter_section_size);
8605 }
8606 std::unique_ptr<crypto::SecureHash> hash(
8607 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8608 hash->Update(response_code_bytes.data(), response_code_bytes.size());
8609 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8610 hash->Update(buffer.data(), buffer.size());
8611 std::string response_hash(32, 0);
8612 hash->Finish(std::data(response_hash), response_hash.size());
8613 if (tag == TPM_ST_SESSIONS) {
8614 if (!authorization_delegate)
8615 return TRUNKS_RC_AUTHORIZATION_FAILED;
8616 if (!authorization_delegate->CheckResponseAuthorization(
8617 response_hash, authorization_section_bytes)) {
8618 return TRUNKS_RC_AUTHORIZATION_FAILED;
8619 }
8620 }
8621 return TPM_RC_SUCCESS;
8622 }
8623
SelfTestErrorCallback(Tpm::SelfTestResponse callback,TPM_RC response_code)8624 void SelfTestErrorCallback(Tpm::SelfTestResponse callback,
8625 TPM_RC response_code) {
8626 VLOG(1) << __func__;
8627 std::move(callback).Run(response_code);
8628 }
8629
SelfTestResponseParser(Tpm::SelfTestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8630 void SelfTestResponseParser(Tpm::SelfTestResponse callback,
8631 AuthorizationDelegate* authorization_delegate,
8632 const std::string& response) {
8633 VLOG(1) << __func__;
8634 TPM_RC rc = Tpm::ParseResponse_SelfTest(response, authorization_delegate);
8635 if (rc != TPM_RC_SUCCESS) {
8636 base::OnceCallback<void(TPM_RC)> error_reporter =
8637 base::BindOnce(SelfTestErrorCallback, std::move(callback));
8638 std::move(error_reporter).Run(rc);
8639 return;
8640 }
8641 std::move(callback).Run(rc);
8642 }
8643
SelfTest(const TPMI_YES_NO & full_test,AuthorizationDelegate * authorization_delegate,SelfTestResponse callback)8644 void Tpm::SelfTest(const TPMI_YES_NO& full_test,
8645 AuthorizationDelegate* authorization_delegate,
8646 SelfTestResponse callback) {
8647 VLOG(1) << __func__;
8648 std::string command;
8649 TPM_RC rc =
8650 SerializeCommand_SelfTest(full_test, &command, authorization_delegate);
8651 if (rc != TPM_RC_SUCCESS) {
8652 base::OnceCallback<void(TPM_RC)> error_reporter =
8653 base::BindOnce(SelfTestErrorCallback, std::move(callback));
8654 std::move(error_reporter).Run(rc);
8655 return;
8656 }
8657 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8658 SelfTestResponseParser, std::move(callback), authorization_delegate);
8659 transceiver_->SendCommand(command, std::move(parser));
8660 }
8661
SelfTestSync(const TPMI_YES_NO & full_test,AuthorizationDelegate * authorization_delegate)8662 TPM_RC Tpm::SelfTestSync(const TPMI_YES_NO& full_test,
8663 AuthorizationDelegate* authorization_delegate) {
8664 VLOG(1) << __func__;
8665 std::string command;
8666 TPM_RC rc =
8667 SerializeCommand_SelfTest(full_test, &command, authorization_delegate);
8668 if (rc != TPM_RC_SUCCESS) {
8669 return rc;
8670 }
8671 std::string response = transceiver_->SendCommandAndWait(command);
8672 rc = ParseResponse_SelfTest(response, authorization_delegate);
8673 return rc;
8674 }
8675
SerializeCommand_IncrementalSelfTest(const TPML_ALG & to_test,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8676 TPM_RC Tpm::SerializeCommand_IncrementalSelfTest(
8677 const TPML_ALG& to_test,
8678 std::string* serialized_command,
8679 AuthorizationDelegate* authorization_delegate) {
8680 VLOG(3) << __func__;
8681 TPM_RC rc = TPM_RC_SUCCESS;
8682 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8683 UINT32 command_size = 10; // Header size.
8684 std::string handle_section_bytes;
8685 std::string parameter_section_bytes;
8686 TPM_CC command_code = TPM_CC_IncrementalSelfTest;
8687 bool is_command_parameter_encryption_possible = false;
8688 bool is_response_parameter_encryption_possible = false;
8689 std::string command_code_bytes;
8690 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8691 if (rc != TPM_RC_SUCCESS) {
8692 return rc;
8693 }
8694 std::string to_test_bytes;
8695 rc = Serialize_TPML_ALG(to_test, &to_test_bytes);
8696 if (rc != TPM_RC_SUCCESS) {
8697 return rc;
8698 }
8699 std::unique_ptr<crypto::SecureHash> hash(
8700 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8701 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8702 hash->Update(to_test_bytes.data(), to_test_bytes.size());
8703 parameter_section_bytes += to_test_bytes;
8704 command_size += to_test_bytes.size();
8705 std::string command_hash(32, 0);
8706 hash->Finish(std::data(command_hash), command_hash.size());
8707 std::string authorization_section_bytes;
8708 std::string authorization_size_bytes;
8709 if (authorization_delegate) {
8710 if (!authorization_delegate->GetCommandAuthorization(
8711 command_hash, is_command_parameter_encryption_possible,
8712 is_response_parameter_encryption_possible,
8713 &authorization_section_bytes)) {
8714 return TRUNKS_RC_AUTHORIZATION_FAILED;
8715 }
8716 if (!authorization_section_bytes.empty()) {
8717 tag = TPM_ST_SESSIONS;
8718 std::string tmp;
8719 rc = Serialize_UINT32(authorization_section_bytes.size(),
8720 &authorization_size_bytes);
8721 if (rc != TPM_RC_SUCCESS) {
8722 return rc;
8723 }
8724 command_size +=
8725 authorization_size_bytes.size() + authorization_section_bytes.size();
8726 }
8727 }
8728 std::string tag_bytes;
8729 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8730 if (rc != TPM_RC_SUCCESS) {
8731 return rc;
8732 }
8733 std::string command_size_bytes;
8734 rc = Serialize_UINT32(command_size, &command_size_bytes);
8735 if (rc != TPM_RC_SUCCESS) {
8736 return rc;
8737 }
8738 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8739 handle_section_bytes + authorization_size_bytes +
8740 authorization_section_bytes + parameter_section_bytes;
8741 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8742 VLOG(2) << "Command: "
8743 << base::HexEncode(serialized_command->data(),
8744 serialized_command->size());
8745 return TPM_RC_SUCCESS;
8746 }
8747
ParseResponse_IncrementalSelfTest(const std::string & response,TPML_ALG * to_do_list,AuthorizationDelegate * authorization_delegate)8748 TPM_RC Tpm::ParseResponse_IncrementalSelfTest(
8749 const std::string& response,
8750 TPML_ALG* to_do_list,
8751 AuthorizationDelegate* authorization_delegate) {
8752 VLOG(3) << __func__;
8753 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8754 TPM_RC rc = TPM_RC_SUCCESS;
8755 std::string buffer(response);
8756 TPM_ST tag;
8757 std::string tag_bytes;
8758 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8759 if (rc != TPM_RC_SUCCESS) {
8760 return rc;
8761 }
8762 UINT32 response_size;
8763 std::string response_size_bytes;
8764 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8765 if (rc != TPM_RC_SUCCESS) {
8766 return rc;
8767 }
8768 TPM_RC response_code;
8769 std::string response_code_bytes;
8770 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8771 if (rc != TPM_RC_SUCCESS) {
8772 return rc;
8773 }
8774 if (response_size != response.size()) {
8775 return TPM_RC_SIZE;
8776 }
8777 if (response_code != TPM_RC_SUCCESS) {
8778 return response_code;
8779 }
8780 TPM_CC command_code = TPM_CC_IncrementalSelfTest;
8781 std::string command_code_bytes;
8782 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8783 if (rc != TPM_RC_SUCCESS) {
8784 return rc;
8785 }
8786 std::string authorization_section_bytes;
8787 if (tag == TPM_ST_SESSIONS) {
8788 UINT32 parameter_section_size = buffer.size();
8789 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
8790 if (rc != TPM_RC_SUCCESS) {
8791 return rc;
8792 }
8793 if (parameter_section_size > buffer.size()) {
8794 return TPM_RC_INSUFFICIENT;
8795 }
8796 authorization_section_bytes = buffer.substr(parameter_section_size);
8797 // Keep the parameter section in |buffer|.
8798 buffer.erase(parameter_section_size);
8799 }
8800 std::unique_ptr<crypto::SecureHash> hash(
8801 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8802 hash->Update(response_code_bytes.data(), response_code_bytes.size());
8803 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8804 hash->Update(buffer.data(), buffer.size());
8805 std::string response_hash(32, 0);
8806 hash->Finish(std::data(response_hash), response_hash.size());
8807 if (tag == TPM_ST_SESSIONS) {
8808 if (!authorization_delegate)
8809 return TRUNKS_RC_AUTHORIZATION_FAILED;
8810 if (!authorization_delegate->CheckResponseAuthorization(
8811 response_hash, authorization_section_bytes)) {
8812 return TRUNKS_RC_AUTHORIZATION_FAILED;
8813 }
8814 }
8815 std::string to_do_list_bytes;
8816 rc = Parse_TPML_ALG(&buffer, to_do_list, &to_do_list_bytes);
8817 if (rc != TPM_RC_SUCCESS) {
8818 return rc;
8819 }
8820 return TPM_RC_SUCCESS;
8821 }
8822
IncrementalSelfTestErrorCallback(Tpm::IncrementalSelfTestResponse callback,TPM_RC response_code)8823 void IncrementalSelfTestErrorCallback(Tpm::IncrementalSelfTestResponse callback,
8824 TPM_RC response_code) {
8825 VLOG(1) << __func__;
8826 std::move(callback).Run(response_code, TPML_ALG());
8827 }
8828
IncrementalSelfTestResponseParser(Tpm::IncrementalSelfTestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8829 void IncrementalSelfTestResponseParser(
8830 Tpm::IncrementalSelfTestResponse callback,
8831 AuthorizationDelegate* authorization_delegate,
8832 const std::string& response) {
8833 VLOG(1) << __func__;
8834 TPML_ALG to_do_list;
8835 TPM_RC rc = Tpm::ParseResponse_IncrementalSelfTest(response, &to_do_list,
8836 authorization_delegate);
8837 if (rc != TPM_RC_SUCCESS) {
8838 base::OnceCallback<void(TPM_RC)> error_reporter =
8839 base::BindOnce(IncrementalSelfTestErrorCallback, std::move(callback));
8840 std::move(error_reporter).Run(rc);
8841 return;
8842 }
8843 std::move(callback).Run(rc, to_do_list);
8844 }
8845
IncrementalSelfTest(const TPML_ALG & to_test,AuthorizationDelegate * authorization_delegate,IncrementalSelfTestResponse callback)8846 void Tpm::IncrementalSelfTest(const TPML_ALG& to_test,
8847 AuthorizationDelegate* authorization_delegate,
8848 IncrementalSelfTestResponse callback) {
8849 VLOG(1) << __func__;
8850 std::string command;
8851 TPM_RC rc = SerializeCommand_IncrementalSelfTest(to_test, &command,
8852 authorization_delegate);
8853 if (rc != TPM_RC_SUCCESS) {
8854 base::OnceCallback<void(TPM_RC)> error_reporter =
8855 base::BindOnce(IncrementalSelfTestErrorCallback, std::move(callback));
8856 std::move(error_reporter).Run(rc);
8857 return;
8858 }
8859 base::OnceCallback<void(const std::string&)> parser =
8860 base::BindOnce(IncrementalSelfTestResponseParser, std::move(callback),
8861 authorization_delegate);
8862 transceiver_->SendCommand(command, std::move(parser));
8863 }
8864
IncrementalSelfTestSync(const TPML_ALG & to_test,TPML_ALG * to_do_list,AuthorizationDelegate * authorization_delegate)8865 TPM_RC Tpm::IncrementalSelfTestSync(
8866 const TPML_ALG& to_test,
8867 TPML_ALG* to_do_list,
8868 AuthorizationDelegate* authorization_delegate) {
8869 VLOG(1) << __func__;
8870 std::string command;
8871 TPM_RC rc = SerializeCommand_IncrementalSelfTest(to_test, &command,
8872 authorization_delegate);
8873 if (rc != TPM_RC_SUCCESS) {
8874 return rc;
8875 }
8876 std::string response = transceiver_->SendCommandAndWait(command);
8877 rc = ParseResponse_IncrementalSelfTest(response, to_do_list,
8878 authorization_delegate);
8879 return rc;
8880 }
8881
SerializeCommand_GetTestResult(std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8882 TPM_RC Tpm::SerializeCommand_GetTestResult(
8883 std::string* serialized_command,
8884 AuthorizationDelegate* authorization_delegate) {
8885 VLOG(3) << __func__;
8886 TPM_RC rc = TPM_RC_SUCCESS;
8887 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8888 UINT32 command_size = 10; // Header size.
8889 std::string handle_section_bytes;
8890 std::string parameter_section_bytes;
8891 TPM_CC command_code = TPM_CC_GetTestResult;
8892 bool is_command_parameter_encryption_possible = false;
8893 bool is_response_parameter_encryption_possible = true;
8894 std::string command_code_bytes;
8895 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8896 if (rc != TPM_RC_SUCCESS) {
8897 return rc;
8898 }
8899 std::unique_ptr<crypto::SecureHash> hash(
8900 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8901 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8902 std::string command_hash(32, 0);
8903 hash->Finish(std::data(command_hash), command_hash.size());
8904 std::string authorization_section_bytes;
8905 std::string authorization_size_bytes;
8906 if (authorization_delegate) {
8907 if (!authorization_delegate->GetCommandAuthorization(
8908 command_hash, is_command_parameter_encryption_possible,
8909 is_response_parameter_encryption_possible,
8910 &authorization_section_bytes)) {
8911 return TRUNKS_RC_AUTHORIZATION_FAILED;
8912 }
8913 if (!authorization_section_bytes.empty()) {
8914 tag = TPM_ST_SESSIONS;
8915 std::string tmp;
8916 rc = Serialize_UINT32(authorization_section_bytes.size(),
8917 &authorization_size_bytes);
8918 if (rc != TPM_RC_SUCCESS) {
8919 return rc;
8920 }
8921 command_size +=
8922 authorization_size_bytes.size() + authorization_section_bytes.size();
8923 }
8924 }
8925 std::string tag_bytes;
8926 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8927 if (rc != TPM_RC_SUCCESS) {
8928 return rc;
8929 }
8930 std::string command_size_bytes;
8931 rc = Serialize_UINT32(command_size, &command_size_bytes);
8932 if (rc != TPM_RC_SUCCESS) {
8933 return rc;
8934 }
8935 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8936 handle_section_bytes + authorization_size_bytes +
8937 authorization_section_bytes + parameter_section_bytes;
8938 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8939 VLOG(2) << "Command: "
8940 << base::HexEncode(serialized_command->data(),
8941 serialized_command->size());
8942 return TPM_RC_SUCCESS;
8943 }
8944
ParseResponse_GetTestResult(const std::string & response,TPM2B_MAX_BUFFER * out_data,TPM_RC * test_result,AuthorizationDelegate * authorization_delegate)8945 TPM_RC Tpm::ParseResponse_GetTestResult(
8946 const std::string& response,
8947 TPM2B_MAX_BUFFER* out_data,
8948 TPM_RC* test_result,
8949 AuthorizationDelegate* authorization_delegate) {
8950 VLOG(3) << __func__;
8951 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8952 TPM_RC rc = TPM_RC_SUCCESS;
8953 std::string buffer(response);
8954 TPM_ST tag;
8955 std::string tag_bytes;
8956 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8957 if (rc != TPM_RC_SUCCESS) {
8958 return rc;
8959 }
8960 UINT32 response_size;
8961 std::string response_size_bytes;
8962 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8963 if (rc != TPM_RC_SUCCESS) {
8964 return rc;
8965 }
8966 TPM_RC response_code;
8967 std::string response_code_bytes;
8968 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8969 if (rc != TPM_RC_SUCCESS) {
8970 return rc;
8971 }
8972 if (response_size != response.size()) {
8973 return TPM_RC_SIZE;
8974 }
8975 if (response_code != TPM_RC_SUCCESS) {
8976 return response_code;
8977 }
8978 TPM_CC command_code = TPM_CC_GetTestResult;
8979 std::string command_code_bytes;
8980 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8981 if (rc != TPM_RC_SUCCESS) {
8982 return rc;
8983 }
8984 std::string authorization_section_bytes;
8985 if (tag == TPM_ST_SESSIONS) {
8986 UINT32 parameter_section_size = buffer.size();
8987 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
8988 if (rc != TPM_RC_SUCCESS) {
8989 return rc;
8990 }
8991 if (parameter_section_size > buffer.size()) {
8992 return TPM_RC_INSUFFICIENT;
8993 }
8994 authorization_section_bytes = buffer.substr(parameter_section_size);
8995 // Keep the parameter section in |buffer|.
8996 buffer.erase(parameter_section_size);
8997 }
8998 std::unique_ptr<crypto::SecureHash> hash(
8999 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9000 hash->Update(response_code_bytes.data(), response_code_bytes.size());
9001 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9002 hash->Update(buffer.data(), buffer.size());
9003 std::string response_hash(32, 0);
9004 hash->Finish(std::data(response_hash), response_hash.size());
9005 if (tag == TPM_ST_SESSIONS) {
9006 if (!authorization_delegate)
9007 return TRUNKS_RC_AUTHORIZATION_FAILED;
9008 if (!authorization_delegate->CheckResponseAuthorization(
9009 response_hash, authorization_section_bytes)) {
9010 return TRUNKS_RC_AUTHORIZATION_FAILED;
9011 }
9012 }
9013 if (tag == TPM_ST_SESSIONS) {
9014 if (!authorization_delegate)
9015 return TRUNKS_RC_AUTHORIZATION_FAILED;
9016
9017 // Parse the encrypted parameter size.
9018 UINT16 size;
9019 std::string size_buffer = buffer.substr(0, 2);
9020 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9021 return result;
9022 }
9023 if (buffer.size() < 2 + size) {
9024 return TPM_RC_INSUFFICIENT;
9025 }
9026
9027 // Decrypt just the parameter data, not the size.
9028 std::string decrypted_data = buffer.substr(2, size);
9029 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9030 return TRUNKS_RC_ENCRYPTION_FAILED;
9031 }
9032 buffer.replace(2, size, decrypted_data);
9033 }
9034 std::string out_data_bytes;
9035 rc = Parse_TPM2B_MAX_BUFFER(&buffer, out_data, &out_data_bytes);
9036 if (rc != TPM_RC_SUCCESS) {
9037 return rc;
9038 }
9039 std::string test_result_bytes;
9040 rc = Parse_TPM_RC(&buffer, test_result, &test_result_bytes);
9041 if (rc != TPM_RC_SUCCESS) {
9042 return rc;
9043 }
9044 return TPM_RC_SUCCESS;
9045 }
9046
GetTestResultErrorCallback(Tpm::GetTestResultResponse callback,TPM_RC response_code)9047 void GetTestResultErrorCallback(Tpm::GetTestResultResponse callback,
9048 TPM_RC response_code) {
9049 VLOG(1) << __func__;
9050 std::move(callback).Run(response_code, TPM2B_MAX_BUFFER(), TPM_RC());
9051 }
9052
GetTestResultResponseParser(Tpm::GetTestResultResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9053 void GetTestResultResponseParser(Tpm::GetTestResultResponse callback,
9054 AuthorizationDelegate* authorization_delegate,
9055 const std::string& response) {
9056 VLOG(1) << __func__;
9057 TPM2B_MAX_BUFFER out_data;
9058 TPM_RC test_result;
9059 TPM_RC rc = Tpm::ParseResponse_GetTestResult(
9060 response, &out_data, &test_result, authorization_delegate);
9061 if (rc != TPM_RC_SUCCESS) {
9062 base::OnceCallback<void(TPM_RC)> error_reporter =
9063 base::BindOnce(GetTestResultErrorCallback, std::move(callback));
9064 std::move(error_reporter).Run(rc);
9065 return;
9066 }
9067 std::move(callback).Run(rc, out_data, test_result);
9068 }
9069
GetTestResult(AuthorizationDelegate * authorization_delegate,GetTestResultResponse callback)9070 void Tpm::GetTestResult(AuthorizationDelegate* authorization_delegate,
9071 GetTestResultResponse callback) {
9072 VLOG(1) << __func__;
9073 std::string command;
9074 TPM_RC rc = SerializeCommand_GetTestResult(&command, authorization_delegate);
9075 if (rc != TPM_RC_SUCCESS) {
9076 base::OnceCallback<void(TPM_RC)> error_reporter =
9077 base::BindOnce(GetTestResultErrorCallback, std::move(callback));
9078 std::move(error_reporter).Run(rc);
9079 return;
9080 }
9081 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9082 GetTestResultResponseParser, std::move(callback), authorization_delegate);
9083 transceiver_->SendCommand(command, std::move(parser));
9084 }
9085
GetTestResultSync(TPM2B_MAX_BUFFER * out_data,TPM_RC * test_result,AuthorizationDelegate * authorization_delegate)9086 TPM_RC Tpm::GetTestResultSync(TPM2B_MAX_BUFFER* out_data,
9087 TPM_RC* test_result,
9088 AuthorizationDelegate* authorization_delegate) {
9089 VLOG(1) << __func__;
9090 std::string command;
9091 TPM_RC rc = SerializeCommand_GetTestResult(&command, authorization_delegate);
9092 if (rc != TPM_RC_SUCCESS) {
9093 return rc;
9094 }
9095 std::string response = transceiver_->SendCommandAndWait(command);
9096 rc = ParseResponse_GetTestResult(response, out_data, test_result,
9097 authorization_delegate);
9098 return rc;
9099 }
9100
SerializeCommand_StartAuthSession(const TPMI_DH_OBJECT & tpm_key,const std::string & tpm_key_name,const TPMI_DH_ENTITY & bind,const std::string & bind_name,const TPM2B_NONCE & nonce_caller,const TPM2B_ENCRYPTED_SECRET & encrypted_salt,const TPM_SE & session_type,const TPMT_SYM_DEF & symmetric,const TPMI_ALG_HASH & auth_hash,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9101 TPM_RC Tpm::SerializeCommand_StartAuthSession(
9102 const TPMI_DH_OBJECT& tpm_key,
9103 const std::string& tpm_key_name,
9104 const TPMI_DH_ENTITY& bind,
9105 const std::string& bind_name,
9106 const TPM2B_NONCE& nonce_caller,
9107 const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9108 const TPM_SE& session_type,
9109 const TPMT_SYM_DEF& symmetric,
9110 const TPMI_ALG_HASH& auth_hash,
9111 std::string* serialized_command,
9112 AuthorizationDelegate* authorization_delegate) {
9113 VLOG(3) << __func__;
9114 TPM_RC rc = TPM_RC_SUCCESS;
9115 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9116 UINT32 command_size = 10; // Header size.
9117 std::string handle_section_bytes;
9118 std::string parameter_section_bytes;
9119 TPM_CC command_code = TPM_CC_StartAuthSession;
9120 bool is_command_parameter_encryption_possible = true;
9121 bool is_response_parameter_encryption_possible = true;
9122 std::string command_code_bytes;
9123 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9124 if (rc != TPM_RC_SUCCESS) {
9125 return rc;
9126 }
9127 std::string tpm_key_bytes;
9128 rc = Serialize_TPMI_DH_OBJECT(tpm_key, &tpm_key_bytes);
9129 if (rc != TPM_RC_SUCCESS) {
9130 return rc;
9131 }
9132 std::string bind_bytes;
9133 rc = Serialize_TPMI_DH_ENTITY(bind, &bind_bytes);
9134 if (rc != TPM_RC_SUCCESS) {
9135 return rc;
9136 }
9137 std::string nonce_caller_bytes;
9138 rc = Serialize_TPM2B_NONCE(nonce_caller, &nonce_caller_bytes);
9139 if (rc != TPM_RC_SUCCESS) {
9140 return rc;
9141 }
9142 std::string encrypted_salt_bytes;
9143 rc = Serialize_TPM2B_ENCRYPTED_SECRET(encrypted_salt, &encrypted_salt_bytes);
9144 if (rc != TPM_RC_SUCCESS) {
9145 return rc;
9146 }
9147 std::string session_type_bytes;
9148 rc = Serialize_TPM_SE(session_type, &session_type_bytes);
9149 if (rc != TPM_RC_SUCCESS) {
9150 return rc;
9151 }
9152 std::string symmetric_bytes;
9153 rc = Serialize_TPMT_SYM_DEF(symmetric, &symmetric_bytes);
9154 if (rc != TPM_RC_SUCCESS) {
9155 return rc;
9156 }
9157 std::string auth_hash_bytes;
9158 rc = Serialize_TPMI_ALG_HASH(auth_hash, &auth_hash_bytes);
9159 if (rc != TPM_RC_SUCCESS) {
9160 return rc;
9161 }
9162 if (authorization_delegate) {
9163 // Encrypt just the parameter data, not the size.
9164 std::string tmp = nonce_caller_bytes.substr(2);
9165 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9166 return TRUNKS_RC_ENCRYPTION_FAILED;
9167 }
9168 nonce_caller_bytes.replace(2, std::string::npos, tmp);
9169 }
9170 std::unique_ptr<crypto::SecureHash> hash(
9171 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9172 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9173 hash->Update(tpm_key_name.data(), tpm_key_name.size());
9174 handle_section_bytes += tpm_key_bytes;
9175 command_size += tpm_key_bytes.size();
9176 hash->Update(bind_name.data(), bind_name.size());
9177 handle_section_bytes += bind_bytes;
9178 command_size += bind_bytes.size();
9179 hash->Update(nonce_caller_bytes.data(), nonce_caller_bytes.size());
9180 parameter_section_bytes += nonce_caller_bytes;
9181 command_size += nonce_caller_bytes.size();
9182 hash->Update(encrypted_salt_bytes.data(), encrypted_salt_bytes.size());
9183 parameter_section_bytes += encrypted_salt_bytes;
9184 command_size += encrypted_salt_bytes.size();
9185 hash->Update(session_type_bytes.data(), session_type_bytes.size());
9186 parameter_section_bytes += session_type_bytes;
9187 command_size += session_type_bytes.size();
9188 hash->Update(symmetric_bytes.data(), symmetric_bytes.size());
9189 parameter_section_bytes += symmetric_bytes;
9190 command_size += symmetric_bytes.size();
9191 hash->Update(auth_hash_bytes.data(), auth_hash_bytes.size());
9192 parameter_section_bytes += auth_hash_bytes;
9193 command_size += auth_hash_bytes.size();
9194 std::string command_hash(32, 0);
9195 hash->Finish(std::data(command_hash), command_hash.size());
9196 std::string authorization_section_bytes;
9197 std::string authorization_size_bytes;
9198 if (authorization_delegate) {
9199 if (!authorization_delegate->GetCommandAuthorization(
9200 command_hash, is_command_parameter_encryption_possible,
9201 is_response_parameter_encryption_possible,
9202 &authorization_section_bytes)) {
9203 return TRUNKS_RC_AUTHORIZATION_FAILED;
9204 }
9205 if (!authorization_section_bytes.empty()) {
9206 tag = TPM_ST_SESSIONS;
9207 std::string tmp;
9208 rc = Serialize_UINT32(authorization_section_bytes.size(),
9209 &authorization_size_bytes);
9210 if (rc != TPM_RC_SUCCESS) {
9211 return rc;
9212 }
9213 command_size +=
9214 authorization_size_bytes.size() + authorization_section_bytes.size();
9215 }
9216 }
9217 std::string tag_bytes;
9218 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9219 if (rc != TPM_RC_SUCCESS) {
9220 return rc;
9221 }
9222 std::string command_size_bytes;
9223 rc = Serialize_UINT32(command_size, &command_size_bytes);
9224 if (rc != TPM_RC_SUCCESS) {
9225 return rc;
9226 }
9227 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9228 handle_section_bytes + authorization_size_bytes +
9229 authorization_section_bytes + parameter_section_bytes;
9230 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9231 VLOG(2) << "Command: "
9232 << base::HexEncode(serialized_command->data(),
9233 serialized_command->size());
9234 return TPM_RC_SUCCESS;
9235 }
9236
ParseResponse_StartAuthSession(const std::string & response,TPMI_SH_AUTH_SESSION * session_handle,TPM2B_NONCE * nonce_tpm,AuthorizationDelegate * authorization_delegate)9237 TPM_RC Tpm::ParseResponse_StartAuthSession(
9238 const std::string& response,
9239 TPMI_SH_AUTH_SESSION* session_handle,
9240 TPM2B_NONCE* nonce_tpm,
9241 AuthorizationDelegate* authorization_delegate) {
9242 VLOG(3) << __func__;
9243 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9244 TPM_RC rc = TPM_RC_SUCCESS;
9245 std::string buffer(response);
9246 TPM_ST tag;
9247 std::string tag_bytes;
9248 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9249 if (rc != TPM_RC_SUCCESS) {
9250 return rc;
9251 }
9252 UINT32 response_size;
9253 std::string response_size_bytes;
9254 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9255 if (rc != TPM_RC_SUCCESS) {
9256 return rc;
9257 }
9258 TPM_RC response_code;
9259 std::string response_code_bytes;
9260 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9261 if (rc != TPM_RC_SUCCESS) {
9262 return rc;
9263 }
9264 if (response_size != response.size()) {
9265 return TPM_RC_SIZE;
9266 }
9267 if (response_code != TPM_RC_SUCCESS) {
9268 return response_code;
9269 }
9270 std::string session_handle_bytes;
9271 rc = Parse_TPMI_SH_AUTH_SESSION(&buffer, session_handle,
9272 &session_handle_bytes);
9273 if (rc != TPM_RC_SUCCESS) {
9274 return rc;
9275 }
9276 TPM_CC command_code = TPM_CC_StartAuthSession;
9277 std::string command_code_bytes;
9278 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9279 if (rc != TPM_RC_SUCCESS) {
9280 return rc;
9281 }
9282 std::string authorization_section_bytes;
9283 if (tag == TPM_ST_SESSIONS) {
9284 UINT32 parameter_section_size = buffer.size();
9285 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
9286 if (rc != TPM_RC_SUCCESS) {
9287 return rc;
9288 }
9289 if (parameter_section_size > buffer.size()) {
9290 return TPM_RC_INSUFFICIENT;
9291 }
9292 authorization_section_bytes = buffer.substr(parameter_section_size);
9293 // Keep the parameter section in |buffer|.
9294 buffer.erase(parameter_section_size);
9295 }
9296 std::unique_ptr<crypto::SecureHash> hash(
9297 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9298 hash->Update(response_code_bytes.data(), response_code_bytes.size());
9299 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9300 hash->Update(buffer.data(), buffer.size());
9301 std::string response_hash(32, 0);
9302 hash->Finish(std::data(response_hash), response_hash.size());
9303 if (tag == TPM_ST_SESSIONS) {
9304 if (!authorization_delegate)
9305 return TRUNKS_RC_AUTHORIZATION_FAILED;
9306 if (!authorization_delegate->CheckResponseAuthorization(
9307 response_hash, authorization_section_bytes)) {
9308 return TRUNKS_RC_AUTHORIZATION_FAILED;
9309 }
9310 }
9311 if (tag == TPM_ST_SESSIONS) {
9312 if (!authorization_delegate)
9313 return TRUNKS_RC_AUTHORIZATION_FAILED;
9314
9315 // Parse the encrypted parameter size.
9316 UINT16 size;
9317 std::string size_buffer = buffer.substr(0, 2);
9318 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9319 return result;
9320 }
9321 if (buffer.size() < 2 + size) {
9322 return TPM_RC_INSUFFICIENT;
9323 }
9324
9325 // Decrypt just the parameter data, not the size.
9326 std::string decrypted_data = buffer.substr(2, size);
9327 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9328 return TRUNKS_RC_ENCRYPTION_FAILED;
9329 }
9330 buffer.replace(2, size, decrypted_data);
9331 }
9332 std::string nonce_tpm_bytes;
9333 rc = Parse_TPM2B_NONCE(&buffer, nonce_tpm, &nonce_tpm_bytes);
9334 if (rc != TPM_RC_SUCCESS) {
9335 return rc;
9336 }
9337 return TPM_RC_SUCCESS;
9338 }
9339
StartAuthSessionErrorCallback(Tpm::StartAuthSessionResponse callback,TPM_RC response_code)9340 void StartAuthSessionErrorCallback(Tpm::StartAuthSessionResponse callback,
9341 TPM_RC response_code) {
9342 VLOG(1) << __func__;
9343 std::move(callback).Run(response_code, TPMI_SH_AUTH_SESSION(), TPM2B_NONCE());
9344 }
9345
StartAuthSessionResponseParser(Tpm::StartAuthSessionResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9346 void StartAuthSessionResponseParser(
9347 Tpm::StartAuthSessionResponse callback,
9348 AuthorizationDelegate* authorization_delegate,
9349 const std::string& response) {
9350 VLOG(1) << __func__;
9351 TPMI_SH_AUTH_SESSION session_handle;
9352 TPM2B_NONCE nonce_tpm;
9353 TPM_RC rc = Tpm::ParseResponse_StartAuthSession(
9354 response, &session_handle, &nonce_tpm, authorization_delegate);
9355 if (rc != TPM_RC_SUCCESS) {
9356 base::OnceCallback<void(TPM_RC)> error_reporter =
9357 base::BindOnce(StartAuthSessionErrorCallback, std::move(callback));
9358 std::move(error_reporter).Run(rc);
9359 return;
9360 }
9361 std::move(callback).Run(rc, session_handle, nonce_tpm);
9362 }
9363
StartAuthSession(const TPMI_DH_OBJECT & tpm_key,const std::string & tpm_key_name,const TPMI_DH_ENTITY & bind,const std::string & bind_name,const TPM2B_NONCE & nonce_caller,const TPM2B_ENCRYPTED_SECRET & encrypted_salt,const TPM_SE & session_type,const TPMT_SYM_DEF & symmetric,const TPMI_ALG_HASH & auth_hash,AuthorizationDelegate * authorization_delegate,StartAuthSessionResponse callback)9364 void Tpm::StartAuthSession(const TPMI_DH_OBJECT& tpm_key,
9365 const std::string& tpm_key_name,
9366 const TPMI_DH_ENTITY& bind,
9367 const std::string& bind_name,
9368 const TPM2B_NONCE& nonce_caller,
9369 const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9370 const TPM_SE& session_type,
9371 const TPMT_SYM_DEF& symmetric,
9372 const TPMI_ALG_HASH& auth_hash,
9373 AuthorizationDelegate* authorization_delegate,
9374 StartAuthSessionResponse callback) {
9375 VLOG(1) << __func__;
9376 std::string command;
9377 TPM_RC rc = SerializeCommand_StartAuthSession(
9378 tpm_key, tpm_key_name, bind, bind_name, nonce_caller, encrypted_salt,
9379 session_type, symmetric, auth_hash, &command, authorization_delegate);
9380 if (rc != TPM_RC_SUCCESS) {
9381 base::OnceCallback<void(TPM_RC)> error_reporter =
9382 base::BindOnce(StartAuthSessionErrorCallback, std::move(callback));
9383 std::move(error_reporter).Run(rc);
9384 return;
9385 }
9386 base::OnceCallback<void(const std::string&)> parser =
9387 base::BindOnce(StartAuthSessionResponseParser, std::move(callback),
9388 authorization_delegate);
9389 transceiver_->SendCommand(command, std::move(parser));
9390 }
9391
StartAuthSessionSync(const TPMI_DH_OBJECT & tpm_key,const std::string & tpm_key_name,const TPMI_DH_ENTITY & bind,const std::string & bind_name,const TPM2B_NONCE & nonce_caller,const TPM2B_ENCRYPTED_SECRET & encrypted_salt,const TPM_SE & session_type,const TPMT_SYM_DEF & symmetric,const TPMI_ALG_HASH & auth_hash,TPMI_SH_AUTH_SESSION * session_handle,TPM2B_NONCE * nonce_tpm,AuthorizationDelegate * authorization_delegate)9392 TPM_RC Tpm::StartAuthSessionSync(
9393 const TPMI_DH_OBJECT& tpm_key,
9394 const std::string& tpm_key_name,
9395 const TPMI_DH_ENTITY& bind,
9396 const std::string& bind_name,
9397 const TPM2B_NONCE& nonce_caller,
9398 const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9399 const TPM_SE& session_type,
9400 const TPMT_SYM_DEF& symmetric,
9401 const TPMI_ALG_HASH& auth_hash,
9402 TPMI_SH_AUTH_SESSION* session_handle,
9403 TPM2B_NONCE* nonce_tpm,
9404 AuthorizationDelegate* authorization_delegate) {
9405 VLOG(1) << __func__;
9406 std::string command;
9407 TPM_RC rc = SerializeCommand_StartAuthSession(
9408 tpm_key, tpm_key_name, bind, bind_name, nonce_caller, encrypted_salt,
9409 session_type, symmetric, auth_hash, &command, authorization_delegate);
9410 if (rc != TPM_RC_SUCCESS) {
9411 return rc;
9412 }
9413 std::string response = transceiver_->SendCommandAndWait(command);
9414 rc = ParseResponse_StartAuthSession(response, session_handle, nonce_tpm,
9415 authorization_delegate);
9416 return rc;
9417 }
9418
SerializeCommand_PolicyRestart(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9419 TPM_RC Tpm::SerializeCommand_PolicyRestart(
9420 const TPMI_SH_POLICY& session_handle,
9421 const std::string& session_handle_name,
9422 std::string* serialized_command,
9423 AuthorizationDelegate* authorization_delegate) {
9424 VLOG(3) << __func__;
9425 TPM_RC rc = TPM_RC_SUCCESS;
9426 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9427 UINT32 command_size = 10; // Header size.
9428 std::string handle_section_bytes;
9429 std::string parameter_section_bytes;
9430 TPM_CC command_code = TPM_CC_PolicyRestart;
9431 bool is_command_parameter_encryption_possible = false;
9432 bool is_response_parameter_encryption_possible = false;
9433 std::string command_code_bytes;
9434 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9435 if (rc != TPM_RC_SUCCESS) {
9436 return rc;
9437 }
9438 std::string session_handle_bytes;
9439 rc = Serialize_TPMI_SH_POLICY(session_handle, &session_handle_bytes);
9440 if (rc != TPM_RC_SUCCESS) {
9441 return rc;
9442 }
9443 std::unique_ptr<crypto::SecureHash> hash(
9444 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9445 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9446 hash->Update(session_handle_name.data(), session_handle_name.size());
9447 handle_section_bytes += session_handle_bytes;
9448 command_size += session_handle_bytes.size();
9449 std::string command_hash(32, 0);
9450 hash->Finish(std::data(command_hash), command_hash.size());
9451 std::string authorization_section_bytes;
9452 std::string authorization_size_bytes;
9453 if (authorization_delegate) {
9454 if (!authorization_delegate->GetCommandAuthorization(
9455 command_hash, is_command_parameter_encryption_possible,
9456 is_response_parameter_encryption_possible,
9457 &authorization_section_bytes)) {
9458 return TRUNKS_RC_AUTHORIZATION_FAILED;
9459 }
9460 if (!authorization_section_bytes.empty()) {
9461 tag = TPM_ST_SESSIONS;
9462 std::string tmp;
9463 rc = Serialize_UINT32(authorization_section_bytes.size(),
9464 &authorization_size_bytes);
9465 if (rc != TPM_RC_SUCCESS) {
9466 return rc;
9467 }
9468 command_size +=
9469 authorization_size_bytes.size() + authorization_section_bytes.size();
9470 }
9471 }
9472 std::string tag_bytes;
9473 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9474 if (rc != TPM_RC_SUCCESS) {
9475 return rc;
9476 }
9477 std::string command_size_bytes;
9478 rc = Serialize_UINT32(command_size, &command_size_bytes);
9479 if (rc != TPM_RC_SUCCESS) {
9480 return rc;
9481 }
9482 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9483 handle_section_bytes + authorization_size_bytes +
9484 authorization_section_bytes + parameter_section_bytes;
9485 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9486 VLOG(2) << "Command: "
9487 << base::HexEncode(serialized_command->data(),
9488 serialized_command->size());
9489 return TPM_RC_SUCCESS;
9490 }
9491
ParseResponse_PolicyRestart(const std::string & response,AuthorizationDelegate * authorization_delegate)9492 TPM_RC Tpm::ParseResponse_PolicyRestart(
9493 const std::string& response,
9494 AuthorizationDelegate* authorization_delegate) {
9495 VLOG(3) << __func__;
9496 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9497 TPM_RC rc = TPM_RC_SUCCESS;
9498 std::string buffer(response);
9499 TPM_ST tag;
9500 std::string tag_bytes;
9501 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9502 if (rc != TPM_RC_SUCCESS) {
9503 return rc;
9504 }
9505 UINT32 response_size;
9506 std::string response_size_bytes;
9507 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9508 if (rc != TPM_RC_SUCCESS) {
9509 return rc;
9510 }
9511 TPM_RC response_code;
9512 std::string response_code_bytes;
9513 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9514 if (rc != TPM_RC_SUCCESS) {
9515 return rc;
9516 }
9517 if (response_size != response.size()) {
9518 return TPM_RC_SIZE;
9519 }
9520 if (response_code != TPM_RC_SUCCESS) {
9521 return response_code;
9522 }
9523 TPM_CC command_code = TPM_CC_PolicyRestart;
9524 std::string command_code_bytes;
9525 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9526 if (rc != TPM_RC_SUCCESS) {
9527 return rc;
9528 }
9529 std::string authorization_section_bytes;
9530 if (tag == TPM_ST_SESSIONS) {
9531 UINT32 parameter_section_size = buffer.size();
9532 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
9533 if (rc != TPM_RC_SUCCESS) {
9534 return rc;
9535 }
9536 if (parameter_section_size > buffer.size()) {
9537 return TPM_RC_INSUFFICIENT;
9538 }
9539 authorization_section_bytes = buffer.substr(parameter_section_size);
9540 // Keep the parameter section in |buffer|.
9541 buffer.erase(parameter_section_size);
9542 }
9543 std::unique_ptr<crypto::SecureHash> hash(
9544 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9545 hash->Update(response_code_bytes.data(), response_code_bytes.size());
9546 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9547 hash->Update(buffer.data(), buffer.size());
9548 std::string response_hash(32, 0);
9549 hash->Finish(std::data(response_hash), response_hash.size());
9550 if (tag == TPM_ST_SESSIONS) {
9551 if (!authorization_delegate)
9552 return TRUNKS_RC_AUTHORIZATION_FAILED;
9553 if (!authorization_delegate->CheckResponseAuthorization(
9554 response_hash, authorization_section_bytes)) {
9555 return TRUNKS_RC_AUTHORIZATION_FAILED;
9556 }
9557 }
9558 return TPM_RC_SUCCESS;
9559 }
9560
PolicyRestartErrorCallback(Tpm::PolicyRestartResponse callback,TPM_RC response_code)9561 void PolicyRestartErrorCallback(Tpm::PolicyRestartResponse callback,
9562 TPM_RC response_code) {
9563 VLOG(1) << __func__;
9564 std::move(callback).Run(response_code);
9565 }
9566
PolicyRestartResponseParser(Tpm::PolicyRestartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9567 void PolicyRestartResponseParser(Tpm::PolicyRestartResponse callback,
9568 AuthorizationDelegate* authorization_delegate,
9569 const std::string& response) {
9570 VLOG(1) << __func__;
9571 TPM_RC rc =
9572 Tpm::ParseResponse_PolicyRestart(response, authorization_delegate);
9573 if (rc != TPM_RC_SUCCESS) {
9574 base::OnceCallback<void(TPM_RC)> error_reporter =
9575 base::BindOnce(PolicyRestartErrorCallback, std::move(callback));
9576 std::move(error_reporter).Run(rc);
9577 return;
9578 }
9579 std::move(callback).Run(rc);
9580 }
9581
PolicyRestart(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,AuthorizationDelegate * authorization_delegate,PolicyRestartResponse callback)9582 void Tpm::PolicyRestart(const TPMI_SH_POLICY& session_handle,
9583 const std::string& session_handle_name,
9584 AuthorizationDelegate* authorization_delegate,
9585 PolicyRestartResponse callback) {
9586 VLOG(1) << __func__;
9587 std::string command;
9588 TPM_RC rc = SerializeCommand_PolicyRestart(
9589 session_handle, session_handle_name, &command, authorization_delegate);
9590 if (rc != TPM_RC_SUCCESS) {
9591 base::OnceCallback<void(TPM_RC)> error_reporter =
9592 base::BindOnce(PolicyRestartErrorCallback, std::move(callback));
9593 std::move(error_reporter).Run(rc);
9594 return;
9595 }
9596 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9597 PolicyRestartResponseParser, std::move(callback), authorization_delegate);
9598 transceiver_->SendCommand(command, std::move(parser));
9599 }
9600
PolicyRestartSync(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,AuthorizationDelegate * authorization_delegate)9601 TPM_RC Tpm::PolicyRestartSync(const TPMI_SH_POLICY& session_handle,
9602 const std::string& session_handle_name,
9603 AuthorizationDelegate* authorization_delegate) {
9604 VLOG(1) << __func__;
9605 std::string command;
9606 TPM_RC rc = SerializeCommand_PolicyRestart(
9607 session_handle, session_handle_name, &command, authorization_delegate);
9608 if (rc != TPM_RC_SUCCESS) {
9609 return rc;
9610 }
9611 std::string response = transceiver_->SendCommandAndWait(command);
9612 rc = ParseResponse_PolicyRestart(response, authorization_delegate);
9613 return rc;
9614 }
9615
SerializeCommand_Create(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9616 TPM_RC Tpm::SerializeCommand_Create(
9617 const TPMI_DH_OBJECT& parent_handle,
9618 const std::string& parent_handle_name,
9619 const TPM2B_SENSITIVE_CREATE& in_sensitive,
9620 const TPM2B_PUBLIC& in_public,
9621 const TPM2B_DATA& outside_info,
9622 const TPML_PCR_SELECTION& creation_pcr,
9623 std::string* serialized_command,
9624 AuthorizationDelegate* authorization_delegate) {
9625 VLOG(3) << __func__;
9626 TPM_RC rc = TPM_RC_SUCCESS;
9627 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9628 UINT32 command_size = 10; // Header size.
9629 std::string handle_section_bytes;
9630 std::string parameter_section_bytes;
9631 TPM_CC command_code = TPM_CC_Create;
9632 bool is_command_parameter_encryption_possible = true;
9633 bool is_response_parameter_encryption_possible = true;
9634 std::string command_code_bytes;
9635 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9636 if (rc != TPM_RC_SUCCESS) {
9637 return rc;
9638 }
9639 std::string parent_handle_bytes;
9640 rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
9641 if (rc != TPM_RC_SUCCESS) {
9642 return rc;
9643 }
9644 std::string in_sensitive_bytes;
9645 rc = Serialize_TPM2B_SENSITIVE_CREATE(in_sensitive, &in_sensitive_bytes);
9646 if (rc != TPM_RC_SUCCESS) {
9647 return rc;
9648 }
9649 std::string in_public_bytes;
9650 rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
9651 if (rc != TPM_RC_SUCCESS) {
9652 return rc;
9653 }
9654 std::string outside_info_bytes;
9655 rc = Serialize_TPM2B_DATA(outside_info, &outside_info_bytes);
9656 if (rc != TPM_RC_SUCCESS) {
9657 return rc;
9658 }
9659 std::string creation_pcr_bytes;
9660 rc = Serialize_TPML_PCR_SELECTION(creation_pcr, &creation_pcr_bytes);
9661 if (rc != TPM_RC_SUCCESS) {
9662 return rc;
9663 }
9664 if (authorization_delegate) {
9665 // Encrypt just the parameter data, not the size.
9666 std::string tmp = in_sensitive_bytes.substr(2);
9667 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9668 return TRUNKS_RC_ENCRYPTION_FAILED;
9669 }
9670 in_sensitive_bytes.replace(2, std::string::npos, tmp);
9671 }
9672 std::unique_ptr<crypto::SecureHash> hash(
9673 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9674 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9675 hash->Update(parent_handle_name.data(), parent_handle_name.size());
9676 handle_section_bytes += parent_handle_bytes;
9677 command_size += parent_handle_bytes.size();
9678 hash->Update(in_sensitive_bytes.data(), in_sensitive_bytes.size());
9679 parameter_section_bytes += in_sensitive_bytes;
9680 command_size += in_sensitive_bytes.size();
9681 hash->Update(in_public_bytes.data(), in_public_bytes.size());
9682 parameter_section_bytes += in_public_bytes;
9683 command_size += in_public_bytes.size();
9684 hash->Update(outside_info_bytes.data(), outside_info_bytes.size());
9685 parameter_section_bytes += outside_info_bytes;
9686 command_size += outside_info_bytes.size();
9687 hash->Update(creation_pcr_bytes.data(), creation_pcr_bytes.size());
9688 parameter_section_bytes += creation_pcr_bytes;
9689 command_size += creation_pcr_bytes.size();
9690 std::string command_hash(32, 0);
9691 hash->Finish(std::data(command_hash), command_hash.size());
9692 std::string authorization_section_bytes;
9693 std::string authorization_size_bytes;
9694 if (authorization_delegate) {
9695 if (!authorization_delegate->GetCommandAuthorization(
9696 command_hash, is_command_parameter_encryption_possible,
9697 is_response_parameter_encryption_possible,
9698 &authorization_section_bytes)) {
9699 return TRUNKS_RC_AUTHORIZATION_FAILED;
9700 }
9701 if (!authorization_section_bytes.empty()) {
9702 tag = TPM_ST_SESSIONS;
9703 std::string tmp;
9704 rc = Serialize_UINT32(authorization_section_bytes.size(),
9705 &authorization_size_bytes);
9706 if (rc != TPM_RC_SUCCESS) {
9707 return rc;
9708 }
9709 command_size +=
9710 authorization_size_bytes.size() + authorization_section_bytes.size();
9711 }
9712 }
9713 std::string tag_bytes;
9714 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9715 if (rc != TPM_RC_SUCCESS) {
9716 return rc;
9717 }
9718 std::string command_size_bytes;
9719 rc = Serialize_UINT32(command_size, &command_size_bytes);
9720 if (rc != TPM_RC_SUCCESS) {
9721 return rc;
9722 }
9723 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9724 handle_section_bytes + authorization_size_bytes +
9725 authorization_section_bytes + parameter_section_bytes;
9726 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9727 VLOG(2) << "Command: "
9728 << base::HexEncode(serialized_command->data(),
9729 serialized_command->size());
9730 return TPM_RC_SUCCESS;
9731 }
9732
ParseResponse_Create(const std::string & response,TPM2B_PRIVATE * out_private,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,AuthorizationDelegate * authorization_delegate)9733 TPM_RC Tpm::ParseResponse_Create(
9734 const std::string& response,
9735 TPM2B_PRIVATE* out_private,
9736 TPM2B_PUBLIC* out_public,
9737 TPM2B_CREATION_DATA* creation_data,
9738 TPM2B_DIGEST* creation_hash,
9739 TPMT_TK_CREATION* creation_ticket,
9740 AuthorizationDelegate* authorization_delegate) {
9741 VLOG(3) << __func__;
9742 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9743 TPM_RC rc = TPM_RC_SUCCESS;
9744 std::string buffer(response);
9745 TPM_ST tag;
9746 std::string tag_bytes;
9747 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9748 if (rc != TPM_RC_SUCCESS) {
9749 return rc;
9750 }
9751 UINT32 response_size;
9752 std::string response_size_bytes;
9753 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9754 if (rc != TPM_RC_SUCCESS) {
9755 return rc;
9756 }
9757 TPM_RC response_code;
9758 std::string response_code_bytes;
9759 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9760 if (rc != TPM_RC_SUCCESS) {
9761 return rc;
9762 }
9763 if (response_size != response.size()) {
9764 return TPM_RC_SIZE;
9765 }
9766 if (response_code != TPM_RC_SUCCESS) {
9767 return response_code;
9768 }
9769 TPM_CC command_code = TPM_CC_Create;
9770 std::string command_code_bytes;
9771 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9772 if (rc != TPM_RC_SUCCESS) {
9773 return rc;
9774 }
9775 std::string authorization_section_bytes;
9776 if (tag == TPM_ST_SESSIONS) {
9777 UINT32 parameter_section_size = buffer.size();
9778 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
9779 if (rc != TPM_RC_SUCCESS) {
9780 return rc;
9781 }
9782 if (parameter_section_size > buffer.size()) {
9783 return TPM_RC_INSUFFICIENT;
9784 }
9785 authorization_section_bytes = buffer.substr(parameter_section_size);
9786 // Keep the parameter section in |buffer|.
9787 buffer.erase(parameter_section_size);
9788 }
9789 std::unique_ptr<crypto::SecureHash> hash(
9790 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9791 hash->Update(response_code_bytes.data(), response_code_bytes.size());
9792 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9793 hash->Update(buffer.data(), buffer.size());
9794 std::string response_hash(32, 0);
9795 hash->Finish(std::data(response_hash), response_hash.size());
9796 if (tag == TPM_ST_SESSIONS) {
9797 if (!authorization_delegate)
9798 return TRUNKS_RC_AUTHORIZATION_FAILED;
9799 if (!authorization_delegate->CheckResponseAuthorization(
9800 response_hash, authorization_section_bytes)) {
9801 return TRUNKS_RC_AUTHORIZATION_FAILED;
9802 }
9803 }
9804 if (tag == TPM_ST_SESSIONS) {
9805 if (!authorization_delegate)
9806 return TRUNKS_RC_AUTHORIZATION_FAILED;
9807
9808 // Parse the encrypted parameter size.
9809 UINT16 size;
9810 std::string size_buffer = buffer.substr(0, 2);
9811 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9812 return result;
9813 }
9814 if (buffer.size() < 2 + size) {
9815 return TPM_RC_INSUFFICIENT;
9816 }
9817
9818 // Decrypt just the parameter data, not the size.
9819 std::string decrypted_data = buffer.substr(2, size);
9820 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9821 return TRUNKS_RC_ENCRYPTION_FAILED;
9822 }
9823 buffer.replace(2, size, decrypted_data);
9824 }
9825 std::string out_private_bytes;
9826 rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
9827 if (rc != TPM_RC_SUCCESS) {
9828 return rc;
9829 }
9830 std::string out_public_bytes;
9831 rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
9832 if (rc != TPM_RC_SUCCESS) {
9833 return rc;
9834 }
9835 std::string creation_data_bytes;
9836 rc = Parse_TPM2B_CREATION_DATA(&buffer, creation_data, &creation_data_bytes);
9837 if (rc != TPM_RC_SUCCESS) {
9838 return rc;
9839 }
9840 std::string creation_hash_bytes;
9841 rc = Parse_TPM2B_DIGEST(&buffer, creation_hash, &creation_hash_bytes);
9842 if (rc != TPM_RC_SUCCESS) {
9843 return rc;
9844 }
9845 std::string creation_ticket_bytes;
9846 rc = Parse_TPMT_TK_CREATION(&buffer, creation_ticket, &creation_ticket_bytes);
9847 if (rc != TPM_RC_SUCCESS) {
9848 return rc;
9849 }
9850 return TPM_RC_SUCCESS;
9851 }
9852
CreateErrorCallback(Tpm::CreateResponse callback,TPM_RC response_code)9853 void CreateErrorCallback(Tpm::CreateResponse callback, TPM_RC response_code) {
9854 VLOG(1) << __func__;
9855 std::move(callback).Run(response_code, TPM2B_PRIVATE(), TPM2B_PUBLIC(),
9856 TPM2B_CREATION_DATA(), TPM2B_DIGEST(),
9857 TPMT_TK_CREATION());
9858 }
9859
CreateResponseParser(Tpm::CreateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9860 void CreateResponseParser(Tpm::CreateResponse callback,
9861 AuthorizationDelegate* authorization_delegate,
9862 const std::string& response) {
9863 VLOG(1) << __func__;
9864 TPM2B_PRIVATE out_private;
9865 TPM2B_PUBLIC out_public;
9866 TPM2B_CREATION_DATA creation_data;
9867 TPM2B_DIGEST creation_hash;
9868 TPMT_TK_CREATION creation_ticket;
9869 TPM_RC rc = Tpm::ParseResponse_Create(
9870 response, &out_private, &out_public, &creation_data, &creation_hash,
9871 &creation_ticket, authorization_delegate);
9872 if (rc != TPM_RC_SUCCESS) {
9873 base::OnceCallback<void(TPM_RC)> error_reporter =
9874 base::BindOnce(CreateErrorCallback, std::move(callback));
9875 std::move(error_reporter).Run(rc);
9876 return;
9877 }
9878 std::move(callback).Run(rc, out_private, out_public, creation_data,
9879 creation_hash, creation_ticket);
9880 }
9881
Create(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,AuthorizationDelegate * authorization_delegate,CreateResponse callback)9882 void Tpm::Create(const TPMI_DH_OBJECT& parent_handle,
9883 const std::string& parent_handle_name,
9884 const TPM2B_SENSITIVE_CREATE& in_sensitive,
9885 const TPM2B_PUBLIC& in_public,
9886 const TPM2B_DATA& outside_info,
9887 const TPML_PCR_SELECTION& creation_pcr,
9888 AuthorizationDelegate* authorization_delegate,
9889 CreateResponse callback) {
9890 VLOG(1) << __func__;
9891 std::string command;
9892 TPM_RC rc = SerializeCommand_Create(
9893 parent_handle, parent_handle_name, in_sensitive, in_public, outside_info,
9894 creation_pcr, &command, authorization_delegate);
9895 if (rc != TPM_RC_SUCCESS) {
9896 base::OnceCallback<void(TPM_RC)> error_reporter =
9897 base::BindOnce(CreateErrorCallback, std::move(callback));
9898 std::move(error_reporter).Run(rc);
9899 return;
9900 }
9901 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9902 CreateResponseParser, std::move(callback), authorization_delegate);
9903 transceiver_->SendCommand(command, std::move(parser));
9904 }
9905
CreateSync(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,TPM2B_PRIVATE * out_private,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,AuthorizationDelegate * authorization_delegate)9906 TPM_RC Tpm::CreateSync(const TPMI_DH_OBJECT& parent_handle,
9907 const std::string& parent_handle_name,
9908 const TPM2B_SENSITIVE_CREATE& in_sensitive,
9909 const TPM2B_PUBLIC& in_public,
9910 const TPM2B_DATA& outside_info,
9911 const TPML_PCR_SELECTION& creation_pcr,
9912 TPM2B_PRIVATE* out_private,
9913 TPM2B_PUBLIC* out_public,
9914 TPM2B_CREATION_DATA* creation_data,
9915 TPM2B_DIGEST* creation_hash,
9916 TPMT_TK_CREATION* creation_ticket,
9917 AuthorizationDelegate* authorization_delegate) {
9918 VLOG(1) << __func__;
9919 std::string command;
9920 TPM_RC rc = SerializeCommand_Create(
9921 parent_handle, parent_handle_name, in_sensitive, in_public, outside_info,
9922 creation_pcr, &command, authorization_delegate);
9923 if (rc != TPM_RC_SUCCESS) {
9924 return rc;
9925 }
9926 std::string response = transceiver_->SendCommandAndWait(command);
9927 rc = ParseResponse_Create(response, out_private, out_public, creation_data,
9928 creation_hash, creation_ticket,
9929 authorization_delegate);
9930 return rc;
9931 }
9932
SerializeCommand_Load(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_PRIVATE & in_private,const TPM2B_PUBLIC & in_public,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9933 TPM_RC Tpm::SerializeCommand_Load(
9934 const TPMI_DH_OBJECT& parent_handle,
9935 const std::string& parent_handle_name,
9936 const TPM2B_PRIVATE& in_private,
9937 const TPM2B_PUBLIC& in_public,
9938 std::string* serialized_command,
9939 AuthorizationDelegate* authorization_delegate) {
9940 VLOG(3) << __func__;
9941 TPM_RC rc = TPM_RC_SUCCESS;
9942 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9943 UINT32 command_size = 10; // Header size.
9944 std::string handle_section_bytes;
9945 std::string parameter_section_bytes;
9946 TPM_CC command_code = TPM_CC_Load;
9947 bool is_command_parameter_encryption_possible = true;
9948 bool is_response_parameter_encryption_possible = true;
9949 std::string command_code_bytes;
9950 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9951 if (rc != TPM_RC_SUCCESS) {
9952 return rc;
9953 }
9954 std::string parent_handle_bytes;
9955 rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
9956 if (rc != TPM_RC_SUCCESS) {
9957 return rc;
9958 }
9959 std::string in_private_bytes;
9960 rc = Serialize_TPM2B_PRIVATE(in_private, &in_private_bytes);
9961 if (rc != TPM_RC_SUCCESS) {
9962 return rc;
9963 }
9964 std::string in_public_bytes;
9965 rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
9966 if (rc != TPM_RC_SUCCESS) {
9967 return rc;
9968 }
9969 if (authorization_delegate) {
9970 // Encrypt just the parameter data, not the size.
9971 std::string tmp = in_private_bytes.substr(2);
9972 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9973 return TRUNKS_RC_ENCRYPTION_FAILED;
9974 }
9975 in_private_bytes.replace(2, std::string::npos, tmp);
9976 }
9977 std::unique_ptr<crypto::SecureHash> hash(
9978 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9979 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9980 hash->Update(parent_handle_name.data(), parent_handle_name.size());
9981 handle_section_bytes += parent_handle_bytes;
9982 command_size += parent_handle_bytes.size();
9983 hash->Update(in_private_bytes.data(), in_private_bytes.size());
9984 parameter_section_bytes += in_private_bytes;
9985 command_size += in_private_bytes.size();
9986 hash->Update(in_public_bytes.data(), in_public_bytes.size());
9987 parameter_section_bytes += in_public_bytes;
9988 command_size += in_public_bytes.size();
9989 std::string command_hash(32, 0);
9990 hash->Finish(std::data(command_hash), command_hash.size());
9991 std::string authorization_section_bytes;
9992 std::string authorization_size_bytes;
9993 if (authorization_delegate) {
9994 if (!authorization_delegate->GetCommandAuthorization(
9995 command_hash, is_command_parameter_encryption_possible,
9996 is_response_parameter_encryption_possible,
9997 &authorization_section_bytes)) {
9998 return TRUNKS_RC_AUTHORIZATION_FAILED;
9999 }
10000 if (!authorization_section_bytes.empty()) {
10001 tag = TPM_ST_SESSIONS;
10002 std::string tmp;
10003 rc = Serialize_UINT32(authorization_section_bytes.size(),
10004 &authorization_size_bytes);
10005 if (rc != TPM_RC_SUCCESS) {
10006 return rc;
10007 }
10008 command_size +=
10009 authorization_size_bytes.size() + authorization_section_bytes.size();
10010 }
10011 }
10012 std::string tag_bytes;
10013 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10014 if (rc != TPM_RC_SUCCESS) {
10015 return rc;
10016 }
10017 std::string command_size_bytes;
10018 rc = Serialize_UINT32(command_size, &command_size_bytes);
10019 if (rc != TPM_RC_SUCCESS) {
10020 return rc;
10021 }
10022 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10023 handle_section_bytes + authorization_size_bytes +
10024 authorization_section_bytes + parameter_section_bytes;
10025 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10026 VLOG(2) << "Command: "
10027 << base::HexEncode(serialized_command->data(),
10028 serialized_command->size());
10029 return TPM_RC_SUCCESS;
10030 }
10031
ParseResponse_Load(const std::string & response,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10032 TPM_RC Tpm::ParseResponse_Load(const std::string& response,
10033 TPM_HANDLE* object_handle,
10034 TPM2B_NAME* name,
10035 AuthorizationDelegate* authorization_delegate) {
10036 VLOG(3) << __func__;
10037 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10038 TPM_RC rc = TPM_RC_SUCCESS;
10039 std::string buffer(response);
10040 TPM_ST tag;
10041 std::string tag_bytes;
10042 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10043 if (rc != TPM_RC_SUCCESS) {
10044 return rc;
10045 }
10046 UINT32 response_size;
10047 std::string response_size_bytes;
10048 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10049 if (rc != TPM_RC_SUCCESS) {
10050 return rc;
10051 }
10052 TPM_RC response_code;
10053 std::string response_code_bytes;
10054 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10055 if (rc != TPM_RC_SUCCESS) {
10056 return rc;
10057 }
10058 if (response_size != response.size()) {
10059 return TPM_RC_SIZE;
10060 }
10061 if (response_code != TPM_RC_SUCCESS) {
10062 return response_code;
10063 }
10064 std::string object_handle_bytes;
10065 rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
10066 if (rc != TPM_RC_SUCCESS) {
10067 return rc;
10068 }
10069 TPM_CC command_code = TPM_CC_Load;
10070 std::string command_code_bytes;
10071 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10072 if (rc != TPM_RC_SUCCESS) {
10073 return rc;
10074 }
10075 std::string authorization_section_bytes;
10076 if (tag == TPM_ST_SESSIONS) {
10077 UINT32 parameter_section_size = buffer.size();
10078 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
10079 if (rc != TPM_RC_SUCCESS) {
10080 return rc;
10081 }
10082 if (parameter_section_size > buffer.size()) {
10083 return TPM_RC_INSUFFICIENT;
10084 }
10085 authorization_section_bytes = buffer.substr(parameter_section_size);
10086 // Keep the parameter section in |buffer|.
10087 buffer.erase(parameter_section_size);
10088 }
10089 std::unique_ptr<crypto::SecureHash> hash(
10090 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10091 hash->Update(response_code_bytes.data(), response_code_bytes.size());
10092 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10093 hash->Update(buffer.data(), buffer.size());
10094 std::string response_hash(32, 0);
10095 hash->Finish(std::data(response_hash), response_hash.size());
10096 if (tag == TPM_ST_SESSIONS) {
10097 if (!authorization_delegate)
10098 return TRUNKS_RC_AUTHORIZATION_FAILED;
10099 if (!authorization_delegate->CheckResponseAuthorization(
10100 response_hash, authorization_section_bytes)) {
10101 return TRUNKS_RC_AUTHORIZATION_FAILED;
10102 }
10103 }
10104 if (tag == TPM_ST_SESSIONS) {
10105 if (!authorization_delegate)
10106 return TRUNKS_RC_AUTHORIZATION_FAILED;
10107
10108 // Parse the encrypted parameter size.
10109 UINT16 size;
10110 std::string size_buffer = buffer.substr(0, 2);
10111 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10112 return result;
10113 }
10114 if (buffer.size() < 2 + size) {
10115 return TPM_RC_INSUFFICIENT;
10116 }
10117
10118 // Decrypt just the parameter data, not the size.
10119 std::string decrypted_data = buffer.substr(2, size);
10120 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10121 return TRUNKS_RC_ENCRYPTION_FAILED;
10122 }
10123 buffer.replace(2, size, decrypted_data);
10124 }
10125 std::string name_bytes;
10126 rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10127 if (rc != TPM_RC_SUCCESS) {
10128 return rc;
10129 }
10130 return TPM_RC_SUCCESS;
10131 }
10132
LoadErrorCallback(Tpm::LoadResponse callback,TPM_RC response_code)10133 void LoadErrorCallback(Tpm::LoadResponse callback, TPM_RC response_code) {
10134 VLOG(1) << __func__;
10135 std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_NAME());
10136 }
10137
LoadResponseParser(Tpm::LoadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10138 void LoadResponseParser(Tpm::LoadResponse callback,
10139 AuthorizationDelegate* authorization_delegate,
10140 const std::string& response) {
10141 VLOG(1) << __func__;
10142 TPM_HANDLE object_handle;
10143 TPM2B_NAME name;
10144 TPM_RC rc = Tpm::ParseResponse_Load(response, &object_handle, &name,
10145 authorization_delegate);
10146 if (rc != TPM_RC_SUCCESS) {
10147 base::OnceCallback<void(TPM_RC)> error_reporter =
10148 base::BindOnce(LoadErrorCallback, std::move(callback));
10149 std::move(error_reporter).Run(rc);
10150 return;
10151 }
10152 std::move(callback).Run(rc, object_handle, name);
10153 }
10154
Load(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_PRIVATE & in_private,const TPM2B_PUBLIC & in_public,AuthorizationDelegate * authorization_delegate,LoadResponse callback)10155 void Tpm::Load(const TPMI_DH_OBJECT& parent_handle,
10156 const std::string& parent_handle_name,
10157 const TPM2B_PRIVATE& in_private,
10158 const TPM2B_PUBLIC& in_public,
10159 AuthorizationDelegate* authorization_delegate,
10160 LoadResponse callback) {
10161 VLOG(1) << __func__;
10162 std::string command;
10163 TPM_RC rc =
10164 SerializeCommand_Load(parent_handle, parent_handle_name, in_private,
10165 in_public, &command, authorization_delegate);
10166 if (rc != TPM_RC_SUCCESS) {
10167 base::OnceCallback<void(TPM_RC)> error_reporter =
10168 base::BindOnce(LoadErrorCallback, std::move(callback));
10169 std::move(error_reporter).Run(rc);
10170 return;
10171 }
10172 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10173 LoadResponseParser, std::move(callback), authorization_delegate);
10174 transceiver_->SendCommand(command, std::move(parser));
10175 }
10176
LoadSync(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_PRIVATE & in_private,const TPM2B_PUBLIC & in_public,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10177 TPM_RC Tpm::LoadSync(const TPMI_DH_OBJECT& parent_handle,
10178 const std::string& parent_handle_name,
10179 const TPM2B_PRIVATE& in_private,
10180 const TPM2B_PUBLIC& in_public,
10181 TPM_HANDLE* object_handle,
10182 TPM2B_NAME* name,
10183 AuthorizationDelegate* authorization_delegate) {
10184 VLOG(1) << __func__;
10185 std::string command;
10186 TPM_RC rc =
10187 SerializeCommand_Load(parent_handle, parent_handle_name, in_private,
10188 in_public, &command, authorization_delegate);
10189 if (rc != TPM_RC_SUCCESS) {
10190 return rc;
10191 }
10192 std::string response = transceiver_->SendCommandAndWait(command);
10193 rc =
10194 ParseResponse_Load(response, object_handle, name, authorization_delegate);
10195 return rc;
10196 }
10197
SerializeCommand_LoadExternal(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10198 TPM_RC Tpm::SerializeCommand_LoadExternal(
10199 const TPM2B_SENSITIVE& in_private,
10200 const TPM2B_PUBLIC& in_public,
10201 const TPMI_RH_HIERARCHY& hierarchy,
10202 std::string* serialized_command,
10203 AuthorizationDelegate* authorization_delegate) {
10204 VLOG(3) << __func__;
10205 TPM_RC rc = TPM_RC_SUCCESS;
10206 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10207 UINT32 command_size = 10; // Header size.
10208 std::string handle_section_bytes;
10209 std::string parameter_section_bytes;
10210 TPM_CC command_code = TPM_CC_LoadExternal;
10211 bool is_command_parameter_encryption_possible = true;
10212 bool is_response_parameter_encryption_possible = true;
10213 std::string command_code_bytes;
10214 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10215 if (rc != TPM_RC_SUCCESS) {
10216 return rc;
10217 }
10218 std::string in_private_bytes;
10219 rc = Serialize_TPM2B_SENSITIVE(in_private, &in_private_bytes);
10220 if (rc != TPM_RC_SUCCESS) {
10221 return rc;
10222 }
10223 std::string in_public_bytes;
10224 rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
10225 if (rc != TPM_RC_SUCCESS) {
10226 return rc;
10227 }
10228 std::string hierarchy_bytes;
10229 rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
10230 if (rc != TPM_RC_SUCCESS) {
10231 return rc;
10232 }
10233 if (authorization_delegate) {
10234 // Encrypt just the parameter data, not the size.
10235 std::string tmp = in_private_bytes.substr(2);
10236 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10237 return TRUNKS_RC_ENCRYPTION_FAILED;
10238 }
10239 in_private_bytes.replace(2, std::string::npos, tmp);
10240 }
10241 std::unique_ptr<crypto::SecureHash> hash(
10242 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10243 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10244 hash->Update(in_private_bytes.data(), in_private_bytes.size());
10245 parameter_section_bytes += in_private_bytes;
10246 command_size += in_private_bytes.size();
10247 hash->Update(in_public_bytes.data(), in_public_bytes.size());
10248 parameter_section_bytes += in_public_bytes;
10249 command_size += in_public_bytes.size();
10250 hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
10251 parameter_section_bytes += hierarchy_bytes;
10252 command_size += hierarchy_bytes.size();
10253 std::string command_hash(32, 0);
10254 hash->Finish(std::data(command_hash), command_hash.size());
10255 std::string authorization_section_bytes;
10256 std::string authorization_size_bytes;
10257 if (authorization_delegate) {
10258 if (!authorization_delegate->GetCommandAuthorization(
10259 command_hash, is_command_parameter_encryption_possible,
10260 is_response_parameter_encryption_possible,
10261 &authorization_section_bytes)) {
10262 return TRUNKS_RC_AUTHORIZATION_FAILED;
10263 }
10264 if (!authorization_section_bytes.empty()) {
10265 tag = TPM_ST_SESSIONS;
10266 std::string tmp;
10267 rc = Serialize_UINT32(authorization_section_bytes.size(),
10268 &authorization_size_bytes);
10269 if (rc != TPM_RC_SUCCESS) {
10270 return rc;
10271 }
10272 command_size +=
10273 authorization_size_bytes.size() + authorization_section_bytes.size();
10274 }
10275 }
10276 std::string tag_bytes;
10277 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10278 if (rc != TPM_RC_SUCCESS) {
10279 return rc;
10280 }
10281 std::string command_size_bytes;
10282 rc = Serialize_UINT32(command_size, &command_size_bytes);
10283 if (rc != TPM_RC_SUCCESS) {
10284 return rc;
10285 }
10286 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10287 handle_section_bytes + authorization_size_bytes +
10288 authorization_section_bytes + parameter_section_bytes;
10289 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10290 VLOG(2) << "Command: "
10291 << base::HexEncode(serialized_command->data(),
10292 serialized_command->size());
10293 return TPM_RC_SUCCESS;
10294 }
10295
ParseResponse_LoadExternal(const std::string & response,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10296 TPM_RC Tpm::ParseResponse_LoadExternal(
10297 const std::string& response,
10298 TPM_HANDLE* object_handle,
10299 TPM2B_NAME* name,
10300 AuthorizationDelegate* authorization_delegate) {
10301 VLOG(3) << __func__;
10302 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10303 TPM_RC rc = TPM_RC_SUCCESS;
10304 std::string buffer(response);
10305 TPM_ST tag;
10306 std::string tag_bytes;
10307 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10308 if (rc != TPM_RC_SUCCESS) {
10309 return rc;
10310 }
10311 UINT32 response_size;
10312 std::string response_size_bytes;
10313 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10314 if (rc != TPM_RC_SUCCESS) {
10315 return rc;
10316 }
10317 TPM_RC response_code;
10318 std::string response_code_bytes;
10319 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10320 if (rc != TPM_RC_SUCCESS) {
10321 return rc;
10322 }
10323 if (response_size != response.size()) {
10324 return TPM_RC_SIZE;
10325 }
10326 if (response_code != TPM_RC_SUCCESS) {
10327 return response_code;
10328 }
10329 std::string object_handle_bytes;
10330 rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
10331 if (rc != TPM_RC_SUCCESS) {
10332 return rc;
10333 }
10334 TPM_CC command_code = TPM_CC_LoadExternal;
10335 std::string command_code_bytes;
10336 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10337 if (rc != TPM_RC_SUCCESS) {
10338 return rc;
10339 }
10340 std::string authorization_section_bytes;
10341 if (tag == TPM_ST_SESSIONS) {
10342 UINT32 parameter_section_size = buffer.size();
10343 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
10344 if (rc != TPM_RC_SUCCESS) {
10345 return rc;
10346 }
10347 if (parameter_section_size > buffer.size()) {
10348 return TPM_RC_INSUFFICIENT;
10349 }
10350 authorization_section_bytes = buffer.substr(parameter_section_size);
10351 // Keep the parameter section in |buffer|.
10352 buffer.erase(parameter_section_size);
10353 }
10354 std::unique_ptr<crypto::SecureHash> hash(
10355 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10356 hash->Update(response_code_bytes.data(), response_code_bytes.size());
10357 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10358 hash->Update(buffer.data(), buffer.size());
10359 std::string response_hash(32, 0);
10360 hash->Finish(std::data(response_hash), response_hash.size());
10361 if (tag == TPM_ST_SESSIONS) {
10362 if (!authorization_delegate)
10363 return TRUNKS_RC_AUTHORIZATION_FAILED;
10364 if (!authorization_delegate->CheckResponseAuthorization(
10365 response_hash, authorization_section_bytes)) {
10366 return TRUNKS_RC_AUTHORIZATION_FAILED;
10367 }
10368 }
10369 if (tag == TPM_ST_SESSIONS) {
10370 if (!authorization_delegate)
10371 return TRUNKS_RC_AUTHORIZATION_FAILED;
10372
10373 // Parse the encrypted parameter size.
10374 UINT16 size;
10375 std::string size_buffer = buffer.substr(0, 2);
10376 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10377 return result;
10378 }
10379 if (buffer.size() < 2 + size) {
10380 return TPM_RC_INSUFFICIENT;
10381 }
10382
10383 // Decrypt just the parameter data, not the size.
10384 std::string decrypted_data = buffer.substr(2, size);
10385 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10386 return TRUNKS_RC_ENCRYPTION_FAILED;
10387 }
10388 buffer.replace(2, size, decrypted_data);
10389 }
10390 std::string name_bytes;
10391 rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10392 if (rc != TPM_RC_SUCCESS) {
10393 return rc;
10394 }
10395 return TPM_RC_SUCCESS;
10396 }
10397
LoadExternalErrorCallback(Tpm::LoadExternalResponse callback,TPM_RC response_code)10398 void LoadExternalErrorCallback(Tpm::LoadExternalResponse callback,
10399 TPM_RC response_code) {
10400 VLOG(1) << __func__;
10401 std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_NAME());
10402 }
10403
LoadExternalResponseParser(Tpm::LoadExternalResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10404 void LoadExternalResponseParser(Tpm::LoadExternalResponse callback,
10405 AuthorizationDelegate* authorization_delegate,
10406 const std::string& response) {
10407 VLOG(1) << __func__;
10408 TPM_HANDLE object_handle;
10409 TPM2B_NAME name;
10410 TPM_RC rc = Tpm::ParseResponse_LoadExternal(response, &object_handle, &name,
10411 authorization_delegate);
10412 if (rc != TPM_RC_SUCCESS) {
10413 base::OnceCallback<void(TPM_RC)> error_reporter =
10414 base::BindOnce(LoadExternalErrorCallback, std::move(callback));
10415 std::move(error_reporter).Run(rc);
10416 return;
10417 }
10418 std::move(callback).Run(rc, object_handle, name);
10419 }
10420
LoadExternal(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,LoadExternalResponse callback)10421 void Tpm::LoadExternal(const TPM2B_SENSITIVE& in_private,
10422 const TPM2B_PUBLIC& in_public,
10423 const TPMI_RH_HIERARCHY& hierarchy,
10424 AuthorizationDelegate* authorization_delegate,
10425 LoadExternalResponse callback) {
10426 VLOG(1) << __func__;
10427 std::string command;
10428 TPM_RC rc = SerializeCommand_LoadExternal(in_private, in_public, hierarchy,
10429 &command, authorization_delegate);
10430 if (rc != TPM_RC_SUCCESS) {
10431 base::OnceCallback<void(TPM_RC)> error_reporter =
10432 base::BindOnce(LoadExternalErrorCallback, std::move(callback));
10433 std::move(error_reporter).Run(rc);
10434 return;
10435 }
10436 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10437 LoadExternalResponseParser, std::move(callback), authorization_delegate);
10438 transceiver_->SendCommand(command, std::move(parser));
10439 }
10440
LoadExternalSync(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10441 TPM_RC Tpm::LoadExternalSync(const TPM2B_SENSITIVE& in_private,
10442 const TPM2B_PUBLIC& in_public,
10443 const TPMI_RH_HIERARCHY& hierarchy,
10444 TPM_HANDLE* object_handle,
10445 TPM2B_NAME* name,
10446 AuthorizationDelegate* authorization_delegate) {
10447 VLOG(1) << __func__;
10448 std::string command;
10449 TPM_RC rc = SerializeCommand_LoadExternal(in_private, in_public, hierarchy,
10450 &command, authorization_delegate);
10451 if (rc != TPM_RC_SUCCESS) {
10452 return rc;
10453 }
10454 std::string response = transceiver_->SendCommandAndWait(command);
10455 rc = ParseResponse_LoadExternal(response, object_handle, name,
10456 authorization_delegate);
10457 return rc;
10458 }
10459
SerializeCommand_ReadPublic(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10460 TPM_RC Tpm::SerializeCommand_ReadPublic(
10461 const TPMI_DH_OBJECT& object_handle,
10462 const std::string& object_handle_name,
10463 std::string* serialized_command,
10464 AuthorizationDelegate* authorization_delegate) {
10465 VLOG(3) << __func__;
10466 TPM_RC rc = TPM_RC_SUCCESS;
10467 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10468 UINT32 command_size = 10; // Header size.
10469 std::string handle_section_bytes;
10470 std::string parameter_section_bytes;
10471 TPM_CC command_code = TPM_CC_ReadPublic;
10472 bool is_command_parameter_encryption_possible = false;
10473 bool is_response_parameter_encryption_possible = true;
10474 std::string command_code_bytes;
10475 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10476 if (rc != TPM_RC_SUCCESS) {
10477 return rc;
10478 }
10479 std::string object_handle_bytes;
10480 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
10481 if (rc != TPM_RC_SUCCESS) {
10482 return rc;
10483 }
10484 std::unique_ptr<crypto::SecureHash> hash(
10485 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10486 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10487 hash->Update(object_handle_name.data(), object_handle_name.size());
10488 handle_section_bytes += object_handle_bytes;
10489 command_size += object_handle_bytes.size();
10490 std::string command_hash(32, 0);
10491 hash->Finish(std::data(command_hash), command_hash.size());
10492 std::string authorization_section_bytes;
10493 std::string authorization_size_bytes;
10494 if (authorization_delegate) {
10495 if (!authorization_delegate->GetCommandAuthorization(
10496 command_hash, is_command_parameter_encryption_possible,
10497 is_response_parameter_encryption_possible,
10498 &authorization_section_bytes)) {
10499 return TRUNKS_RC_AUTHORIZATION_FAILED;
10500 }
10501 if (!authorization_section_bytes.empty()) {
10502 tag = TPM_ST_SESSIONS;
10503 std::string tmp;
10504 rc = Serialize_UINT32(authorization_section_bytes.size(),
10505 &authorization_size_bytes);
10506 if (rc != TPM_RC_SUCCESS) {
10507 return rc;
10508 }
10509 command_size +=
10510 authorization_size_bytes.size() + authorization_section_bytes.size();
10511 }
10512 }
10513 std::string tag_bytes;
10514 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10515 if (rc != TPM_RC_SUCCESS) {
10516 return rc;
10517 }
10518 std::string command_size_bytes;
10519 rc = Serialize_UINT32(command_size, &command_size_bytes);
10520 if (rc != TPM_RC_SUCCESS) {
10521 return rc;
10522 }
10523 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10524 handle_section_bytes + authorization_size_bytes +
10525 authorization_section_bytes + parameter_section_bytes;
10526 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10527 VLOG(2) << "Command: "
10528 << base::HexEncode(serialized_command->data(),
10529 serialized_command->size());
10530 return TPM_RC_SUCCESS;
10531 }
10532
ParseResponse_ReadPublic(const std::string & response,TPM2B_PUBLIC * out_public,TPM2B_NAME * name,TPM2B_NAME * qualified_name,AuthorizationDelegate * authorization_delegate)10533 TPM_RC Tpm::ParseResponse_ReadPublic(
10534 const std::string& response,
10535 TPM2B_PUBLIC* out_public,
10536 TPM2B_NAME* name,
10537 TPM2B_NAME* qualified_name,
10538 AuthorizationDelegate* authorization_delegate) {
10539 VLOG(3) << __func__;
10540 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10541 TPM_RC rc = TPM_RC_SUCCESS;
10542 std::string buffer(response);
10543 TPM_ST tag;
10544 std::string tag_bytes;
10545 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10546 if (rc != TPM_RC_SUCCESS) {
10547 return rc;
10548 }
10549 UINT32 response_size;
10550 std::string response_size_bytes;
10551 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10552 if (rc != TPM_RC_SUCCESS) {
10553 return rc;
10554 }
10555 TPM_RC response_code;
10556 std::string response_code_bytes;
10557 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10558 if (rc != TPM_RC_SUCCESS) {
10559 return rc;
10560 }
10561 if (response_size != response.size()) {
10562 return TPM_RC_SIZE;
10563 }
10564 if (response_code != TPM_RC_SUCCESS) {
10565 return response_code;
10566 }
10567 TPM_CC command_code = TPM_CC_ReadPublic;
10568 std::string command_code_bytes;
10569 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10570 if (rc != TPM_RC_SUCCESS) {
10571 return rc;
10572 }
10573 std::string authorization_section_bytes;
10574 if (tag == TPM_ST_SESSIONS) {
10575 UINT32 parameter_section_size = buffer.size();
10576 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
10577 if (rc != TPM_RC_SUCCESS) {
10578 return rc;
10579 }
10580 if (parameter_section_size > buffer.size()) {
10581 return TPM_RC_INSUFFICIENT;
10582 }
10583 authorization_section_bytes = buffer.substr(parameter_section_size);
10584 // Keep the parameter section in |buffer|.
10585 buffer.erase(parameter_section_size);
10586 }
10587 std::unique_ptr<crypto::SecureHash> hash(
10588 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10589 hash->Update(response_code_bytes.data(), response_code_bytes.size());
10590 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10591 hash->Update(buffer.data(), buffer.size());
10592 std::string response_hash(32, 0);
10593 hash->Finish(std::data(response_hash), response_hash.size());
10594 if (tag == TPM_ST_SESSIONS) {
10595 if (!authorization_delegate)
10596 return TRUNKS_RC_AUTHORIZATION_FAILED;
10597 if (!authorization_delegate->CheckResponseAuthorization(
10598 response_hash, authorization_section_bytes)) {
10599 return TRUNKS_RC_AUTHORIZATION_FAILED;
10600 }
10601 }
10602 if (tag == TPM_ST_SESSIONS) {
10603 if (!authorization_delegate)
10604 return TRUNKS_RC_AUTHORIZATION_FAILED;
10605
10606 // Parse the encrypted parameter size.
10607 UINT16 size;
10608 std::string size_buffer = buffer.substr(0, 2);
10609 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10610 return result;
10611 }
10612 if (buffer.size() < 2 + size) {
10613 return TPM_RC_INSUFFICIENT;
10614 }
10615
10616 // Decrypt just the parameter data, not the size.
10617 std::string decrypted_data = buffer.substr(2, size);
10618 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10619 return TRUNKS_RC_ENCRYPTION_FAILED;
10620 }
10621 buffer.replace(2, size, decrypted_data);
10622 }
10623 std::string out_public_bytes;
10624 rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
10625 if (rc != TPM_RC_SUCCESS) {
10626 return rc;
10627 }
10628 std::string name_bytes;
10629 rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10630 if (rc != TPM_RC_SUCCESS) {
10631 return rc;
10632 }
10633 std::string qualified_name_bytes;
10634 rc = Parse_TPM2B_NAME(&buffer, qualified_name, &qualified_name_bytes);
10635 if (rc != TPM_RC_SUCCESS) {
10636 return rc;
10637 }
10638 return TPM_RC_SUCCESS;
10639 }
10640
ReadPublicErrorCallback(Tpm::ReadPublicResponse callback,TPM_RC response_code)10641 void ReadPublicErrorCallback(Tpm::ReadPublicResponse callback,
10642 TPM_RC response_code) {
10643 VLOG(1) << __func__;
10644 std::move(callback).Run(response_code, TPM2B_PUBLIC(), TPM2B_NAME(),
10645 TPM2B_NAME());
10646 }
10647
ReadPublicResponseParser(Tpm::ReadPublicResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10648 void ReadPublicResponseParser(Tpm::ReadPublicResponse callback,
10649 AuthorizationDelegate* authorization_delegate,
10650 const std::string& response) {
10651 VLOG(1) << __func__;
10652 TPM2B_PUBLIC out_public;
10653 TPM2B_NAME name;
10654 TPM2B_NAME qualified_name;
10655 TPM_RC rc = Tpm::ParseResponse_ReadPublic(
10656 response, &out_public, &name, &qualified_name, authorization_delegate);
10657 if (rc != TPM_RC_SUCCESS) {
10658 base::OnceCallback<void(TPM_RC)> error_reporter =
10659 base::BindOnce(ReadPublicErrorCallback, std::move(callback));
10660 std::move(error_reporter).Run(rc);
10661 return;
10662 }
10663 std::move(callback).Run(rc, out_public, name, qualified_name);
10664 }
10665
ReadPublic(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,AuthorizationDelegate * authorization_delegate,ReadPublicResponse callback)10666 void Tpm::ReadPublic(const TPMI_DH_OBJECT& object_handle,
10667 const std::string& object_handle_name,
10668 AuthorizationDelegate* authorization_delegate,
10669 ReadPublicResponse callback) {
10670 VLOG(1) << __func__;
10671 std::string command;
10672 TPM_RC rc = SerializeCommand_ReadPublic(object_handle, object_handle_name,
10673 &command, authorization_delegate);
10674 if (rc != TPM_RC_SUCCESS) {
10675 base::OnceCallback<void(TPM_RC)> error_reporter =
10676 base::BindOnce(ReadPublicErrorCallback, std::move(callback));
10677 std::move(error_reporter).Run(rc);
10678 return;
10679 }
10680 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10681 ReadPublicResponseParser, std::move(callback), authorization_delegate);
10682 transceiver_->SendCommand(command, std::move(parser));
10683 }
10684
ReadPublicSync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,TPM2B_PUBLIC * out_public,TPM2B_NAME * name,TPM2B_NAME * qualified_name,AuthorizationDelegate * authorization_delegate)10685 TPM_RC Tpm::ReadPublicSync(const TPMI_DH_OBJECT& object_handle,
10686 const std::string& object_handle_name,
10687 TPM2B_PUBLIC* out_public,
10688 TPM2B_NAME* name,
10689 TPM2B_NAME* qualified_name,
10690 AuthorizationDelegate* authorization_delegate) {
10691 VLOG(1) << __func__;
10692 std::string command;
10693 TPM_RC rc = SerializeCommand_ReadPublic(object_handle, object_handle_name,
10694 &command, authorization_delegate);
10695 if (rc != TPM_RC_SUCCESS) {
10696 return rc;
10697 }
10698 std::string response = transceiver_->SendCommandAndWait(command);
10699 rc = ParseResponse_ReadPublic(response, out_public, name, qualified_name,
10700 authorization_delegate);
10701 return rc;
10702 }
10703
SerializeCommand_ActivateCredential(const TPMI_DH_OBJECT & activate_handle,const std::string & activate_handle_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ID_OBJECT & credential_blob,const TPM2B_ENCRYPTED_SECRET & secret,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10704 TPM_RC Tpm::SerializeCommand_ActivateCredential(
10705 const TPMI_DH_OBJECT& activate_handle,
10706 const std::string& activate_handle_name,
10707 const TPMI_DH_OBJECT& key_handle,
10708 const std::string& key_handle_name,
10709 const TPM2B_ID_OBJECT& credential_blob,
10710 const TPM2B_ENCRYPTED_SECRET& secret,
10711 std::string* serialized_command,
10712 AuthorizationDelegate* authorization_delegate) {
10713 VLOG(3) << __func__;
10714 TPM_RC rc = TPM_RC_SUCCESS;
10715 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10716 UINT32 command_size = 10; // Header size.
10717 std::string handle_section_bytes;
10718 std::string parameter_section_bytes;
10719 TPM_CC command_code = TPM_CC_ActivateCredential;
10720 bool is_command_parameter_encryption_possible = true;
10721 bool is_response_parameter_encryption_possible = true;
10722 std::string command_code_bytes;
10723 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10724 if (rc != TPM_RC_SUCCESS) {
10725 return rc;
10726 }
10727 std::string activate_handle_bytes;
10728 rc = Serialize_TPMI_DH_OBJECT(activate_handle, &activate_handle_bytes);
10729 if (rc != TPM_RC_SUCCESS) {
10730 return rc;
10731 }
10732 std::string key_handle_bytes;
10733 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
10734 if (rc != TPM_RC_SUCCESS) {
10735 return rc;
10736 }
10737 std::string credential_blob_bytes;
10738 rc = Serialize_TPM2B_ID_OBJECT(credential_blob, &credential_blob_bytes);
10739 if (rc != TPM_RC_SUCCESS) {
10740 return rc;
10741 }
10742 std::string secret_bytes;
10743 rc = Serialize_TPM2B_ENCRYPTED_SECRET(secret, &secret_bytes);
10744 if (rc != TPM_RC_SUCCESS) {
10745 return rc;
10746 }
10747 if (authorization_delegate) {
10748 // Encrypt just the parameter data, not the size.
10749 std::string tmp = credential_blob_bytes.substr(2);
10750 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10751 return TRUNKS_RC_ENCRYPTION_FAILED;
10752 }
10753 credential_blob_bytes.replace(2, std::string::npos, tmp);
10754 }
10755 std::unique_ptr<crypto::SecureHash> hash(
10756 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10757 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10758 hash->Update(activate_handle_name.data(), activate_handle_name.size());
10759 handle_section_bytes += activate_handle_bytes;
10760 command_size += activate_handle_bytes.size();
10761 hash->Update(key_handle_name.data(), key_handle_name.size());
10762 handle_section_bytes += key_handle_bytes;
10763 command_size += key_handle_bytes.size();
10764 hash->Update(credential_blob_bytes.data(), credential_blob_bytes.size());
10765 parameter_section_bytes += credential_blob_bytes;
10766 command_size += credential_blob_bytes.size();
10767 hash->Update(secret_bytes.data(), secret_bytes.size());
10768 parameter_section_bytes += secret_bytes;
10769 command_size += secret_bytes.size();
10770 std::string command_hash(32, 0);
10771 hash->Finish(std::data(command_hash), command_hash.size());
10772 std::string authorization_section_bytes;
10773 std::string authorization_size_bytes;
10774 if (authorization_delegate) {
10775 if (!authorization_delegate->GetCommandAuthorization(
10776 command_hash, is_command_parameter_encryption_possible,
10777 is_response_parameter_encryption_possible,
10778 &authorization_section_bytes)) {
10779 return TRUNKS_RC_AUTHORIZATION_FAILED;
10780 }
10781 if (!authorization_section_bytes.empty()) {
10782 tag = TPM_ST_SESSIONS;
10783 std::string tmp;
10784 rc = Serialize_UINT32(authorization_section_bytes.size(),
10785 &authorization_size_bytes);
10786 if (rc != TPM_RC_SUCCESS) {
10787 return rc;
10788 }
10789 command_size +=
10790 authorization_size_bytes.size() + authorization_section_bytes.size();
10791 }
10792 }
10793 std::string tag_bytes;
10794 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10795 if (rc != TPM_RC_SUCCESS) {
10796 return rc;
10797 }
10798 std::string command_size_bytes;
10799 rc = Serialize_UINT32(command_size, &command_size_bytes);
10800 if (rc != TPM_RC_SUCCESS) {
10801 return rc;
10802 }
10803 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10804 handle_section_bytes + authorization_size_bytes +
10805 authorization_section_bytes + parameter_section_bytes;
10806 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10807 VLOG(2) << "Command: "
10808 << base::HexEncode(serialized_command->data(),
10809 serialized_command->size());
10810 return TPM_RC_SUCCESS;
10811 }
10812
ParseResponse_ActivateCredential(const std::string & response,TPM2B_DIGEST * cert_info,AuthorizationDelegate * authorization_delegate)10813 TPM_RC Tpm::ParseResponse_ActivateCredential(
10814 const std::string& response,
10815 TPM2B_DIGEST* cert_info,
10816 AuthorizationDelegate* authorization_delegate) {
10817 VLOG(3) << __func__;
10818 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10819 TPM_RC rc = TPM_RC_SUCCESS;
10820 std::string buffer(response);
10821 TPM_ST tag;
10822 std::string tag_bytes;
10823 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10824 if (rc != TPM_RC_SUCCESS) {
10825 return rc;
10826 }
10827 UINT32 response_size;
10828 std::string response_size_bytes;
10829 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10830 if (rc != TPM_RC_SUCCESS) {
10831 return rc;
10832 }
10833 TPM_RC response_code;
10834 std::string response_code_bytes;
10835 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10836 if (rc != TPM_RC_SUCCESS) {
10837 return rc;
10838 }
10839 if (response_size != response.size()) {
10840 return TPM_RC_SIZE;
10841 }
10842 if (response_code != TPM_RC_SUCCESS) {
10843 return response_code;
10844 }
10845 TPM_CC command_code = TPM_CC_ActivateCredential;
10846 std::string command_code_bytes;
10847 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10848 if (rc != TPM_RC_SUCCESS) {
10849 return rc;
10850 }
10851 std::string authorization_section_bytes;
10852 if (tag == TPM_ST_SESSIONS) {
10853 UINT32 parameter_section_size = buffer.size();
10854 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
10855 if (rc != TPM_RC_SUCCESS) {
10856 return rc;
10857 }
10858 if (parameter_section_size > buffer.size()) {
10859 return TPM_RC_INSUFFICIENT;
10860 }
10861 authorization_section_bytes = buffer.substr(parameter_section_size);
10862 // Keep the parameter section in |buffer|.
10863 buffer.erase(parameter_section_size);
10864 }
10865 std::unique_ptr<crypto::SecureHash> hash(
10866 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10867 hash->Update(response_code_bytes.data(), response_code_bytes.size());
10868 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10869 hash->Update(buffer.data(), buffer.size());
10870 std::string response_hash(32, 0);
10871 hash->Finish(std::data(response_hash), response_hash.size());
10872 if (tag == TPM_ST_SESSIONS) {
10873 if (!authorization_delegate)
10874 return TRUNKS_RC_AUTHORIZATION_FAILED;
10875 if (!authorization_delegate->CheckResponseAuthorization(
10876 response_hash, authorization_section_bytes)) {
10877 return TRUNKS_RC_AUTHORIZATION_FAILED;
10878 }
10879 }
10880 if (tag == TPM_ST_SESSIONS) {
10881 if (!authorization_delegate)
10882 return TRUNKS_RC_AUTHORIZATION_FAILED;
10883
10884 // Parse the encrypted parameter size.
10885 UINT16 size;
10886 std::string size_buffer = buffer.substr(0, 2);
10887 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10888 return result;
10889 }
10890 if (buffer.size() < 2 + size) {
10891 return TPM_RC_INSUFFICIENT;
10892 }
10893
10894 // Decrypt just the parameter data, not the size.
10895 std::string decrypted_data = buffer.substr(2, size);
10896 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10897 return TRUNKS_RC_ENCRYPTION_FAILED;
10898 }
10899 buffer.replace(2, size, decrypted_data);
10900 }
10901 std::string cert_info_bytes;
10902 rc = Parse_TPM2B_DIGEST(&buffer, cert_info, &cert_info_bytes);
10903 if (rc != TPM_RC_SUCCESS) {
10904 return rc;
10905 }
10906 return TPM_RC_SUCCESS;
10907 }
10908
ActivateCredentialErrorCallback(Tpm::ActivateCredentialResponse callback,TPM_RC response_code)10909 void ActivateCredentialErrorCallback(Tpm::ActivateCredentialResponse callback,
10910 TPM_RC response_code) {
10911 VLOG(1) << __func__;
10912 std::move(callback).Run(response_code, TPM2B_DIGEST());
10913 }
10914
ActivateCredentialResponseParser(Tpm::ActivateCredentialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10915 void ActivateCredentialResponseParser(
10916 Tpm::ActivateCredentialResponse callback,
10917 AuthorizationDelegate* authorization_delegate,
10918 const std::string& response) {
10919 VLOG(1) << __func__;
10920 TPM2B_DIGEST cert_info;
10921 TPM_RC rc = Tpm::ParseResponse_ActivateCredential(response, &cert_info,
10922 authorization_delegate);
10923 if (rc != TPM_RC_SUCCESS) {
10924 base::OnceCallback<void(TPM_RC)> error_reporter =
10925 base::BindOnce(ActivateCredentialErrorCallback, std::move(callback));
10926 std::move(error_reporter).Run(rc);
10927 return;
10928 }
10929 std::move(callback).Run(rc, cert_info);
10930 }
10931
ActivateCredential(const TPMI_DH_OBJECT & activate_handle,const std::string & activate_handle_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ID_OBJECT & credential_blob,const TPM2B_ENCRYPTED_SECRET & secret,AuthorizationDelegate * authorization_delegate,ActivateCredentialResponse callback)10932 void Tpm::ActivateCredential(const TPMI_DH_OBJECT& activate_handle,
10933 const std::string& activate_handle_name,
10934 const TPMI_DH_OBJECT& key_handle,
10935 const std::string& key_handle_name,
10936 const TPM2B_ID_OBJECT& credential_blob,
10937 const TPM2B_ENCRYPTED_SECRET& secret,
10938 AuthorizationDelegate* authorization_delegate,
10939 ActivateCredentialResponse callback) {
10940 VLOG(1) << __func__;
10941 std::string command;
10942 TPM_RC rc = SerializeCommand_ActivateCredential(
10943 activate_handle, activate_handle_name, key_handle, key_handle_name,
10944 credential_blob, secret, &command, authorization_delegate);
10945 if (rc != TPM_RC_SUCCESS) {
10946 base::OnceCallback<void(TPM_RC)> error_reporter =
10947 base::BindOnce(ActivateCredentialErrorCallback, std::move(callback));
10948 std::move(error_reporter).Run(rc);
10949 return;
10950 }
10951 base::OnceCallback<void(const std::string&)> parser =
10952 base::BindOnce(ActivateCredentialResponseParser, std::move(callback),
10953 authorization_delegate);
10954 transceiver_->SendCommand(command, std::move(parser));
10955 }
10956
ActivateCredentialSync(const TPMI_DH_OBJECT & activate_handle,const std::string & activate_handle_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ID_OBJECT & credential_blob,const TPM2B_ENCRYPTED_SECRET & secret,TPM2B_DIGEST * cert_info,AuthorizationDelegate * authorization_delegate)10957 TPM_RC Tpm::ActivateCredentialSync(
10958 const TPMI_DH_OBJECT& activate_handle,
10959 const std::string& activate_handle_name,
10960 const TPMI_DH_OBJECT& key_handle,
10961 const std::string& key_handle_name,
10962 const TPM2B_ID_OBJECT& credential_blob,
10963 const TPM2B_ENCRYPTED_SECRET& secret,
10964 TPM2B_DIGEST* cert_info,
10965 AuthorizationDelegate* authorization_delegate) {
10966 VLOG(1) << __func__;
10967 std::string command;
10968 TPM_RC rc = SerializeCommand_ActivateCredential(
10969 activate_handle, activate_handle_name, key_handle, key_handle_name,
10970 credential_blob, secret, &command, authorization_delegate);
10971 if (rc != TPM_RC_SUCCESS) {
10972 return rc;
10973 }
10974 std::string response = transceiver_->SendCommandAndWait(command);
10975 rc = ParseResponse_ActivateCredential(response, cert_info,
10976 authorization_delegate);
10977 return rc;
10978 }
10979
SerializeCommand_MakeCredential(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_DIGEST & credential,const TPM2B_NAME & object_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10980 TPM_RC Tpm::SerializeCommand_MakeCredential(
10981 const TPMI_DH_OBJECT& handle,
10982 const std::string& handle_name,
10983 const TPM2B_DIGEST& credential,
10984 const TPM2B_NAME& object_name,
10985 std::string* serialized_command,
10986 AuthorizationDelegate* authorization_delegate) {
10987 VLOG(3) << __func__;
10988 TPM_RC rc = TPM_RC_SUCCESS;
10989 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10990 UINT32 command_size = 10; // Header size.
10991 std::string handle_section_bytes;
10992 std::string parameter_section_bytes;
10993 TPM_CC command_code = TPM_CC_MakeCredential;
10994 bool is_command_parameter_encryption_possible = true;
10995 bool is_response_parameter_encryption_possible = true;
10996 std::string command_code_bytes;
10997 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10998 if (rc != TPM_RC_SUCCESS) {
10999 return rc;
11000 }
11001 std::string handle_bytes;
11002 rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
11003 if (rc != TPM_RC_SUCCESS) {
11004 return rc;
11005 }
11006 std::string credential_bytes;
11007 rc = Serialize_TPM2B_DIGEST(credential, &credential_bytes);
11008 if (rc != TPM_RC_SUCCESS) {
11009 return rc;
11010 }
11011 std::string object_name_bytes;
11012 rc = Serialize_TPM2B_NAME(object_name, &object_name_bytes);
11013 if (rc != TPM_RC_SUCCESS) {
11014 return rc;
11015 }
11016 if (authorization_delegate) {
11017 // Encrypt just the parameter data, not the size.
11018 std::string tmp = credential_bytes.substr(2);
11019 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11020 return TRUNKS_RC_ENCRYPTION_FAILED;
11021 }
11022 credential_bytes.replace(2, std::string::npos, tmp);
11023 }
11024 std::unique_ptr<crypto::SecureHash> hash(
11025 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11026 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11027 hash->Update(handle_name.data(), handle_name.size());
11028 handle_section_bytes += handle_bytes;
11029 command_size += handle_bytes.size();
11030 hash->Update(credential_bytes.data(), credential_bytes.size());
11031 parameter_section_bytes += credential_bytes;
11032 command_size += credential_bytes.size();
11033 hash->Update(object_name_bytes.data(), object_name_bytes.size());
11034 parameter_section_bytes += object_name_bytes;
11035 command_size += object_name_bytes.size();
11036 std::string command_hash(32, 0);
11037 hash->Finish(std::data(command_hash), command_hash.size());
11038 std::string authorization_section_bytes;
11039 std::string authorization_size_bytes;
11040 if (authorization_delegate) {
11041 if (!authorization_delegate->GetCommandAuthorization(
11042 command_hash, is_command_parameter_encryption_possible,
11043 is_response_parameter_encryption_possible,
11044 &authorization_section_bytes)) {
11045 return TRUNKS_RC_AUTHORIZATION_FAILED;
11046 }
11047 if (!authorization_section_bytes.empty()) {
11048 tag = TPM_ST_SESSIONS;
11049 std::string tmp;
11050 rc = Serialize_UINT32(authorization_section_bytes.size(),
11051 &authorization_size_bytes);
11052 if (rc != TPM_RC_SUCCESS) {
11053 return rc;
11054 }
11055 command_size +=
11056 authorization_size_bytes.size() + authorization_section_bytes.size();
11057 }
11058 }
11059 std::string tag_bytes;
11060 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11061 if (rc != TPM_RC_SUCCESS) {
11062 return rc;
11063 }
11064 std::string command_size_bytes;
11065 rc = Serialize_UINT32(command_size, &command_size_bytes);
11066 if (rc != TPM_RC_SUCCESS) {
11067 return rc;
11068 }
11069 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11070 handle_section_bytes + authorization_size_bytes +
11071 authorization_section_bytes + parameter_section_bytes;
11072 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11073 VLOG(2) << "Command: "
11074 << base::HexEncode(serialized_command->data(),
11075 serialized_command->size());
11076 return TPM_RC_SUCCESS;
11077 }
11078
ParseResponse_MakeCredential(const std::string & response,TPM2B_ID_OBJECT * credential_blob,TPM2B_ENCRYPTED_SECRET * secret,AuthorizationDelegate * authorization_delegate)11079 TPM_RC Tpm::ParseResponse_MakeCredential(
11080 const std::string& response,
11081 TPM2B_ID_OBJECT* credential_blob,
11082 TPM2B_ENCRYPTED_SECRET* secret,
11083 AuthorizationDelegate* authorization_delegate) {
11084 VLOG(3) << __func__;
11085 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11086 TPM_RC rc = TPM_RC_SUCCESS;
11087 std::string buffer(response);
11088 TPM_ST tag;
11089 std::string tag_bytes;
11090 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11091 if (rc != TPM_RC_SUCCESS) {
11092 return rc;
11093 }
11094 UINT32 response_size;
11095 std::string response_size_bytes;
11096 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11097 if (rc != TPM_RC_SUCCESS) {
11098 return rc;
11099 }
11100 TPM_RC response_code;
11101 std::string response_code_bytes;
11102 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11103 if (rc != TPM_RC_SUCCESS) {
11104 return rc;
11105 }
11106 if (response_size != response.size()) {
11107 return TPM_RC_SIZE;
11108 }
11109 if (response_code != TPM_RC_SUCCESS) {
11110 return response_code;
11111 }
11112 TPM_CC command_code = TPM_CC_MakeCredential;
11113 std::string command_code_bytes;
11114 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11115 if (rc != TPM_RC_SUCCESS) {
11116 return rc;
11117 }
11118 std::string authorization_section_bytes;
11119 if (tag == TPM_ST_SESSIONS) {
11120 UINT32 parameter_section_size = buffer.size();
11121 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
11122 if (rc != TPM_RC_SUCCESS) {
11123 return rc;
11124 }
11125 if (parameter_section_size > buffer.size()) {
11126 return TPM_RC_INSUFFICIENT;
11127 }
11128 authorization_section_bytes = buffer.substr(parameter_section_size);
11129 // Keep the parameter section in |buffer|.
11130 buffer.erase(parameter_section_size);
11131 }
11132 std::unique_ptr<crypto::SecureHash> hash(
11133 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11134 hash->Update(response_code_bytes.data(), response_code_bytes.size());
11135 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11136 hash->Update(buffer.data(), buffer.size());
11137 std::string response_hash(32, 0);
11138 hash->Finish(std::data(response_hash), response_hash.size());
11139 if (tag == TPM_ST_SESSIONS) {
11140 if (!authorization_delegate)
11141 return TRUNKS_RC_AUTHORIZATION_FAILED;
11142 if (!authorization_delegate->CheckResponseAuthorization(
11143 response_hash, authorization_section_bytes)) {
11144 return TRUNKS_RC_AUTHORIZATION_FAILED;
11145 }
11146 }
11147 if (tag == TPM_ST_SESSIONS) {
11148 if (!authorization_delegate)
11149 return TRUNKS_RC_AUTHORIZATION_FAILED;
11150
11151 // Parse the encrypted parameter size.
11152 UINT16 size;
11153 std::string size_buffer = buffer.substr(0, 2);
11154 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11155 return result;
11156 }
11157 if (buffer.size() < 2 + size) {
11158 return TPM_RC_INSUFFICIENT;
11159 }
11160
11161 // Decrypt just the parameter data, not the size.
11162 std::string decrypted_data = buffer.substr(2, size);
11163 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11164 return TRUNKS_RC_ENCRYPTION_FAILED;
11165 }
11166 buffer.replace(2, size, decrypted_data);
11167 }
11168 std::string credential_blob_bytes;
11169 rc = Parse_TPM2B_ID_OBJECT(&buffer, credential_blob, &credential_blob_bytes);
11170 if (rc != TPM_RC_SUCCESS) {
11171 return rc;
11172 }
11173 std::string secret_bytes;
11174 rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, secret, &secret_bytes);
11175 if (rc != TPM_RC_SUCCESS) {
11176 return rc;
11177 }
11178 return TPM_RC_SUCCESS;
11179 }
11180
MakeCredentialErrorCallback(Tpm::MakeCredentialResponse callback,TPM_RC response_code)11181 void MakeCredentialErrorCallback(Tpm::MakeCredentialResponse callback,
11182 TPM_RC response_code) {
11183 VLOG(1) << __func__;
11184 std::move(callback).Run(response_code, TPM2B_ID_OBJECT(),
11185 TPM2B_ENCRYPTED_SECRET());
11186 }
11187
MakeCredentialResponseParser(Tpm::MakeCredentialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11188 void MakeCredentialResponseParser(Tpm::MakeCredentialResponse callback,
11189 AuthorizationDelegate* authorization_delegate,
11190 const std::string& response) {
11191 VLOG(1) << __func__;
11192 TPM2B_ID_OBJECT credential_blob;
11193 TPM2B_ENCRYPTED_SECRET secret;
11194 TPM_RC rc = Tpm::ParseResponse_MakeCredential(
11195 response, &credential_blob, &secret, authorization_delegate);
11196 if (rc != TPM_RC_SUCCESS) {
11197 base::OnceCallback<void(TPM_RC)> error_reporter =
11198 base::BindOnce(MakeCredentialErrorCallback, std::move(callback));
11199 std::move(error_reporter).Run(rc);
11200 return;
11201 }
11202 std::move(callback).Run(rc, credential_blob, secret);
11203 }
11204
MakeCredential(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_DIGEST & credential,const TPM2B_NAME & object_name,AuthorizationDelegate * authorization_delegate,MakeCredentialResponse callback)11205 void Tpm::MakeCredential(const TPMI_DH_OBJECT& handle,
11206 const std::string& handle_name,
11207 const TPM2B_DIGEST& credential,
11208 const TPM2B_NAME& object_name,
11209 AuthorizationDelegate* authorization_delegate,
11210 MakeCredentialResponse callback) {
11211 VLOG(1) << __func__;
11212 std::string command;
11213 TPM_RC rc = SerializeCommand_MakeCredential(handle, handle_name, credential,
11214 object_name, &command,
11215 authorization_delegate);
11216 if (rc != TPM_RC_SUCCESS) {
11217 base::OnceCallback<void(TPM_RC)> error_reporter =
11218 base::BindOnce(MakeCredentialErrorCallback, std::move(callback));
11219 std::move(error_reporter).Run(rc);
11220 return;
11221 }
11222 base::OnceCallback<void(const std::string&)> parser =
11223 base::BindOnce(MakeCredentialResponseParser, std::move(callback),
11224 authorization_delegate);
11225 transceiver_->SendCommand(command, std::move(parser));
11226 }
11227
MakeCredentialSync(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_DIGEST & credential,const TPM2B_NAME & object_name,TPM2B_ID_OBJECT * credential_blob,TPM2B_ENCRYPTED_SECRET * secret,AuthorizationDelegate * authorization_delegate)11228 TPM_RC Tpm::MakeCredentialSync(const TPMI_DH_OBJECT& handle,
11229 const std::string& handle_name,
11230 const TPM2B_DIGEST& credential,
11231 const TPM2B_NAME& object_name,
11232 TPM2B_ID_OBJECT* credential_blob,
11233 TPM2B_ENCRYPTED_SECRET* secret,
11234 AuthorizationDelegate* authorization_delegate) {
11235 VLOG(1) << __func__;
11236 std::string command;
11237 TPM_RC rc = SerializeCommand_MakeCredential(handle, handle_name, credential,
11238 object_name, &command,
11239 authorization_delegate);
11240 if (rc != TPM_RC_SUCCESS) {
11241 return rc;
11242 }
11243 std::string response = transceiver_->SendCommandAndWait(command);
11244 rc = ParseResponse_MakeCredential(response, credential_blob, secret,
11245 authorization_delegate);
11246 return rc;
11247 }
11248
SerializeCommand_Unseal(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)11249 TPM_RC Tpm::SerializeCommand_Unseal(
11250 const TPMI_DH_OBJECT& item_handle,
11251 const std::string& item_handle_name,
11252 std::string* serialized_command,
11253 AuthorizationDelegate* authorization_delegate) {
11254 VLOG(3) << __func__;
11255 TPM_RC rc = TPM_RC_SUCCESS;
11256 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11257 UINT32 command_size = 10; // Header size.
11258 std::string handle_section_bytes;
11259 std::string parameter_section_bytes;
11260 TPM_CC command_code = TPM_CC_Unseal;
11261 bool is_command_parameter_encryption_possible = false;
11262 bool is_response_parameter_encryption_possible = true;
11263 std::string command_code_bytes;
11264 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11265 if (rc != TPM_RC_SUCCESS) {
11266 return rc;
11267 }
11268 std::string item_handle_bytes;
11269 rc = Serialize_TPMI_DH_OBJECT(item_handle, &item_handle_bytes);
11270 if (rc != TPM_RC_SUCCESS) {
11271 return rc;
11272 }
11273 std::unique_ptr<crypto::SecureHash> hash(
11274 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11275 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11276 hash->Update(item_handle_name.data(), item_handle_name.size());
11277 handle_section_bytes += item_handle_bytes;
11278 command_size += item_handle_bytes.size();
11279 std::string command_hash(32, 0);
11280 hash->Finish(std::data(command_hash), command_hash.size());
11281 std::string authorization_section_bytes;
11282 std::string authorization_size_bytes;
11283 if (authorization_delegate) {
11284 if (!authorization_delegate->GetCommandAuthorization(
11285 command_hash, is_command_parameter_encryption_possible,
11286 is_response_parameter_encryption_possible,
11287 &authorization_section_bytes)) {
11288 return TRUNKS_RC_AUTHORIZATION_FAILED;
11289 }
11290 if (!authorization_section_bytes.empty()) {
11291 tag = TPM_ST_SESSIONS;
11292 std::string tmp;
11293 rc = Serialize_UINT32(authorization_section_bytes.size(),
11294 &authorization_size_bytes);
11295 if (rc != TPM_RC_SUCCESS) {
11296 return rc;
11297 }
11298 command_size +=
11299 authorization_size_bytes.size() + authorization_section_bytes.size();
11300 }
11301 }
11302 std::string tag_bytes;
11303 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11304 if (rc != TPM_RC_SUCCESS) {
11305 return rc;
11306 }
11307 std::string command_size_bytes;
11308 rc = Serialize_UINT32(command_size, &command_size_bytes);
11309 if (rc != TPM_RC_SUCCESS) {
11310 return rc;
11311 }
11312 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11313 handle_section_bytes + authorization_size_bytes +
11314 authorization_section_bytes + parameter_section_bytes;
11315 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11316 VLOG(2) << "Command: "
11317 << base::HexEncode(serialized_command->data(),
11318 serialized_command->size());
11319 return TPM_RC_SUCCESS;
11320 }
11321
ParseResponse_Unseal(const std::string & response,TPM2B_SENSITIVE_DATA * out_data,AuthorizationDelegate * authorization_delegate)11322 TPM_RC Tpm::ParseResponse_Unseal(
11323 const std::string& response,
11324 TPM2B_SENSITIVE_DATA* out_data,
11325 AuthorizationDelegate* authorization_delegate) {
11326 VLOG(3) << __func__;
11327 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11328 TPM_RC rc = TPM_RC_SUCCESS;
11329 std::string buffer(response);
11330 TPM_ST tag;
11331 std::string tag_bytes;
11332 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11333 if (rc != TPM_RC_SUCCESS) {
11334 return rc;
11335 }
11336 UINT32 response_size;
11337 std::string response_size_bytes;
11338 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11339 if (rc != TPM_RC_SUCCESS) {
11340 return rc;
11341 }
11342 TPM_RC response_code;
11343 std::string response_code_bytes;
11344 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11345 if (rc != TPM_RC_SUCCESS) {
11346 return rc;
11347 }
11348 if (response_size != response.size()) {
11349 return TPM_RC_SIZE;
11350 }
11351 if (response_code != TPM_RC_SUCCESS) {
11352 return response_code;
11353 }
11354 TPM_CC command_code = TPM_CC_Unseal;
11355 std::string command_code_bytes;
11356 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11357 if (rc != TPM_RC_SUCCESS) {
11358 return rc;
11359 }
11360 std::string authorization_section_bytes;
11361 if (tag == TPM_ST_SESSIONS) {
11362 UINT32 parameter_section_size = buffer.size();
11363 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
11364 if (rc != TPM_RC_SUCCESS) {
11365 return rc;
11366 }
11367 if (parameter_section_size > buffer.size()) {
11368 return TPM_RC_INSUFFICIENT;
11369 }
11370 authorization_section_bytes = buffer.substr(parameter_section_size);
11371 // Keep the parameter section in |buffer|.
11372 buffer.erase(parameter_section_size);
11373 }
11374 std::unique_ptr<crypto::SecureHash> hash(
11375 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11376 hash->Update(response_code_bytes.data(), response_code_bytes.size());
11377 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11378 hash->Update(buffer.data(), buffer.size());
11379 std::string response_hash(32, 0);
11380 hash->Finish(std::data(response_hash), response_hash.size());
11381 if (tag == TPM_ST_SESSIONS) {
11382 if (!authorization_delegate)
11383 return TRUNKS_RC_AUTHORIZATION_FAILED;
11384 if (!authorization_delegate->CheckResponseAuthorization(
11385 response_hash, authorization_section_bytes)) {
11386 return TRUNKS_RC_AUTHORIZATION_FAILED;
11387 }
11388 }
11389 if (tag == TPM_ST_SESSIONS) {
11390 if (!authorization_delegate)
11391 return TRUNKS_RC_AUTHORIZATION_FAILED;
11392
11393 // Parse the encrypted parameter size.
11394 UINT16 size;
11395 std::string size_buffer = buffer.substr(0, 2);
11396 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11397 return result;
11398 }
11399 if (buffer.size() < 2 + size) {
11400 return TPM_RC_INSUFFICIENT;
11401 }
11402
11403 // Decrypt just the parameter data, not the size.
11404 std::string decrypted_data = buffer.substr(2, size);
11405 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11406 return TRUNKS_RC_ENCRYPTION_FAILED;
11407 }
11408 buffer.replace(2, size, decrypted_data);
11409 }
11410 std::string out_data_bytes;
11411 rc = Parse_TPM2B_SENSITIVE_DATA(&buffer, out_data, &out_data_bytes);
11412 if (rc != TPM_RC_SUCCESS) {
11413 return rc;
11414 }
11415 return TPM_RC_SUCCESS;
11416 }
11417
UnsealErrorCallback(Tpm::UnsealResponse callback,TPM_RC response_code)11418 void UnsealErrorCallback(Tpm::UnsealResponse callback, TPM_RC response_code) {
11419 VLOG(1) << __func__;
11420 std::move(callback).Run(response_code, TPM2B_SENSITIVE_DATA());
11421 }
11422
UnsealResponseParser(Tpm::UnsealResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11423 void UnsealResponseParser(Tpm::UnsealResponse callback,
11424 AuthorizationDelegate* authorization_delegate,
11425 const std::string& response) {
11426 VLOG(1) << __func__;
11427 TPM2B_SENSITIVE_DATA out_data;
11428 TPM_RC rc =
11429 Tpm::ParseResponse_Unseal(response, &out_data, authorization_delegate);
11430 if (rc != TPM_RC_SUCCESS) {
11431 base::OnceCallback<void(TPM_RC)> error_reporter =
11432 base::BindOnce(UnsealErrorCallback, std::move(callback));
11433 std::move(error_reporter).Run(rc);
11434 return;
11435 }
11436 std::move(callback).Run(rc, out_data);
11437 }
11438
Unseal(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,AuthorizationDelegate * authorization_delegate,UnsealResponse callback)11439 void Tpm::Unseal(const TPMI_DH_OBJECT& item_handle,
11440 const std::string& item_handle_name,
11441 AuthorizationDelegate* authorization_delegate,
11442 UnsealResponse callback) {
11443 VLOG(1) << __func__;
11444 std::string command;
11445 TPM_RC rc = SerializeCommand_Unseal(item_handle, item_handle_name, &command,
11446 authorization_delegate);
11447 if (rc != TPM_RC_SUCCESS) {
11448 base::OnceCallback<void(TPM_RC)> error_reporter =
11449 base::BindOnce(UnsealErrorCallback, std::move(callback));
11450 std::move(error_reporter).Run(rc);
11451 return;
11452 }
11453 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
11454 UnsealResponseParser, std::move(callback), authorization_delegate);
11455 transceiver_->SendCommand(command, std::move(parser));
11456 }
11457
UnsealSync(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,TPM2B_SENSITIVE_DATA * out_data,AuthorizationDelegate * authorization_delegate)11458 TPM_RC Tpm::UnsealSync(const TPMI_DH_OBJECT& item_handle,
11459 const std::string& item_handle_name,
11460 TPM2B_SENSITIVE_DATA* out_data,
11461 AuthorizationDelegate* authorization_delegate) {
11462 VLOG(1) << __func__;
11463 std::string command;
11464 TPM_RC rc = SerializeCommand_Unseal(item_handle, item_handle_name, &command,
11465 authorization_delegate);
11466 if (rc != TPM_RC_SUCCESS) {
11467 return rc;
11468 }
11469 std::string response = transceiver_->SendCommandAndWait(command);
11470 rc = ParseResponse_Unseal(response, out_data, authorization_delegate);
11471 return rc;
11472 }
11473
SerializeCommand_ObjectChangeAuth(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_AUTH & new_auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)11474 TPM_RC Tpm::SerializeCommand_ObjectChangeAuth(
11475 const TPMI_DH_OBJECT& object_handle,
11476 const std::string& object_handle_name,
11477 const TPMI_DH_OBJECT& parent_handle,
11478 const std::string& parent_handle_name,
11479 const TPM2B_AUTH& new_auth,
11480 std::string* serialized_command,
11481 AuthorizationDelegate* authorization_delegate) {
11482 VLOG(3) << __func__;
11483 TPM_RC rc = TPM_RC_SUCCESS;
11484 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11485 UINT32 command_size = 10; // Header size.
11486 std::string handle_section_bytes;
11487 std::string parameter_section_bytes;
11488 TPM_CC command_code = TPM_CC_ObjectChangeAuth;
11489 bool is_command_parameter_encryption_possible = true;
11490 bool is_response_parameter_encryption_possible = true;
11491 std::string command_code_bytes;
11492 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11493 if (rc != TPM_RC_SUCCESS) {
11494 return rc;
11495 }
11496 std::string object_handle_bytes;
11497 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
11498 if (rc != TPM_RC_SUCCESS) {
11499 return rc;
11500 }
11501 std::string parent_handle_bytes;
11502 rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
11503 if (rc != TPM_RC_SUCCESS) {
11504 return rc;
11505 }
11506 std::string new_auth_bytes;
11507 rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
11508 if (rc != TPM_RC_SUCCESS) {
11509 return rc;
11510 }
11511 if (authorization_delegate) {
11512 // Encrypt just the parameter data, not the size.
11513 std::string tmp = new_auth_bytes.substr(2);
11514 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11515 return TRUNKS_RC_ENCRYPTION_FAILED;
11516 }
11517 new_auth_bytes.replace(2, std::string::npos, tmp);
11518 }
11519 std::unique_ptr<crypto::SecureHash> hash(
11520 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11521 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11522 hash->Update(object_handle_name.data(), object_handle_name.size());
11523 handle_section_bytes += object_handle_bytes;
11524 command_size += object_handle_bytes.size();
11525 hash->Update(parent_handle_name.data(), parent_handle_name.size());
11526 handle_section_bytes += parent_handle_bytes;
11527 command_size += parent_handle_bytes.size();
11528 hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
11529 parameter_section_bytes += new_auth_bytes;
11530 command_size += new_auth_bytes.size();
11531 std::string command_hash(32, 0);
11532 hash->Finish(std::data(command_hash), command_hash.size());
11533 std::string authorization_section_bytes;
11534 std::string authorization_size_bytes;
11535 if (authorization_delegate) {
11536 if (!authorization_delegate->GetCommandAuthorization(
11537 command_hash, is_command_parameter_encryption_possible,
11538 is_response_parameter_encryption_possible,
11539 &authorization_section_bytes)) {
11540 return TRUNKS_RC_AUTHORIZATION_FAILED;
11541 }
11542 if (!authorization_section_bytes.empty()) {
11543 tag = TPM_ST_SESSIONS;
11544 std::string tmp;
11545 rc = Serialize_UINT32(authorization_section_bytes.size(),
11546 &authorization_size_bytes);
11547 if (rc != TPM_RC_SUCCESS) {
11548 return rc;
11549 }
11550 command_size +=
11551 authorization_size_bytes.size() + authorization_section_bytes.size();
11552 }
11553 }
11554 std::string tag_bytes;
11555 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11556 if (rc != TPM_RC_SUCCESS) {
11557 return rc;
11558 }
11559 std::string command_size_bytes;
11560 rc = Serialize_UINT32(command_size, &command_size_bytes);
11561 if (rc != TPM_RC_SUCCESS) {
11562 return rc;
11563 }
11564 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11565 handle_section_bytes + authorization_size_bytes +
11566 authorization_section_bytes + parameter_section_bytes;
11567 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11568 VLOG(2) << "Command: "
11569 << base::HexEncode(serialized_command->data(),
11570 serialized_command->size());
11571 return TPM_RC_SUCCESS;
11572 }
11573
ParseResponse_ObjectChangeAuth(const std::string & response,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)11574 TPM_RC Tpm::ParseResponse_ObjectChangeAuth(
11575 const std::string& response,
11576 TPM2B_PRIVATE* out_private,
11577 AuthorizationDelegate* authorization_delegate) {
11578 VLOG(3) << __func__;
11579 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11580 TPM_RC rc = TPM_RC_SUCCESS;
11581 std::string buffer(response);
11582 TPM_ST tag;
11583 std::string tag_bytes;
11584 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11585 if (rc != TPM_RC_SUCCESS) {
11586 return rc;
11587 }
11588 UINT32 response_size;
11589 std::string response_size_bytes;
11590 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11591 if (rc != TPM_RC_SUCCESS) {
11592 return rc;
11593 }
11594 TPM_RC response_code;
11595 std::string response_code_bytes;
11596 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11597 if (rc != TPM_RC_SUCCESS) {
11598 return rc;
11599 }
11600 if (response_size != response.size()) {
11601 return TPM_RC_SIZE;
11602 }
11603 if (response_code != TPM_RC_SUCCESS) {
11604 return response_code;
11605 }
11606 TPM_CC command_code = TPM_CC_ObjectChangeAuth;
11607 std::string command_code_bytes;
11608 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11609 if (rc != TPM_RC_SUCCESS) {
11610 return rc;
11611 }
11612 std::string authorization_section_bytes;
11613 if (tag == TPM_ST_SESSIONS) {
11614 UINT32 parameter_section_size = buffer.size();
11615 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
11616 if (rc != TPM_RC_SUCCESS) {
11617 return rc;
11618 }
11619 if (parameter_section_size > buffer.size()) {
11620 return TPM_RC_INSUFFICIENT;
11621 }
11622 authorization_section_bytes = buffer.substr(parameter_section_size);
11623 // Keep the parameter section in |buffer|.
11624 buffer.erase(parameter_section_size);
11625 }
11626 std::unique_ptr<crypto::SecureHash> hash(
11627 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11628 hash->Update(response_code_bytes.data(), response_code_bytes.size());
11629 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11630 hash->Update(buffer.data(), buffer.size());
11631 std::string response_hash(32, 0);
11632 hash->Finish(std::data(response_hash), response_hash.size());
11633 if (tag == TPM_ST_SESSIONS) {
11634 if (!authorization_delegate)
11635 return TRUNKS_RC_AUTHORIZATION_FAILED;
11636 if (!authorization_delegate->CheckResponseAuthorization(
11637 response_hash, authorization_section_bytes)) {
11638 return TRUNKS_RC_AUTHORIZATION_FAILED;
11639 }
11640 }
11641 if (tag == TPM_ST_SESSIONS) {
11642 if (!authorization_delegate)
11643 return TRUNKS_RC_AUTHORIZATION_FAILED;
11644
11645 // Parse the encrypted parameter size.
11646 UINT16 size;
11647 std::string size_buffer = buffer.substr(0, 2);
11648 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11649 return result;
11650 }
11651 if (buffer.size() < 2 + size) {
11652 return TPM_RC_INSUFFICIENT;
11653 }
11654
11655 // Decrypt just the parameter data, not the size.
11656 std::string decrypted_data = buffer.substr(2, size);
11657 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11658 return TRUNKS_RC_ENCRYPTION_FAILED;
11659 }
11660 buffer.replace(2, size, decrypted_data);
11661 }
11662 std::string out_private_bytes;
11663 rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
11664 if (rc != TPM_RC_SUCCESS) {
11665 return rc;
11666 }
11667 return TPM_RC_SUCCESS;
11668 }
11669
ObjectChangeAuthErrorCallback(Tpm::ObjectChangeAuthResponse callback,TPM_RC response_code)11670 void ObjectChangeAuthErrorCallback(Tpm::ObjectChangeAuthResponse callback,
11671 TPM_RC response_code) {
11672 VLOG(1) << __func__;
11673 std::move(callback).Run(response_code, TPM2B_PRIVATE());
11674 }
11675
ObjectChangeAuthResponseParser(Tpm::ObjectChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11676 void ObjectChangeAuthResponseParser(
11677 Tpm::ObjectChangeAuthResponse callback,
11678 AuthorizationDelegate* authorization_delegate,
11679 const std::string& response) {
11680 VLOG(1) << __func__;
11681 TPM2B_PRIVATE out_private;
11682 TPM_RC rc = Tpm::ParseResponse_ObjectChangeAuth(response, &out_private,
11683 authorization_delegate);
11684 if (rc != TPM_RC_SUCCESS) {
11685 base::OnceCallback<void(TPM_RC)> error_reporter =
11686 base::BindOnce(ObjectChangeAuthErrorCallback, std::move(callback));
11687 std::move(error_reporter).Run(rc);
11688 return;
11689 }
11690 std::move(callback).Run(rc, out_private);
11691 }
11692
ObjectChangeAuth(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate,ObjectChangeAuthResponse callback)11693 void Tpm::ObjectChangeAuth(const TPMI_DH_OBJECT& object_handle,
11694 const std::string& object_handle_name,
11695 const TPMI_DH_OBJECT& parent_handle,
11696 const std::string& parent_handle_name,
11697 const TPM2B_AUTH& new_auth,
11698 AuthorizationDelegate* authorization_delegate,
11699 ObjectChangeAuthResponse callback) {
11700 VLOG(1) << __func__;
11701 std::string command;
11702 TPM_RC rc = SerializeCommand_ObjectChangeAuth(
11703 object_handle, object_handle_name, parent_handle, parent_handle_name,
11704 new_auth, &command, authorization_delegate);
11705 if (rc != TPM_RC_SUCCESS) {
11706 base::OnceCallback<void(TPM_RC)> error_reporter =
11707 base::BindOnce(ObjectChangeAuthErrorCallback, std::move(callback));
11708 std::move(error_reporter).Run(rc);
11709 return;
11710 }
11711 base::OnceCallback<void(const std::string&)> parser =
11712 base::BindOnce(ObjectChangeAuthResponseParser, std::move(callback),
11713 authorization_delegate);
11714 transceiver_->SendCommand(command, std::move(parser));
11715 }
11716
ObjectChangeAuthSync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_AUTH & new_auth,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)11717 TPM_RC Tpm::ObjectChangeAuthSync(
11718 const TPMI_DH_OBJECT& object_handle,
11719 const std::string& object_handle_name,
11720 const TPMI_DH_OBJECT& parent_handle,
11721 const std::string& parent_handle_name,
11722 const TPM2B_AUTH& new_auth,
11723 TPM2B_PRIVATE* out_private,
11724 AuthorizationDelegate* authorization_delegate) {
11725 VLOG(1) << __func__;
11726 std::string command;
11727 TPM_RC rc = SerializeCommand_ObjectChangeAuth(
11728 object_handle, object_handle_name, parent_handle, parent_handle_name,
11729 new_auth, &command, authorization_delegate);
11730 if (rc != TPM_RC_SUCCESS) {
11731 return rc;
11732 }
11733 std::string response = transceiver_->SendCommandAndWait(command);
11734 rc = ParseResponse_ObjectChangeAuth(response, out_private,
11735 authorization_delegate);
11736 return rc;
11737 }
11738
SerializeCommand_Duplicate(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & new_parent_handle,const std::string & new_parent_handle_name,const TPM2B_DATA & encryption_key_in,const TPMT_SYM_DEF_OBJECT & symmetric_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)11739 TPM_RC Tpm::SerializeCommand_Duplicate(
11740 const TPMI_DH_OBJECT& object_handle,
11741 const std::string& object_handle_name,
11742 const TPMI_DH_OBJECT& new_parent_handle,
11743 const std::string& new_parent_handle_name,
11744 const TPM2B_DATA& encryption_key_in,
11745 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11746 std::string* serialized_command,
11747 AuthorizationDelegate* authorization_delegate) {
11748 VLOG(3) << __func__;
11749 TPM_RC rc = TPM_RC_SUCCESS;
11750 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11751 UINT32 command_size = 10; // Header size.
11752 std::string handle_section_bytes;
11753 std::string parameter_section_bytes;
11754 TPM_CC command_code = TPM_CC_Duplicate;
11755 bool is_command_parameter_encryption_possible = true;
11756 bool is_response_parameter_encryption_possible = true;
11757 std::string command_code_bytes;
11758 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11759 if (rc != TPM_RC_SUCCESS) {
11760 return rc;
11761 }
11762 std::string object_handle_bytes;
11763 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
11764 if (rc != TPM_RC_SUCCESS) {
11765 return rc;
11766 }
11767 std::string new_parent_handle_bytes;
11768 rc = Serialize_TPMI_DH_OBJECT(new_parent_handle, &new_parent_handle_bytes);
11769 if (rc != TPM_RC_SUCCESS) {
11770 return rc;
11771 }
11772 std::string encryption_key_in_bytes;
11773 rc = Serialize_TPM2B_DATA(encryption_key_in, &encryption_key_in_bytes);
11774 if (rc != TPM_RC_SUCCESS) {
11775 return rc;
11776 }
11777 std::string symmetric_alg_bytes;
11778 rc = Serialize_TPMT_SYM_DEF_OBJECT(symmetric_alg, &symmetric_alg_bytes);
11779 if (rc != TPM_RC_SUCCESS) {
11780 return rc;
11781 }
11782 if (authorization_delegate) {
11783 // Encrypt just the parameter data, not the size.
11784 std::string tmp = encryption_key_in_bytes.substr(2);
11785 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11786 return TRUNKS_RC_ENCRYPTION_FAILED;
11787 }
11788 encryption_key_in_bytes.replace(2, std::string::npos, tmp);
11789 }
11790 std::unique_ptr<crypto::SecureHash> hash(
11791 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11792 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11793 hash->Update(object_handle_name.data(), object_handle_name.size());
11794 handle_section_bytes += object_handle_bytes;
11795 command_size += object_handle_bytes.size();
11796 hash->Update(new_parent_handle_name.data(), new_parent_handle_name.size());
11797 handle_section_bytes += new_parent_handle_bytes;
11798 command_size += new_parent_handle_bytes.size();
11799 hash->Update(encryption_key_in_bytes.data(), encryption_key_in_bytes.size());
11800 parameter_section_bytes += encryption_key_in_bytes;
11801 command_size += encryption_key_in_bytes.size();
11802 hash->Update(symmetric_alg_bytes.data(), symmetric_alg_bytes.size());
11803 parameter_section_bytes += symmetric_alg_bytes;
11804 command_size += symmetric_alg_bytes.size();
11805 std::string command_hash(32, 0);
11806 hash->Finish(std::data(command_hash), command_hash.size());
11807 std::string authorization_section_bytes;
11808 std::string authorization_size_bytes;
11809 if (authorization_delegate) {
11810 if (!authorization_delegate->GetCommandAuthorization(
11811 command_hash, is_command_parameter_encryption_possible,
11812 is_response_parameter_encryption_possible,
11813 &authorization_section_bytes)) {
11814 return TRUNKS_RC_AUTHORIZATION_FAILED;
11815 }
11816 if (!authorization_section_bytes.empty()) {
11817 tag = TPM_ST_SESSIONS;
11818 std::string tmp;
11819 rc = Serialize_UINT32(authorization_section_bytes.size(),
11820 &authorization_size_bytes);
11821 if (rc != TPM_RC_SUCCESS) {
11822 return rc;
11823 }
11824 command_size +=
11825 authorization_size_bytes.size() + authorization_section_bytes.size();
11826 }
11827 }
11828 std::string tag_bytes;
11829 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11830 if (rc != TPM_RC_SUCCESS) {
11831 return rc;
11832 }
11833 std::string command_size_bytes;
11834 rc = Serialize_UINT32(command_size, &command_size_bytes);
11835 if (rc != TPM_RC_SUCCESS) {
11836 return rc;
11837 }
11838 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11839 handle_section_bytes + authorization_size_bytes +
11840 authorization_section_bytes + parameter_section_bytes;
11841 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11842 VLOG(2) << "Command: "
11843 << base::HexEncode(serialized_command->data(),
11844 serialized_command->size());
11845 return TPM_RC_SUCCESS;
11846 }
11847
ParseResponse_Duplicate(const std::string & response,TPM2B_DATA * encryption_key_out,TPM2B_PRIVATE * duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)11848 TPM_RC Tpm::ParseResponse_Duplicate(
11849 const std::string& response,
11850 TPM2B_DATA* encryption_key_out,
11851 TPM2B_PRIVATE* duplicate,
11852 TPM2B_ENCRYPTED_SECRET* out_sym_seed,
11853 AuthorizationDelegate* authorization_delegate) {
11854 VLOG(3) << __func__;
11855 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11856 TPM_RC rc = TPM_RC_SUCCESS;
11857 std::string buffer(response);
11858 TPM_ST tag;
11859 std::string tag_bytes;
11860 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11861 if (rc != TPM_RC_SUCCESS) {
11862 return rc;
11863 }
11864 UINT32 response_size;
11865 std::string response_size_bytes;
11866 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11867 if (rc != TPM_RC_SUCCESS) {
11868 return rc;
11869 }
11870 TPM_RC response_code;
11871 std::string response_code_bytes;
11872 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11873 if (rc != TPM_RC_SUCCESS) {
11874 return rc;
11875 }
11876 if (response_size != response.size()) {
11877 return TPM_RC_SIZE;
11878 }
11879 if (response_code != TPM_RC_SUCCESS) {
11880 return response_code;
11881 }
11882 TPM_CC command_code = TPM_CC_Duplicate;
11883 std::string command_code_bytes;
11884 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11885 if (rc != TPM_RC_SUCCESS) {
11886 return rc;
11887 }
11888 std::string authorization_section_bytes;
11889 if (tag == TPM_ST_SESSIONS) {
11890 UINT32 parameter_section_size = buffer.size();
11891 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
11892 if (rc != TPM_RC_SUCCESS) {
11893 return rc;
11894 }
11895 if (parameter_section_size > buffer.size()) {
11896 return TPM_RC_INSUFFICIENT;
11897 }
11898 authorization_section_bytes = buffer.substr(parameter_section_size);
11899 // Keep the parameter section in |buffer|.
11900 buffer.erase(parameter_section_size);
11901 }
11902 std::unique_ptr<crypto::SecureHash> hash(
11903 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11904 hash->Update(response_code_bytes.data(), response_code_bytes.size());
11905 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11906 hash->Update(buffer.data(), buffer.size());
11907 std::string response_hash(32, 0);
11908 hash->Finish(std::data(response_hash), response_hash.size());
11909 if (tag == TPM_ST_SESSIONS) {
11910 if (!authorization_delegate)
11911 return TRUNKS_RC_AUTHORIZATION_FAILED;
11912 if (!authorization_delegate->CheckResponseAuthorization(
11913 response_hash, authorization_section_bytes)) {
11914 return TRUNKS_RC_AUTHORIZATION_FAILED;
11915 }
11916 }
11917 if (tag == TPM_ST_SESSIONS) {
11918 if (!authorization_delegate)
11919 return TRUNKS_RC_AUTHORIZATION_FAILED;
11920
11921 // Parse the encrypted parameter size.
11922 UINT16 size;
11923 std::string size_buffer = buffer.substr(0, 2);
11924 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11925 return result;
11926 }
11927 if (buffer.size() < 2 + size) {
11928 return TPM_RC_INSUFFICIENT;
11929 }
11930
11931 // Decrypt just the parameter data, not the size.
11932 std::string decrypted_data = buffer.substr(2, size);
11933 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11934 return TRUNKS_RC_ENCRYPTION_FAILED;
11935 }
11936 buffer.replace(2, size, decrypted_data);
11937 }
11938 std::string encryption_key_out_bytes;
11939 rc = Parse_TPM2B_DATA(&buffer, encryption_key_out, &encryption_key_out_bytes);
11940 if (rc != TPM_RC_SUCCESS) {
11941 return rc;
11942 }
11943 std::string duplicate_bytes;
11944 rc = Parse_TPM2B_PRIVATE(&buffer, duplicate, &duplicate_bytes);
11945 if (rc != TPM_RC_SUCCESS) {
11946 return rc;
11947 }
11948 std::string out_sym_seed_bytes;
11949 rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, out_sym_seed, &out_sym_seed_bytes);
11950 if (rc != TPM_RC_SUCCESS) {
11951 return rc;
11952 }
11953 return TPM_RC_SUCCESS;
11954 }
11955
DuplicateErrorCallback(Tpm::DuplicateResponse callback,TPM_RC response_code)11956 void DuplicateErrorCallback(Tpm::DuplicateResponse callback,
11957 TPM_RC response_code) {
11958 VLOG(1) << __func__;
11959 std::move(callback).Run(response_code, TPM2B_DATA(), TPM2B_PRIVATE(),
11960 TPM2B_ENCRYPTED_SECRET());
11961 }
11962
DuplicateResponseParser(Tpm::DuplicateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11963 void DuplicateResponseParser(Tpm::DuplicateResponse callback,
11964 AuthorizationDelegate* authorization_delegate,
11965 const std::string& response) {
11966 VLOG(1) << __func__;
11967 TPM2B_DATA encryption_key_out;
11968 TPM2B_PRIVATE duplicate;
11969 TPM2B_ENCRYPTED_SECRET out_sym_seed;
11970 TPM_RC rc =
11971 Tpm::ParseResponse_Duplicate(response, &encryption_key_out, &duplicate,
11972 &out_sym_seed, authorization_delegate);
11973 if (rc != TPM_RC_SUCCESS) {
11974 base::OnceCallback<void(TPM_RC)> error_reporter =
11975 base::BindOnce(DuplicateErrorCallback, std::move(callback));
11976 std::move(error_reporter).Run(rc);
11977 return;
11978 }
11979 std::move(callback).Run(rc, encryption_key_out, duplicate, out_sym_seed);
11980 }
11981
Duplicate(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & new_parent_handle,const std::string & new_parent_handle_name,const TPM2B_DATA & encryption_key_in,const TPMT_SYM_DEF_OBJECT & symmetric_alg,AuthorizationDelegate * authorization_delegate,DuplicateResponse callback)11982 void Tpm::Duplicate(const TPMI_DH_OBJECT& object_handle,
11983 const std::string& object_handle_name,
11984 const TPMI_DH_OBJECT& new_parent_handle,
11985 const std::string& new_parent_handle_name,
11986 const TPM2B_DATA& encryption_key_in,
11987 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11988 AuthorizationDelegate* authorization_delegate,
11989 DuplicateResponse callback) {
11990 VLOG(1) << __func__;
11991 std::string command;
11992 TPM_RC rc = SerializeCommand_Duplicate(
11993 object_handle, object_handle_name, new_parent_handle,
11994 new_parent_handle_name, encryption_key_in, symmetric_alg, &command,
11995 authorization_delegate);
11996 if (rc != TPM_RC_SUCCESS) {
11997 base::OnceCallback<void(TPM_RC)> error_reporter =
11998 base::BindOnce(DuplicateErrorCallback, std::move(callback));
11999 std::move(error_reporter).Run(rc);
12000 return;
12001 }
12002 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12003 DuplicateResponseParser, std::move(callback), authorization_delegate);
12004 transceiver_->SendCommand(command, std::move(parser));
12005 }
12006
DuplicateSync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & new_parent_handle,const std::string & new_parent_handle_name,const TPM2B_DATA & encryption_key_in,const TPMT_SYM_DEF_OBJECT & symmetric_alg,TPM2B_DATA * encryption_key_out,TPM2B_PRIVATE * duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)12007 TPM_RC Tpm::DuplicateSync(const TPMI_DH_OBJECT& object_handle,
12008 const std::string& object_handle_name,
12009 const TPMI_DH_OBJECT& new_parent_handle,
12010 const std::string& new_parent_handle_name,
12011 const TPM2B_DATA& encryption_key_in,
12012 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12013 TPM2B_DATA* encryption_key_out,
12014 TPM2B_PRIVATE* duplicate,
12015 TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12016 AuthorizationDelegate* authorization_delegate) {
12017 VLOG(1) << __func__;
12018 std::string command;
12019 TPM_RC rc = SerializeCommand_Duplicate(
12020 object_handle, object_handle_name, new_parent_handle,
12021 new_parent_handle_name, encryption_key_in, symmetric_alg, &command,
12022 authorization_delegate);
12023 if (rc != TPM_RC_SUCCESS) {
12024 return rc;
12025 }
12026 std::string response = transceiver_->SendCommandAndWait(command);
12027 rc = ParseResponse_Duplicate(response, encryption_key_out, duplicate,
12028 out_sym_seed, authorization_delegate);
12029 return rc;
12030 }
12031
SerializeCommand_Rewrap(const TPMI_DH_OBJECT & old_parent,const std::string & old_parent_name,const TPMI_DH_OBJECT & new_parent,const std::string & new_parent_name,const TPM2B_PRIVATE & in_duplicate,const TPM2B_NAME & name,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12032 TPM_RC Tpm::SerializeCommand_Rewrap(
12033 const TPMI_DH_OBJECT& old_parent,
12034 const std::string& old_parent_name,
12035 const TPMI_DH_OBJECT& new_parent,
12036 const std::string& new_parent_name,
12037 const TPM2B_PRIVATE& in_duplicate,
12038 const TPM2B_NAME& name,
12039 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12040 std::string* serialized_command,
12041 AuthorizationDelegate* authorization_delegate) {
12042 VLOG(3) << __func__;
12043 TPM_RC rc = TPM_RC_SUCCESS;
12044 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12045 UINT32 command_size = 10; // Header size.
12046 std::string handle_section_bytes;
12047 std::string parameter_section_bytes;
12048 TPM_CC command_code = TPM_CC_Rewrap;
12049 bool is_command_parameter_encryption_possible = true;
12050 bool is_response_parameter_encryption_possible = true;
12051 std::string command_code_bytes;
12052 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12053 if (rc != TPM_RC_SUCCESS) {
12054 return rc;
12055 }
12056 std::string old_parent_bytes;
12057 rc = Serialize_TPMI_DH_OBJECT(old_parent, &old_parent_bytes);
12058 if (rc != TPM_RC_SUCCESS) {
12059 return rc;
12060 }
12061 std::string new_parent_bytes;
12062 rc = Serialize_TPMI_DH_OBJECT(new_parent, &new_parent_bytes);
12063 if (rc != TPM_RC_SUCCESS) {
12064 return rc;
12065 }
12066 std::string in_duplicate_bytes;
12067 rc = Serialize_TPM2B_PRIVATE(in_duplicate, &in_duplicate_bytes);
12068 if (rc != TPM_RC_SUCCESS) {
12069 return rc;
12070 }
12071 std::string name_bytes;
12072 rc = Serialize_TPM2B_NAME(name, &name_bytes);
12073 if (rc != TPM_RC_SUCCESS) {
12074 return rc;
12075 }
12076 std::string in_sym_seed_bytes;
12077 rc = Serialize_TPM2B_ENCRYPTED_SECRET(in_sym_seed, &in_sym_seed_bytes);
12078 if (rc != TPM_RC_SUCCESS) {
12079 return rc;
12080 }
12081 if (authorization_delegate) {
12082 // Encrypt just the parameter data, not the size.
12083 std::string tmp = in_duplicate_bytes.substr(2);
12084 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12085 return TRUNKS_RC_ENCRYPTION_FAILED;
12086 }
12087 in_duplicate_bytes.replace(2, std::string::npos, tmp);
12088 }
12089 std::unique_ptr<crypto::SecureHash> hash(
12090 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12091 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12092 hash->Update(old_parent_name.data(), old_parent_name.size());
12093 handle_section_bytes += old_parent_bytes;
12094 command_size += old_parent_bytes.size();
12095 hash->Update(new_parent_name.data(), new_parent_name.size());
12096 handle_section_bytes += new_parent_bytes;
12097 command_size += new_parent_bytes.size();
12098 hash->Update(in_duplicate_bytes.data(), in_duplicate_bytes.size());
12099 parameter_section_bytes += in_duplicate_bytes;
12100 command_size += in_duplicate_bytes.size();
12101 hash->Update(name_bytes.data(), name_bytes.size());
12102 parameter_section_bytes += name_bytes;
12103 command_size += name_bytes.size();
12104 hash->Update(in_sym_seed_bytes.data(), in_sym_seed_bytes.size());
12105 parameter_section_bytes += in_sym_seed_bytes;
12106 command_size += in_sym_seed_bytes.size();
12107 std::string command_hash(32, 0);
12108 hash->Finish(std::data(command_hash), command_hash.size());
12109 std::string authorization_section_bytes;
12110 std::string authorization_size_bytes;
12111 if (authorization_delegate) {
12112 if (!authorization_delegate->GetCommandAuthorization(
12113 command_hash, is_command_parameter_encryption_possible,
12114 is_response_parameter_encryption_possible,
12115 &authorization_section_bytes)) {
12116 return TRUNKS_RC_AUTHORIZATION_FAILED;
12117 }
12118 if (!authorization_section_bytes.empty()) {
12119 tag = TPM_ST_SESSIONS;
12120 std::string tmp;
12121 rc = Serialize_UINT32(authorization_section_bytes.size(),
12122 &authorization_size_bytes);
12123 if (rc != TPM_RC_SUCCESS) {
12124 return rc;
12125 }
12126 command_size +=
12127 authorization_size_bytes.size() + authorization_section_bytes.size();
12128 }
12129 }
12130 std::string tag_bytes;
12131 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12132 if (rc != TPM_RC_SUCCESS) {
12133 return rc;
12134 }
12135 std::string command_size_bytes;
12136 rc = Serialize_UINT32(command_size, &command_size_bytes);
12137 if (rc != TPM_RC_SUCCESS) {
12138 return rc;
12139 }
12140 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12141 handle_section_bytes + authorization_size_bytes +
12142 authorization_section_bytes + parameter_section_bytes;
12143 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12144 VLOG(2) << "Command: "
12145 << base::HexEncode(serialized_command->data(),
12146 serialized_command->size());
12147 return TPM_RC_SUCCESS;
12148 }
12149
ParseResponse_Rewrap(const std::string & response,TPM2B_PRIVATE * out_duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)12150 TPM_RC Tpm::ParseResponse_Rewrap(
12151 const std::string& response,
12152 TPM2B_PRIVATE* out_duplicate,
12153 TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12154 AuthorizationDelegate* authorization_delegate) {
12155 VLOG(3) << __func__;
12156 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12157 TPM_RC rc = TPM_RC_SUCCESS;
12158 std::string buffer(response);
12159 TPM_ST tag;
12160 std::string tag_bytes;
12161 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12162 if (rc != TPM_RC_SUCCESS) {
12163 return rc;
12164 }
12165 UINT32 response_size;
12166 std::string response_size_bytes;
12167 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12168 if (rc != TPM_RC_SUCCESS) {
12169 return rc;
12170 }
12171 TPM_RC response_code;
12172 std::string response_code_bytes;
12173 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12174 if (rc != TPM_RC_SUCCESS) {
12175 return rc;
12176 }
12177 if (response_size != response.size()) {
12178 return TPM_RC_SIZE;
12179 }
12180 if (response_code != TPM_RC_SUCCESS) {
12181 return response_code;
12182 }
12183 TPM_CC command_code = TPM_CC_Rewrap;
12184 std::string command_code_bytes;
12185 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12186 if (rc != TPM_RC_SUCCESS) {
12187 return rc;
12188 }
12189 std::string authorization_section_bytes;
12190 if (tag == TPM_ST_SESSIONS) {
12191 UINT32 parameter_section_size = buffer.size();
12192 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
12193 if (rc != TPM_RC_SUCCESS) {
12194 return rc;
12195 }
12196 if (parameter_section_size > buffer.size()) {
12197 return TPM_RC_INSUFFICIENT;
12198 }
12199 authorization_section_bytes = buffer.substr(parameter_section_size);
12200 // Keep the parameter section in |buffer|.
12201 buffer.erase(parameter_section_size);
12202 }
12203 std::unique_ptr<crypto::SecureHash> hash(
12204 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12205 hash->Update(response_code_bytes.data(), response_code_bytes.size());
12206 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12207 hash->Update(buffer.data(), buffer.size());
12208 std::string response_hash(32, 0);
12209 hash->Finish(std::data(response_hash), response_hash.size());
12210 if (tag == TPM_ST_SESSIONS) {
12211 if (!authorization_delegate)
12212 return TRUNKS_RC_AUTHORIZATION_FAILED;
12213 if (!authorization_delegate->CheckResponseAuthorization(
12214 response_hash, authorization_section_bytes)) {
12215 return TRUNKS_RC_AUTHORIZATION_FAILED;
12216 }
12217 }
12218 if (tag == TPM_ST_SESSIONS) {
12219 if (!authorization_delegate)
12220 return TRUNKS_RC_AUTHORIZATION_FAILED;
12221
12222 // Parse the encrypted parameter size.
12223 UINT16 size;
12224 std::string size_buffer = buffer.substr(0, 2);
12225 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12226 return result;
12227 }
12228 if (buffer.size() < 2 + size) {
12229 return TPM_RC_INSUFFICIENT;
12230 }
12231
12232 // Decrypt just the parameter data, not the size.
12233 std::string decrypted_data = buffer.substr(2, size);
12234 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12235 return TRUNKS_RC_ENCRYPTION_FAILED;
12236 }
12237 buffer.replace(2, size, decrypted_data);
12238 }
12239 std::string out_duplicate_bytes;
12240 rc = Parse_TPM2B_PRIVATE(&buffer, out_duplicate, &out_duplicate_bytes);
12241 if (rc != TPM_RC_SUCCESS) {
12242 return rc;
12243 }
12244 std::string out_sym_seed_bytes;
12245 rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, out_sym_seed, &out_sym_seed_bytes);
12246 if (rc != TPM_RC_SUCCESS) {
12247 return rc;
12248 }
12249 return TPM_RC_SUCCESS;
12250 }
12251
RewrapErrorCallback(Tpm::RewrapResponse callback,TPM_RC response_code)12252 void RewrapErrorCallback(Tpm::RewrapResponse callback, TPM_RC response_code) {
12253 VLOG(1) << __func__;
12254 std::move(callback).Run(response_code, TPM2B_PRIVATE(),
12255 TPM2B_ENCRYPTED_SECRET());
12256 }
12257
RewrapResponseParser(Tpm::RewrapResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12258 void RewrapResponseParser(Tpm::RewrapResponse callback,
12259 AuthorizationDelegate* authorization_delegate,
12260 const std::string& response) {
12261 VLOG(1) << __func__;
12262 TPM2B_PRIVATE out_duplicate;
12263 TPM2B_ENCRYPTED_SECRET out_sym_seed;
12264 TPM_RC rc = Tpm::ParseResponse_Rewrap(response, &out_duplicate, &out_sym_seed,
12265 authorization_delegate);
12266 if (rc != TPM_RC_SUCCESS) {
12267 base::OnceCallback<void(TPM_RC)> error_reporter =
12268 base::BindOnce(RewrapErrorCallback, std::move(callback));
12269 std::move(error_reporter).Run(rc);
12270 return;
12271 }
12272 std::move(callback).Run(rc, out_duplicate, out_sym_seed);
12273 }
12274
Rewrap(const TPMI_DH_OBJECT & old_parent,const std::string & old_parent_name,const TPMI_DH_OBJECT & new_parent,const std::string & new_parent_name,const TPM2B_PRIVATE & in_duplicate,const TPM2B_NAME & name,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,AuthorizationDelegate * authorization_delegate,RewrapResponse callback)12275 void Tpm::Rewrap(const TPMI_DH_OBJECT& old_parent,
12276 const std::string& old_parent_name,
12277 const TPMI_DH_OBJECT& new_parent,
12278 const std::string& new_parent_name,
12279 const TPM2B_PRIVATE& in_duplicate,
12280 const TPM2B_NAME& name,
12281 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12282 AuthorizationDelegate* authorization_delegate,
12283 RewrapResponse callback) {
12284 VLOG(1) << __func__;
12285 std::string command;
12286 TPM_RC rc = SerializeCommand_Rewrap(
12287 old_parent, old_parent_name, new_parent, new_parent_name, in_duplicate,
12288 name, in_sym_seed, &command, authorization_delegate);
12289 if (rc != TPM_RC_SUCCESS) {
12290 base::OnceCallback<void(TPM_RC)> error_reporter =
12291 base::BindOnce(RewrapErrorCallback, std::move(callback));
12292 std::move(error_reporter).Run(rc);
12293 return;
12294 }
12295 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12296 RewrapResponseParser, std::move(callback), authorization_delegate);
12297 transceiver_->SendCommand(command, std::move(parser));
12298 }
12299
RewrapSync(const TPMI_DH_OBJECT & old_parent,const std::string & old_parent_name,const TPMI_DH_OBJECT & new_parent,const std::string & new_parent_name,const TPM2B_PRIVATE & in_duplicate,const TPM2B_NAME & name,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,TPM2B_PRIVATE * out_duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)12300 TPM_RC Tpm::RewrapSync(const TPMI_DH_OBJECT& old_parent,
12301 const std::string& old_parent_name,
12302 const TPMI_DH_OBJECT& new_parent,
12303 const std::string& new_parent_name,
12304 const TPM2B_PRIVATE& in_duplicate,
12305 const TPM2B_NAME& name,
12306 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12307 TPM2B_PRIVATE* out_duplicate,
12308 TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12309 AuthorizationDelegate* authorization_delegate) {
12310 VLOG(1) << __func__;
12311 std::string command;
12312 TPM_RC rc = SerializeCommand_Rewrap(
12313 old_parent, old_parent_name, new_parent, new_parent_name, in_duplicate,
12314 name, in_sym_seed, &command, authorization_delegate);
12315 if (rc != TPM_RC_SUCCESS) {
12316 return rc;
12317 }
12318 std::string response = transceiver_->SendCommandAndWait(command);
12319 rc = ParseResponse_Rewrap(response, out_duplicate, out_sym_seed,
12320 authorization_delegate);
12321 return rc;
12322 }
12323
SerializeCommand_Import(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_DATA & encryption_key,const TPM2B_PUBLIC & object_public,const TPM2B_PRIVATE & duplicate,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,const TPMT_SYM_DEF_OBJECT & symmetric_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12324 TPM_RC Tpm::SerializeCommand_Import(
12325 const TPMI_DH_OBJECT& parent_handle,
12326 const std::string& parent_handle_name,
12327 const TPM2B_DATA& encryption_key,
12328 const TPM2B_PUBLIC& object_public,
12329 const TPM2B_PRIVATE& duplicate,
12330 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12331 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12332 std::string* serialized_command,
12333 AuthorizationDelegate* authorization_delegate) {
12334 VLOG(3) << __func__;
12335 TPM_RC rc = TPM_RC_SUCCESS;
12336 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12337 UINT32 command_size = 10; // Header size.
12338 std::string handle_section_bytes;
12339 std::string parameter_section_bytes;
12340 TPM_CC command_code = TPM_CC_Import;
12341 bool is_command_parameter_encryption_possible = true;
12342 bool is_response_parameter_encryption_possible = true;
12343 std::string command_code_bytes;
12344 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12345 if (rc != TPM_RC_SUCCESS) {
12346 return rc;
12347 }
12348 std::string parent_handle_bytes;
12349 rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
12350 if (rc != TPM_RC_SUCCESS) {
12351 return rc;
12352 }
12353 std::string encryption_key_bytes;
12354 rc = Serialize_TPM2B_DATA(encryption_key, &encryption_key_bytes);
12355 if (rc != TPM_RC_SUCCESS) {
12356 return rc;
12357 }
12358 std::string object_public_bytes;
12359 rc = Serialize_TPM2B_PUBLIC(object_public, &object_public_bytes);
12360 if (rc != TPM_RC_SUCCESS) {
12361 return rc;
12362 }
12363 std::string duplicate_bytes;
12364 rc = Serialize_TPM2B_PRIVATE(duplicate, &duplicate_bytes);
12365 if (rc != TPM_RC_SUCCESS) {
12366 return rc;
12367 }
12368 std::string in_sym_seed_bytes;
12369 rc = Serialize_TPM2B_ENCRYPTED_SECRET(in_sym_seed, &in_sym_seed_bytes);
12370 if (rc != TPM_RC_SUCCESS) {
12371 return rc;
12372 }
12373 std::string symmetric_alg_bytes;
12374 rc = Serialize_TPMT_SYM_DEF_OBJECT(symmetric_alg, &symmetric_alg_bytes);
12375 if (rc != TPM_RC_SUCCESS) {
12376 return rc;
12377 }
12378 if (authorization_delegate) {
12379 // Encrypt just the parameter data, not the size.
12380 std::string tmp = encryption_key_bytes.substr(2);
12381 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12382 return TRUNKS_RC_ENCRYPTION_FAILED;
12383 }
12384 encryption_key_bytes.replace(2, std::string::npos, tmp);
12385 }
12386 std::unique_ptr<crypto::SecureHash> hash(
12387 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12388 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12389 hash->Update(parent_handle_name.data(), parent_handle_name.size());
12390 handle_section_bytes += parent_handle_bytes;
12391 command_size += parent_handle_bytes.size();
12392 hash->Update(encryption_key_bytes.data(), encryption_key_bytes.size());
12393 parameter_section_bytes += encryption_key_bytes;
12394 command_size += encryption_key_bytes.size();
12395 hash->Update(object_public_bytes.data(), object_public_bytes.size());
12396 parameter_section_bytes += object_public_bytes;
12397 command_size += object_public_bytes.size();
12398 hash->Update(duplicate_bytes.data(), duplicate_bytes.size());
12399 parameter_section_bytes += duplicate_bytes;
12400 command_size += duplicate_bytes.size();
12401 hash->Update(in_sym_seed_bytes.data(), in_sym_seed_bytes.size());
12402 parameter_section_bytes += in_sym_seed_bytes;
12403 command_size += in_sym_seed_bytes.size();
12404 hash->Update(symmetric_alg_bytes.data(), symmetric_alg_bytes.size());
12405 parameter_section_bytes += symmetric_alg_bytes;
12406 command_size += symmetric_alg_bytes.size();
12407 std::string command_hash(32, 0);
12408 hash->Finish(std::data(command_hash), command_hash.size());
12409 std::string authorization_section_bytes;
12410 std::string authorization_size_bytes;
12411 if (authorization_delegate) {
12412 if (!authorization_delegate->GetCommandAuthorization(
12413 command_hash, is_command_parameter_encryption_possible,
12414 is_response_parameter_encryption_possible,
12415 &authorization_section_bytes)) {
12416 return TRUNKS_RC_AUTHORIZATION_FAILED;
12417 }
12418 if (!authorization_section_bytes.empty()) {
12419 tag = TPM_ST_SESSIONS;
12420 std::string tmp;
12421 rc = Serialize_UINT32(authorization_section_bytes.size(),
12422 &authorization_size_bytes);
12423 if (rc != TPM_RC_SUCCESS) {
12424 return rc;
12425 }
12426 command_size +=
12427 authorization_size_bytes.size() + authorization_section_bytes.size();
12428 }
12429 }
12430 std::string tag_bytes;
12431 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12432 if (rc != TPM_RC_SUCCESS) {
12433 return rc;
12434 }
12435 std::string command_size_bytes;
12436 rc = Serialize_UINT32(command_size, &command_size_bytes);
12437 if (rc != TPM_RC_SUCCESS) {
12438 return rc;
12439 }
12440 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12441 handle_section_bytes + authorization_size_bytes +
12442 authorization_section_bytes + parameter_section_bytes;
12443 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12444 VLOG(2) << "Command: "
12445 << base::HexEncode(serialized_command->data(),
12446 serialized_command->size());
12447 return TPM_RC_SUCCESS;
12448 }
12449
ParseResponse_Import(const std::string & response,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)12450 TPM_RC Tpm::ParseResponse_Import(
12451 const std::string& response,
12452 TPM2B_PRIVATE* out_private,
12453 AuthorizationDelegate* authorization_delegate) {
12454 VLOG(3) << __func__;
12455 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12456 TPM_RC rc = TPM_RC_SUCCESS;
12457 std::string buffer(response);
12458 TPM_ST tag;
12459 std::string tag_bytes;
12460 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12461 if (rc != TPM_RC_SUCCESS) {
12462 return rc;
12463 }
12464 UINT32 response_size;
12465 std::string response_size_bytes;
12466 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12467 if (rc != TPM_RC_SUCCESS) {
12468 return rc;
12469 }
12470 TPM_RC response_code;
12471 std::string response_code_bytes;
12472 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12473 if (rc != TPM_RC_SUCCESS) {
12474 return rc;
12475 }
12476 if (response_size != response.size()) {
12477 return TPM_RC_SIZE;
12478 }
12479 if (response_code != TPM_RC_SUCCESS) {
12480 return response_code;
12481 }
12482 TPM_CC command_code = TPM_CC_Import;
12483 std::string command_code_bytes;
12484 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12485 if (rc != TPM_RC_SUCCESS) {
12486 return rc;
12487 }
12488 std::string authorization_section_bytes;
12489 if (tag == TPM_ST_SESSIONS) {
12490 UINT32 parameter_section_size = buffer.size();
12491 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
12492 if (rc != TPM_RC_SUCCESS) {
12493 return rc;
12494 }
12495 if (parameter_section_size > buffer.size()) {
12496 return TPM_RC_INSUFFICIENT;
12497 }
12498 authorization_section_bytes = buffer.substr(parameter_section_size);
12499 // Keep the parameter section in |buffer|.
12500 buffer.erase(parameter_section_size);
12501 }
12502 std::unique_ptr<crypto::SecureHash> hash(
12503 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12504 hash->Update(response_code_bytes.data(), response_code_bytes.size());
12505 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12506 hash->Update(buffer.data(), buffer.size());
12507 std::string response_hash(32, 0);
12508 hash->Finish(std::data(response_hash), response_hash.size());
12509 if (tag == TPM_ST_SESSIONS) {
12510 if (!authorization_delegate)
12511 return TRUNKS_RC_AUTHORIZATION_FAILED;
12512 if (!authorization_delegate->CheckResponseAuthorization(
12513 response_hash, authorization_section_bytes)) {
12514 return TRUNKS_RC_AUTHORIZATION_FAILED;
12515 }
12516 }
12517 if (tag == TPM_ST_SESSIONS) {
12518 if (!authorization_delegate)
12519 return TRUNKS_RC_AUTHORIZATION_FAILED;
12520
12521 // Parse the encrypted parameter size.
12522 UINT16 size;
12523 std::string size_buffer = buffer.substr(0, 2);
12524 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12525 return result;
12526 }
12527 if (buffer.size() < 2 + size) {
12528 return TPM_RC_INSUFFICIENT;
12529 }
12530
12531 // Decrypt just the parameter data, not the size.
12532 std::string decrypted_data = buffer.substr(2, size);
12533 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12534 return TRUNKS_RC_ENCRYPTION_FAILED;
12535 }
12536 buffer.replace(2, size, decrypted_data);
12537 }
12538 std::string out_private_bytes;
12539 rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
12540 if (rc != TPM_RC_SUCCESS) {
12541 return rc;
12542 }
12543 return TPM_RC_SUCCESS;
12544 }
12545
ImportErrorCallback(Tpm::ImportResponse callback,TPM_RC response_code)12546 void ImportErrorCallback(Tpm::ImportResponse callback, TPM_RC response_code) {
12547 VLOG(1) << __func__;
12548 std::move(callback).Run(response_code, TPM2B_PRIVATE());
12549 }
12550
ImportResponseParser(Tpm::ImportResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12551 void ImportResponseParser(Tpm::ImportResponse callback,
12552 AuthorizationDelegate* authorization_delegate,
12553 const std::string& response) {
12554 VLOG(1) << __func__;
12555 TPM2B_PRIVATE out_private;
12556 TPM_RC rc =
12557 Tpm::ParseResponse_Import(response, &out_private, authorization_delegate);
12558 if (rc != TPM_RC_SUCCESS) {
12559 base::OnceCallback<void(TPM_RC)> error_reporter =
12560 base::BindOnce(ImportErrorCallback, std::move(callback));
12561 std::move(error_reporter).Run(rc);
12562 return;
12563 }
12564 std::move(callback).Run(rc, out_private);
12565 }
12566
Import(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_DATA & encryption_key,const TPM2B_PUBLIC & object_public,const TPM2B_PRIVATE & duplicate,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,const TPMT_SYM_DEF_OBJECT & symmetric_alg,AuthorizationDelegate * authorization_delegate,ImportResponse callback)12567 void Tpm::Import(const TPMI_DH_OBJECT& parent_handle,
12568 const std::string& parent_handle_name,
12569 const TPM2B_DATA& encryption_key,
12570 const TPM2B_PUBLIC& object_public,
12571 const TPM2B_PRIVATE& duplicate,
12572 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12573 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12574 AuthorizationDelegate* authorization_delegate,
12575 ImportResponse callback) {
12576 VLOG(1) << __func__;
12577 std::string command;
12578 TPM_RC rc = SerializeCommand_Import(
12579 parent_handle, parent_handle_name, encryption_key, object_public,
12580 duplicate, in_sym_seed, symmetric_alg, &command, authorization_delegate);
12581 if (rc != TPM_RC_SUCCESS) {
12582 base::OnceCallback<void(TPM_RC)> error_reporter =
12583 base::BindOnce(ImportErrorCallback, std::move(callback));
12584 std::move(error_reporter).Run(rc);
12585 return;
12586 }
12587 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12588 ImportResponseParser, std::move(callback), authorization_delegate);
12589 transceiver_->SendCommand(command, std::move(parser));
12590 }
12591
ImportSync(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_DATA & encryption_key,const TPM2B_PUBLIC & object_public,const TPM2B_PRIVATE & duplicate,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,const TPMT_SYM_DEF_OBJECT & symmetric_alg,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)12592 TPM_RC Tpm::ImportSync(const TPMI_DH_OBJECT& parent_handle,
12593 const std::string& parent_handle_name,
12594 const TPM2B_DATA& encryption_key,
12595 const TPM2B_PUBLIC& object_public,
12596 const TPM2B_PRIVATE& duplicate,
12597 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12598 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12599 TPM2B_PRIVATE* out_private,
12600 AuthorizationDelegate* authorization_delegate) {
12601 VLOG(1) << __func__;
12602 std::string command;
12603 TPM_RC rc = SerializeCommand_Import(
12604 parent_handle, parent_handle_name, encryption_key, object_public,
12605 duplicate, in_sym_seed, symmetric_alg, &command, authorization_delegate);
12606 if (rc != TPM_RC_SUCCESS) {
12607 return rc;
12608 }
12609 std::string response = transceiver_->SendCommandAndWait(command);
12610 rc = ParseResponse_Import(response, out_private, authorization_delegate);
12611 return rc;
12612 }
12613
SerializeCommand_RSA_Encrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & message,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12614 TPM_RC Tpm::SerializeCommand_RSA_Encrypt(
12615 const TPMI_DH_OBJECT& key_handle,
12616 const std::string& key_handle_name,
12617 const TPM2B_PUBLIC_KEY_RSA& message,
12618 const TPMT_RSA_DECRYPT& in_scheme,
12619 const TPM2B_DATA& label,
12620 std::string* serialized_command,
12621 AuthorizationDelegate* authorization_delegate) {
12622 VLOG(3) << __func__;
12623 TPM_RC rc = TPM_RC_SUCCESS;
12624 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12625 UINT32 command_size = 10; // Header size.
12626 std::string handle_section_bytes;
12627 std::string parameter_section_bytes;
12628 TPM_CC command_code = TPM_CC_RSA_Encrypt;
12629 bool is_command_parameter_encryption_possible = true;
12630 bool is_response_parameter_encryption_possible = true;
12631 std::string command_code_bytes;
12632 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12633 if (rc != TPM_RC_SUCCESS) {
12634 return rc;
12635 }
12636 std::string key_handle_bytes;
12637 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
12638 if (rc != TPM_RC_SUCCESS) {
12639 return rc;
12640 }
12641 std::string message_bytes;
12642 rc = Serialize_TPM2B_PUBLIC_KEY_RSA(message, &message_bytes);
12643 if (rc != TPM_RC_SUCCESS) {
12644 return rc;
12645 }
12646 std::string in_scheme_bytes;
12647 rc = Serialize_TPMT_RSA_DECRYPT(in_scheme, &in_scheme_bytes);
12648 if (rc != TPM_RC_SUCCESS) {
12649 return rc;
12650 }
12651 std::string label_bytes;
12652 rc = Serialize_TPM2B_DATA(label, &label_bytes);
12653 if (rc != TPM_RC_SUCCESS) {
12654 return rc;
12655 }
12656 if (authorization_delegate) {
12657 // Encrypt just the parameter data, not the size.
12658 std::string tmp = message_bytes.substr(2);
12659 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12660 return TRUNKS_RC_ENCRYPTION_FAILED;
12661 }
12662 message_bytes.replace(2, std::string::npos, tmp);
12663 }
12664 std::unique_ptr<crypto::SecureHash> hash(
12665 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12666 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12667 hash->Update(key_handle_name.data(), key_handle_name.size());
12668 handle_section_bytes += key_handle_bytes;
12669 command_size += key_handle_bytes.size();
12670 hash->Update(message_bytes.data(), message_bytes.size());
12671 parameter_section_bytes += message_bytes;
12672 command_size += message_bytes.size();
12673 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
12674 parameter_section_bytes += in_scheme_bytes;
12675 command_size += in_scheme_bytes.size();
12676 hash->Update(label_bytes.data(), label_bytes.size());
12677 parameter_section_bytes += label_bytes;
12678 command_size += label_bytes.size();
12679 std::string command_hash(32, 0);
12680 hash->Finish(std::data(command_hash), command_hash.size());
12681 std::string authorization_section_bytes;
12682 std::string authorization_size_bytes;
12683 if (authorization_delegate) {
12684 if (!authorization_delegate->GetCommandAuthorization(
12685 command_hash, is_command_parameter_encryption_possible,
12686 is_response_parameter_encryption_possible,
12687 &authorization_section_bytes)) {
12688 return TRUNKS_RC_AUTHORIZATION_FAILED;
12689 }
12690 if (!authorization_section_bytes.empty()) {
12691 tag = TPM_ST_SESSIONS;
12692 std::string tmp;
12693 rc = Serialize_UINT32(authorization_section_bytes.size(),
12694 &authorization_size_bytes);
12695 if (rc != TPM_RC_SUCCESS) {
12696 return rc;
12697 }
12698 command_size +=
12699 authorization_size_bytes.size() + authorization_section_bytes.size();
12700 }
12701 }
12702 std::string tag_bytes;
12703 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12704 if (rc != TPM_RC_SUCCESS) {
12705 return rc;
12706 }
12707 std::string command_size_bytes;
12708 rc = Serialize_UINT32(command_size, &command_size_bytes);
12709 if (rc != TPM_RC_SUCCESS) {
12710 return rc;
12711 }
12712 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12713 handle_section_bytes + authorization_size_bytes +
12714 authorization_section_bytes + parameter_section_bytes;
12715 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12716 VLOG(2) << "Command: "
12717 << base::HexEncode(serialized_command->data(),
12718 serialized_command->size());
12719 return TPM_RC_SUCCESS;
12720 }
12721
ParseResponse_RSA_Encrypt(const std::string & response,TPM2B_PUBLIC_KEY_RSA * out_data,AuthorizationDelegate * authorization_delegate)12722 TPM_RC Tpm::ParseResponse_RSA_Encrypt(
12723 const std::string& response,
12724 TPM2B_PUBLIC_KEY_RSA* out_data,
12725 AuthorizationDelegate* authorization_delegate) {
12726 VLOG(3) << __func__;
12727 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12728 TPM_RC rc = TPM_RC_SUCCESS;
12729 std::string buffer(response);
12730 TPM_ST tag;
12731 std::string tag_bytes;
12732 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12733 if (rc != TPM_RC_SUCCESS) {
12734 return rc;
12735 }
12736 UINT32 response_size;
12737 std::string response_size_bytes;
12738 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12739 if (rc != TPM_RC_SUCCESS) {
12740 return rc;
12741 }
12742 TPM_RC response_code;
12743 std::string response_code_bytes;
12744 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12745 if (rc != TPM_RC_SUCCESS) {
12746 return rc;
12747 }
12748 if (response_size != response.size()) {
12749 return TPM_RC_SIZE;
12750 }
12751 if (response_code != TPM_RC_SUCCESS) {
12752 return response_code;
12753 }
12754 TPM_CC command_code = TPM_CC_RSA_Encrypt;
12755 std::string command_code_bytes;
12756 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12757 if (rc != TPM_RC_SUCCESS) {
12758 return rc;
12759 }
12760 std::string authorization_section_bytes;
12761 if (tag == TPM_ST_SESSIONS) {
12762 UINT32 parameter_section_size = buffer.size();
12763 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
12764 if (rc != TPM_RC_SUCCESS) {
12765 return rc;
12766 }
12767 if (parameter_section_size > buffer.size()) {
12768 return TPM_RC_INSUFFICIENT;
12769 }
12770 authorization_section_bytes = buffer.substr(parameter_section_size);
12771 // Keep the parameter section in |buffer|.
12772 buffer.erase(parameter_section_size);
12773 }
12774 std::unique_ptr<crypto::SecureHash> hash(
12775 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12776 hash->Update(response_code_bytes.data(), response_code_bytes.size());
12777 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12778 hash->Update(buffer.data(), buffer.size());
12779 std::string response_hash(32, 0);
12780 hash->Finish(std::data(response_hash), response_hash.size());
12781 if (tag == TPM_ST_SESSIONS) {
12782 if (!authorization_delegate)
12783 return TRUNKS_RC_AUTHORIZATION_FAILED;
12784 if (!authorization_delegate->CheckResponseAuthorization(
12785 response_hash, authorization_section_bytes)) {
12786 return TRUNKS_RC_AUTHORIZATION_FAILED;
12787 }
12788 }
12789 if (tag == TPM_ST_SESSIONS) {
12790 if (!authorization_delegate)
12791 return TRUNKS_RC_AUTHORIZATION_FAILED;
12792
12793 // Parse the encrypted parameter size.
12794 UINT16 size;
12795 std::string size_buffer = buffer.substr(0, 2);
12796 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12797 return result;
12798 }
12799 if (buffer.size() < 2 + size) {
12800 return TPM_RC_INSUFFICIENT;
12801 }
12802
12803 // Decrypt just the parameter data, not the size.
12804 std::string decrypted_data = buffer.substr(2, size);
12805 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12806 return TRUNKS_RC_ENCRYPTION_FAILED;
12807 }
12808 buffer.replace(2, size, decrypted_data);
12809 }
12810 std::string out_data_bytes;
12811 rc = Parse_TPM2B_PUBLIC_KEY_RSA(&buffer, out_data, &out_data_bytes);
12812 if (rc != TPM_RC_SUCCESS) {
12813 return rc;
12814 }
12815 return TPM_RC_SUCCESS;
12816 }
12817
RSA_EncryptErrorCallback(Tpm::RSA_EncryptResponse callback,TPM_RC response_code)12818 void RSA_EncryptErrorCallback(Tpm::RSA_EncryptResponse callback,
12819 TPM_RC response_code) {
12820 VLOG(1) << __func__;
12821 std::move(callback).Run(response_code, TPM2B_PUBLIC_KEY_RSA());
12822 }
12823
RSA_EncryptResponseParser(Tpm::RSA_EncryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12824 void RSA_EncryptResponseParser(Tpm::RSA_EncryptResponse callback,
12825 AuthorizationDelegate* authorization_delegate,
12826 const std::string& response) {
12827 VLOG(1) << __func__;
12828 TPM2B_PUBLIC_KEY_RSA out_data;
12829 TPM_RC rc = Tpm::ParseResponse_RSA_Encrypt(response, &out_data,
12830 authorization_delegate);
12831 if (rc != TPM_RC_SUCCESS) {
12832 base::OnceCallback<void(TPM_RC)> error_reporter =
12833 base::BindOnce(RSA_EncryptErrorCallback, std::move(callback));
12834 std::move(error_reporter).Run(rc);
12835 return;
12836 }
12837 std::move(callback).Run(rc, out_data);
12838 }
12839
RSA_Encrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & message,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,AuthorizationDelegate * authorization_delegate,RSA_EncryptResponse callback)12840 void Tpm::RSA_Encrypt(const TPMI_DH_OBJECT& key_handle,
12841 const std::string& key_handle_name,
12842 const TPM2B_PUBLIC_KEY_RSA& message,
12843 const TPMT_RSA_DECRYPT& in_scheme,
12844 const TPM2B_DATA& label,
12845 AuthorizationDelegate* authorization_delegate,
12846 RSA_EncryptResponse callback) {
12847 VLOG(1) << __func__;
12848 std::string command;
12849 TPM_RC rc = SerializeCommand_RSA_Encrypt(key_handle, key_handle_name, message,
12850 in_scheme, label, &command,
12851 authorization_delegate);
12852 if (rc != TPM_RC_SUCCESS) {
12853 base::OnceCallback<void(TPM_RC)> error_reporter =
12854 base::BindOnce(RSA_EncryptErrorCallback, std::move(callback));
12855 std::move(error_reporter).Run(rc);
12856 return;
12857 }
12858 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12859 RSA_EncryptResponseParser, std::move(callback), authorization_delegate);
12860 transceiver_->SendCommand(command, std::move(parser));
12861 }
12862
RSA_EncryptSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & message,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,TPM2B_PUBLIC_KEY_RSA * out_data,AuthorizationDelegate * authorization_delegate)12863 TPM_RC Tpm::RSA_EncryptSync(const TPMI_DH_OBJECT& key_handle,
12864 const std::string& key_handle_name,
12865 const TPM2B_PUBLIC_KEY_RSA& message,
12866 const TPMT_RSA_DECRYPT& in_scheme,
12867 const TPM2B_DATA& label,
12868 TPM2B_PUBLIC_KEY_RSA* out_data,
12869 AuthorizationDelegate* authorization_delegate) {
12870 VLOG(1) << __func__;
12871 std::string command;
12872 TPM_RC rc = SerializeCommand_RSA_Encrypt(key_handle, key_handle_name, message,
12873 in_scheme, label, &command,
12874 authorization_delegate);
12875 if (rc != TPM_RC_SUCCESS) {
12876 return rc;
12877 }
12878 std::string response = transceiver_->SendCommandAndWait(command);
12879 rc = ParseResponse_RSA_Encrypt(response, out_data, authorization_delegate);
12880 return rc;
12881 }
12882
SerializeCommand_RSA_Decrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & cipher_text,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12883 TPM_RC Tpm::SerializeCommand_RSA_Decrypt(
12884 const TPMI_DH_OBJECT& key_handle,
12885 const std::string& key_handle_name,
12886 const TPM2B_PUBLIC_KEY_RSA& cipher_text,
12887 const TPMT_RSA_DECRYPT& in_scheme,
12888 const TPM2B_DATA& label,
12889 std::string* serialized_command,
12890 AuthorizationDelegate* authorization_delegate) {
12891 VLOG(3) << __func__;
12892 TPM_RC rc = TPM_RC_SUCCESS;
12893 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12894 UINT32 command_size = 10; // Header size.
12895 std::string handle_section_bytes;
12896 std::string parameter_section_bytes;
12897 TPM_CC command_code = TPM_CC_RSA_Decrypt;
12898 bool is_command_parameter_encryption_possible = true;
12899 bool is_response_parameter_encryption_possible = true;
12900 std::string command_code_bytes;
12901 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12902 if (rc != TPM_RC_SUCCESS) {
12903 return rc;
12904 }
12905 std::string key_handle_bytes;
12906 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
12907 if (rc != TPM_RC_SUCCESS) {
12908 return rc;
12909 }
12910 std::string cipher_text_bytes;
12911 rc = Serialize_TPM2B_PUBLIC_KEY_RSA(cipher_text, &cipher_text_bytes);
12912 if (rc != TPM_RC_SUCCESS) {
12913 return rc;
12914 }
12915 std::string in_scheme_bytes;
12916 rc = Serialize_TPMT_RSA_DECRYPT(in_scheme, &in_scheme_bytes);
12917 if (rc != TPM_RC_SUCCESS) {
12918 return rc;
12919 }
12920 std::string label_bytes;
12921 rc = Serialize_TPM2B_DATA(label, &label_bytes);
12922 if (rc != TPM_RC_SUCCESS) {
12923 return rc;
12924 }
12925 if (authorization_delegate) {
12926 // Encrypt just the parameter data, not the size.
12927 std::string tmp = cipher_text_bytes.substr(2);
12928 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12929 return TRUNKS_RC_ENCRYPTION_FAILED;
12930 }
12931 cipher_text_bytes.replace(2, std::string::npos, tmp);
12932 }
12933 std::unique_ptr<crypto::SecureHash> hash(
12934 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12935 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12936 hash->Update(key_handle_name.data(), key_handle_name.size());
12937 handle_section_bytes += key_handle_bytes;
12938 command_size += key_handle_bytes.size();
12939 hash->Update(cipher_text_bytes.data(), cipher_text_bytes.size());
12940 parameter_section_bytes += cipher_text_bytes;
12941 command_size += cipher_text_bytes.size();
12942 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
12943 parameter_section_bytes += in_scheme_bytes;
12944 command_size += in_scheme_bytes.size();
12945 hash->Update(label_bytes.data(), label_bytes.size());
12946 parameter_section_bytes += label_bytes;
12947 command_size += label_bytes.size();
12948 std::string command_hash(32, 0);
12949 hash->Finish(std::data(command_hash), command_hash.size());
12950 std::string authorization_section_bytes;
12951 std::string authorization_size_bytes;
12952 if (authorization_delegate) {
12953 if (!authorization_delegate->GetCommandAuthorization(
12954 command_hash, is_command_parameter_encryption_possible,
12955 is_response_parameter_encryption_possible,
12956 &authorization_section_bytes)) {
12957 return TRUNKS_RC_AUTHORIZATION_FAILED;
12958 }
12959 if (!authorization_section_bytes.empty()) {
12960 tag = TPM_ST_SESSIONS;
12961 std::string tmp;
12962 rc = Serialize_UINT32(authorization_section_bytes.size(),
12963 &authorization_size_bytes);
12964 if (rc != TPM_RC_SUCCESS) {
12965 return rc;
12966 }
12967 command_size +=
12968 authorization_size_bytes.size() + authorization_section_bytes.size();
12969 }
12970 }
12971 std::string tag_bytes;
12972 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12973 if (rc != TPM_RC_SUCCESS) {
12974 return rc;
12975 }
12976 std::string command_size_bytes;
12977 rc = Serialize_UINT32(command_size, &command_size_bytes);
12978 if (rc != TPM_RC_SUCCESS) {
12979 return rc;
12980 }
12981 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12982 handle_section_bytes + authorization_size_bytes +
12983 authorization_section_bytes + parameter_section_bytes;
12984 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12985 VLOG(2) << "Command: "
12986 << base::HexEncode(serialized_command->data(),
12987 serialized_command->size());
12988 return TPM_RC_SUCCESS;
12989 }
12990
ParseResponse_RSA_Decrypt(const std::string & response,TPM2B_PUBLIC_KEY_RSA * message,AuthorizationDelegate * authorization_delegate)12991 TPM_RC Tpm::ParseResponse_RSA_Decrypt(
12992 const std::string& response,
12993 TPM2B_PUBLIC_KEY_RSA* message,
12994 AuthorizationDelegate* authorization_delegate) {
12995 VLOG(3) << __func__;
12996 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12997 TPM_RC rc = TPM_RC_SUCCESS;
12998 std::string buffer(response);
12999 TPM_ST tag;
13000 std::string tag_bytes;
13001 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13002 if (rc != TPM_RC_SUCCESS) {
13003 return rc;
13004 }
13005 UINT32 response_size;
13006 std::string response_size_bytes;
13007 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13008 if (rc != TPM_RC_SUCCESS) {
13009 return rc;
13010 }
13011 TPM_RC response_code;
13012 std::string response_code_bytes;
13013 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13014 if (rc != TPM_RC_SUCCESS) {
13015 return rc;
13016 }
13017 if (response_size != response.size()) {
13018 return TPM_RC_SIZE;
13019 }
13020 if (response_code != TPM_RC_SUCCESS) {
13021 return response_code;
13022 }
13023 TPM_CC command_code = TPM_CC_RSA_Decrypt;
13024 std::string command_code_bytes;
13025 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13026 if (rc != TPM_RC_SUCCESS) {
13027 return rc;
13028 }
13029 std::string authorization_section_bytes;
13030 if (tag == TPM_ST_SESSIONS) {
13031 UINT32 parameter_section_size = buffer.size();
13032 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
13033 if (rc != TPM_RC_SUCCESS) {
13034 return rc;
13035 }
13036 if (parameter_section_size > buffer.size()) {
13037 return TPM_RC_INSUFFICIENT;
13038 }
13039 authorization_section_bytes = buffer.substr(parameter_section_size);
13040 // Keep the parameter section in |buffer|.
13041 buffer.erase(parameter_section_size);
13042 }
13043 std::unique_ptr<crypto::SecureHash> hash(
13044 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13045 hash->Update(response_code_bytes.data(), response_code_bytes.size());
13046 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13047 hash->Update(buffer.data(), buffer.size());
13048 std::string response_hash(32, 0);
13049 hash->Finish(std::data(response_hash), response_hash.size());
13050 if (tag == TPM_ST_SESSIONS) {
13051 if (!authorization_delegate)
13052 return TRUNKS_RC_AUTHORIZATION_FAILED;
13053 if (!authorization_delegate->CheckResponseAuthorization(
13054 response_hash, authorization_section_bytes)) {
13055 return TRUNKS_RC_AUTHORIZATION_FAILED;
13056 }
13057 }
13058 if (tag == TPM_ST_SESSIONS) {
13059 if (!authorization_delegate)
13060 return TRUNKS_RC_AUTHORIZATION_FAILED;
13061
13062 // Parse the encrypted parameter size.
13063 UINT16 size;
13064 std::string size_buffer = buffer.substr(0, 2);
13065 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13066 return result;
13067 }
13068 if (buffer.size() < 2 + size) {
13069 return TPM_RC_INSUFFICIENT;
13070 }
13071
13072 // Decrypt just the parameter data, not the size.
13073 std::string decrypted_data = buffer.substr(2, size);
13074 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13075 return TRUNKS_RC_ENCRYPTION_FAILED;
13076 }
13077 buffer.replace(2, size, decrypted_data);
13078 }
13079 std::string message_bytes;
13080 rc = Parse_TPM2B_PUBLIC_KEY_RSA(&buffer, message, &message_bytes);
13081 if (rc != TPM_RC_SUCCESS) {
13082 return rc;
13083 }
13084 return TPM_RC_SUCCESS;
13085 }
13086
RSA_DecryptErrorCallback(Tpm::RSA_DecryptResponse callback,TPM_RC response_code)13087 void RSA_DecryptErrorCallback(Tpm::RSA_DecryptResponse callback,
13088 TPM_RC response_code) {
13089 VLOG(1) << __func__;
13090 std::move(callback).Run(response_code, TPM2B_PUBLIC_KEY_RSA());
13091 }
13092
RSA_DecryptResponseParser(Tpm::RSA_DecryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13093 void RSA_DecryptResponseParser(Tpm::RSA_DecryptResponse callback,
13094 AuthorizationDelegate* authorization_delegate,
13095 const std::string& response) {
13096 VLOG(1) << __func__;
13097 TPM2B_PUBLIC_KEY_RSA message;
13098 TPM_RC rc = Tpm::ParseResponse_RSA_Decrypt(response, &message,
13099 authorization_delegate);
13100 if (rc != TPM_RC_SUCCESS) {
13101 base::OnceCallback<void(TPM_RC)> error_reporter =
13102 base::BindOnce(RSA_DecryptErrorCallback, std::move(callback));
13103 std::move(error_reporter).Run(rc);
13104 return;
13105 }
13106 std::move(callback).Run(rc, message);
13107 }
13108
RSA_Decrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & cipher_text,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,AuthorizationDelegate * authorization_delegate,RSA_DecryptResponse callback)13109 void Tpm::RSA_Decrypt(const TPMI_DH_OBJECT& key_handle,
13110 const std::string& key_handle_name,
13111 const TPM2B_PUBLIC_KEY_RSA& cipher_text,
13112 const TPMT_RSA_DECRYPT& in_scheme,
13113 const TPM2B_DATA& label,
13114 AuthorizationDelegate* authorization_delegate,
13115 RSA_DecryptResponse callback) {
13116 VLOG(1) << __func__;
13117 std::string command;
13118 TPM_RC rc = SerializeCommand_RSA_Decrypt(key_handle, key_handle_name,
13119 cipher_text, in_scheme, label,
13120 &command, authorization_delegate);
13121 if (rc != TPM_RC_SUCCESS) {
13122 base::OnceCallback<void(TPM_RC)> error_reporter =
13123 base::BindOnce(RSA_DecryptErrorCallback, std::move(callback));
13124 std::move(error_reporter).Run(rc);
13125 return;
13126 }
13127 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13128 RSA_DecryptResponseParser, std::move(callback), authorization_delegate);
13129 transceiver_->SendCommand(command, std::move(parser));
13130 }
13131
RSA_DecryptSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & cipher_text,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,TPM2B_PUBLIC_KEY_RSA * message,AuthorizationDelegate * authorization_delegate)13132 TPM_RC Tpm::RSA_DecryptSync(const TPMI_DH_OBJECT& key_handle,
13133 const std::string& key_handle_name,
13134 const TPM2B_PUBLIC_KEY_RSA& cipher_text,
13135 const TPMT_RSA_DECRYPT& in_scheme,
13136 const TPM2B_DATA& label,
13137 TPM2B_PUBLIC_KEY_RSA* message,
13138 AuthorizationDelegate* authorization_delegate) {
13139 VLOG(1) << __func__;
13140 std::string command;
13141 TPM_RC rc = SerializeCommand_RSA_Decrypt(key_handle, key_handle_name,
13142 cipher_text, in_scheme, label,
13143 &command, authorization_delegate);
13144 if (rc != TPM_RC_SUCCESS) {
13145 return rc;
13146 }
13147 std::string response = transceiver_->SendCommandAndWait(command);
13148 rc = ParseResponse_RSA_Decrypt(response, message, authorization_delegate);
13149 return rc;
13150 }
13151
SerializeCommand_ECDH_KeyGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13152 TPM_RC Tpm::SerializeCommand_ECDH_KeyGen(
13153 const TPMI_DH_OBJECT& key_handle,
13154 const std::string& key_handle_name,
13155 std::string* serialized_command,
13156 AuthorizationDelegate* authorization_delegate) {
13157 VLOG(3) << __func__;
13158 TPM_RC rc = TPM_RC_SUCCESS;
13159 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13160 UINT32 command_size = 10; // Header size.
13161 std::string handle_section_bytes;
13162 std::string parameter_section_bytes;
13163 TPM_CC command_code = TPM_CC_ECDH_KeyGen;
13164 bool is_command_parameter_encryption_possible = false;
13165 bool is_response_parameter_encryption_possible = true;
13166 std::string command_code_bytes;
13167 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13168 if (rc != TPM_RC_SUCCESS) {
13169 return rc;
13170 }
13171 std::string key_handle_bytes;
13172 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13173 if (rc != TPM_RC_SUCCESS) {
13174 return rc;
13175 }
13176 std::unique_ptr<crypto::SecureHash> hash(
13177 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13178 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13179 hash->Update(key_handle_name.data(), key_handle_name.size());
13180 handle_section_bytes += key_handle_bytes;
13181 command_size += key_handle_bytes.size();
13182 std::string command_hash(32, 0);
13183 hash->Finish(std::data(command_hash), command_hash.size());
13184 std::string authorization_section_bytes;
13185 std::string authorization_size_bytes;
13186 if (authorization_delegate) {
13187 if (!authorization_delegate->GetCommandAuthorization(
13188 command_hash, is_command_parameter_encryption_possible,
13189 is_response_parameter_encryption_possible,
13190 &authorization_section_bytes)) {
13191 return TRUNKS_RC_AUTHORIZATION_FAILED;
13192 }
13193 if (!authorization_section_bytes.empty()) {
13194 tag = TPM_ST_SESSIONS;
13195 std::string tmp;
13196 rc = Serialize_UINT32(authorization_section_bytes.size(),
13197 &authorization_size_bytes);
13198 if (rc != TPM_RC_SUCCESS) {
13199 return rc;
13200 }
13201 command_size +=
13202 authorization_size_bytes.size() + authorization_section_bytes.size();
13203 }
13204 }
13205 std::string tag_bytes;
13206 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13207 if (rc != TPM_RC_SUCCESS) {
13208 return rc;
13209 }
13210 std::string command_size_bytes;
13211 rc = Serialize_UINT32(command_size, &command_size_bytes);
13212 if (rc != TPM_RC_SUCCESS) {
13213 return rc;
13214 }
13215 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13216 handle_section_bytes + authorization_size_bytes +
13217 authorization_section_bytes + parameter_section_bytes;
13218 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13219 VLOG(2) << "Command: "
13220 << base::HexEncode(serialized_command->data(),
13221 serialized_command->size());
13222 return TPM_RC_SUCCESS;
13223 }
13224
ParseResponse_ECDH_KeyGen(const std::string & response,TPM2B_ECC_POINT * z_point,TPM2B_ECC_POINT * pub_point,AuthorizationDelegate * authorization_delegate)13225 TPM_RC Tpm::ParseResponse_ECDH_KeyGen(
13226 const std::string& response,
13227 TPM2B_ECC_POINT* z_point,
13228 TPM2B_ECC_POINT* pub_point,
13229 AuthorizationDelegate* authorization_delegate) {
13230 VLOG(3) << __func__;
13231 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13232 TPM_RC rc = TPM_RC_SUCCESS;
13233 std::string buffer(response);
13234 TPM_ST tag;
13235 std::string tag_bytes;
13236 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13237 if (rc != TPM_RC_SUCCESS) {
13238 return rc;
13239 }
13240 UINT32 response_size;
13241 std::string response_size_bytes;
13242 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13243 if (rc != TPM_RC_SUCCESS) {
13244 return rc;
13245 }
13246 TPM_RC response_code;
13247 std::string response_code_bytes;
13248 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13249 if (rc != TPM_RC_SUCCESS) {
13250 return rc;
13251 }
13252 if (response_size != response.size()) {
13253 return TPM_RC_SIZE;
13254 }
13255 if (response_code != TPM_RC_SUCCESS) {
13256 return response_code;
13257 }
13258 TPM_CC command_code = TPM_CC_ECDH_KeyGen;
13259 std::string command_code_bytes;
13260 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13261 if (rc != TPM_RC_SUCCESS) {
13262 return rc;
13263 }
13264 std::string authorization_section_bytes;
13265 if (tag == TPM_ST_SESSIONS) {
13266 UINT32 parameter_section_size = buffer.size();
13267 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
13268 if (rc != TPM_RC_SUCCESS) {
13269 return rc;
13270 }
13271 if (parameter_section_size > buffer.size()) {
13272 return TPM_RC_INSUFFICIENT;
13273 }
13274 authorization_section_bytes = buffer.substr(parameter_section_size);
13275 // Keep the parameter section in |buffer|.
13276 buffer.erase(parameter_section_size);
13277 }
13278 std::unique_ptr<crypto::SecureHash> hash(
13279 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13280 hash->Update(response_code_bytes.data(), response_code_bytes.size());
13281 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13282 hash->Update(buffer.data(), buffer.size());
13283 std::string response_hash(32, 0);
13284 hash->Finish(std::data(response_hash), response_hash.size());
13285 if (tag == TPM_ST_SESSIONS) {
13286 if (!authorization_delegate)
13287 return TRUNKS_RC_AUTHORIZATION_FAILED;
13288 if (!authorization_delegate->CheckResponseAuthorization(
13289 response_hash, authorization_section_bytes)) {
13290 return TRUNKS_RC_AUTHORIZATION_FAILED;
13291 }
13292 }
13293 if (tag == TPM_ST_SESSIONS) {
13294 if (!authorization_delegate)
13295 return TRUNKS_RC_AUTHORIZATION_FAILED;
13296
13297 // Parse the encrypted parameter size.
13298 UINT16 size;
13299 std::string size_buffer = buffer.substr(0, 2);
13300 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13301 return result;
13302 }
13303 if (buffer.size() < 2 + size) {
13304 return TPM_RC_INSUFFICIENT;
13305 }
13306
13307 // Decrypt just the parameter data, not the size.
13308 std::string decrypted_data = buffer.substr(2, size);
13309 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13310 return TRUNKS_RC_ENCRYPTION_FAILED;
13311 }
13312 buffer.replace(2, size, decrypted_data);
13313 }
13314 std::string z_point_bytes;
13315 rc = Parse_TPM2B_ECC_POINT(&buffer, z_point, &z_point_bytes);
13316 if (rc != TPM_RC_SUCCESS) {
13317 return rc;
13318 }
13319 std::string pub_point_bytes;
13320 rc = Parse_TPM2B_ECC_POINT(&buffer, pub_point, &pub_point_bytes);
13321 if (rc != TPM_RC_SUCCESS) {
13322 return rc;
13323 }
13324 return TPM_RC_SUCCESS;
13325 }
13326
ECDH_KeyGenErrorCallback(Tpm::ECDH_KeyGenResponse callback,TPM_RC response_code)13327 void ECDH_KeyGenErrorCallback(Tpm::ECDH_KeyGenResponse callback,
13328 TPM_RC response_code) {
13329 VLOG(1) << __func__;
13330 std::move(callback).Run(response_code, TPM2B_ECC_POINT(), TPM2B_ECC_POINT());
13331 }
13332
ECDH_KeyGenResponseParser(Tpm::ECDH_KeyGenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13333 void ECDH_KeyGenResponseParser(Tpm::ECDH_KeyGenResponse callback,
13334 AuthorizationDelegate* authorization_delegate,
13335 const std::string& response) {
13336 VLOG(1) << __func__;
13337 TPM2B_ECC_POINT z_point;
13338 TPM2B_ECC_POINT pub_point;
13339 TPM_RC rc = Tpm::ParseResponse_ECDH_KeyGen(response, &z_point, &pub_point,
13340 authorization_delegate);
13341 if (rc != TPM_RC_SUCCESS) {
13342 base::OnceCallback<void(TPM_RC)> error_reporter =
13343 base::BindOnce(ECDH_KeyGenErrorCallback, std::move(callback));
13344 std::move(error_reporter).Run(rc);
13345 return;
13346 }
13347 std::move(callback).Run(rc, z_point, pub_point);
13348 }
13349
ECDH_KeyGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,AuthorizationDelegate * authorization_delegate,ECDH_KeyGenResponse callback)13350 void Tpm::ECDH_KeyGen(const TPMI_DH_OBJECT& key_handle,
13351 const std::string& key_handle_name,
13352 AuthorizationDelegate* authorization_delegate,
13353 ECDH_KeyGenResponse callback) {
13354 VLOG(1) << __func__;
13355 std::string command;
13356 TPM_RC rc = SerializeCommand_ECDH_KeyGen(key_handle, key_handle_name,
13357 &command, authorization_delegate);
13358 if (rc != TPM_RC_SUCCESS) {
13359 base::OnceCallback<void(TPM_RC)> error_reporter =
13360 base::BindOnce(ECDH_KeyGenErrorCallback, std::move(callback));
13361 std::move(error_reporter).Run(rc);
13362 return;
13363 }
13364 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13365 ECDH_KeyGenResponseParser, std::move(callback), authorization_delegate);
13366 transceiver_->SendCommand(command, std::move(parser));
13367 }
13368
ECDH_KeyGenSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,TPM2B_ECC_POINT * z_point,TPM2B_ECC_POINT * pub_point,AuthorizationDelegate * authorization_delegate)13369 TPM_RC Tpm::ECDH_KeyGenSync(const TPMI_DH_OBJECT& key_handle,
13370 const std::string& key_handle_name,
13371 TPM2B_ECC_POINT* z_point,
13372 TPM2B_ECC_POINT* pub_point,
13373 AuthorizationDelegate* authorization_delegate) {
13374 VLOG(1) << __func__;
13375 std::string command;
13376 TPM_RC rc = SerializeCommand_ECDH_KeyGen(key_handle, key_handle_name,
13377 &command, authorization_delegate);
13378 if (rc != TPM_RC_SUCCESS) {
13379 return rc;
13380 }
13381 std::string response = transceiver_->SendCommandAndWait(command);
13382 rc = ParseResponse_ECDH_KeyGen(response, z_point, pub_point,
13383 authorization_delegate);
13384 return rc;
13385 }
13386
SerializeCommand_ECDH_ZGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ECC_POINT & in_point,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13387 TPM_RC Tpm::SerializeCommand_ECDH_ZGen(
13388 const TPMI_DH_OBJECT& key_handle,
13389 const std::string& key_handle_name,
13390 const TPM2B_ECC_POINT& in_point,
13391 std::string* serialized_command,
13392 AuthorizationDelegate* authorization_delegate) {
13393 VLOG(3) << __func__;
13394 TPM_RC rc = TPM_RC_SUCCESS;
13395 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13396 UINT32 command_size = 10; // Header size.
13397 std::string handle_section_bytes;
13398 std::string parameter_section_bytes;
13399 TPM_CC command_code = TPM_CC_ECDH_ZGen;
13400 bool is_command_parameter_encryption_possible = true;
13401 bool is_response_parameter_encryption_possible = true;
13402 std::string command_code_bytes;
13403 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13404 if (rc != TPM_RC_SUCCESS) {
13405 return rc;
13406 }
13407 std::string key_handle_bytes;
13408 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13409 if (rc != TPM_RC_SUCCESS) {
13410 return rc;
13411 }
13412 std::string in_point_bytes;
13413 rc = Serialize_TPM2B_ECC_POINT(in_point, &in_point_bytes);
13414 if (rc != TPM_RC_SUCCESS) {
13415 return rc;
13416 }
13417 if (authorization_delegate) {
13418 // Encrypt just the parameter data, not the size.
13419 std::string tmp = in_point_bytes.substr(2);
13420 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
13421 return TRUNKS_RC_ENCRYPTION_FAILED;
13422 }
13423 in_point_bytes.replace(2, std::string::npos, tmp);
13424 }
13425 std::unique_ptr<crypto::SecureHash> hash(
13426 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13427 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13428 hash->Update(key_handle_name.data(), key_handle_name.size());
13429 handle_section_bytes += key_handle_bytes;
13430 command_size += key_handle_bytes.size();
13431 hash->Update(in_point_bytes.data(), in_point_bytes.size());
13432 parameter_section_bytes += in_point_bytes;
13433 command_size += in_point_bytes.size();
13434 std::string command_hash(32, 0);
13435 hash->Finish(std::data(command_hash), command_hash.size());
13436 std::string authorization_section_bytes;
13437 std::string authorization_size_bytes;
13438 if (authorization_delegate) {
13439 if (!authorization_delegate->GetCommandAuthorization(
13440 command_hash, is_command_parameter_encryption_possible,
13441 is_response_parameter_encryption_possible,
13442 &authorization_section_bytes)) {
13443 return TRUNKS_RC_AUTHORIZATION_FAILED;
13444 }
13445 if (!authorization_section_bytes.empty()) {
13446 tag = TPM_ST_SESSIONS;
13447 std::string tmp;
13448 rc = Serialize_UINT32(authorization_section_bytes.size(),
13449 &authorization_size_bytes);
13450 if (rc != TPM_RC_SUCCESS) {
13451 return rc;
13452 }
13453 command_size +=
13454 authorization_size_bytes.size() + authorization_section_bytes.size();
13455 }
13456 }
13457 std::string tag_bytes;
13458 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13459 if (rc != TPM_RC_SUCCESS) {
13460 return rc;
13461 }
13462 std::string command_size_bytes;
13463 rc = Serialize_UINT32(command_size, &command_size_bytes);
13464 if (rc != TPM_RC_SUCCESS) {
13465 return rc;
13466 }
13467 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13468 handle_section_bytes + authorization_size_bytes +
13469 authorization_section_bytes + parameter_section_bytes;
13470 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13471 VLOG(2) << "Command: "
13472 << base::HexEncode(serialized_command->data(),
13473 serialized_command->size());
13474 return TPM_RC_SUCCESS;
13475 }
13476
ParseResponse_ECDH_ZGen(const std::string & response,TPM2B_ECC_POINT * out_point,AuthorizationDelegate * authorization_delegate)13477 TPM_RC Tpm::ParseResponse_ECDH_ZGen(
13478 const std::string& response,
13479 TPM2B_ECC_POINT* out_point,
13480 AuthorizationDelegate* authorization_delegate) {
13481 VLOG(3) << __func__;
13482 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13483 TPM_RC rc = TPM_RC_SUCCESS;
13484 std::string buffer(response);
13485 TPM_ST tag;
13486 std::string tag_bytes;
13487 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13488 if (rc != TPM_RC_SUCCESS) {
13489 return rc;
13490 }
13491 UINT32 response_size;
13492 std::string response_size_bytes;
13493 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13494 if (rc != TPM_RC_SUCCESS) {
13495 return rc;
13496 }
13497 TPM_RC response_code;
13498 std::string response_code_bytes;
13499 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13500 if (rc != TPM_RC_SUCCESS) {
13501 return rc;
13502 }
13503 if (response_size != response.size()) {
13504 return TPM_RC_SIZE;
13505 }
13506 if (response_code != TPM_RC_SUCCESS) {
13507 return response_code;
13508 }
13509 TPM_CC command_code = TPM_CC_ECDH_ZGen;
13510 std::string command_code_bytes;
13511 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13512 if (rc != TPM_RC_SUCCESS) {
13513 return rc;
13514 }
13515 std::string authorization_section_bytes;
13516 if (tag == TPM_ST_SESSIONS) {
13517 UINT32 parameter_section_size = buffer.size();
13518 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
13519 if (rc != TPM_RC_SUCCESS) {
13520 return rc;
13521 }
13522 if (parameter_section_size > buffer.size()) {
13523 return TPM_RC_INSUFFICIENT;
13524 }
13525 authorization_section_bytes = buffer.substr(parameter_section_size);
13526 // Keep the parameter section in |buffer|.
13527 buffer.erase(parameter_section_size);
13528 }
13529 std::unique_ptr<crypto::SecureHash> hash(
13530 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13531 hash->Update(response_code_bytes.data(), response_code_bytes.size());
13532 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13533 hash->Update(buffer.data(), buffer.size());
13534 std::string response_hash(32, 0);
13535 hash->Finish(std::data(response_hash), response_hash.size());
13536 if (tag == TPM_ST_SESSIONS) {
13537 if (!authorization_delegate)
13538 return TRUNKS_RC_AUTHORIZATION_FAILED;
13539 if (!authorization_delegate->CheckResponseAuthorization(
13540 response_hash, authorization_section_bytes)) {
13541 return TRUNKS_RC_AUTHORIZATION_FAILED;
13542 }
13543 }
13544 if (tag == TPM_ST_SESSIONS) {
13545 if (!authorization_delegate)
13546 return TRUNKS_RC_AUTHORIZATION_FAILED;
13547
13548 // Parse the encrypted parameter size.
13549 UINT16 size;
13550 std::string size_buffer = buffer.substr(0, 2);
13551 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13552 return result;
13553 }
13554 if (buffer.size() < 2 + size) {
13555 return TPM_RC_INSUFFICIENT;
13556 }
13557
13558 // Decrypt just the parameter data, not the size.
13559 std::string decrypted_data = buffer.substr(2, size);
13560 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13561 return TRUNKS_RC_ENCRYPTION_FAILED;
13562 }
13563 buffer.replace(2, size, decrypted_data);
13564 }
13565 std::string out_point_bytes;
13566 rc = Parse_TPM2B_ECC_POINT(&buffer, out_point, &out_point_bytes);
13567 if (rc != TPM_RC_SUCCESS) {
13568 return rc;
13569 }
13570 return TPM_RC_SUCCESS;
13571 }
13572
ECDH_ZGenErrorCallback(Tpm::ECDH_ZGenResponse callback,TPM_RC response_code)13573 void ECDH_ZGenErrorCallback(Tpm::ECDH_ZGenResponse callback,
13574 TPM_RC response_code) {
13575 VLOG(1) << __func__;
13576 std::move(callback).Run(response_code, TPM2B_ECC_POINT());
13577 }
13578
ECDH_ZGenResponseParser(Tpm::ECDH_ZGenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13579 void ECDH_ZGenResponseParser(Tpm::ECDH_ZGenResponse callback,
13580 AuthorizationDelegate* authorization_delegate,
13581 const std::string& response) {
13582 VLOG(1) << __func__;
13583 TPM2B_ECC_POINT out_point;
13584 TPM_RC rc = Tpm::ParseResponse_ECDH_ZGen(response, &out_point,
13585 authorization_delegate);
13586 if (rc != TPM_RC_SUCCESS) {
13587 base::OnceCallback<void(TPM_RC)> error_reporter =
13588 base::BindOnce(ECDH_ZGenErrorCallback, std::move(callback));
13589 std::move(error_reporter).Run(rc);
13590 return;
13591 }
13592 std::move(callback).Run(rc, out_point);
13593 }
13594
ECDH_ZGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ECC_POINT & in_point,AuthorizationDelegate * authorization_delegate,ECDH_ZGenResponse callback)13595 void Tpm::ECDH_ZGen(const TPMI_DH_OBJECT& key_handle,
13596 const std::string& key_handle_name,
13597 const TPM2B_ECC_POINT& in_point,
13598 AuthorizationDelegate* authorization_delegate,
13599 ECDH_ZGenResponse callback) {
13600 VLOG(1) << __func__;
13601 std::string command;
13602 TPM_RC rc = SerializeCommand_ECDH_ZGen(key_handle, key_handle_name, in_point,
13603 &command, authorization_delegate);
13604 if (rc != TPM_RC_SUCCESS) {
13605 base::OnceCallback<void(TPM_RC)> error_reporter =
13606 base::BindOnce(ECDH_ZGenErrorCallback, std::move(callback));
13607 std::move(error_reporter).Run(rc);
13608 return;
13609 }
13610 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13611 ECDH_ZGenResponseParser, std::move(callback), authorization_delegate);
13612 transceiver_->SendCommand(command, std::move(parser));
13613 }
13614
ECDH_ZGenSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ECC_POINT & in_point,TPM2B_ECC_POINT * out_point,AuthorizationDelegate * authorization_delegate)13615 TPM_RC Tpm::ECDH_ZGenSync(const TPMI_DH_OBJECT& key_handle,
13616 const std::string& key_handle_name,
13617 const TPM2B_ECC_POINT& in_point,
13618 TPM2B_ECC_POINT* out_point,
13619 AuthorizationDelegate* authorization_delegate) {
13620 VLOG(1) << __func__;
13621 std::string command;
13622 TPM_RC rc = SerializeCommand_ECDH_ZGen(key_handle, key_handle_name, in_point,
13623 &command, authorization_delegate);
13624 if (rc != TPM_RC_SUCCESS) {
13625 return rc;
13626 }
13627 std::string response = transceiver_->SendCommandAndWait(command);
13628 rc = ParseResponse_ECDH_ZGen(response, out_point, authorization_delegate);
13629 return rc;
13630 }
13631
SerializeCommand_ECC_Parameters(const TPMI_ECC_CURVE & curve_id,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13632 TPM_RC Tpm::SerializeCommand_ECC_Parameters(
13633 const TPMI_ECC_CURVE& curve_id,
13634 std::string* serialized_command,
13635 AuthorizationDelegate* authorization_delegate) {
13636 VLOG(3) << __func__;
13637 TPM_RC rc = TPM_RC_SUCCESS;
13638 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13639 UINT32 command_size = 10; // Header size.
13640 std::string handle_section_bytes;
13641 std::string parameter_section_bytes;
13642 TPM_CC command_code = TPM_CC_ECC_Parameters;
13643 bool is_command_parameter_encryption_possible = false;
13644 bool is_response_parameter_encryption_possible = false;
13645 std::string command_code_bytes;
13646 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13647 if (rc != TPM_RC_SUCCESS) {
13648 return rc;
13649 }
13650 std::string curve_id_bytes;
13651 rc = Serialize_TPMI_ECC_CURVE(curve_id, &curve_id_bytes);
13652 if (rc != TPM_RC_SUCCESS) {
13653 return rc;
13654 }
13655 std::unique_ptr<crypto::SecureHash> hash(
13656 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13657 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13658 hash->Update(curve_id_bytes.data(), curve_id_bytes.size());
13659 parameter_section_bytes += curve_id_bytes;
13660 command_size += curve_id_bytes.size();
13661 std::string command_hash(32, 0);
13662 hash->Finish(std::data(command_hash), command_hash.size());
13663 std::string authorization_section_bytes;
13664 std::string authorization_size_bytes;
13665 if (authorization_delegate) {
13666 if (!authorization_delegate->GetCommandAuthorization(
13667 command_hash, is_command_parameter_encryption_possible,
13668 is_response_parameter_encryption_possible,
13669 &authorization_section_bytes)) {
13670 return TRUNKS_RC_AUTHORIZATION_FAILED;
13671 }
13672 if (!authorization_section_bytes.empty()) {
13673 tag = TPM_ST_SESSIONS;
13674 std::string tmp;
13675 rc = Serialize_UINT32(authorization_section_bytes.size(),
13676 &authorization_size_bytes);
13677 if (rc != TPM_RC_SUCCESS) {
13678 return rc;
13679 }
13680 command_size +=
13681 authorization_size_bytes.size() + authorization_section_bytes.size();
13682 }
13683 }
13684 std::string tag_bytes;
13685 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13686 if (rc != TPM_RC_SUCCESS) {
13687 return rc;
13688 }
13689 std::string command_size_bytes;
13690 rc = Serialize_UINT32(command_size, &command_size_bytes);
13691 if (rc != TPM_RC_SUCCESS) {
13692 return rc;
13693 }
13694 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13695 handle_section_bytes + authorization_size_bytes +
13696 authorization_section_bytes + parameter_section_bytes;
13697 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13698 VLOG(2) << "Command: "
13699 << base::HexEncode(serialized_command->data(),
13700 serialized_command->size());
13701 return TPM_RC_SUCCESS;
13702 }
13703
ParseResponse_ECC_Parameters(const std::string & response,TPMS_ALGORITHM_DETAIL_ECC * parameters,AuthorizationDelegate * authorization_delegate)13704 TPM_RC Tpm::ParseResponse_ECC_Parameters(
13705 const std::string& response,
13706 TPMS_ALGORITHM_DETAIL_ECC* parameters,
13707 AuthorizationDelegate* authorization_delegate) {
13708 VLOG(3) << __func__;
13709 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13710 TPM_RC rc = TPM_RC_SUCCESS;
13711 std::string buffer(response);
13712 TPM_ST tag;
13713 std::string tag_bytes;
13714 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13715 if (rc != TPM_RC_SUCCESS) {
13716 return rc;
13717 }
13718 UINT32 response_size;
13719 std::string response_size_bytes;
13720 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13721 if (rc != TPM_RC_SUCCESS) {
13722 return rc;
13723 }
13724 TPM_RC response_code;
13725 std::string response_code_bytes;
13726 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13727 if (rc != TPM_RC_SUCCESS) {
13728 return rc;
13729 }
13730 if (response_size != response.size()) {
13731 return TPM_RC_SIZE;
13732 }
13733 if (response_code != TPM_RC_SUCCESS) {
13734 return response_code;
13735 }
13736 TPM_CC command_code = TPM_CC_ECC_Parameters;
13737 std::string command_code_bytes;
13738 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13739 if (rc != TPM_RC_SUCCESS) {
13740 return rc;
13741 }
13742 std::string authorization_section_bytes;
13743 if (tag == TPM_ST_SESSIONS) {
13744 UINT32 parameter_section_size = buffer.size();
13745 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
13746 if (rc != TPM_RC_SUCCESS) {
13747 return rc;
13748 }
13749 if (parameter_section_size > buffer.size()) {
13750 return TPM_RC_INSUFFICIENT;
13751 }
13752 authorization_section_bytes = buffer.substr(parameter_section_size);
13753 // Keep the parameter section in |buffer|.
13754 buffer.erase(parameter_section_size);
13755 }
13756 std::unique_ptr<crypto::SecureHash> hash(
13757 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13758 hash->Update(response_code_bytes.data(), response_code_bytes.size());
13759 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13760 hash->Update(buffer.data(), buffer.size());
13761 std::string response_hash(32, 0);
13762 hash->Finish(std::data(response_hash), response_hash.size());
13763 if (tag == TPM_ST_SESSIONS) {
13764 if (!authorization_delegate)
13765 return TRUNKS_RC_AUTHORIZATION_FAILED;
13766 if (!authorization_delegate->CheckResponseAuthorization(
13767 response_hash, authorization_section_bytes)) {
13768 return TRUNKS_RC_AUTHORIZATION_FAILED;
13769 }
13770 }
13771 std::string parameters_bytes;
13772 rc = Parse_TPMS_ALGORITHM_DETAIL_ECC(&buffer, parameters, ¶meters_bytes);
13773 if (rc != TPM_RC_SUCCESS) {
13774 return rc;
13775 }
13776 return TPM_RC_SUCCESS;
13777 }
13778
ECC_ParametersErrorCallback(Tpm::ECC_ParametersResponse callback,TPM_RC response_code)13779 void ECC_ParametersErrorCallback(Tpm::ECC_ParametersResponse callback,
13780 TPM_RC response_code) {
13781 VLOG(1) << __func__;
13782 std::move(callback).Run(response_code, TPMS_ALGORITHM_DETAIL_ECC());
13783 }
13784
ECC_ParametersResponseParser(Tpm::ECC_ParametersResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13785 void ECC_ParametersResponseParser(Tpm::ECC_ParametersResponse callback,
13786 AuthorizationDelegate* authorization_delegate,
13787 const std::string& response) {
13788 VLOG(1) << __func__;
13789 TPMS_ALGORITHM_DETAIL_ECC parameters;
13790 TPM_RC rc = Tpm::ParseResponse_ECC_Parameters(response, ¶meters,
13791 authorization_delegate);
13792 if (rc != TPM_RC_SUCCESS) {
13793 base::OnceCallback<void(TPM_RC)> error_reporter =
13794 base::BindOnce(ECC_ParametersErrorCallback, std::move(callback));
13795 std::move(error_reporter).Run(rc);
13796 return;
13797 }
13798 std::move(callback).Run(rc, parameters);
13799 }
13800
ECC_Parameters(const TPMI_ECC_CURVE & curve_id,AuthorizationDelegate * authorization_delegate,ECC_ParametersResponse callback)13801 void Tpm::ECC_Parameters(const TPMI_ECC_CURVE& curve_id,
13802 AuthorizationDelegate* authorization_delegate,
13803 ECC_ParametersResponse callback) {
13804 VLOG(1) << __func__;
13805 std::string command;
13806 TPM_RC rc = SerializeCommand_ECC_Parameters(curve_id, &command,
13807 authorization_delegate);
13808 if (rc != TPM_RC_SUCCESS) {
13809 base::OnceCallback<void(TPM_RC)> error_reporter =
13810 base::BindOnce(ECC_ParametersErrorCallback, std::move(callback));
13811 std::move(error_reporter).Run(rc);
13812 return;
13813 }
13814 base::OnceCallback<void(const std::string&)> parser =
13815 base::BindOnce(ECC_ParametersResponseParser, std::move(callback),
13816 authorization_delegate);
13817 transceiver_->SendCommand(command, std::move(parser));
13818 }
13819
ECC_ParametersSync(const TPMI_ECC_CURVE & curve_id,TPMS_ALGORITHM_DETAIL_ECC * parameters,AuthorizationDelegate * authorization_delegate)13820 TPM_RC Tpm::ECC_ParametersSync(const TPMI_ECC_CURVE& curve_id,
13821 TPMS_ALGORITHM_DETAIL_ECC* parameters,
13822 AuthorizationDelegate* authorization_delegate) {
13823 VLOG(1) << __func__;
13824 std::string command;
13825 TPM_RC rc = SerializeCommand_ECC_Parameters(curve_id, &command,
13826 authorization_delegate);
13827 if (rc != TPM_RC_SUCCESS) {
13828 return rc;
13829 }
13830 std::string response = transceiver_->SendCommandAndWait(command);
13831 rc = ParseResponse_ECC_Parameters(response, parameters,
13832 authorization_delegate);
13833 return rc;
13834 }
13835
SerializeCommand_ZGen_2Phase(const TPMI_DH_OBJECT & key_a,const std::string & key_a_name,const TPM2B_ECC_POINT & in_qs_b,const TPM2B_ECC_POINT & in_qe_b,const TPMI_ECC_KEY_EXCHANGE & in_scheme,const UINT16 & counter,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13836 TPM_RC Tpm::SerializeCommand_ZGen_2Phase(
13837 const TPMI_DH_OBJECT& key_a,
13838 const std::string& key_a_name,
13839 const TPM2B_ECC_POINT& in_qs_b,
13840 const TPM2B_ECC_POINT& in_qe_b,
13841 const TPMI_ECC_KEY_EXCHANGE& in_scheme,
13842 const UINT16& counter,
13843 std::string* serialized_command,
13844 AuthorizationDelegate* authorization_delegate) {
13845 VLOG(3) << __func__;
13846 TPM_RC rc = TPM_RC_SUCCESS;
13847 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13848 UINT32 command_size = 10; // Header size.
13849 std::string handle_section_bytes;
13850 std::string parameter_section_bytes;
13851 TPM_CC command_code = TPM_CC_ZGen_2Phase;
13852 bool is_command_parameter_encryption_possible = true;
13853 bool is_response_parameter_encryption_possible = true;
13854 std::string command_code_bytes;
13855 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13856 if (rc != TPM_RC_SUCCESS) {
13857 return rc;
13858 }
13859 std::string key_a_bytes;
13860 rc = Serialize_TPMI_DH_OBJECT(key_a, &key_a_bytes);
13861 if (rc != TPM_RC_SUCCESS) {
13862 return rc;
13863 }
13864 std::string in_qs_b_bytes;
13865 rc = Serialize_TPM2B_ECC_POINT(in_qs_b, &in_qs_b_bytes);
13866 if (rc != TPM_RC_SUCCESS) {
13867 return rc;
13868 }
13869 std::string in_qe_b_bytes;
13870 rc = Serialize_TPM2B_ECC_POINT(in_qe_b, &in_qe_b_bytes);
13871 if (rc != TPM_RC_SUCCESS) {
13872 return rc;
13873 }
13874 std::string in_scheme_bytes;
13875 rc = Serialize_TPMI_ECC_KEY_EXCHANGE(in_scheme, &in_scheme_bytes);
13876 if (rc != TPM_RC_SUCCESS) {
13877 return rc;
13878 }
13879 std::string counter_bytes;
13880 rc = Serialize_UINT16(counter, &counter_bytes);
13881 if (rc != TPM_RC_SUCCESS) {
13882 return rc;
13883 }
13884 if (authorization_delegate) {
13885 // Encrypt just the parameter data, not the size.
13886 std::string tmp = in_qs_b_bytes.substr(2);
13887 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
13888 return TRUNKS_RC_ENCRYPTION_FAILED;
13889 }
13890 in_qs_b_bytes.replace(2, std::string::npos, tmp);
13891 }
13892 std::unique_ptr<crypto::SecureHash> hash(
13893 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13894 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13895 hash->Update(key_a_name.data(), key_a_name.size());
13896 handle_section_bytes += key_a_bytes;
13897 command_size += key_a_bytes.size();
13898 hash->Update(in_qs_b_bytes.data(), in_qs_b_bytes.size());
13899 parameter_section_bytes += in_qs_b_bytes;
13900 command_size += in_qs_b_bytes.size();
13901 hash->Update(in_qe_b_bytes.data(), in_qe_b_bytes.size());
13902 parameter_section_bytes += in_qe_b_bytes;
13903 command_size += in_qe_b_bytes.size();
13904 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
13905 parameter_section_bytes += in_scheme_bytes;
13906 command_size += in_scheme_bytes.size();
13907 hash->Update(counter_bytes.data(), counter_bytes.size());
13908 parameter_section_bytes += counter_bytes;
13909 command_size += counter_bytes.size();
13910 std::string command_hash(32, 0);
13911 hash->Finish(std::data(command_hash), command_hash.size());
13912 std::string authorization_section_bytes;
13913 std::string authorization_size_bytes;
13914 if (authorization_delegate) {
13915 if (!authorization_delegate->GetCommandAuthorization(
13916 command_hash, is_command_parameter_encryption_possible,
13917 is_response_parameter_encryption_possible,
13918 &authorization_section_bytes)) {
13919 return TRUNKS_RC_AUTHORIZATION_FAILED;
13920 }
13921 if (!authorization_section_bytes.empty()) {
13922 tag = TPM_ST_SESSIONS;
13923 std::string tmp;
13924 rc = Serialize_UINT32(authorization_section_bytes.size(),
13925 &authorization_size_bytes);
13926 if (rc != TPM_RC_SUCCESS) {
13927 return rc;
13928 }
13929 command_size +=
13930 authorization_size_bytes.size() + authorization_section_bytes.size();
13931 }
13932 }
13933 std::string tag_bytes;
13934 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13935 if (rc != TPM_RC_SUCCESS) {
13936 return rc;
13937 }
13938 std::string command_size_bytes;
13939 rc = Serialize_UINT32(command_size, &command_size_bytes);
13940 if (rc != TPM_RC_SUCCESS) {
13941 return rc;
13942 }
13943 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13944 handle_section_bytes + authorization_size_bytes +
13945 authorization_section_bytes + parameter_section_bytes;
13946 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13947 VLOG(2) << "Command: "
13948 << base::HexEncode(serialized_command->data(),
13949 serialized_command->size());
13950 return TPM_RC_SUCCESS;
13951 }
13952
ParseResponse_ZGen_2Phase(const std::string & response,TPM2B_ECC_POINT * out_z1,TPM2B_ECC_POINT * out_z2,AuthorizationDelegate * authorization_delegate)13953 TPM_RC Tpm::ParseResponse_ZGen_2Phase(
13954 const std::string& response,
13955 TPM2B_ECC_POINT* out_z1,
13956 TPM2B_ECC_POINT* out_z2,
13957 AuthorizationDelegate* authorization_delegate) {
13958 VLOG(3) << __func__;
13959 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13960 TPM_RC rc = TPM_RC_SUCCESS;
13961 std::string buffer(response);
13962 TPM_ST tag;
13963 std::string tag_bytes;
13964 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13965 if (rc != TPM_RC_SUCCESS) {
13966 return rc;
13967 }
13968 UINT32 response_size;
13969 std::string response_size_bytes;
13970 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13971 if (rc != TPM_RC_SUCCESS) {
13972 return rc;
13973 }
13974 TPM_RC response_code;
13975 std::string response_code_bytes;
13976 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13977 if (rc != TPM_RC_SUCCESS) {
13978 return rc;
13979 }
13980 if (response_size != response.size()) {
13981 return TPM_RC_SIZE;
13982 }
13983 if (response_code != TPM_RC_SUCCESS) {
13984 return response_code;
13985 }
13986 TPM_CC command_code = TPM_CC_ZGen_2Phase;
13987 std::string command_code_bytes;
13988 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13989 if (rc != TPM_RC_SUCCESS) {
13990 return rc;
13991 }
13992 std::string authorization_section_bytes;
13993 if (tag == TPM_ST_SESSIONS) {
13994 UINT32 parameter_section_size = buffer.size();
13995 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
13996 if (rc != TPM_RC_SUCCESS) {
13997 return rc;
13998 }
13999 if (parameter_section_size > buffer.size()) {
14000 return TPM_RC_INSUFFICIENT;
14001 }
14002 authorization_section_bytes = buffer.substr(parameter_section_size);
14003 // Keep the parameter section in |buffer|.
14004 buffer.erase(parameter_section_size);
14005 }
14006 std::unique_ptr<crypto::SecureHash> hash(
14007 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14008 hash->Update(response_code_bytes.data(), response_code_bytes.size());
14009 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14010 hash->Update(buffer.data(), buffer.size());
14011 std::string response_hash(32, 0);
14012 hash->Finish(std::data(response_hash), response_hash.size());
14013 if (tag == TPM_ST_SESSIONS) {
14014 if (!authorization_delegate)
14015 return TRUNKS_RC_AUTHORIZATION_FAILED;
14016 if (!authorization_delegate->CheckResponseAuthorization(
14017 response_hash, authorization_section_bytes)) {
14018 return TRUNKS_RC_AUTHORIZATION_FAILED;
14019 }
14020 }
14021 if (tag == TPM_ST_SESSIONS) {
14022 if (!authorization_delegate)
14023 return TRUNKS_RC_AUTHORIZATION_FAILED;
14024
14025 // Parse the encrypted parameter size.
14026 UINT16 size;
14027 std::string size_buffer = buffer.substr(0, 2);
14028 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14029 return result;
14030 }
14031 if (buffer.size() < 2 + size) {
14032 return TPM_RC_INSUFFICIENT;
14033 }
14034
14035 // Decrypt just the parameter data, not the size.
14036 std::string decrypted_data = buffer.substr(2, size);
14037 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14038 return TRUNKS_RC_ENCRYPTION_FAILED;
14039 }
14040 buffer.replace(2, size, decrypted_data);
14041 }
14042 std::string out_z1_bytes;
14043 rc = Parse_TPM2B_ECC_POINT(&buffer, out_z1, &out_z1_bytes);
14044 if (rc != TPM_RC_SUCCESS) {
14045 return rc;
14046 }
14047 std::string out_z2_bytes;
14048 rc = Parse_TPM2B_ECC_POINT(&buffer, out_z2, &out_z2_bytes);
14049 if (rc != TPM_RC_SUCCESS) {
14050 return rc;
14051 }
14052 return TPM_RC_SUCCESS;
14053 }
14054
ZGen_2PhaseErrorCallback(Tpm::ZGen_2PhaseResponse callback,TPM_RC response_code)14055 void ZGen_2PhaseErrorCallback(Tpm::ZGen_2PhaseResponse callback,
14056 TPM_RC response_code) {
14057 VLOG(1) << __func__;
14058 std::move(callback).Run(response_code, TPM2B_ECC_POINT(), TPM2B_ECC_POINT());
14059 }
14060
ZGen_2PhaseResponseParser(Tpm::ZGen_2PhaseResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14061 void ZGen_2PhaseResponseParser(Tpm::ZGen_2PhaseResponse callback,
14062 AuthorizationDelegate* authorization_delegate,
14063 const std::string& response) {
14064 VLOG(1) << __func__;
14065 TPM2B_ECC_POINT out_z1;
14066 TPM2B_ECC_POINT out_z2;
14067 TPM_RC rc = Tpm::ParseResponse_ZGen_2Phase(response, &out_z1, &out_z2,
14068 authorization_delegate);
14069 if (rc != TPM_RC_SUCCESS) {
14070 base::OnceCallback<void(TPM_RC)> error_reporter =
14071 base::BindOnce(ZGen_2PhaseErrorCallback, std::move(callback));
14072 std::move(error_reporter).Run(rc);
14073 return;
14074 }
14075 std::move(callback).Run(rc, out_z1, out_z2);
14076 }
14077
ZGen_2Phase(const TPMI_DH_OBJECT & key_a,const std::string & key_a_name,const TPM2B_ECC_POINT & in_qs_b,const TPM2B_ECC_POINT & in_qe_b,const TPMI_ECC_KEY_EXCHANGE & in_scheme,const UINT16 & counter,AuthorizationDelegate * authorization_delegate,ZGen_2PhaseResponse callback)14078 void Tpm::ZGen_2Phase(const TPMI_DH_OBJECT& key_a,
14079 const std::string& key_a_name,
14080 const TPM2B_ECC_POINT& in_qs_b,
14081 const TPM2B_ECC_POINT& in_qe_b,
14082 const TPMI_ECC_KEY_EXCHANGE& in_scheme,
14083 const UINT16& counter,
14084 AuthorizationDelegate* authorization_delegate,
14085 ZGen_2PhaseResponse callback) {
14086 VLOG(1) << __func__;
14087 std::string command;
14088 TPM_RC rc = SerializeCommand_ZGen_2Phase(key_a, key_a_name, in_qs_b, in_qe_b,
14089 in_scheme, counter, &command,
14090 authorization_delegate);
14091 if (rc != TPM_RC_SUCCESS) {
14092 base::OnceCallback<void(TPM_RC)> error_reporter =
14093 base::BindOnce(ZGen_2PhaseErrorCallback, std::move(callback));
14094 std::move(error_reporter).Run(rc);
14095 return;
14096 }
14097 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14098 ZGen_2PhaseResponseParser, std::move(callback), authorization_delegate);
14099 transceiver_->SendCommand(command, std::move(parser));
14100 }
14101
ZGen_2PhaseSync(const TPMI_DH_OBJECT & key_a,const std::string & key_a_name,const TPM2B_ECC_POINT & in_qs_b,const TPM2B_ECC_POINT & in_qe_b,const TPMI_ECC_KEY_EXCHANGE & in_scheme,const UINT16 & counter,TPM2B_ECC_POINT * out_z1,TPM2B_ECC_POINT * out_z2,AuthorizationDelegate * authorization_delegate)14102 TPM_RC Tpm::ZGen_2PhaseSync(const TPMI_DH_OBJECT& key_a,
14103 const std::string& key_a_name,
14104 const TPM2B_ECC_POINT& in_qs_b,
14105 const TPM2B_ECC_POINT& in_qe_b,
14106 const TPMI_ECC_KEY_EXCHANGE& in_scheme,
14107 const UINT16& counter,
14108 TPM2B_ECC_POINT* out_z1,
14109 TPM2B_ECC_POINT* out_z2,
14110 AuthorizationDelegate* authorization_delegate) {
14111 VLOG(1) << __func__;
14112 std::string command;
14113 TPM_RC rc = SerializeCommand_ZGen_2Phase(key_a, key_a_name, in_qs_b, in_qe_b,
14114 in_scheme, counter, &command,
14115 authorization_delegate);
14116 if (rc != TPM_RC_SUCCESS) {
14117 return rc;
14118 }
14119 std::string response = transceiver_->SendCommandAndWait(command);
14120 rc = ParseResponse_ZGen_2Phase(response, out_z1, out_z2,
14121 authorization_delegate);
14122 return rc;
14123 }
14124
SerializeCommand_EncryptDecrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPMI_YES_NO & decrypt,const TPMI_ALG_SYM_MODE & mode,const TPM2B_IV & iv_in,const TPM2B_MAX_BUFFER & in_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14125 TPM_RC Tpm::SerializeCommand_EncryptDecrypt(
14126 const TPMI_DH_OBJECT& key_handle,
14127 const std::string& key_handle_name,
14128 const TPMI_YES_NO& decrypt,
14129 const TPMI_ALG_SYM_MODE& mode,
14130 const TPM2B_IV& iv_in,
14131 const TPM2B_MAX_BUFFER& in_data,
14132 std::string* serialized_command,
14133 AuthorizationDelegate* authorization_delegate) {
14134 VLOG(3) << __func__;
14135 TPM_RC rc = TPM_RC_SUCCESS;
14136 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14137 UINT32 command_size = 10; // Header size.
14138 std::string handle_section_bytes;
14139 std::string parameter_section_bytes;
14140 TPM_CC command_code = TPM_CC_EncryptDecrypt;
14141 bool is_command_parameter_encryption_possible = false;
14142 bool is_response_parameter_encryption_possible = true;
14143 std::string command_code_bytes;
14144 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14145 if (rc != TPM_RC_SUCCESS) {
14146 return rc;
14147 }
14148 std::string key_handle_bytes;
14149 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
14150 if (rc != TPM_RC_SUCCESS) {
14151 return rc;
14152 }
14153 std::string decrypt_bytes;
14154 rc = Serialize_TPMI_YES_NO(decrypt, &decrypt_bytes);
14155 if (rc != TPM_RC_SUCCESS) {
14156 return rc;
14157 }
14158 std::string mode_bytes;
14159 rc = Serialize_TPMI_ALG_SYM_MODE(mode, &mode_bytes);
14160 if (rc != TPM_RC_SUCCESS) {
14161 return rc;
14162 }
14163 std::string iv_in_bytes;
14164 rc = Serialize_TPM2B_IV(iv_in, &iv_in_bytes);
14165 if (rc != TPM_RC_SUCCESS) {
14166 return rc;
14167 }
14168 std::string in_data_bytes;
14169 rc = Serialize_TPM2B_MAX_BUFFER(in_data, &in_data_bytes);
14170 if (rc != TPM_RC_SUCCESS) {
14171 return rc;
14172 }
14173 std::unique_ptr<crypto::SecureHash> hash(
14174 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14175 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14176 hash->Update(key_handle_name.data(), key_handle_name.size());
14177 handle_section_bytes += key_handle_bytes;
14178 command_size += key_handle_bytes.size();
14179 hash->Update(decrypt_bytes.data(), decrypt_bytes.size());
14180 parameter_section_bytes += decrypt_bytes;
14181 command_size += decrypt_bytes.size();
14182 hash->Update(mode_bytes.data(), mode_bytes.size());
14183 parameter_section_bytes += mode_bytes;
14184 command_size += mode_bytes.size();
14185 hash->Update(iv_in_bytes.data(), iv_in_bytes.size());
14186 parameter_section_bytes += iv_in_bytes;
14187 command_size += iv_in_bytes.size();
14188 hash->Update(in_data_bytes.data(), in_data_bytes.size());
14189 parameter_section_bytes += in_data_bytes;
14190 command_size += in_data_bytes.size();
14191 std::string command_hash(32, 0);
14192 hash->Finish(std::data(command_hash), command_hash.size());
14193 std::string authorization_section_bytes;
14194 std::string authorization_size_bytes;
14195 if (authorization_delegate) {
14196 if (!authorization_delegate->GetCommandAuthorization(
14197 command_hash, is_command_parameter_encryption_possible,
14198 is_response_parameter_encryption_possible,
14199 &authorization_section_bytes)) {
14200 return TRUNKS_RC_AUTHORIZATION_FAILED;
14201 }
14202 if (!authorization_section_bytes.empty()) {
14203 tag = TPM_ST_SESSIONS;
14204 std::string tmp;
14205 rc = Serialize_UINT32(authorization_section_bytes.size(),
14206 &authorization_size_bytes);
14207 if (rc != TPM_RC_SUCCESS) {
14208 return rc;
14209 }
14210 command_size +=
14211 authorization_size_bytes.size() + authorization_section_bytes.size();
14212 }
14213 }
14214 std::string tag_bytes;
14215 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14216 if (rc != TPM_RC_SUCCESS) {
14217 return rc;
14218 }
14219 std::string command_size_bytes;
14220 rc = Serialize_UINT32(command_size, &command_size_bytes);
14221 if (rc != TPM_RC_SUCCESS) {
14222 return rc;
14223 }
14224 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14225 handle_section_bytes + authorization_size_bytes +
14226 authorization_section_bytes + parameter_section_bytes;
14227 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14228 VLOG(2) << "Command: "
14229 << base::HexEncode(serialized_command->data(),
14230 serialized_command->size());
14231 return TPM_RC_SUCCESS;
14232 }
14233
ParseResponse_EncryptDecrypt(const std::string & response,TPM2B_MAX_BUFFER * out_data,TPM2B_IV * iv_out,AuthorizationDelegate * authorization_delegate)14234 TPM_RC Tpm::ParseResponse_EncryptDecrypt(
14235 const std::string& response,
14236 TPM2B_MAX_BUFFER* out_data,
14237 TPM2B_IV* iv_out,
14238 AuthorizationDelegate* authorization_delegate) {
14239 VLOG(3) << __func__;
14240 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14241 TPM_RC rc = TPM_RC_SUCCESS;
14242 std::string buffer(response);
14243 TPM_ST tag;
14244 std::string tag_bytes;
14245 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14246 if (rc != TPM_RC_SUCCESS) {
14247 return rc;
14248 }
14249 UINT32 response_size;
14250 std::string response_size_bytes;
14251 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14252 if (rc != TPM_RC_SUCCESS) {
14253 return rc;
14254 }
14255 TPM_RC response_code;
14256 std::string response_code_bytes;
14257 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14258 if (rc != TPM_RC_SUCCESS) {
14259 return rc;
14260 }
14261 if (response_size != response.size()) {
14262 return TPM_RC_SIZE;
14263 }
14264 if (response_code != TPM_RC_SUCCESS) {
14265 return response_code;
14266 }
14267 TPM_CC command_code = TPM_CC_EncryptDecrypt;
14268 std::string command_code_bytes;
14269 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14270 if (rc != TPM_RC_SUCCESS) {
14271 return rc;
14272 }
14273 std::string authorization_section_bytes;
14274 if (tag == TPM_ST_SESSIONS) {
14275 UINT32 parameter_section_size = buffer.size();
14276 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
14277 if (rc != TPM_RC_SUCCESS) {
14278 return rc;
14279 }
14280 if (parameter_section_size > buffer.size()) {
14281 return TPM_RC_INSUFFICIENT;
14282 }
14283 authorization_section_bytes = buffer.substr(parameter_section_size);
14284 // Keep the parameter section in |buffer|.
14285 buffer.erase(parameter_section_size);
14286 }
14287 std::unique_ptr<crypto::SecureHash> hash(
14288 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14289 hash->Update(response_code_bytes.data(), response_code_bytes.size());
14290 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14291 hash->Update(buffer.data(), buffer.size());
14292 std::string response_hash(32, 0);
14293 hash->Finish(std::data(response_hash), response_hash.size());
14294 if (tag == TPM_ST_SESSIONS) {
14295 if (!authorization_delegate)
14296 return TRUNKS_RC_AUTHORIZATION_FAILED;
14297 if (!authorization_delegate->CheckResponseAuthorization(
14298 response_hash, authorization_section_bytes)) {
14299 return TRUNKS_RC_AUTHORIZATION_FAILED;
14300 }
14301 }
14302 if (tag == TPM_ST_SESSIONS) {
14303 if (!authorization_delegate)
14304 return TRUNKS_RC_AUTHORIZATION_FAILED;
14305
14306 // Parse the encrypted parameter size.
14307 UINT16 size;
14308 std::string size_buffer = buffer.substr(0, 2);
14309 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14310 return result;
14311 }
14312 if (buffer.size() < 2 + size) {
14313 return TPM_RC_INSUFFICIENT;
14314 }
14315
14316 // Decrypt just the parameter data, not the size.
14317 std::string decrypted_data = buffer.substr(2, size);
14318 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14319 return TRUNKS_RC_ENCRYPTION_FAILED;
14320 }
14321 buffer.replace(2, size, decrypted_data);
14322 }
14323 std::string out_data_bytes;
14324 rc = Parse_TPM2B_MAX_BUFFER(&buffer, out_data, &out_data_bytes);
14325 if (rc != TPM_RC_SUCCESS) {
14326 return rc;
14327 }
14328 std::string iv_out_bytes;
14329 rc = Parse_TPM2B_IV(&buffer, iv_out, &iv_out_bytes);
14330 if (rc != TPM_RC_SUCCESS) {
14331 return rc;
14332 }
14333 return TPM_RC_SUCCESS;
14334 }
14335
EncryptDecryptErrorCallback(Tpm::EncryptDecryptResponse callback,TPM_RC response_code)14336 void EncryptDecryptErrorCallback(Tpm::EncryptDecryptResponse callback,
14337 TPM_RC response_code) {
14338 VLOG(1) << __func__;
14339 std::move(callback).Run(response_code, TPM2B_MAX_BUFFER(), TPM2B_IV());
14340 }
14341
EncryptDecryptResponseParser(Tpm::EncryptDecryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14342 void EncryptDecryptResponseParser(Tpm::EncryptDecryptResponse callback,
14343 AuthorizationDelegate* authorization_delegate,
14344 const std::string& response) {
14345 VLOG(1) << __func__;
14346 TPM2B_MAX_BUFFER out_data;
14347 TPM2B_IV iv_out;
14348 TPM_RC rc = Tpm::ParseResponse_EncryptDecrypt(response, &out_data, &iv_out,
14349 authorization_delegate);
14350 if (rc != TPM_RC_SUCCESS) {
14351 base::OnceCallback<void(TPM_RC)> error_reporter =
14352 base::BindOnce(EncryptDecryptErrorCallback, std::move(callback));
14353 std::move(error_reporter).Run(rc);
14354 return;
14355 }
14356 std::move(callback).Run(rc, out_data, iv_out);
14357 }
14358
EncryptDecrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPMI_YES_NO & decrypt,const TPMI_ALG_SYM_MODE & mode,const TPM2B_IV & iv_in,const TPM2B_MAX_BUFFER & in_data,AuthorizationDelegate * authorization_delegate,EncryptDecryptResponse callback)14359 void Tpm::EncryptDecrypt(const TPMI_DH_OBJECT& key_handle,
14360 const std::string& key_handle_name,
14361 const TPMI_YES_NO& decrypt,
14362 const TPMI_ALG_SYM_MODE& mode,
14363 const TPM2B_IV& iv_in,
14364 const TPM2B_MAX_BUFFER& in_data,
14365 AuthorizationDelegate* authorization_delegate,
14366 EncryptDecryptResponse callback) {
14367 VLOG(1) << __func__;
14368 std::string command;
14369 TPM_RC rc = SerializeCommand_EncryptDecrypt(key_handle, key_handle_name,
14370 decrypt, mode, iv_in, in_data,
14371 &command, authorization_delegate);
14372 if (rc != TPM_RC_SUCCESS) {
14373 base::OnceCallback<void(TPM_RC)> error_reporter =
14374 base::BindOnce(EncryptDecryptErrorCallback, std::move(callback));
14375 std::move(error_reporter).Run(rc);
14376 return;
14377 }
14378 base::OnceCallback<void(const std::string&)> parser =
14379 base::BindOnce(EncryptDecryptResponseParser, std::move(callback),
14380 authorization_delegate);
14381 transceiver_->SendCommand(command, std::move(parser));
14382 }
14383
EncryptDecryptSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPMI_YES_NO & decrypt,const TPMI_ALG_SYM_MODE & mode,const TPM2B_IV & iv_in,const TPM2B_MAX_BUFFER & in_data,TPM2B_MAX_BUFFER * out_data,TPM2B_IV * iv_out,AuthorizationDelegate * authorization_delegate)14384 TPM_RC Tpm::EncryptDecryptSync(const TPMI_DH_OBJECT& key_handle,
14385 const std::string& key_handle_name,
14386 const TPMI_YES_NO& decrypt,
14387 const TPMI_ALG_SYM_MODE& mode,
14388 const TPM2B_IV& iv_in,
14389 const TPM2B_MAX_BUFFER& in_data,
14390 TPM2B_MAX_BUFFER* out_data,
14391 TPM2B_IV* iv_out,
14392 AuthorizationDelegate* authorization_delegate) {
14393 VLOG(1) << __func__;
14394 std::string command;
14395 TPM_RC rc = SerializeCommand_EncryptDecrypt(key_handle, key_handle_name,
14396 decrypt, mode, iv_in, in_data,
14397 &command, authorization_delegate);
14398 if (rc != TPM_RC_SUCCESS) {
14399 return rc;
14400 }
14401 std::string response = transceiver_->SendCommandAndWait(command);
14402 rc = ParseResponse_EncryptDecrypt(response, out_data, iv_out,
14403 authorization_delegate);
14404 return rc;
14405 }
14406
SerializeCommand_Hash(const TPM2B_MAX_BUFFER & data,const TPMI_ALG_HASH & hash_alg,const TPMI_RH_HIERARCHY & hierarchy,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14407 TPM_RC Tpm::SerializeCommand_Hash(
14408 const TPM2B_MAX_BUFFER& data,
14409 const TPMI_ALG_HASH& hash_alg,
14410 const TPMI_RH_HIERARCHY& hierarchy,
14411 std::string* serialized_command,
14412 AuthorizationDelegate* authorization_delegate) {
14413 VLOG(3) << __func__;
14414 TPM_RC rc = TPM_RC_SUCCESS;
14415 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14416 UINT32 command_size = 10; // Header size.
14417 std::string handle_section_bytes;
14418 std::string parameter_section_bytes;
14419 TPM_CC command_code = TPM_CC_Hash;
14420 bool is_command_parameter_encryption_possible = true;
14421 bool is_response_parameter_encryption_possible = true;
14422 std::string command_code_bytes;
14423 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14424 if (rc != TPM_RC_SUCCESS) {
14425 return rc;
14426 }
14427 std::string data_bytes;
14428 rc = Serialize_TPM2B_MAX_BUFFER(data, &data_bytes);
14429 if (rc != TPM_RC_SUCCESS) {
14430 return rc;
14431 }
14432 std::string hash_alg_bytes;
14433 rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
14434 if (rc != TPM_RC_SUCCESS) {
14435 return rc;
14436 }
14437 std::string hierarchy_bytes;
14438 rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
14439 if (rc != TPM_RC_SUCCESS) {
14440 return rc;
14441 }
14442 if (authorization_delegate) {
14443 // Encrypt just the parameter data, not the size.
14444 std::string tmp = data_bytes.substr(2);
14445 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14446 return TRUNKS_RC_ENCRYPTION_FAILED;
14447 }
14448 data_bytes.replace(2, std::string::npos, tmp);
14449 }
14450 std::unique_ptr<crypto::SecureHash> hash(
14451 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14452 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14453 hash->Update(data_bytes.data(), data_bytes.size());
14454 parameter_section_bytes += data_bytes;
14455 command_size += data_bytes.size();
14456 hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
14457 parameter_section_bytes += hash_alg_bytes;
14458 command_size += hash_alg_bytes.size();
14459 hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
14460 parameter_section_bytes += hierarchy_bytes;
14461 command_size += hierarchy_bytes.size();
14462 std::string command_hash(32, 0);
14463 hash->Finish(std::data(command_hash), command_hash.size());
14464 std::string authorization_section_bytes;
14465 std::string authorization_size_bytes;
14466 if (authorization_delegate) {
14467 if (!authorization_delegate->GetCommandAuthorization(
14468 command_hash, is_command_parameter_encryption_possible,
14469 is_response_parameter_encryption_possible,
14470 &authorization_section_bytes)) {
14471 return TRUNKS_RC_AUTHORIZATION_FAILED;
14472 }
14473 if (!authorization_section_bytes.empty()) {
14474 tag = TPM_ST_SESSIONS;
14475 std::string tmp;
14476 rc = Serialize_UINT32(authorization_section_bytes.size(),
14477 &authorization_size_bytes);
14478 if (rc != TPM_RC_SUCCESS) {
14479 return rc;
14480 }
14481 command_size +=
14482 authorization_size_bytes.size() + authorization_section_bytes.size();
14483 }
14484 }
14485 std::string tag_bytes;
14486 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14487 if (rc != TPM_RC_SUCCESS) {
14488 return rc;
14489 }
14490 std::string command_size_bytes;
14491 rc = Serialize_UINT32(command_size, &command_size_bytes);
14492 if (rc != TPM_RC_SUCCESS) {
14493 return rc;
14494 }
14495 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14496 handle_section_bytes + authorization_size_bytes +
14497 authorization_section_bytes + parameter_section_bytes;
14498 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14499 VLOG(2) << "Command: "
14500 << base::HexEncode(serialized_command->data(),
14501 serialized_command->size());
14502 return TPM_RC_SUCCESS;
14503 }
14504
ParseResponse_Hash(const std::string & response,TPM2B_DIGEST * out_hash,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)14505 TPM_RC Tpm::ParseResponse_Hash(const std::string& response,
14506 TPM2B_DIGEST* out_hash,
14507 TPMT_TK_HASHCHECK* validation,
14508 AuthorizationDelegate* authorization_delegate) {
14509 VLOG(3) << __func__;
14510 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14511 TPM_RC rc = TPM_RC_SUCCESS;
14512 std::string buffer(response);
14513 TPM_ST tag;
14514 std::string tag_bytes;
14515 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14516 if (rc != TPM_RC_SUCCESS) {
14517 return rc;
14518 }
14519 UINT32 response_size;
14520 std::string response_size_bytes;
14521 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14522 if (rc != TPM_RC_SUCCESS) {
14523 return rc;
14524 }
14525 TPM_RC response_code;
14526 std::string response_code_bytes;
14527 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14528 if (rc != TPM_RC_SUCCESS) {
14529 return rc;
14530 }
14531 if (response_size != response.size()) {
14532 return TPM_RC_SIZE;
14533 }
14534 if (response_code != TPM_RC_SUCCESS) {
14535 return response_code;
14536 }
14537 TPM_CC command_code = TPM_CC_Hash;
14538 std::string command_code_bytes;
14539 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14540 if (rc != TPM_RC_SUCCESS) {
14541 return rc;
14542 }
14543 std::string authorization_section_bytes;
14544 if (tag == TPM_ST_SESSIONS) {
14545 UINT32 parameter_section_size = buffer.size();
14546 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
14547 if (rc != TPM_RC_SUCCESS) {
14548 return rc;
14549 }
14550 if (parameter_section_size > buffer.size()) {
14551 return TPM_RC_INSUFFICIENT;
14552 }
14553 authorization_section_bytes = buffer.substr(parameter_section_size);
14554 // Keep the parameter section in |buffer|.
14555 buffer.erase(parameter_section_size);
14556 }
14557 std::unique_ptr<crypto::SecureHash> hash(
14558 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14559 hash->Update(response_code_bytes.data(), response_code_bytes.size());
14560 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14561 hash->Update(buffer.data(), buffer.size());
14562 std::string response_hash(32, 0);
14563 hash->Finish(std::data(response_hash), response_hash.size());
14564 if (tag == TPM_ST_SESSIONS) {
14565 if (!authorization_delegate)
14566 return TRUNKS_RC_AUTHORIZATION_FAILED;
14567 if (!authorization_delegate->CheckResponseAuthorization(
14568 response_hash, authorization_section_bytes)) {
14569 return TRUNKS_RC_AUTHORIZATION_FAILED;
14570 }
14571 }
14572 if (tag == TPM_ST_SESSIONS) {
14573 if (!authorization_delegate)
14574 return TRUNKS_RC_AUTHORIZATION_FAILED;
14575
14576 // Parse the encrypted parameter size.
14577 UINT16 size;
14578 std::string size_buffer = buffer.substr(0, 2);
14579 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14580 return result;
14581 }
14582 if (buffer.size() < 2 + size) {
14583 return TPM_RC_INSUFFICIENT;
14584 }
14585
14586 // Decrypt just the parameter data, not the size.
14587 std::string decrypted_data = buffer.substr(2, size);
14588 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14589 return TRUNKS_RC_ENCRYPTION_FAILED;
14590 }
14591 buffer.replace(2, size, decrypted_data);
14592 }
14593 std::string out_hash_bytes;
14594 rc = Parse_TPM2B_DIGEST(&buffer, out_hash, &out_hash_bytes);
14595 if (rc != TPM_RC_SUCCESS) {
14596 return rc;
14597 }
14598 std::string validation_bytes;
14599 rc = Parse_TPMT_TK_HASHCHECK(&buffer, validation, &validation_bytes);
14600 if (rc != TPM_RC_SUCCESS) {
14601 return rc;
14602 }
14603 return TPM_RC_SUCCESS;
14604 }
14605
HashErrorCallback(Tpm::HashResponse callback,TPM_RC response_code)14606 void HashErrorCallback(Tpm::HashResponse callback, TPM_RC response_code) {
14607 VLOG(1) << __func__;
14608 std::move(callback).Run(response_code, TPM2B_DIGEST(), TPMT_TK_HASHCHECK());
14609 }
14610
HashResponseParser(Tpm::HashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14611 void HashResponseParser(Tpm::HashResponse callback,
14612 AuthorizationDelegate* authorization_delegate,
14613 const std::string& response) {
14614 VLOG(1) << __func__;
14615 TPM2B_DIGEST out_hash;
14616 TPMT_TK_HASHCHECK validation;
14617 TPM_RC rc = Tpm::ParseResponse_Hash(response, &out_hash, &validation,
14618 authorization_delegate);
14619 if (rc != TPM_RC_SUCCESS) {
14620 base::OnceCallback<void(TPM_RC)> error_reporter =
14621 base::BindOnce(HashErrorCallback, std::move(callback));
14622 std::move(error_reporter).Run(rc);
14623 return;
14624 }
14625 std::move(callback).Run(rc, out_hash, validation);
14626 }
14627
Hash(const TPM2B_MAX_BUFFER & data,const TPMI_ALG_HASH & hash_alg,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,HashResponse callback)14628 void Tpm::Hash(const TPM2B_MAX_BUFFER& data,
14629 const TPMI_ALG_HASH& hash_alg,
14630 const TPMI_RH_HIERARCHY& hierarchy,
14631 AuthorizationDelegate* authorization_delegate,
14632 HashResponse callback) {
14633 VLOG(1) << __func__;
14634 std::string command;
14635 TPM_RC rc = SerializeCommand_Hash(data, hash_alg, hierarchy, &command,
14636 authorization_delegate);
14637 if (rc != TPM_RC_SUCCESS) {
14638 base::OnceCallback<void(TPM_RC)> error_reporter =
14639 base::BindOnce(HashErrorCallback, std::move(callback));
14640 std::move(error_reporter).Run(rc);
14641 return;
14642 }
14643 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14644 HashResponseParser, std::move(callback), authorization_delegate);
14645 transceiver_->SendCommand(command, std::move(parser));
14646 }
14647
HashSync(const TPM2B_MAX_BUFFER & data,const TPMI_ALG_HASH & hash_alg,const TPMI_RH_HIERARCHY & hierarchy,TPM2B_DIGEST * out_hash,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)14648 TPM_RC Tpm::HashSync(const TPM2B_MAX_BUFFER& data,
14649 const TPMI_ALG_HASH& hash_alg,
14650 const TPMI_RH_HIERARCHY& hierarchy,
14651 TPM2B_DIGEST* out_hash,
14652 TPMT_TK_HASHCHECK* validation,
14653 AuthorizationDelegate* authorization_delegate) {
14654 VLOG(1) << __func__;
14655 std::string command;
14656 TPM_RC rc = SerializeCommand_Hash(data, hash_alg, hierarchy, &command,
14657 authorization_delegate);
14658 if (rc != TPM_RC_SUCCESS) {
14659 return rc;
14660 }
14661 std::string response = transceiver_->SendCommandAndWait(command);
14662 rc = ParseResponse_Hash(response, out_hash, validation,
14663 authorization_delegate);
14664 return rc;
14665 }
14666
SerializeCommand_HMAC(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14667 TPM_RC Tpm::SerializeCommand_HMAC(
14668 const TPMI_DH_OBJECT& handle,
14669 const std::string& handle_name,
14670 const TPM2B_MAX_BUFFER& buffer,
14671 const TPMI_ALG_HASH& hash_alg,
14672 std::string* serialized_command,
14673 AuthorizationDelegate* authorization_delegate) {
14674 VLOG(3) << __func__;
14675 TPM_RC rc = TPM_RC_SUCCESS;
14676 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14677 UINT32 command_size = 10; // Header size.
14678 std::string handle_section_bytes;
14679 std::string parameter_section_bytes;
14680 TPM_CC command_code = TPM_CC_HMAC;
14681 bool is_command_parameter_encryption_possible = true;
14682 bool is_response_parameter_encryption_possible = true;
14683 std::string command_code_bytes;
14684 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14685 if (rc != TPM_RC_SUCCESS) {
14686 return rc;
14687 }
14688 std::string handle_bytes;
14689 rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
14690 if (rc != TPM_RC_SUCCESS) {
14691 return rc;
14692 }
14693 std::string buffer_bytes;
14694 rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
14695 if (rc != TPM_RC_SUCCESS) {
14696 return rc;
14697 }
14698 std::string hash_alg_bytes;
14699 rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
14700 if (rc != TPM_RC_SUCCESS) {
14701 return rc;
14702 }
14703 if (authorization_delegate) {
14704 // Encrypt just the parameter data, not the size.
14705 std::string tmp = buffer_bytes.substr(2);
14706 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14707 return TRUNKS_RC_ENCRYPTION_FAILED;
14708 }
14709 buffer_bytes.replace(2, std::string::npos, tmp);
14710 }
14711 std::unique_ptr<crypto::SecureHash> hash(
14712 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14713 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14714 hash->Update(handle_name.data(), handle_name.size());
14715 handle_section_bytes += handle_bytes;
14716 command_size += handle_bytes.size();
14717 hash->Update(buffer_bytes.data(), buffer_bytes.size());
14718 parameter_section_bytes += buffer_bytes;
14719 command_size += buffer_bytes.size();
14720 hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
14721 parameter_section_bytes += hash_alg_bytes;
14722 command_size += hash_alg_bytes.size();
14723 std::string command_hash(32, 0);
14724 hash->Finish(std::data(command_hash), command_hash.size());
14725 std::string authorization_section_bytes;
14726 std::string authorization_size_bytes;
14727 if (authorization_delegate) {
14728 if (!authorization_delegate->GetCommandAuthorization(
14729 command_hash, is_command_parameter_encryption_possible,
14730 is_response_parameter_encryption_possible,
14731 &authorization_section_bytes)) {
14732 return TRUNKS_RC_AUTHORIZATION_FAILED;
14733 }
14734 if (!authorization_section_bytes.empty()) {
14735 tag = TPM_ST_SESSIONS;
14736 std::string tmp;
14737 rc = Serialize_UINT32(authorization_section_bytes.size(),
14738 &authorization_size_bytes);
14739 if (rc != TPM_RC_SUCCESS) {
14740 return rc;
14741 }
14742 command_size +=
14743 authorization_size_bytes.size() + authorization_section_bytes.size();
14744 }
14745 }
14746 std::string tag_bytes;
14747 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14748 if (rc != TPM_RC_SUCCESS) {
14749 return rc;
14750 }
14751 std::string command_size_bytes;
14752 rc = Serialize_UINT32(command_size, &command_size_bytes);
14753 if (rc != TPM_RC_SUCCESS) {
14754 return rc;
14755 }
14756 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14757 handle_section_bytes + authorization_size_bytes +
14758 authorization_section_bytes + parameter_section_bytes;
14759 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14760 VLOG(2) << "Command: "
14761 << base::HexEncode(serialized_command->data(),
14762 serialized_command->size());
14763 return TPM_RC_SUCCESS;
14764 }
14765
ParseResponse_HMAC(const std::string & response,TPM2B_DIGEST * out_hmac,AuthorizationDelegate * authorization_delegate)14766 TPM_RC Tpm::ParseResponse_HMAC(const std::string& response,
14767 TPM2B_DIGEST* out_hmac,
14768 AuthorizationDelegate* authorization_delegate) {
14769 VLOG(3) << __func__;
14770 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14771 TPM_RC rc = TPM_RC_SUCCESS;
14772 std::string buffer(response);
14773 TPM_ST tag;
14774 std::string tag_bytes;
14775 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14776 if (rc != TPM_RC_SUCCESS) {
14777 return rc;
14778 }
14779 UINT32 response_size;
14780 std::string response_size_bytes;
14781 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14782 if (rc != TPM_RC_SUCCESS) {
14783 return rc;
14784 }
14785 TPM_RC response_code;
14786 std::string response_code_bytes;
14787 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14788 if (rc != TPM_RC_SUCCESS) {
14789 return rc;
14790 }
14791 if (response_size != response.size()) {
14792 return TPM_RC_SIZE;
14793 }
14794 if (response_code != TPM_RC_SUCCESS) {
14795 return response_code;
14796 }
14797 TPM_CC command_code = TPM_CC_HMAC;
14798 std::string command_code_bytes;
14799 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14800 if (rc != TPM_RC_SUCCESS) {
14801 return rc;
14802 }
14803 std::string authorization_section_bytes;
14804 if (tag == TPM_ST_SESSIONS) {
14805 UINT32 parameter_section_size = buffer.size();
14806 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
14807 if (rc != TPM_RC_SUCCESS) {
14808 return rc;
14809 }
14810 if (parameter_section_size > buffer.size()) {
14811 return TPM_RC_INSUFFICIENT;
14812 }
14813 authorization_section_bytes = buffer.substr(parameter_section_size);
14814 // Keep the parameter section in |buffer|.
14815 buffer.erase(parameter_section_size);
14816 }
14817 std::unique_ptr<crypto::SecureHash> hash(
14818 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14819 hash->Update(response_code_bytes.data(), response_code_bytes.size());
14820 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14821 hash->Update(buffer.data(), buffer.size());
14822 std::string response_hash(32, 0);
14823 hash->Finish(std::data(response_hash), response_hash.size());
14824 if (tag == TPM_ST_SESSIONS) {
14825 if (!authorization_delegate)
14826 return TRUNKS_RC_AUTHORIZATION_FAILED;
14827 if (!authorization_delegate->CheckResponseAuthorization(
14828 response_hash, authorization_section_bytes)) {
14829 return TRUNKS_RC_AUTHORIZATION_FAILED;
14830 }
14831 }
14832 if (tag == TPM_ST_SESSIONS) {
14833 if (!authorization_delegate)
14834 return TRUNKS_RC_AUTHORIZATION_FAILED;
14835
14836 // Parse the encrypted parameter size.
14837 UINT16 size;
14838 std::string size_buffer = buffer.substr(0, 2);
14839 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14840 return result;
14841 }
14842 if (buffer.size() < 2 + size) {
14843 return TPM_RC_INSUFFICIENT;
14844 }
14845
14846 // Decrypt just the parameter data, not the size.
14847 std::string decrypted_data = buffer.substr(2, size);
14848 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14849 return TRUNKS_RC_ENCRYPTION_FAILED;
14850 }
14851 buffer.replace(2, size, decrypted_data);
14852 }
14853 std::string out_hmac_bytes;
14854 rc = Parse_TPM2B_DIGEST(&buffer, out_hmac, &out_hmac_bytes);
14855 if (rc != TPM_RC_SUCCESS) {
14856 return rc;
14857 }
14858 return TPM_RC_SUCCESS;
14859 }
14860
HMACErrorCallback(Tpm::HMACResponse callback,TPM_RC response_code)14861 void HMACErrorCallback(Tpm::HMACResponse callback, TPM_RC response_code) {
14862 VLOG(1) << __func__;
14863 std::move(callback).Run(response_code, TPM2B_DIGEST());
14864 }
14865
HMACResponseParser(Tpm::HMACResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14866 void HMACResponseParser(Tpm::HMACResponse callback,
14867 AuthorizationDelegate* authorization_delegate,
14868 const std::string& response) {
14869 VLOG(1) << __func__;
14870 TPM2B_DIGEST out_hmac;
14871 TPM_RC rc =
14872 Tpm::ParseResponse_HMAC(response, &out_hmac, authorization_delegate);
14873 if (rc != TPM_RC_SUCCESS) {
14874 base::OnceCallback<void(TPM_RC)> error_reporter =
14875 base::BindOnce(HMACErrorCallback, std::move(callback));
14876 std::move(error_reporter).Run(rc);
14877 return;
14878 }
14879 std::move(callback).Run(rc, out_hmac);
14880 }
14881
HMAC(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,HMACResponse callback)14882 void Tpm::HMAC(const TPMI_DH_OBJECT& handle,
14883 const std::string& handle_name,
14884 const TPM2B_MAX_BUFFER& buffer,
14885 const TPMI_ALG_HASH& hash_alg,
14886 AuthorizationDelegate* authorization_delegate,
14887 HMACResponse callback) {
14888 VLOG(1) << __func__;
14889 std::string command;
14890 TPM_RC rc = SerializeCommand_HMAC(handle, handle_name, buffer, hash_alg,
14891 &command, authorization_delegate);
14892 if (rc != TPM_RC_SUCCESS) {
14893 base::OnceCallback<void(TPM_RC)> error_reporter =
14894 base::BindOnce(HMACErrorCallback, std::move(callback));
14895 std::move(error_reporter).Run(rc);
14896 return;
14897 }
14898 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14899 HMACResponseParser, std::move(callback), authorization_delegate);
14900 transceiver_->SendCommand(command, std::move(parser));
14901 }
14902
HMACSync(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_ALG_HASH & hash_alg,TPM2B_DIGEST * out_hmac,AuthorizationDelegate * authorization_delegate)14903 TPM_RC Tpm::HMACSync(const TPMI_DH_OBJECT& handle,
14904 const std::string& handle_name,
14905 const TPM2B_MAX_BUFFER& buffer,
14906 const TPMI_ALG_HASH& hash_alg,
14907 TPM2B_DIGEST* out_hmac,
14908 AuthorizationDelegate* authorization_delegate) {
14909 VLOG(1) << __func__;
14910 std::string command;
14911 TPM_RC rc = SerializeCommand_HMAC(handle, handle_name, buffer, hash_alg,
14912 &command, authorization_delegate);
14913 if (rc != TPM_RC_SUCCESS) {
14914 return rc;
14915 }
14916 std::string response = transceiver_->SendCommandAndWait(command);
14917 rc = ParseResponse_HMAC(response, out_hmac, authorization_delegate);
14918 return rc;
14919 }
14920
SerializeCommand_GetRandom(const UINT16 & bytes_requested,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14921 TPM_RC Tpm::SerializeCommand_GetRandom(
14922 const UINT16& bytes_requested,
14923 std::string* serialized_command,
14924 AuthorizationDelegate* authorization_delegate) {
14925 VLOG(3) << __func__;
14926 TPM_RC rc = TPM_RC_SUCCESS;
14927 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14928 UINT32 command_size = 10; // Header size.
14929 std::string handle_section_bytes;
14930 std::string parameter_section_bytes;
14931 TPM_CC command_code = TPM_CC_GetRandom;
14932 bool is_command_parameter_encryption_possible = false;
14933 bool is_response_parameter_encryption_possible = true;
14934 std::string command_code_bytes;
14935 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14936 if (rc != TPM_RC_SUCCESS) {
14937 return rc;
14938 }
14939 std::string bytes_requested_bytes;
14940 rc = Serialize_UINT16(bytes_requested, &bytes_requested_bytes);
14941 if (rc != TPM_RC_SUCCESS) {
14942 return rc;
14943 }
14944 std::unique_ptr<crypto::SecureHash> hash(
14945 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14946 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14947 hash->Update(bytes_requested_bytes.data(), bytes_requested_bytes.size());
14948 parameter_section_bytes += bytes_requested_bytes;
14949 command_size += bytes_requested_bytes.size();
14950 std::string command_hash(32, 0);
14951 hash->Finish(std::data(command_hash), command_hash.size());
14952 std::string authorization_section_bytes;
14953 std::string authorization_size_bytes;
14954 if (authorization_delegate) {
14955 if (!authorization_delegate->GetCommandAuthorization(
14956 command_hash, is_command_parameter_encryption_possible,
14957 is_response_parameter_encryption_possible,
14958 &authorization_section_bytes)) {
14959 return TRUNKS_RC_AUTHORIZATION_FAILED;
14960 }
14961 if (!authorization_section_bytes.empty()) {
14962 tag = TPM_ST_SESSIONS;
14963 std::string tmp;
14964 rc = Serialize_UINT32(authorization_section_bytes.size(),
14965 &authorization_size_bytes);
14966 if (rc != TPM_RC_SUCCESS) {
14967 return rc;
14968 }
14969 command_size +=
14970 authorization_size_bytes.size() + authorization_section_bytes.size();
14971 }
14972 }
14973 std::string tag_bytes;
14974 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14975 if (rc != TPM_RC_SUCCESS) {
14976 return rc;
14977 }
14978 std::string command_size_bytes;
14979 rc = Serialize_UINT32(command_size, &command_size_bytes);
14980 if (rc != TPM_RC_SUCCESS) {
14981 return rc;
14982 }
14983 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14984 handle_section_bytes + authorization_size_bytes +
14985 authorization_section_bytes + parameter_section_bytes;
14986 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14987 VLOG(2) << "Command: "
14988 << base::HexEncode(serialized_command->data(),
14989 serialized_command->size());
14990 return TPM_RC_SUCCESS;
14991 }
14992
ParseResponse_GetRandom(const std::string & response,TPM2B_DIGEST * random_bytes,AuthorizationDelegate * authorization_delegate)14993 TPM_RC Tpm::ParseResponse_GetRandom(
14994 const std::string& response,
14995 TPM2B_DIGEST* random_bytes,
14996 AuthorizationDelegate* authorization_delegate) {
14997 VLOG(3) << __func__;
14998 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14999 TPM_RC rc = TPM_RC_SUCCESS;
15000 std::string buffer(response);
15001 TPM_ST tag;
15002 std::string tag_bytes;
15003 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15004 if (rc != TPM_RC_SUCCESS) {
15005 return rc;
15006 }
15007 UINT32 response_size;
15008 std::string response_size_bytes;
15009 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15010 if (rc != TPM_RC_SUCCESS) {
15011 return rc;
15012 }
15013 TPM_RC response_code;
15014 std::string response_code_bytes;
15015 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15016 if (rc != TPM_RC_SUCCESS) {
15017 return rc;
15018 }
15019 if (response_size != response.size()) {
15020 return TPM_RC_SIZE;
15021 }
15022 if (response_code != TPM_RC_SUCCESS) {
15023 return response_code;
15024 }
15025 TPM_CC command_code = TPM_CC_GetRandom;
15026 std::string command_code_bytes;
15027 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15028 if (rc != TPM_RC_SUCCESS) {
15029 return rc;
15030 }
15031 std::string authorization_section_bytes;
15032 if (tag == TPM_ST_SESSIONS) {
15033 UINT32 parameter_section_size = buffer.size();
15034 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
15035 if (rc != TPM_RC_SUCCESS) {
15036 return rc;
15037 }
15038 if (parameter_section_size > buffer.size()) {
15039 return TPM_RC_INSUFFICIENT;
15040 }
15041 authorization_section_bytes = buffer.substr(parameter_section_size);
15042 // Keep the parameter section in |buffer|.
15043 buffer.erase(parameter_section_size);
15044 }
15045 std::unique_ptr<crypto::SecureHash> hash(
15046 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15047 hash->Update(response_code_bytes.data(), response_code_bytes.size());
15048 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15049 hash->Update(buffer.data(), buffer.size());
15050 std::string response_hash(32, 0);
15051 hash->Finish(std::data(response_hash), response_hash.size());
15052 if (tag == TPM_ST_SESSIONS) {
15053 if (!authorization_delegate)
15054 return TRUNKS_RC_AUTHORIZATION_FAILED;
15055 if (!authorization_delegate->CheckResponseAuthorization(
15056 response_hash, authorization_section_bytes)) {
15057 return TRUNKS_RC_AUTHORIZATION_FAILED;
15058 }
15059 }
15060 if (tag == TPM_ST_SESSIONS) {
15061 if (!authorization_delegate)
15062 return TRUNKS_RC_AUTHORIZATION_FAILED;
15063
15064 // Parse the encrypted parameter size.
15065 UINT16 size;
15066 std::string size_buffer = buffer.substr(0, 2);
15067 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
15068 return result;
15069 }
15070 if (buffer.size() < 2 + size) {
15071 return TPM_RC_INSUFFICIENT;
15072 }
15073
15074 // Decrypt just the parameter data, not the size.
15075 std::string decrypted_data = buffer.substr(2, size);
15076 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
15077 return TRUNKS_RC_ENCRYPTION_FAILED;
15078 }
15079 buffer.replace(2, size, decrypted_data);
15080 }
15081 std::string random_bytes_bytes;
15082 rc = Parse_TPM2B_DIGEST(&buffer, random_bytes, &random_bytes_bytes);
15083 if (rc != TPM_RC_SUCCESS) {
15084 return rc;
15085 }
15086 return TPM_RC_SUCCESS;
15087 }
15088
GetRandomErrorCallback(Tpm::GetRandomResponse callback,TPM_RC response_code)15089 void GetRandomErrorCallback(Tpm::GetRandomResponse callback,
15090 TPM_RC response_code) {
15091 VLOG(1) << __func__;
15092 std::move(callback).Run(response_code, TPM2B_DIGEST());
15093 }
15094
GetRandomResponseParser(Tpm::GetRandomResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15095 void GetRandomResponseParser(Tpm::GetRandomResponse callback,
15096 AuthorizationDelegate* authorization_delegate,
15097 const std::string& response) {
15098 VLOG(1) << __func__;
15099 TPM2B_DIGEST random_bytes;
15100 TPM_RC rc = Tpm::ParseResponse_GetRandom(response, &random_bytes,
15101 authorization_delegate);
15102 if (rc != TPM_RC_SUCCESS) {
15103 base::OnceCallback<void(TPM_RC)> error_reporter =
15104 base::BindOnce(GetRandomErrorCallback, std::move(callback));
15105 std::move(error_reporter).Run(rc);
15106 return;
15107 }
15108 std::move(callback).Run(rc, random_bytes);
15109 }
15110
GetRandom(const UINT16 & bytes_requested,AuthorizationDelegate * authorization_delegate,GetRandomResponse callback)15111 void Tpm::GetRandom(const UINT16& bytes_requested,
15112 AuthorizationDelegate* authorization_delegate,
15113 GetRandomResponse callback) {
15114 VLOG(1) << __func__;
15115 std::string command;
15116 TPM_RC rc = SerializeCommand_GetRandom(bytes_requested, &command,
15117 authorization_delegate);
15118 if (rc != TPM_RC_SUCCESS) {
15119 base::OnceCallback<void(TPM_RC)> error_reporter =
15120 base::BindOnce(GetRandomErrorCallback, std::move(callback));
15121 std::move(error_reporter).Run(rc);
15122 return;
15123 }
15124 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15125 GetRandomResponseParser, std::move(callback), authorization_delegate);
15126 transceiver_->SendCommand(command, std::move(parser));
15127 }
15128
GetRandomSync(const UINT16 & bytes_requested,TPM2B_DIGEST * random_bytes,AuthorizationDelegate * authorization_delegate)15129 TPM_RC Tpm::GetRandomSync(const UINT16& bytes_requested,
15130 TPM2B_DIGEST* random_bytes,
15131 AuthorizationDelegate* authorization_delegate) {
15132 VLOG(1) << __func__;
15133 std::string command;
15134 TPM_RC rc = SerializeCommand_GetRandom(bytes_requested, &command,
15135 authorization_delegate);
15136 if (rc != TPM_RC_SUCCESS) {
15137 return rc;
15138 }
15139 std::string response = transceiver_->SendCommandAndWait(command);
15140 rc = ParseResponse_GetRandom(response, random_bytes, authorization_delegate);
15141 return rc;
15142 }
15143
SerializeCommand_StirRandom(const TPM2B_SENSITIVE_DATA & in_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15144 TPM_RC Tpm::SerializeCommand_StirRandom(
15145 const TPM2B_SENSITIVE_DATA& in_data,
15146 std::string* serialized_command,
15147 AuthorizationDelegate* authorization_delegate) {
15148 VLOG(3) << __func__;
15149 TPM_RC rc = TPM_RC_SUCCESS;
15150 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15151 UINT32 command_size = 10; // Header size.
15152 std::string handle_section_bytes;
15153 std::string parameter_section_bytes;
15154 TPM_CC command_code = TPM_CC_StirRandom;
15155 bool is_command_parameter_encryption_possible = true;
15156 bool is_response_parameter_encryption_possible = false;
15157 std::string command_code_bytes;
15158 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15159 if (rc != TPM_RC_SUCCESS) {
15160 return rc;
15161 }
15162 std::string in_data_bytes;
15163 rc = Serialize_TPM2B_SENSITIVE_DATA(in_data, &in_data_bytes);
15164 if (rc != TPM_RC_SUCCESS) {
15165 return rc;
15166 }
15167 if (authorization_delegate) {
15168 // Encrypt just the parameter data, not the size.
15169 std::string tmp = in_data_bytes.substr(2);
15170 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15171 return TRUNKS_RC_ENCRYPTION_FAILED;
15172 }
15173 in_data_bytes.replace(2, std::string::npos, tmp);
15174 }
15175 std::unique_ptr<crypto::SecureHash> hash(
15176 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15177 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15178 hash->Update(in_data_bytes.data(), in_data_bytes.size());
15179 parameter_section_bytes += in_data_bytes;
15180 command_size += in_data_bytes.size();
15181 std::string command_hash(32, 0);
15182 hash->Finish(std::data(command_hash), command_hash.size());
15183 std::string authorization_section_bytes;
15184 std::string authorization_size_bytes;
15185 if (authorization_delegate) {
15186 if (!authorization_delegate->GetCommandAuthorization(
15187 command_hash, is_command_parameter_encryption_possible,
15188 is_response_parameter_encryption_possible,
15189 &authorization_section_bytes)) {
15190 return TRUNKS_RC_AUTHORIZATION_FAILED;
15191 }
15192 if (!authorization_section_bytes.empty()) {
15193 tag = TPM_ST_SESSIONS;
15194 std::string tmp;
15195 rc = Serialize_UINT32(authorization_section_bytes.size(),
15196 &authorization_size_bytes);
15197 if (rc != TPM_RC_SUCCESS) {
15198 return rc;
15199 }
15200 command_size +=
15201 authorization_size_bytes.size() + authorization_section_bytes.size();
15202 }
15203 }
15204 std::string tag_bytes;
15205 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15206 if (rc != TPM_RC_SUCCESS) {
15207 return rc;
15208 }
15209 std::string command_size_bytes;
15210 rc = Serialize_UINT32(command_size, &command_size_bytes);
15211 if (rc != TPM_RC_SUCCESS) {
15212 return rc;
15213 }
15214 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15215 handle_section_bytes + authorization_size_bytes +
15216 authorization_section_bytes + parameter_section_bytes;
15217 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15218 VLOG(2) << "Command: "
15219 << base::HexEncode(serialized_command->data(),
15220 serialized_command->size());
15221 return TPM_RC_SUCCESS;
15222 }
15223
ParseResponse_StirRandom(const std::string & response,AuthorizationDelegate * authorization_delegate)15224 TPM_RC Tpm::ParseResponse_StirRandom(
15225 const std::string& response,
15226 AuthorizationDelegate* authorization_delegate) {
15227 VLOG(3) << __func__;
15228 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15229 TPM_RC rc = TPM_RC_SUCCESS;
15230 std::string buffer(response);
15231 TPM_ST tag;
15232 std::string tag_bytes;
15233 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15234 if (rc != TPM_RC_SUCCESS) {
15235 return rc;
15236 }
15237 UINT32 response_size;
15238 std::string response_size_bytes;
15239 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15240 if (rc != TPM_RC_SUCCESS) {
15241 return rc;
15242 }
15243 TPM_RC response_code;
15244 std::string response_code_bytes;
15245 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15246 if (rc != TPM_RC_SUCCESS) {
15247 return rc;
15248 }
15249 if (response_size != response.size()) {
15250 return TPM_RC_SIZE;
15251 }
15252 if (response_code != TPM_RC_SUCCESS) {
15253 return response_code;
15254 }
15255 TPM_CC command_code = TPM_CC_StirRandom;
15256 std::string command_code_bytes;
15257 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15258 if (rc != TPM_RC_SUCCESS) {
15259 return rc;
15260 }
15261 std::string authorization_section_bytes;
15262 if (tag == TPM_ST_SESSIONS) {
15263 UINT32 parameter_section_size = buffer.size();
15264 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
15265 if (rc != TPM_RC_SUCCESS) {
15266 return rc;
15267 }
15268 if (parameter_section_size > buffer.size()) {
15269 return TPM_RC_INSUFFICIENT;
15270 }
15271 authorization_section_bytes = buffer.substr(parameter_section_size);
15272 // Keep the parameter section in |buffer|.
15273 buffer.erase(parameter_section_size);
15274 }
15275 std::unique_ptr<crypto::SecureHash> hash(
15276 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15277 hash->Update(response_code_bytes.data(), response_code_bytes.size());
15278 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15279 hash->Update(buffer.data(), buffer.size());
15280 std::string response_hash(32, 0);
15281 hash->Finish(std::data(response_hash), response_hash.size());
15282 if (tag == TPM_ST_SESSIONS) {
15283 if (!authorization_delegate)
15284 return TRUNKS_RC_AUTHORIZATION_FAILED;
15285 if (!authorization_delegate->CheckResponseAuthorization(
15286 response_hash, authorization_section_bytes)) {
15287 return TRUNKS_RC_AUTHORIZATION_FAILED;
15288 }
15289 }
15290 return TPM_RC_SUCCESS;
15291 }
15292
StirRandomErrorCallback(Tpm::StirRandomResponse callback,TPM_RC response_code)15293 void StirRandomErrorCallback(Tpm::StirRandomResponse callback,
15294 TPM_RC response_code) {
15295 VLOG(1) << __func__;
15296 std::move(callback).Run(response_code);
15297 }
15298
StirRandomResponseParser(Tpm::StirRandomResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15299 void StirRandomResponseParser(Tpm::StirRandomResponse callback,
15300 AuthorizationDelegate* authorization_delegate,
15301 const std::string& response) {
15302 VLOG(1) << __func__;
15303 TPM_RC rc = Tpm::ParseResponse_StirRandom(response, authorization_delegate);
15304 if (rc != TPM_RC_SUCCESS) {
15305 base::OnceCallback<void(TPM_RC)> error_reporter =
15306 base::BindOnce(StirRandomErrorCallback, std::move(callback));
15307 std::move(error_reporter).Run(rc);
15308 return;
15309 }
15310 std::move(callback).Run(rc);
15311 }
15312
StirRandom(const TPM2B_SENSITIVE_DATA & in_data,AuthorizationDelegate * authorization_delegate,StirRandomResponse callback)15313 void Tpm::StirRandom(const TPM2B_SENSITIVE_DATA& in_data,
15314 AuthorizationDelegate* authorization_delegate,
15315 StirRandomResponse callback) {
15316 VLOG(1) << __func__;
15317 std::string command;
15318 TPM_RC rc =
15319 SerializeCommand_StirRandom(in_data, &command, authorization_delegate);
15320 if (rc != TPM_RC_SUCCESS) {
15321 base::OnceCallback<void(TPM_RC)> error_reporter =
15322 base::BindOnce(StirRandomErrorCallback, std::move(callback));
15323 std::move(error_reporter).Run(rc);
15324 return;
15325 }
15326 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15327 StirRandomResponseParser, std::move(callback), authorization_delegate);
15328 transceiver_->SendCommand(command, std::move(parser));
15329 }
15330
StirRandomSync(const TPM2B_SENSITIVE_DATA & in_data,AuthorizationDelegate * authorization_delegate)15331 TPM_RC Tpm::StirRandomSync(const TPM2B_SENSITIVE_DATA& in_data,
15332 AuthorizationDelegate* authorization_delegate) {
15333 VLOG(1) << __func__;
15334 std::string command;
15335 TPM_RC rc =
15336 SerializeCommand_StirRandom(in_data, &command, authorization_delegate);
15337 if (rc != TPM_RC_SUCCESS) {
15338 return rc;
15339 }
15340 std::string response = transceiver_->SendCommandAndWait(command);
15341 rc = ParseResponse_StirRandom(response, authorization_delegate);
15342 return rc;
15343 }
15344
SerializeCommand_HMAC_Start(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15345 TPM_RC Tpm::SerializeCommand_HMAC_Start(
15346 const TPMI_DH_OBJECT& handle,
15347 const std::string& handle_name,
15348 const TPM2B_AUTH& auth,
15349 const TPMI_ALG_HASH& hash_alg,
15350 std::string* serialized_command,
15351 AuthorizationDelegate* authorization_delegate) {
15352 VLOG(3) << __func__;
15353 TPM_RC rc = TPM_RC_SUCCESS;
15354 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15355 UINT32 command_size = 10; // Header size.
15356 std::string handle_section_bytes;
15357 std::string parameter_section_bytes;
15358 TPM_CC command_code = TPM_CC_HMAC_Start;
15359 bool is_command_parameter_encryption_possible = true;
15360 bool is_response_parameter_encryption_possible = false;
15361 std::string command_code_bytes;
15362 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15363 if (rc != TPM_RC_SUCCESS) {
15364 return rc;
15365 }
15366 std::string handle_bytes;
15367 rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
15368 if (rc != TPM_RC_SUCCESS) {
15369 return rc;
15370 }
15371 std::string auth_bytes;
15372 rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
15373 if (rc != TPM_RC_SUCCESS) {
15374 return rc;
15375 }
15376 std::string hash_alg_bytes;
15377 rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
15378 if (rc != TPM_RC_SUCCESS) {
15379 return rc;
15380 }
15381 if (authorization_delegate) {
15382 // Encrypt just the parameter data, not the size.
15383 std::string tmp = auth_bytes.substr(2);
15384 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15385 return TRUNKS_RC_ENCRYPTION_FAILED;
15386 }
15387 auth_bytes.replace(2, std::string::npos, tmp);
15388 }
15389 std::unique_ptr<crypto::SecureHash> hash(
15390 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15391 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15392 hash->Update(handle_name.data(), handle_name.size());
15393 handle_section_bytes += handle_bytes;
15394 command_size += handle_bytes.size();
15395 hash->Update(auth_bytes.data(), auth_bytes.size());
15396 parameter_section_bytes += auth_bytes;
15397 command_size += auth_bytes.size();
15398 hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
15399 parameter_section_bytes += hash_alg_bytes;
15400 command_size += hash_alg_bytes.size();
15401 std::string command_hash(32, 0);
15402 hash->Finish(std::data(command_hash), command_hash.size());
15403 std::string authorization_section_bytes;
15404 std::string authorization_size_bytes;
15405 if (authorization_delegate) {
15406 if (!authorization_delegate->GetCommandAuthorization(
15407 command_hash, is_command_parameter_encryption_possible,
15408 is_response_parameter_encryption_possible,
15409 &authorization_section_bytes)) {
15410 return TRUNKS_RC_AUTHORIZATION_FAILED;
15411 }
15412 if (!authorization_section_bytes.empty()) {
15413 tag = TPM_ST_SESSIONS;
15414 std::string tmp;
15415 rc = Serialize_UINT32(authorization_section_bytes.size(),
15416 &authorization_size_bytes);
15417 if (rc != TPM_RC_SUCCESS) {
15418 return rc;
15419 }
15420 command_size +=
15421 authorization_size_bytes.size() + authorization_section_bytes.size();
15422 }
15423 }
15424 std::string tag_bytes;
15425 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15426 if (rc != TPM_RC_SUCCESS) {
15427 return rc;
15428 }
15429 std::string command_size_bytes;
15430 rc = Serialize_UINT32(command_size, &command_size_bytes);
15431 if (rc != TPM_RC_SUCCESS) {
15432 return rc;
15433 }
15434 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15435 handle_section_bytes + authorization_size_bytes +
15436 authorization_section_bytes + parameter_section_bytes;
15437 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15438 VLOG(2) << "Command: "
15439 << base::HexEncode(serialized_command->data(),
15440 serialized_command->size());
15441 return TPM_RC_SUCCESS;
15442 }
15443
ParseResponse_HMAC_Start(const std::string & response,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15444 TPM_RC Tpm::ParseResponse_HMAC_Start(
15445 const std::string& response,
15446 TPMI_DH_OBJECT* sequence_handle,
15447 AuthorizationDelegate* authorization_delegate) {
15448 VLOG(3) << __func__;
15449 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15450 TPM_RC rc = TPM_RC_SUCCESS;
15451 std::string buffer(response);
15452 TPM_ST tag;
15453 std::string tag_bytes;
15454 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15455 if (rc != TPM_RC_SUCCESS) {
15456 return rc;
15457 }
15458 UINT32 response_size;
15459 std::string response_size_bytes;
15460 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15461 if (rc != TPM_RC_SUCCESS) {
15462 return rc;
15463 }
15464 TPM_RC response_code;
15465 std::string response_code_bytes;
15466 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15467 if (rc != TPM_RC_SUCCESS) {
15468 return rc;
15469 }
15470 if (response_size != response.size()) {
15471 return TPM_RC_SIZE;
15472 }
15473 if (response_code != TPM_RC_SUCCESS) {
15474 return response_code;
15475 }
15476 std::string sequence_handle_bytes;
15477 rc = Parse_TPMI_DH_OBJECT(&buffer, sequence_handle, &sequence_handle_bytes);
15478 if (rc != TPM_RC_SUCCESS) {
15479 return rc;
15480 }
15481 TPM_CC command_code = TPM_CC_HMAC_Start;
15482 std::string command_code_bytes;
15483 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15484 if (rc != TPM_RC_SUCCESS) {
15485 return rc;
15486 }
15487 std::string authorization_section_bytes;
15488 if (tag == TPM_ST_SESSIONS) {
15489 UINT32 parameter_section_size = buffer.size();
15490 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
15491 if (rc != TPM_RC_SUCCESS) {
15492 return rc;
15493 }
15494 if (parameter_section_size > buffer.size()) {
15495 return TPM_RC_INSUFFICIENT;
15496 }
15497 authorization_section_bytes = buffer.substr(parameter_section_size);
15498 // Keep the parameter section in |buffer|.
15499 buffer.erase(parameter_section_size);
15500 }
15501 std::unique_ptr<crypto::SecureHash> hash(
15502 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15503 hash->Update(response_code_bytes.data(), response_code_bytes.size());
15504 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15505 hash->Update(buffer.data(), buffer.size());
15506 std::string response_hash(32, 0);
15507 hash->Finish(std::data(response_hash), response_hash.size());
15508 if (tag == TPM_ST_SESSIONS) {
15509 if (!authorization_delegate)
15510 return TRUNKS_RC_AUTHORIZATION_FAILED;
15511 if (!authorization_delegate->CheckResponseAuthorization(
15512 response_hash, authorization_section_bytes)) {
15513 return TRUNKS_RC_AUTHORIZATION_FAILED;
15514 }
15515 }
15516 return TPM_RC_SUCCESS;
15517 }
15518
HMAC_StartErrorCallback(Tpm::HMAC_StartResponse callback,TPM_RC response_code)15519 void HMAC_StartErrorCallback(Tpm::HMAC_StartResponse callback,
15520 TPM_RC response_code) {
15521 VLOG(1) << __func__;
15522 std::move(callback).Run(response_code, TPMI_DH_OBJECT());
15523 }
15524
HMAC_StartResponseParser(Tpm::HMAC_StartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15525 void HMAC_StartResponseParser(Tpm::HMAC_StartResponse callback,
15526 AuthorizationDelegate* authorization_delegate,
15527 const std::string& response) {
15528 VLOG(1) << __func__;
15529 TPMI_DH_OBJECT sequence_handle;
15530 TPM_RC rc = Tpm::ParseResponse_HMAC_Start(response, &sequence_handle,
15531 authorization_delegate);
15532 if (rc != TPM_RC_SUCCESS) {
15533 base::OnceCallback<void(TPM_RC)> error_reporter =
15534 base::BindOnce(HMAC_StartErrorCallback, std::move(callback));
15535 std::move(error_reporter).Run(rc);
15536 return;
15537 }
15538 std::move(callback).Run(rc, sequence_handle);
15539 }
15540
HMAC_Start(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,HMAC_StartResponse callback)15541 void Tpm::HMAC_Start(const TPMI_DH_OBJECT& handle,
15542 const std::string& handle_name,
15543 const TPM2B_AUTH& auth,
15544 const TPMI_ALG_HASH& hash_alg,
15545 AuthorizationDelegate* authorization_delegate,
15546 HMAC_StartResponse callback) {
15547 VLOG(1) << __func__;
15548 std::string command;
15549 TPM_RC rc = SerializeCommand_HMAC_Start(handle, handle_name, auth, hash_alg,
15550 &command, authorization_delegate);
15551 if (rc != TPM_RC_SUCCESS) {
15552 base::OnceCallback<void(TPM_RC)> error_reporter =
15553 base::BindOnce(HMAC_StartErrorCallback, std::move(callback));
15554 std::move(error_reporter).Run(rc);
15555 return;
15556 }
15557 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15558 HMAC_StartResponseParser, std::move(callback), authorization_delegate);
15559 transceiver_->SendCommand(command, std::move(parser));
15560 }
15561
HMAC_StartSync(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15562 TPM_RC Tpm::HMAC_StartSync(const TPMI_DH_OBJECT& handle,
15563 const std::string& handle_name,
15564 const TPM2B_AUTH& auth,
15565 const TPMI_ALG_HASH& hash_alg,
15566 TPMI_DH_OBJECT* sequence_handle,
15567 AuthorizationDelegate* authorization_delegate) {
15568 VLOG(1) << __func__;
15569 std::string command;
15570 TPM_RC rc = SerializeCommand_HMAC_Start(handle, handle_name, auth, hash_alg,
15571 &command, authorization_delegate);
15572 if (rc != TPM_RC_SUCCESS) {
15573 return rc;
15574 }
15575 std::string response = transceiver_->SendCommandAndWait(command);
15576 rc = ParseResponse_HMAC_Start(response, sequence_handle,
15577 authorization_delegate);
15578 return rc;
15579 }
15580
SerializeCommand_HashSequenceStart(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15581 TPM_RC Tpm::SerializeCommand_HashSequenceStart(
15582 const TPM2B_AUTH& auth,
15583 const TPMI_ALG_HASH& hash_alg,
15584 std::string* serialized_command,
15585 AuthorizationDelegate* authorization_delegate) {
15586 VLOG(3) << __func__;
15587 TPM_RC rc = TPM_RC_SUCCESS;
15588 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15589 UINT32 command_size = 10; // Header size.
15590 std::string handle_section_bytes;
15591 std::string parameter_section_bytes;
15592 TPM_CC command_code = TPM_CC_HashSequenceStart;
15593 bool is_command_parameter_encryption_possible = true;
15594 bool is_response_parameter_encryption_possible = false;
15595 std::string command_code_bytes;
15596 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15597 if (rc != TPM_RC_SUCCESS) {
15598 return rc;
15599 }
15600 std::string auth_bytes;
15601 rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
15602 if (rc != TPM_RC_SUCCESS) {
15603 return rc;
15604 }
15605 std::string hash_alg_bytes;
15606 rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
15607 if (rc != TPM_RC_SUCCESS) {
15608 return rc;
15609 }
15610 if (authorization_delegate) {
15611 // Encrypt just the parameter data, not the size.
15612 std::string tmp = auth_bytes.substr(2);
15613 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15614 return TRUNKS_RC_ENCRYPTION_FAILED;
15615 }
15616 auth_bytes.replace(2, std::string::npos, tmp);
15617 }
15618 std::unique_ptr<crypto::SecureHash> hash(
15619 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15620 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15621 hash->Update(auth_bytes.data(), auth_bytes.size());
15622 parameter_section_bytes += auth_bytes;
15623 command_size += auth_bytes.size();
15624 hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
15625 parameter_section_bytes += hash_alg_bytes;
15626 command_size += hash_alg_bytes.size();
15627 std::string command_hash(32, 0);
15628 hash->Finish(std::data(command_hash), command_hash.size());
15629 std::string authorization_section_bytes;
15630 std::string authorization_size_bytes;
15631 if (authorization_delegate) {
15632 if (!authorization_delegate->GetCommandAuthorization(
15633 command_hash, is_command_parameter_encryption_possible,
15634 is_response_parameter_encryption_possible,
15635 &authorization_section_bytes)) {
15636 return TRUNKS_RC_AUTHORIZATION_FAILED;
15637 }
15638 if (!authorization_section_bytes.empty()) {
15639 tag = TPM_ST_SESSIONS;
15640 std::string tmp;
15641 rc = Serialize_UINT32(authorization_section_bytes.size(),
15642 &authorization_size_bytes);
15643 if (rc != TPM_RC_SUCCESS) {
15644 return rc;
15645 }
15646 command_size +=
15647 authorization_size_bytes.size() + authorization_section_bytes.size();
15648 }
15649 }
15650 std::string tag_bytes;
15651 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15652 if (rc != TPM_RC_SUCCESS) {
15653 return rc;
15654 }
15655 std::string command_size_bytes;
15656 rc = Serialize_UINT32(command_size, &command_size_bytes);
15657 if (rc != TPM_RC_SUCCESS) {
15658 return rc;
15659 }
15660 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15661 handle_section_bytes + authorization_size_bytes +
15662 authorization_section_bytes + parameter_section_bytes;
15663 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15664 VLOG(2) << "Command: "
15665 << base::HexEncode(serialized_command->data(),
15666 serialized_command->size());
15667 return TPM_RC_SUCCESS;
15668 }
15669
ParseResponse_HashSequenceStart(const std::string & response,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15670 TPM_RC Tpm::ParseResponse_HashSequenceStart(
15671 const std::string& response,
15672 TPMI_DH_OBJECT* sequence_handle,
15673 AuthorizationDelegate* authorization_delegate) {
15674 VLOG(3) << __func__;
15675 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15676 TPM_RC rc = TPM_RC_SUCCESS;
15677 std::string buffer(response);
15678 TPM_ST tag;
15679 std::string tag_bytes;
15680 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15681 if (rc != TPM_RC_SUCCESS) {
15682 return rc;
15683 }
15684 UINT32 response_size;
15685 std::string response_size_bytes;
15686 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15687 if (rc != TPM_RC_SUCCESS) {
15688 return rc;
15689 }
15690 TPM_RC response_code;
15691 std::string response_code_bytes;
15692 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15693 if (rc != TPM_RC_SUCCESS) {
15694 return rc;
15695 }
15696 if (response_size != response.size()) {
15697 return TPM_RC_SIZE;
15698 }
15699 if (response_code != TPM_RC_SUCCESS) {
15700 return response_code;
15701 }
15702 std::string sequence_handle_bytes;
15703 rc = Parse_TPMI_DH_OBJECT(&buffer, sequence_handle, &sequence_handle_bytes);
15704 if (rc != TPM_RC_SUCCESS) {
15705 return rc;
15706 }
15707 TPM_CC command_code = TPM_CC_HashSequenceStart;
15708 std::string command_code_bytes;
15709 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15710 if (rc != TPM_RC_SUCCESS) {
15711 return rc;
15712 }
15713 std::string authorization_section_bytes;
15714 if (tag == TPM_ST_SESSIONS) {
15715 UINT32 parameter_section_size = buffer.size();
15716 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
15717 if (rc != TPM_RC_SUCCESS) {
15718 return rc;
15719 }
15720 if (parameter_section_size > buffer.size()) {
15721 return TPM_RC_INSUFFICIENT;
15722 }
15723 authorization_section_bytes = buffer.substr(parameter_section_size);
15724 // Keep the parameter section in |buffer|.
15725 buffer.erase(parameter_section_size);
15726 }
15727 std::unique_ptr<crypto::SecureHash> hash(
15728 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15729 hash->Update(response_code_bytes.data(), response_code_bytes.size());
15730 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15731 hash->Update(buffer.data(), buffer.size());
15732 std::string response_hash(32, 0);
15733 hash->Finish(std::data(response_hash), response_hash.size());
15734 if (tag == TPM_ST_SESSIONS) {
15735 if (!authorization_delegate)
15736 return TRUNKS_RC_AUTHORIZATION_FAILED;
15737 if (!authorization_delegate->CheckResponseAuthorization(
15738 response_hash, authorization_section_bytes)) {
15739 return TRUNKS_RC_AUTHORIZATION_FAILED;
15740 }
15741 }
15742 return TPM_RC_SUCCESS;
15743 }
15744
HashSequenceStartErrorCallback(Tpm::HashSequenceStartResponse callback,TPM_RC response_code)15745 void HashSequenceStartErrorCallback(Tpm::HashSequenceStartResponse callback,
15746 TPM_RC response_code) {
15747 VLOG(1) << __func__;
15748 std::move(callback).Run(response_code, TPMI_DH_OBJECT());
15749 }
15750
HashSequenceStartResponseParser(Tpm::HashSequenceStartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15751 void HashSequenceStartResponseParser(
15752 Tpm::HashSequenceStartResponse callback,
15753 AuthorizationDelegate* authorization_delegate,
15754 const std::string& response) {
15755 VLOG(1) << __func__;
15756 TPMI_DH_OBJECT sequence_handle;
15757 TPM_RC rc = Tpm::ParseResponse_HashSequenceStart(response, &sequence_handle,
15758 authorization_delegate);
15759 if (rc != TPM_RC_SUCCESS) {
15760 base::OnceCallback<void(TPM_RC)> error_reporter =
15761 base::BindOnce(HashSequenceStartErrorCallback, std::move(callback));
15762 std::move(error_reporter).Run(rc);
15763 return;
15764 }
15765 std::move(callback).Run(rc, sequence_handle);
15766 }
15767
HashSequenceStart(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,HashSequenceStartResponse callback)15768 void Tpm::HashSequenceStart(const TPM2B_AUTH& auth,
15769 const TPMI_ALG_HASH& hash_alg,
15770 AuthorizationDelegate* authorization_delegate,
15771 HashSequenceStartResponse callback) {
15772 VLOG(1) << __func__;
15773 std::string command;
15774 TPM_RC rc = SerializeCommand_HashSequenceStart(auth, hash_alg, &command,
15775 authorization_delegate);
15776 if (rc != TPM_RC_SUCCESS) {
15777 base::OnceCallback<void(TPM_RC)> error_reporter =
15778 base::BindOnce(HashSequenceStartErrorCallback, std::move(callback));
15779 std::move(error_reporter).Run(rc);
15780 return;
15781 }
15782 base::OnceCallback<void(const std::string&)> parser =
15783 base::BindOnce(HashSequenceStartResponseParser, std::move(callback),
15784 authorization_delegate);
15785 transceiver_->SendCommand(command, std::move(parser));
15786 }
15787
HashSequenceStartSync(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15788 TPM_RC Tpm::HashSequenceStartSync(
15789 const TPM2B_AUTH& auth,
15790 const TPMI_ALG_HASH& hash_alg,
15791 TPMI_DH_OBJECT* sequence_handle,
15792 AuthorizationDelegate* authorization_delegate) {
15793 VLOG(1) << __func__;
15794 std::string command;
15795 TPM_RC rc = SerializeCommand_HashSequenceStart(auth, hash_alg, &command,
15796 authorization_delegate);
15797 if (rc != TPM_RC_SUCCESS) {
15798 return rc;
15799 }
15800 std::string response = transceiver_->SendCommandAndWait(command);
15801 rc = ParseResponse_HashSequenceStart(response, sequence_handle,
15802 authorization_delegate);
15803 return rc;
15804 }
15805
SerializeCommand_SequenceUpdate(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15806 TPM_RC Tpm::SerializeCommand_SequenceUpdate(
15807 const TPMI_DH_OBJECT& sequence_handle,
15808 const std::string& sequence_handle_name,
15809 const TPM2B_MAX_BUFFER& buffer,
15810 std::string* serialized_command,
15811 AuthorizationDelegate* authorization_delegate) {
15812 VLOG(3) << __func__;
15813 TPM_RC rc = TPM_RC_SUCCESS;
15814 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15815 UINT32 command_size = 10; // Header size.
15816 std::string handle_section_bytes;
15817 std::string parameter_section_bytes;
15818 TPM_CC command_code = TPM_CC_SequenceUpdate;
15819 bool is_command_parameter_encryption_possible = true;
15820 bool is_response_parameter_encryption_possible = false;
15821 std::string command_code_bytes;
15822 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15823 if (rc != TPM_RC_SUCCESS) {
15824 return rc;
15825 }
15826 std::string sequence_handle_bytes;
15827 rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
15828 if (rc != TPM_RC_SUCCESS) {
15829 return rc;
15830 }
15831 std::string buffer_bytes;
15832 rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
15833 if (rc != TPM_RC_SUCCESS) {
15834 return rc;
15835 }
15836 if (authorization_delegate) {
15837 // Encrypt just the parameter data, not the size.
15838 std::string tmp = buffer_bytes.substr(2);
15839 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15840 return TRUNKS_RC_ENCRYPTION_FAILED;
15841 }
15842 buffer_bytes.replace(2, std::string::npos, tmp);
15843 }
15844 std::unique_ptr<crypto::SecureHash> hash(
15845 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15846 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15847 hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
15848 handle_section_bytes += sequence_handle_bytes;
15849 command_size += sequence_handle_bytes.size();
15850 hash->Update(buffer_bytes.data(), buffer_bytes.size());
15851 parameter_section_bytes += buffer_bytes;
15852 command_size += buffer_bytes.size();
15853 std::string command_hash(32, 0);
15854 hash->Finish(std::data(command_hash), command_hash.size());
15855 std::string authorization_section_bytes;
15856 std::string authorization_size_bytes;
15857 if (authorization_delegate) {
15858 if (!authorization_delegate->GetCommandAuthorization(
15859 command_hash, is_command_parameter_encryption_possible,
15860 is_response_parameter_encryption_possible,
15861 &authorization_section_bytes)) {
15862 return TRUNKS_RC_AUTHORIZATION_FAILED;
15863 }
15864 if (!authorization_section_bytes.empty()) {
15865 tag = TPM_ST_SESSIONS;
15866 std::string tmp;
15867 rc = Serialize_UINT32(authorization_section_bytes.size(),
15868 &authorization_size_bytes);
15869 if (rc != TPM_RC_SUCCESS) {
15870 return rc;
15871 }
15872 command_size +=
15873 authorization_size_bytes.size() + authorization_section_bytes.size();
15874 }
15875 }
15876 std::string tag_bytes;
15877 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15878 if (rc != TPM_RC_SUCCESS) {
15879 return rc;
15880 }
15881 std::string command_size_bytes;
15882 rc = Serialize_UINT32(command_size, &command_size_bytes);
15883 if (rc != TPM_RC_SUCCESS) {
15884 return rc;
15885 }
15886 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15887 handle_section_bytes + authorization_size_bytes +
15888 authorization_section_bytes + parameter_section_bytes;
15889 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15890 VLOG(2) << "Command: "
15891 << base::HexEncode(serialized_command->data(),
15892 serialized_command->size());
15893 return TPM_RC_SUCCESS;
15894 }
15895
ParseResponse_SequenceUpdate(const std::string & response,AuthorizationDelegate * authorization_delegate)15896 TPM_RC Tpm::ParseResponse_SequenceUpdate(
15897 const std::string& response,
15898 AuthorizationDelegate* authorization_delegate) {
15899 VLOG(3) << __func__;
15900 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15901 TPM_RC rc = TPM_RC_SUCCESS;
15902 std::string buffer(response);
15903 TPM_ST tag;
15904 std::string tag_bytes;
15905 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15906 if (rc != TPM_RC_SUCCESS) {
15907 return rc;
15908 }
15909 UINT32 response_size;
15910 std::string response_size_bytes;
15911 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15912 if (rc != TPM_RC_SUCCESS) {
15913 return rc;
15914 }
15915 TPM_RC response_code;
15916 std::string response_code_bytes;
15917 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15918 if (rc != TPM_RC_SUCCESS) {
15919 return rc;
15920 }
15921 if (response_size != response.size()) {
15922 return TPM_RC_SIZE;
15923 }
15924 if (response_code != TPM_RC_SUCCESS) {
15925 return response_code;
15926 }
15927 TPM_CC command_code = TPM_CC_SequenceUpdate;
15928 std::string command_code_bytes;
15929 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15930 if (rc != TPM_RC_SUCCESS) {
15931 return rc;
15932 }
15933 std::string authorization_section_bytes;
15934 if (tag == TPM_ST_SESSIONS) {
15935 UINT32 parameter_section_size = buffer.size();
15936 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
15937 if (rc != TPM_RC_SUCCESS) {
15938 return rc;
15939 }
15940 if (parameter_section_size > buffer.size()) {
15941 return TPM_RC_INSUFFICIENT;
15942 }
15943 authorization_section_bytes = buffer.substr(parameter_section_size);
15944 // Keep the parameter section in |buffer|.
15945 buffer.erase(parameter_section_size);
15946 }
15947 std::unique_ptr<crypto::SecureHash> hash(
15948 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15949 hash->Update(response_code_bytes.data(), response_code_bytes.size());
15950 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15951 hash->Update(buffer.data(), buffer.size());
15952 std::string response_hash(32, 0);
15953 hash->Finish(std::data(response_hash), response_hash.size());
15954 if (tag == TPM_ST_SESSIONS) {
15955 if (!authorization_delegate)
15956 return TRUNKS_RC_AUTHORIZATION_FAILED;
15957 if (!authorization_delegate->CheckResponseAuthorization(
15958 response_hash, authorization_section_bytes)) {
15959 return TRUNKS_RC_AUTHORIZATION_FAILED;
15960 }
15961 }
15962 return TPM_RC_SUCCESS;
15963 }
15964
SequenceUpdateErrorCallback(Tpm::SequenceUpdateResponse callback,TPM_RC response_code)15965 void SequenceUpdateErrorCallback(Tpm::SequenceUpdateResponse callback,
15966 TPM_RC response_code) {
15967 VLOG(1) << __func__;
15968 std::move(callback).Run(response_code);
15969 }
15970
SequenceUpdateResponseParser(Tpm::SequenceUpdateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15971 void SequenceUpdateResponseParser(Tpm::SequenceUpdateResponse callback,
15972 AuthorizationDelegate* authorization_delegate,
15973 const std::string& response) {
15974 VLOG(1) << __func__;
15975 TPM_RC rc =
15976 Tpm::ParseResponse_SequenceUpdate(response, authorization_delegate);
15977 if (rc != TPM_RC_SUCCESS) {
15978 base::OnceCallback<void(TPM_RC)> error_reporter =
15979 base::BindOnce(SequenceUpdateErrorCallback, std::move(callback));
15980 std::move(error_reporter).Run(rc);
15981 return;
15982 }
15983 std::move(callback).Run(rc);
15984 }
15985
SequenceUpdate(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate,SequenceUpdateResponse callback)15986 void Tpm::SequenceUpdate(const TPMI_DH_OBJECT& sequence_handle,
15987 const std::string& sequence_handle_name,
15988 const TPM2B_MAX_BUFFER& buffer,
15989 AuthorizationDelegate* authorization_delegate,
15990 SequenceUpdateResponse callback) {
15991 VLOG(1) << __func__;
15992 std::string command;
15993 TPM_RC rc =
15994 SerializeCommand_SequenceUpdate(sequence_handle, sequence_handle_name,
15995 buffer, &command, authorization_delegate);
15996 if (rc != TPM_RC_SUCCESS) {
15997 base::OnceCallback<void(TPM_RC)> error_reporter =
15998 base::BindOnce(SequenceUpdateErrorCallback, std::move(callback));
15999 std::move(error_reporter).Run(rc);
16000 return;
16001 }
16002 base::OnceCallback<void(const std::string&)> parser =
16003 base::BindOnce(SequenceUpdateResponseParser, std::move(callback),
16004 authorization_delegate);
16005 transceiver_->SendCommand(command, std::move(parser));
16006 }
16007
SequenceUpdateSync(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate)16008 TPM_RC Tpm::SequenceUpdateSync(const TPMI_DH_OBJECT& sequence_handle,
16009 const std::string& sequence_handle_name,
16010 const TPM2B_MAX_BUFFER& buffer,
16011 AuthorizationDelegate* authorization_delegate) {
16012 VLOG(1) << __func__;
16013 std::string command;
16014 TPM_RC rc =
16015 SerializeCommand_SequenceUpdate(sequence_handle, sequence_handle_name,
16016 buffer, &command, authorization_delegate);
16017 if (rc != TPM_RC_SUCCESS) {
16018 return rc;
16019 }
16020 std::string response = transceiver_->SendCommandAndWait(command);
16021 rc = ParseResponse_SequenceUpdate(response, authorization_delegate);
16022 return rc;
16023 }
16024
SerializeCommand_SequenceComplete(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_RH_HIERARCHY & hierarchy,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16025 TPM_RC Tpm::SerializeCommand_SequenceComplete(
16026 const TPMI_DH_OBJECT& sequence_handle,
16027 const std::string& sequence_handle_name,
16028 const TPM2B_MAX_BUFFER& buffer,
16029 const TPMI_RH_HIERARCHY& hierarchy,
16030 std::string* serialized_command,
16031 AuthorizationDelegate* authorization_delegate) {
16032 VLOG(3) << __func__;
16033 TPM_RC rc = TPM_RC_SUCCESS;
16034 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16035 UINT32 command_size = 10; // Header size.
16036 std::string handle_section_bytes;
16037 std::string parameter_section_bytes;
16038 TPM_CC command_code = TPM_CC_SequenceComplete;
16039 bool is_command_parameter_encryption_possible = true;
16040 bool is_response_parameter_encryption_possible = true;
16041 std::string command_code_bytes;
16042 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16043 if (rc != TPM_RC_SUCCESS) {
16044 return rc;
16045 }
16046 std::string sequence_handle_bytes;
16047 rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
16048 if (rc != TPM_RC_SUCCESS) {
16049 return rc;
16050 }
16051 std::string buffer_bytes;
16052 rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
16053 if (rc != TPM_RC_SUCCESS) {
16054 return rc;
16055 }
16056 std::string hierarchy_bytes;
16057 rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
16058 if (rc != TPM_RC_SUCCESS) {
16059 return rc;
16060 }
16061 if (authorization_delegate) {
16062 // Encrypt just the parameter data, not the size.
16063 std::string tmp = buffer_bytes.substr(2);
16064 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16065 return TRUNKS_RC_ENCRYPTION_FAILED;
16066 }
16067 buffer_bytes.replace(2, std::string::npos, tmp);
16068 }
16069 std::unique_ptr<crypto::SecureHash> hash(
16070 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16071 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16072 hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
16073 handle_section_bytes += sequence_handle_bytes;
16074 command_size += sequence_handle_bytes.size();
16075 hash->Update(buffer_bytes.data(), buffer_bytes.size());
16076 parameter_section_bytes += buffer_bytes;
16077 command_size += buffer_bytes.size();
16078 hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
16079 parameter_section_bytes += hierarchy_bytes;
16080 command_size += hierarchy_bytes.size();
16081 std::string command_hash(32, 0);
16082 hash->Finish(std::data(command_hash), command_hash.size());
16083 std::string authorization_section_bytes;
16084 std::string authorization_size_bytes;
16085 if (authorization_delegate) {
16086 if (!authorization_delegate->GetCommandAuthorization(
16087 command_hash, is_command_parameter_encryption_possible,
16088 is_response_parameter_encryption_possible,
16089 &authorization_section_bytes)) {
16090 return TRUNKS_RC_AUTHORIZATION_FAILED;
16091 }
16092 if (!authorization_section_bytes.empty()) {
16093 tag = TPM_ST_SESSIONS;
16094 std::string tmp;
16095 rc = Serialize_UINT32(authorization_section_bytes.size(),
16096 &authorization_size_bytes);
16097 if (rc != TPM_RC_SUCCESS) {
16098 return rc;
16099 }
16100 command_size +=
16101 authorization_size_bytes.size() + authorization_section_bytes.size();
16102 }
16103 }
16104 std::string tag_bytes;
16105 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16106 if (rc != TPM_RC_SUCCESS) {
16107 return rc;
16108 }
16109 std::string command_size_bytes;
16110 rc = Serialize_UINT32(command_size, &command_size_bytes);
16111 if (rc != TPM_RC_SUCCESS) {
16112 return rc;
16113 }
16114 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16115 handle_section_bytes + authorization_size_bytes +
16116 authorization_section_bytes + parameter_section_bytes;
16117 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16118 VLOG(2) << "Command: "
16119 << base::HexEncode(serialized_command->data(),
16120 serialized_command->size());
16121 return TPM_RC_SUCCESS;
16122 }
16123
ParseResponse_SequenceComplete(const std::string & response,TPM2B_DIGEST * result,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)16124 TPM_RC Tpm::ParseResponse_SequenceComplete(
16125 const std::string& response,
16126 TPM2B_DIGEST* result,
16127 TPMT_TK_HASHCHECK* validation,
16128 AuthorizationDelegate* authorization_delegate) {
16129 VLOG(3) << __func__;
16130 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16131 TPM_RC rc = TPM_RC_SUCCESS;
16132 std::string buffer(response);
16133 TPM_ST tag;
16134 std::string tag_bytes;
16135 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16136 if (rc != TPM_RC_SUCCESS) {
16137 return rc;
16138 }
16139 UINT32 response_size;
16140 std::string response_size_bytes;
16141 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16142 if (rc != TPM_RC_SUCCESS) {
16143 return rc;
16144 }
16145 TPM_RC response_code;
16146 std::string response_code_bytes;
16147 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16148 if (rc != TPM_RC_SUCCESS) {
16149 return rc;
16150 }
16151 if (response_size != response.size()) {
16152 return TPM_RC_SIZE;
16153 }
16154 if (response_code != TPM_RC_SUCCESS) {
16155 return response_code;
16156 }
16157 TPM_CC command_code = TPM_CC_SequenceComplete;
16158 std::string command_code_bytes;
16159 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16160 if (rc != TPM_RC_SUCCESS) {
16161 return rc;
16162 }
16163 std::string authorization_section_bytes;
16164 if (tag == TPM_ST_SESSIONS) {
16165 UINT32 parameter_section_size = buffer.size();
16166 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
16167 if (rc != TPM_RC_SUCCESS) {
16168 return rc;
16169 }
16170 if (parameter_section_size > buffer.size()) {
16171 return TPM_RC_INSUFFICIENT;
16172 }
16173 authorization_section_bytes = buffer.substr(parameter_section_size);
16174 // Keep the parameter section in |buffer|.
16175 buffer.erase(parameter_section_size);
16176 }
16177 std::unique_ptr<crypto::SecureHash> hash(
16178 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16179 hash->Update(response_code_bytes.data(), response_code_bytes.size());
16180 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16181 hash->Update(buffer.data(), buffer.size());
16182 std::string response_hash(32, 0);
16183 hash->Finish(std::data(response_hash), response_hash.size());
16184 if (tag == TPM_ST_SESSIONS) {
16185 if (!authorization_delegate)
16186 return TRUNKS_RC_AUTHORIZATION_FAILED;
16187 if (!authorization_delegate->CheckResponseAuthorization(
16188 response_hash, authorization_section_bytes)) {
16189 return TRUNKS_RC_AUTHORIZATION_FAILED;
16190 }
16191 }
16192 if (tag == TPM_ST_SESSIONS) {
16193 if (!authorization_delegate)
16194 return TRUNKS_RC_AUTHORIZATION_FAILED;
16195
16196 // Parse the encrypted parameter size.
16197 UINT16 size;
16198 std::string size_buffer = buffer.substr(0, 2);
16199 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
16200 return result;
16201 }
16202 if (buffer.size() < 2 + size) {
16203 return TPM_RC_INSUFFICIENT;
16204 }
16205
16206 // Decrypt just the parameter data, not the size.
16207 std::string decrypted_data = buffer.substr(2, size);
16208 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
16209 return TRUNKS_RC_ENCRYPTION_FAILED;
16210 }
16211 buffer.replace(2, size, decrypted_data);
16212 }
16213 std::string result_bytes;
16214 rc = Parse_TPM2B_DIGEST(&buffer, result, &result_bytes);
16215 if (rc != TPM_RC_SUCCESS) {
16216 return rc;
16217 }
16218 std::string validation_bytes;
16219 rc = Parse_TPMT_TK_HASHCHECK(&buffer, validation, &validation_bytes);
16220 if (rc != TPM_RC_SUCCESS) {
16221 return rc;
16222 }
16223 return TPM_RC_SUCCESS;
16224 }
16225
SequenceCompleteErrorCallback(Tpm::SequenceCompleteResponse callback,TPM_RC response_code)16226 void SequenceCompleteErrorCallback(Tpm::SequenceCompleteResponse callback,
16227 TPM_RC response_code) {
16228 VLOG(1) << __func__;
16229 std::move(callback).Run(response_code, TPM2B_DIGEST(), TPMT_TK_HASHCHECK());
16230 }
16231
SequenceCompleteResponseParser(Tpm::SequenceCompleteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16232 void SequenceCompleteResponseParser(
16233 Tpm::SequenceCompleteResponse callback,
16234 AuthorizationDelegate* authorization_delegate,
16235 const std::string& response) {
16236 VLOG(1) << __func__;
16237 TPM2B_DIGEST result;
16238 TPMT_TK_HASHCHECK validation;
16239 TPM_RC rc = Tpm::ParseResponse_SequenceComplete(
16240 response, &result, &validation, authorization_delegate);
16241 if (rc != TPM_RC_SUCCESS) {
16242 base::OnceCallback<void(TPM_RC)> error_reporter =
16243 base::BindOnce(SequenceCompleteErrorCallback, std::move(callback));
16244 std::move(error_reporter).Run(rc);
16245 return;
16246 }
16247 std::move(callback).Run(rc, result, validation);
16248 }
16249
SequenceComplete(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,SequenceCompleteResponse callback)16250 void Tpm::SequenceComplete(const TPMI_DH_OBJECT& sequence_handle,
16251 const std::string& sequence_handle_name,
16252 const TPM2B_MAX_BUFFER& buffer,
16253 const TPMI_RH_HIERARCHY& hierarchy,
16254 AuthorizationDelegate* authorization_delegate,
16255 SequenceCompleteResponse callback) {
16256 VLOG(1) << __func__;
16257 std::string command;
16258 TPM_RC rc = SerializeCommand_SequenceComplete(
16259 sequence_handle, sequence_handle_name, buffer, hierarchy, &command,
16260 authorization_delegate);
16261 if (rc != TPM_RC_SUCCESS) {
16262 base::OnceCallback<void(TPM_RC)> error_reporter =
16263 base::BindOnce(SequenceCompleteErrorCallback, std::move(callback));
16264 std::move(error_reporter).Run(rc);
16265 return;
16266 }
16267 base::OnceCallback<void(const std::string&)> parser =
16268 base::BindOnce(SequenceCompleteResponseParser, std::move(callback),
16269 authorization_delegate);
16270 transceiver_->SendCommand(command, std::move(parser));
16271 }
16272
SequenceCompleteSync(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_RH_HIERARCHY & hierarchy,TPM2B_DIGEST * result,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)16273 TPM_RC Tpm::SequenceCompleteSync(
16274 const TPMI_DH_OBJECT& sequence_handle,
16275 const std::string& sequence_handle_name,
16276 const TPM2B_MAX_BUFFER& buffer,
16277 const TPMI_RH_HIERARCHY& hierarchy,
16278 TPM2B_DIGEST* result,
16279 TPMT_TK_HASHCHECK* validation,
16280 AuthorizationDelegate* authorization_delegate) {
16281 VLOG(1) << __func__;
16282 std::string command;
16283 TPM_RC rc = SerializeCommand_SequenceComplete(
16284 sequence_handle, sequence_handle_name, buffer, hierarchy, &command,
16285 authorization_delegate);
16286 if (rc != TPM_RC_SUCCESS) {
16287 return rc;
16288 }
16289 std::string response = transceiver_->SendCommandAndWait(command);
16290 rc = ParseResponse_SequenceComplete(response, result, validation,
16291 authorization_delegate);
16292 return rc;
16293 }
16294
SerializeCommand_EventSequenceComplete(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16295 TPM_RC Tpm::SerializeCommand_EventSequenceComplete(
16296 const TPMI_DH_PCR& pcr_handle,
16297 const std::string& pcr_handle_name,
16298 const TPMI_DH_OBJECT& sequence_handle,
16299 const std::string& sequence_handle_name,
16300 const TPM2B_MAX_BUFFER& buffer,
16301 std::string* serialized_command,
16302 AuthorizationDelegate* authorization_delegate) {
16303 VLOG(3) << __func__;
16304 TPM_RC rc = TPM_RC_SUCCESS;
16305 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16306 UINT32 command_size = 10; // Header size.
16307 std::string handle_section_bytes;
16308 std::string parameter_section_bytes;
16309 TPM_CC command_code = TPM_CC_EventSequenceComplete;
16310 bool is_command_parameter_encryption_possible = true;
16311 bool is_response_parameter_encryption_possible = false;
16312 std::string command_code_bytes;
16313 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16314 if (rc != TPM_RC_SUCCESS) {
16315 return rc;
16316 }
16317 std::string pcr_handle_bytes;
16318 rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
16319 if (rc != TPM_RC_SUCCESS) {
16320 return rc;
16321 }
16322 std::string sequence_handle_bytes;
16323 rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
16324 if (rc != TPM_RC_SUCCESS) {
16325 return rc;
16326 }
16327 std::string buffer_bytes;
16328 rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
16329 if (rc != TPM_RC_SUCCESS) {
16330 return rc;
16331 }
16332 if (authorization_delegate) {
16333 // Encrypt just the parameter data, not the size.
16334 std::string tmp = buffer_bytes.substr(2);
16335 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16336 return TRUNKS_RC_ENCRYPTION_FAILED;
16337 }
16338 buffer_bytes.replace(2, std::string::npos, tmp);
16339 }
16340 std::unique_ptr<crypto::SecureHash> hash(
16341 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16342 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16343 hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
16344 handle_section_bytes += pcr_handle_bytes;
16345 command_size += pcr_handle_bytes.size();
16346 hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
16347 handle_section_bytes += sequence_handle_bytes;
16348 command_size += sequence_handle_bytes.size();
16349 hash->Update(buffer_bytes.data(), buffer_bytes.size());
16350 parameter_section_bytes += buffer_bytes;
16351 command_size += buffer_bytes.size();
16352 std::string command_hash(32, 0);
16353 hash->Finish(std::data(command_hash), command_hash.size());
16354 std::string authorization_section_bytes;
16355 std::string authorization_size_bytes;
16356 if (authorization_delegate) {
16357 if (!authorization_delegate->GetCommandAuthorization(
16358 command_hash, is_command_parameter_encryption_possible,
16359 is_response_parameter_encryption_possible,
16360 &authorization_section_bytes)) {
16361 return TRUNKS_RC_AUTHORIZATION_FAILED;
16362 }
16363 if (!authorization_section_bytes.empty()) {
16364 tag = TPM_ST_SESSIONS;
16365 std::string tmp;
16366 rc = Serialize_UINT32(authorization_section_bytes.size(),
16367 &authorization_size_bytes);
16368 if (rc != TPM_RC_SUCCESS) {
16369 return rc;
16370 }
16371 command_size +=
16372 authorization_size_bytes.size() + authorization_section_bytes.size();
16373 }
16374 }
16375 std::string tag_bytes;
16376 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16377 if (rc != TPM_RC_SUCCESS) {
16378 return rc;
16379 }
16380 std::string command_size_bytes;
16381 rc = Serialize_UINT32(command_size, &command_size_bytes);
16382 if (rc != TPM_RC_SUCCESS) {
16383 return rc;
16384 }
16385 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16386 handle_section_bytes + authorization_size_bytes +
16387 authorization_section_bytes + parameter_section_bytes;
16388 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16389 VLOG(2) << "Command: "
16390 << base::HexEncode(serialized_command->data(),
16391 serialized_command->size());
16392 return TPM_RC_SUCCESS;
16393 }
16394
ParseResponse_EventSequenceComplete(const std::string & response,TPML_DIGEST_VALUES * results,AuthorizationDelegate * authorization_delegate)16395 TPM_RC Tpm::ParseResponse_EventSequenceComplete(
16396 const std::string& response,
16397 TPML_DIGEST_VALUES* results,
16398 AuthorizationDelegate* authorization_delegate) {
16399 VLOG(3) << __func__;
16400 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16401 TPM_RC rc = TPM_RC_SUCCESS;
16402 std::string buffer(response);
16403 TPM_ST tag;
16404 std::string tag_bytes;
16405 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16406 if (rc != TPM_RC_SUCCESS) {
16407 return rc;
16408 }
16409 UINT32 response_size;
16410 std::string response_size_bytes;
16411 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16412 if (rc != TPM_RC_SUCCESS) {
16413 return rc;
16414 }
16415 TPM_RC response_code;
16416 std::string response_code_bytes;
16417 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16418 if (rc != TPM_RC_SUCCESS) {
16419 return rc;
16420 }
16421 if (response_size != response.size()) {
16422 return TPM_RC_SIZE;
16423 }
16424 if (response_code != TPM_RC_SUCCESS) {
16425 return response_code;
16426 }
16427 TPM_CC command_code = TPM_CC_EventSequenceComplete;
16428 std::string command_code_bytes;
16429 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16430 if (rc != TPM_RC_SUCCESS) {
16431 return rc;
16432 }
16433 std::string authorization_section_bytes;
16434 if (tag == TPM_ST_SESSIONS) {
16435 UINT32 parameter_section_size = buffer.size();
16436 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
16437 if (rc != TPM_RC_SUCCESS) {
16438 return rc;
16439 }
16440 if (parameter_section_size > buffer.size()) {
16441 return TPM_RC_INSUFFICIENT;
16442 }
16443 authorization_section_bytes = buffer.substr(parameter_section_size);
16444 // Keep the parameter section in |buffer|.
16445 buffer.erase(parameter_section_size);
16446 }
16447 std::unique_ptr<crypto::SecureHash> hash(
16448 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16449 hash->Update(response_code_bytes.data(), response_code_bytes.size());
16450 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16451 hash->Update(buffer.data(), buffer.size());
16452 std::string response_hash(32, 0);
16453 hash->Finish(std::data(response_hash), response_hash.size());
16454 if (tag == TPM_ST_SESSIONS) {
16455 if (!authorization_delegate)
16456 return TRUNKS_RC_AUTHORIZATION_FAILED;
16457 if (!authorization_delegate->CheckResponseAuthorization(
16458 response_hash, authorization_section_bytes)) {
16459 return TRUNKS_RC_AUTHORIZATION_FAILED;
16460 }
16461 }
16462 std::string results_bytes;
16463 rc = Parse_TPML_DIGEST_VALUES(&buffer, results, &results_bytes);
16464 if (rc != TPM_RC_SUCCESS) {
16465 return rc;
16466 }
16467 return TPM_RC_SUCCESS;
16468 }
16469
EventSequenceCompleteErrorCallback(Tpm::EventSequenceCompleteResponse callback,TPM_RC response_code)16470 void EventSequenceCompleteErrorCallback(
16471 Tpm::EventSequenceCompleteResponse callback, TPM_RC response_code) {
16472 VLOG(1) << __func__;
16473 std::move(callback).Run(response_code, TPML_DIGEST_VALUES());
16474 }
16475
EventSequenceCompleteResponseParser(Tpm::EventSequenceCompleteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16476 void EventSequenceCompleteResponseParser(
16477 Tpm::EventSequenceCompleteResponse callback,
16478 AuthorizationDelegate* authorization_delegate,
16479 const std::string& response) {
16480 VLOG(1) << __func__;
16481 TPML_DIGEST_VALUES results;
16482 TPM_RC rc = Tpm::ParseResponse_EventSequenceComplete(response, &results,
16483 authorization_delegate);
16484 if (rc != TPM_RC_SUCCESS) {
16485 base::OnceCallback<void(TPM_RC)> error_reporter =
16486 base::BindOnce(EventSequenceCompleteErrorCallback, std::move(callback));
16487 std::move(error_reporter).Run(rc);
16488 return;
16489 }
16490 std::move(callback).Run(rc, results);
16491 }
16492
EventSequenceComplete(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate,EventSequenceCompleteResponse callback)16493 void Tpm::EventSequenceComplete(const TPMI_DH_PCR& pcr_handle,
16494 const std::string& pcr_handle_name,
16495 const TPMI_DH_OBJECT& sequence_handle,
16496 const std::string& sequence_handle_name,
16497 const TPM2B_MAX_BUFFER& buffer,
16498 AuthorizationDelegate* authorization_delegate,
16499 EventSequenceCompleteResponse callback) {
16500 VLOG(1) << __func__;
16501 std::string command;
16502 TPM_RC rc = SerializeCommand_EventSequenceComplete(
16503 pcr_handle, pcr_handle_name, sequence_handle, sequence_handle_name,
16504 buffer, &command, authorization_delegate);
16505 if (rc != TPM_RC_SUCCESS) {
16506 base::OnceCallback<void(TPM_RC)> error_reporter =
16507 base::BindOnce(EventSequenceCompleteErrorCallback, std::move(callback));
16508 std::move(error_reporter).Run(rc);
16509 return;
16510 }
16511 base::OnceCallback<void(const std::string&)> parser =
16512 base::BindOnce(EventSequenceCompleteResponseParser, std::move(callback),
16513 authorization_delegate);
16514 transceiver_->SendCommand(command, std::move(parser));
16515 }
16516
EventSequenceCompleteSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,TPML_DIGEST_VALUES * results,AuthorizationDelegate * authorization_delegate)16517 TPM_RC Tpm::EventSequenceCompleteSync(
16518 const TPMI_DH_PCR& pcr_handle,
16519 const std::string& pcr_handle_name,
16520 const TPMI_DH_OBJECT& sequence_handle,
16521 const std::string& sequence_handle_name,
16522 const TPM2B_MAX_BUFFER& buffer,
16523 TPML_DIGEST_VALUES* results,
16524 AuthorizationDelegate* authorization_delegate) {
16525 VLOG(1) << __func__;
16526 std::string command;
16527 TPM_RC rc = SerializeCommand_EventSequenceComplete(
16528 pcr_handle, pcr_handle_name, sequence_handle, sequence_handle_name,
16529 buffer, &command, authorization_delegate);
16530 if (rc != TPM_RC_SUCCESS) {
16531 return rc;
16532 }
16533 std::string response = transceiver_->SendCommandAndWait(command);
16534 rc = ParseResponse_EventSequenceComplete(response, results,
16535 authorization_delegate);
16536 return rc;
16537 }
16538
SerializeCommand_Certify(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16539 TPM_RC Tpm::SerializeCommand_Certify(
16540 const TPMI_DH_OBJECT& object_handle,
16541 const std::string& object_handle_name,
16542 const TPMI_DH_OBJECT& sign_handle,
16543 const std::string& sign_handle_name,
16544 const TPM2B_DATA& qualifying_data,
16545 const TPMT_SIG_SCHEME& in_scheme,
16546 std::string* serialized_command,
16547 AuthorizationDelegate* authorization_delegate) {
16548 VLOG(3) << __func__;
16549 TPM_RC rc = TPM_RC_SUCCESS;
16550 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16551 UINT32 command_size = 10; // Header size.
16552 std::string handle_section_bytes;
16553 std::string parameter_section_bytes;
16554 TPM_CC command_code = TPM_CC_Certify;
16555 bool is_command_parameter_encryption_possible = true;
16556 bool is_response_parameter_encryption_possible = true;
16557 std::string command_code_bytes;
16558 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16559 if (rc != TPM_RC_SUCCESS) {
16560 return rc;
16561 }
16562 std::string object_handle_bytes;
16563 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
16564 if (rc != TPM_RC_SUCCESS) {
16565 return rc;
16566 }
16567 std::string sign_handle_bytes;
16568 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16569 if (rc != TPM_RC_SUCCESS) {
16570 return rc;
16571 }
16572 std::string qualifying_data_bytes;
16573 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16574 if (rc != TPM_RC_SUCCESS) {
16575 return rc;
16576 }
16577 std::string in_scheme_bytes;
16578 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16579 if (rc != TPM_RC_SUCCESS) {
16580 return rc;
16581 }
16582 if (authorization_delegate) {
16583 // Encrypt just the parameter data, not the size.
16584 std::string tmp = qualifying_data_bytes.substr(2);
16585 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16586 return TRUNKS_RC_ENCRYPTION_FAILED;
16587 }
16588 qualifying_data_bytes.replace(2, std::string::npos, tmp);
16589 }
16590 std::unique_ptr<crypto::SecureHash> hash(
16591 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16592 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16593 hash->Update(object_handle_name.data(), object_handle_name.size());
16594 handle_section_bytes += object_handle_bytes;
16595 command_size += object_handle_bytes.size();
16596 hash->Update(sign_handle_name.data(), sign_handle_name.size());
16597 handle_section_bytes += sign_handle_bytes;
16598 command_size += sign_handle_bytes.size();
16599 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16600 parameter_section_bytes += qualifying_data_bytes;
16601 command_size += qualifying_data_bytes.size();
16602 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16603 parameter_section_bytes += in_scheme_bytes;
16604 command_size += in_scheme_bytes.size();
16605 std::string command_hash(32, 0);
16606 hash->Finish(std::data(command_hash), command_hash.size());
16607 std::string authorization_section_bytes;
16608 std::string authorization_size_bytes;
16609 if (authorization_delegate) {
16610 if (!authorization_delegate->GetCommandAuthorization(
16611 command_hash, is_command_parameter_encryption_possible,
16612 is_response_parameter_encryption_possible,
16613 &authorization_section_bytes)) {
16614 return TRUNKS_RC_AUTHORIZATION_FAILED;
16615 }
16616 if (!authorization_section_bytes.empty()) {
16617 tag = TPM_ST_SESSIONS;
16618 std::string tmp;
16619 rc = Serialize_UINT32(authorization_section_bytes.size(),
16620 &authorization_size_bytes);
16621 if (rc != TPM_RC_SUCCESS) {
16622 return rc;
16623 }
16624 command_size +=
16625 authorization_size_bytes.size() + authorization_section_bytes.size();
16626 }
16627 }
16628 std::string tag_bytes;
16629 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16630 if (rc != TPM_RC_SUCCESS) {
16631 return rc;
16632 }
16633 std::string command_size_bytes;
16634 rc = Serialize_UINT32(command_size, &command_size_bytes);
16635 if (rc != TPM_RC_SUCCESS) {
16636 return rc;
16637 }
16638 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16639 handle_section_bytes + authorization_size_bytes +
16640 authorization_section_bytes + parameter_section_bytes;
16641 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16642 VLOG(2) << "Command: "
16643 << base::HexEncode(serialized_command->data(),
16644 serialized_command->size());
16645 return TPM_RC_SUCCESS;
16646 }
16647
ParseResponse_Certify(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16648 TPM_RC Tpm::ParseResponse_Certify(
16649 const std::string& response,
16650 TPM2B_ATTEST* certify_info,
16651 TPMT_SIGNATURE* signature,
16652 AuthorizationDelegate* authorization_delegate) {
16653 VLOG(3) << __func__;
16654 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16655 TPM_RC rc = TPM_RC_SUCCESS;
16656 std::string buffer(response);
16657 TPM_ST tag;
16658 std::string tag_bytes;
16659 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16660 if (rc != TPM_RC_SUCCESS) {
16661 return rc;
16662 }
16663 UINT32 response_size;
16664 std::string response_size_bytes;
16665 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16666 if (rc != TPM_RC_SUCCESS) {
16667 return rc;
16668 }
16669 TPM_RC response_code;
16670 std::string response_code_bytes;
16671 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16672 if (rc != TPM_RC_SUCCESS) {
16673 return rc;
16674 }
16675 if (response_size != response.size()) {
16676 return TPM_RC_SIZE;
16677 }
16678 if (response_code != TPM_RC_SUCCESS) {
16679 return response_code;
16680 }
16681 TPM_CC command_code = TPM_CC_Certify;
16682 std::string command_code_bytes;
16683 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16684 if (rc != TPM_RC_SUCCESS) {
16685 return rc;
16686 }
16687 std::string authorization_section_bytes;
16688 if (tag == TPM_ST_SESSIONS) {
16689 UINT32 parameter_section_size = buffer.size();
16690 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
16691 if (rc != TPM_RC_SUCCESS) {
16692 return rc;
16693 }
16694 if (parameter_section_size > buffer.size()) {
16695 return TPM_RC_INSUFFICIENT;
16696 }
16697 authorization_section_bytes = buffer.substr(parameter_section_size);
16698 // Keep the parameter section in |buffer|.
16699 buffer.erase(parameter_section_size);
16700 }
16701 std::unique_ptr<crypto::SecureHash> hash(
16702 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16703 hash->Update(response_code_bytes.data(), response_code_bytes.size());
16704 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16705 hash->Update(buffer.data(), buffer.size());
16706 std::string response_hash(32, 0);
16707 hash->Finish(std::data(response_hash), response_hash.size());
16708 if (tag == TPM_ST_SESSIONS) {
16709 if (!authorization_delegate)
16710 return TRUNKS_RC_AUTHORIZATION_FAILED;
16711 if (!authorization_delegate->CheckResponseAuthorization(
16712 response_hash, authorization_section_bytes)) {
16713 return TRUNKS_RC_AUTHORIZATION_FAILED;
16714 }
16715 }
16716 if (tag == TPM_ST_SESSIONS) {
16717 if (!authorization_delegate)
16718 return TRUNKS_RC_AUTHORIZATION_FAILED;
16719
16720 // Parse the encrypted parameter size.
16721 UINT16 size;
16722 std::string size_buffer = buffer.substr(0, 2);
16723 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
16724 return result;
16725 }
16726 if (buffer.size() < 2 + size) {
16727 return TPM_RC_INSUFFICIENT;
16728 }
16729
16730 // Decrypt just the parameter data, not the size.
16731 std::string decrypted_data = buffer.substr(2, size);
16732 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
16733 return TRUNKS_RC_ENCRYPTION_FAILED;
16734 }
16735 buffer.replace(2, size, decrypted_data);
16736 }
16737 std::string certify_info_bytes;
16738 rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
16739 if (rc != TPM_RC_SUCCESS) {
16740 return rc;
16741 }
16742 std::string signature_bytes;
16743 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
16744 if (rc != TPM_RC_SUCCESS) {
16745 return rc;
16746 }
16747 return TPM_RC_SUCCESS;
16748 }
16749
CertifyErrorCallback(Tpm::CertifyResponse callback,TPM_RC response_code)16750 void CertifyErrorCallback(Tpm::CertifyResponse callback, TPM_RC response_code) {
16751 VLOG(1) << __func__;
16752 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
16753 }
16754
CertifyResponseParser(Tpm::CertifyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16755 void CertifyResponseParser(Tpm::CertifyResponse callback,
16756 AuthorizationDelegate* authorization_delegate,
16757 const std::string& response) {
16758 VLOG(1) << __func__;
16759 TPM2B_ATTEST certify_info;
16760 TPMT_SIGNATURE signature;
16761 TPM_RC rc = Tpm::ParseResponse_Certify(response, &certify_info, &signature,
16762 authorization_delegate);
16763 if (rc != TPM_RC_SUCCESS) {
16764 base::OnceCallback<void(TPM_RC)> error_reporter =
16765 base::BindOnce(CertifyErrorCallback, std::move(callback));
16766 std::move(error_reporter).Run(rc);
16767 return;
16768 }
16769 std::move(callback).Run(rc, certify_info, signature);
16770 }
16771
Certify(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,CertifyResponse callback)16772 void Tpm::Certify(const TPMI_DH_OBJECT& object_handle,
16773 const std::string& object_handle_name,
16774 const TPMI_DH_OBJECT& sign_handle,
16775 const std::string& sign_handle_name,
16776 const TPM2B_DATA& qualifying_data,
16777 const TPMT_SIG_SCHEME& in_scheme,
16778 AuthorizationDelegate* authorization_delegate,
16779 CertifyResponse callback) {
16780 VLOG(1) << __func__;
16781 std::string command;
16782 TPM_RC rc = SerializeCommand_Certify(
16783 object_handle, object_handle_name, sign_handle, sign_handle_name,
16784 qualifying_data, in_scheme, &command, authorization_delegate);
16785 if (rc != TPM_RC_SUCCESS) {
16786 base::OnceCallback<void(TPM_RC)> error_reporter =
16787 base::BindOnce(CertifyErrorCallback, std::move(callback));
16788 std::move(error_reporter).Run(rc);
16789 return;
16790 }
16791 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
16792 CertifyResponseParser, std::move(callback), authorization_delegate);
16793 transceiver_->SendCommand(command, std::move(parser));
16794 }
16795
CertifySync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16796 TPM_RC Tpm::CertifySync(const TPMI_DH_OBJECT& object_handle,
16797 const std::string& object_handle_name,
16798 const TPMI_DH_OBJECT& sign_handle,
16799 const std::string& sign_handle_name,
16800 const TPM2B_DATA& qualifying_data,
16801 const TPMT_SIG_SCHEME& in_scheme,
16802 TPM2B_ATTEST* certify_info,
16803 TPMT_SIGNATURE* signature,
16804 AuthorizationDelegate* authorization_delegate) {
16805 VLOG(1) << __func__;
16806 std::string command;
16807 TPM_RC rc = SerializeCommand_Certify(
16808 object_handle, object_handle_name, sign_handle, sign_handle_name,
16809 qualifying_data, in_scheme, &command, authorization_delegate);
16810 if (rc != TPM_RC_SUCCESS) {
16811 return rc;
16812 }
16813 std::string response = transceiver_->SendCommandAndWait(command);
16814 rc = ParseResponse_Certify(response, certify_info, signature,
16815 authorization_delegate);
16816 return rc;
16817 }
16818
SerializeCommand_CertifyCreation(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPM2B_DATA & qualifying_data,const TPM2B_DIGEST & creation_hash,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_CREATION & creation_ticket,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16819 TPM_RC Tpm::SerializeCommand_CertifyCreation(
16820 const TPMI_DH_OBJECT& sign_handle,
16821 const std::string& sign_handle_name,
16822 const TPMI_DH_OBJECT& object_handle,
16823 const std::string& object_handle_name,
16824 const TPM2B_DATA& qualifying_data,
16825 const TPM2B_DIGEST& creation_hash,
16826 const TPMT_SIG_SCHEME& in_scheme,
16827 const TPMT_TK_CREATION& creation_ticket,
16828 std::string* serialized_command,
16829 AuthorizationDelegate* authorization_delegate) {
16830 VLOG(3) << __func__;
16831 TPM_RC rc = TPM_RC_SUCCESS;
16832 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16833 UINT32 command_size = 10; // Header size.
16834 std::string handle_section_bytes;
16835 std::string parameter_section_bytes;
16836 TPM_CC command_code = TPM_CC_CertifyCreation;
16837 bool is_command_parameter_encryption_possible = true;
16838 bool is_response_parameter_encryption_possible = true;
16839 std::string command_code_bytes;
16840 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16841 if (rc != TPM_RC_SUCCESS) {
16842 return rc;
16843 }
16844 std::string sign_handle_bytes;
16845 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16846 if (rc != TPM_RC_SUCCESS) {
16847 return rc;
16848 }
16849 std::string object_handle_bytes;
16850 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
16851 if (rc != TPM_RC_SUCCESS) {
16852 return rc;
16853 }
16854 std::string qualifying_data_bytes;
16855 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16856 if (rc != TPM_RC_SUCCESS) {
16857 return rc;
16858 }
16859 std::string creation_hash_bytes;
16860 rc = Serialize_TPM2B_DIGEST(creation_hash, &creation_hash_bytes);
16861 if (rc != TPM_RC_SUCCESS) {
16862 return rc;
16863 }
16864 std::string in_scheme_bytes;
16865 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16866 if (rc != TPM_RC_SUCCESS) {
16867 return rc;
16868 }
16869 std::string creation_ticket_bytes;
16870 rc = Serialize_TPMT_TK_CREATION(creation_ticket, &creation_ticket_bytes);
16871 if (rc != TPM_RC_SUCCESS) {
16872 return rc;
16873 }
16874 if (authorization_delegate) {
16875 // Encrypt just the parameter data, not the size.
16876 std::string tmp = qualifying_data_bytes.substr(2);
16877 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16878 return TRUNKS_RC_ENCRYPTION_FAILED;
16879 }
16880 qualifying_data_bytes.replace(2, std::string::npos, tmp);
16881 }
16882 std::unique_ptr<crypto::SecureHash> hash(
16883 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16884 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16885 hash->Update(sign_handle_name.data(), sign_handle_name.size());
16886 handle_section_bytes += sign_handle_bytes;
16887 command_size += sign_handle_bytes.size();
16888 hash->Update(object_handle_name.data(), object_handle_name.size());
16889 handle_section_bytes += object_handle_bytes;
16890 command_size += object_handle_bytes.size();
16891 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16892 parameter_section_bytes += qualifying_data_bytes;
16893 command_size += qualifying_data_bytes.size();
16894 hash->Update(creation_hash_bytes.data(), creation_hash_bytes.size());
16895 parameter_section_bytes += creation_hash_bytes;
16896 command_size += creation_hash_bytes.size();
16897 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16898 parameter_section_bytes += in_scheme_bytes;
16899 command_size += in_scheme_bytes.size();
16900 hash->Update(creation_ticket_bytes.data(), creation_ticket_bytes.size());
16901 parameter_section_bytes += creation_ticket_bytes;
16902 command_size += creation_ticket_bytes.size();
16903 std::string command_hash(32, 0);
16904 hash->Finish(std::data(command_hash), command_hash.size());
16905 std::string authorization_section_bytes;
16906 std::string authorization_size_bytes;
16907 if (authorization_delegate) {
16908 if (!authorization_delegate->GetCommandAuthorization(
16909 command_hash, is_command_parameter_encryption_possible,
16910 is_response_parameter_encryption_possible,
16911 &authorization_section_bytes)) {
16912 return TRUNKS_RC_AUTHORIZATION_FAILED;
16913 }
16914 if (!authorization_section_bytes.empty()) {
16915 tag = TPM_ST_SESSIONS;
16916 std::string tmp;
16917 rc = Serialize_UINT32(authorization_section_bytes.size(),
16918 &authorization_size_bytes);
16919 if (rc != TPM_RC_SUCCESS) {
16920 return rc;
16921 }
16922 command_size +=
16923 authorization_size_bytes.size() + authorization_section_bytes.size();
16924 }
16925 }
16926 std::string tag_bytes;
16927 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16928 if (rc != TPM_RC_SUCCESS) {
16929 return rc;
16930 }
16931 std::string command_size_bytes;
16932 rc = Serialize_UINT32(command_size, &command_size_bytes);
16933 if (rc != TPM_RC_SUCCESS) {
16934 return rc;
16935 }
16936 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16937 handle_section_bytes + authorization_size_bytes +
16938 authorization_section_bytes + parameter_section_bytes;
16939 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16940 VLOG(2) << "Command: "
16941 << base::HexEncode(serialized_command->data(),
16942 serialized_command->size());
16943 return TPM_RC_SUCCESS;
16944 }
16945
ParseResponse_CertifyCreation(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16946 TPM_RC Tpm::ParseResponse_CertifyCreation(
16947 const std::string& response,
16948 TPM2B_ATTEST* certify_info,
16949 TPMT_SIGNATURE* signature,
16950 AuthorizationDelegate* authorization_delegate) {
16951 VLOG(3) << __func__;
16952 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16953 TPM_RC rc = TPM_RC_SUCCESS;
16954 std::string buffer(response);
16955 TPM_ST tag;
16956 std::string tag_bytes;
16957 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16958 if (rc != TPM_RC_SUCCESS) {
16959 return rc;
16960 }
16961 UINT32 response_size;
16962 std::string response_size_bytes;
16963 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16964 if (rc != TPM_RC_SUCCESS) {
16965 return rc;
16966 }
16967 TPM_RC response_code;
16968 std::string response_code_bytes;
16969 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16970 if (rc != TPM_RC_SUCCESS) {
16971 return rc;
16972 }
16973 if (response_size != response.size()) {
16974 return TPM_RC_SIZE;
16975 }
16976 if (response_code != TPM_RC_SUCCESS) {
16977 return response_code;
16978 }
16979 TPM_CC command_code = TPM_CC_CertifyCreation;
16980 std::string command_code_bytes;
16981 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16982 if (rc != TPM_RC_SUCCESS) {
16983 return rc;
16984 }
16985 std::string authorization_section_bytes;
16986 if (tag == TPM_ST_SESSIONS) {
16987 UINT32 parameter_section_size = buffer.size();
16988 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
16989 if (rc != TPM_RC_SUCCESS) {
16990 return rc;
16991 }
16992 if (parameter_section_size > buffer.size()) {
16993 return TPM_RC_INSUFFICIENT;
16994 }
16995 authorization_section_bytes = buffer.substr(parameter_section_size);
16996 // Keep the parameter section in |buffer|.
16997 buffer.erase(parameter_section_size);
16998 }
16999 std::unique_ptr<crypto::SecureHash> hash(
17000 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17001 hash->Update(response_code_bytes.data(), response_code_bytes.size());
17002 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17003 hash->Update(buffer.data(), buffer.size());
17004 std::string response_hash(32, 0);
17005 hash->Finish(std::data(response_hash), response_hash.size());
17006 if (tag == TPM_ST_SESSIONS) {
17007 if (!authorization_delegate)
17008 return TRUNKS_RC_AUTHORIZATION_FAILED;
17009 if (!authorization_delegate->CheckResponseAuthorization(
17010 response_hash, authorization_section_bytes)) {
17011 return TRUNKS_RC_AUTHORIZATION_FAILED;
17012 }
17013 }
17014 if (tag == TPM_ST_SESSIONS) {
17015 if (!authorization_delegate)
17016 return TRUNKS_RC_AUTHORIZATION_FAILED;
17017
17018 // Parse the encrypted parameter size.
17019 UINT16 size;
17020 std::string size_buffer = buffer.substr(0, 2);
17021 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17022 return result;
17023 }
17024 if (buffer.size() < 2 + size) {
17025 return TPM_RC_INSUFFICIENT;
17026 }
17027
17028 // Decrypt just the parameter data, not the size.
17029 std::string decrypted_data = buffer.substr(2, size);
17030 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17031 return TRUNKS_RC_ENCRYPTION_FAILED;
17032 }
17033 buffer.replace(2, size, decrypted_data);
17034 }
17035 std::string certify_info_bytes;
17036 rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
17037 if (rc != TPM_RC_SUCCESS) {
17038 return rc;
17039 }
17040 std::string signature_bytes;
17041 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17042 if (rc != TPM_RC_SUCCESS) {
17043 return rc;
17044 }
17045 return TPM_RC_SUCCESS;
17046 }
17047
CertifyCreationErrorCallback(Tpm::CertifyCreationResponse callback,TPM_RC response_code)17048 void CertifyCreationErrorCallback(Tpm::CertifyCreationResponse callback,
17049 TPM_RC response_code) {
17050 VLOG(1) << __func__;
17051 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17052 }
17053
CertifyCreationResponseParser(Tpm::CertifyCreationResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17054 void CertifyCreationResponseParser(
17055 Tpm::CertifyCreationResponse callback,
17056 AuthorizationDelegate* authorization_delegate,
17057 const std::string& response) {
17058 VLOG(1) << __func__;
17059 TPM2B_ATTEST certify_info;
17060 TPMT_SIGNATURE signature;
17061 TPM_RC rc = Tpm::ParseResponse_CertifyCreation(
17062 response, &certify_info, &signature, authorization_delegate);
17063 if (rc != TPM_RC_SUCCESS) {
17064 base::OnceCallback<void(TPM_RC)> error_reporter =
17065 base::BindOnce(CertifyCreationErrorCallback, std::move(callback));
17066 std::move(error_reporter).Run(rc);
17067 return;
17068 }
17069 std::move(callback).Run(rc, certify_info, signature);
17070 }
17071
CertifyCreation(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPM2B_DATA & qualifying_data,const TPM2B_DIGEST & creation_hash,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_CREATION & creation_ticket,AuthorizationDelegate * authorization_delegate,CertifyCreationResponse callback)17072 void Tpm::CertifyCreation(const TPMI_DH_OBJECT& sign_handle,
17073 const std::string& sign_handle_name,
17074 const TPMI_DH_OBJECT& object_handle,
17075 const std::string& object_handle_name,
17076 const TPM2B_DATA& qualifying_data,
17077 const TPM2B_DIGEST& creation_hash,
17078 const TPMT_SIG_SCHEME& in_scheme,
17079 const TPMT_TK_CREATION& creation_ticket,
17080 AuthorizationDelegate* authorization_delegate,
17081 CertifyCreationResponse callback) {
17082 VLOG(1) << __func__;
17083 std::string command;
17084 TPM_RC rc = SerializeCommand_CertifyCreation(
17085 sign_handle, sign_handle_name, object_handle, object_handle_name,
17086 qualifying_data, creation_hash, in_scheme, creation_ticket, &command,
17087 authorization_delegate);
17088 if (rc != TPM_RC_SUCCESS) {
17089 base::OnceCallback<void(TPM_RC)> error_reporter =
17090 base::BindOnce(CertifyCreationErrorCallback, std::move(callback));
17091 std::move(error_reporter).Run(rc);
17092 return;
17093 }
17094 base::OnceCallback<void(const std::string&)> parser =
17095 base::BindOnce(CertifyCreationResponseParser, std::move(callback),
17096 authorization_delegate);
17097 transceiver_->SendCommand(command, std::move(parser));
17098 }
17099
CertifyCreationSync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPM2B_DATA & qualifying_data,const TPM2B_DIGEST & creation_hash,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_CREATION & creation_ticket,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17100 TPM_RC Tpm::CertifyCreationSync(const TPMI_DH_OBJECT& sign_handle,
17101 const std::string& sign_handle_name,
17102 const TPMI_DH_OBJECT& object_handle,
17103 const std::string& object_handle_name,
17104 const TPM2B_DATA& qualifying_data,
17105 const TPM2B_DIGEST& creation_hash,
17106 const TPMT_SIG_SCHEME& in_scheme,
17107 const TPMT_TK_CREATION& creation_ticket,
17108 TPM2B_ATTEST* certify_info,
17109 TPMT_SIGNATURE* signature,
17110 AuthorizationDelegate* authorization_delegate) {
17111 VLOG(1) << __func__;
17112 std::string command;
17113 TPM_RC rc = SerializeCommand_CertifyCreation(
17114 sign_handle, sign_handle_name, object_handle, object_handle_name,
17115 qualifying_data, creation_hash, in_scheme, creation_ticket, &command,
17116 authorization_delegate);
17117 if (rc != TPM_RC_SUCCESS) {
17118 return rc;
17119 }
17120 std::string response = transceiver_->SendCommandAndWait(command);
17121 rc = ParseResponse_CertifyCreation(response, certify_info, signature,
17122 authorization_delegate);
17123 return rc;
17124 }
17125
SerializeCommand_Quote(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const TPML_PCR_SELECTION & pcrselect,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17126 TPM_RC Tpm::SerializeCommand_Quote(
17127 const TPMI_DH_OBJECT& sign_handle,
17128 const std::string& sign_handle_name,
17129 const TPM2B_DATA& qualifying_data,
17130 const TPMT_SIG_SCHEME& in_scheme,
17131 const TPML_PCR_SELECTION& pcrselect,
17132 std::string* serialized_command,
17133 AuthorizationDelegate* authorization_delegate) {
17134 VLOG(3) << __func__;
17135 TPM_RC rc = TPM_RC_SUCCESS;
17136 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17137 UINT32 command_size = 10; // Header size.
17138 std::string handle_section_bytes;
17139 std::string parameter_section_bytes;
17140 TPM_CC command_code = TPM_CC_Quote;
17141 bool is_command_parameter_encryption_possible = true;
17142 bool is_response_parameter_encryption_possible = true;
17143 std::string command_code_bytes;
17144 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17145 if (rc != TPM_RC_SUCCESS) {
17146 return rc;
17147 }
17148 std::string sign_handle_bytes;
17149 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17150 if (rc != TPM_RC_SUCCESS) {
17151 return rc;
17152 }
17153 std::string qualifying_data_bytes;
17154 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17155 if (rc != TPM_RC_SUCCESS) {
17156 return rc;
17157 }
17158 std::string in_scheme_bytes;
17159 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17160 if (rc != TPM_RC_SUCCESS) {
17161 return rc;
17162 }
17163 std::string pcrselect_bytes;
17164 rc = Serialize_TPML_PCR_SELECTION(pcrselect, &pcrselect_bytes);
17165 if (rc != TPM_RC_SUCCESS) {
17166 return rc;
17167 }
17168 if (authorization_delegate) {
17169 // Encrypt just the parameter data, not the size.
17170 std::string tmp = qualifying_data_bytes.substr(2);
17171 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17172 return TRUNKS_RC_ENCRYPTION_FAILED;
17173 }
17174 qualifying_data_bytes.replace(2, std::string::npos, tmp);
17175 }
17176 std::unique_ptr<crypto::SecureHash> hash(
17177 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17178 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17179 hash->Update(sign_handle_name.data(), sign_handle_name.size());
17180 handle_section_bytes += sign_handle_bytes;
17181 command_size += sign_handle_bytes.size();
17182 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17183 parameter_section_bytes += qualifying_data_bytes;
17184 command_size += qualifying_data_bytes.size();
17185 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17186 parameter_section_bytes += in_scheme_bytes;
17187 command_size += in_scheme_bytes.size();
17188 hash->Update(pcrselect_bytes.data(), pcrselect_bytes.size());
17189 parameter_section_bytes += pcrselect_bytes;
17190 command_size += pcrselect_bytes.size();
17191 std::string command_hash(32, 0);
17192 hash->Finish(std::data(command_hash), command_hash.size());
17193 std::string authorization_section_bytes;
17194 std::string authorization_size_bytes;
17195 if (authorization_delegate) {
17196 if (!authorization_delegate->GetCommandAuthorization(
17197 command_hash, is_command_parameter_encryption_possible,
17198 is_response_parameter_encryption_possible,
17199 &authorization_section_bytes)) {
17200 return TRUNKS_RC_AUTHORIZATION_FAILED;
17201 }
17202 if (!authorization_section_bytes.empty()) {
17203 tag = TPM_ST_SESSIONS;
17204 std::string tmp;
17205 rc = Serialize_UINT32(authorization_section_bytes.size(),
17206 &authorization_size_bytes);
17207 if (rc != TPM_RC_SUCCESS) {
17208 return rc;
17209 }
17210 command_size +=
17211 authorization_size_bytes.size() + authorization_section_bytes.size();
17212 }
17213 }
17214 std::string tag_bytes;
17215 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17216 if (rc != TPM_RC_SUCCESS) {
17217 return rc;
17218 }
17219 std::string command_size_bytes;
17220 rc = Serialize_UINT32(command_size, &command_size_bytes);
17221 if (rc != TPM_RC_SUCCESS) {
17222 return rc;
17223 }
17224 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17225 handle_section_bytes + authorization_size_bytes +
17226 authorization_section_bytes + parameter_section_bytes;
17227 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17228 VLOG(2) << "Command: "
17229 << base::HexEncode(serialized_command->data(),
17230 serialized_command->size());
17231 return TPM_RC_SUCCESS;
17232 }
17233
ParseResponse_Quote(const std::string & response,TPM2B_ATTEST * quoted,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17234 TPM_RC Tpm::ParseResponse_Quote(const std::string& response,
17235 TPM2B_ATTEST* quoted,
17236 TPMT_SIGNATURE* signature,
17237 AuthorizationDelegate* authorization_delegate) {
17238 VLOG(3) << __func__;
17239 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17240 TPM_RC rc = TPM_RC_SUCCESS;
17241 std::string buffer(response);
17242 TPM_ST tag;
17243 std::string tag_bytes;
17244 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17245 if (rc != TPM_RC_SUCCESS) {
17246 return rc;
17247 }
17248 UINT32 response_size;
17249 std::string response_size_bytes;
17250 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17251 if (rc != TPM_RC_SUCCESS) {
17252 return rc;
17253 }
17254 TPM_RC response_code;
17255 std::string response_code_bytes;
17256 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17257 if (rc != TPM_RC_SUCCESS) {
17258 return rc;
17259 }
17260 if (response_size != response.size()) {
17261 return TPM_RC_SIZE;
17262 }
17263 if (response_code != TPM_RC_SUCCESS) {
17264 return response_code;
17265 }
17266 TPM_CC command_code = TPM_CC_Quote;
17267 std::string command_code_bytes;
17268 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17269 if (rc != TPM_RC_SUCCESS) {
17270 return rc;
17271 }
17272 std::string authorization_section_bytes;
17273 if (tag == TPM_ST_SESSIONS) {
17274 UINT32 parameter_section_size = buffer.size();
17275 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
17276 if (rc != TPM_RC_SUCCESS) {
17277 return rc;
17278 }
17279 if (parameter_section_size > buffer.size()) {
17280 return TPM_RC_INSUFFICIENT;
17281 }
17282 authorization_section_bytes = buffer.substr(parameter_section_size);
17283 // Keep the parameter section in |buffer|.
17284 buffer.erase(parameter_section_size);
17285 }
17286 std::unique_ptr<crypto::SecureHash> hash(
17287 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17288 hash->Update(response_code_bytes.data(), response_code_bytes.size());
17289 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17290 hash->Update(buffer.data(), buffer.size());
17291 std::string response_hash(32, 0);
17292 hash->Finish(std::data(response_hash), response_hash.size());
17293 if (tag == TPM_ST_SESSIONS) {
17294 if (!authorization_delegate)
17295 return TRUNKS_RC_AUTHORIZATION_FAILED;
17296 if (!authorization_delegate->CheckResponseAuthorization(
17297 response_hash, authorization_section_bytes)) {
17298 return TRUNKS_RC_AUTHORIZATION_FAILED;
17299 }
17300 }
17301 if (tag == TPM_ST_SESSIONS) {
17302 if (!authorization_delegate)
17303 return TRUNKS_RC_AUTHORIZATION_FAILED;
17304
17305 // Parse the encrypted parameter size.
17306 UINT16 size;
17307 std::string size_buffer = buffer.substr(0, 2);
17308 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17309 return result;
17310 }
17311 if (buffer.size() < 2 + size) {
17312 return TPM_RC_INSUFFICIENT;
17313 }
17314
17315 // Decrypt just the parameter data, not the size.
17316 std::string decrypted_data = buffer.substr(2, size);
17317 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17318 return TRUNKS_RC_ENCRYPTION_FAILED;
17319 }
17320 buffer.replace(2, size, decrypted_data);
17321 }
17322 std::string quoted_bytes;
17323 rc = Parse_TPM2B_ATTEST(&buffer, quoted, "ed_bytes);
17324 if (rc != TPM_RC_SUCCESS) {
17325 return rc;
17326 }
17327 std::string signature_bytes;
17328 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17329 if (rc != TPM_RC_SUCCESS) {
17330 return rc;
17331 }
17332 return TPM_RC_SUCCESS;
17333 }
17334
QuoteErrorCallback(Tpm::QuoteResponse callback,TPM_RC response_code)17335 void QuoteErrorCallback(Tpm::QuoteResponse callback, TPM_RC response_code) {
17336 VLOG(1) << __func__;
17337 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17338 }
17339
QuoteResponseParser(Tpm::QuoteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17340 void QuoteResponseParser(Tpm::QuoteResponse callback,
17341 AuthorizationDelegate* authorization_delegate,
17342 const std::string& response) {
17343 VLOG(1) << __func__;
17344 TPM2B_ATTEST quoted;
17345 TPMT_SIGNATURE signature;
17346 TPM_RC rc = Tpm::ParseResponse_Quote(response, "ed, &signature,
17347 authorization_delegate);
17348 if (rc != TPM_RC_SUCCESS) {
17349 base::OnceCallback<void(TPM_RC)> error_reporter =
17350 base::BindOnce(QuoteErrorCallback, std::move(callback));
17351 std::move(error_reporter).Run(rc);
17352 return;
17353 }
17354 std::move(callback).Run(rc, quoted, signature);
17355 }
17356
Quote(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const TPML_PCR_SELECTION & pcrselect,AuthorizationDelegate * authorization_delegate,QuoteResponse callback)17357 void Tpm::Quote(const TPMI_DH_OBJECT& sign_handle,
17358 const std::string& sign_handle_name,
17359 const TPM2B_DATA& qualifying_data,
17360 const TPMT_SIG_SCHEME& in_scheme,
17361 const TPML_PCR_SELECTION& pcrselect,
17362 AuthorizationDelegate* authorization_delegate,
17363 QuoteResponse callback) {
17364 VLOG(1) << __func__;
17365 std::string command;
17366 TPM_RC rc = SerializeCommand_Quote(sign_handle, sign_handle_name,
17367 qualifying_data, in_scheme, pcrselect,
17368 &command, authorization_delegate);
17369 if (rc != TPM_RC_SUCCESS) {
17370 base::OnceCallback<void(TPM_RC)> error_reporter =
17371 base::BindOnce(QuoteErrorCallback, std::move(callback));
17372 std::move(error_reporter).Run(rc);
17373 return;
17374 }
17375 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
17376 QuoteResponseParser, std::move(callback), authorization_delegate);
17377 transceiver_->SendCommand(command, std::move(parser));
17378 }
17379
QuoteSync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const TPML_PCR_SELECTION & pcrselect,TPM2B_ATTEST * quoted,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17380 TPM_RC Tpm::QuoteSync(const TPMI_DH_OBJECT& sign_handle,
17381 const std::string& sign_handle_name,
17382 const TPM2B_DATA& qualifying_data,
17383 const TPMT_SIG_SCHEME& in_scheme,
17384 const TPML_PCR_SELECTION& pcrselect,
17385 TPM2B_ATTEST* quoted,
17386 TPMT_SIGNATURE* signature,
17387 AuthorizationDelegate* authorization_delegate) {
17388 VLOG(1) << __func__;
17389 std::string command;
17390 TPM_RC rc = SerializeCommand_Quote(sign_handle, sign_handle_name,
17391 qualifying_data, in_scheme, pcrselect,
17392 &command, authorization_delegate);
17393 if (rc != TPM_RC_SUCCESS) {
17394 return rc;
17395 }
17396 std::string response = transceiver_->SendCommandAndWait(command);
17397 rc = ParseResponse_Quote(response, quoted, signature, authorization_delegate);
17398 return rc;
17399 }
17400
SerializeCommand_GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_SH_HMAC & session_handle,const std::string & session_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17401 TPM_RC Tpm::SerializeCommand_GetSessionAuditDigest(
17402 const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17403 const std::string& privacy_admin_handle_name,
17404 const TPMI_DH_OBJECT& sign_handle,
17405 const std::string& sign_handle_name,
17406 const TPMI_SH_HMAC& session_handle,
17407 const std::string& session_handle_name,
17408 const TPM2B_DATA& qualifying_data,
17409 const TPMT_SIG_SCHEME& in_scheme,
17410 std::string* serialized_command,
17411 AuthorizationDelegate* authorization_delegate) {
17412 VLOG(3) << __func__;
17413 TPM_RC rc = TPM_RC_SUCCESS;
17414 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17415 UINT32 command_size = 10; // Header size.
17416 std::string handle_section_bytes;
17417 std::string parameter_section_bytes;
17418 TPM_CC command_code = TPM_CC_GetSessionAuditDigest;
17419 bool is_command_parameter_encryption_possible = true;
17420 bool is_response_parameter_encryption_possible = true;
17421 std::string command_code_bytes;
17422 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17423 if (rc != TPM_RC_SUCCESS) {
17424 return rc;
17425 }
17426 std::string privacy_admin_handle_bytes;
17427 rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_admin_handle,
17428 &privacy_admin_handle_bytes);
17429 if (rc != TPM_RC_SUCCESS) {
17430 return rc;
17431 }
17432 std::string sign_handle_bytes;
17433 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17434 if (rc != TPM_RC_SUCCESS) {
17435 return rc;
17436 }
17437 std::string session_handle_bytes;
17438 rc = Serialize_TPMI_SH_HMAC(session_handle, &session_handle_bytes);
17439 if (rc != TPM_RC_SUCCESS) {
17440 return rc;
17441 }
17442 std::string qualifying_data_bytes;
17443 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17444 if (rc != TPM_RC_SUCCESS) {
17445 return rc;
17446 }
17447 std::string in_scheme_bytes;
17448 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17449 if (rc != TPM_RC_SUCCESS) {
17450 return rc;
17451 }
17452 if (authorization_delegate) {
17453 // Encrypt just the parameter data, not the size.
17454 std::string tmp = qualifying_data_bytes.substr(2);
17455 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17456 return TRUNKS_RC_ENCRYPTION_FAILED;
17457 }
17458 qualifying_data_bytes.replace(2, std::string::npos, tmp);
17459 }
17460 std::unique_ptr<crypto::SecureHash> hash(
17461 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17462 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17463 hash->Update(privacy_admin_handle_name.data(),
17464 privacy_admin_handle_name.size());
17465 handle_section_bytes += privacy_admin_handle_bytes;
17466 command_size += privacy_admin_handle_bytes.size();
17467 hash->Update(sign_handle_name.data(), sign_handle_name.size());
17468 handle_section_bytes += sign_handle_bytes;
17469 command_size += sign_handle_bytes.size();
17470 hash->Update(session_handle_name.data(), session_handle_name.size());
17471 handle_section_bytes += session_handle_bytes;
17472 command_size += session_handle_bytes.size();
17473 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17474 parameter_section_bytes += qualifying_data_bytes;
17475 command_size += qualifying_data_bytes.size();
17476 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17477 parameter_section_bytes += in_scheme_bytes;
17478 command_size += in_scheme_bytes.size();
17479 std::string command_hash(32, 0);
17480 hash->Finish(std::data(command_hash), command_hash.size());
17481 std::string authorization_section_bytes;
17482 std::string authorization_size_bytes;
17483 if (authorization_delegate) {
17484 if (!authorization_delegate->GetCommandAuthorization(
17485 command_hash, is_command_parameter_encryption_possible,
17486 is_response_parameter_encryption_possible,
17487 &authorization_section_bytes)) {
17488 return TRUNKS_RC_AUTHORIZATION_FAILED;
17489 }
17490 if (!authorization_section_bytes.empty()) {
17491 tag = TPM_ST_SESSIONS;
17492 std::string tmp;
17493 rc = Serialize_UINT32(authorization_section_bytes.size(),
17494 &authorization_size_bytes);
17495 if (rc != TPM_RC_SUCCESS) {
17496 return rc;
17497 }
17498 command_size +=
17499 authorization_size_bytes.size() + authorization_section_bytes.size();
17500 }
17501 }
17502 std::string tag_bytes;
17503 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17504 if (rc != TPM_RC_SUCCESS) {
17505 return rc;
17506 }
17507 std::string command_size_bytes;
17508 rc = Serialize_UINT32(command_size, &command_size_bytes);
17509 if (rc != TPM_RC_SUCCESS) {
17510 return rc;
17511 }
17512 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17513 handle_section_bytes + authorization_size_bytes +
17514 authorization_section_bytes + parameter_section_bytes;
17515 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17516 VLOG(2) << "Command: "
17517 << base::HexEncode(serialized_command->data(),
17518 serialized_command->size());
17519 return TPM_RC_SUCCESS;
17520 }
17521
ParseResponse_GetSessionAuditDigest(const std::string & response,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17522 TPM_RC Tpm::ParseResponse_GetSessionAuditDigest(
17523 const std::string& response,
17524 TPM2B_ATTEST* audit_info,
17525 TPMT_SIGNATURE* signature,
17526 AuthorizationDelegate* authorization_delegate) {
17527 VLOG(3) << __func__;
17528 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17529 TPM_RC rc = TPM_RC_SUCCESS;
17530 std::string buffer(response);
17531 TPM_ST tag;
17532 std::string tag_bytes;
17533 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17534 if (rc != TPM_RC_SUCCESS) {
17535 return rc;
17536 }
17537 UINT32 response_size;
17538 std::string response_size_bytes;
17539 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17540 if (rc != TPM_RC_SUCCESS) {
17541 return rc;
17542 }
17543 TPM_RC response_code;
17544 std::string response_code_bytes;
17545 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17546 if (rc != TPM_RC_SUCCESS) {
17547 return rc;
17548 }
17549 if (response_size != response.size()) {
17550 return TPM_RC_SIZE;
17551 }
17552 if (response_code != TPM_RC_SUCCESS) {
17553 return response_code;
17554 }
17555 TPM_CC command_code = TPM_CC_GetSessionAuditDigest;
17556 std::string command_code_bytes;
17557 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17558 if (rc != TPM_RC_SUCCESS) {
17559 return rc;
17560 }
17561 std::string authorization_section_bytes;
17562 if (tag == TPM_ST_SESSIONS) {
17563 UINT32 parameter_section_size = buffer.size();
17564 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
17565 if (rc != TPM_RC_SUCCESS) {
17566 return rc;
17567 }
17568 if (parameter_section_size > buffer.size()) {
17569 return TPM_RC_INSUFFICIENT;
17570 }
17571 authorization_section_bytes = buffer.substr(parameter_section_size);
17572 // Keep the parameter section in |buffer|.
17573 buffer.erase(parameter_section_size);
17574 }
17575 std::unique_ptr<crypto::SecureHash> hash(
17576 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17577 hash->Update(response_code_bytes.data(), response_code_bytes.size());
17578 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17579 hash->Update(buffer.data(), buffer.size());
17580 std::string response_hash(32, 0);
17581 hash->Finish(std::data(response_hash), response_hash.size());
17582 if (tag == TPM_ST_SESSIONS) {
17583 if (!authorization_delegate)
17584 return TRUNKS_RC_AUTHORIZATION_FAILED;
17585 if (!authorization_delegate->CheckResponseAuthorization(
17586 response_hash, authorization_section_bytes)) {
17587 return TRUNKS_RC_AUTHORIZATION_FAILED;
17588 }
17589 }
17590 if (tag == TPM_ST_SESSIONS) {
17591 if (!authorization_delegate)
17592 return TRUNKS_RC_AUTHORIZATION_FAILED;
17593
17594 // Parse the encrypted parameter size.
17595 UINT16 size;
17596 std::string size_buffer = buffer.substr(0, 2);
17597 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17598 return result;
17599 }
17600 if (buffer.size() < 2 + size) {
17601 return TPM_RC_INSUFFICIENT;
17602 }
17603
17604 // Decrypt just the parameter data, not the size.
17605 std::string decrypted_data = buffer.substr(2, size);
17606 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17607 return TRUNKS_RC_ENCRYPTION_FAILED;
17608 }
17609 buffer.replace(2, size, decrypted_data);
17610 }
17611 std::string audit_info_bytes;
17612 rc = Parse_TPM2B_ATTEST(&buffer, audit_info, &audit_info_bytes);
17613 if (rc != TPM_RC_SUCCESS) {
17614 return rc;
17615 }
17616 std::string signature_bytes;
17617 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17618 if (rc != TPM_RC_SUCCESS) {
17619 return rc;
17620 }
17621 return TPM_RC_SUCCESS;
17622 }
17623
GetSessionAuditDigestErrorCallback(Tpm::GetSessionAuditDigestResponse callback,TPM_RC response_code)17624 void GetSessionAuditDigestErrorCallback(
17625 Tpm::GetSessionAuditDigestResponse callback, TPM_RC response_code) {
17626 VLOG(1) << __func__;
17627 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17628 }
17629
GetSessionAuditDigestResponseParser(Tpm::GetSessionAuditDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17630 void GetSessionAuditDigestResponseParser(
17631 Tpm::GetSessionAuditDigestResponse callback,
17632 AuthorizationDelegate* authorization_delegate,
17633 const std::string& response) {
17634 VLOG(1) << __func__;
17635 TPM2B_ATTEST audit_info;
17636 TPMT_SIGNATURE signature;
17637 TPM_RC rc = Tpm::ParseResponse_GetSessionAuditDigest(
17638 response, &audit_info, &signature, authorization_delegate);
17639 if (rc != TPM_RC_SUCCESS) {
17640 base::OnceCallback<void(TPM_RC)> error_reporter =
17641 base::BindOnce(GetSessionAuditDigestErrorCallback, std::move(callback));
17642 std::move(error_reporter).Run(rc);
17643 return;
17644 }
17645 std::move(callback).Run(rc, audit_info, signature);
17646 }
17647
GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_SH_HMAC & session_handle,const std::string & session_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,GetSessionAuditDigestResponse callback)17648 void Tpm::GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17649 const std::string& privacy_admin_handle_name,
17650 const TPMI_DH_OBJECT& sign_handle,
17651 const std::string& sign_handle_name,
17652 const TPMI_SH_HMAC& session_handle,
17653 const std::string& session_handle_name,
17654 const TPM2B_DATA& qualifying_data,
17655 const TPMT_SIG_SCHEME& in_scheme,
17656 AuthorizationDelegate* authorization_delegate,
17657 GetSessionAuditDigestResponse callback) {
17658 VLOG(1) << __func__;
17659 std::string command;
17660 TPM_RC rc = SerializeCommand_GetSessionAuditDigest(
17661 privacy_admin_handle, privacy_admin_handle_name, sign_handle,
17662 sign_handle_name, session_handle, session_handle_name, qualifying_data,
17663 in_scheme, &command, authorization_delegate);
17664 if (rc != TPM_RC_SUCCESS) {
17665 base::OnceCallback<void(TPM_RC)> error_reporter =
17666 base::BindOnce(GetSessionAuditDigestErrorCallback, std::move(callback));
17667 std::move(error_reporter).Run(rc);
17668 return;
17669 }
17670 base::OnceCallback<void(const std::string&)> parser =
17671 base::BindOnce(GetSessionAuditDigestResponseParser, std::move(callback),
17672 authorization_delegate);
17673 transceiver_->SendCommand(command, std::move(parser));
17674 }
17675
GetSessionAuditDigestSync(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_SH_HMAC & session_handle,const std::string & session_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17676 TPM_RC Tpm::GetSessionAuditDigestSync(
17677 const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17678 const std::string& privacy_admin_handle_name,
17679 const TPMI_DH_OBJECT& sign_handle,
17680 const std::string& sign_handle_name,
17681 const TPMI_SH_HMAC& session_handle,
17682 const std::string& session_handle_name,
17683 const TPM2B_DATA& qualifying_data,
17684 const TPMT_SIG_SCHEME& in_scheme,
17685 TPM2B_ATTEST* audit_info,
17686 TPMT_SIGNATURE* signature,
17687 AuthorizationDelegate* authorization_delegate) {
17688 VLOG(1) << __func__;
17689 std::string command;
17690 TPM_RC rc = SerializeCommand_GetSessionAuditDigest(
17691 privacy_admin_handle, privacy_admin_handle_name, sign_handle,
17692 sign_handle_name, session_handle, session_handle_name, qualifying_data,
17693 in_scheme, &command, authorization_delegate);
17694 if (rc != TPM_RC_SUCCESS) {
17695 return rc;
17696 }
17697 std::string response = transceiver_->SendCommandAndWait(command);
17698 rc = ParseResponse_GetSessionAuditDigest(response, audit_info, signature,
17699 authorization_delegate);
17700 return rc;
17701 }
17702
SerializeCommand_GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_handle,const std::string & privacy_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17703 TPM_RC Tpm::SerializeCommand_GetCommandAuditDigest(
17704 const TPMI_RH_ENDORSEMENT& privacy_handle,
17705 const std::string& privacy_handle_name,
17706 const TPMI_DH_OBJECT& sign_handle,
17707 const std::string& sign_handle_name,
17708 const TPM2B_DATA& qualifying_data,
17709 const TPMT_SIG_SCHEME& in_scheme,
17710 std::string* serialized_command,
17711 AuthorizationDelegate* authorization_delegate) {
17712 VLOG(3) << __func__;
17713 TPM_RC rc = TPM_RC_SUCCESS;
17714 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17715 UINT32 command_size = 10; // Header size.
17716 std::string handle_section_bytes;
17717 std::string parameter_section_bytes;
17718 TPM_CC command_code = TPM_CC_GetCommandAuditDigest;
17719 bool is_command_parameter_encryption_possible = true;
17720 bool is_response_parameter_encryption_possible = true;
17721 std::string command_code_bytes;
17722 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17723 if (rc != TPM_RC_SUCCESS) {
17724 return rc;
17725 }
17726 std::string privacy_handle_bytes;
17727 rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_handle, &privacy_handle_bytes);
17728 if (rc != TPM_RC_SUCCESS) {
17729 return rc;
17730 }
17731 std::string sign_handle_bytes;
17732 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17733 if (rc != TPM_RC_SUCCESS) {
17734 return rc;
17735 }
17736 std::string qualifying_data_bytes;
17737 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17738 if (rc != TPM_RC_SUCCESS) {
17739 return rc;
17740 }
17741 std::string in_scheme_bytes;
17742 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17743 if (rc != TPM_RC_SUCCESS) {
17744 return rc;
17745 }
17746 if (authorization_delegate) {
17747 // Encrypt just the parameter data, not the size.
17748 std::string tmp = qualifying_data_bytes.substr(2);
17749 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17750 return TRUNKS_RC_ENCRYPTION_FAILED;
17751 }
17752 qualifying_data_bytes.replace(2, std::string::npos, tmp);
17753 }
17754 std::unique_ptr<crypto::SecureHash> hash(
17755 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17756 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17757 hash->Update(privacy_handle_name.data(), privacy_handle_name.size());
17758 handle_section_bytes += privacy_handle_bytes;
17759 command_size += privacy_handle_bytes.size();
17760 hash->Update(sign_handle_name.data(), sign_handle_name.size());
17761 handle_section_bytes += sign_handle_bytes;
17762 command_size += sign_handle_bytes.size();
17763 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17764 parameter_section_bytes += qualifying_data_bytes;
17765 command_size += qualifying_data_bytes.size();
17766 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17767 parameter_section_bytes += in_scheme_bytes;
17768 command_size += in_scheme_bytes.size();
17769 std::string command_hash(32, 0);
17770 hash->Finish(std::data(command_hash), command_hash.size());
17771 std::string authorization_section_bytes;
17772 std::string authorization_size_bytes;
17773 if (authorization_delegate) {
17774 if (!authorization_delegate->GetCommandAuthorization(
17775 command_hash, is_command_parameter_encryption_possible,
17776 is_response_parameter_encryption_possible,
17777 &authorization_section_bytes)) {
17778 return TRUNKS_RC_AUTHORIZATION_FAILED;
17779 }
17780 if (!authorization_section_bytes.empty()) {
17781 tag = TPM_ST_SESSIONS;
17782 std::string tmp;
17783 rc = Serialize_UINT32(authorization_section_bytes.size(),
17784 &authorization_size_bytes);
17785 if (rc != TPM_RC_SUCCESS) {
17786 return rc;
17787 }
17788 command_size +=
17789 authorization_size_bytes.size() + authorization_section_bytes.size();
17790 }
17791 }
17792 std::string tag_bytes;
17793 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17794 if (rc != TPM_RC_SUCCESS) {
17795 return rc;
17796 }
17797 std::string command_size_bytes;
17798 rc = Serialize_UINT32(command_size, &command_size_bytes);
17799 if (rc != TPM_RC_SUCCESS) {
17800 return rc;
17801 }
17802 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17803 handle_section_bytes + authorization_size_bytes +
17804 authorization_section_bytes + parameter_section_bytes;
17805 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17806 VLOG(2) << "Command: "
17807 << base::HexEncode(serialized_command->data(),
17808 serialized_command->size());
17809 return TPM_RC_SUCCESS;
17810 }
17811
ParseResponse_GetCommandAuditDigest(const std::string & response,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17812 TPM_RC Tpm::ParseResponse_GetCommandAuditDigest(
17813 const std::string& response,
17814 TPM2B_ATTEST* audit_info,
17815 TPMT_SIGNATURE* signature,
17816 AuthorizationDelegate* authorization_delegate) {
17817 VLOG(3) << __func__;
17818 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17819 TPM_RC rc = TPM_RC_SUCCESS;
17820 std::string buffer(response);
17821 TPM_ST tag;
17822 std::string tag_bytes;
17823 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17824 if (rc != TPM_RC_SUCCESS) {
17825 return rc;
17826 }
17827 UINT32 response_size;
17828 std::string response_size_bytes;
17829 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17830 if (rc != TPM_RC_SUCCESS) {
17831 return rc;
17832 }
17833 TPM_RC response_code;
17834 std::string response_code_bytes;
17835 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17836 if (rc != TPM_RC_SUCCESS) {
17837 return rc;
17838 }
17839 if (response_size != response.size()) {
17840 return TPM_RC_SIZE;
17841 }
17842 if (response_code != TPM_RC_SUCCESS) {
17843 return response_code;
17844 }
17845 TPM_CC command_code = TPM_CC_GetCommandAuditDigest;
17846 std::string command_code_bytes;
17847 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17848 if (rc != TPM_RC_SUCCESS) {
17849 return rc;
17850 }
17851 std::string authorization_section_bytes;
17852 if (tag == TPM_ST_SESSIONS) {
17853 UINT32 parameter_section_size = buffer.size();
17854 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
17855 if (rc != TPM_RC_SUCCESS) {
17856 return rc;
17857 }
17858 if (parameter_section_size > buffer.size()) {
17859 return TPM_RC_INSUFFICIENT;
17860 }
17861 authorization_section_bytes = buffer.substr(parameter_section_size);
17862 // Keep the parameter section in |buffer|.
17863 buffer.erase(parameter_section_size);
17864 }
17865 std::unique_ptr<crypto::SecureHash> hash(
17866 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17867 hash->Update(response_code_bytes.data(), response_code_bytes.size());
17868 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17869 hash->Update(buffer.data(), buffer.size());
17870 std::string response_hash(32, 0);
17871 hash->Finish(std::data(response_hash), response_hash.size());
17872 if (tag == TPM_ST_SESSIONS) {
17873 if (!authorization_delegate)
17874 return TRUNKS_RC_AUTHORIZATION_FAILED;
17875 if (!authorization_delegate->CheckResponseAuthorization(
17876 response_hash, authorization_section_bytes)) {
17877 return TRUNKS_RC_AUTHORIZATION_FAILED;
17878 }
17879 }
17880 if (tag == TPM_ST_SESSIONS) {
17881 if (!authorization_delegate)
17882 return TRUNKS_RC_AUTHORIZATION_FAILED;
17883
17884 // Parse the encrypted parameter size.
17885 UINT16 size;
17886 std::string size_buffer = buffer.substr(0, 2);
17887 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17888 return result;
17889 }
17890 if (buffer.size() < 2 + size) {
17891 return TPM_RC_INSUFFICIENT;
17892 }
17893
17894 // Decrypt just the parameter data, not the size.
17895 std::string decrypted_data = buffer.substr(2, size);
17896 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17897 return TRUNKS_RC_ENCRYPTION_FAILED;
17898 }
17899 buffer.replace(2, size, decrypted_data);
17900 }
17901 std::string audit_info_bytes;
17902 rc = Parse_TPM2B_ATTEST(&buffer, audit_info, &audit_info_bytes);
17903 if (rc != TPM_RC_SUCCESS) {
17904 return rc;
17905 }
17906 std::string signature_bytes;
17907 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17908 if (rc != TPM_RC_SUCCESS) {
17909 return rc;
17910 }
17911 return TPM_RC_SUCCESS;
17912 }
17913
GetCommandAuditDigestErrorCallback(Tpm::GetCommandAuditDigestResponse callback,TPM_RC response_code)17914 void GetCommandAuditDigestErrorCallback(
17915 Tpm::GetCommandAuditDigestResponse callback, TPM_RC response_code) {
17916 VLOG(1) << __func__;
17917 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17918 }
17919
GetCommandAuditDigestResponseParser(Tpm::GetCommandAuditDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17920 void GetCommandAuditDigestResponseParser(
17921 Tpm::GetCommandAuditDigestResponse callback,
17922 AuthorizationDelegate* authorization_delegate,
17923 const std::string& response) {
17924 VLOG(1) << __func__;
17925 TPM2B_ATTEST audit_info;
17926 TPMT_SIGNATURE signature;
17927 TPM_RC rc = Tpm::ParseResponse_GetCommandAuditDigest(
17928 response, &audit_info, &signature, authorization_delegate);
17929 if (rc != TPM_RC_SUCCESS) {
17930 base::OnceCallback<void(TPM_RC)> error_reporter =
17931 base::BindOnce(GetCommandAuditDigestErrorCallback, std::move(callback));
17932 std::move(error_reporter).Run(rc);
17933 return;
17934 }
17935 std::move(callback).Run(rc, audit_info, signature);
17936 }
17937
GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_handle,const std::string & privacy_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,GetCommandAuditDigestResponse callback)17938 void Tpm::GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT& privacy_handle,
17939 const std::string& privacy_handle_name,
17940 const TPMI_DH_OBJECT& sign_handle,
17941 const std::string& sign_handle_name,
17942 const TPM2B_DATA& qualifying_data,
17943 const TPMT_SIG_SCHEME& in_scheme,
17944 AuthorizationDelegate* authorization_delegate,
17945 GetCommandAuditDigestResponse callback) {
17946 VLOG(1) << __func__;
17947 std::string command;
17948 TPM_RC rc = SerializeCommand_GetCommandAuditDigest(
17949 privacy_handle, privacy_handle_name, sign_handle, sign_handle_name,
17950 qualifying_data, in_scheme, &command, authorization_delegate);
17951 if (rc != TPM_RC_SUCCESS) {
17952 base::OnceCallback<void(TPM_RC)> error_reporter =
17953 base::BindOnce(GetCommandAuditDigestErrorCallback, std::move(callback));
17954 std::move(error_reporter).Run(rc);
17955 return;
17956 }
17957 base::OnceCallback<void(const std::string&)> parser =
17958 base::BindOnce(GetCommandAuditDigestResponseParser, std::move(callback),
17959 authorization_delegate);
17960 transceiver_->SendCommand(command, std::move(parser));
17961 }
17962
GetCommandAuditDigestSync(const TPMI_RH_ENDORSEMENT & privacy_handle,const std::string & privacy_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17963 TPM_RC Tpm::GetCommandAuditDigestSync(
17964 const TPMI_RH_ENDORSEMENT& privacy_handle,
17965 const std::string& privacy_handle_name,
17966 const TPMI_DH_OBJECT& sign_handle,
17967 const std::string& sign_handle_name,
17968 const TPM2B_DATA& qualifying_data,
17969 const TPMT_SIG_SCHEME& in_scheme,
17970 TPM2B_ATTEST* audit_info,
17971 TPMT_SIGNATURE* signature,
17972 AuthorizationDelegate* authorization_delegate) {
17973 VLOG(1) << __func__;
17974 std::string command;
17975 TPM_RC rc = SerializeCommand_GetCommandAuditDigest(
17976 privacy_handle, privacy_handle_name, sign_handle, sign_handle_name,
17977 qualifying_data, in_scheme, &command, authorization_delegate);
17978 if (rc != TPM_RC_SUCCESS) {
17979 return rc;
17980 }
17981 std::string response = transceiver_->SendCommandAndWait(command);
17982 rc = ParseResponse_GetCommandAuditDigest(response, audit_info, signature,
17983 authorization_delegate);
17984 return rc;
17985 }
17986
SerializeCommand_GetTime(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17987 TPM_RC Tpm::SerializeCommand_GetTime(
17988 const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17989 const std::string& privacy_admin_handle_name,
17990 const TPMI_DH_OBJECT& sign_handle,
17991 const std::string& sign_handle_name,
17992 const TPM2B_DATA& qualifying_data,
17993 const TPMT_SIG_SCHEME& in_scheme,
17994 std::string* serialized_command,
17995 AuthorizationDelegate* authorization_delegate) {
17996 VLOG(3) << __func__;
17997 TPM_RC rc = TPM_RC_SUCCESS;
17998 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17999 UINT32 command_size = 10; // Header size.
18000 std::string handle_section_bytes;
18001 std::string parameter_section_bytes;
18002 TPM_CC command_code = TPM_CC_GetTime;
18003 bool is_command_parameter_encryption_possible = true;
18004 bool is_response_parameter_encryption_possible = true;
18005 std::string command_code_bytes;
18006 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18007 if (rc != TPM_RC_SUCCESS) {
18008 return rc;
18009 }
18010 std::string privacy_admin_handle_bytes;
18011 rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_admin_handle,
18012 &privacy_admin_handle_bytes);
18013 if (rc != TPM_RC_SUCCESS) {
18014 return rc;
18015 }
18016 std::string sign_handle_bytes;
18017 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
18018 if (rc != TPM_RC_SUCCESS) {
18019 return rc;
18020 }
18021 std::string qualifying_data_bytes;
18022 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
18023 if (rc != TPM_RC_SUCCESS) {
18024 return rc;
18025 }
18026 std::string in_scheme_bytes;
18027 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
18028 if (rc != TPM_RC_SUCCESS) {
18029 return rc;
18030 }
18031 if (authorization_delegate) {
18032 // Encrypt just the parameter data, not the size.
18033 std::string tmp = qualifying_data_bytes.substr(2);
18034 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
18035 return TRUNKS_RC_ENCRYPTION_FAILED;
18036 }
18037 qualifying_data_bytes.replace(2, std::string::npos, tmp);
18038 }
18039 std::unique_ptr<crypto::SecureHash> hash(
18040 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18041 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18042 hash->Update(privacy_admin_handle_name.data(),
18043 privacy_admin_handle_name.size());
18044 handle_section_bytes += privacy_admin_handle_bytes;
18045 command_size += privacy_admin_handle_bytes.size();
18046 hash->Update(sign_handle_name.data(), sign_handle_name.size());
18047 handle_section_bytes += sign_handle_bytes;
18048 command_size += sign_handle_bytes.size();
18049 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
18050 parameter_section_bytes += qualifying_data_bytes;
18051 command_size += qualifying_data_bytes.size();
18052 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
18053 parameter_section_bytes += in_scheme_bytes;
18054 command_size += in_scheme_bytes.size();
18055 std::string command_hash(32, 0);
18056 hash->Finish(std::data(command_hash), command_hash.size());
18057 std::string authorization_section_bytes;
18058 std::string authorization_size_bytes;
18059 if (authorization_delegate) {
18060 if (!authorization_delegate->GetCommandAuthorization(
18061 command_hash, is_command_parameter_encryption_possible,
18062 is_response_parameter_encryption_possible,
18063 &authorization_section_bytes)) {
18064 return TRUNKS_RC_AUTHORIZATION_FAILED;
18065 }
18066 if (!authorization_section_bytes.empty()) {
18067 tag = TPM_ST_SESSIONS;
18068 std::string tmp;
18069 rc = Serialize_UINT32(authorization_section_bytes.size(),
18070 &authorization_size_bytes);
18071 if (rc != TPM_RC_SUCCESS) {
18072 return rc;
18073 }
18074 command_size +=
18075 authorization_size_bytes.size() + authorization_section_bytes.size();
18076 }
18077 }
18078 std::string tag_bytes;
18079 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18080 if (rc != TPM_RC_SUCCESS) {
18081 return rc;
18082 }
18083 std::string command_size_bytes;
18084 rc = Serialize_UINT32(command_size, &command_size_bytes);
18085 if (rc != TPM_RC_SUCCESS) {
18086 return rc;
18087 }
18088 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18089 handle_section_bytes + authorization_size_bytes +
18090 authorization_section_bytes + parameter_section_bytes;
18091 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18092 VLOG(2) << "Command: "
18093 << base::HexEncode(serialized_command->data(),
18094 serialized_command->size());
18095 return TPM_RC_SUCCESS;
18096 }
18097
ParseResponse_GetTime(const std::string & response,TPM2B_ATTEST * time_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)18098 TPM_RC Tpm::ParseResponse_GetTime(
18099 const std::string& response,
18100 TPM2B_ATTEST* time_info,
18101 TPMT_SIGNATURE* signature,
18102 AuthorizationDelegate* authorization_delegate) {
18103 VLOG(3) << __func__;
18104 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18105 TPM_RC rc = TPM_RC_SUCCESS;
18106 std::string buffer(response);
18107 TPM_ST tag;
18108 std::string tag_bytes;
18109 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18110 if (rc != TPM_RC_SUCCESS) {
18111 return rc;
18112 }
18113 UINT32 response_size;
18114 std::string response_size_bytes;
18115 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18116 if (rc != TPM_RC_SUCCESS) {
18117 return rc;
18118 }
18119 TPM_RC response_code;
18120 std::string response_code_bytes;
18121 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18122 if (rc != TPM_RC_SUCCESS) {
18123 return rc;
18124 }
18125 if (response_size != response.size()) {
18126 return TPM_RC_SIZE;
18127 }
18128 if (response_code != TPM_RC_SUCCESS) {
18129 return response_code;
18130 }
18131 TPM_CC command_code = TPM_CC_GetTime;
18132 std::string command_code_bytes;
18133 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18134 if (rc != TPM_RC_SUCCESS) {
18135 return rc;
18136 }
18137 std::string authorization_section_bytes;
18138 if (tag == TPM_ST_SESSIONS) {
18139 UINT32 parameter_section_size = buffer.size();
18140 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
18141 if (rc != TPM_RC_SUCCESS) {
18142 return rc;
18143 }
18144 if (parameter_section_size > buffer.size()) {
18145 return TPM_RC_INSUFFICIENT;
18146 }
18147 authorization_section_bytes = buffer.substr(parameter_section_size);
18148 // Keep the parameter section in |buffer|.
18149 buffer.erase(parameter_section_size);
18150 }
18151 std::unique_ptr<crypto::SecureHash> hash(
18152 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18153 hash->Update(response_code_bytes.data(), response_code_bytes.size());
18154 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18155 hash->Update(buffer.data(), buffer.size());
18156 std::string response_hash(32, 0);
18157 hash->Finish(std::data(response_hash), response_hash.size());
18158 if (tag == TPM_ST_SESSIONS) {
18159 if (!authorization_delegate)
18160 return TRUNKS_RC_AUTHORIZATION_FAILED;
18161 if (!authorization_delegate->CheckResponseAuthorization(
18162 response_hash, authorization_section_bytes)) {
18163 return TRUNKS_RC_AUTHORIZATION_FAILED;
18164 }
18165 }
18166 if (tag == TPM_ST_SESSIONS) {
18167 if (!authorization_delegate)
18168 return TRUNKS_RC_AUTHORIZATION_FAILED;
18169
18170 // Parse the encrypted parameter size.
18171 UINT16 size;
18172 std::string size_buffer = buffer.substr(0, 2);
18173 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
18174 return result;
18175 }
18176 if (buffer.size() < 2 + size) {
18177 return TPM_RC_INSUFFICIENT;
18178 }
18179
18180 // Decrypt just the parameter data, not the size.
18181 std::string decrypted_data = buffer.substr(2, size);
18182 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
18183 return TRUNKS_RC_ENCRYPTION_FAILED;
18184 }
18185 buffer.replace(2, size, decrypted_data);
18186 }
18187 std::string time_info_bytes;
18188 rc = Parse_TPM2B_ATTEST(&buffer, time_info, &time_info_bytes);
18189 if (rc != TPM_RC_SUCCESS) {
18190 return rc;
18191 }
18192 std::string signature_bytes;
18193 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
18194 if (rc != TPM_RC_SUCCESS) {
18195 return rc;
18196 }
18197 return TPM_RC_SUCCESS;
18198 }
18199
GetTimeErrorCallback(Tpm::GetTimeResponse callback,TPM_RC response_code)18200 void GetTimeErrorCallback(Tpm::GetTimeResponse callback, TPM_RC response_code) {
18201 VLOG(1) << __func__;
18202 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
18203 }
18204
GetTimeResponseParser(Tpm::GetTimeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18205 void GetTimeResponseParser(Tpm::GetTimeResponse callback,
18206 AuthorizationDelegate* authorization_delegate,
18207 const std::string& response) {
18208 VLOG(1) << __func__;
18209 TPM2B_ATTEST time_info;
18210 TPMT_SIGNATURE signature;
18211 TPM_RC rc = Tpm::ParseResponse_GetTime(response, &time_info, &signature,
18212 authorization_delegate);
18213 if (rc != TPM_RC_SUCCESS) {
18214 base::OnceCallback<void(TPM_RC)> error_reporter =
18215 base::BindOnce(GetTimeErrorCallback, std::move(callback));
18216 std::move(error_reporter).Run(rc);
18217 return;
18218 }
18219 std::move(callback).Run(rc, time_info, signature);
18220 }
18221
GetTime(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,GetTimeResponse callback)18222 void Tpm::GetTime(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
18223 const std::string& privacy_admin_handle_name,
18224 const TPMI_DH_OBJECT& sign_handle,
18225 const std::string& sign_handle_name,
18226 const TPM2B_DATA& qualifying_data,
18227 const TPMT_SIG_SCHEME& in_scheme,
18228 AuthorizationDelegate* authorization_delegate,
18229 GetTimeResponse callback) {
18230 VLOG(1) << __func__;
18231 std::string command;
18232 TPM_RC rc =
18233 SerializeCommand_GetTime(privacy_admin_handle, privacy_admin_handle_name,
18234 sign_handle, sign_handle_name, qualifying_data,
18235 in_scheme, &command, authorization_delegate);
18236 if (rc != TPM_RC_SUCCESS) {
18237 base::OnceCallback<void(TPM_RC)> error_reporter =
18238 base::BindOnce(GetTimeErrorCallback, std::move(callback));
18239 std::move(error_reporter).Run(rc);
18240 return;
18241 }
18242 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18243 GetTimeResponseParser, std::move(callback), authorization_delegate);
18244 transceiver_->SendCommand(command, std::move(parser));
18245 }
18246
GetTimeSync(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * time_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)18247 TPM_RC Tpm::GetTimeSync(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
18248 const std::string& privacy_admin_handle_name,
18249 const TPMI_DH_OBJECT& sign_handle,
18250 const std::string& sign_handle_name,
18251 const TPM2B_DATA& qualifying_data,
18252 const TPMT_SIG_SCHEME& in_scheme,
18253 TPM2B_ATTEST* time_info,
18254 TPMT_SIGNATURE* signature,
18255 AuthorizationDelegate* authorization_delegate) {
18256 VLOG(1) << __func__;
18257 std::string command;
18258 TPM_RC rc =
18259 SerializeCommand_GetTime(privacy_admin_handle, privacy_admin_handle_name,
18260 sign_handle, sign_handle_name, qualifying_data,
18261 in_scheme, &command, authorization_delegate);
18262 if (rc != TPM_RC_SUCCESS) {
18263 return rc;
18264 }
18265 std::string response = transceiver_->SendCommandAndWait(command);
18266 rc = ParseResponse_GetTime(response, time_info, signature,
18267 authorization_delegate);
18268 return rc;
18269 }
18270
SerializeCommand_Commit(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const UINT32 & param_size,const TPM2B_ECC_POINT & p1,const TPM2B_SENSITIVE_DATA & s2,const TPM2B_ECC_PARAMETER & y2,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)18271 TPM_RC Tpm::SerializeCommand_Commit(
18272 const TPMI_DH_OBJECT& sign_handle,
18273 const std::string& sign_handle_name,
18274 const UINT32& param_size,
18275 const TPM2B_ECC_POINT& p1,
18276 const TPM2B_SENSITIVE_DATA& s2,
18277 const TPM2B_ECC_PARAMETER& y2,
18278 std::string* serialized_command,
18279 AuthorizationDelegate* authorization_delegate) {
18280 VLOG(3) << __func__;
18281 TPM_RC rc = TPM_RC_SUCCESS;
18282 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18283 UINT32 command_size = 10; // Header size.
18284 std::string handle_section_bytes;
18285 std::string parameter_section_bytes;
18286 TPM_CC command_code = TPM_CC_Commit;
18287 bool is_command_parameter_encryption_possible = false;
18288 bool is_response_parameter_encryption_possible = false;
18289 std::string command_code_bytes;
18290 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18291 if (rc != TPM_RC_SUCCESS) {
18292 return rc;
18293 }
18294 std::string param_size_bytes;
18295 rc = Serialize_UINT32(param_size, ¶m_size_bytes);
18296 if (rc != TPM_RC_SUCCESS) {
18297 return rc;
18298 }
18299 std::string sign_handle_bytes;
18300 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
18301 if (rc != TPM_RC_SUCCESS) {
18302 return rc;
18303 }
18304 std::string p1_bytes;
18305 rc = Serialize_TPM2B_ECC_POINT(p1, &p1_bytes);
18306 if (rc != TPM_RC_SUCCESS) {
18307 return rc;
18308 }
18309 std::string s2_bytes;
18310 rc = Serialize_TPM2B_SENSITIVE_DATA(s2, &s2_bytes);
18311 if (rc != TPM_RC_SUCCESS) {
18312 return rc;
18313 }
18314 std::string y2_bytes;
18315 rc = Serialize_TPM2B_ECC_PARAMETER(y2, &y2_bytes);
18316 if (rc != TPM_RC_SUCCESS) {
18317 return rc;
18318 }
18319 std::unique_ptr<crypto::SecureHash> hash(
18320 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18321 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18322 hash->Update(sign_handle_name.data(), sign_handle_name.size());
18323 handle_section_bytes += sign_handle_bytes;
18324 command_size += sign_handle_bytes.size();
18325 hash->Update(param_size_bytes.data(), param_size_bytes.size());
18326 parameter_section_bytes += param_size_bytes;
18327 command_size += param_size_bytes.size();
18328 hash->Update(p1_bytes.data(), p1_bytes.size());
18329 parameter_section_bytes += p1_bytes;
18330 command_size += p1_bytes.size();
18331 hash->Update(s2_bytes.data(), s2_bytes.size());
18332 parameter_section_bytes += s2_bytes;
18333 command_size += s2_bytes.size();
18334 hash->Update(y2_bytes.data(), y2_bytes.size());
18335 parameter_section_bytes += y2_bytes;
18336 command_size += y2_bytes.size();
18337 std::string command_hash(32, 0);
18338 hash->Finish(std::data(command_hash), command_hash.size());
18339 std::string authorization_section_bytes;
18340 std::string authorization_size_bytes;
18341 if (authorization_delegate) {
18342 if (!authorization_delegate->GetCommandAuthorization(
18343 command_hash, is_command_parameter_encryption_possible,
18344 is_response_parameter_encryption_possible,
18345 &authorization_section_bytes)) {
18346 return TRUNKS_RC_AUTHORIZATION_FAILED;
18347 }
18348 if (!authorization_section_bytes.empty()) {
18349 tag = TPM_ST_SESSIONS;
18350 std::string tmp;
18351 rc = Serialize_UINT32(authorization_section_bytes.size(),
18352 &authorization_size_bytes);
18353 if (rc != TPM_RC_SUCCESS) {
18354 return rc;
18355 }
18356 command_size +=
18357 authorization_size_bytes.size() + authorization_section_bytes.size();
18358 }
18359 }
18360 std::string tag_bytes;
18361 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18362 if (rc != TPM_RC_SUCCESS) {
18363 return rc;
18364 }
18365 std::string command_size_bytes;
18366 rc = Serialize_UINT32(command_size, &command_size_bytes);
18367 if (rc != TPM_RC_SUCCESS) {
18368 return rc;
18369 }
18370 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18371 handle_section_bytes + authorization_size_bytes +
18372 authorization_section_bytes + parameter_section_bytes;
18373 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18374 VLOG(2) << "Command: "
18375 << base::HexEncode(serialized_command->data(),
18376 serialized_command->size());
18377 return TPM_RC_SUCCESS;
18378 }
18379
ParseResponse_Commit(const std::string & response,UINT32 * param_size_out,TPM2B_ECC_POINT * k,TPM2B_ECC_POINT * l,TPM2B_ECC_POINT * e,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18380 TPM_RC Tpm::ParseResponse_Commit(
18381 const std::string& response,
18382 UINT32* param_size_out,
18383 TPM2B_ECC_POINT* k,
18384 TPM2B_ECC_POINT* l,
18385 TPM2B_ECC_POINT* e,
18386 UINT16* counter,
18387 AuthorizationDelegate* authorization_delegate) {
18388 VLOG(3) << __func__;
18389 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18390 TPM_RC rc = TPM_RC_SUCCESS;
18391 std::string buffer(response);
18392 TPM_ST tag;
18393 std::string tag_bytes;
18394 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18395 if (rc != TPM_RC_SUCCESS) {
18396 return rc;
18397 }
18398 UINT32 response_size;
18399 std::string response_size_bytes;
18400 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18401 if (rc != TPM_RC_SUCCESS) {
18402 return rc;
18403 }
18404 TPM_RC response_code;
18405 std::string response_code_bytes;
18406 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18407 if (rc != TPM_RC_SUCCESS) {
18408 return rc;
18409 }
18410 if (response_size != response.size()) {
18411 return TPM_RC_SIZE;
18412 }
18413 if (response_code != TPM_RC_SUCCESS) {
18414 return response_code;
18415 }
18416 TPM_CC command_code = TPM_CC_Commit;
18417 std::string command_code_bytes;
18418 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18419 if (rc != TPM_RC_SUCCESS) {
18420 return rc;
18421 }
18422 std::string authorization_section_bytes;
18423 if (tag == TPM_ST_SESSIONS) {
18424 UINT32 parameter_section_size = buffer.size();
18425 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
18426 if (rc != TPM_RC_SUCCESS) {
18427 return rc;
18428 }
18429 if (parameter_section_size > buffer.size()) {
18430 return TPM_RC_INSUFFICIENT;
18431 }
18432 authorization_section_bytes = buffer.substr(parameter_section_size);
18433 // Keep the parameter section in |buffer|.
18434 buffer.erase(parameter_section_size);
18435 }
18436 std::unique_ptr<crypto::SecureHash> hash(
18437 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18438 hash->Update(response_code_bytes.data(), response_code_bytes.size());
18439 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18440 hash->Update(buffer.data(), buffer.size());
18441 std::string response_hash(32, 0);
18442 hash->Finish(std::data(response_hash), response_hash.size());
18443 if (tag == TPM_ST_SESSIONS) {
18444 if (!authorization_delegate)
18445 return TRUNKS_RC_AUTHORIZATION_FAILED;
18446 if (!authorization_delegate->CheckResponseAuthorization(
18447 response_hash, authorization_section_bytes)) {
18448 return TRUNKS_RC_AUTHORIZATION_FAILED;
18449 }
18450 }
18451 std::string param_size_out_bytes;
18452 rc = Parse_UINT32(&buffer, param_size_out, ¶m_size_out_bytes);
18453 if (rc != TPM_RC_SUCCESS) {
18454 return rc;
18455 }
18456 std::string k_bytes;
18457 rc = Parse_TPM2B_ECC_POINT(&buffer, k, &k_bytes);
18458 if (rc != TPM_RC_SUCCESS) {
18459 return rc;
18460 }
18461 std::string l_bytes;
18462 rc = Parse_TPM2B_ECC_POINT(&buffer, l, &l_bytes);
18463 if (rc != TPM_RC_SUCCESS) {
18464 return rc;
18465 }
18466 std::string e_bytes;
18467 rc = Parse_TPM2B_ECC_POINT(&buffer, e, &e_bytes);
18468 if (rc != TPM_RC_SUCCESS) {
18469 return rc;
18470 }
18471 std::string counter_bytes;
18472 rc = Parse_UINT16(&buffer, counter, &counter_bytes);
18473 if (rc != TPM_RC_SUCCESS) {
18474 return rc;
18475 }
18476 return TPM_RC_SUCCESS;
18477 }
18478
CommitErrorCallback(Tpm::CommitResponse callback,TPM_RC response_code)18479 void CommitErrorCallback(Tpm::CommitResponse callback, TPM_RC response_code) {
18480 VLOG(1) << __func__;
18481 std::move(callback).Run(response_code, UINT32(), TPM2B_ECC_POINT(),
18482 TPM2B_ECC_POINT(), TPM2B_ECC_POINT(), UINT16());
18483 }
18484
CommitResponseParser(Tpm::CommitResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18485 void CommitResponseParser(Tpm::CommitResponse callback,
18486 AuthorizationDelegate* authorization_delegate,
18487 const std::string& response) {
18488 VLOG(1) << __func__;
18489 UINT32 param_size_out;
18490 TPM2B_ECC_POINT k;
18491 TPM2B_ECC_POINT l;
18492 TPM2B_ECC_POINT e;
18493 UINT16 counter;
18494 TPM_RC rc = Tpm::ParseResponse_Commit(response, ¶m_size_out, &k, &l, &e,
18495 &counter, authorization_delegate);
18496 if (rc != TPM_RC_SUCCESS) {
18497 base::OnceCallback<void(TPM_RC)> error_reporter =
18498 base::BindOnce(CommitErrorCallback, std::move(callback));
18499 std::move(error_reporter).Run(rc);
18500 return;
18501 }
18502 std::move(callback).Run(rc, param_size_out, k, l, e, counter);
18503 }
18504
Commit(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const UINT32 & param_size,const TPM2B_ECC_POINT & p1,const TPM2B_SENSITIVE_DATA & s2,const TPM2B_ECC_PARAMETER & y2,AuthorizationDelegate * authorization_delegate,CommitResponse callback)18505 void Tpm::Commit(const TPMI_DH_OBJECT& sign_handle,
18506 const std::string& sign_handle_name,
18507 const UINT32& param_size,
18508 const TPM2B_ECC_POINT& p1,
18509 const TPM2B_SENSITIVE_DATA& s2,
18510 const TPM2B_ECC_PARAMETER& y2,
18511 AuthorizationDelegate* authorization_delegate,
18512 CommitResponse callback) {
18513 VLOG(1) << __func__;
18514 std::string command;
18515 TPM_RC rc =
18516 SerializeCommand_Commit(sign_handle, sign_handle_name, param_size, p1, s2,
18517 y2, &command, authorization_delegate);
18518 if (rc != TPM_RC_SUCCESS) {
18519 base::OnceCallback<void(TPM_RC)> error_reporter =
18520 base::BindOnce(CommitErrorCallback, std::move(callback));
18521 std::move(error_reporter).Run(rc);
18522 return;
18523 }
18524 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18525 CommitResponseParser, std::move(callback), authorization_delegate);
18526 transceiver_->SendCommand(command, std::move(parser));
18527 }
18528
CommitSync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const UINT32 & param_size,const TPM2B_ECC_POINT & p1,const TPM2B_SENSITIVE_DATA & s2,const TPM2B_ECC_PARAMETER & y2,UINT32 * param_size_out,TPM2B_ECC_POINT * k,TPM2B_ECC_POINT * l,TPM2B_ECC_POINT * e,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18529 TPM_RC Tpm::CommitSync(const TPMI_DH_OBJECT& sign_handle,
18530 const std::string& sign_handle_name,
18531 const UINT32& param_size,
18532 const TPM2B_ECC_POINT& p1,
18533 const TPM2B_SENSITIVE_DATA& s2,
18534 const TPM2B_ECC_PARAMETER& y2,
18535 UINT32* param_size_out,
18536 TPM2B_ECC_POINT* k,
18537 TPM2B_ECC_POINT* l,
18538 TPM2B_ECC_POINT* e,
18539 UINT16* counter,
18540 AuthorizationDelegate* authorization_delegate) {
18541 VLOG(1) << __func__;
18542 std::string command;
18543 TPM_RC rc =
18544 SerializeCommand_Commit(sign_handle, sign_handle_name, param_size, p1, s2,
18545 y2, &command, authorization_delegate);
18546 if (rc != TPM_RC_SUCCESS) {
18547 return rc;
18548 }
18549 std::string response = transceiver_->SendCommandAndWait(command);
18550 rc = ParseResponse_Commit(response, param_size_out, k, l, e, counter,
18551 authorization_delegate);
18552 return rc;
18553 }
18554
SerializeCommand_EC_Ephemeral(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)18555 TPM_RC Tpm::SerializeCommand_EC_Ephemeral(
18556 const UINT32& param_size,
18557 const TPMI_ECC_CURVE& curve_id,
18558 std::string* serialized_command,
18559 AuthorizationDelegate* authorization_delegate) {
18560 VLOG(3) << __func__;
18561 TPM_RC rc = TPM_RC_SUCCESS;
18562 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18563 UINT32 command_size = 10; // Header size.
18564 std::string handle_section_bytes;
18565 std::string parameter_section_bytes;
18566 TPM_CC command_code = TPM_CC_EC_Ephemeral;
18567 bool is_command_parameter_encryption_possible = false;
18568 bool is_response_parameter_encryption_possible = false;
18569 std::string command_code_bytes;
18570 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18571 if (rc != TPM_RC_SUCCESS) {
18572 return rc;
18573 }
18574 std::string param_size_bytes;
18575 rc = Serialize_UINT32(param_size, ¶m_size_bytes);
18576 if (rc != TPM_RC_SUCCESS) {
18577 return rc;
18578 }
18579 std::string curve_id_bytes;
18580 rc = Serialize_TPMI_ECC_CURVE(curve_id, &curve_id_bytes);
18581 if (rc != TPM_RC_SUCCESS) {
18582 return rc;
18583 }
18584 std::unique_ptr<crypto::SecureHash> hash(
18585 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18586 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18587 hash->Update(param_size_bytes.data(), param_size_bytes.size());
18588 parameter_section_bytes += param_size_bytes;
18589 command_size += param_size_bytes.size();
18590 hash->Update(curve_id_bytes.data(), curve_id_bytes.size());
18591 parameter_section_bytes += curve_id_bytes;
18592 command_size += curve_id_bytes.size();
18593 std::string command_hash(32, 0);
18594 hash->Finish(std::data(command_hash), command_hash.size());
18595 std::string authorization_section_bytes;
18596 std::string authorization_size_bytes;
18597 if (authorization_delegate) {
18598 if (!authorization_delegate->GetCommandAuthorization(
18599 command_hash, is_command_parameter_encryption_possible,
18600 is_response_parameter_encryption_possible,
18601 &authorization_section_bytes)) {
18602 return TRUNKS_RC_AUTHORIZATION_FAILED;
18603 }
18604 if (!authorization_section_bytes.empty()) {
18605 tag = TPM_ST_SESSIONS;
18606 std::string tmp;
18607 rc = Serialize_UINT32(authorization_section_bytes.size(),
18608 &authorization_size_bytes);
18609 if (rc != TPM_RC_SUCCESS) {
18610 return rc;
18611 }
18612 command_size +=
18613 authorization_size_bytes.size() + authorization_section_bytes.size();
18614 }
18615 }
18616 std::string tag_bytes;
18617 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18618 if (rc != TPM_RC_SUCCESS) {
18619 return rc;
18620 }
18621 std::string command_size_bytes;
18622 rc = Serialize_UINT32(command_size, &command_size_bytes);
18623 if (rc != TPM_RC_SUCCESS) {
18624 return rc;
18625 }
18626 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18627 handle_section_bytes + authorization_size_bytes +
18628 authorization_section_bytes + parameter_section_bytes;
18629 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18630 VLOG(2) << "Command: "
18631 << base::HexEncode(serialized_command->data(),
18632 serialized_command->size());
18633 return TPM_RC_SUCCESS;
18634 }
18635
ParseResponse_EC_Ephemeral(const std::string & response,UINT32 * param_size_out,TPM2B_ECC_POINT * q,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18636 TPM_RC Tpm::ParseResponse_EC_Ephemeral(
18637 const std::string& response,
18638 UINT32* param_size_out,
18639 TPM2B_ECC_POINT* q,
18640 UINT16* counter,
18641 AuthorizationDelegate* authorization_delegate) {
18642 VLOG(3) << __func__;
18643 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18644 TPM_RC rc = TPM_RC_SUCCESS;
18645 std::string buffer(response);
18646 TPM_ST tag;
18647 std::string tag_bytes;
18648 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18649 if (rc != TPM_RC_SUCCESS) {
18650 return rc;
18651 }
18652 UINT32 response_size;
18653 std::string response_size_bytes;
18654 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18655 if (rc != TPM_RC_SUCCESS) {
18656 return rc;
18657 }
18658 TPM_RC response_code;
18659 std::string response_code_bytes;
18660 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18661 if (rc != TPM_RC_SUCCESS) {
18662 return rc;
18663 }
18664 if (response_size != response.size()) {
18665 return TPM_RC_SIZE;
18666 }
18667 if (response_code != TPM_RC_SUCCESS) {
18668 return response_code;
18669 }
18670 TPM_CC command_code = TPM_CC_EC_Ephemeral;
18671 std::string command_code_bytes;
18672 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18673 if (rc != TPM_RC_SUCCESS) {
18674 return rc;
18675 }
18676 std::string authorization_section_bytes;
18677 if (tag == TPM_ST_SESSIONS) {
18678 UINT32 parameter_section_size = buffer.size();
18679 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
18680 if (rc != TPM_RC_SUCCESS) {
18681 return rc;
18682 }
18683 if (parameter_section_size > buffer.size()) {
18684 return TPM_RC_INSUFFICIENT;
18685 }
18686 authorization_section_bytes = buffer.substr(parameter_section_size);
18687 // Keep the parameter section in |buffer|.
18688 buffer.erase(parameter_section_size);
18689 }
18690 std::unique_ptr<crypto::SecureHash> hash(
18691 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18692 hash->Update(response_code_bytes.data(), response_code_bytes.size());
18693 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18694 hash->Update(buffer.data(), buffer.size());
18695 std::string response_hash(32, 0);
18696 hash->Finish(std::data(response_hash), response_hash.size());
18697 if (tag == TPM_ST_SESSIONS) {
18698 if (!authorization_delegate)
18699 return TRUNKS_RC_AUTHORIZATION_FAILED;
18700 if (!authorization_delegate->CheckResponseAuthorization(
18701 response_hash, authorization_section_bytes)) {
18702 return TRUNKS_RC_AUTHORIZATION_FAILED;
18703 }
18704 }
18705 std::string param_size_out_bytes;
18706 rc = Parse_UINT32(&buffer, param_size_out, ¶m_size_out_bytes);
18707 if (rc != TPM_RC_SUCCESS) {
18708 return rc;
18709 }
18710 std::string q_bytes;
18711 rc = Parse_TPM2B_ECC_POINT(&buffer, q, &q_bytes);
18712 if (rc != TPM_RC_SUCCESS) {
18713 return rc;
18714 }
18715 std::string counter_bytes;
18716 rc = Parse_UINT16(&buffer, counter, &counter_bytes);
18717 if (rc != TPM_RC_SUCCESS) {
18718 return rc;
18719 }
18720 return TPM_RC_SUCCESS;
18721 }
18722
EC_EphemeralErrorCallback(Tpm::EC_EphemeralResponse callback,TPM_RC response_code)18723 void EC_EphemeralErrorCallback(Tpm::EC_EphemeralResponse callback,
18724 TPM_RC response_code) {
18725 VLOG(1) << __func__;
18726 std::move(callback).Run(response_code, UINT32(), TPM2B_ECC_POINT(), UINT16());
18727 }
18728
EC_EphemeralResponseParser(Tpm::EC_EphemeralResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18729 void EC_EphemeralResponseParser(Tpm::EC_EphemeralResponse callback,
18730 AuthorizationDelegate* authorization_delegate,
18731 const std::string& response) {
18732 VLOG(1) << __func__;
18733 UINT32 param_size_out;
18734 TPM2B_ECC_POINT q;
18735 UINT16 counter;
18736 TPM_RC rc = Tpm::ParseResponse_EC_Ephemeral(response, ¶m_size_out, &q,
18737 &counter, authorization_delegate);
18738 if (rc != TPM_RC_SUCCESS) {
18739 base::OnceCallback<void(TPM_RC)> error_reporter =
18740 base::BindOnce(EC_EphemeralErrorCallback, std::move(callback));
18741 std::move(error_reporter).Run(rc);
18742 return;
18743 }
18744 std::move(callback).Run(rc, param_size_out, q, counter);
18745 }
18746
EC_Ephemeral(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,AuthorizationDelegate * authorization_delegate,EC_EphemeralResponse callback)18747 void Tpm::EC_Ephemeral(const UINT32& param_size,
18748 const TPMI_ECC_CURVE& curve_id,
18749 AuthorizationDelegate* authorization_delegate,
18750 EC_EphemeralResponse callback) {
18751 VLOG(1) << __func__;
18752 std::string command;
18753 TPM_RC rc = SerializeCommand_EC_Ephemeral(param_size, curve_id, &command,
18754 authorization_delegate);
18755 if (rc != TPM_RC_SUCCESS) {
18756 base::OnceCallback<void(TPM_RC)> error_reporter =
18757 base::BindOnce(EC_EphemeralErrorCallback, std::move(callback));
18758 std::move(error_reporter).Run(rc);
18759 return;
18760 }
18761 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18762 EC_EphemeralResponseParser, std::move(callback), authorization_delegate);
18763 transceiver_->SendCommand(command, std::move(parser));
18764 }
18765
EC_EphemeralSync(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,UINT32 * param_size_out,TPM2B_ECC_POINT * q,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18766 TPM_RC Tpm::EC_EphemeralSync(const UINT32& param_size,
18767 const TPMI_ECC_CURVE& curve_id,
18768 UINT32* param_size_out,
18769 TPM2B_ECC_POINT* q,
18770 UINT16* counter,
18771 AuthorizationDelegate* authorization_delegate) {
18772 VLOG(1) << __func__;
18773 std::string command;
18774 TPM_RC rc = SerializeCommand_EC_Ephemeral(param_size, curve_id, &command,
18775 authorization_delegate);
18776 if (rc != TPM_RC_SUCCESS) {
18777 return rc;
18778 }
18779 std::string response = transceiver_->SendCommandAndWait(command);
18780 rc = ParseResponse_EC_Ephemeral(response, param_size_out, q, counter,
18781 authorization_delegate);
18782 return rc;
18783 }
18784
SerializeCommand_VerifySignature(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIGNATURE & signature,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)18785 TPM_RC Tpm::SerializeCommand_VerifySignature(
18786 const TPMI_DH_OBJECT& key_handle,
18787 const std::string& key_handle_name,
18788 const TPM2B_DIGEST& digest,
18789 const TPMT_SIGNATURE& signature,
18790 std::string* serialized_command,
18791 AuthorizationDelegate* authorization_delegate) {
18792 VLOG(3) << __func__;
18793 TPM_RC rc = TPM_RC_SUCCESS;
18794 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18795 UINT32 command_size = 10; // Header size.
18796 std::string handle_section_bytes;
18797 std::string parameter_section_bytes;
18798 TPM_CC command_code = TPM_CC_VerifySignature;
18799 bool is_command_parameter_encryption_possible = true;
18800 bool is_response_parameter_encryption_possible = false;
18801 std::string command_code_bytes;
18802 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18803 if (rc != TPM_RC_SUCCESS) {
18804 return rc;
18805 }
18806 std::string key_handle_bytes;
18807 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
18808 if (rc != TPM_RC_SUCCESS) {
18809 return rc;
18810 }
18811 std::string digest_bytes;
18812 rc = Serialize_TPM2B_DIGEST(digest, &digest_bytes);
18813 if (rc != TPM_RC_SUCCESS) {
18814 return rc;
18815 }
18816 std::string signature_bytes;
18817 rc = Serialize_TPMT_SIGNATURE(signature, &signature_bytes);
18818 if (rc != TPM_RC_SUCCESS) {
18819 return rc;
18820 }
18821 if (authorization_delegate) {
18822 // Encrypt just the parameter data, not the size.
18823 std::string tmp = digest_bytes.substr(2);
18824 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
18825 return TRUNKS_RC_ENCRYPTION_FAILED;
18826 }
18827 digest_bytes.replace(2, std::string::npos, tmp);
18828 }
18829 std::unique_ptr<crypto::SecureHash> hash(
18830 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18831 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18832 hash->Update(key_handle_name.data(), key_handle_name.size());
18833 handle_section_bytes += key_handle_bytes;
18834 command_size += key_handle_bytes.size();
18835 hash->Update(digest_bytes.data(), digest_bytes.size());
18836 parameter_section_bytes += digest_bytes;
18837 command_size += digest_bytes.size();
18838 hash->Update(signature_bytes.data(), signature_bytes.size());
18839 parameter_section_bytes += signature_bytes;
18840 command_size += signature_bytes.size();
18841 std::string command_hash(32, 0);
18842 hash->Finish(std::data(command_hash), command_hash.size());
18843 std::string authorization_section_bytes;
18844 std::string authorization_size_bytes;
18845 if (authorization_delegate) {
18846 if (!authorization_delegate->GetCommandAuthorization(
18847 command_hash, is_command_parameter_encryption_possible,
18848 is_response_parameter_encryption_possible,
18849 &authorization_section_bytes)) {
18850 return TRUNKS_RC_AUTHORIZATION_FAILED;
18851 }
18852 if (!authorization_section_bytes.empty()) {
18853 tag = TPM_ST_SESSIONS;
18854 std::string tmp;
18855 rc = Serialize_UINT32(authorization_section_bytes.size(),
18856 &authorization_size_bytes);
18857 if (rc != TPM_RC_SUCCESS) {
18858 return rc;
18859 }
18860 command_size +=
18861 authorization_size_bytes.size() + authorization_section_bytes.size();
18862 }
18863 }
18864 std::string tag_bytes;
18865 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18866 if (rc != TPM_RC_SUCCESS) {
18867 return rc;
18868 }
18869 std::string command_size_bytes;
18870 rc = Serialize_UINT32(command_size, &command_size_bytes);
18871 if (rc != TPM_RC_SUCCESS) {
18872 return rc;
18873 }
18874 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18875 handle_section_bytes + authorization_size_bytes +
18876 authorization_section_bytes + parameter_section_bytes;
18877 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18878 VLOG(2) << "Command: "
18879 << base::HexEncode(serialized_command->data(),
18880 serialized_command->size());
18881 return TPM_RC_SUCCESS;
18882 }
18883
ParseResponse_VerifySignature(const std::string & response,TPMT_TK_VERIFIED * validation,AuthorizationDelegate * authorization_delegate)18884 TPM_RC Tpm::ParseResponse_VerifySignature(
18885 const std::string& response,
18886 TPMT_TK_VERIFIED* validation,
18887 AuthorizationDelegate* authorization_delegate) {
18888 VLOG(3) << __func__;
18889 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18890 TPM_RC rc = TPM_RC_SUCCESS;
18891 std::string buffer(response);
18892 TPM_ST tag;
18893 std::string tag_bytes;
18894 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18895 if (rc != TPM_RC_SUCCESS) {
18896 return rc;
18897 }
18898 UINT32 response_size;
18899 std::string response_size_bytes;
18900 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18901 if (rc != TPM_RC_SUCCESS) {
18902 return rc;
18903 }
18904 TPM_RC response_code;
18905 std::string response_code_bytes;
18906 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18907 if (rc != TPM_RC_SUCCESS) {
18908 return rc;
18909 }
18910 if (response_size != response.size()) {
18911 return TPM_RC_SIZE;
18912 }
18913 if (response_code != TPM_RC_SUCCESS) {
18914 return response_code;
18915 }
18916 TPM_CC command_code = TPM_CC_VerifySignature;
18917 std::string command_code_bytes;
18918 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18919 if (rc != TPM_RC_SUCCESS) {
18920 return rc;
18921 }
18922 std::string authorization_section_bytes;
18923 if (tag == TPM_ST_SESSIONS) {
18924 UINT32 parameter_section_size = buffer.size();
18925 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
18926 if (rc != TPM_RC_SUCCESS) {
18927 return rc;
18928 }
18929 if (parameter_section_size > buffer.size()) {
18930 return TPM_RC_INSUFFICIENT;
18931 }
18932 authorization_section_bytes = buffer.substr(parameter_section_size);
18933 // Keep the parameter section in |buffer|.
18934 buffer.erase(parameter_section_size);
18935 }
18936 std::unique_ptr<crypto::SecureHash> hash(
18937 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18938 hash->Update(response_code_bytes.data(), response_code_bytes.size());
18939 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18940 hash->Update(buffer.data(), buffer.size());
18941 std::string response_hash(32, 0);
18942 hash->Finish(std::data(response_hash), response_hash.size());
18943 if (tag == TPM_ST_SESSIONS) {
18944 if (!authorization_delegate)
18945 return TRUNKS_RC_AUTHORIZATION_FAILED;
18946 if (!authorization_delegate->CheckResponseAuthorization(
18947 response_hash, authorization_section_bytes)) {
18948 return TRUNKS_RC_AUTHORIZATION_FAILED;
18949 }
18950 }
18951 std::string validation_bytes;
18952 rc = Parse_TPMT_TK_VERIFIED(&buffer, validation, &validation_bytes);
18953 if (rc != TPM_RC_SUCCESS) {
18954 return rc;
18955 }
18956 return TPM_RC_SUCCESS;
18957 }
18958
VerifySignatureErrorCallback(Tpm::VerifySignatureResponse callback,TPM_RC response_code)18959 void VerifySignatureErrorCallback(Tpm::VerifySignatureResponse callback,
18960 TPM_RC response_code) {
18961 VLOG(1) << __func__;
18962 std::move(callback).Run(response_code, TPMT_TK_VERIFIED());
18963 }
18964
VerifySignatureResponseParser(Tpm::VerifySignatureResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18965 void VerifySignatureResponseParser(
18966 Tpm::VerifySignatureResponse callback,
18967 AuthorizationDelegate* authorization_delegate,
18968 const std::string& response) {
18969 VLOG(1) << __func__;
18970 TPMT_TK_VERIFIED validation;
18971 TPM_RC rc = Tpm::ParseResponse_VerifySignature(response, &validation,
18972 authorization_delegate);
18973 if (rc != TPM_RC_SUCCESS) {
18974 base::OnceCallback<void(TPM_RC)> error_reporter =
18975 base::BindOnce(VerifySignatureErrorCallback, std::move(callback));
18976 std::move(error_reporter).Run(rc);
18977 return;
18978 }
18979 std::move(callback).Run(rc, validation);
18980 }
18981
VerifySignature(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIGNATURE & signature,AuthorizationDelegate * authorization_delegate,VerifySignatureResponse callback)18982 void Tpm::VerifySignature(const TPMI_DH_OBJECT& key_handle,
18983 const std::string& key_handle_name,
18984 const TPM2B_DIGEST& digest,
18985 const TPMT_SIGNATURE& signature,
18986 AuthorizationDelegate* authorization_delegate,
18987 VerifySignatureResponse callback) {
18988 VLOG(1) << __func__;
18989 std::string command;
18990 TPM_RC rc = SerializeCommand_VerifySignature(key_handle, key_handle_name,
18991 digest, signature, &command,
18992 authorization_delegate);
18993 if (rc != TPM_RC_SUCCESS) {
18994 base::OnceCallback<void(TPM_RC)> error_reporter =
18995 base::BindOnce(VerifySignatureErrorCallback, std::move(callback));
18996 std::move(error_reporter).Run(rc);
18997 return;
18998 }
18999 base::OnceCallback<void(const std::string&)> parser =
19000 base::BindOnce(VerifySignatureResponseParser, std::move(callback),
19001 authorization_delegate);
19002 transceiver_->SendCommand(command, std::move(parser));
19003 }
19004
VerifySignatureSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIGNATURE & signature,TPMT_TK_VERIFIED * validation,AuthorizationDelegate * authorization_delegate)19005 TPM_RC Tpm::VerifySignatureSync(const TPMI_DH_OBJECT& key_handle,
19006 const std::string& key_handle_name,
19007 const TPM2B_DIGEST& digest,
19008 const TPMT_SIGNATURE& signature,
19009 TPMT_TK_VERIFIED* validation,
19010 AuthorizationDelegate* authorization_delegate) {
19011 VLOG(1) << __func__;
19012 std::string command;
19013 TPM_RC rc = SerializeCommand_VerifySignature(key_handle, key_handle_name,
19014 digest, signature, &command,
19015 authorization_delegate);
19016 if (rc != TPM_RC_SUCCESS) {
19017 return rc;
19018 }
19019 std::string response = transceiver_->SendCommandAndWait(command);
19020 rc = ParseResponse_VerifySignature(response, validation,
19021 authorization_delegate);
19022 return rc;
19023 }
19024
SerializeCommand_Sign(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_HASHCHECK & validation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19025 TPM_RC Tpm::SerializeCommand_Sign(
19026 const TPMI_DH_OBJECT& key_handle,
19027 const std::string& key_handle_name,
19028 const TPM2B_DIGEST& digest,
19029 const TPMT_SIG_SCHEME& in_scheme,
19030 const TPMT_TK_HASHCHECK& validation,
19031 std::string* serialized_command,
19032 AuthorizationDelegate* authorization_delegate) {
19033 VLOG(3) << __func__;
19034 TPM_RC rc = TPM_RC_SUCCESS;
19035 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19036 UINT32 command_size = 10; // Header size.
19037 std::string handle_section_bytes;
19038 std::string parameter_section_bytes;
19039 TPM_CC command_code = TPM_CC_Sign;
19040 bool is_command_parameter_encryption_possible = true;
19041 bool is_response_parameter_encryption_possible = false;
19042 std::string command_code_bytes;
19043 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19044 if (rc != TPM_RC_SUCCESS) {
19045 return rc;
19046 }
19047 std::string key_handle_bytes;
19048 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
19049 if (rc != TPM_RC_SUCCESS) {
19050 return rc;
19051 }
19052 std::string digest_bytes;
19053 rc = Serialize_TPM2B_DIGEST(digest, &digest_bytes);
19054 if (rc != TPM_RC_SUCCESS) {
19055 return rc;
19056 }
19057 std::string in_scheme_bytes;
19058 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
19059 if (rc != TPM_RC_SUCCESS) {
19060 return rc;
19061 }
19062 std::string validation_bytes;
19063 rc = Serialize_TPMT_TK_HASHCHECK(validation, &validation_bytes);
19064 if (rc != TPM_RC_SUCCESS) {
19065 return rc;
19066 }
19067 if (authorization_delegate) {
19068 // Encrypt just the parameter data, not the size.
19069 std::string tmp = digest_bytes.substr(2);
19070 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
19071 return TRUNKS_RC_ENCRYPTION_FAILED;
19072 }
19073 digest_bytes.replace(2, std::string::npos, tmp);
19074 }
19075 std::unique_ptr<crypto::SecureHash> hash(
19076 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19077 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19078 hash->Update(key_handle_name.data(), key_handle_name.size());
19079 handle_section_bytes += key_handle_bytes;
19080 command_size += key_handle_bytes.size();
19081 hash->Update(digest_bytes.data(), digest_bytes.size());
19082 parameter_section_bytes += digest_bytes;
19083 command_size += digest_bytes.size();
19084 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
19085 parameter_section_bytes += in_scheme_bytes;
19086 command_size += in_scheme_bytes.size();
19087 hash->Update(validation_bytes.data(), validation_bytes.size());
19088 parameter_section_bytes += validation_bytes;
19089 command_size += validation_bytes.size();
19090 std::string command_hash(32, 0);
19091 hash->Finish(std::data(command_hash), command_hash.size());
19092 std::string authorization_section_bytes;
19093 std::string authorization_size_bytes;
19094 if (authorization_delegate) {
19095 if (!authorization_delegate->GetCommandAuthorization(
19096 command_hash, is_command_parameter_encryption_possible,
19097 is_response_parameter_encryption_possible,
19098 &authorization_section_bytes)) {
19099 return TRUNKS_RC_AUTHORIZATION_FAILED;
19100 }
19101 if (!authorization_section_bytes.empty()) {
19102 tag = TPM_ST_SESSIONS;
19103 std::string tmp;
19104 rc = Serialize_UINT32(authorization_section_bytes.size(),
19105 &authorization_size_bytes);
19106 if (rc != TPM_RC_SUCCESS) {
19107 return rc;
19108 }
19109 command_size +=
19110 authorization_size_bytes.size() + authorization_section_bytes.size();
19111 }
19112 }
19113 std::string tag_bytes;
19114 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19115 if (rc != TPM_RC_SUCCESS) {
19116 return rc;
19117 }
19118 std::string command_size_bytes;
19119 rc = Serialize_UINT32(command_size, &command_size_bytes);
19120 if (rc != TPM_RC_SUCCESS) {
19121 return rc;
19122 }
19123 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19124 handle_section_bytes + authorization_size_bytes +
19125 authorization_section_bytes + parameter_section_bytes;
19126 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19127 VLOG(2) << "Command: "
19128 << base::HexEncode(serialized_command->data(),
19129 serialized_command->size());
19130 return TPM_RC_SUCCESS;
19131 }
19132
ParseResponse_Sign(const std::string & response,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)19133 TPM_RC Tpm::ParseResponse_Sign(const std::string& response,
19134 TPMT_SIGNATURE* signature,
19135 AuthorizationDelegate* authorization_delegate) {
19136 VLOG(3) << __func__;
19137 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19138 TPM_RC rc = TPM_RC_SUCCESS;
19139 std::string buffer(response);
19140 TPM_ST tag;
19141 std::string tag_bytes;
19142 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19143 if (rc != TPM_RC_SUCCESS) {
19144 return rc;
19145 }
19146 UINT32 response_size;
19147 std::string response_size_bytes;
19148 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19149 if (rc != TPM_RC_SUCCESS) {
19150 return rc;
19151 }
19152 TPM_RC response_code;
19153 std::string response_code_bytes;
19154 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19155 if (rc != TPM_RC_SUCCESS) {
19156 return rc;
19157 }
19158 if (response_size != response.size()) {
19159 return TPM_RC_SIZE;
19160 }
19161 if (response_code != TPM_RC_SUCCESS) {
19162 return response_code;
19163 }
19164 TPM_CC command_code = TPM_CC_Sign;
19165 std::string command_code_bytes;
19166 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19167 if (rc != TPM_RC_SUCCESS) {
19168 return rc;
19169 }
19170 std::string authorization_section_bytes;
19171 if (tag == TPM_ST_SESSIONS) {
19172 UINT32 parameter_section_size = buffer.size();
19173 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
19174 if (rc != TPM_RC_SUCCESS) {
19175 return rc;
19176 }
19177 if (parameter_section_size > buffer.size()) {
19178 return TPM_RC_INSUFFICIENT;
19179 }
19180 authorization_section_bytes = buffer.substr(parameter_section_size);
19181 // Keep the parameter section in |buffer|.
19182 buffer.erase(parameter_section_size);
19183 }
19184 std::unique_ptr<crypto::SecureHash> hash(
19185 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19186 hash->Update(response_code_bytes.data(), response_code_bytes.size());
19187 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19188 hash->Update(buffer.data(), buffer.size());
19189 std::string response_hash(32, 0);
19190 hash->Finish(std::data(response_hash), response_hash.size());
19191 if (tag == TPM_ST_SESSIONS) {
19192 if (!authorization_delegate)
19193 return TRUNKS_RC_AUTHORIZATION_FAILED;
19194 if (!authorization_delegate->CheckResponseAuthorization(
19195 response_hash, authorization_section_bytes)) {
19196 return TRUNKS_RC_AUTHORIZATION_FAILED;
19197 }
19198 }
19199 std::string signature_bytes;
19200 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
19201 if (rc != TPM_RC_SUCCESS) {
19202 return rc;
19203 }
19204 return TPM_RC_SUCCESS;
19205 }
19206
SignErrorCallback(Tpm::SignResponse callback,TPM_RC response_code)19207 void SignErrorCallback(Tpm::SignResponse callback, TPM_RC response_code) {
19208 VLOG(1) << __func__;
19209 std::move(callback).Run(response_code, TPMT_SIGNATURE());
19210 }
19211
SignResponseParser(Tpm::SignResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19212 void SignResponseParser(Tpm::SignResponse callback,
19213 AuthorizationDelegate* authorization_delegate,
19214 const std::string& response) {
19215 VLOG(1) << __func__;
19216 TPMT_SIGNATURE signature;
19217 TPM_RC rc =
19218 Tpm::ParseResponse_Sign(response, &signature, authorization_delegate);
19219 if (rc != TPM_RC_SUCCESS) {
19220 base::OnceCallback<void(TPM_RC)> error_reporter =
19221 base::BindOnce(SignErrorCallback, std::move(callback));
19222 std::move(error_reporter).Run(rc);
19223 return;
19224 }
19225 std::move(callback).Run(rc, signature);
19226 }
19227
Sign(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_HASHCHECK & validation,AuthorizationDelegate * authorization_delegate,SignResponse callback)19228 void Tpm::Sign(const TPMI_DH_OBJECT& key_handle,
19229 const std::string& key_handle_name,
19230 const TPM2B_DIGEST& digest,
19231 const TPMT_SIG_SCHEME& in_scheme,
19232 const TPMT_TK_HASHCHECK& validation,
19233 AuthorizationDelegate* authorization_delegate,
19234 SignResponse callback) {
19235 VLOG(1) << __func__;
19236 std::string command;
19237 TPM_RC rc =
19238 SerializeCommand_Sign(key_handle, key_handle_name, digest, in_scheme,
19239 validation, &command, authorization_delegate);
19240 if (rc != TPM_RC_SUCCESS) {
19241 base::OnceCallback<void(TPM_RC)> error_reporter =
19242 base::BindOnce(SignErrorCallback, std::move(callback));
19243 std::move(error_reporter).Run(rc);
19244 return;
19245 }
19246 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19247 SignResponseParser, std::move(callback), authorization_delegate);
19248 transceiver_->SendCommand(command, std::move(parser));
19249 }
19250
SignSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_HASHCHECK & validation,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)19251 TPM_RC Tpm::SignSync(const TPMI_DH_OBJECT& key_handle,
19252 const std::string& key_handle_name,
19253 const TPM2B_DIGEST& digest,
19254 const TPMT_SIG_SCHEME& in_scheme,
19255 const TPMT_TK_HASHCHECK& validation,
19256 TPMT_SIGNATURE* signature,
19257 AuthorizationDelegate* authorization_delegate) {
19258 VLOG(1) << __func__;
19259 std::string command;
19260 TPM_RC rc =
19261 SerializeCommand_Sign(key_handle, key_handle_name, digest, in_scheme,
19262 validation, &command, authorization_delegate);
19263 if (rc != TPM_RC_SUCCESS) {
19264 return rc;
19265 }
19266 std::string response = transceiver_->SendCommandAndWait(command);
19267 rc = ParseResponse_Sign(response, signature, authorization_delegate);
19268 return rc;
19269 }
19270
SerializeCommand_SetCommandCodeAuditStatus(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_ALG_HASH & audit_alg,const TPML_CC & set_list,const TPML_CC & clear_list,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19271 TPM_RC Tpm::SerializeCommand_SetCommandCodeAuditStatus(
19272 const TPMI_RH_PROVISION& auth,
19273 const std::string& auth_name,
19274 const TPMI_ALG_HASH& audit_alg,
19275 const TPML_CC& set_list,
19276 const TPML_CC& clear_list,
19277 std::string* serialized_command,
19278 AuthorizationDelegate* authorization_delegate) {
19279 VLOG(3) << __func__;
19280 TPM_RC rc = TPM_RC_SUCCESS;
19281 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19282 UINT32 command_size = 10; // Header size.
19283 std::string handle_section_bytes;
19284 std::string parameter_section_bytes;
19285 TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus;
19286 bool is_command_parameter_encryption_possible = false;
19287 bool is_response_parameter_encryption_possible = false;
19288 std::string command_code_bytes;
19289 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19290 if (rc != TPM_RC_SUCCESS) {
19291 return rc;
19292 }
19293 std::string auth_bytes;
19294 rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
19295 if (rc != TPM_RC_SUCCESS) {
19296 return rc;
19297 }
19298 std::string audit_alg_bytes;
19299 rc = Serialize_TPMI_ALG_HASH(audit_alg, &audit_alg_bytes);
19300 if (rc != TPM_RC_SUCCESS) {
19301 return rc;
19302 }
19303 std::string set_list_bytes;
19304 rc = Serialize_TPML_CC(set_list, &set_list_bytes);
19305 if (rc != TPM_RC_SUCCESS) {
19306 return rc;
19307 }
19308 std::string clear_list_bytes;
19309 rc = Serialize_TPML_CC(clear_list, &clear_list_bytes);
19310 if (rc != TPM_RC_SUCCESS) {
19311 return rc;
19312 }
19313 std::unique_ptr<crypto::SecureHash> hash(
19314 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19315 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19316 hash->Update(auth_name.data(), auth_name.size());
19317 handle_section_bytes += auth_bytes;
19318 command_size += auth_bytes.size();
19319 hash->Update(audit_alg_bytes.data(), audit_alg_bytes.size());
19320 parameter_section_bytes += audit_alg_bytes;
19321 command_size += audit_alg_bytes.size();
19322 hash->Update(set_list_bytes.data(), set_list_bytes.size());
19323 parameter_section_bytes += set_list_bytes;
19324 command_size += set_list_bytes.size();
19325 hash->Update(clear_list_bytes.data(), clear_list_bytes.size());
19326 parameter_section_bytes += clear_list_bytes;
19327 command_size += clear_list_bytes.size();
19328 std::string command_hash(32, 0);
19329 hash->Finish(std::data(command_hash), command_hash.size());
19330 std::string authorization_section_bytes;
19331 std::string authorization_size_bytes;
19332 if (authorization_delegate) {
19333 if (!authorization_delegate->GetCommandAuthorization(
19334 command_hash, is_command_parameter_encryption_possible,
19335 is_response_parameter_encryption_possible,
19336 &authorization_section_bytes)) {
19337 return TRUNKS_RC_AUTHORIZATION_FAILED;
19338 }
19339 if (!authorization_section_bytes.empty()) {
19340 tag = TPM_ST_SESSIONS;
19341 std::string tmp;
19342 rc = Serialize_UINT32(authorization_section_bytes.size(),
19343 &authorization_size_bytes);
19344 if (rc != TPM_RC_SUCCESS) {
19345 return rc;
19346 }
19347 command_size +=
19348 authorization_size_bytes.size() + authorization_section_bytes.size();
19349 }
19350 }
19351 std::string tag_bytes;
19352 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19353 if (rc != TPM_RC_SUCCESS) {
19354 return rc;
19355 }
19356 std::string command_size_bytes;
19357 rc = Serialize_UINT32(command_size, &command_size_bytes);
19358 if (rc != TPM_RC_SUCCESS) {
19359 return rc;
19360 }
19361 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19362 handle_section_bytes + authorization_size_bytes +
19363 authorization_section_bytes + parameter_section_bytes;
19364 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19365 VLOG(2) << "Command: "
19366 << base::HexEncode(serialized_command->data(),
19367 serialized_command->size());
19368 return TPM_RC_SUCCESS;
19369 }
19370
ParseResponse_SetCommandCodeAuditStatus(const std::string & response,AuthorizationDelegate * authorization_delegate)19371 TPM_RC Tpm::ParseResponse_SetCommandCodeAuditStatus(
19372 const std::string& response,
19373 AuthorizationDelegate* authorization_delegate) {
19374 VLOG(3) << __func__;
19375 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19376 TPM_RC rc = TPM_RC_SUCCESS;
19377 std::string buffer(response);
19378 TPM_ST tag;
19379 std::string tag_bytes;
19380 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19381 if (rc != TPM_RC_SUCCESS) {
19382 return rc;
19383 }
19384 UINT32 response_size;
19385 std::string response_size_bytes;
19386 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19387 if (rc != TPM_RC_SUCCESS) {
19388 return rc;
19389 }
19390 TPM_RC response_code;
19391 std::string response_code_bytes;
19392 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19393 if (rc != TPM_RC_SUCCESS) {
19394 return rc;
19395 }
19396 if (response_size != response.size()) {
19397 return TPM_RC_SIZE;
19398 }
19399 if (response_code != TPM_RC_SUCCESS) {
19400 return response_code;
19401 }
19402 TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus;
19403 std::string command_code_bytes;
19404 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19405 if (rc != TPM_RC_SUCCESS) {
19406 return rc;
19407 }
19408 std::string authorization_section_bytes;
19409 if (tag == TPM_ST_SESSIONS) {
19410 UINT32 parameter_section_size = buffer.size();
19411 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
19412 if (rc != TPM_RC_SUCCESS) {
19413 return rc;
19414 }
19415 if (parameter_section_size > buffer.size()) {
19416 return TPM_RC_INSUFFICIENT;
19417 }
19418 authorization_section_bytes = buffer.substr(parameter_section_size);
19419 // Keep the parameter section in |buffer|.
19420 buffer.erase(parameter_section_size);
19421 }
19422 std::unique_ptr<crypto::SecureHash> hash(
19423 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19424 hash->Update(response_code_bytes.data(), response_code_bytes.size());
19425 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19426 hash->Update(buffer.data(), buffer.size());
19427 std::string response_hash(32, 0);
19428 hash->Finish(std::data(response_hash), response_hash.size());
19429 if (tag == TPM_ST_SESSIONS) {
19430 if (!authorization_delegate)
19431 return TRUNKS_RC_AUTHORIZATION_FAILED;
19432 if (!authorization_delegate->CheckResponseAuthorization(
19433 response_hash, authorization_section_bytes)) {
19434 return TRUNKS_RC_AUTHORIZATION_FAILED;
19435 }
19436 }
19437 return TPM_RC_SUCCESS;
19438 }
19439
SetCommandCodeAuditStatusErrorCallback(Tpm::SetCommandCodeAuditStatusResponse callback,TPM_RC response_code)19440 void SetCommandCodeAuditStatusErrorCallback(
19441 Tpm::SetCommandCodeAuditStatusResponse callback, TPM_RC response_code) {
19442 VLOG(1) << __func__;
19443 std::move(callback).Run(response_code);
19444 }
19445
SetCommandCodeAuditStatusResponseParser(Tpm::SetCommandCodeAuditStatusResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19446 void SetCommandCodeAuditStatusResponseParser(
19447 Tpm::SetCommandCodeAuditStatusResponse callback,
19448 AuthorizationDelegate* authorization_delegate,
19449 const std::string& response) {
19450 VLOG(1) << __func__;
19451 TPM_RC rc = Tpm::ParseResponse_SetCommandCodeAuditStatus(
19452 response, authorization_delegate);
19453 if (rc != TPM_RC_SUCCESS) {
19454 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
19455 SetCommandCodeAuditStatusErrorCallback, std::move(callback));
19456 std::move(error_reporter).Run(rc);
19457 return;
19458 }
19459 std::move(callback).Run(rc);
19460 }
19461
SetCommandCodeAuditStatus(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_ALG_HASH & audit_alg,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate,SetCommandCodeAuditStatusResponse callback)19462 void Tpm::SetCommandCodeAuditStatus(
19463 const TPMI_RH_PROVISION& auth,
19464 const std::string& auth_name,
19465 const TPMI_ALG_HASH& audit_alg,
19466 const TPML_CC& set_list,
19467 const TPML_CC& clear_list,
19468 AuthorizationDelegate* authorization_delegate,
19469 SetCommandCodeAuditStatusResponse callback) {
19470 VLOG(1) << __func__;
19471 std::string command;
19472 TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus(
19473 auth, auth_name, audit_alg, set_list, clear_list, &command,
19474 authorization_delegate);
19475 if (rc != TPM_RC_SUCCESS) {
19476 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
19477 SetCommandCodeAuditStatusErrorCallback, std::move(callback));
19478 std::move(error_reporter).Run(rc);
19479 return;
19480 }
19481 base::OnceCallback<void(const std::string&)> parser =
19482 base::BindOnce(SetCommandCodeAuditStatusResponseParser,
19483 std::move(callback), authorization_delegate);
19484 transceiver_->SendCommand(command, std::move(parser));
19485 }
19486
SetCommandCodeAuditStatusSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_ALG_HASH & audit_alg,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate)19487 TPM_RC Tpm::SetCommandCodeAuditStatusSync(
19488 const TPMI_RH_PROVISION& auth,
19489 const std::string& auth_name,
19490 const TPMI_ALG_HASH& audit_alg,
19491 const TPML_CC& set_list,
19492 const TPML_CC& clear_list,
19493 AuthorizationDelegate* authorization_delegate) {
19494 VLOG(1) << __func__;
19495 std::string command;
19496 TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus(
19497 auth, auth_name, audit_alg, set_list, clear_list, &command,
19498 authorization_delegate);
19499 if (rc != TPM_RC_SUCCESS) {
19500 return rc;
19501 }
19502 std::string response = transceiver_->SendCommandAndWait(command);
19503 rc =
19504 ParseResponse_SetCommandCodeAuditStatus(response, authorization_delegate);
19505 return rc;
19506 }
19507
SerializeCommand_PCR_Extend(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPML_DIGEST_VALUES & digests,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19508 TPM_RC Tpm::SerializeCommand_PCR_Extend(
19509 const TPMI_DH_PCR& pcr_handle,
19510 const std::string& pcr_handle_name,
19511 const TPML_DIGEST_VALUES& digests,
19512 std::string* serialized_command,
19513 AuthorizationDelegate* authorization_delegate) {
19514 VLOG(3) << __func__;
19515 TPM_RC rc = TPM_RC_SUCCESS;
19516 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19517 UINT32 command_size = 10; // Header size.
19518 std::string handle_section_bytes;
19519 std::string parameter_section_bytes;
19520 TPM_CC command_code = TPM_CC_PCR_Extend;
19521 bool is_command_parameter_encryption_possible = false;
19522 bool is_response_parameter_encryption_possible = false;
19523 std::string command_code_bytes;
19524 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19525 if (rc != TPM_RC_SUCCESS) {
19526 return rc;
19527 }
19528 std::string pcr_handle_bytes;
19529 rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
19530 if (rc != TPM_RC_SUCCESS) {
19531 return rc;
19532 }
19533 std::string digests_bytes;
19534 rc = Serialize_TPML_DIGEST_VALUES(digests, &digests_bytes);
19535 if (rc != TPM_RC_SUCCESS) {
19536 return rc;
19537 }
19538 std::unique_ptr<crypto::SecureHash> hash(
19539 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19540 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19541 hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
19542 handle_section_bytes += pcr_handle_bytes;
19543 command_size += pcr_handle_bytes.size();
19544 hash->Update(digests_bytes.data(), digests_bytes.size());
19545 parameter_section_bytes += digests_bytes;
19546 command_size += digests_bytes.size();
19547 std::string command_hash(32, 0);
19548 hash->Finish(std::data(command_hash), command_hash.size());
19549 std::string authorization_section_bytes;
19550 std::string authorization_size_bytes;
19551 if (authorization_delegate) {
19552 if (!authorization_delegate->GetCommandAuthorization(
19553 command_hash, is_command_parameter_encryption_possible,
19554 is_response_parameter_encryption_possible,
19555 &authorization_section_bytes)) {
19556 return TRUNKS_RC_AUTHORIZATION_FAILED;
19557 }
19558 if (!authorization_section_bytes.empty()) {
19559 tag = TPM_ST_SESSIONS;
19560 std::string tmp;
19561 rc = Serialize_UINT32(authorization_section_bytes.size(),
19562 &authorization_size_bytes);
19563 if (rc != TPM_RC_SUCCESS) {
19564 return rc;
19565 }
19566 command_size +=
19567 authorization_size_bytes.size() + authorization_section_bytes.size();
19568 }
19569 }
19570 std::string tag_bytes;
19571 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19572 if (rc != TPM_RC_SUCCESS) {
19573 return rc;
19574 }
19575 std::string command_size_bytes;
19576 rc = Serialize_UINT32(command_size, &command_size_bytes);
19577 if (rc != TPM_RC_SUCCESS) {
19578 return rc;
19579 }
19580 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19581 handle_section_bytes + authorization_size_bytes +
19582 authorization_section_bytes + parameter_section_bytes;
19583 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19584 VLOG(2) << "Command: "
19585 << base::HexEncode(serialized_command->data(),
19586 serialized_command->size());
19587 return TPM_RC_SUCCESS;
19588 }
19589
ParseResponse_PCR_Extend(const std::string & response,AuthorizationDelegate * authorization_delegate)19590 TPM_RC Tpm::ParseResponse_PCR_Extend(
19591 const std::string& response,
19592 AuthorizationDelegate* authorization_delegate) {
19593 VLOG(3) << __func__;
19594 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19595 TPM_RC rc = TPM_RC_SUCCESS;
19596 std::string buffer(response);
19597 TPM_ST tag;
19598 std::string tag_bytes;
19599 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19600 if (rc != TPM_RC_SUCCESS) {
19601 return rc;
19602 }
19603 UINT32 response_size;
19604 std::string response_size_bytes;
19605 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19606 if (rc != TPM_RC_SUCCESS) {
19607 return rc;
19608 }
19609 TPM_RC response_code;
19610 std::string response_code_bytes;
19611 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19612 if (rc != TPM_RC_SUCCESS) {
19613 return rc;
19614 }
19615 if (response_size != response.size()) {
19616 return TPM_RC_SIZE;
19617 }
19618 if (response_code != TPM_RC_SUCCESS) {
19619 return response_code;
19620 }
19621 TPM_CC command_code = TPM_CC_PCR_Extend;
19622 std::string command_code_bytes;
19623 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19624 if (rc != TPM_RC_SUCCESS) {
19625 return rc;
19626 }
19627 std::string authorization_section_bytes;
19628 if (tag == TPM_ST_SESSIONS) {
19629 UINT32 parameter_section_size = buffer.size();
19630 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
19631 if (rc != TPM_RC_SUCCESS) {
19632 return rc;
19633 }
19634 if (parameter_section_size > buffer.size()) {
19635 return TPM_RC_INSUFFICIENT;
19636 }
19637 authorization_section_bytes = buffer.substr(parameter_section_size);
19638 // Keep the parameter section in |buffer|.
19639 buffer.erase(parameter_section_size);
19640 }
19641 std::unique_ptr<crypto::SecureHash> hash(
19642 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19643 hash->Update(response_code_bytes.data(), response_code_bytes.size());
19644 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19645 hash->Update(buffer.data(), buffer.size());
19646 std::string response_hash(32, 0);
19647 hash->Finish(std::data(response_hash), response_hash.size());
19648 if (tag == TPM_ST_SESSIONS) {
19649 if (!authorization_delegate)
19650 return TRUNKS_RC_AUTHORIZATION_FAILED;
19651 if (!authorization_delegate->CheckResponseAuthorization(
19652 response_hash, authorization_section_bytes)) {
19653 return TRUNKS_RC_AUTHORIZATION_FAILED;
19654 }
19655 }
19656 return TPM_RC_SUCCESS;
19657 }
19658
PCR_ExtendErrorCallback(Tpm::PCR_ExtendResponse callback,TPM_RC response_code)19659 void PCR_ExtendErrorCallback(Tpm::PCR_ExtendResponse callback,
19660 TPM_RC response_code) {
19661 VLOG(1) << __func__;
19662 std::move(callback).Run(response_code);
19663 }
19664
PCR_ExtendResponseParser(Tpm::PCR_ExtendResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19665 void PCR_ExtendResponseParser(Tpm::PCR_ExtendResponse callback,
19666 AuthorizationDelegate* authorization_delegate,
19667 const std::string& response) {
19668 VLOG(1) << __func__;
19669 TPM_RC rc = Tpm::ParseResponse_PCR_Extend(response, authorization_delegate);
19670 if (rc != TPM_RC_SUCCESS) {
19671 base::OnceCallback<void(TPM_RC)> error_reporter =
19672 base::BindOnce(PCR_ExtendErrorCallback, std::move(callback));
19673 std::move(error_reporter).Run(rc);
19674 return;
19675 }
19676 std::move(callback).Run(rc);
19677 }
19678
PCR_Extend(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPML_DIGEST_VALUES & digests,AuthorizationDelegate * authorization_delegate,PCR_ExtendResponse callback)19679 void Tpm::PCR_Extend(const TPMI_DH_PCR& pcr_handle,
19680 const std::string& pcr_handle_name,
19681 const TPML_DIGEST_VALUES& digests,
19682 AuthorizationDelegate* authorization_delegate,
19683 PCR_ExtendResponse callback) {
19684 VLOG(1) << __func__;
19685 std::string command;
19686 TPM_RC rc = SerializeCommand_PCR_Extend(pcr_handle, pcr_handle_name, digests,
19687 &command, authorization_delegate);
19688 if (rc != TPM_RC_SUCCESS) {
19689 base::OnceCallback<void(TPM_RC)> error_reporter =
19690 base::BindOnce(PCR_ExtendErrorCallback, std::move(callback));
19691 std::move(error_reporter).Run(rc);
19692 return;
19693 }
19694 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19695 PCR_ExtendResponseParser, std::move(callback), authorization_delegate);
19696 transceiver_->SendCommand(command, std::move(parser));
19697 }
19698
PCR_ExtendSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPML_DIGEST_VALUES & digests,AuthorizationDelegate * authorization_delegate)19699 TPM_RC Tpm::PCR_ExtendSync(const TPMI_DH_PCR& pcr_handle,
19700 const std::string& pcr_handle_name,
19701 const TPML_DIGEST_VALUES& digests,
19702 AuthorizationDelegate* authorization_delegate) {
19703 VLOG(1) << __func__;
19704 std::string command;
19705 TPM_RC rc = SerializeCommand_PCR_Extend(pcr_handle, pcr_handle_name, digests,
19706 &command, authorization_delegate);
19707 if (rc != TPM_RC_SUCCESS) {
19708 return rc;
19709 }
19710 std::string response = transceiver_->SendCommandAndWait(command);
19711 rc = ParseResponse_PCR_Extend(response, authorization_delegate);
19712 return rc;
19713 }
19714
SerializeCommand_PCR_Event(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_EVENT & event_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19715 TPM_RC Tpm::SerializeCommand_PCR_Event(
19716 const TPMI_DH_PCR& pcr_handle,
19717 const std::string& pcr_handle_name,
19718 const TPM2B_EVENT& event_data,
19719 std::string* serialized_command,
19720 AuthorizationDelegate* authorization_delegate) {
19721 VLOG(3) << __func__;
19722 TPM_RC rc = TPM_RC_SUCCESS;
19723 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19724 UINT32 command_size = 10; // Header size.
19725 std::string handle_section_bytes;
19726 std::string parameter_section_bytes;
19727 TPM_CC command_code = TPM_CC_PCR_Event;
19728 bool is_command_parameter_encryption_possible = true;
19729 bool is_response_parameter_encryption_possible = false;
19730 std::string command_code_bytes;
19731 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19732 if (rc != TPM_RC_SUCCESS) {
19733 return rc;
19734 }
19735 std::string pcr_handle_bytes;
19736 rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
19737 if (rc != TPM_RC_SUCCESS) {
19738 return rc;
19739 }
19740 std::string event_data_bytes;
19741 rc = Serialize_TPM2B_EVENT(event_data, &event_data_bytes);
19742 if (rc != TPM_RC_SUCCESS) {
19743 return rc;
19744 }
19745 if (authorization_delegate) {
19746 // Encrypt just the parameter data, not the size.
19747 std::string tmp = event_data_bytes.substr(2);
19748 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
19749 return TRUNKS_RC_ENCRYPTION_FAILED;
19750 }
19751 event_data_bytes.replace(2, std::string::npos, tmp);
19752 }
19753 std::unique_ptr<crypto::SecureHash> hash(
19754 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19755 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19756 hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
19757 handle_section_bytes += pcr_handle_bytes;
19758 command_size += pcr_handle_bytes.size();
19759 hash->Update(event_data_bytes.data(), event_data_bytes.size());
19760 parameter_section_bytes += event_data_bytes;
19761 command_size += event_data_bytes.size();
19762 std::string command_hash(32, 0);
19763 hash->Finish(std::data(command_hash), command_hash.size());
19764 std::string authorization_section_bytes;
19765 std::string authorization_size_bytes;
19766 if (authorization_delegate) {
19767 if (!authorization_delegate->GetCommandAuthorization(
19768 command_hash, is_command_parameter_encryption_possible,
19769 is_response_parameter_encryption_possible,
19770 &authorization_section_bytes)) {
19771 return TRUNKS_RC_AUTHORIZATION_FAILED;
19772 }
19773 if (!authorization_section_bytes.empty()) {
19774 tag = TPM_ST_SESSIONS;
19775 std::string tmp;
19776 rc = Serialize_UINT32(authorization_section_bytes.size(),
19777 &authorization_size_bytes);
19778 if (rc != TPM_RC_SUCCESS) {
19779 return rc;
19780 }
19781 command_size +=
19782 authorization_size_bytes.size() + authorization_section_bytes.size();
19783 }
19784 }
19785 std::string tag_bytes;
19786 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19787 if (rc != TPM_RC_SUCCESS) {
19788 return rc;
19789 }
19790 std::string command_size_bytes;
19791 rc = Serialize_UINT32(command_size, &command_size_bytes);
19792 if (rc != TPM_RC_SUCCESS) {
19793 return rc;
19794 }
19795 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19796 handle_section_bytes + authorization_size_bytes +
19797 authorization_section_bytes + parameter_section_bytes;
19798 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19799 VLOG(2) << "Command: "
19800 << base::HexEncode(serialized_command->data(),
19801 serialized_command->size());
19802 return TPM_RC_SUCCESS;
19803 }
19804
ParseResponse_PCR_Event(const std::string & response,TPML_DIGEST_VALUES * digests,AuthorizationDelegate * authorization_delegate)19805 TPM_RC Tpm::ParseResponse_PCR_Event(
19806 const std::string& response,
19807 TPML_DIGEST_VALUES* digests,
19808 AuthorizationDelegate* authorization_delegate) {
19809 VLOG(3) << __func__;
19810 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19811 TPM_RC rc = TPM_RC_SUCCESS;
19812 std::string buffer(response);
19813 TPM_ST tag;
19814 std::string tag_bytes;
19815 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19816 if (rc != TPM_RC_SUCCESS) {
19817 return rc;
19818 }
19819 UINT32 response_size;
19820 std::string response_size_bytes;
19821 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19822 if (rc != TPM_RC_SUCCESS) {
19823 return rc;
19824 }
19825 TPM_RC response_code;
19826 std::string response_code_bytes;
19827 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19828 if (rc != TPM_RC_SUCCESS) {
19829 return rc;
19830 }
19831 if (response_size != response.size()) {
19832 return TPM_RC_SIZE;
19833 }
19834 if (response_code != TPM_RC_SUCCESS) {
19835 return response_code;
19836 }
19837 TPM_CC command_code = TPM_CC_PCR_Event;
19838 std::string command_code_bytes;
19839 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19840 if (rc != TPM_RC_SUCCESS) {
19841 return rc;
19842 }
19843 std::string authorization_section_bytes;
19844 if (tag == TPM_ST_SESSIONS) {
19845 UINT32 parameter_section_size = buffer.size();
19846 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
19847 if (rc != TPM_RC_SUCCESS) {
19848 return rc;
19849 }
19850 if (parameter_section_size > buffer.size()) {
19851 return TPM_RC_INSUFFICIENT;
19852 }
19853 authorization_section_bytes = buffer.substr(parameter_section_size);
19854 // Keep the parameter section in |buffer|.
19855 buffer.erase(parameter_section_size);
19856 }
19857 std::unique_ptr<crypto::SecureHash> hash(
19858 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19859 hash->Update(response_code_bytes.data(), response_code_bytes.size());
19860 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19861 hash->Update(buffer.data(), buffer.size());
19862 std::string response_hash(32, 0);
19863 hash->Finish(std::data(response_hash), response_hash.size());
19864 if (tag == TPM_ST_SESSIONS) {
19865 if (!authorization_delegate)
19866 return TRUNKS_RC_AUTHORIZATION_FAILED;
19867 if (!authorization_delegate->CheckResponseAuthorization(
19868 response_hash, authorization_section_bytes)) {
19869 return TRUNKS_RC_AUTHORIZATION_FAILED;
19870 }
19871 }
19872 std::string digests_bytes;
19873 rc = Parse_TPML_DIGEST_VALUES(&buffer, digests, &digests_bytes);
19874 if (rc != TPM_RC_SUCCESS) {
19875 return rc;
19876 }
19877 return TPM_RC_SUCCESS;
19878 }
19879
PCR_EventErrorCallback(Tpm::PCR_EventResponse callback,TPM_RC response_code)19880 void PCR_EventErrorCallback(Tpm::PCR_EventResponse callback,
19881 TPM_RC response_code) {
19882 VLOG(1) << __func__;
19883 std::move(callback).Run(response_code, TPML_DIGEST_VALUES());
19884 }
19885
PCR_EventResponseParser(Tpm::PCR_EventResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19886 void PCR_EventResponseParser(Tpm::PCR_EventResponse callback,
19887 AuthorizationDelegate* authorization_delegate,
19888 const std::string& response) {
19889 VLOG(1) << __func__;
19890 TPML_DIGEST_VALUES digests;
19891 TPM_RC rc =
19892 Tpm::ParseResponse_PCR_Event(response, &digests, authorization_delegate);
19893 if (rc != TPM_RC_SUCCESS) {
19894 base::OnceCallback<void(TPM_RC)> error_reporter =
19895 base::BindOnce(PCR_EventErrorCallback, std::move(callback));
19896 std::move(error_reporter).Run(rc);
19897 return;
19898 }
19899 std::move(callback).Run(rc, digests);
19900 }
19901
PCR_Event(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_EVENT & event_data,AuthorizationDelegate * authorization_delegate,PCR_EventResponse callback)19902 void Tpm::PCR_Event(const TPMI_DH_PCR& pcr_handle,
19903 const std::string& pcr_handle_name,
19904 const TPM2B_EVENT& event_data,
19905 AuthorizationDelegate* authorization_delegate,
19906 PCR_EventResponse callback) {
19907 VLOG(1) << __func__;
19908 std::string command;
19909 TPM_RC rc =
19910 SerializeCommand_PCR_Event(pcr_handle, pcr_handle_name, event_data,
19911 &command, authorization_delegate);
19912 if (rc != TPM_RC_SUCCESS) {
19913 base::OnceCallback<void(TPM_RC)> error_reporter =
19914 base::BindOnce(PCR_EventErrorCallback, std::move(callback));
19915 std::move(error_reporter).Run(rc);
19916 return;
19917 }
19918 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19919 PCR_EventResponseParser, std::move(callback), authorization_delegate);
19920 transceiver_->SendCommand(command, std::move(parser));
19921 }
19922
PCR_EventSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_EVENT & event_data,TPML_DIGEST_VALUES * digests,AuthorizationDelegate * authorization_delegate)19923 TPM_RC Tpm::PCR_EventSync(const TPMI_DH_PCR& pcr_handle,
19924 const std::string& pcr_handle_name,
19925 const TPM2B_EVENT& event_data,
19926 TPML_DIGEST_VALUES* digests,
19927 AuthorizationDelegate* authorization_delegate) {
19928 VLOG(1) << __func__;
19929 std::string command;
19930 TPM_RC rc =
19931 SerializeCommand_PCR_Event(pcr_handle, pcr_handle_name, event_data,
19932 &command, authorization_delegate);
19933 if (rc != TPM_RC_SUCCESS) {
19934 return rc;
19935 }
19936 std::string response = transceiver_->SendCommandAndWait(command);
19937 rc = ParseResponse_PCR_Event(response, digests, authorization_delegate);
19938 return rc;
19939 }
19940
SerializeCommand_PCR_Read(const TPML_PCR_SELECTION & pcr_selection_in,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19941 TPM_RC Tpm::SerializeCommand_PCR_Read(
19942 const TPML_PCR_SELECTION& pcr_selection_in,
19943 std::string* serialized_command,
19944 AuthorizationDelegate* authorization_delegate) {
19945 VLOG(3) << __func__;
19946 TPM_RC rc = TPM_RC_SUCCESS;
19947 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19948 UINT32 command_size = 10; // Header size.
19949 std::string handle_section_bytes;
19950 std::string parameter_section_bytes;
19951 TPM_CC command_code = TPM_CC_PCR_Read;
19952 bool is_command_parameter_encryption_possible = false;
19953 bool is_response_parameter_encryption_possible = false;
19954 std::string command_code_bytes;
19955 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19956 if (rc != TPM_RC_SUCCESS) {
19957 return rc;
19958 }
19959 std::string pcr_selection_in_bytes;
19960 rc = Serialize_TPML_PCR_SELECTION(pcr_selection_in, &pcr_selection_in_bytes);
19961 if (rc != TPM_RC_SUCCESS) {
19962 return rc;
19963 }
19964 std::unique_ptr<crypto::SecureHash> hash(
19965 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19966 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19967 hash->Update(pcr_selection_in_bytes.data(), pcr_selection_in_bytes.size());
19968 parameter_section_bytes += pcr_selection_in_bytes;
19969 command_size += pcr_selection_in_bytes.size();
19970 std::string command_hash(32, 0);
19971 hash->Finish(std::data(command_hash), command_hash.size());
19972 std::string authorization_section_bytes;
19973 std::string authorization_size_bytes;
19974 if (authorization_delegate) {
19975 if (!authorization_delegate->GetCommandAuthorization(
19976 command_hash, is_command_parameter_encryption_possible,
19977 is_response_parameter_encryption_possible,
19978 &authorization_section_bytes)) {
19979 return TRUNKS_RC_AUTHORIZATION_FAILED;
19980 }
19981 if (!authorization_section_bytes.empty()) {
19982 tag = TPM_ST_SESSIONS;
19983 std::string tmp;
19984 rc = Serialize_UINT32(authorization_section_bytes.size(),
19985 &authorization_size_bytes);
19986 if (rc != TPM_RC_SUCCESS) {
19987 return rc;
19988 }
19989 command_size +=
19990 authorization_size_bytes.size() + authorization_section_bytes.size();
19991 }
19992 }
19993 std::string tag_bytes;
19994 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19995 if (rc != TPM_RC_SUCCESS) {
19996 return rc;
19997 }
19998 std::string command_size_bytes;
19999 rc = Serialize_UINT32(command_size, &command_size_bytes);
20000 if (rc != TPM_RC_SUCCESS) {
20001 return rc;
20002 }
20003 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20004 handle_section_bytes + authorization_size_bytes +
20005 authorization_section_bytes + parameter_section_bytes;
20006 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20007 VLOG(2) << "Command: "
20008 << base::HexEncode(serialized_command->data(),
20009 serialized_command->size());
20010 return TPM_RC_SUCCESS;
20011 }
20012
ParseResponse_PCR_Read(const std::string & response,UINT32 * pcr_update_counter,TPML_PCR_SELECTION * pcr_selection_out,TPML_DIGEST * pcr_values,AuthorizationDelegate * authorization_delegate)20013 TPM_RC Tpm::ParseResponse_PCR_Read(
20014 const std::string& response,
20015 UINT32* pcr_update_counter,
20016 TPML_PCR_SELECTION* pcr_selection_out,
20017 TPML_DIGEST* pcr_values,
20018 AuthorizationDelegate* authorization_delegate) {
20019 VLOG(3) << __func__;
20020 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20021 TPM_RC rc = TPM_RC_SUCCESS;
20022 std::string buffer(response);
20023 TPM_ST tag;
20024 std::string tag_bytes;
20025 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20026 if (rc != TPM_RC_SUCCESS) {
20027 return rc;
20028 }
20029 UINT32 response_size;
20030 std::string response_size_bytes;
20031 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20032 if (rc != TPM_RC_SUCCESS) {
20033 return rc;
20034 }
20035 TPM_RC response_code;
20036 std::string response_code_bytes;
20037 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20038 if (rc != TPM_RC_SUCCESS) {
20039 return rc;
20040 }
20041 if (response_size != response.size()) {
20042 return TPM_RC_SIZE;
20043 }
20044 if (response_code != TPM_RC_SUCCESS) {
20045 return response_code;
20046 }
20047 TPM_CC command_code = TPM_CC_PCR_Read;
20048 std::string command_code_bytes;
20049 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20050 if (rc != TPM_RC_SUCCESS) {
20051 return rc;
20052 }
20053 std::string authorization_section_bytes;
20054 if (tag == TPM_ST_SESSIONS) {
20055 UINT32 parameter_section_size = buffer.size();
20056 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
20057 if (rc != TPM_RC_SUCCESS) {
20058 return rc;
20059 }
20060 if (parameter_section_size > buffer.size()) {
20061 return TPM_RC_INSUFFICIENT;
20062 }
20063 authorization_section_bytes = buffer.substr(parameter_section_size);
20064 // Keep the parameter section in |buffer|.
20065 buffer.erase(parameter_section_size);
20066 }
20067 std::unique_ptr<crypto::SecureHash> hash(
20068 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20069 hash->Update(response_code_bytes.data(), response_code_bytes.size());
20070 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20071 hash->Update(buffer.data(), buffer.size());
20072 std::string response_hash(32, 0);
20073 hash->Finish(std::data(response_hash), response_hash.size());
20074 if (tag == TPM_ST_SESSIONS) {
20075 if (!authorization_delegate)
20076 return TRUNKS_RC_AUTHORIZATION_FAILED;
20077 if (!authorization_delegate->CheckResponseAuthorization(
20078 response_hash, authorization_section_bytes)) {
20079 return TRUNKS_RC_AUTHORIZATION_FAILED;
20080 }
20081 }
20082 std::string pcr_update_counter_bytes;
20083 rc = Parse_UINT32(&buffer, pcr_update_counter, &pcr_update_counter_bytes);
20084 if (rc != TPM_RC_SUCCESS) {
20085 return rc;
20086 }
20087 std::string pcr_selection_out_bytes;
20088 rc = Parse_TPML_PCR_SELECTION(&buffer, pcr_selection_out,
20089 &pcr_selection_out_bytes);
20090 if (rc != TPM_RC_SUCCESS) {
20091 return rc;
20092 }
20093 std::string pcr_values_bytes;
20094 rc = Parse_TPML_DIGEST(&buffer, pcr_values, &pcr_values_bytes);
20095 if (rc != TPM_RC_SUCCESS) {
20096 return rc;
20097 }
20098 return TPM_RC_SUCCESS;
20099 }
20100
PCR_ReadErrorCallback(Tpm::PCR_ReadResponse callback,TPM_RC response_code)20101 void PCR_ReadErrorCallback(Tpm::PCR_ReadResponse callback,
20102 TPM_RC response_code) {
20103 VLOG(1) << __func__;
20104 std::move(callback).Run(response_code, UINT32(), TPML_PCR_SELECTION(),
20105 TPML_DIGEST());
20106 }
20107
PCR_ReadResponseParser(Tpm::PCR_ReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20108 void PCR_ReadResponseParser(Tpm::PCR_ReadResponse callback,
20109 AuthorizationDelegate* authorization_delegate,
20110 const std::string& response) {
20111 VLOG(1) << __func__;
20112 UINT32 pcr_update_counter;
20113 TPML_PCR_SELECTION pcr_selection_out;
20114 TPML_DIGEST pcr_values;
20115 TPM_RC rc = Tpm::ParseResponse_PCR_Read(response, &pcr_update_counter,
20116 &pcr_selection_out, &pcr_values,
20117 authorization_delegate);
20118 if (rc != TPM_RC_SUCCESS) {
20119 base::OnceCallback<void(TPM_RC)> error_reporter =
20120 base::BindOnce(PCR_ReadErrorCallback, std::move(callback));
20121 std::move(error_reporter).Run(rc);
20122 return;
20123 }
20124 std::move(callback).Run(rc, pcr_update_counter, pcr_selection_out,
20125 pcr_values);
20126 }
20127
PCR_Read(const TPML_PCR_SELECTION & pcr_selection_in,AuthorizationDelegate * authorization_delegate,PCR_ReadResponse callback)20128 void Tpm::PCR_Read(const TPML_PCR_SELECTION& pcr_selection_in,
20129 AuthorizationDelegate* authorization_delegate,
20130 PCR_ReadResponse callback) {
20131 VLOG(1) << __func__;
20132 std::string command;
20133 TPM_RC rc = SerializeCommand_PCR_Read(pcr_selection_in, &command,
20134 authorization_delegate);
20135 if (rc != TPM_RC_SUCCESS) {
20136 base::OnceCallback<void(TPM_RC)> error_reporter =
20137 base::BindOnce(PCR_ReadErrorCallback, std::move(callback));
20138 std::move(error_reporter).Run(rc);
20139 return;
20140 }
20141 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
20142 PCR_ReadResponseParser, std::move(callback), authorization_delegate);
20143 transceiver_->SendCommand(command, std::move(parser));
20144 }
20145
PCR_ReadSync(const TPML_PCR_SELECTION & pcr_selection_in,UINT32 * pcr_update_counter,TPML_PCR_SELECTION * pcr_selection_out,TPML_DIGEST * pcr_values,AuthorizationDelegate * authorization_delegate)20146 TPM_RC Tpm::PCR_ReadSync(const TPML_PCR_SELECTION& pcr_selection_in,
20147 UINT32* pcr_update_counter,
20148 TPML_PCR_SELECTION* pcr_selection_out,
20149 TPML_DIGEST* pcr_values,
20150 AuthorizationDelegate* authorization_delegate) {
20151 VLOG(1) << __func__;
20152 std::string command;
20153 TPM_RC rc = SerializeCommand_PCR_Read(pcr_selection_in, &command,
20154 authorization_delegate);
20155 if (rc != TPM_RC_SUCCESS) {
20156 return rc;
20157 }
20158 std::string response = transceiver_->SendCommandAndWait(command);
20159 rc = ParseResponse_PCR_Read(response, pcr_update_counter, pcr_selection_out,
20160 pcr_values, authorization_delegate);
20161 return rc;
20162 }
20163
SerializeCommand_PCR_Allocate(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPML_PCR_SELECTION & pcr_allocation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20164 TPM_RC Tpm::SerializeCommand_PCR_Allocate(
20165 const TPMI_RH_PLATFORM& auth_handle,
20166 const std::string& auth_handle_name,
20167 const TPML_PCR_SELECTION& pcr_allocation,
20168 std::string* serialized_command,
20169 AuthorizationDelegate* authorization_delegate) {
20170 VLOG(3) << __func__;
20171 TPM_RC rc = TPM_RC_SUCCESS;
20172 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20173 UINT32 command_size = 10; // Header size.
20174 std::string handle_section_bytes;
20175 std::string parameter_section_bytes;
20176 TPM_CC command_code = TPM_CC_PCR_Allocate;
20177 bool is_command_parameter_encryption_possible = false;
20178 bool is_response_parameter_encryption_possible = false;
20179 std::string command_code_bytes;
20180 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20181 if (rc != TPM_RC_SUCCESS) {
20182 return rc;
20183 }
20184 std::string auth_handle_bytes;
20185 rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
20186 if (rc != TPM_RC_SUCCESS) {
20187 return rc;
20188 }
20189 std::string pcr_allocation_bytes;
20190 rc = Serialize_TPML_PCR_SELECTION(pcr_allocation, &pcr_allocation_bytes);
20191 if (rc != TPM_RC_SUCCESS) {
20192 return rc;
20193 }
20194 std::unique_ptr<crypto::SecureHash> hash(
20195 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20196 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20197 hash->Update(auth_handle_name.data(), auth_handle_name.size());
20198 handle_section_bytes += auth_handle_bytes;
20199 command_size += auth_handle_bytes.size();
20200 hash->Update(pcr_allocation_bytes.data(), pcr_allocation_bytes.size());
20201 parameter_section_bytes += pcr_allocation_bytes;
20202 command_size += pcr_allocation_bytes.size();
20203 std::string command_hash(32, 0);
20204 hash->Finish(std::data(command_hash), command_hash.size());
20205 std::string authorization_section_bytes;
20206 std::string authorization_size_bytes;
20207 if (authorization_delegate) {
20208 if (!authorization_delegate->GetCommandAuthorization(
20209 command_hash, is_command_parameter_encryption_possible,
20210 is_response_parameter_encryption_possible,
20211 &authorization_section_bytes)) {
20212 return TRUNKS_RC_AUTHORIZATION_FAILED;
20213 }
20214 if (!authorization_section_bytes.empty()) {
20215 tag = TPM_ST_SESSIONS;
20216 std::string tmp;
20217 rc = Serialize_UINT32(authorization_section_bytes.size(),
20218 &authorization_size_bytes);
20219 if (rc != TPM_RC_SUCCESS) {
20220 return rc;
20221 }
20222 command_size +=
20223 authorization_size_bytes.size() + authorization_section_bytes.size();
20224 }
20225 }
20226 std::string tag_bytes;
20227 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20228 if (rc != TPM_RC_SUCCESS) {
20229 return rc;
20230 }
20231 std::string command_size_bytes;
20232 rc = Serialize_UINT32(command_size, &command_size_bytes);
20233 if (rc != TPM_RC_SUCCESS) {
20234 return rc;
20235 }
20236 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20237 handle_section_bytes + authorization_size_bytes +
20238 authorization_section_bytes + parameter_section_bytes;
20239 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20240 VLOG(2) << "Command: "
20241 << base::HexEncode(serialized_command->data(),
20242 serialized_command->size());
20243 return TPM_RC_SUCCESS;
20244 }
20245
ParseResponse_PCR_Allocate(const std::string & response,TPMI_YES_NO * allocation_success,UINT32 * max_pcr,UINT32 * size_needed,UINT32 * size_available,AuthorizationDelegate * authorization_delegate)20246 TPM_RC Tpm::ParseResponse_PCR_Allocate(
20247 const std::string& response,
20248 TPMI_YES_NO* allocation_success,
20249 UINT32* max_pcr,
20250 UINT32* size_needed,
20251 UINT32* size_available,
20252 AuthorizationDelegate* authorization_delegate) {
20253 VLOG(3) << __func__;
20254 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20255 TPM_RC rc = TPM_RC_SUCCESS;
20256 std::string buffer(response);
20257 TPM_ST tag;
20258 std::string tag_bytes;
20259 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20260 if (rc != TPM_RC_SUCCESS) {
20261 return rc;
20262 }
20263 UINT32 response_size;
20264 std::string response_size_bytes;
20265 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20266 if (rc != TPM_RC_SUCCESS) {
20267 return rc;
20268 }
20269 TPM_RC response_code;
20270 std::string response_code_bytes;
20271 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20272 if (rc != TPM_RC_SUCCESS) {
20273 return rc;
20274 }
20275 if (response_size != response.size()) {
20276 return TPM_RC_SIZE;
20277 }
20278 if (response_code != TPM_RC_SUCCESS) {
20279 return response_code;
20280 }
20281 TPM_CC command_code = TPM_CC_PCR_Allocate;
20282 std::string command_code_bytes;
20283 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20284 if (rc != TPM_RC_SUCCESS) {
20285 return rc;
20286 }
20287 std::string authorization_section_bytes;
20288 if (tag == TPM_ST_SESSIONS) {
20289 UINT32 parameter_section_size = buffer.size();
20290 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
20291 if (rc != TPM_RC_SUCCESS) {
20292 return rc;
20293 }
20294 if (parameter_section_size > buffer.size()) {
20295 return TPM_RC_INSUFFICIENT;
20296 }
20297 authorization_section_bytes = buffer.substr(parameter_section_size);
20298 // Keep the parameter section in |buffer|.
20299 buffer.erase(parameter_section_size);
20300 }
20301 std::unique_ptr<crypto::SecureHash> hash(
20302 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20303 hash->Update(response_code_bytes.data(), response_code_bytes.size());
20304 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20305 hash->Update(buffer.data(), buffer.size());
20306 std::string response_hash(32, 0);
20307 hash->Finish(std::data(response_hash), response_hash.size());
20308 if (tag == TPM_ST_SESSIONS) {
20309 if (!authorization_delegate)
20310 return TRUNKS_RC_AUTHORIZATION_FAILED;
20311 if (!authorization_delegate->CheckResponseAuthorization(
20312 response_hash, authorization_section_bytes)) {
20313 return TRUNKS_RC_AUTHORIZATION_FAILED;
20314 }
20315 }
20316 std::string allocation_success_bytes;
20317 rc =
20318 Parse_TPMI_YES_NO(&buffer, allocation_success, &allocation_success_bytes);
20319 if (rc != TPM_RC_SUCCESS) {
20320 return rc;
20321 }
20322 std::string max_pcr_bytes;
20323 rc = Parse_UINT32(&buffer, max_pcr, &max_pcr_bytes);
20324 if (rc != TPM_RC_SUCCESS) {
20325 return rc;
20326 }
20327 std::string size_needed_bytes;
20328 rc = Parse_UINT32(&buffer, size_needed, &size_needed_bytes);
20329 if (rc != TPM_RC_SUCCESS) {
20330 return rc;
20331 }
20332 std::string size_available_bytes;
20333 rc = Parse_UINT32(&buffer, size_available, &size_available_bytes);
20334 if (rc != TPM_RC_SUCCESS) {
20335 return rc;
20336 }
20337 return TPM_RC_SUCCESS;
20338 }
20339
PCR_AllocateErrorCallback(Tpm::PCR_AllocateResponse callback,TPM_RC response_code)20340 void PCR_AllocateErrorCallback(Tpm::PCR_AllocateResponse callback,
20341 TPM_RC response_code) {
20342 VLOG(1) << __func__;
20343 std::move(callback).Run(response_code, TPMI_YES_NO(), UINT32(), UINT32(),
20344 UINT32());
20345 }
20346
PCR_AllocateResponseParser(Tpm::PCR_AllocateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20347 void PCR_AllocateResponseParser(Tpm::PCR_AllocateResponse callback,
20348 AuthorizationDelegate* authorization_delegate,
20349 const std::string& response) {
20350 VLOG(1) << __func__;
20351 TPMI_YES_NO allocation_success;
20352 UINT32 max_pcr;
20353 UINT32 size_needed;
20354 UINT32 size_available;
20355 TPM_RC rc = Tpm::ParseResponse_PCR_Allocate(
20356 response, &allocation_success, &max_pcr, &size_needed, &size_available,
20357 authorization_delegate);
20358 if (rc != TPM_RC_SUCCESS) {
20359 base::OnceCallback<void(TPM_RC)> error_reporter =
20360 base::BindOnce(PCR_AllocateErrorCallback, std::move(callback));
20361 std::move(error_reporter).Run(rc);
20362 return;
20363 }
20364 std::move(callback).Run(rc, allocation_success, max_pcr, size_needed,
20365 size_available);
20366 }
20367
PCR_Allocate(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPML_PCR_SELECTION & pcr_allocation,AuthorizationDelegate * authorization_delegate,PCR_AllocateResponse callback)20368 void Tpm::PCR_Allocate(const TPMI_RH_PLATFORM& auth_handle,
20369 const std::string& auth_handle_name,
20370 const TPML_PCR_SELECTION& pcr_allocation,
20371 AuthorizationDelegate* authorization_delegate,
20372 PCR_AllocateResponse callback) {
20373 VLOG(1) << __func__;
20374 std::string command;
20375 TPM_RC rc = SerializeCommand_PCR_Allocate(auth_handle, auth_handle_name,
20376 pcr_allocation, &command,
20377 authorization_delegate);
20378 if (rc != TPM_RC_SUCCESS) {
20379 base::OnceCallback<void(TPM_RC)> error_reporter =
20380 base::BindOnce(PCR_AllocateErrorCallback, std::move(callback));
20381 std::move(error_reporter).Run(rc);
20382 return;
20383 }
20384 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
20385 PCR_AllocateResponseParser, std::move(callback), authorization_delegate);
20386 transceiver_->SendCommand(command, std::move(parser));
20387 }
20388
PCR_AllocateSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPML_PCR_SELECTION & pcr_allocation,TPMI_YES_NO * allocation_success,UINT32 * max_pcr,UINT32 * size_needed,UINT32 * size_available,AuthorizationDelegate * authorization_delegate)20389 TPM_RC Tpm::PCR_AllocateSync(const TPMI_RH_PLATFORM& auth_handle,
20390 const std::string& auth_handle_name,
20391 const TPML_PCR_SELECTION& pcr_allocation,
20392 TPMI_YES_NO* allocation_success,
20393 UINT32* max_pcr,
20394 UINT32* size_needed,
20395 UINT32* size_available,
20396 AuthorizationDelegate* authorization_delegate) {
20397 VLOG(1) << __func__;
20398 std::string command;
20399 TPM_RC rc = SerializeCommand_PCR_Allocate(auth_handle, auth_handle_name,
20400 pcr_allocation, &command,
20401 authorization_delegate);
20402 if (rc != TPM_RC_SUCCESS) {
20403 return rc;
20404 }
20405 std::string response = transceiver_->SendCommandAndWait(command);
20406 rc = ParseResponse_PCR_Allocate(response, allocation_success, max_pcr,
20407 size_needed, size_available,
20408 authorization_delegate);
20409 return rc;
20410 }
20411
SerializeCommand_PCR_SetAuthPolicy(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPMI_DH_PCR & pcr_num,const std::string & pcr_num_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & policy_digest,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20412 TPM_RC Tpm::SerializeCommand_PCR_SetAuthPolicy(
20413 const TPMI_RH_PLATFORM& auth_handle,
20414 const std::string& auth_handle_name,
20415 const TPMI_DH_PCR& pcr_num,
20416 const std::string& pcr_num_name,
20417 const TPM2B_DIGEST& auth_policy,
20418 const TPMI_ALG_HASH& policy_digest,
20419 std::string* serialized_command,
20420 AuthorizationDelegate* authorization_delegate) {
20421 VLOG(3) << __func__;
20422 TPM_RC rc = TPM_RC_SUCCESS;
20423 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20424 UINT32 command_size = 10; // Header size.
20425 std::string handle_section_bytes;
20426 std::string parameter_section_bytes;
20427 TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy;
20428 bool is_command_parameter_encryption_possible = true;
20429 bool is_response_parameter_encryption_possible = false;
20430 std::string command_code_bytes;
20431 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20432 if (rc != TPM_RC_SUCCESS) {
20433 return rc;
20434 }
20435 std::string auth_handle_bytes;
20436 rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
20437 if (rc != TPM_RC_SUCCESS) {
20438 return rc;
20439 }
20440 std::string auth_policy_bytes;
20441 rc = Serialize_TPM2B_DIGEST(auth_policy, &auth_policy_bytes);
20442 if (rc != TPM_RC_SUCCESS) {
20443 return rc;
20444 }
20445 std::string policy_digest_bytes;
20446 rc = Serialize_TPMI_ALG_HASH(policy_digest, &policy_digest_bytes);
20447 if (rc != TPM_RC_SUCCESS) {
20448 return rc;
20449 }
20450 std::string pcr_num_bytes;
20451 rc = Serialize_TPMI_DH_PCR(pcr_num, &pcr_num_bytes);
20452 if (rc != TPM_RC_SUCCESS) {
20453 return rc;
20454 }
20455 if (authorization_delegate) {
20456 // Encrypt just the parameter data, not the size.
20457 std::string tmp = auth_policy_bytes.substr(2);
20458 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20459 return TRUNKS_RC_ENCRYPTION_FAILED;
20460 }
20461 auth_policy_bytes.replace(2, std::string::npos, tmp);
20462 }
20463 std::unique_ptr<crypto::SecureHash> hash(
20464 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20465 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20466 hash->Update(auth_handle_name.data(), auth_handle_name.size());
20467 handle_section_bytes += auth_handle_bytes;
20468 command_size += auth_handle_bytes.size();
20469 hash->Update(pcr_num_name.data(), pcr_num_name.size());
20470 handle_section_bytes += pcr_num_bytes;
20471 command_size += pcr_num_bytes.size();
20472 hash->Update(auth_policy_bytes.data(), auth_policy_bytes.size());
20473 parameter_section_bytes += auth_policy_bytes;
20474 command_size += auth_policy_bytes.size();
20475 hash->Update(policy_digest_bytes.data(), policy_digest_bytes.size());
20476 parameter_section_bytes += policy_digest_bytes;
20477 command_size += policy_digest_bytes.size();
20478 std::string command_hash(32, 0);
20479 hash->Finish(std::data(command_hash), command_hash.size());
20480 std::string authorization_section_bytes;
20481 std::string authorization_size_bytes;
20482 if (authorization_delegate) {
20483 if (!authorization_delegate->GetCommandAuthorization(
20484 command_hash, is_command_parameter_encryption_possible,
20485 is_response_parameter_encryption_possible,
20486 &authorization_section_bytes)) {
20487 return TRUNKS_RC_AUTHORIZATION_FAILED;
20488 }
20489 if (!authorization_section_bytes.empty()) {
20490 tag = TPM_ST_SESSIONS;
20491 std::string tmp;
20492 rc = Serialize_UINT32(authorization_section_bytes.size(),
20493 &authorization_size_bytes);
20494 if (rc != TPM_RC_SUCCESS) {
20495 return rc;
20496 }
20497 command_size +=
20498 authorization_size_bytes.size() + authorization_section_bytes.size();
20499 }
20500 }
20501 std::string tag_bytes;
20502 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20503 if (rc != TPM_RC_SUCCESS) {
20504 return rc;
20505 }
20506 std::string command_size_bytes;
20507 rc = Serialize_UINT32(command_size, &command_size_bytes);
20508 if (rc != TPM_RC_SUCCESS) {
20509 return rc;
20510 }
20511 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20512 handle_section_bytes + authorization_size_bytes +
20513 authorization_section_bytes + parameter_section_bytes;
20514 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20515 VLOG(2) << "Command: "
20516 << base::HexEncode(serialized_command->data(),
20517 serialized_command->size());
20518 return TPM_RC_SUCCESS;
20519 }
20520
ParseResponse_PCR_SetAuthPolicy(const std::string & response,AuthorizationDelegate * authorization_delegate)20521 TPM_RC Tpm::ParseResponse_PCR_SetAuthPolicy(
20522 const std::string& response,
20523 AuthorizationDelegate* authorization_delegate) {
20524 VLOG(3) << __func__;
20525 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20526 TPM_RC rc = TPM_RC_SUCCESS;
20527 std::string buffer(response);
20528 TPM_ST tag;
20529 std::string tag_bytes;
20530 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20531 if (rc != TPM_RC_SUCCESS) {
20532 return rc;
20533 }
20534 UINT32 response_size;
20535 std::string response_size_bytes;
20536 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20537 if (rc != TPM_RC_SUCCESS) {
20538 return rc;
20539 }
20540 TPM_RC response_code;
20541 std::string response_code_bytes;
20542 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20543 if (rc != TPM_RC_SUCCESS) {
20544 return rc;
20545 }
20546 if (response_size != response.size()) {
20547 return TPM_RC_SIZE;
20548 }
20549 if (response_code != TPM_RC_SUCCESS) {
20550 return response_code;
20551 }
20552 TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy;
20553 std::string command_code_bytes;
20554 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20555 if (rc != TPM_RC_SUCCESS) {
20556 return rc;
20557 }
20558 std::string authorization_section_bytes;
20559 if (tag == TPM_ST_SESSIONS) {
20560 UINT32 parameter_section_size = buffer.size();
20561 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
20562 if (rc != TPM_RC_SUCCESS) {
20563 return rc;
20564 }
20565 if (parameter_section_size > buffer.size()) {
20566 return TPM_RC_INSUFFICIENT;
20567 }
20568 authorization_section_bytes = buffer.substr(parameter_section_size);
20569 // Keep the parameter section in |buffer|.
20570 buffer.erase(parameter_section_size);
20571 }
20572 std::unique_ptr<crypto::SecureHash> hash(
20573 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20574 hash->Update(response_code_bytes.data(), response_code_bytes.size());
20575 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20576 hash->Update(buffer.data(), buffer.size());
20577 std::string response_hash(32, 0);
20578 hash->Finish(std::data(response_hash), response_hash.size());
20579 if (tag == TPM_ST_SESSIONS) {
20580 if (!authorization_delegate)
20581 return TRUNKS_RC_AUTHORIZATION_FAILED;
20582 if (!authorization_delegate->CheckResponseAuthorization(
20583 response_hash, authorization_section_bytes)) {
20584 return TRUNKS_RC_AUTHORIZATION_FAILED;
20585 }
20586 }
20587 return TPM_RC_SUCCESS;
20588 }
20589
PCR_SetAuthPolicyErrorCallback(Tpm::PCR_SetAuthPolicyResponse callback,TPM_RC response_code)20590 void PCR_SetAuthPolicyErrorCallback(Tpm::PCR_SetAuthPolicyResponse callback,
20591 TPM_RC response_code) {
20592 VLOG(1) << __func__;
20593 std::move(callback).Run(response_code);
20594 }
20595
PCR_SetAuthPolicyResponseParser(Tpm::PCR_SetAuthPolicyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20596 void PCR_SetAuthPolicyResponseParser(
20597 Tpm::PCR_SetAuthPolicyResponse callback,
20598 AuthorizationDelegate* authorization_delegate,
20599 const std::string& response) {
20600 VLOG(1) << __func__;
20601 TPM_RC rc =
20602 Tpm::ParseResponse_PCR_SetAuthPolicy(response, authorization_delegate);
20603 if (rc != TPM_RC_SUCCESS) {
20604 base::OnceCallback<void(TPM_RC)> error_reporter =
20605 base::BindOnce(PCR_SetAuthPolicyErrorCallback, std::move(callback));
20606 std::move(error_reporter).Run(rc);
20607 return;
20608 }
20609 std::move(callback).Run(rc);
20610 }
20611
PCR_SetAuthPolicy(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPMI_DH_PCR & pcr_num,const std::string & pcr_num_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & policy_digest,AuthorizationDelegate * authorization_delegate,PCR_SetAuthPolicyResponse callback)20612 void Tpm::PCR_SetAuthPolicy(const TPMI_RH_PLATFORM& auth_handle,
20613 const std::string& auth_handle_name,
20614 const TPMI_DH_PCR& pcr_num,
20615 const std::string& pcr_num_name,
20616 const TPM2B_DIGEST& auth_policy,
20617 const TPMI_ALG_HASH& policy_digest,
20618 AuthorizationDelegate* authorization_delegate,
20619 PCR_SetAuthPolicyResponse callback) {
20620 VLOG(1) << __func__;
20621 std::string command;
20622 TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy(
20623 auth_handle, auth_handle_name, pcr_num, pcr_num_name, auth_policy,
20624 policy_digest, &command, authorization_delegate);
20625 if (rc != TPM_RC_SUCCESS) {
20626 base::OnceCallback<void(TPM_RC)> error_reporter =
20627 base::BindOnce(PCR_SetAuthPolicyErrorCallback, std::move(callback));
20628 std::move(error_reporter).Run(rc);
20629 return;
20630 }
20631 base::OnceCallback<void(const std::string&)> parser =
20632 base::BindOnce(PCR_SetAuthPolicyResponseParser, std::move(callback),
20633 authorization_delegate);
20634 transceiver_->SendCommand(command, std::move(parser));
20635 }
20636
PCR_SetAuthPolicySync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPMI_DH_PCR & pcr_num,const std::string & pcr_num_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & policy_digest,AuthorizationDelegate * authorization_delegate)20637 TPM_RC Tpm::PCR_SetAuthPolicySync(
20638 const TPMI_RH_PLATFORM& auth_handle,
20639 const std::string& auth_handle_name,
20640 const TPMI_DH_PCR& pcr_num,
20641 const std::string& pcr_num_name,
20642 const TPM2B_DIGEST& auth_policy,
20643 const TPMI_ALG_HASH& policy_digest,
20644 AuthorizationDelegate* authorization_delegate) {
20645 VLOG(1) << __func__;
20646 std::string command;
20647 TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy(
20648 auth_handle, auth_handle_name, pcr_num, pcr_num_name, auth_policy,
20649 policy_digest, &command, authorization_delegate);
20650 if (rc != TPM_RC_SUCCESS) {
20651 return rc;
20652 }
20653 std::string response = transceiver_->SendCommandAndWait(command);
20654 rc = ParseResponse_PCR_SetAuthPolicy(response, authorization_delegate);
20655 return rc;
20656 }
20657
SerializeCommand_PCR_SetAuthValue(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20658 TPM_RC Tpm::SerializeCommand_PCR_SetAuthValue(
20659 const TPMI_DH_PCR& pcr_handle,
20660 const std::string& pcr_handle_name,
20661 const TPM2B_DIGEST& auth,
20662 std::string* serialized_command,
20663 AuthorizationDelegate* authorization_delegate) {
20664 VLOG(3) << __func__;
20665 TPM_RC rc = TPM_RC_SUCCESS;
20666 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20667 UINT32 command_size = 10; // Header size.
20668 std::string handle_section_bytes;
20669 std::string parameter_section_bytes;
20670 TPM_CC command_code = TPM_CC_PCR_SetAuthValue;
20671 bool is_command_parameter_encryption_possible = true;
20672 bool is_response_parameter_encryption_possible = false;
20673 std::string command_code_bytes;
20674 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20675 if (rc != TPM_RC_SUCCESS) {
20676 return rc;
20677 }
20678 std::string pcr_handle_bytes;
20679 rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
20680 if (rc != TPM_RC_SUCCESS) {
20681 return rc;
20682 }
20683 std::string auth_bytes;
20684 rc = Serialize_TPM2B_DIGEST(auth, &auth_bytes);
20685 if (rc != TPM_RC_SUCCESS) {
20686 return rc;
20687 }
20688 if (authorization_delegate) {
20689 // Encrypt just the parameter data, not the size.
20690 std::string tmp = auth_bytes.substr(2);
20691 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20692 return TRUNKS_RC_ENCRYPTION_FAILED;
20693 }
20694 auth_bytes.replace(2, std::string::npos, tmp);
20695 }
20696 std::unique_ptr<crypto::SecureHash> hash(
20697 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20698 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20699 hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
20700 handle_section_bytes += pcr_handle_bytes;
20701 command_size += pcr_handle_bytes.size();
20702 hash->Update(auth_bytes.data(), auth_bytes.size());
20703 parameter_section_bytes += auth_bytes;
20704 command_size += auth_bytes.size();
20705 std::string command_hash(32, 0);
20706 hash->Finish(std::data(command_hash), command_hash.size());
20707 std::string authorization_section_bytes;
20708 std::string authorization_size_bytes;
20709 if (authorization_delegate) {
20710 if (!authorization_delegate->GetCommandAuthorization(
20711 command_hash, is_command_parameter_encryption_possible,
20712 is_response_parameter_encryption_possible,
20713 &authorization_section_bytes)) {
20714 return TRUNKS_RC_AUTHORIZATION_FAILED;
20715 }
20716 if (!authorization_section_bytes.empty()) {
20717 tag = TPM_ST_SESSIONS;
20718 std::string tmp;
20719 rc = Serialize_UINT32(authorization_section_bytes.size(),
20720 &authorization_size_bytes);
20721 if (rc != TPM_RC_SUCCESS) {
20722 return rc;
20723 }
20724 command_size +=
20725 authorization_size_bytes.size() + authorization_section_bytes.size();
20726 }
20727 }
20728 std::string tag_bytes;
20729 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20730 if (rc != TPM_RC_SUCCESS) {
20731 return rc;
20732 }
20733 std::string command_size_bytes;
20734 rc = Serialize_UINT32(command_size, &command_size_bytes);
20735 if (rc != TPM_RC_SUCCESS) {
20736 return rc;
20737 }
20738 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20739 handle_section_bytes + authorization_size_bytes +
20740 authorization_section_bytes + parameter_section_bytes;
20741 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20742 VLOG(2) << "Command: "
20743 << base::HexEncode(serialized_command->data(),
20744 serialized_command->size());
20745 return TPM_RC_SUCCESS;
20746 }
20747
ParseResponse_PCR_SetAuthValue(const std::string & response,AuthorizationDelegate * authorization_delegate)20748 TPM_RC Tpm::ParseResponse_PCR_SetAuthValue(
20749 const std::string& response,
20750 AuthorizationDelegate* authorization_delegate) {
20751 VLOG(3) << __func__;
20752 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20753 TPM_RC rc = TPM_RC_SUCCESS;
20754 std::string buffer(response);
20755 TPM_ST tag;
20756 std::string tag_bytes;
20757 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20758 if (rc != TPM_RC_SUCCESS) {
20759 return rc;
20760 }
20761 UINT32 response_size;
20762 std::string response_size_bytes;
20763 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20764 if (rc != TPM_RC_SUCCESS) {
20765 return rc;
20766 }
20767 TPM_RC response_code;
20768 std::string response_code_bytes;
20769 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20770 if (rc != TPM_RC_SUCCESS) {
20771 return rc;
20772 }
20773 if (response_size != response.size()) {
20774 return TPM_RC_SIZE;
20775 }
20776 if (response_code != TPM_RC_SUCCESS) {
20777 return response_code;
20778 }
20779 TPM_CC command_code = TPM_CC_PCR_SetAuthValue;
20780 std::string command_code_bytes;
20781 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20782 if (rc != TPM_RC_SUCCESS) {
20783 return rc;
20784 }
20785 std::string authorization_section_bytes;
20786 if (tag == TPM_ST_SESSIONS) {
20787 UINT32 parameter_section_size = buffer.size();
20788 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
20789 if (rc != TPM_RC_SUCCESS) {
20790 return rc;
20791 }
20792 if (parameter_section_size > buffer.size()) {
20793 return TPM_RC_INSUFFICIENT;
20794 }
20795 authorization_section_bytes = buffer.substr(parameter_section_size);
20796 // Keep the parameter section in |buffer|.
20797 buffer.erase(parameter_section_size);
20798 }
20799 std::unique_ptr<crypto::SecureHash> hash(
20800 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20801 hash->Update(response_code_bytes.data(), response_code_bytes.size());
20802 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20803 hash->Update(buffer.data(), buffer.size());
20804 std::string response_hash(32, 0);
20805 hash->Finish(std::data(response_hash), response_hash.size());
20806 if (tag == TPM_ST_SESSIONS) {
20807 if (!authorization_delegate)
20808 return TRUNKS_RC_AUTHORIZATION_FAILED;
20809 if (!authorization_delegate->CheckResponseAuthorization(
20810 response_hash, authorization_section_bytes)) {
20811 return TRUNKS_RC_AUTHORIZATION_FAILED;
20812 }
20813 }
20814 return TPM_RC_SUCCESS;
20815 }
20816
PCR_SetAuthValueErrorCallback(Tpm::PCR_SetAuthValueResponse callback,TPM_RC response_code)20817 void PCR_SetAuthValueErrorCallback(Tpm::PCR_SetAuthValueResponse callback,
20818 TPM_RC response_code) {
20819 VLOG(1) << __func__;
20820 std::move(callback).Run(response_code);
20821 }
20822
PCR_SetAuthValueResponseParser(Tpm::PCR_SetAuthValueResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20823 void PCR_SetAuthValueResponseParser(
20824 Tpm::PCR_SetAuthValueResponse callback,
20825 AuthorizationDelegate* authorization_delegate,
20826 const std::string& response) {
20827 VLOG(1) << __func__;
20828 TPM_RC rc =
20829 Tpm::ParseResponse_PCR_SetAuthValue(response, authorization_delegate);
20830 if (rc != TPM_RC_SUCCESS) {
20831 base::OnceCallback<void(TPM_RC)> error_reporter =
20832 base::BindOnce(PCR_SetAuthValueErrorCallback, std::move(callback));
20833 std::move(error_reporter).Run(rc);
20834 return;
20835 }
20836 std::move(callback).Run(rc);
20837 }
20838
PCR_SetAuthValue(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,AuthorizationDelegate * authorization_delegate,PCR_SetAuthValueResponse callback)20839 void Tpm::PCR_SetAuthValue(const TPMI_DH_PCR& pcr_handle,
20840 const std::string& pcr_handle_name,
20841 const TPM2B_DIGEST& auth,
20842 AuthorizationDelegate* authorization_delegate,
20843 PCR_SetAuthValueResponse callback) {
20844 VLOG(1) << __func__;
20845 std::string command;
20846 TPM_RC rc = SerializeCommand_PCR_SetAuthValue(
20847 pcr_handle, pcr_handle_name, auth, &command, authorization_delegate);
20848 if (rc != TPM_RC_SUCCESS) {
20849 base::OnceCallback<void(TPM_RC)> error_reporter =
20850 base::BindOnce(PCR_SetAuthValueErrorCallback, std::move(callback));
20851 std::move(error_reporter).Run(rc);
20852 return;
20853 }
20854 base::OnceCallback<void(const std::string&)> parser =
20855 base::BindOnce(PCR_SetAuthValueResponseParser, std::move(callback),
20856 authorization_delegate);
20857 transceiver_->SendCommand(command, std::move(parser));
20858 }
20859
PCR_SetAuthValueSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,AuthorizationDelegate * authorization_delegate)20860 TPM_RC Tpm::PCR_SetAuthValueSync(
20861 const TPMI_DH_PCR& pcr_handle,
20862 const std::string& pcr_handle_name,
20863 const TPM2B_DIGEST& auth,
20864 AuthorizationDelegate* authorization_delegate) {
20865 VLOG(1) << __func__;
20866 std::string command;
20867 TPM_RC rc = SerializeCommand_PCR_SetAuthValue(
20868 pcr_handle, pcr_handle_name, auth, &command, authorization_delegate);
20869 if (rc != TPM_RC_SUCCESS) {
20870 return rc;
20871 }
20872 std::string response = transceiver_->SendCommandAndWait(command);
20873 rc = ParseResponse_PCR_SetAuthValue(response, authorization_delegate);
20874 return rc;
20875 }
20876
SerializeCommand_PCR_Reset(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20877 TPM_RC Tpm::SerializeCommand_PCR_Reset(
20878 const TPMI_DH_PCR& pcr_handle,
20879 const std::string& pcr_handle_name,
20880 std::string* serialized_command,
20881 AuthorizationDelegate* authorization_delegate) {
20882 VLOG(3) << __func__;
20883 TPM_RC rc = TPM_RC_SUCCESS;
20884 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20885 UINT32 command_size = 10; // Header size.
20886 std::string handle_section_bytes;
20887 std::string parameter_section_bytes;
20888 TPM_CC command_code = TPM_CC_PCR_Reset;
20889 bool is_command_parameter_encryption_possible = false;
20890 bool is_response_parameter_encryption_possible = false;
20891 std::string command_code_bytes;
20892 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20893 if (rc != TPM_RC_SUCCESS) {
20894 return rc;
20895 }
20896 std::string pcr_handle_bytes;
20897 rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
20898 if (rc != TPM_RC_SUCCESS) {
20899 return rc;
20900 }
20901 std::unique_ptr<crypto::SecureHash> hash(
20902 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20903 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20904 hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
20905 handle_section_bytes += pcr_handle_bytes;
20906 command_size += pcr_handle_bytes.size();
20907 std::string command_hash(32, 0);
20908 hash->Finish(std::data(command_hash), command_hash.size());
20909 std::string authorization_section_bytes;
20910 std::string authorization_size_bytes;
20911 if (authorization_delegate) {
20912 if (!authorization_delegate->GetCommandAuthorization(
20913 command_hash, is_command_parameter_encryption_possible,
20914 is_response_parameter_encryption_possible,
20915 &authorization_section_bytes)) {
20916 return TRUNKS_RC_AUTHORIZATION_FAILED;
20917 }
20918 if (!authorization_section_bytes.empty()) {
20919 tag = TPM_ST_SESSIONS;
20920 std::string tmp;
20921 rc = Serialize_UINT32(authorization_section_bytes.size(),
20922 &authorization_size_bytes);
20923 if (rc != TPM_RC_SUCCESS) {
20924 return rc;
20925 }
20926 command_size +=
20927 authorization_size_bytes.size() + authorization_section_bytes.size();
20928 }
20929 }
20930 std::string tag_bytes;
20931 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20932 if (rc != TPM_RC_SUCCESS) {
20933 return rc;
20934 }
20935 std::string command_size_bytes;
20936 rc = Serialize_UINT32(command_size, &command_size_bytes);
20937 if (rc != TPM_RC_SUCCESS) {
20938 return rc;
20939 }
20940 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20941 handle_section_bytes + authorization_size_bytes +
20942 authorization_section_bytes + parameter_section_bytes;
20943 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20944 VLOG(2) << "Command: "
20945 << base::HexEncode(serialized_command->data(),
20946 serialized_command->size());
20947 return TPM_RC_SUCCESS;
20948 }
20949
ParseResponse_PCR_Reset(const std::string & response,AuthorizationDelegate * authorization_delegate)20950 TPM_RC Tpm::ParseResponse_PCR_Reset(
20951 const std::string& response,
20952 AuthorizationDelegate* authorization_delegate) {
20953 VLOG(3) << __func__;
20954 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20955 TPM_RC rc = TPM_RC_SUCCESS;
20956 std::string buffer(response);
20957 TPM_ST tag;
20958 std::string tag_bytes;
20959 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20960 if (rc != TPM_RC_SUCCESS) {
20961 return rc;
20962 }
20963 UINT32 response_size;
20964 std::string response_size_bytes;
20965 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20966 if (rc != TPM_RC_SUCCESS) {
20967 return rc;
20968 }
20969 TPM_RC response_code;
20970 std::string response_code_bytes;
20971 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20972 if (rc != TPM_RC_SUCCESS) {
20973 return rc;
20974 }
20975 if (response_size != response.size()) {
20976 return TPM_RC_SIZE;
20977 }
20978 if (response_code != TPM_RC_SUCCESS) {
20979 return response_code;
20980 }
20981 TPM_CC command_code = TPM_CC_PCR_Reset;
20982 std::string command_code_bytes;
20983 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20984 if (rc != TPM_RC_SUCCESS) {
20985 return rc;
20986 }
20987 std::string authorization_section_bytes;
20988 if (tag == TPM_ST_SESSIONS) {
20989 UINT32 parameter_section_size = buffer.size();
20990 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
20991 if (rc != TPM_RC_SUCCESS) {
20992 return rc;
20993 }
20994 if (parameter_section_size > buffer.size()) {
20995 return TPM_RC_INSUFFICIENT;
20996 }
20997 authorization_section_bytes = buffer.substr(parameter_section_size);
20998 // Keep the parameter section in |buffer|.
20999 buffer.erase(parameter_section_size);
21000 }
21001 std::unique_ptr<crypto::SecureHash> hash(
21002 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21003 hash->Update(response_code_bytes.data(), response_code_bytes.size());
21004 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21005 hash->Update(buffer.data(), buffer.size());
21006 std::string response_hash(32, 0);
21007 hash->Finish(std::data(response_hash), response_hash.size());
21008 if (tag == TPM_ST_SESSIONS) {
21009 if (!authorization_delegate)
21010 return TRUNKS_RC_AUTHORIZATION_FAILED;
21011 if (!authorization_delegate->CheckResponseAuthorization(
21012 response_hash, authorization_section_bytes)) {
21013 return TRUNKS_RC_AUTHORIZATION_FAILED;
21014 }
21015 }
21016 return TPM_RC_SUCCESS;
21017 }
21018
PCR_ResetErrorCallback(Tpm::PCR_ResetResponse callback,TPM_RC response_code)21019 void PCR_ResetErrorCallback(Tpm::PCR_ResetResponse callback,
21020 TPM_RC response_code) {
21021 VLOG(1) << __func__;
21022 std::move(callback).Run(response_code);
21023 }
21024
PCR_ResetResponseParser(Tpm::PCR_ResetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21025 void PCR_ResetResponseParser(Tpm::PCR_ResetResponse callback,
21026 AuthorizationDelegate* authorization_delegate,
21027 const std::string& response) {
21028 VLOG(1) << __func__;
21029 TPM_RC rc = Tpm::ParseResponse_PCR_Reset(response, authorization_delegate);
21030 if (rc != TPM_RC_SUCCESS) {
21031 base::OnceCallback<void(TPM_RC)> error_reporter =
21032 base::BindOnce(PCR_ResetErrorCallback, std::move(callback));
21033 std::move(error_reporter).Run(rc);
21034 return;
21035 }
21036 std::move(callback).Run(rc);
21037 }
21038
PCR_Reset(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,AuthorizationDelegate * authorization_delegate,PCR_ResetResponse callback)21039 void Tpm::PCR_Reset(const TPMI_DH_PCR& pcr_handle,
21040 const std::string& pcr_handle_name,
21041 AuthorizationDelegate* authorization_delegate,
21042 PCR_ResetResponse callback) {
21043 VLOG(1) << __func__;
21044 std::string command;
21045 TPM_RC rc = SerializeCommand_PCR_Reset(pcr_handle, pcr_handle_name, &command,
21046 authorization_delegate);
21047 if (rc != TPM_RC_SUCCESS) {
21048 base::OnceCallback<void(TPM_RC)> error_reporter =
21049 base::BindOnce(PCR_ResetErrorCallback, std::move(callback));
21050 std::move(error_reporter).Run(rc);
21051 return;
21052 }
21053 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21054 PCR_ResetResponseParser, std::move(callback), authorization_delegate);
21055 transceiver_->SendCommand(command, std::move(parser));
21056 }
21057
PCR_ResetSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,AuthorizationDelegate * authorization_delegate)21058 TPM_RC Tpm::PCR_ResetSync(const TPMI_DH_PCR& pcr_handle,
21059 const std::string& pcr_handle_name,
21060 AuthorizationDelegate* authorization_delegate) {
21061 VLOG(1) << __func__;
21062 std::string command;
21063 TPM_RC rc = SerializeCommand_PCR_Reset(pcr_handle, pcr_handle_name, &command,
21064 authorization_delegate);
21065 if (rc != TPM_RC_SUCCESS) {
21066 return rc;
21067 }
21068 std::string response = transceiver_->SendCommandAndWait(command);
21069 rc = ParseResponse_PCR_Reset(response, authorization_delegate);
21070 return rc;
21071 }
21072
SerializeCommand_PolicySigned(const TPMI_DH_OBJECT & auth_object,const std::string & auth_object_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,const TPMT_SIGNATURE & auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21073 TPM_RC Tpm::SerializeCommand_PolicySigned(
21074 const TPMI_DH_OBJECT& auth_object,
21075 const std::string& auth_object_name,
21076 const TPMI_SH_POLICY& policy_session,
21077 const std::string& policy_session_name,
21078 const TPM2B_NONCE& nonce_tpm,
21079 const TPM2B_DIGEST& cp_hash_a,
21080 const TPM2B_NONCE& policy_ref,
21081 const INT32& expiration,
21082 const TPMT_SIGNATURE& auth,
21083 std::string* serialized_command,
21084 AuthorizationDelegate* authorization_delegate) {
21085 VLOG(3) << __func__;
21086 TPM_RC rc = TPM_RC_SUCCESS;
21087 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21088 UINT32 command_size = 10; // Header size.
21089 std::string handle_section_bytes;
21090 std::string parameter_section_bytes;
21091 TPM_CC command_code = TPM_CC_PolicySigned;
21092 bool is_command_parameter_encryption_possible = true;
21093 bool is_response_parameter_encryption_possible = true;
21094 std::string command_code_bytes;
21095 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21096 if (rc != TPM_RC_SUCCESS) {
21097 return rc;
21098 }
21099 std::string auth_object_bytes;
21100 rc = Serialize_TPMI_DH_OBJECT(auth_object, &auth_object_bytes);
21101 if (rc != TPM_RC_SUCCESS) {
21102 return rc;
21103 }
21104 std::string policy_session_bytes;
21105 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21106 if (rc != TPM_RC_SUCCESS) {
21107 return rc;
21108 }
21109 std::string nonce_tpm_bytes;
21110 rc = Serialize_TPM2B_NONCE(nonce_tpm, &nonce_tpm_bytes);
21111 if (rc != TPM_RC_SUCCESS) {
21112 return rc;
21113 }
21114 std::string cp_hash_a_bytes;
21115 rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21116 if (rc != TPM_RC_SUCCESS) {
21117 return rc;
21118 }
21119 std::string policy_ref_bytes;
21120 rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21121 if (rc != TPM_RC_SUCCESS) {
21122 return rc;
21123 }
21124 std::string expiration_bytes;
21125 rc = Serialize_INT32(expiration, &expiration_bytes);
21126 if (rc != TPM_RC_SUCCESS) {
21127 return rc;
21128 }
21129 std::string auth_bytes;
21130 rc = Serialize_TPMT_SIGNATURE(auth, &auth_bytes);
21131 if (rc != TPM_RC_SUCCESS) {
21132 return rc;
21133 }
21134 if (authorization_delegate) {
21135 // Encrypt just the parameter data, not the size.
21136 std::string tmp = nonce_tpm_bytes.substr(2);
21137 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21138 return TRUNKS_RC_ENCRYPTION_FAILED;
21139 }
21140 nonce_tpm_bytes.replace(2, std::string::npos, tmp);
21141 }
21142 std::unique_ptr<crypto::SecureHash> hash(
21143 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21144 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21145 hash->Update(auth_object_name.data(), auth_object_name.size());
21146 handle_section_bytes += auth_object_bytes;
21147 command_size += auth_object_bytes.size();
21148 hash->Update(policy_session_name.data(), policy_session_name.size());
21149 handle_section_bytes += policy_session_bytes;
21150 command_size += policy_session_bytes.size();
21151 hash->Update(nonce_tpm_bytes.data(), nonce_tpm_bytes.size());
21152 parameter_section_bytes += nonce_tpm_bytes;
21153 command_size += nonce_tpm_bytes.size();
21154 hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21155 parameter_section_bytes += cp_hash_a_bytes;
21156 command_size += cp_hash_a_bytes.size();
21157 hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21158 parameter_section_bytes += policy_ref_bytes;
21159 command_size += policy_ref_bytes.size();
21160 hash->Update(expiration_bytes.data(), expiration_bytes.size());
21161 parameter_section_bytes += expiration_bytes;
21162 command_size += expiration_bytes.size();
21163 hash->Update(auth_bytes.data(), auth_bytes.size());
21164 parameter_section_bytes += auth_bytes;
21165 command_size += auth_bytes.size();
21166 std::string command_hash(32, 0);
21167 hash->Finish(std::data(command_hash), command_hash.size());
21168 std::string authorization_section_bytes;
21169 std::string authorization_size_bytes;
21170 if (authorization_delegate) {
21171 if (!authorization_delegate->GetCommandAuthorization(
21172 command_hash, is_command_parameter_encryption_possible,
21173 is_response_parameter_encryption_possible,
21174 &authorization_section_bytes)) {
21175 return TRUNKS_RC_AUTHORIZATION_FAILED;
21176 }
21177 if (!authorization_section_bytes.empty()) {
21178 tag = TPM_ST_SESSIONS;
21179 std::string tmp;
21180 rc = Serialize_UINT32(authorization_section_bytes.size(),
21181 &authorization_size_bytes);
21182 if (rc != TPM_RC_SUCCESS) {
21183 return rc;
21184 }
21185 command_size +=
21186 authorization_size_bytes.size() + authorization_section_bytes.size();
21187 }
21188 }
21189 std::string tag_bytes;
21190 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21191 if (rc != TPM_RC_SUCCESS) {
21192 return rc;
21193 }
21194 std::string command_size_bytes;
21195 rc = Serialize_UINT32(command_size, &command_size_bytes);
21196 if (rc != TPM_RC_SUCCESS) {
21197 return rc;
21198 }
21199 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21200 handle_section_bytes + authorization_size_bytes +
21201 authorization_section_bytes + parameter_section_bytes;
21202 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21203 VLOG(2) << "Command: "
21204 << base::HexEncode(serialized_command->data(),
21205 serialized_command->size());
21206 return TPM_RC_SUCCESS;
21207 }
21208
ParseResponse_PolicySigned(const std::string & response,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21209 TPM_RC Tpm::ParseResponse_PolicySigned(
21210 const std::string& response,
21211 TPM2B_TIMEOUT* timeout,
21212 TPMT_TK_AUTH* policy_ticket,
21213 AuthorizationDelegate* authorization_delegate) {
21214 VLOG(3) << __func__;
21215 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21216 TPM_RC rc = TPM_RC_SUCCESS;
21217 std::string buffer(response);
21218 TPM_ST tag;
21219 std::string tag_bytes;
21220 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21221 if (rc != TPM_RC_SUCCESS) {
21222 return rc;
21223 }
21224 UINT32 response_size;
21225 std::string response_size_bytes;
21226 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21227 if (rc != TPM_RC_SUCCESS) {
21228 return rc;
21229 }
21230 TPM_RC response_code;
21231 std::string response_code_bytes;
21232 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21233 if (rc != TPM_RC_SUCCESS) {
21234 return rc;
21235 }
21236 if (response_size != response.size()) {
21237 return TPM_RC_SIZE;
21238 }
21239 if (response_code != TPM_RC_SUCCESS) {
21240 return response_code;
21241 }
21242 TPM_CC command_code = TPM_CC_PolicySigned;
21243 std::string command_code_bytes;
21244 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21245 if (rc != TPM_RC_SUCCESS) {
21246 return rc;
21247 }
21248 std::string authorization_section_bytes;
21249 if (tag == TPM_ST_SESSIONS) {
21250 UINT32 parameter_section_size = buffer.size();
21251 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
21252 if (rc != TPM_RC_SUCCESS) {
21253 return rc;
21254 }
21255 if (parameter_section_size > buffer.size()) {
21256 return TPM_RC_INSUFFICIENT;
21257 }
21258 authorization_section_bytes = buffer.substr(parameter_section_size);
21259 // Keep the parameter section in |buffer|.
21260 buffer.erase(parameter_section_size);
21261 }
21262 std::unique_ptr<crypto::SecureHash> hash(
21263 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21264 hash->Update(response_code_bytes.data(), response_code_bytes.size());
21265 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21266 hash->Update(buffer.data(), buffer.size());
21267 std::string response_hash(32, 0);
21268 hash->Finish(std::data(response_hash), response_hash.size());
21269 if (tag == TPM_ST_SESSIONS) {
21270 if (!authorization_delegate)
21271 return TRUNKS_RC_AUTHORIZATION_FAILED;
21272 if (!authorization_delegate->CheckResponseAuthorization(
21273 response_hash, authorization_section_bytes)) {
21274 return TRUNKS_RC_AUTHORIZATION_FAILED;
21275 }
21276 }
21277 if (tag == TPM_ST_SESSIONS) {
21278 if (!authorization_delegate)
21279 return TRUNKS_RC_AUTHORIZATION_FAILED;
21280
21281 // Parse the encrypted parameter size.
21282 UINT16 size;
21283 std::string size_buffer = buffer.substr(0, 2);
21284 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
21285 return result;
21286 }
21287 if (buffer.size() < 2 + size) {
21288 return TPM_RC_INSUFFICIENT;
21289 }
21290
21291 // Decrypt just the parameter data, not the size.
21292 std::string decrypted_data = buffer.substr(2, size);
21293 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
21294 return TRUNKS_RC_ENCRYPTION_FAILED;
21295 }
21296 buffer.replace(2, size, decrypted_data);
21297 }
21298 std::string timeout_bytes;
21299 rc = Parse_TPM2B_TIMEOUT(&buffer, timeout, &timeout_bytes);
21300 if (rc != TPM_RC_SUCCESS) {
21301 return rc;
21302 }
21303 std::string policy_ticket_bytes;
21304 rc = Parse_TPMT_TK_AUTH(&buffer, policy_ticket, &policy_ticket_bytes);
21305 if (rc != TPM_RC_SUCCESS) {
21306 return rc;
21307 }
21308 return TPM_RC_SUCCESS;
21309 }
21310
PolicySignedErrorCallback(Tpm::PolicySignedResponse callback,TPM_RC response_code)21311 void PolicySignedErrorCallback(Tpm::PolicySignedResponse callback,
21312 TPM_RC response_code) {
21313 VLOG(1) << __func__;
21314 std::move(callback).Run(response_code, TPM2B_TIMEOUT(), TPMT_TK_AUTH());
21315 }
21316
PolicySignedResponseParser(Tpm::PolicySignedResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21317 void PolicySignedResponseParser(Tpm::PolicySignedResponse callback,
21318 AuthorizationDelegate* authorization_delegate,
21319 const std::string& response) {
21320 VLOG(1) << __func__;
21321 TPM2B_TIMEOUT timeout;
21322 TPMT_TK_AUTH policy_ticket;
21323 TPM_RC rc = Tpm::ParseResponse_PolicySigned(
21324 response, &timeout, &policy_ticket, authorization_delegate);
21325 if (rc != TPM_RC_SUCCESS) {
21326 base::OnceCallback<void(TPM_RC)> error_reporter =
21327 base::BindOnce(PolicySignedErrorCallback, std::move(callback));
21328 std::move(error_reporter).Run(rc);
21329 return;
21330 }
21331 std::move(callback).Run(rc, timeout, policy_ticket);
21332 }
21333
PolicySigned(const TPMI_DH_OBJECT & auth_object,const std::string & auth_object_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,const TPMT_SIGNATURE & auth,AuthorizationDelegate * authorization_delegate,PolicySignedResponse callback)21334 void Tpm::PolicySigned(const TPMI_DH_OBJECT& auth_object,
21335 const std::string& auth_object_name,
21336 const TPMI_SH_POLICY& policy_session,
21337 const std::string& policy_session_name,
21338 const TPM2B_NONCE& nonce_tpm,
21339 const TPM2B_DIGEST& cp_hash_a,
21340 const TPM2B_NONCE& policy_ref,
21341 const INT32& expiration,
21342 const TPMT_SIGNATURE& auth,
21343 AuthorizationDelegate* authorization_delegate,
21344 PolicySignedResponse callback) {
21345 VLOG(1) << __func__;
21346 std::string command;
21347 TPM_RC rc = SerializeCommand_PolicySigned(
21348 auth_object, auth_object_name, policy_session, policy_session_name,
21349 nonce_tpm, cp_hash_a, policy_ref, expiration, auth, &command,
21350 authorization_delegate);
21351 if (rc != TPM_RC_SUCCESS) {
21352 base::OnceCallback<void(TPM_RC)> error_reporter =
21353 base::BindOnce(PolicySignedErrorCallback, std::move(callback));
21354 std::move(error_reporter).Run(rc);
21355 return;
21356 }
21357 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21358 PolicySignedResponseParser, std::move(callback), authorization_delegate);
21359 transceiver_->SendCommand(command, std::move(parser));
21360 }
21361
PolicySignedSync(const TPMI_DH_OBJECT & auth_object,const std::string & auth_object_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,const TPMT_SIGNATURE & auth,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21362 TPM_RC Tpm::PolicySignedSync(const TPMI_DH_OBJECT& auth_object,
21363 const std::string& auth_object_name,
21364 const TPMI_SH_POLICY& policy_session,
21365 const std::string& policy_session_name,
21366 const TPM2B_NONCE& nonce_tpm,
21367 const TPM2B_DIGEST& cp_hash_a,
21368 const TPM2B_NONCE& policy_ref,
21369 const INT32& expiration,
21370 const TPMT_SIGNATURE& auth,
21371 TPM2B_TIMEOUT* timeout,
21372 TPMT_TK_AUTH* policy_ticket,
21373 AuthorizationDelegate* authorization_delegate) {
21374 VLOG(1) << __func__;
21375 std::string command;
21376 TPM_RC rc = SerializeCommand_PolicySigned(
21377 auth_object, auth_object_name, policy_session, policy_session_name,
21378 nonce_tpm, cp_hash_a, policy_ref, expiration, auth, &command,
21379 authorization_delegate);
21380 if (rc != TPM_RC_SUCCESS) {
21381 return rc;
21382 }
21383 std::string response = transceiver_->SendCommandAndWait(command);
21384 rc = ParseResponse_PolicySigned(response, timeout, policy_ticket,
21385 authorization_delegate);
21386 return rc;
21387 }
21388
SerializeCommand_PolicySecret(const TPMI_DH_ENTITY & auth_handle,const std::string & auth_handle_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21389 TPM_RC Tpm::SerializeCommand_PolicySecret(
21390 const TPMI_DH_ENTITY& auth_handle,
21391 const std::string& auth_handle_name,
21392 const TPMI_SH_POLICY& policy_session,
21393 const std::string& policy_session_name,
21394 const TPM2B_NONCE& nonce_tpm,
21395 const TPM2B_DIGEST& cp_hash_a,
21396 const TPM2B_NONCE& policy_ref,
21397 const INT32& expiration,
21398 std::string* serialized_command,
21399 AuthorizationDelegate* authorization_delegate) {
21400 VLOG(3) << __func__;
21401 TPM_RC rc = TPM_RC_SUCCESS;
21402 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21403 UINT32 command_size = 10; // Header size.
21404 std::string handle_section_bytes;
21405 std::string parameter_section_bytes;
21406 TPM_CC command_code = TPM_CC_PolicySecret;
21407 bool is_command_parameter_encryption_possible = true;
21408 bool is_response_parameter_encryption_possible = true;
21409 std::string command_code_bytes;
21410 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21411 if (rc != TPM_RC_SUCCESS) {
21412 return rc;
21413 }
21414 std::string auth_handle_bytes;
21415 rc = Serialize_TPMI_DH_ENTITY(auth_handle, &auth_handle_bytes);
21416 if (rc != TPM_RC_SUCCESS) {
21417 return rc;
21418 }
21419 std::string policy_session_bytes;
21420 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21421 if (rc != TPM_RC_SUCCESS) {
21422 return rc;
21423 }
21424 std::string nonce_tpm_bytes;
21425 rc = Serialize_TPM2B_NONCE(nonce_tpm, &nonce_tpm_bytes);
21426 if (rc != TPM_RC_SUCCESS) {
21427 return rc;
21428 }
21429 std::string cp_hash_a_bytes;
21430 rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21431 if (rc != TPM_RC_SUCCESS) {
21432 return rc;
21433 }
21434 std::string policy_ref_bytes;
21435 rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21436 if (rc != TPM_RC_SUCCESS) {
21437 return rc;
21438 }
21439 std::string expiration_bytes;
21440 rc = Serialize_INT32(expiration, &expiration_bytes);
21441 if (rc != TPM_RC_SUCCESS) {
21442 return rc;
21443 }
21444 if (authorization_delegate) {
21445 // Encrypt just the parameter data, not the size.
21446 std::string tmp = nonce_tpm_bytes.substr(2);
21447 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21448 return TRUNKS_RC_ENCRYPTION_FAILED;
21449 }
21450 nonce_tpm_bytes.replace(2, std::string::npos, tmp);
21451 }
21452 std::unique_ptr<crypto::SecureHash> hash(
21453 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21454 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21455 hash->Update(auth_handle_name.data(), auth_handle_name.size());
21456 handle_section_bytes += auth_handle_bytes;
21457 command_size += auth_handle_bytes.size();
21458 hash->Update(policy_session_name.data(), policy_session_name.size());
21459 handle_section_bytes += policy_session_bytes;
21460 command_size += policy_session_bytes.size();
21461 hash->Update(nonce_tpm_bytes.data(), nonce_tpm_bytes.size());
21462 parameter_section_bytes += nonce_tpm_bytes;
21463 command_size += nonce_tpm_bytes.size();
21464 hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21465 parameter_section_bytes += cp_hash_a_bytes;
21466 command_size += cp_hash_a_bytes.size();
21467 hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21468 parameter_section_bytes += policy_ref_bytes;
21469 command_size += policy_ref_bytes.size();
21470 hash->Update(expiration_bytes.data(), expiration_bytes.size());
21471 parameter_section_bytes += expiration_bytes;
21472 command_size += expiration_bytes.size();
21473 std::string command_hash(32, 0);
21474 hash->Finish(std::data(command_hash), command_hash.size());
21475 std::string authorization_section_bytes;
21476 std::string authorization_size_bytes;
21477 if (authorization_delegate) {
21478 if (!authorization_delegate->GetCommandAuthorization(
21479 command_hash, is_command_parameter_encryption_possible,
21480 is_response_parameter_encryption_possible,
21481 &authorization_section_bytes)) {
21482 return TRUNKS_RC_AUTHORIZATION_FAILED;
21483 }
21484 if (!authorization_section_bytes.empty()) {
21485 tag = TPM_ST_SESSIONS;
21486 std::string tmp;
21487 rc = Serialize_UINT32(authorization_section_bytes.size(),
21488 &authorization_size_bytes);
21489 if (rc != TPM_RC_SUCCESS) {
21490 return rc;
21491 }
21492 command_size +=
21493 authorization_size_bytes.size() + authorization_section_bytes.size();
21494 }
21495 }
21496 std::string tag_bytes;
21497 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21498 if (rc != TPM_RC_SUCCESS) {
21499 return rc;
21500 }
21501 std::string command_size_bytes;
21502 rc = Serialize_UINT32(command_size, &command_size_bytes);
21503 if (rc != TPM_RC_SUCCESS) {
21504 return rc;
21505 }
21506 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21507 handle_section_bytes + authorization_size_bytes +
21508 authorization_section_bytes + parameter_section_bytes;
21509 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21510 VLOG(2) << "Command: "
21511 << base::HexEncode(serialized_command->data(),
21512 serialized_command->size());
21513 return TPM_RC_SUCCESS;
21514 }
21515
ParseResponse_PolicySecret(const std::string & response,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21516 TPM_RC Tpm::ParseResponse_PolicySecret(
21517 const std::string& response,
21518 TPM2B_TIMEOUT* timeout,
21519 TPMT_TK_AUTH* policy_ticket,
21520 AuthorizationDelegate* authorization_delegate) {
21521 VLOG(3) << __func__;
21522 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21523 TPM_RC rc = TPM_RC_SUCCESS;
21524 std::string buffer(response);
21525 TPM_ST tag;
21526 std::string tag_bytes;
21527 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21528 if (rc != TPM_RC_SUCCESS) {
21529 return rc;
21530 }
21531 UINT32 response_size;
21532 std::string response_size_bytes;
21533 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21534 if (rc != TPM_RC_SUCCESS) {
21535 return rc;
21536 }
21537 TPM_RC response_code;
21538 std::string response_code_bytes;
21539 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21540 if (rc != TPM_RC_SUCCESS) {
21541 return rc;
21542 }
21543 if (response_size != response.size()) {
21544 return TPM_RC_SIZE;
21545 }
21546 if (response_code != TPM_RC_SUCCESS) {
21547 return response_code;
21548 }
21549 TPM_CC command_code = TPM_CC_PolicySecret;
21550 std::string command_code_bytes;
21551 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21552 if (rc != TPM_RC_SUCCESS) {
21553 return rc;
21554 }
21555 std::string authorization_section_bytes;
21556 if (tag == TPM_ST_SESSIONS) {
21557 UINT32 parameter_section_size = buffer.size();
21558 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
21559 if (rc != TPM_RC_SUCCESS) {
21560 return rc;
21561 }
21562 if (parameter_section_size > buffer.size()) {
21563 return TPM_RC_INSUFFICIENT;
21564 }
21565 authorization_section_bytes = buffer.substr(parameter_section_size);
21566 // Keep the parameter section in |buffer|.
21567 buffer.erase(parameter_section_size);
21568 }
21569 std::unique_ptr<crypto::SecureHash> hash(
21570 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21571 hash->Update(response_code_bytes.data(), response_code_bytes.size());
21572 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21573 hash->Update(buffer.data(), buffer.size());
21574 std::string response_hash(32, 0);
21575 hash->Finish(std::data(response_hash), response_hash.size());
21576 if (tag == TPM_ST_SESSIONS) {
21577 if (!authorization_delegate)
21578 return TRUNKS_RC_AUTHORIZATION_FAILED;
21579 if (!authorization_delegate->CheckResponseAuthorization(
21580 response_hash, authorization_section_bytes)) {
21581 return TRUNKS_RC_AUTHORIZATION_FAILED;
21582 }
21583 }
21584 if (tag == TPM_ST_SESSIONS) {
21585 if (!authorization_delegate)
21586 return TRUNKS_RC_AUTHORIZATION_FAILED;
21587
21588 // Parse the encrypted parameter size.
21589 UINT16 size;
21590 std::string size_buffer = buffer.substr(0, 2);
21591 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
21592 return result;
21593 }
21594 if (buffer.size() < 2 + size) {
21595 return TPM_RC_INSUFFICIENT;
21596 }
21597
21598 // Decrypt just the parameter data, not the size.
21599 std::string decrypted_data = buffer.substr(2, size);
21600 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
21601 return TRUNKS_RC_ENCRYPTION_FAILED;
21602 }
21603 buffer.replace(2, size, decrypted_data);
21604 }
21605 std::string timeout_bytes;
21606 rc = Parse_TPM2B_TIMEOUT(&buffer, timeout, &timeout_bytes);
21607 if (rc != TPM_RC_SUCCESS) {
21608 return rc;
21609 }
21610 std::string policy_ticket_bytes;
21611 rc = Parse_TPMT_TK_AUTH(&buffer, policy_ticket, &policy_ticket_bytes);
21612 if (rc != TPM_RC_SUCCESS) {
21613 return rc;
21614 }
21615 return TPM_RC_SUCCESS;
21616 }
21617
PolicySecretErrorCallback(Tpm::PolicySecretResponse callback,TPM_RC response_code)21618 void PolicySecretErrorCallback(Tpm::PolicySecretResponse callback,
21619 TPM_RC response_code) {
21620 VLOG(1) << __func__;
21621 std::move(callback).Run(response_code, TPM2B_TIMEOUT(), TPMT_TK_AUTH());
21622 }
21623
PolicySecretResponseParser(Tpm::PolicySecretResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21624 void PolicySecretResponseParser(Tpm::PolicySecretResponse callback,
21625 AuthorizationDelegate* authorization_delegate,
21626 const std::string& response) {
21627 VLOG(1) << __func__;
21628 TPM2B_TIMEOUT timeout;
21629 TPMT_TK_AUTH policy_ticket;
21630 TPM_RC rc = Tpm::ParseResponse_PolicySecret(
21631 response, &timeout, &policy_ticket, authorization_delegate);
21632 if (rc != TPM_RC_SUCCESS) {
21633 base::OnceCallback<void(TPM_RC)> error_reporter =
21634 base::BindOnce(PolicySecretErrorCallback, std::move(callback));
21635 std::move(error_reporter).Run(rc);
21636 return;
21637 }
21638 std::move(callback).Run(rc, timeout, policy_ticket);
21639 }
21640
PolicySecret(const TPMI_DH_ENTITY & auth_handle,const std::string & auth_handle_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,AuthorizationDelegate * authorization_delegate,PolicySecretResponse callback)21641 void Tpm::PolicySecret(const TPMI_DH_ENTITY& auth_handle,
21642 const std::string& auth_handle_name,
21643 const TPMI_SH_POLICY& policy_session,
21644 const std::string& policy_session_name,
21645 const TPM2B_NONCE& nonce_tpm,
21646 const TPM2B_DIGEST& cp_hash_a,
21647 const TPM2B_NONCE& policy_ref,
21648 const INT32& expiration,
21649 AuthorizationDelegate* authorization_delegate,
21650 PolicySecretResponse callback) {
21651 VLOG(1) << __func__;
21652 std::string command;
21653 TPM_RC rc = SerializeCommand_PolicySecret(
21654 auth_handle, auth_handle_name, policy_session, policy_session_name,
21655 nonce_tpm, cp_hash_a, policy_ref, expiration, &command,
21656 authorization_delegate);
21657 if (rc != TPM_RC_SUCCESS) {
21658 base::OnceCallback<void(TPM_RC)> error_reporter =
21659 base::BindOnce(PolicySecretErrorCallback, std::move(callback));
21660 std::move(error_reporter).Run(rc);
21661 return;
21662 }
21663 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21664 PolicySecretResponseParser, std::move(callback), authorization_delegate);
21665 transceiver_->SendCommand(command, std::move(parser));
21666 }
21667
PolicySecretSync(const TPMI_DH_ENTITY & auth_handle,const std::string & auth_handle_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21668 TPM_RC Tpm::PolicySecretSync(const TPMI_DH_ENTITY& auth_handle,
21669 const std::string& auth_handle_name,
21670 const TPMI_SH_POLICY& policy_session,
21671 const std::string& policy_session_name,
21672 const TPM2B_NONCE& nonce_tpm,
21673 const TPM2B_DIGEST& cp_hash_a,
21674 const TPM2B_NONCE& policy_ref,
21675 const INT32& expiration,
21676 TPM2B_TIMEOUT* timeout,
21677 TPMT_TK_AUTH* policy_ticket,
21678 AuthorizationDelegate* authorization_delegate) {
21679 VLOG(1) << __func__;
21680 std::string command;
21681 TPM_RC rc = SerializeCommand_PolicySecret(
21682 auth_handle, auth_handle_name, policy_session, policy_session_name,
21683 nonce_tpm, cp_hash_a, policy_ref, expiration, &command,
21684 authorization_delegate);
21685 if (rc != TPM_RC_SUCCESS) {
21686 return rc;
21687 }
21688 std::string response = transceiver_->SendCommandAndWait(command);
21689 rc = ParseResponse_PolicySecret(response, timeout, policy_ticket,
21690 authorization_delegate);
21691 return rc;
21692 }
21693
SerializeCommand_PolicyTicket(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_TIMEOUT & timeout,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & auth_name,const TPMT_TK_AUTH & ticket,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21694 TPM_RC Tpm::SerializeCommand_PolicyTicket(
21695 const TPMI_SH_POLICY& policy_session,
21696 const std::string& policy_session_name,
21697 const TPM2B_TIMEOUT& timeout,
21698 const TPM2B_DIGEST& cp_hash_a,
21699 const TPM2B_NONCE& policy_ref,
21700 const TPM2B_NAME& auth_name,
21701 const TPMT_TK_AUTH& ticket,
21702 std::string* serialized_command,
21703 AuthorizationDelegate* authorization_delegate) {
21704 VLOG(3) << __func__;
21705 TPM_RC rc = TPM_RC_SUCCESS;
21706 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21707 UINT32 command_size = 10; // Header size.
21708 std::string handle_section_bytes;
21709 std::string parameter_section_bytes;
21710 TPM_CC command_code = TPM_CC_PolicyTicket;
21711 bool is_command_parameter_encryption_possible = true;
21712 bool is_response_parameter_encryption_possible = false;
21713 std::string command_code_bytes;
21714 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21715 if (rc != TPM_RC_SUCCESS) {
21716 return rc;
21717 }
21718 std::string policy_session_bytes;
21719 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21720 if (rc != TPM_RC_SUCCESS) {
21721 return rc;
21722 }
21723 std::string timeout_bytes;
21724 rc = Serialize_TPM2B_TIMEOUT(timeout, &timeout_bytes);
21725 if (rc != TPM_RC_SUCCESS) {
21726 return rc;
21727 }
21728 std::string cp_hash_a_bytes;
21729 rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21730 if (rc != TPM_RC_SUCCESS) {
21731 return rc;
21732 }
21733 std::string policy_ref_bytes;
21734 rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21735 if (rc != TPM_RC_SUCCESS) {
21736 return rc;
21737 }
21738 std::string auth_name_bytes;
21739 rc = Serialize_TPM2B_NAME(auth_name, &auth_name_bytes);
21740 if (rc != TPM_RC_SUCCESS) {
21741 return rc;
21742 }
21743 std::string ticket_bytes;
21744 rc = Serialize_TPMT_TK_AUTH(ticket, &ticket_bytes);
21745 if (rc != TPM_RC_SUCCESS) {
21746 return rc;
21747 }
21748 if (authorization_delegate) {
21749 // Encrypt just the parameter data, not the size.
21750 std::string tmp = timeout_bytes.substr(2);
21751 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21752 return TRUNKS_RC_ENCRYPTION_FAILED;
21753 }
21754 timeout_bytes.replace(2, std::string::npos, tmp);
21755 }
21756 std::unique_ptr<crypto::SecureHash> hash(
21757 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21758 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21759 hash->Update(policy_session_name.data(), policy_session_name.size());
21760 handle_section_bytes += policy_session_bytes;
21761 command_size += policy_session_bytes.size();
21762 hash->Update(timeout_bytes.data(), timeout_bytes.size());
21763 parameter_section_bytes += timeout_bytes;
21764 command_size += timeout_bytes.size();
21765 hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21766 parameter_section_bytes += cp_hash_a_bytes;
21767 command_size += cp_hash_a_bytes.size();
21768 hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21769 parameter_section_bytes += policy_ref_bytes;
21770 command_size += policy_ref_bytes.size();
21771 hash->Update(auth_name_bytes.data(), auth_name_bytes.size());
21772 parameter_section_bytes += auth_name_bytes;
21773 command_size += auth_name_bytes.size();
21774 hash->Update(ticket_bytes.data(), ticket_bytes.size());
21775 parameter_section_bytes += ticket_bytes;
21776 command_size += ticket_bytes.size();
21777 std::string command_hash(32, 0);
21778 hash->Finish(std::data(command_hash), command_hash.size());
21779 std::string authorization_section_bytes;
21780 std::string authorization_size_bytes;
21781 if (authorization_delegate) {
21782 if (!authorization_delegate->GetCommandAuthorization(
21783 command_hash, is_command_parameter_encryption_possible,
21784 is_response_parameter_encryption_possible,
21785 &authorization_section_bytes)) {
21786 return TRUNKS_RC_AUTHORIZATION_FAILED;
21787 }
21788 if (!authorization_section_bytes.empty()) {
21789 tag = TPM_ST_SESSIONS;
21790 std::string tmp;
21791 rc = Serialize_UINT32(authorization_section_bytes.size(),
21792 &authorization_size_bytes);
21793 if (rc != TPM_RC_SUCCESS) {
21794 return rc;
21795 }
21796 command_size +=
21797 authorization_size_bytes.size() + authorization_section_bytes.size();
21798 }
21799 }
21800 std::string tag_bytes;
21801 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21802 if (rc != TPM_RC_SUCCESS) {
21803 return rc;
21804 }
21805 std::string command_size_bytes;
21806 rc = Serialize_UINT32(command_size, &command_size_bytes);
21807 if (rc != TPM_RC_SUCCESS) {
21808 return rc;
21809 }
21810 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21811 handle_section_bytes + authorization_size_bytes +
21812 authorization_section_bytes + parameter_section_bytes;
21813 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21814 VLOG(2) << "Command: "
21815 << base::HexEncode(serialized_command->data(),
21816 serialized_command->size());
21817 return TPM_RC_SUCCESS;
21818 }
21819
ParseResponse_PolicyTicket(const std::string & response,AuthorizationDelegate * authorization_delegate)21820 TPM_RC Tpm::ParseResponse_PolicyTicket(
21821 const std::string& response,
21822 AuthorizationDelegate* authorization_delegate) {
21823 VLOG(3) << __func__;
21824 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21825 TPM_RC rc = TPM_RC_SUCCESS;
21826 std::string buffer(response);
21827 TPM_ST tag;
21828 std::string tag_bytes;
21829 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21830 if (rc != TPM_RC_SUCCESS) {
21831 return rc;
21832 }
21833 UINT32 response_size;
21834 std::string response_size_bytes;
21835 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21836 if (rc != TPM_RC_SUCCESS) {
21837 return rc;
21838 }
21839 TPM_RC response_code;
21840 std::string response_code_bytes;
21841 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21842 if (rc != TPM_RC_SUCCESS) {
21843 return rc;
21844 }
21845 if (response_size != response.size()) {
21846 return TPM_RC_SIZE;
21847 }
21848 if (response_code != TPM_RC_SUCCESS) {
21849 return response_code;
21850 }
21851 TPM_CC command_code = TPM_CC_PolicyTicket;
21852 std::string command_code_bytes;
21853 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21854 if (rc != TPM_RC_SUCCESS) {
21855 return rc;
21856 }
21857 std::string authorization_section_bytes;
21858 if (tag == TPM_ST_SESSIONS) {
21859 UINT32 parameter_section_size = buffer.size();
21860 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
21861 if (rc != TPM_RC_SUCCESS) {
21862 return rc;
21863 }
21864 if (parameter_section_size > buffer.size()) {
21865 return TPM_RC_INSUFFICIENT;
21866 }
21867 authorization_section_bytes = buffer.substr(parameter_section_size);
21868 // Keep the parameter section in |buffer|.
21869 buffer.erase(parameter_section_size);
21870 }
21871 std::unique_ptr<crypto::SecureHash> hash(
21872 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21873 hash->Update(response_code_bytes.data(), response_code_bytes.size());
21874 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21875 hash->Update(buffer.data(), buffer.size());
21876 std::string response_hash(32, 0);
21877 hash->Finish(std::data(response_hash), response_hash.size());
21878 if (tag == TPM_ST_SESSIONS) {
21879 if (!authorization_delegate)
21880 return TRUNKS_RC_AUTHORIZATION_FAILED;
21881 if (!authorization_delegate->CheckResponseAuthorization(
21882 response_hash, authorization_section_bytes)) {
21883 return TRUNKS_RC_AUTHORIZATION_FAILED;
21884 }
21885 }
21886 return TPM_RC_SUCCESS;
21887 }
21888
PolicyTicketErrorCallback(Tpm::PolicyTicketResponse callback,TPM_RC response_code)21889 void PolicyTicketErrorCallback(Tpm::PolicyTicketResponse callback,
21890 TPM_RC response_code) {
21891 VLOG(1) << __func__;
21892 std::move(callback).Run(response_code);
21893 }
21894
PolicyTicketResponseParser(Tpm::PolicyTicketResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21895 void PolicyTicketResponseParser(Tpm::PolicyTicketResponse callback,
21896 AuthorizationDelegate* authorization_delegate,
21897 const std::string& response) {
21898 VLOG(1) << __func__;
21899 TPM_RC rc = Tpm::ParseResponse_PolicyTicket(response, authorization_delegate);
21900 if (rc != TPM_RC_SUCCESS) {
21901 base::OnceCallback<void(TPM_RC)> error_reporter =
21902 base::BindOnce(PolicyTicketErrorCallback, std::move(callback));
21903 std::move(error_reporter).Run(rc);
21904 return;
21905 }
21906 std::move(callback).Run(rc);
21907 }
21908
PolicyTicket(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_TIMEOUT & timeout,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & auth_name,const TPMT_TK_AUTH & ticket,AuthorizationDelegate * authorization_delegate,PolicyTicketResponse callback)21909 void Tpm::PolicyTicket(const TPMI_SH_POLICY& policy_session,
21910 const std::string& policy_session_name,
21911 const TPM2B_TIMEOUT& timeout,
21912 const TPM2B_DIGEST& cp_hash_a,
21913 const TPM2B_NONCE& policy_ref,
21914 const TPM2B_NAME& auth_name,
21915 const TPMT_TK_AUTH& ticket,
21916 AuthorizationDelegate* authorization_delegate,
21917 PolicyTicketResponse callback) {
21918 VLOG(1) << __func__;
21919 std::string command;
21920 TPM_RC rc = SerializeCommand_PolicyTicket(
21921 policy_session, policy_session_name, timeout, cp_hash_a, policy_ref,
21922 auth_name, ticket, &command, authorization_delegate);
21923 if (rc != TPM_RC_SUCCESS) {
21924 base::OnceCallback<void(TPM_RC)> error_reporter =
21925 base::BindOnce(PolicyTicketErrorCallback, std::move(callback));
21926 std::move(error_reporter).Run(rc);
21927 return;
21928 }
21929 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21930 PolicyTicketResponseParser, std::move(callback), authorization_delegate);
21931 transceiver_->SendCommand(command, std::move(parser));
21932 }
21933
PolicyTicketSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_TIMEOUT & timeout,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & auth_name,const TPMT_TK_AUTH & ticket,AuthorizationDelegate * authorization_delegate)21934 TPM_RC Tpm::PolicyTicketSync(const TPMI_SH_POLICY& policy_session,
21935 const std::string& policy_session_name,
21936 const TPM2B_TIMEOUT& timeout,
21937 const TPM2B_DIGEST& cp_hash_a,
21938 const TPM2B_NONCE& policy_ref,
21939 const TPM2B_NAME& auth_name,
21940 const TPMT_TK_AUTH& ticket,
21941 AuthorizationDelegate* authorization_delegate) {
21942 VLOG(1) << __func__;
21943 std::string command;
21944 TPM_RC rc = SerializeCommand_PolicyTicket(
21945 policy_session, policy_session_name, timeout, cp_hash_a, policy_ref,
21946 auth_name, ticket, &command, authorization_delegate);
21947 if (rc != TPM_RC_SUCCESS) {
21948 return rc;
21949 }
21950 std::string response = transceiver_->SendCommandAndWait(command);
21951 rc = ParseResponse_PolicyTicket(response, authorization_delegate);
21952 return rc;
21953 }
21954
SerializeCommand_PolicyOR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21955 TPM_RC Tpm::SerializeCommand_PolicyOR(
21956 const TPMI_SH_POLICY& policy_session,
21957 const std::string& policy_session_name,
21958 const TPML_DIGEST& p_hash_list,
21959 std::string* serialized_command,
21960 AuthorizationDelegate* authorization_delegate) {
21961 VLOG(3) << __func__;
21962 TPM_RC rc = TPM_RC_SUCCESS;
21963 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21964 UINT32 command_size = 10; // Header size.
21965 std::string handle_section_bytes;
21966 std::string parameter_section_bytes;
21967 TPM_CC command_code = TPM_CC_PolicyOR;
21968 bool is_command_parameter_encryption_possible = false;
21969 bool is_response_parameter_encryption_possible = false;
21970 std::string command_code_bytes;
21971 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21972 if (rc != TPM_RC_SUCCESS) {
21973 return rc;
21974 }
21975 std::string policy_session_bytes;
21976 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21977 if (rc != TPM_RC_SUCCESS) {
21978 return rc;
21979 }
21980 std::string p_hash_list_bytes;
21981 rc = Serialize_TPML_DIGEST(p_hash_list, &p_hash_list_bytes);
21982 if (rc != TPM_RC_SUCCESS) {
21983 return rc;
21984 }
21985 std::unique_ptr<crypto::SecureHash> hash(
21986 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21987 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21988 hash->Update(policy_session_name.data(), policy_session_name.size());
21989 handle_section_bytes += policy_session_bytes;
21990 command_size += policy_session_bytes.size();
21991 hash->Update(p_hash_list_bytes.data(), p_hash_list_bytes.size());
21992 parameter_section_bytes += p_hash_list_bytes;
21993 command_size += p_hash_list_bytes.size();
21994 std::string command_hash(32, 0);
21995 hash->Finish(std::data(command_hash), command_hash.size());
21996 std::string authorization_section_bytes;
21997 std::string authorization_size_bytes;
21998 if (authorization_delegate) {
21999 if (!authorization_delegate->GetCommandAuthorization(
22000 command_hash, is_command_parameter_encryption_possible,
22001 is_response_parameter_encryption_possible,
22002 &authorization_section_bytes)) {
22003 return TRUNKS_RC_AUTHORIZATION_FAILED;
22004 }
22005 if (!authorization_section_bytes.empty()) {
22006 tag = TPM_ST_SESSIONS;
22007 std::string tmp;
22008 rc = Serialize_UINT32(authorization_section_bytes.size(),
22009 &authorization_size_bytes);
22010 if (rc != TPM_RC_SUCCESS) {
22011 return rc;
22012 }
22013 command_size +=
22014 authorization_size_bytes.size() + authorization_section_bytes.size();
22015 }
22016 }
22017 std::string tag_bytes;
22018 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22019 if (rc != TPM_RC_SUCCESS) {
22020 return rc;
22021 }
22022 std::string command_size_bytes;
22023 rc = Serialize_UINT32(command_size, &command_size_bytes);
22024 if (rc != TPM_RC_SUCCESS) {
22025 return rc;
22026 }
22027 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22028 handle_section_bytes + authorization_size_bytes +
22029 authorization_section_bytes + parameter_section_bytes;
22030 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22031 VLOG(2) << "Command: "
22032 << base::HexEncode(serialized_command->data(),
22033 serialized_command->size());
22034 return TPM_RC_SUCCESS;
22035 }
22036
ParseResponse_PolicyOR(const std::string & response,AuthorizationDelegate * authorization_delegate)22037 TPM_RC Tpm::ParseResponse_PolicyOR(
22038 const std::string& response,
22039 AuthorizationDelegate* authorization_delegate) {
22040 VLOG(3) << __func__;
22041 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22042 TPM_RC rc = TPM_RC_SUCCESS;
22043 std::string buffer(response);
22044 TPM_ST tag;
22045 std::string tag_bytes;
22046 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22047 if (rc != TPM_RC_SUCCESS) {
22048 return rc;
22049 }
22050 UINT32 response_size;
22051 std::string response_size_bytes;
22052 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22053 if (rc != TPM_RC_SUCCESS) {
22054 return rc;
22055 }
22056 TPM_RC response_code;
22057 std::string response_code_bytes;
22058 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22059 if (rc != TPM_RC_SUCCESS) {
22060 return rc;
22061 }
22062 if (response_size != response.size()) {
22063 return TPM_RC_SIZE;
22064 }
22065 if (response_code != TPM_RC_SUCCESS) {
22066 return response_code;
22067 }
22068 TPM_CC command_code = TPM_CC_PolicyOR;
22069 std::string command_code_bytes;
22070 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22071 if (rc != TPM_RC_SUCCESS) {
22072 return rc;
22073 }
22074 std::string authorization_section_bytes;
22075 if (tag == TPM_ST_SESSIONS) {
22076 UINT32 parameter_section_size = buffer.size();
22077 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
22078 if (rc != TPM_RC_SUCCESS) {
22079 return rc;
22080 }
22081 if (parameter_section_size > buffer.size()) {
22082 return TPM_RC_INSUFFICIENT;
22083 }
22084 authorization_section_bytes = buffer.substr(parameter_section_size);
22085 // Keep the parameter section in |buffer|.
22086 buffer.erase(parameter_section_size);
22087 }
22088 std::unique_ptr<crypto::SecureHash> hash(
22089 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22090 hash->Update(response_code_bytes.data(), response_code_bytes.size());
22091 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22092 hash->Update(buffer.data(), buffer.size());
22093 std::string response_hash(32, 0);
22094 hash->Finish(std::data(response_hash), response_hash.size());
22095 if (tag == TPM_ST_SESSIONS) {
22096 if (!authorization_delegate)
22097 return TRUNKS_RC_AUTHORIZATION_FAILED;
22098 if (!authorization_delegate->CheckResponseAuthorization(
22099 response_hash, authorization_section_bytes)) {
22100 return TRUNKS_RC_AUTHORIZATION_FAILED;
22101 }
22102 }
22103 return TPM_RC_SUCCESS;
22104 }
22105
PolicyORErrorCallback(Tpm::PolicyORResponse callback,TPM_RC response_code)22106 void PolicyORErrorCallback(Tpm::PolicyORResponse callback,
22107 TPM_RC response_code) {
22108 VLOG(1) << __func__;
22109 std::move(callback).Run(response_code);
22110 }
22111
PolicyORResponseParser(Tpm::PolicyORResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22112 void PolicyORResponseParser(Tpm::PolicyORResponse callback,
22113 AuthorizationDelegate* authorization_delegate,
22114 const std::string& response) {
22115 VLOG(1) << __func__;
22116 TPM_RC rc = Tpm::ParseResponse_PolicyOR(response, authorization_delegate);
22117 if (rc != TPM_RC_SUCCESS) {
22118 base::OnceCallback<void(TPM_RC)> error_reporter =
22119 base::BindOnce(PolicyORErrorCallback, std::move(callback));
22120 std::move(error_reporter).Run(rc);
22121 return;
22122 }
22123 std::move(callback).Run(rc);
22124 }
22125
PolicyOR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,AuthorizationDelegate * authorization_delegate,PolicyORResponse callback)22126 void Tpm::PolicyOR(const TPMI_SH_POLICY& policy_session,
22127 const std::string& policy_session_name,
22128 const TPML_DIGEST& p_hash_list,
22129 AuthorizationDelegate* authorization_delegate,
22130 PolicyORResponse callback) {
22131 VLOG(1) << __func__;
22132 std::string command;
22133 TPM_RC rc =
22134 SerializeCommand_PolicyOR(policy_session, policy_session_name,
22135 p_hash_list, &command, authorization_delegate);
22136 if (rc != TPM_RC_SUCCESS) {
22137 base::OnceCallback<void(TPM_RC)> error_reporter =
22138 base::BindOnce(PolicyORErrorCallback, std::move(callback));
22139 std::move(error_reporter).Run(rc);
22140 return;
22141 }
22142 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22143 PolicyORResponseParser, std::move(callback), authorization_delegate);
22144 transceiver_->SendCommand(command, std::move(parser));
22145 }
22146
PolicyORSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,AuthorizationDelegate * authorization_delegate)22147 TPM_RC Tpm::PolicyORSync(const TPMI_SH_POLICY& policy_session,
22148 const std::string& policy_session_name,
22149 const TPML_DIGEST& p_hash_list,
22150 AuthorizationDelegate* authorization_delegate) {
22151 VLOG(1) << __func__;
22152 std::string command;
22153 TPM_RC rc =
22154 SerializeCommand_PolicyOR(policy_session, policy_session_name,
22155 p_hash_list, &command, authorization_delegate);
22156 if (rc != TPM_RC_SUCCESS) {
22157 return rc;
22158 }
22159 std::string response = transceiver_->SendCommandAndWait(command);
22160 rc = ParseResponse_PolicyOR(response, authorization_delegate);
22161 return rc;
22162 }
22163
SerializeCommand_PolicyPCR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & pcr_digest,const TPML_PCR_SELECTION & pcrs,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22164 TPM_RC Tpm::SerializeCommand_PolicyPCR(
22165 const TPMI_SH_POLICY& policy_session,
22166 const std::string& policy_session_name,
22167 const TPM2B_DIGEST& pcr_digest,
22168 const TPML_PCR_SELECTION& pcrs,
22169 std::string* serialized_command,
22170 AuthorizationDelegate* authorization_delegate) {
22171 VLOG(3) << __func__;
22172 TPM_RC rc = TPM_RC_SUCCESS;
22173 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22174 UINT32 command_size = 10; // Header size.
22175 std::string handle_section_bytes;
22176 std::string parameter_section_bytes;
22177 TPM_CC command_code = TPM_CC_PolicyPCR;
22178 bool is_command_parameter_encryption_possible = true;
22179 bool is_response_parameter_encryption_possible = false;
22180 std::string command_code_bytes;
22181 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22182 if (rc != TPM_RC_SUCCESS) {
22183 return rc;
22184 }
22185 std::string policy_session_bytes;
22186 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22187 if (rc != TPM_RC_SUCCESS) {
22188 return rc;
22189 }
22190 std::string pcr_digest_bytes;
22191 rc = Serialize_TPM2B_DIGEST(pcr_digest, &pcr_digest_bytes);
22192 if (rc != TPM_RC_SUCCESS) {
22193 return rc;
22194 }
22195 std::string pcrs_bytes;
22196 rc = Serialize_TPML_PCR_SELECTION(pcrs, &pcrs_bytes);
22197 if (rc != TPM_RC_SUCCESS) {
22198 return rc;
22199 }
22200 if (authorization_delegate) {
22201 // Encrypt just the parameter data, not the size.
22202 std::string tmp = pcr_digest_bytes.substr(2);
22203 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22204 return TRUNKS_RC_ENCRYPTION_FAILED;
22205 }
22206 pcr_digest_bytes.replace(2, std::string::npos, tmp);
22207 }
22208 std::unique_ptr<crypto::SecureHash> hash(
22209 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22210 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22211 hash->Update(policy_session_name.data(), policy_session_name.size());
22212 handle_section_bytes += policy_session_bytes;
22213 command_size += policy_session_bytes.size();
22214 hash->Update(pcr_digest_bytes.data(), pcr_digest_bytes.size());
22215 parameter_section_bytes += pcr_digest_bytes;
22216 command_size += pcr_digest_bytes.size();
22217 hash->Update(pcrs_bytes.data(), pcrs_bytes.size());
22218 parameter_section_bytes += pcrs_bytes;
22219 command_size += pcrs_bytes.size();
22220 std::string command_hash(32, 0);
22221 hash->Finish(std::data(command_hash), command_hash.size());
22222 std::string authorization_section_bytes;
22223 std::string authorization_size_bytes;
22224 if (authorization_delegate) {
22225 if (!authorization_delegate->GetCommandAuthorization(
22226 command_hash, is_command_parameter_encryption_possible,
22227 is_response_parameter_encryption_possible,
22228 &authorization_section_bytes)) {
22229 return TRUNKS_RC_AUTHORIZATION_FAILED;
22230 }
22231 if (!authorization_section_bytes.empty()) {
22232 tag = TPM_ST_SESSIONS;
22233 std::string tmp;
22234 rc = Serialize_UINT32(authorization_section_bytes.size(),
22235 &authorization_size_bytes);
22236 if (rc != TPM_RC_SUCCESS) {
22237 return rc;
22238 }
22239 command_size +=
22240 authorization_size_bytes.size() + authorization_section_bytes.size();
22241 }
22242 }
22243 std::string tag_bytes;
22244 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22245 if (rc != TPM_RC_SUCCESS) {
22246 return rc;
22247 }
22248 std::string command_size_bytes;
22249 rc = Serialize_UINT32(command_size, &command_size_bytes);
22250 if (rc != TPM_RC_SUCCESS) {
22251 return rc;
22252 }
22253 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22254 handle_section_bytes + authorization_size_bytes +
22255 authorization_section_bytes + parameter_section_bytes;
22256 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22257 VLOG(2) << "Command: "
22258 << base::HexEncode(serialized_command->data(),
22259 serialized_command->size());
22260 return TPM_RC_SUCCESS;
22261 }
22262
ParseResponse_PolicyPCR(const std::string & response,AuthorizationDelegate * authorization_delegate)22263 TPM_RC Tpm::ParseResponse_PolicyPCR(
22264 const std::string& response,
22265 AuthorizationDelegate* authorization_delegate) {
22266 VLOG(3) << __func__;
22267 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22268 TPM_RC rc = TPM_RC_SUCCESS;
22269 std::string buffer(response);
22270 TPM_ST tag;
22271 std::string tag_bytes;
22272 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22273 if (rc != TPM_RC_SUCCESS) {
22274 return rc;
22275 }
22276 UINT32 response_size;
22277 std::string response_size_bytes;
22278 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22279 if (rc != TPM_RC_SUCCESS) {
22280 return rc;
22281 }
22282 TPM_RC response_code;
22283 std::string response_code_bytes;
22284 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22285 if (rc != TPM_RC_SUCCESS) {
22286 return rc;
22287 }
22288 if (response_size != response.size()) {
22289 return TPM_RC_SIZE;
22290 }
22291 if (response_code != TPM_RC_SUCCESS) {
22292 return response_code;
22293 }
22294 TPM_CC command_code = TPM_CC_PolicyPCR;
22295 std::string command_code_bytes;
22296 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22297 if (rc != TPM_RC_SUCCESS) {
22298 return rc;
22299 }
22300 std::string authorization_section_bytes;
22301 if (tag == TPM_ST_SESSIONS) {
22302 UINT32 parameter_section_size = buffer.size();
22303 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
22304 if (rc != TPM_RC_SUCCESS) {
22305 return rc;
22306 }
22307 if (parameter_section_size > buffer.size()) {
22308 return TPM_RC_INSUFFICIENT;
22309 }
22310 authorization_section_bytes = buffer.substr(parameter_section_size);
22311 // Keep the parameter section in |buffer|.
22312 buffer.erase(parameter_section_size);
22313 }
22314 std::unique_ptr<crypto::SecureHash> hash(
22315 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22316 hash->Update(response_code_bytes.data(), response_code_bytes.size());
22317 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22318 hash->Update(buffer.data(), buffer.size());
22319 std::string response_hash(32, 0);
22320 hash->Finish(std::data(response_hash), response_hash.size());
22321 if (tag == TPM_ST_SESSIONS) {
22322 if (!authorization_delegate)
22323 return TRUNKS_RC_AUTHORIZATION_FAILED;
22324 if (!authorization_delegate->CheckResponseAuthorization(
22325 response_hash, authorization_section_bytes)) {
22326 return TRUNKS_RC_AUTHORIZATION_FAILED;
22327 }
22328 }
22329 return TPM_RC_SUCCESS;
22330 }
22331
PolicyPCRErrorCallback(Tpm::PolicyPCRResponse callback,TPM_RC response_code)22332 void PolicyPCRErrorCallback(Tpm::PolicyPCRResponse callback,
22333 TPM_RC response_code) {
22334 VLOG(1) << __func__;
22335 std::move(callback).Run(response_code);
22336 }
22337
PolicyPCRResponseParser(Tpm::PolicyPCRResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22338 void PolicyPCRResponseParser(Tpm::PolicyPCRResponse callback,
22339 AuthorizationDelegate* authorization_delegate,
22340 const std::string& response) {
22341 VLOG(1) << __func__;
22342 TPM_RC rc = Tpm::ParseResponse_PolicyPCR(response, authorization_delegate);
22343 if (rc != TPM_RC_SUCCESS) {
22344 base::OnceCallback<void(TPM_RC)> error_reporter =
22345 base::BindOnce(PolicyPCRErrorCallback, std::move(callback));
22346 std::move(error_reporter).Run(rc);
22347 return;
22348 }
22349 std::move(callback).Run(rc);
22350 }
22351
PolicyPCR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & pcr_digest,const TPML_PCR_SELECTION & pcrs,AuthorizationDelegate * authorization_delegate,PolicyPCRResponse callback)22352 void Tpm::PolicyPCR(const TPMI_SH_POLICY& policy_session,
22353 const std::string& policy_session_name,
22354 const TPM2B_DIGEST& pcr_digest,
22355 const TPML_PCR_SELECTION& pcrs,
22356 AuthorizationDelegate* authorization_delegate,
22357 PolicyPCRResponse callback) {
22358 VLOG(1) << __func__;
22359 std::string command;
22360 TPM_RC rc = SerializeCommand_PolicyPCR(policy_session, policy_session_name,
22361 pcr_digest, pcrs, &command,
22362 authorization_delegate);
22363 if (rc != TPM_RC_SUCCESS) {
22364 base::OnceCallback<void(TPM_RC)> error_reporter =
22365 base::BindOnce(PolicyPCRErrorCallback, std::move(callback));
22366 std::move(error_reporter).Run(rc);
22367 return;
22368 }
22369 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22370 PolicyPCRResponseParser, std::move(callback), authorization_delegate);
22371 transceiver_->SendCommand(command, std::move(parser));
22372 }
22373
PolicyPCRSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & pcr_digest,const TPML_PCR_SELECTION & pcrs,AuthorizationDelegate * authorization_delegate)22374 TPM_RC Tpm::PolicyPCRSync(const TPMI_SH_POLICY& policy_session,
22375 const std::string& policy_session_name,
22376 const TPM2B_DIGEST& pcr_digest,
22377 const TPML_PCR_SELECTION& pcrs,
22378 AuthorizationDelegate* authorization_delegate) {
22379 VLOG(1) << __func__;
22380 std::string command;
22381 TPM_RC rc = SerializeCommand_PolicyPCR(policy_session, policy_session_name,
22382 pcr_digest, pcrs, &command,
22383 authorization_delegate);
22384 if (rc != TPM_RC_SUCCESS) {
22385 return rc;
22386 }
22387 std::string response = transceiver_->SendCommandAndWait(command);
22388 rc = ParseResponse_PolicyPCR(response, authorization_delegate);
22389 return rc;
22390 }
22391
SerializeCommand_PolicyLocality(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22392 TPM_RC Tpm::SerializeCommand_PolicyLocality(
22393 const TPMI_SH_POLICY& policy_session,
22394 const std::string& policy_session_name,
22395 const TPMA_LOCALITY& locality,
22396 std::string* serialized_command,
22397 AuthorizationDelegate* authorization_delegate) {
22398 VLOG(3) << __func__;
22399 TPM_RC rc = TPM_RC_SUCCESS;
22400 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22401 UINT32 command_size = 10; // Header size.
22402 std::string handle_section_bytes;
22403 std::string parameter_section_bytes;
22404 TPM_CC command_code = TPM_CC_PolicyLocality;
22405 bool is_command_parameter_encryption_possible = false;
22406 bool is_response_parameter_encryption_possible = false;
22407 std::string command_code_bytes;
22408 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22409 if (rc != TPM_RC_SUCCESS) {
22410 return rc;
22411 }
22412 std::string policy_session_bytes;
22413 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22414 if (rc != TPM_RC_SUCCESS) {
22415 return rc;
22416 }
22417 std::string locality_bytes;
22418 rc = Serialize_TPMA_LOCALITY(locality, &locality_bytes);
22419 if (rc != TPM_RC_SUCCESS) {
22420 return rc;
22421 }
22422 std::unique_ptr<crypto::SecureHash> hash(
22423 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22424 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22425 hash->Update(policy_session_name.data(), policy_session_name.size());
22426 handle_section_bytes += policy_session_bytes;
22427 command_size += policy_session_bytes.size();
22428 hash->Update(locality_bytes.data(), locality_bytes.size());
22429 parameter_section_bytes += locality_bytes;
22430 command_size += locality_bytes.size();
22431 std::string command_hash(32, 0);
22432 hash->Finish(std::data(command_hash), command_hash.size());
22433 std::string authorization_section_bytes;
22434 std::string authorization_size_bytes;
22435 if (authorization_delegate) {
22436 if (!authorization_delegate->GetCommandAuthorization(
22437 command_hash, is_command_parameter_encryption_possible,
22438 is_response_parameter_encryption_possible,
22439 &authorization_section_bytes)) {
22440 return TRUNKS_RC_AUTHORIZATION_FAILED;
22441 }
22442 if (!authorization_section_bytes.empty()) {
22443 tag = TPM_ST_SESSIONS;
22444 std::string tmp;
22445 rc = Serialize_UINT32(authorization_section_bytes.size(),
22446 &authorization_size_bytes);
22447 if (rc != TPM_RC_SUCCESS) {
22448 return rc;
22449 }
22450 command_size +=
22451 authorization_size_bytes.size() + authorization_section_bytes.size();
22452 }
22453 }
22454 std::string tag_bytes;
22455 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22456 if (rc != TPM_RC_SUCCESS) {
22457 return rc;
22458 }
22459 std::string command_size_bytes;
22460 rc = Serialize_UINT32(command_size, &command_size_bytes);
22461 if (rc != TPM_RC_SUCCESS) {
22462 return rc;
22463 }
22464 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22465 handle_section_bytes + authorization_size_bytes +
22466 authorization_section_bytes + parameter_section_bytes;
22467 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22468 VLOG(2) << "Command: "
22469 << base::HexEncode(serialized_command->data(),
22470 serialized_command->size());
22471 return TPM_RC_SUCCESS;
22472 }
22473
ParseResponse_PolicyLocality(const std::string & response,AuthorizationDelegate * authorization_delegate)22474 TPM_RC Tpm::ParseResponse_PolicyLocality(
22475 const std::string& response,
22476 AuthorizationDelegate* authorization_delegate) {
22477 VLOG(3) << __func__;
22478 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22479 TPM_RC rc = TPM_RC_SUCCESS;
22480 std::string buffer(response);
22481 TPM_ST tag;
22482 std::string tag_bytes;
22483 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22484 if (rc != TPM_RC_SUCCESS) {
22485 return rc;
22486 }
22487 UINT32 response_size;
22488 std::string response_size_bytes;
22489 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22490 if (rc != TPM_RC_SUCCESS) {
22491 return rc;
22492 }
22493 TPM_RC response_code;
22494 std::string response_code_bytes;
22495 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22496 if (rc != TPM_RC_SUCCESS) {
22497 return rc;
22498 }
22499 if (response_size != response.size()) {
22500 return TPM_RC_SIZE;
22501 }
22502 if (response_code != TPM_RC_SUCCESS) {
22503 return response_code;
22504 }
22505 TPM_CC command_code = TPM_CC_PolicyLocality;
22506 std::string command_code_bytes;
22507 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22508 if (rc != TPM_RC_SUCCESS) {
22509 return rc;
22510 }
22511 std::string authorization_section_bytes;
22512 if (tag == TPM_ST_SESSIONS) {
22513 UINT32 parameter_section_size = buffer.size();
22514 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
22515 if (rc != TPM_RC_SUCCESS) {
22516 return rc;
22517 }
22518 if (parameter_section_size > buffer.size()) {
22519 return TPM_RC_INSUFFICIENT;
22520 }
22521 authorization_section_bytes = buffer.substr(parameter_section_size);
22522 // Keep the parameter section in |buffer|.
22523 buffer.erase(parameter_section_size);
22524 }
22525 std::unique_ptr<crypto::SecureHash> hash(
22526 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22527 hash->Update(response_code_bytes.data(), response_code_bytes.size());
22528 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22529 hash->Update(buffer.data(), buffer.size());
22530 std::string response_hash(32, 0);
22531 hash->Finish(std::data(response_hash), response_hash.size());
22532 if (tag == TPM_ST_SESSIONS) {
22533 if (!authorization_delegate)
22534 return TRUNKS_RC_AUTHORIZATION_FAILED;
22535 if (!authorization_delegate->CheckResponseAuthorization(
22536 response_hash, authorization_section_bytes)) {
22537 return TRUNKS_RC_AUTHORIZATION_FAILED;
22538 }
22539 }
22540 return TPM_RC_SUCCESS;
22541 }
22542
PolicyLocalityErrorCallback(Tpm::PolicyLocalityResponse callback,TPM_RC response_code)22543 void PolicyLocalityErrorCallback(Tpm::PolicyLocalityResponse callback,
22544 TPM_RC response_code) {
22545 VLOG(1) << __func__;
22546 std::move(callback).Run(response_code);
22547 }
22548
PolicyLocalityResponseParser(Tpm::PolicyLocalityResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22549 void PolicyLocalityResponseParser(Tpm::PolicyLocalityResponse callback,
22550 AuthorizationDelegate* authorization_delegate,
22551 const std::string& response) {
22552 VLOG(1) << __func__;
22553 TPM_RC rc =
22554 Tpm::ParseResponse_PolicyLocality(response, authorization_delegate);
22555 if (rc != TPM_RC_SUCCESS) {
22556 base::OnceCallback<void(TPM_RC)> error_reporter =
22557 base::BindOnce(PolicyLocalityErrorCallback, std::move(callback));
22558 std::move(error_reporter).Run(rc);
22559 return;
22560 }
22561 std::move(callback).Run(rc);
22562 }
22563
PolicyLocality(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,AuthorizationDelegate * authorization_delegate,PolicyLocalityResponse callback)22564 void Tpm::PolicyLocality(const TPMI_SH_POLICY& policy_session,
22565 const std::string& policy_session_name,
22566 const TPMA_LOCALITY& locality,
22567 AuthorizationDelegate* authorization_delegate,
22568 PolicyLocalityResponse callback) {
22569 VLOG(1) << __func__;
22570 std::string command;
22571 TPM_RC rc = SerializeCommand_PolicyLocality(policy_session,
22572 policy_session_name, locality,
22573 &command, authorization_delegate);
22574 if (rc != TPM_RC_SUCCESS) {
22575 base::OnceCallback<void(TPM_RC)> error_reporter =
22576 base::BindOnce(PolicyLocalityErrorCallback, std::move(callback));
22577 std::move(error_reporter).Run(rc);
22578 return;
22579 }
22580 base::OnceCallback<void(const std::string&)> parser =
22581 base::BindOnce(PolicyLocalityResponseParser, std::move(callback),
22582 authorization_delegate);
22583 transceiver_->SendCommand(command, std::move(parser));
22584 }
22585
PolicyLocalitySync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,AuthorizationDelegate * authorization_delegate)22586 TPM_RC Tpm::PolicyLocalitySync(const TPMI_SH_POLICY& policy_session,
22587 const std::string& policy_session_name,
22588 const TPMA_LOCALITY& locality,
22589 AuthorizationDelegate* authorization_delegate) {
22590 VLOG(1) << __func__;
22591 std::string command;
22592 TPM_RC rc = SerializeCommand_PolicyLocality(policy_session,
22593 policy_session_name, locality,
22594 &command, authorization_delegate);
22595 if (rc != TPM_RC_SUCCESS) {
22596 return rc;
22597 }
22598 std::string response = transceiver_->SendCommandAndWait(command);
22599 rc = ParseResponse_PolicyLocality(response, authorization_delegate);
22600 return rc;
22601 }
22602
SerializeCommand_PolicyNV(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22603 TPM_RC Tpm::SerializeCommand_PolicyNV(
22604 const TPMI_RH_NV_AUTH& auth_handle,
22605 const std::string& auth_handle_name,
22606 const TPMI_RH_NV_INDEX& nv_index,
22607 const std::string& nv_index_name,
22608 const TPMI_SH_POLICY& policy_session,
22609 const std::string& policy_session_name,
22610 const TPM2B_OPERAND& operand_b,
22611 const UINT16& offset,
22612 const TPM_EO& operation,
22613 std::string* serialized_command,
22614 AuthorizationDelegate* authorization_delegate) {
22615 VLOG(3) << __func__;
22616 TPM_RC rc = TPM_RC_SUCCESS;
22617 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22618 UINT32 command_size = 10; // Header size.
22619 std::string handle_section_bytes;
22620 std::string parameter_section_bytes;
22621 TPM_CC command_code = TPM_CC_PolicyNV;
22622 bool is_command_parameter_encryption_possible = true;
22623 bool is_response_parameter_encryption_possible = false;
22624 std::string command_code_bytes;
22625 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22626 if (rc != TPM_RC_SUCCESS) {
22627 return rc;
22628 }
22629 std::string auth_handle_bytes;
22630 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
22631 if (rc != TPM_RC_SUCCESS) {
22632 return rc;
22633 }
22634 std::string nv_index_bytes;
22635 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
22636 if (rc != TPM_RC_SUCCESS) {
22637 return rc;
22638 }
22639 std::string policy_session_bytes;
22640 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22641 if (rc != TPM_RC_SUCCESS) {
22642 return rc;
22643 }
22644 std::string operand_b_bytes;
22645 rc = Serialize_TPM2B_OPERAND(operand_b, &operand_b_bytes);
22646 if (rc != TPM_RC_SUCCESS) {
22647 return rc;
22648 }
22649 std::string offset_bytes;
22650 rc = Serialize_UINT16(offset, &offset_bytes);
22651 if (rc != TPM_RC_SUCCESS) {
22652 return rc;
22653 }
22654 std::string operation_bytes;
22655 rc = Serialize_TPM_EO(operation, &operation_bytes);
22656 if (rc != TPM_RC_SUCCESS) {
22657 return rc;
22658 }
22659 if (authorization_delegate) {
22660 // Encrypt just the parameter data, not the size.
22661 std::string tmp = operand_b_bytes.substr(2);
22662 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22663 return TRUNKS_RC_ENCRYPTION_FAILED;
22664 }
22665 operand_b_bytes.replace(2, std::string::npos, tmp);
22666 }
22667 std::unique_ptr<crypto::SecureHash> hash(
22668 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22669 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22670 hash->Update(auth_handle_name.data(), auth_handle_name.size());
22671 handle_section_bytes += auth_handle_bytes;
22672 command_size += auth_handle_bytes.size();
22673 hash->Update(nv_index_name.data(), nv_index_name.size());
22674 handle_section_bytes += nv_index_bytes;
22675 command_size += nv_index_bytes.size();
22676 hash->Update(policy_session_name.data(), policy_session_name.size());
22677 handle_section_bytes += policy_session_bytes;
22678 command_size += policy_session_bytes.size();
22679 hash->Update(operand_b_bytes.data(), operand_b_bytes.size());
22680 parameter_section_bytes += operand_b_bytes;
22681 command_size += operand_b_bytes.size();
22682 hash->Update(offset_bytes.data(), offset_bytes.size());
22683 parameter_section_bytes += offset_bytes;
22684 command_size += offset_bytes.size();
22685 hash->Update(operation_bytes.data(), operation_bytes.size());
22686 parameter_section_bytes += operation_bytes;
22687 command_size += operation_bytes.size();
22688 std::string command_hash(32, 0);
22689 hash->Finish(std::data(command_hash), command_hash.size());
22690 std::string authorization_section_bytes;
22691 std::string authorization_size_bytes;
22692 if (authorization_delegate) {
22693 if (!authorization_delegate->GetCommandAuthorization(
22694 command_hash, is_command_parameter_encryption_possible,
22695 is_response_parameter_encryption_possible,
22696 &authorization_section_bytes)) {
22697 return TRUNKS_RC_AUTHORIZATION_FAILED;
22698 }
22699 if (!authorization_section_bytes.empty()) {
22700 tag = TPM_ST_SESSIONS;
22701 std::string tmp;
22702 rc = Serialize_UINT32(authorization_section_bytes.size(),
22703 &authorization_size_bytes);
22704 if (rc != TPM_RC_SUCCESS) {
22705 return rc;
22706 }
22707 command_size +=
22708 authorization_size_bytes.size() + authorization_section_bytes.size();
22709 }
22710 }
22711 std::string tag_bytes;
22712 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22713 if (rc != TPM_RC_SUCCESS) {
22714 return rc;
22715 }
22716 std::string command_size_bytes;
22717 rc = Serialize_UINT32(command_size, &command_size_bytes);
22718 if (rc != TPM_RC_SUCCESS) {
22719 return rc;
22720 }
22721 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22722 handle_section_bytes + authorization_size_bytes +
22723 authorization_section_bytes + parameter_section_bytes;
22724 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22725 VLOG(2) << "Command: "
22726 << base::HexEncode(serialized_command->data(),
22727 serialized_command->size());
22728 return TPM_RC_SUCCESS;
22729 }
22730
ParseResponse_PolicyNV(const std::string & response,AuthorizationDelegate * authorization_delegate)22731 TPM_RC Tpm::ParseResponse_PolicyNV(
22732 const std::string& response,
22733 AuthorizationDelegate* authorization_delegate) {
22734 VLOG(3) << __func__;
22735 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22736 TPM_RC rc = TPM_RC_SUCCESS;
22737 std::string buffer(response);
22738 TPM_ST tag;
22739 std::string tag_bytes;
22740 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22741 if (rc != TPM_RC_SUCCESS) {
22742 return rc;
22743 }
22744 UINT32 response_size;
22745 std::string response_size_bytes;
22746 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22747 if (rc != TPM_RC_SUCCESS) {
22748 return rc;
22749 }
22750 TPM_RC response_code;
22751 std::string response_code_bytes;
22752 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22753 if (rc != TPM_RC_SUCCESS) {
22754 return rc;
22755 }
22756 if (response_size != response.size()) {
22757 return TPM_RC_SIZE;
22758 }
22759 if (response_code != TPM_RC_SUCCESS) {
22760 return response_code;
22761 }
22762 TPM_CC command_code = TPM_CC_PolicyNV;
22763 std::string command_code_bytes;
22764 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22765 if (rc != TPM_RC_SUCCESS) {
22766 return rc;
22767 }
22768 std::string authorization_section_bytes;
22769 if (tag == TPM_ST_SESSIONS) {
22770 UINT32 parameter_section_size = buffer.size();
22771 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
22772 if (rc != TPM_RC_SUCCESS) {
22773 return rc;
22774 }
22775 if (parameter_section_size > buffer.size()) {
22776 return TPM_RC_INSUFFICIENT;
22777 }
22778 authorization_section_bytes = buffer.substr(parameter_section_size);
22779 // Keep the parameter section in |buffer|.
22780 buffer.erase(parameter_section_size);
22781 }
22782 std::unique_ptr<crypto::SecureHash> hash(
22783 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22784 hash->Update(response_code_bytes.data(), response_code_bytes.size());
22785 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22786 hash->Update(buffer.data(), buffer.size());
22787 std::string response_hash(32, 0);
22788 hash->Finish(std::data(response_hash), response_hash.size());
22789 if (tag == TPM_ST_SESSIONS) {
22790 if (!authorization_delegate)
22791 return TRUNKS_RC_AUTHORIZATION_FAILED;
22792 if (!authorization_delegate->CheckResponseAuthorization(
22793 response_hash, authorization_section_bytes)) {
22794 return TRUNKS_RC_AUTHORIZATION_FAILED;
22795 }
22796 }
22797 return TPM_RC_SUCCESS;
22798 }
22799
PolicyNVErrorCallback(Tpm::PolicyNVResponse callback,TPM_RC response_code)22800 void PolicyNVErrorCallback(Tpm::PolicyNVResponse callback,
22801 TPM_RC response_code) {
22802 VLOG(1) << __func__;
22803 std::move(callback).Run(response_code);
22804 }
22805
PolicyNVResponseParser(Tpm::PolicyNVResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22806 void PolicyNVResponseParser(Tpm::PolicyNVResponse callback,
22807 AuthorizationDelegate* authorization_delegate,
22808 const std::string& response) {
22809 VLOG(1) << __func__;
22810 TPM_RC rc = Tpm::ParseResponse_PolicyNV(response, authorization_delegate);
22811 if (rc != TPM_RC_SUCCESS) {
22812 base::OnceCallback<void(TPM_RC)> error_reporter =
22813 base::BindOnce(PolicyNVErrorCallback, std::move(callback));
22814 std::move(error_reporter).Run(rc);
22815 return;
22816 }
22817 std::move(callback).Run(rc);
22818 }
22819
PolicyNV(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate,PolicyNVResponse callback)22820 void Tpm::PolicyNV(const TPMI_RH_NV_AUTH& auth_handle,
22821 const std::string& auth_handle_name,
22822 const TPMI_RH_NV_INDEX& nv_index,
22823 const std::string& nv_index_name,
22824 const TPMI_SH_POLICY& policy_session,
22825 const std::string& policy_session_name,
22826 const TPM2B_OPERAND& operand_b,
22827 const UINT16& offset,
22828 const TPM_EO& operation,
22829 AuthorizationDelegate* authorization_delegate,
22830 PolicyNVResponse callback) {
22831 VLOG(1) << __func__;
22832 std::string command;
22833 TPM_RC rc = SerializeCommand_PolicyNV(
22834 auth_handle, auth_handle_name, nv_index, nv_index_name, policy_session,
22835 policy_session_name, operand_b, offset, operation, &command,
22836 authorization_delegate);
22837 if (rc != TPM_RC_SUCCESS) {
22838 base::OnceCallback<void(TPM_RC)> error_reporter =
22839 base::BindOnce(PolicyNVErrorCallback, std::move(callback));
22840 std::move(error_reporter).Run(rc);
22841 return;
22842 }
22843 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22844 PolicyNVResponseParser, std::move(callback), authorization_delegate);
22845 transceiver_->SendCommand(command, std::move(parser));
22846 }
22847
PolicyNVSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate)22848 TPM_RC Tpm::PolicyNVSync(const TPMI_RH_NV_AUTH& auth_handle,
22849 const std::string& auth_handle_name,
22850 const TPMI_RH_NV_INDEX& nv_index,
22851 const std::string& nv_index_name,
22852 const TPMI_SH_POLICY& policy_session,
22853 const std::string& policy_session_name,
22854 const TPM2B_OPERAND& operand_b,
22855 const UINT16& offset,
22856 const TPM_EO& operation,
22857 AuthorizationDelegate* authorization_delegate) {
22858 VLOG(1) << __func__;
22859 std::string command;
22860 TPM_RC rc = SerializeCommand_PolicyNV(
22861 auth_handle, auth_handle_name, nv_index, nv_index_name, policy_session,
22862 policy_session_name, operand_b, offset, operation, &command,
22863 authorization_delegate);
22864 if (rc != TPM_RC_SUCCESS) {
22865 return rc;
22866 }
22867 std::string response = transceiver_->SendCommandAndWait(command);
22868 rc = ParseResponse_PolicyNV(response, authorization_delegate);
22869 return rc;
22870 }
22871
SerializeCommand_PolicyCounterTimer(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22872 TPM_RC Tpm::SerializeCommand_PolicyCounterTimer(
22873 const TPMI_SH_POLICY& policy_session,
22874 const std::string& policy_session_name,
22875 const TPM2B_OPERAND& operand_b,
22876 const UINT16& offset,
22877 const TPM_EO& operation,
22878 std::string* serialized_command,
22879 AuthorizationDelegate* authorization_delegate) {
22880 VLOG(3) << __func__;
22881 TPM_RC rc = TPM_RC_SUCCESS;
22882 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22883 UINT32 command_size = 10; // Header size.
22884 std::string handle_section_bytes;
22885 std::string parameter_section_bytes;
22886 TPM_CC command_code = TPM_CC_PolicyCounterTimer;
22887 bool is_command_parameter_encryption_possible = true;
22888 bool is_response_parameter_encryption_possible = false;
22889 std::string command_code_bytes;
22890 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22891 if (rc != TPM_RC_SUCCESS) {
22892 return rc;
22893 }
22894 std::string policy_session_bytes;
22895 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22896 if (rc != TPM_RC_SUCCESS) {
22897 return rc;
22898 }
22899 std::string operand_b_bytes;
22900 rc = Serialize_TPM2B_OPERAND(operand_b, &operand_b_bytes);
22901 if (rc != TPM_RC_SUCCESS) {
22902 return rc;
22903 }
22904 std::string offset_bytes;
22905 rc = Serialize_UINT16(offset, &offset_bytes);
22906 if (rc != TPM_RC_SUCCESS) {
22907 return rc;
22908 }
22909 std::string operation_bytes;
22910 rc = Serialize_TPM_EO(operation, &operation_bytes);
22911 if (rc != TPM_RC_SUCCESS) {
22912 return rc;
22913 }
22914 if (authorization_delegate) {
22915 // Encrypt just the parameter data, not the size.
22916 std::string tmp = operand_b_bytes.substr(2);
22917 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22918 return TRUNKS_RC_ENCRYPTION_FAILED;
22919 }
22920 operand_b_bytes.replace(2, std::string::npos, tmp);
22921 }
22922 std::unique_ptr<crypto::SecureHash> hash(
22923 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22924 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22925 hash->Update(policy_session_name.data(), policy_session_name.size());
22926 handle_section_bytes += policy_session_bytes;
22927 command_size += policy_session_bytes.size();
22928 hash->Update(operand_b_bytes.data(), operand_b_bytes.size());
22929 parameter_section_bytes += operand_b_bytes;
22930 command_size += operand_b_bytes.size();
22931 hash->Update(offset_bytes.data(), offset_bytes.size());
22932 parameter_section_bytes += offset_bytes;
22933 command_size += offset_bytes.size();
22934 hash->Update(operation_bytes.data(), operation_bytes.size());
22935 parameter_section_bytes += operation_bytes;
22936 command_size += operation_bytes.size();
22937 std::string command_hash(32, 0);
22938 hash->Finish(std::data(command_hash), command_hash.size());
22939 std::string authorization_section_bytes;
22940 std::string authorization_size_bytes;
22941 if (authorization_delegate) {
22942 if (!authorization_delegate->GetCommandAuthorization(
22943 command_hash, is_command_parameter_encryption_possible,
22944 is_response_parameter_encryption_possible,
22945 &authorization_section_bytes)) {
22946 return TRUNKS_RC_AUTHORIZATION_FAILED;
22947 }
22948 if (!authorization_section_bytes.empty()) {
22949 tag = TPM_ST_SESSIONS;
22950 std::string tmp;
22951 rc = Serialize_UINT32(authorization_section_bytes.size(),
22952 &authorization_size_bytes);
22953 if (rc != TPM_RC_SUCCESS) {
22954 return rc;
22955 }
22956 command_size +=
22957 authorization_size_bytes.size() + authorization_section_bytes.size();
22958 }
22959 }
22960 std::string tag_bytes;
22961 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22962 if (rc != TPM_RC_SUCCESS) {
22963 return rc;
22964 }
22965 std::string command_size_bytes;
22966 rc = Serialize_UINT32(command_size, &command_size_bytes);
22967 if (rc != TPM_RC_SUCCESS) {
22968 return rc;
22969 }
22970 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22971 handle_section_bytes + authorization_size_bytes +
22972 authorization_section_bytes + parameter_section_bytes;
22973 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22974 VLOG(2) << "Command: "
22975 << base::HexEncode(serialized_command->data(),
22976 serialized_command->size());
22977 return TPM_RC_SUCCESS;
22978 }
22979
ParseResponse_PolicyCounterTimer(const std::string & response,AuthorizationDelegate * authorization_delegate)22980 TPM_RC Tpm::ParseResponse_PolicyCounterTimer(
22981 const std::string& response,
22982 AuthorizationDelegate* authorization_delegate) {
22983 VLOG(3) << __func__;
22984 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22985 TPM_RC rc = TPM_RC_SUCCESS;
22986 std::string buffer(response);
22987 TPM_ST tag;
22988 std::string tag_bytes;
22989 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22990 if (rc != TPM_RC_SUCCESS) {
22991 return rc;
22992 }
22993 UINT32 response_size;
22994 std::string response_size_bytes;
22995 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22996 if (rc != TPM_RC_SUCCESS) {
22997 return rc;
22998 }
22999 TPM_RC response_code;
23000 std::string response_code_bytes;
23001 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23002 if (rc != TPM_RC_SUCCESS) {
23003 return rc;
23004 }
23005 if (response_size != response.size()) {
23006 return TPM_RC_SIZE;
23007 }
23008 if (response_code != TPM_RC_SUCCESS) {
23009 return response_code;
23010 }
23011 TPM_CC command_code = TPM_CC_PolicyCounterTimer;
23012 std::string command_code_bytes;
23013 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23014 if (rc != TPM_RC_SUCCESS) {
23015 return rc;
23016 }
23017 std::string authorization_section_bytes;
23018 if (tag == TPM_ST_SESSIONS) {
23019 UINT32 parameter_section_size = buffer.size();
23020 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
23021 if (rc != TPM_RC_SUCCESS) {
23022 return rc;
23023 }
23024 if (parameter_section_size > buffer.size()) {
23025 return TPM_RC_INSUFFICIENT;
23026 }
23027 authorization_section_bytes = buffer.substr(parameter_section_size);
23028 // Keep the parameter section in |buffer|.
23029 buffer.erase(parameter_section_size);
23030 }
23031 std::unique_ptr<crypto::SecureHash> hash(
23032 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23033 hash->Update(response_code_bytes.data(), response_code_bytes.size());
23034 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23035 hash->Update(buffer.data(), buffer.size());
23036 std::string response_hash(32, 0);
23037 hash->Finish(std::data(response_hash), response_hash.size());
23038 if (tag == TPM_ST_SESSIONS) {
23039 if (!authorization_delegate)
23040 return TRUNKS_RC_AUTHORIZATION_FAILED;
23041 if (!authorization_delegate->CheckResponseAuthorization(
23042 response_hash, authorization_section_bytes)) {
23043 return TRUNKS_RC_AUTHORIZATION_FAILED;
23044 }
23045 }
23046 return TPM_RC_SUCCESS;
23047 }
23048
PolicyCounterTimerErrorCallback(Tpm::PolicyCounterTimerResponse callback,TPM_RC response_code)23049 void PolicyCounterTimerErrorCallback(Tpm::PolicyCounterTimerResponse callback,
23050 TPM_RC response_code) {
23051 VLOG(1) << __func__;
23052 std::move(callback).Run(response_code);
23053 }
23054
PolicyCounterTimerResponseParser(Tpm::PolicyCounterTimerResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23055 void PolicyCounterTimerResponseParser(
23056 Tpm::PolicyCounterTimerResponse callback,
23057 AuthorizationDelegate* authorization_delegate,
23058 const std::string& response) {
23059 VLOG(1) << __func__;
23060 TPM_RC rc =
23061 Tpm::ParseResponse_PolicyCounterTimer(response, authorization_delegate);
23062 if (rc != TPM_RC_SUCCESS) {
23063 base::OnceCallback<void(TPM_RC)> error_reporter =
23064 base::BindOnce(PolicyCounterTimerErrorCallback, std::move(callback));
23065 std::move(error_reporter).Run(rc);
23066 return;
23067 }
23068 std::move(callback).Run(rc);
23069 }
23070
PolicyCounterTimer(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate,PolicyCounterTimerResponse callback)23071 void Tpm::PolicyCounterTimer(const TPMI_SH_POLICY& policy_session,
23072 const std::string& policy_session_name,
23073 const TPM2B_OPERAND& operand_b,
23074 const UINT16& offset,
23075 const TPM_EO& operation,
23076 AuthorizationDelegate* authorization_delegate,
23077 PolicyCounterTimerResponse callback) {
23078 VLOG(1) << __func__;
23079 std::string command;
23080 TPM_RC rc = SerializeCommand_PolicyCounterTimer(
23081 policy_session, policy_session_name, operand_b, offset, operation,
23082 &command, authorization_delegate);
23083 if (rc != TPM_RC_SUCCESS) {
23084 base::OnceCallback<void(TPM_RC)> error_reporter =
23085 base::BindOnce(PolicyCounterTimerErrorCallback, std::move(callback));
23086 std::move(error_reporter).Run(rc);
23087 return;
23088 }
23089 base::OnceCallback<void(const std::string&)> parser =
23090 base::BindOnce(PolicyCounterTimerResponseParser, std::move(callback),
23091 authorization_delegate);
23092 transceiver_->SendCommand(command, std::move(parser));
23093 }
23094
PolicyCounterTimerSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate)23095 TPM_RC Tpm::PolicyCounterTimerSync(
23096 const TPMI_SH_POLICY& policy_session,
23097 const std::string& policy_session_name,
23098 const TPM2B_OPERAND& operand_b,
23099 const UINT16& offset,
23100 const TPM_EO& operation,
23101 AuthorizationDelegate* authorization_delegate) {
23102 VLOG(1) << __func__;
23103 std::string command;
23104 TPM_RC rc = SerializeCommand_PolicyCounterTimer(
23105 policy_session, policy_session_name, operand_b, offset, operation,
23106 &command, authorization_delegate);
23107 if (rc != TPM_RC_SUCCESS) {
23108 return rc;
23109 }
23110 std::string response = transceiver_->SendCommandAndWait(command);
23111 rc = ParseResponse_PolicyCounterTimer(response, authorization_delegate);
23112 return rc;
23113 }
23114
SerializeCommand_PolicyCommandCode(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23115 TPM_RC Tpm::SerializeCommand_PolicyCommandCode(
23116 const TPMI_SH_POLICY& policy_session,
23117 const std::string& policy_session_name,
23118 const TPM_CC& code,
23119 std::string* serialized_command,
23120 AuthorizationDelegate* authorization_delegate) {
23121 VLOG(3) << __func__;
23122 TPM_RC rc = TPM_RC_SUCCESS;
23123 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23124 UINT32 command_size = 10; // Header size.
23125 std::string handle_section_bytes;
23126 std::string parameter_section_bytes;
23127 TPM_CC command_code = TPM_CC_PolicyCommandCode;
23128 bool is_command_parameter_encryption_possible = false;
23129 bool is_response_parameter_encryption_possible = false;
23130 std::string command_code_bytes;
23131 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23132 if (rc != TPM_RC_SUCCESS) {
23133 return rc;
23134 }
23135 std::string policy_session_bytes;
23136 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23137 if (rc != TPM_RC_SUCCESS) {
23138 return rc;
23139 }
23140 std::string code_bytes;
23141 rc = Serialize_TPM_CC(code, &code_bytes);
23142 if (rc != TPM_RC_SUCCESS) {
23143 return rc;
23144 }
23145 std::unique_ptr<crypto::SecureHash> hash(
23146 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23147 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23148 hash->Update(policy_session_name.data(), policy_session_name.size());
23149 handle_section_bytes += policy_session_bytes;
23150 command_size += policy_session_bytes.size();
23151 hash->Update(code_bytes.data(), code_bytes.size());
23152 parameter_section_bytes += code_bytes;
23153 command_size += code_bytes.size();
23154 std::string command_hash(32, 0);
23155 hash->Finish(std::data(command_hash), command_hash.size());
23156 std::string authorization_section_bytes;
23157 std::string authorization_size_bytes;
23158 if (authorization_delegate) {
23159 if (!authorization_delegate->GetCommandAuthorization(
23160 command_hash, is_command_parameter_encryption_possible,
23161 is_response_parameter_encryption_possible,
23162 &authorization_section_bytes)) {
23163 return TRUNKS_RC_AUTHORIZATION_FAILED;
23164 }
23165 if (!authorization_section_bytes.empty()) {
23166 tag = TPM_ST_SESSIONS;
23167 std::string tmp;
23168 rc = Serialize_UINT32(authorization_section_bytes.size(),
23169 &authorization_size_bytes);
23170 if (rc != TPM_RC_SUCCESS) {
23171 return rc;
23172 }
23173 command_size +=
23174 authorization_size_bytes.size() + authorization_section_bytes.size();
23175 }
23176 }
23177 std::string tag_bytes;
23178 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23179 if (rc != TPM_RC_SUCCESS) {
23180 return rc;
23181 }
23182 std::string command_size_bytes;
23183 rc = Serialize_UINT32(command_size, &command_size_bytes);
23184 if (rc != TPM_RC_SUCCESS) {
23185 return rc;
23186 }
23187 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23188 handle_section_bytes + authorization_size_bytes +
23189 authorization_section_bytes + parameter_section_bytes;
23190 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23191 VLOG(2) << "Command: "
23192 << base::HexEncode(serialized_command->data(),
23193 serialized_command->size());
23194 return TPM_RC_SUCCESS;
23195 }
23196
ParseResponse_PolicyCommandCode(const std::string & response,AuthorizationDelegate * authorization_delegate)23197 TPM_RC Tpm::ParseResponse_PolicyCommandCode(
23198 const std::string& response,
23199 AuthorizationDelegate* authorization_delegate) {
23200 VLOG(3) << __func__;
23201 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23202 TPM_RC rc = TPM_RC_SUCCESS;
23203 std::string buffer(response);
23204 TPM_ST tag;
23205 std::string tag_bytes;
23206 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23207 if (rc != TPM_RC_SUCCESS) {
23208 return rc;
23209 }
23210 UINT32 response_size;
23211 std::string response_size_bytes;
23212 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23213 if (rc != TPM_RC_SUCCESS) {
23214 return rc;
23215 }
23216 TPM_RC response_code;
23217 std::string response_code_bytes;
23218 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23219 if (rc != TPM_RC_SUCCESS) {
23220 return rc;
23221 }
23222 if (response_size != response.size()) {
23223 return TPM_RC_SIZE;
23224 }
23225 if (response_code != TPM_RC_SUCCESS) {
23226 return response_code;
23227 }
23228 TPM_CC command_code = TPM_CC_PolicyCommandCode;
23229 std::string command_code_bytes;
23230 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23231 if (rc != TPM_RC_SUCCESS) {
23232 return rc;
23233 }
23234 std::string authorization_section_bytes;
23235 if (tag == TPM_ST_SESSIONS) {
23236 UINT32 parameter_section_size = buffer.size();
23237 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
23238 if (rc != TPM_RC_SUCCESS) {
23239 return rc;
23240 }
23241 if (parameter_section_size > buffer.size()) {
23242 return TPM_RC_INSUFFICIENT;
23243 }
23244 authorization_section_bytes = buffer.substr(parameter_section_size);
23245 // Keep the parameter section in |buffer|.
23246 buffer.erase(parameter_section_size);
23247 }
23248 std::unique_ptr<crypto::SecureHash> hash(
23249 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23250 hash->Update(response_code_bytes.data(), response_code_bytes.size());
23251 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23252 hash->Update(buffer.data(), buffer.size());
23253 std::string response_hash(32, 0);
23254 hash->Finish(std::data(response_hash), response_hash.size());
23255 if (tag == TPM_ST_SESSIONS) {
23256 if (!authorization_delegate)
23257 return TRUNKS_RC_AUTHORIZATION_FAILED;
23258 if (!authorization_delegate->CheckResponseAuthorization(
23259 response_hash, authorization_section_bytes)) {
23260 return TRUNKS_RC_AUTHORIZATION_FAILED;
23261 }
23262 }
23263 return TPM_RC_SUCCESS;
23264 }
23265
PolicyCommandCodeErrorCallback(Tpm::PolicyCommandCodeResponse callback,TPM_RC response_code)23266 void PolicyCommandCodeErrorCallback(Tpm::PolicyCommandCodeResponse callback,
23267 TPM_RC response_code) {
23268 VLOG(1) << __func__;
23269 std::move(callback).Run(response_code);
23270 }
23271
PolicyCommandCodeResponseParser(Tpm::PolicyCommandCodeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23272 void PolicyCommandCodeResponseParser(
23273 Tpm::PolicyCommandCodeResponse callback,
23274 AuthorizationDelegate* authorization_delegate,
23275 const std::string& response) {
23276 VLOG(1) << __func__;
23277 TPM_RC rc =
23278 Tpm::ParseResponse_PolicyCommandCode(response, authorization_delegate);
23279 if (rc != TPM_RC_SUCCESS) {
23280 base::OnceCallback<void(TPM_RC)> error_reporter =
23281 base::BindOnce(PolicyCommandCodeErrorCallback, std::move(callback));
23282 std::move(error_reporter).Run(rc);
23283 return;
23284 }
23285 std::move(callback).Run(rc);
23286 }
23287
PolicyCommandCode(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,AuthorizationDelegate * authorization_delegate,PolicyCommandCodeResponse callback)23288 void Tpm::PolicyCommandCode(const TPMI_SH_POLICY& policy_session,
23289 const std::string& policy_session_name,
23290 const TPM_CC& code,
23291 AuthorizationDelegate* authorization_delegate,
23292 PolicyCommandCodeResponse callback) {
23293 VLOG(1) << __func__;
23294 std::string command;
23295 TPM_RC rc = SerializeCommand_PolicyCommandCode(
23296 policy_session, policy_session_name, code, &command,
23297 authorization_delegate);
23298 if (rc != TPM_RC_SUCCESS) {
23299 base::OnceCallback<void(TPM_RC)> error_reporter =
23300 base::BindOnce(PolicyCommandCodeErrorCallback, std::move(callback));
23301 std::move(error_reporter).Run(rc);
23302 return;
23303 }
23304 base::OnceCallback<void(const std::string&)> parser =
23305 base::BindOnce(PolicyCommandCodeResponseParser, std::move(callback),
23306 authorization_delegate);
23307 transceiver_->SendCommand(command, std::move(parser));
23308 }
23309
PolicyCommandCodeSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,AuthorizationDelegate * authorization_delegate)23310 TPM_RC Tpm::PolicyCommandCodeSync(
23311 const TPMI_SH_POLICY& policy_session,
23312 const std::string& policy_session_name,
23313 const TPM_CC& code,
23314 AuthorizationDelegate* authorization_delegate) {
23315 VLOG(1) << __func__;
23316 std::string command;
23317 TPM_RC rc = SerializeCommand_PolicyCommandCode(
23318 policy_session, policy_session_name, code, &command,
23319 authorization_delegate);
23320 if (rc != TPM_RC_SUCCESS) {
23321 return rc;
23322 }
23323 std::string response = transceiver_->SendCommandAndWait(command);
23324 rc = ParseResponse_PolicyCommandCode(response, authorization_delegate);
23325 return rc;
23326 }
23327
SerializeCommand_PolicyPhysicalPresence(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23328 TPM_RC Tpm::SerializeCommand_PolicyPhysicalPresence(
23329 const TPMI_SH_POLICY& policy_session,
23330 const std::string& policy_session_name,
23331 std::string* serialized_command,
23332 AuthorizationDelegate* authorization_delegate) {
23333 VLOG(3) << __func__;
23334 TPM_RC rc = TPM_RC_SUCCESS;
23335 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23336 UINT32 command_size = 10; // Header size.
23337 std::string handle_section_bytes;
23338 std::string parameter_section_bytes;
23339 TPM_CC command_code = TPM_CC_PolicyPhysicalPresence;
23340 bool is_command_parameter_encryption_possible = false;
23341 bool is_response_parameter_encryption_possible = false;
23342 std::string command_code_bytes;
23343 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23344 if (rc != TPM_RC_SUCCESS) {
23345 return rc;
23346 }
23347 std::string policy_session_bytes;
23348 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23349 if (rc != TPM_RC_SUCCESS) {
23350 return rc;
23351 }
23352 std::unique_ptr<crypto::SecureHash> hash(
23353 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23354 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23355 hash->Update(policy_session_name.data(), policy_session_name.size());
23356 handle_section_bytes += policy_session_bytes;
23357 command_size += policy_session_bytes.size();
23358 std::string command_hash(32, 0);
23359 hash->Finish(std::data(command_hash), command_hash.size());
23360 std::string authorization_section_bytes;
23361 std::string authorization_size_bytes;
23362 if (authorization_delegate) {
23363 if (!authorization_delegate->GetCommandAuthorization(
23364 command_hash, is_command_parameter_encryption_possible,
23365 is_response_parameter_encryption_possible,
23366 &authorization_section_bytes)) {
23367 return TRUNKS_RC_AUTHORIZATION_FAILED;
23368 }
23369 if (!authorization_section_bytes.empty()) {
23370 tag = TPM_ST_SESSIONS;
23371 std::string tmp;
23372 rc = Serialize_UINT32(authorization_section_bytes.size(),
23373 &authorization_size_bytes);
23374 if (rc != TPM_RC_SUCCESS) {
23375 return rc;
23376 }
23377 command_size +=
23378 authorization_size_bytes.size() + authorization_section_bytes.size();
23379 }
23380 }
23381 std::string tag_bytes;
23382 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23383 if (rc != TPM_RC_SUCCESS) {
23384 return rc;
23385 }
23386 std::string command_size_bytes;
23387 rc = Serialize_UINT32(command_size, &command_size_bytes);
23388 if (rc != TPM_RC_SUCCESS) {
23389 return rc;
23390 }
23391 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23392 handle_section_bytes + authorization_size_bytes +
23393 authorization_section_bytes + parameter_section_bytes;
23394 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23395 VLOG(2) << "Command: "
23396 << base::HexEncode(serialized_command->data(),
23397 serialized_command->size());
23398 return TPM_RC_SUCCESS;
23399 }
23400
ParseResponse_PolicyPhysicalPresence(const std::string & response,AuthorizationDelegate * authorization_delegate)23401 TPM_RC Tpm::ParseResponse_PolicyPhysicalPresence(
23402 const std::string& response,
23403 AuthorizationDelegate* authorization_delegate) {
23404 VLOG(3) << __func__;
23405 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23406 TPM_RC rc = TPM_RC_SUCCESS;
23407 std::string buffer(response);
23408 TPM_ST tag;
23409 std::string tag_bytes;
23410 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23411 if (rc != TPM_RC_SUCCESS) {
23412 return rc;
23413 }
23414 UINT32 response_size;
23415 std::string response_size_bytes;
23416 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23417 if (rc != TPM_RC_SUCCESS) {
23418 return rc;
23419 }
23420 TPM_RC response_code;
23421 std::string response_code_bytes;
23422 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23423 if (rc != TPM_RC_SUCCESS) {
23424 return rc;
23425 }
23426 if (response_size != response.size()) {
23427 return TPM_RC_SIZE;
23428 }
23429 if (response_code != TPM_RC_SUCCESS) {
23430 return response_code;
23431 }
23432 TPM_CC command_code = TPM_CC_PolicyPhysicalPresence;
23433 std::string command_code_bytes;
23434 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23435 if (rc != TPM_RC_SUCCESS) {
23436 return rc;
23437 }
23438 std::string authorization_section_bytes;
23439 if (tag == TPM_ST_SESSIONS) {
23440 UINT32 parameter_section_size = buffer.size();
23441 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
23442 if (rc != TPM_RC_SUCCESS) {
23443 return rc;
23444 }
23445 if (parameter_section_size > buffer.size()) {
23446 return TPM_RC_INSUFFICIENT;
23447 }
23448 authorization_section_bytes = buffer.substr(parameter_section_size);
23449 // Keep the parameter section in |buffer|.
23450 buffer.erase(parameter_section_size);
23451 }
23452 std::unique_ptr<crypto::SecureHash> hash(
23453 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23454 hash->Update(response_code_bytes.data(), response_code_bytes.size());
23455 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23456 hash->Update(buffer.data(), buffer.size());
23457 std::string response_hash(32, 0);
23458 hash->Finish(std::data(response_hash), response_hash.size());
23459 if (tag == TPM_ST_SESSIONS) {
23460 if (!authorization_delegate)
23461 return TRUNKS_RC_AUTHORIZATION_FAILED;
23462 if (!authorization_delegate->CheckResponseAuthorization(
23463 response_hash, authorization_section_bytes)) {
23464 return TRUNKS_RC_AUTHORIZATION_FAILED;
23465 }
23466 }
23467 return TPM_RC_SUCCESS;
23468 }
23469
PolicyPhysicalPresenceErrorCallback(Tpm::PolicyPhysicalPresenceResponse callback,TPM_RC response_code)23470 void PolicyPhysicalPresenceErrorCallback(
23471 Tpm::PolicyPhysicalPresenceResponse callback, TPM_RC response_code) {
23472 VLOG(1) << __func__;
23473 std::move(callback).Run(response_code);
23474 }
23475
PolicyPhysicalPresenceResponseParser(Tpm::PolicyPhysicalPresenceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23476 void PolicyPhysicalPresenceResponseParser(
23477 Tpm::PolicyPhysicalPresenceResponse callback,
23478 AuthorizationDelegate* authorization_delegate,
23479 const std::string& response) {
23480 VLOG(1) << __func__;
23481 TPM_RC rc = Tpm::ParseResponse_PolicyPhysicalPresence(response,
23482 authorization_delegate);
23483 if (rc != TPM_RC_SUCCESS) {
23484 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
23485 PolicyPhysicalPresenceErrorCallback, std::move(callback));
23486 std::move(error_reporter).Run(rc);
23487 return;
23488 }
23489 std::move(callback).Run(rc);
23490 }
23491
PolicyPhysicalPresence(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyPhysicalPresenceResponse callback)23492 void Tpm::PolicyPhysicalPresence(const TPMI_SH_POLICY& policy_session,
23493 const std::string& policy_session_name,
23494 AuthorizationDelegate* authorization_delegate,
23495 PolicyPhysicalPresenceResponse callback) {
23496 VLOG(1) << __func__;
23497 std::string command;
23498 TPM_RC rc = SerializeCommand_PolicyPhysicalPresence(
23499 policy_session, policy_session_name, &command, authorization_delegate);
23500 if (rc != TPM_RC_SUCCESS) {
23501 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
23502 PolicyPhysicalPresenceErrorCallback, std::move(callback));
23503 std::move(error_reporter).Run(rc);
23504 return;
23505 }
23506 base::OnceCallback<void(const std::string&)> parser =
23507 base::BindOnce(PolicyPhysicalPresenceResponseParser, std::move(callback),
23508 authorization_delegate);
23509 transceiver_->SendCommand(command, std::move(parser));
23510 }
23511
PolicyPhysicalPresenceSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)23512 TPM_RC Tpm::PolicyPhysicalPresenceSync(
23513 const TPMI_SH_POLICY& policy_session,
23514 const std::string& policy_session_name,
23515 AuthorizationDelegate* authorization_delegate) {
23516 VLOG(1) << __func__;
23517 std::string command;
23518 TPM_RC rc = SerializeCommand_PolicyPhysicalPresence(
23519 policy_session, policy_session_name, &command, authorization_delegate);
23520 if (rc != TPM_RC_SUCCESS) {
23521 return rc;
23522 }
23523 std::string response = transceiver_->SendCommandAndWait(command);
23524 rc = ParseResponse_PolicyPhysicalPresence(response, authorization_delegate);
23525 return rc;
23526 }
23527
SerializeCommand_PolicyCpHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23528 TPM_RC Tpm::SerializeCommand_PolicyCpHash(
23529 const TPMI_SH_POLICY& policy_session,
23530 const std::string& policy_session_name,
23531 const TPM2B_DIGEST& cp_hash_a,
23532 std::string* serialized_command,
23533 AuthorizationDelegate* authorization_delegate) {
23534 VLOG(3) << __func__;
23535 TPM_RC rc = TPM_RC_SUCCESS;
23536 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23537 UINT32 command_size = 10; // Header size.
23538 std::string handle_section_bytes;
23539 std::string parameter_section_bytes;
23540 TPM_CC command_code = TPM_CC_PolicyCpHash;
23541 bool is_command_parameter_encryption_possible = true;
23542 bool is_response_parameter_encryption_possible = false;
23543 std::string command_code_bytes;
23544 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23545 if (rc != TPM_RC_SUCCESS) {
23546 return rc;
23547 }
23548 std::string policy_session_bytes;
23549 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23550 if (rc != TPM_RC_SUCCESS) {
23551 return rc;
23552 }
23553 std::string cp_hash_a_bytes;
23554 rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
23555 if (rc != TPM_RC_SUCCESS) {
23556 return rc;
23557 }
23558 if (authorization_delegate) {
23559 // Encrypt just the parameter data, not the size.
23560 std::string tmp = cp_hash_a_bytes.substr(2);
23561 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23562 return TRUNKS_RC_ENCRYPTION_FAILED;
23563 }
23564 cp_hash_a_bytes.replace(2, std::string::npos, tmp);
23565 }
23566 std::unique_ptr<crypto::SecureHash> hash(
23567 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23568 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23569 hash->Update(policy_session_name.data(), policy_session_name.size());
23570 handle_section_bytes += policy_session_bytes;
23571 command_size += policy_session_bytes.size();
23572 hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
23573 parameter_section_bytes += cp_hash_a_bytes;
23574 command_size += cp_hash_a_bytes.size();
23575 std::string command_hash(32, 0);
23576 hash->Finish(std::data(command_hash), command_hash.size());
23577 std::string authorization_section_bytes;
23578 std::string authorization_size_bytes;
23579 if (authorization_delegate) {
23580 if (!authorization_delegate->GetCommandAuthorization(
23581 command_hash, is_command_parameter_encryption_possible,
23582 is_response_parameter_encryption_possible,
23583 &authorization_section_bytes)) {
23584 return TRUNKS_RC_AUTHORIZATION_FAILED;
23585 }
23586 if (!authorization_section_bytes.empty()) {
23587 tag = TPM_ST_SESSIONS;
23588 std::string tmp;
23589 rc = Serialize_UINT32(authorization_section_bytes.size(),
23590 &authorization_size_bytes);
23591 if (rc != TPM_RC_SUCCESS) {
23592 return rc;
23593 }
23594 command_size +=
23595 authorization_size_bytes.size() + authorization_section_bytes.size();
23596 }
23597 }
23598 std::string tag_bytes;
23599 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23600 if (rc != TPM_RC_SUCCESS) {
23601 return rc;
23602 }
23603 std::string command_size_bytes;
23604 rc = Serialize_UINT32(command_size, &command_size_bytes);
23605 if (rc != TPM_RC_SUCCESS) {
23606 return rc;
23607 }
23608 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23609 handle_section_bytes + authorization_size_bytes +
23610 authorization_section_bytes + parameter_section_bytes;
23611 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23612 VLOG(2) << "Command: "
23613 << base::HexEncode(serialized_command->data(),
23614 serialized_command->size());
23615 return TPM_RC_SUCCESS;
23616 }
23617
ParseResponse_PolicyCpHash(const std::string & response,AuthorizationDelegate * authorization_delegate)23618 TPM_RC Tpm::ParseResponse_PolicyCpHash(
23619 const std::string& response,
23620 AuthorizationDelegate* authorization_delegate) {
23621 VLOG(3) << __func__;
23622 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23623 TPM_RC rc = TPM_RC_SUCCESS;
23624 std::string buffer(response);
23625 TPM_ST tag;
23626 std::string tag_bytes;
23627 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23628 if (rc != TPM_RC_SUCCESS) {
23629 return rc;
23630 }
23631 UINT32 response_size;
23632 std::string response_size_bytes;
23633 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23634 if (rc != TPM_RC_SUCCESS) {
23635 return rc;
23636 }
23637 TPM_RC response_code;
23638 std::string response_code_bytes;
23639 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23640 if (rc != TPM_RC_SUCCESS) {
23641 return rc;
23642 }
23643 if (response_size != response.size()) {
23644 return TPM_RC_SIZE;
23645 }
23646 if (response_code != TPM_RC_SUCCESS) {
23647 return response_code;
23648 }
23649 TPM_CC command_code = TPM_CC_PolicyCpHash;
23650 std::string command_code_bytes;
23651 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23652 if (rc != TPM_RC_SUCCESS) {
23653 return rc;
23654 }
23655 std::string authorization_section_bytes;
23656 if (tag == TPM_ST_SESSIONS) {
23657 UINT32 parameter_section_size = buffer.size();
23658 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
23659 if (rc != TPM_RC_SUCCESS) {
23660 return rc;
23661 }
23662 if (parameter_section_size > buffer.size()) {
23663 return TPM_RC_INSUFFICIENT;
23664 }
23665 authorization_section_bytes = buffer.substr(parameter_section_size);
23666 // Keep the parameter section in |buffer|.
23667 buffer.erase(parameter_section_size);
23668 }
23669 std::unique_ptr<crypto::SecureHash> hash(
23670 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23671 hash->Update(response_code_bytes.data(), response_code_bytes.size());
23672 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23673 hash->Update(buffer.data(), buffer.size());
23674 std::string response_hash(32, 0);
23675 hash->Finish(std::data(response_hash), response_hash.size());
23676 if (tag == TPM_ST_SESSIONS) {
23677 if (!authorization_delegate)
23678 return TRUNKS_RC_AUTHORIZATION_FAILED;
23679 if (!authorization_delegate->CheckResponseAuthorization(
23680 response_hash, authorization_section_bytes)) {
23681 return TRUNKS_RC_AUTHORIZATION_FAILED;
23682 }
23683 }
23684 return TPM_RC_SUCCESS;
23685 }
23686
PolicyCpHashErrorCallback(Tpm::PolicyCpHashResponse callback,TPM_RC response_code)23687 void PolicyCpHashErrorCallback(Tpm::PolicyCpHashResponse callback,
23688 TPM_RC response_code) {
23689 VLOG(1) << __func__;
23690 std::move(callback).Run(response_code);
23691 }
23692
PolicyCpHashResponseParser(Tpm::PolicyCpHashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23693 void PolicyCpHashResponseParser(Tpm::PolicyCpHashResponse callback,
23694 AuthorizationDelegate* authorization_delegate,
23695 const std::string& response) {
23696 VLOG(1) << __func__;
23697 TPM_RC rc = Tpm::ParseResponse_PolicyCpHash(response, authorization_delegate);
23698 if (rc != TPM_RC_SUCCESS) {
23699 base::OnceCallback<void(TPM_RC)> error_reporter =
23700 base::BindOnce(PolicyCpHashErrorCallback, std::move(callback));
23701 std::move(error_reporter).Run(rc);
23702 return;
23703 }
23704 std::move(callback).Run(rc);
23705 }
23706
PolicyCpHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,AuthorizationDelegate * authorization_delegate,PolicyCpHashResponse callback)23707 void Tpm::PolicyCpHash(const TPMI_SH_POLICY& policy_session,
23708 const std::string& policy_session_name,
23709 const TPM2B_DIGEST& cp_hash_a,
23710 AuthorizationDelegate* authorization_delegate,
23711 PolicyCpHashResponse callback) {
23712 VLOG(1) << __func__;
23713 std::string command;
23714 TPM_RC rc = SerializeCommand_PolicyCpHash(policy_session, policy_session_name,
23715 cp_hash_a, &command,
23716 authorization_delegate);
23717 if (rc != TPM_RC_SUCCESS) {
23718 base::OnceCallback<void(TPM_RC)> error_reporter =
23719 base::BindOnce(PolicyCpHashErrorCallback, std::move(callback));
23720 std::move(error_reporter).Run(rc);
23721 return;
23722 }
23723 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
23724 PolicyCpHashResponseParser, std::move(callback), authorization_delegate);
23725 transceiver_->SendCommand(command, std::move(parser));
23726 }
23727
PolicyCpHashSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,AuthorizationDelegate * authorization_delegate)23728 TPM_RC Tpm::PolicyCpHashSync(const TPMI_SH_POLICY& policy_session,
23729 const std::string& policy_session_name,
23730 const TPM2B_DIGEST& cp_hash_a,
23731 AuthorizationDelegate* authorization_delegate) {
23732 VLOG(1) << __func__;
23733 std::string command;
23734 TPM_RC rc = SerializeCommand_PolicyCpHash(policy_session, policy_session_name,
23735 cp_hash_a, &command,
23736 authorization_delegate);
23737 if (rc != TPM_RC_SUCCESS) {
23738 return rc;
23739 }
23740 std::string response = transceiver_->SendCommandAndWait(command);
23741 rc = ParseResponse_PolicyCpHash(response, authorization_delegate);
23742 return rc;
23743 }
23744
SerializeCommand_PolicyNameHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23745 TPM_RC Tpm::SerializeCommand_PolicyNameHash(
23746 const TPMI_SH_POLICY& policy_session,
23747 const std::string& policy_session_name,
23748 const TPM2B_DIGEST& name_hash,
23749 std::string* serialized_command,
23750 AuthorizationDelegate* authorization_delegate) {
23751 VLOG(3) << __func__;
23752 TPM_RC rc = TPM_RC_SUCCESS;
23753 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23754 UINT32 command_size = 10; // Header size.
23755 std::string handle_section_bytes;
23756 std::string parameter_section_bytes;
23757 TPM_CC command_code = TPM_CC_PolicyNameHash;
23758 bool is_command_parameter_encryption_possible = true;
23759 bool is_response_parameter_encryption_possible = false;
23760 std::string command_code_bytes;
23761 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23762 if (rc != TPM_RC_SUCCESS) {
23763 return rc;
23764 }
23765 std::string policy_session_bytes;
23766 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23767 if (rc != TPM_RC_SUCCESS) {
23768 return rc;
23769 }
23770 std::string name_hash_bytes;
23771 rc = Serialize_TPM2B_DIGEST(name_hash, &name_hash_bytes);
23772 if (rc != TPM_RC_SUCCESS) {
23773 return rc;
23774 }
23775 if (authorization_delegate) {
23776 // Encrypt just the parameter data, not the size.
23777 std::string tmp = name_hash_bytes.substr(2);
23778 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23779 return TRUNKS_RC_ENCRYPTION_FAILED;
23780 }
23781 name_hash_bytes.replace(2, std::string::npos, tmp);
23782 }
23783 std::unique_ptr<crypto::SecureHash> hash(
23784 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23785 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23786 hash->Update(policy_session_name.data(), policy_session_name.size());
23787 handle_section_bytes += policy_session_bytes;
23788 command_size += policy_session_bytes.size();
23789 hash->Update(name_hash_bytes.data(), name_hash_bytes.size());
23790 parameter_section_bytes += name_hash_bytes;
23791 command_size += name_hash_bytes.size();
23792 std::string command_hash(32, 0);
23793 hash->Finish(std::data(command_hash), command_hash.size());
23794 std::string authorization_section_bytes;
23795 std::string authorization_size_bytes;
23796 if (authorization_delegate) {
23797 if (!authorization_delegate->GetCommandAuthorization(
23798 command_hash, is_command_parameter_encryption_possible,
23799 is_response_parameter_encryption_possible,
23800 &authorization_section_bytes)) {
23801 return TRUNKS_RC_AUTHORIZATION_FAILED;
23802 }
23803 if (!authorization_section_bytes.empty()) {
23804 tag = TPM_ST_SESSIONS;
23805 std::string tmp;
23806 rc = Serialize_UINT32(authorization_section_bytes.size(),
23807 &authorization_size_bytes);
23808 if (rc != TPM_RC_SUCCESS) {
23809 return rc;
23810 }
23811 command_size +=
23812 authorization_size_bytes.size() + authorization_section_bytes.size();
23813 }
23814 }
23815 std::string tag_bytes;
23816 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23817 if (rc != TPM_RC_SUCCESS) {
23818 return rc;
23819 }
23820 std::string command_size_bytes;
23821 rc = Serialize_UINT32(command_size, &command_size_bytes);
23822 if (rc != TPM_RC_SUCCESS) {
23823 return rc;
23824 }
23825 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23826 handle_section_bytes + authorization_size_bytes +
23827 authorization_section_bytes + parameter_section_bytes;
23828 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23829 VLOG(2) << "Command: "
23830 << base::HexEncode(serialized_command->data(),
23831 serialized_command->size());
23832 return TPM_RC_SUCCESS;
23833 }
23834
ParseResponse_PolicyNameHash(const std::string & response,AuthorizationDelegate * authorization_delegate)23835 TPM_RC Tpm::ParseResponse_PolicyNameHash(
23836 const std::string& response,
23837 AuthorizationDelegate* authorization_delegate) {
23838 VLOG(3) << __func__;
23839 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23840 TPM_RC rc = TPM_RC_SUCCESS;
23841 std::string buffer(response);
23842 TPM_ST tag;
23843 std::string tag_bytes;
23844 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23845 if (rc != TPM_RC_SUCCESS) {
23846 return rc;
23847 }
23848 UINT32 response_size;
23849 std::string response_size_bytes;
23850 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23851 if (rc != TPM_RC_SUCCESS) {
23852 return rc;
23853 }
23854 TPM_RC response_code;
23855 std::string response_code_bytes;
23856 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23857 if (rc != TPM_RC_SUCCESS) {
23858 return rc;
23859 }
23860 if (response_size != response.size()) {
23861 return TPM_RC_SIZE;
23862 }
23863 if (response_code != TPM_RC_SUCCESS) {
23864 return response_code;
23865 }
23866 TPM_CC command_code = TPM_CC_PolicyNameHash;
23867 std::string command_code_bytes;
23868 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23869 if (rc != TPM_RC_SUCCESS) {
23870 return rc;
23871 }
23872 std::string authorization_section_bytes;
23873 if (tag == TPM_ST_SESSIONS) {
23874 UINT32 parameter_section_size = buffer.size();
23875 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
23876 if (rc != TPM_RC_SUCCESS) {
23877 return rc;
23878 }
23879 if (parameter_section_size > buffer.size()) {
23880 return TPM_RC_INSUFFICIENT;
23881 }
23882 authorization_section_bytes = buffer.substr(parameter_section_size);
23883 // Keep the parameter section in |buffer|.
23884 buffer.erase(parameter_section_size);
23885 }
23886 std::unique_ptr<crypto::SecureHash> hash(
23887 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23888 hash->Update(response_code_bytes.data(), response_code_bytes.size());
23889 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23890 hash->Update(buffer.data(), buffer.size());
23891 std::string response_hash(32, 0);
23892 hash->Finish(std::data(response_hash), response_hash.size());
23893 if (tag == TPM_ST_SESSIONS) {
23894 if (!authorization_delegate)
23895 return TRUNKS_RC_AUTHORIZATION_FAILED;
23896 if (!authorization_delegate->CheckResponseAuthorization(
23897 response_hash, authorization_section_bytes)) {
23898 return TRUNKS_RC_AUTHORIZATION_FAILED;
23899 }
23900 }
23901 return TPM_RC_SUCCESS;
23902 }
23903
PolicyNameHashErrorCallback(Tpm::PolicyNameHashResponse callback,TPM_RC response_code)23904 void PolicyNameHashErrorCallback(Tpm::PolicyNameHashResponse callback,
23905 TPM_RC response_code) {
23906 VLOG(1) << __func__;
23907 std::move(callback).Run(response_code);
23908 }
23909
PolicyNameHashResponseParser(Tpm::PolicyNameHashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23910 void PolicyNameHashResponseParser(Tpm::PolicyNameHashResponse callback,
23911 AuthorizationDelegate* authorization_delegate,
23912 const std::string& response) {
23913 VLOG(1) << __func__;
23914 TPM_RC rc =
23915 Tpm::ParseResponse_PolicyNameHash(response, authorization_delegate);
23916 if (rc != TPM_RC_SUCCESS) {
23917 base::OnceCallback<void(TPM_RC)> error_reporter =
23918 base::BindOnce(PolicyNameHashErrorCallback, std::move(callback));
23919 std::move(error_reporter).Run(rc);
23920 return;
23921 }
23922 std::move(callback).Run(rc);
23923 }
23924
PolicyNameHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,AuthorizationDelegate * authorization_delegate,PolicyNameHashResponse callback)23925 void Tpm::PolicyNameHash(const TPMI_SH_POLICY& policy_session,
23926 const std::string& policy_session_name,
23927 const TPM2B_DIGEST& name_hash,
23928 AuthorizationDelegate* authorization_delegate,
23929 PolicyNameHashResponse callback) {
23930 VLOG(1) << __func__;
23931 std::string command;
23932 TPM_RC rc = SerializeCommand_PolicyNameHash(policy_session,
23933 policy_session_name, name_hash,
23934 &command, authorization_delegate);
23935 if (rc != TPM_RC_SUCCESS) {
23936 base::OnceCallback<void(TPM_RC)> error_reporter =
23937 base::BindOnce(PolicyNameHashErrorCallback, std::move(callback));
23938 std::move(error_reporter).Run(rc);
23939 return;
23940 }
23941 base::OnceCallback<void(const std::string&)> parser =
23942 base::BindOnce(PolicyNameHashResponseParser, std::move(callback),
23943 authorization_delegate);
23944 transceiver_->SendCommand(command, std::move(parser));
23945 }
23946
PolicyNameHashSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,AuthorizationDelegate * authorization_delegate)23947 TPM_RC Tpm::PolicyNameHashSync(const TPMI_SH_POLICY& policy_session,
23948 const std::string& policy_session_name,
23949 const TPM2B_DIGEST& name_hash,
23950 AuthorizationDelegate* authorization_delegate) {
23951 VLOG(1) << __func__;
23952 std::string command;
23953 TPM_RC rc = SerializeCommand_PolicyNameHash(policy_session,
23954 policy_session_name, name_hash,
23955 &command, authorization_delegate);
23956 if (rc != TPM_RC_SUCCESS) {
23957 return rc;
23958 }
23959 std::string response = transceiver_->SendCommandAndWait(command);
23960 rc = ParseResponse_PolicyNameHash(response, authorization_delegate);
23961 return rc;
23962 }
23963
SerializeCommand_PolicyDuplicationSelect(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NAME & object_name,const TPM2B_NAME & new_parent_name,const TPMI_YES_NO & include_object,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23964 TPM_RC Tpm::SerializeCommand_PolicyDuplicationSelect(
23965 const TPMI_SH_POLICY& policy_session,
23966 const std::string& policy_session_name,
23967 const TPM2B_NAME& object_name,
23968 const TPM2B_NAME& new_parent_name,
23969 const TPMI_YES_NO& include_object,
23970 std::string* serialized_command,
23971 AuthorizationDelegate* authorization_delegate) {
23972 VLOG(3) << __func__;
23973 TPM_RC rc = TPM_RC_SUCCESS;
23974 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23975 UINT32 command_size = 10; // Header size.
23976 std::string handle_section_bytes;
23977 std::string parameter_section_bytes;
23978 TPM_CC command_code = TPM_CC_PolicyDuplicationSelect;
23979 bool is_command_parameter_encryption_possible = true;
23980 bool is_response_parameter_encryption_possible = false;
23981 std::string command_code_bytes;
23982 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23983 if (rc != TPM_RC_SUCCESS) {
23984 return rc;
23985 }
23986 std::string policy_session_bytes;
23987 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23988 if (rc != TPM_RC_SUCCESS) {
23989 return rc;
23990 }
23991 std::string object_name_bytes;
23992 rc = Serialize_TPM2B_NAME(object_name, &object_name_bytes);
23993 if (rc != TPM_RC_SUCCESS) {
23994 return rc;
23995 }
23996 std::string new_parent_name_bytes;
23997 rc = Serialize_TPM2B_NAME(new_parent_name, &new_parent_name_bytes);
23998 if (rc != TPM_RC_SUCCESS) {
23999 return rc;
24000 }
24001 std::string include_object_bytes;
24002 rc = Serialize_TPMI_YES_NO(include_object, &include_object_bytes);
24003 if (rc != TPM_RC_SUCCESS) {
24004 return rc;
24005 }
24006 if (authorization_delegate) {
24007 // Encrypt just the parameter data, not the size.
24008 std::string tmp = object_name_bytes.substr(2);
24009 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
24010 return TRUNKS_RC_ENCRYPTION_FAILED;
24011 }
24012 object_name_bytes.replace(2, std::string::npos, tmp);
24013 }
24014 std::unique_ptr<crypto::SecureHash> hash(
24015 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24016 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24017 hash->Update(policy_session_name.data(), policy_session_name.size());
24018 handle_section_bytes += policy_session_bytes;
24019 command_size += policy_session_bytes.size();
24020 hash->Update(object_name_bytes.data(), object_name_bytes.size());
24021 parameter_section_bytes += object_name_bytes;
24022 command_size += object_name_bytes.size();
24023 hash->Update(new_parent_name_bytes.data(), new_parent_name_bytes.size());
24024 parameter_section_bytes += new_parent_name_bytes;
24025 command_size += new_parent_name_bytes.size();
24026 hash->Update(include_object_bytes.data(), include_object_bytes.size());
24027 parameter_section_bytes += include_object_bytes;
24028 command_size += include_object_bytes.size();
24029 std::string command_hash(32, 0);
24030 hash->Finish(std::data(command_hash), command_hash.size());
24031 std::string authorization_section_bytes;
24032 std::string authorization_size_bytes;
24033 if (authorization_delegate) {
24034 if (!authorization_delegate->GetCommandAuthorization(
24035 command_hash, is_command_parameter_encryption_possible,
24036 is_response_parameter_encryption_possible,
24037 &authorization_section_bytes)) {
24038 return TRUNKS_RC_AUTHORIZATION_FAILED;
24039 }
24040 if (!authorization_section_bytes.empty()) {
24041 tag = TPM_ST_SESSIONS;
24042 std::string tmp;
24043 rc = Serialize_UINT32(authorization_section_bytes.size(),
24044 &authorization_size_bytes);
24045 if (rc != TPM_RC_SUCCESS) {
24046 return rc;
24047 }
24048 command_size +=
24049 authorization_size_bytes.size() + authorization_section_bytes.size();
24050 }
24051 }
24052 std::string tag_bytes;
24053 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24054 if (rc != TPM_RC_SUCCESS) {
24055 return rc;
24056 }
24057 std::string command_size_bytes;
24058 rc = Serialize_UINT32(command_size, &command_size_bytes);
24059 if (rc != TPM_RC_SUCCESS) {
24060 return rc;
24061 }
24062 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24063 handle_section_bytes + authorization_size_bytes +
24064 authorization_section_bytes + parameter_section_bytes;
24065 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24066 VLOG(2) << "Command: "
24067 << base::HexEncode(serialized_command->data(),
24068 serialized_command->size());
24069 return TPM_RC_SUCCESS;
24070 }
24071
ParseResponse_PolicyDuplicationSelect(const std::string & response,AuthorizationDelegate * authorization_delegate)24072 TPM_RC Tpm::ParseResponse_PolicyDuplicationSelect(
24073 const std::string& response,
24074 AuthorizationDelegate* authorization_delegate) {
24075 VLOG(3) << __func__;
24076 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24077 TPM_RC rc = TPM_RC_SUCCESS;
24078 std::string buffer(response);
24079 TPM_ST tag;
24080 std::string tag_bytes;
24081 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24082 if (rc != TPM_RC_SUCCESS) {
24083 return rc;
24084 }
24085 UINT32 response_size;
24086 std::string response_size_bytes;
24087 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24088 if (rc != TPM_RC_SUCCESS) {
24089 return rc;
24090 }
24091 TPM_RC response_code;
24092 std::string response_code_bytes;
24093 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24094 if (rc != TPM_RC_SUCCESS) {
24095 return rc;
24096 }
24097 if (response_size != response.size()) {
24098 return TPM_RC_SIZE;
24099 }
24100 if (response_code != TPM_RC_SUCCESS) {
24101 return response_code;
24102 }
24103 TPM_CC command_code = TPM_CC_PolicyDuplicationSelect;
24104 std::string command_code_bytes;
24105 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24106 if (rc != TPM_RC_SUCCESS) {
24107 return rc;
24108 }
24109 std::string authorization_section_bytes;
24110 if (tag == TPM_ST_SESSIONS) {
24111 UINT32 parameter_section_size = buffer.size();
24112 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
24113 if (rc != TPM_RC_SUCCESS) {
24114 return rc;
24115 }
24116 if (parameter_section_size > buffer.size()) {
24117 return TPM_RC_INSUFFICIENT;
24118 }
24119 authorization_section_bytes = buffer.substr(parameter_section_size);
24120 // Keep the parameter section in |buffer|.
24121 buffer.erase(parameter_section_size);
24122 }
24123 std::unique_ptr<crypto::SecureHash> hash(
24124 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24125 hash->Update(response_code_bytes.data(), response_code_bytes.size());
24126 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24127 hash->Update(buffer.data(), buffer.size());
24128 std::string response_hash(32, 0);
24129 hash->Finish(std::data(response_hash), response_hash.size());
24130 if (tag == TPM_ST_SESSIONS) {
24131 if (!authorization_delegate)
24132 return TRUNKS_RC_AUTHORIZATION_FAILED;
24133 if (!authorization_delegate->CheckResponseAuthorization(
24134 response_hash, authorization_section_bytes)) {
24135 return TRUNKS_RC_AUTHORIZATION_FAILED;
24136 }
24137 }
24138 return TPM_RC_SUCCESS;
24139 }
24140
PolicyDuplicationSelectErrorCallback(Tpm::PolicyDuplicationSelectResponse callback,TPM_RC response_code)24141 void PolicyDuplicationSelectErrorCallback(
24142 Tpm::PolicyDuplicationSelectResponse callback, TPM_RC response_code) {
24143 VLOG(1) << __func__;
24144 std::move(callback).Run(response_code);
24145 }
24146
PolicyDuplicationSelectResponseParser(Tpm::PolicyDuplicationSelectResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24147 void PolicyDuplicationSelectResponseParser(
24148 Tpm::PolicyDuplicationSelectResponse callback,
24149 AuthorizationDelegate* authorization_delegate,
24150 const std::string& response) {
24151 VLOG(1) << __func__;
24152 TPM_RC rc = Tpm::ParseResponse_PolicyDuplicationSelect(
24153 response, authorization_delegate);
24154 if (rc != TPM_RC_SUCCESS) {
24155 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
24156 PolicyDuplicationSelectErrorCallback, std::move(callback));
24157 std::move(error_reporter).Run(rc);
24158 return;
24159 }
24160 std::move(callback).Run(rc);
24161 }
24162
PolicyDuplicationSelect(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NAME & object_name,const TPM2B_NAME & new_parent_name,const TPMI_YES_NO & include_object,AuthorizationDelegate * authorization_delegate,PolicyDuplicationSelectResponse callback)24163 void Tpm::PolicyDuplicationSelect(const TPMI_SH_POLICY& policy_session,
24164 const std::string& policy_session_name,
24165 const TPM2B_NAME& object_name,
24166 const TPM2B_NAME& new_parent_name,
24167 const TPMI_YES_NO& include_object,
24168 AuthorizationDelegate* authorization_delegate,
24169 PolicyDuplicationSelectResponse callback) {
24170 VLOG(1) << __func__;
24171 std::string command;
24172 TPM_RC rc = SerializeCommand_PolicyDuplicationSelect(
24173 policy_session, policy_session_name, object_name, new_parent_name,
24174 include_object, &command, authorization_delegate);
24175 if (rc != TPM_RC_SUCCESS) {
24176 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
24177 PolicyDuplicationSelectErrorCallback, std::move(callback));
24178 std::move(error_reporter).Run(rc);
24179 return;
24180 }
24181 base::OnceCallback<void(const std::string&)> parser =
24182 base::BindOnce(PolicyDuplicationSelectResponseParser, std::move(callback),
24183 authorization_delegate);
24184 transceiver_->SendCommand(command, std::move(parser));
24185 }
24186
PolicyDuplicationSelectSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NAME & object_name,const TPM2B_NAME & new_parent_name,const TPMI_YES_NO & include_object,AuthorizationDelegate * authorization_delegate)24187 TPM_RC Tpm::PolicyDuplicationSelectSync(
24188 const TPMI_SH_POLICY& policy_session,
24189 const std::string& policy_session_name,
24190 const TPM2B_NAME& object_name,
24191 const TPM2B_NAME& new_parent_name,
24192 const TPMI_YES_NO& include_object,
24193 AuthorizationDelegate* authorization_delegate) {
24194 VLOG(1) << __func__;
24195 std::string command;
24196 TPM_RC rc = SerializeCommand_PolicyDuplicationSelect(
24197 policy_session, policy_session_name, object_name, new_parent_name,
24198 include_object, &command, authorization_delegate);
24199 if (rc != TPM_RC_SUCCESS) {
24200 return rc;
24201 }
24202 std::string response = transceiver_->SendCommandAndWait(command);
24203 rc = ParseResponse_PolicyDuplicationSelect(response, authorization_delegate);
24204 return rc;
24205 }
24206
SerializeCommand_PolicyAuthorize(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & approved_policy,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & key_sign,const TPMT_TK_VERIFIED & check_ticket,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24207 TPM_RC Tpm::SerializeCommand_PolicyAuthorize(
24208 const TPMI_SH_POLICY& policy_session,
24209 const std::string& policy_session_name,
24210 const TPM2B_DIGEST& approved_policy,
24211 const TPM2B_NONCE& policy_ref,
24212 const TPM2B_NAME& key_sign,
24213 const TPMT_TK_VERIFIED& check_ticket,
24214 std::string* serialized_command,
24215 AuthorizationDelegate* authorization_delegate) {
24216 VLOG(3) << __func__;
24217 TPM_RC rc = TPM_RC_SUCCESS;
24218 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24219 UINT32 command_size = 10; // Header size.
24220 std::string handle_section_bytes;
24221 std::string parameter_section_bytes;
24222 TPM_CC command_code = TPM_CC_PolicyAuthorize;
24223 bool is_command_parameter_encryption_possible = true;
24224 bool is_response_parameter_encryption_possible = false;
24225 std::string command_code_bytes;
24226 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24227 if (rc != TPM_RC_SUCCESS) {
24228 return rc;
24229 }
24230 std::string policy_session_bytes;
24231 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24232 if (rc != TPM_RC_SUCCESS) {
24233 return rc;
24234 }
24235 std::string approved_policy_bytes;
24236 rc = Serialize_TPM2B_DIGEST(approved_policy, &approved_policy_bytes);
24237 if (rc != TPM_RC_SUCCESS) {
24238 return rc;
24239 }
24240 std::string policy_ref_bytes;
24241 rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
24242 if (rc != TPM_RC_SUCCESS) {
24243 return rc;
24244 }
24245 std::string key_sign_bytes;
24246 rc = Serialize_TPM2B_NAME(key_sign, &key_sign_bytes);
24247 if (rc != TPM_RC_SUCCESS) {
24248 return rc;
24249 }
24250 std::string check_ticket_bytes;
24251 rc = Serialize_TPMT_TK_VERIFIED(check_ticket, &check_ticket_bytes);
24252 if (rc != TPM_RC_SUCCESS) {
24253 return rc;
24254 }
24255 if (authorization_delegate) {
24256 // Encrypt just the parameter data, not the size.
24257 std::string tmp = approved_policy_bytes.substr(2);
24258 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
24259 return TRUNKS_RC_ENCRYPTION_FAILED;
24260 }
24261 approved_policy_bytes.replace(2, std::string::npos, tmp);
24262 }
24263 std::unique_ptr<crypto::SecureHash> hash(
24264 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24265 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24266 hash->Update(policy_session_name.data(), policy_session_name.size());
24267 handle_section_bytes += policy_session_bytes;
24268 command_size += policy_session_bytes.size();
24269 hash->Update(approved_policy_bytes.data(), approved_policy_bytes.size());
24270 parameter_section_bytes += approved_policy_bytes;
24271 command_size += approved_policy_bytes.size();
24272 hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
24273 parameter_section_bytes += policy_ref_bytes;
24274 command_size += policy_ref_bytes.size();
24275 hash->Update(key_sign_bytes.data(), key_sign_bytes.size());
24276 parameter_section_bytes += key_sign_bytes;
24277 command_size += key_sign_bytes.size();
24278 hash->Update(check_ticket_bytes.data(), check_ticket_bytes.size());
24279 parameter_section_bytes += check_ticket_bytes;
24280 command_size += check_ticket_bytes.size();
24281 std::string command_hash(32, 0);
24282 hash->Finish(std::data(command_hash), command_hash.size());
24283 std::string authorization_section_bytes;
24284 std::string authorization_size_bytes;
24285 if (authorization_delegate) {
24286 if (!authorization_delegate->GetCommandAuthorization(
24287 command_hash, is_command_parameter_encryption_possible,
24288 is_response_parameter_encryption_possible,
24289 &authorization_section_bytes)) {
24290 return TRUNKS_RC_AUTHORIZATION_FAILED;
24291 }
24292 if (!authorization_section_bytes.empty()) {
24293 tag = TPM_ST_SESSIONS;
24294 std::string tmp;
24295 rc = Serialize_UINT32(authorization_section_bytes.size(),
24296 &authorization_size_bytes);
24297 if (rc != TPM_RC_SUCCESS) {
24298 return rc;
24299 }
24300 command_size +=
24301 authorization_size_bytes.size() + authorization_section_bytes.size();
24302 }
24303 }
24304 std::string tag_bytes;
24305 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24306 if (rc != TPM_RC_SUCCESS) {
24307 return rc;
24308 }
24309 std::string command_size_bytes;
24310 rc = Serialize_UINT32(command_size, &command_size_bytes);
24311 if (rc != TPM_RC_SUCCESS) {
24312 return rc;
24313 }
24314 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24315 handle_section_bytes + authorization_size_bytes +
24316 authorization_section_bytes + parameter_section_bytes;
24317 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24318 VLOG(2) << "Command: "
24319 << base::HexEncode(serialized_command->data(),
24320 serialized_command->size());
24321 return TPM_RC_SUCCESS;
24322 }
24323
ParseResponse_PolicyAuthorize(const std::string & response,AuthorizationDelegate * authorization_delegate)24324 TPM_RC Tpm::ParseResponse_PolicyAuthorize(
24325 const std::string& response,
24326 AuthorizationDelegate* authorization_delegate) {
24327 VLOG(3) << __func__;
24328 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24329 TPM_RC rc = TPM_RC_SUCCESS;
24330 std::string buffer(response);
24331 TPM_ST tag;
24332 std::string tag_bytes;
24333 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24334 if (rc != TPM_RC_SUCCESS) {
24335 return rc;
24336 }
24337 UINT32 response_size;
24338 std::string response_size_bytes;
24339 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24340 if (rc != TPM_RC_SUCCESS) {
24341 return rc;
24342 }
24343 TPM_RC response_code;
24344 std::string response_code_bytes;
24345 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24346 if (rc != TPM_RC_SUCCESS) {
24347 return rc;
24348 }
24349 if (response_size != response.size()) {
24350 return TPM_RC_SIZE;
24351 }
24352 if (response_code != TPM_RC_SUCCESS) {
24353 return response_code;
24354 }
24355 TPM_CC command_code = TPM_CC_PolicyAuthorize;
24356 std::string command_code_bytes;
24357 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24358 if (rc != TPM_RC_SUCCESS) {
24359 return rc;
24360 }
24361 std::string authorization_section_bytes;
24362 if (tag == TPM_ST_SESSIONS) {
24363 UINT32 parameter_section_size = buffer.size();
24364 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
24365 if (rc != TPM_RC_SUCCESS) {
24366 return rc;
24367 }
24368 if (parameter_section_size > buffer.size()) {
24369 return TPM_RC_INSUFFICIENT;
24370 }
24371 authorization_section_bytes = buffer.substr(parameter_section_size);
24372 // Keep the parameter section in |buffer|.
24373 buffer.erase(parameter_section_size);
24374 }
24375 std::unique_ptr<crypto::SecureHash> hash(
24376 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24377 hash->Update(response_code_bytes.data(), response_code_bytes.size());
24378 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24379 hash->Update(buffer.data(), buffer.size());
24380 std::string response_hash(32, 0);
24381 hash->Finish(std::data(response_hash), response_hash.size());
24382 if (tag == TPM_ST_SESSIONS) {
24383 if (!authorization_delegate)
24384 return TRUNKS_RC_AUTHORIZATION_FAILED;
24385 if (!authorization_delegate->CheckResponseAuthorization(
24386 response_hash, authorization_section_bytes)) {
24387 return TRUNKS_RC_AUTHORIZATION_FAILED;
24388 }
24389 }
24390 return TPM_RC_SUCCESS;
24391 }
24392
PolicyAuthorizeErrorCallback(Tpm::PolicyAuthorizeResponse callback,TPM_RC response_code)24393 void PolicyAuthorizeErrorCallback(Tpm::PolicyAuthorizeResponse callback,
24394 TPM_RC response_code) {
24395 VLOG(1) << __func__;
24396 std::move(callback).Run(response_code);
24397 }
24398
PolicyAuthorizeResponseParser(Tpm::PolicyAuthorizeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24399 void PolicyAuthorizeResponseParser(
24400 Tpm::PolicyAuthorizeResponse callback,
24401 AuthorizationDelegate* authorization_delegate,
24402 const std::string& response) {
24403 VLOG(1) << __func__;
24404 TPM_RC rc =
24405 Tpm::ParseResponse_PolicyAuthorize(response, authorization_delegate);
24406 if (rc != TPM_RC_SUCCESS) {
24407 base::OnceCallback<void(TPM_RC)> error_reporter =
24408 base::BindOnce(PolicyAuthorizeErrorCallback, std::move(callback));
24409 std::move(error_reporter).Run(rc);
24410 return;
24411 }
24412 std::move(callback).Run(rc);
24413 }
24414
PolicyAuthorize(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & approved_policy,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & key_sign,const TPMT_TK_VERIFIED & check_ticket,AuthorizationDelegate * authorization_delegate,PolicyAuthorizeResponse callback)24415 void Tpm::PolicyAuthorize(const TPMI_SH_POLICY& policy_session,
24416 const std::string& policy_session_name,
24417 const TPM2B_DIGEST& approved_policy,
24418 const TPM2B_NONCE& policy_ref,
24419 const TPM2B_NAME& key_sign,
24420 const TPMT_TK_VERIFIED& check_ticket,
24421 AuthorizationDelegate* authorization_delegate,
24422 PolicyAuthorizeResponse callback) {
24423 VLOG(1) << __func__;
24424 std::string command;
24425 TPM_RC rc = SerializeCommand_PolicyAuthorize(
24426 policy_session, policy_session_name, approved_policy, policy_ref,
24427 key_sign, check_ticket, &command, authorization_delegate);
24428 if (rc != TPM_RC_SUCCESS) {
24429 base::OnceCallback<void(TPM_RC)> error_reporter =
24430 base::BindOnce(PolicyAuthorizeErrorCallback, std::move(callback));
24431 std::move(error_reporter).Run(rc);
24432 return;
24433 }
24434 base::OnceCallback<void(const std::string&)> parser =
24435 base::BindOnce(PolicyAuthorizeResponseParser, std::move(callback),
24436 authorization_delegate);
24437 transceiver_->SendCommand(command, std::move(parser));
24438 }
24439
PolicyAuthorizeSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & approved_policy,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & key_sign,const TPMT_TK_VERIFIED & check_ticket,AuthorizationDelegate * authorization_delegate)24440 TPM_RC Tpm::PolicyAuthorizeSync(const TPMI_SH_POLICY& policy_session,
24441 const std::string& policy_session_name,
24442 const TPM2B_DIGEST& approved_policy,
24443 const TPM2B_NONCE& policy_ref,
24444 const TPM2B_NAME& key_sign,
24445 const TPMT_TK_VERIFIED& check_ticket,
24446 AuthorizationDelegate* authorization_delegate) {
24447 VLOG(1) << __func__;
24448 std::string command;
24449 TPM_RC rc = SerializeCommand_PolicyAuthorize(
24450 policy_session, policy_session_name, approved_policy, policy_ref,
24451 key_sign, check_ticket, &command, authorization_delegate);
24452 if (rc != TPM_RC_SUCCESS) {
24453 return rc;
24454 }
24455 std::string response = transceiver_->SendCommandAndWait(command);
24456 rc = ParseResponse_PolicyAuthorize(response, authorization_delegate);
24457 return rc;
24458 }
24459
SerializeCommand_PolicyAuthValue(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24460 TPM_RC Tpm::SerializeCommand_PolicyAuthValue(
24461 const TPMI_SH_POLICY& policy_session,
24462 const std::string& policy_session_name,
24463 std::string* serialized_command,
24464 AuthorizationDelegate* authorization_delegate) {
24465 VLOG(3) << __func__;
24466 TPM_RC rc = TPM_RC_SUCCESS;
24467 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24468 UINT32 command_size = 10; // Header size.
24469 std::string handle_section_bytes;
24470 std::string parameter_section_bytes;
24471 TPM_CC command_code = TPM_CC_PolicyAuthValue;
24472 bool is_command_parameter_encryption_possible = false;
24473 bool is_response_parameter_encryption_possible = false;
24474 std::string command_code_bytes;
24475 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24476 if (rc != TPM_RC_SUCCESS) {
24477 return rc;
24478 }
24479 std::string policy_session_bytes;
24480 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24481 if (rc != TPM_RC_SUCCESS) {
24482 return rc;
24483 }
24484 std::unique_ptr<crypto::SecureHash> hash(
24485 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24486 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24487 hash->Update(policy_session_name.data(), policy_session_name.size());
24488 handle_section_bytes += policy_session_bytes;
24489 command_size += policy_session_bytes.size();
24490 std::string command_hash(32, 0);
24491 hash->Finish(std::data(command_hash), command_hash.size());
24492 std::string authorization_section_bytes;
24493 std::string authorization_size_bytes;
24494 if (authorization_delegate) {
24495 if (!authorization_delegate->GetCommandAuthorization(
24496 command_hash, is_command_parameter_encryption_possible,
24497 is_response_parameter_encryption_possible,
24498 &authorization_section_bytes)) {
24499 return TRUNKS_RC_AUTHORIZATION_FAILED;
24500 }
24501 if (!authorization_section_bytes.empty()) {
24502 tag = TPM_ST_SESSIONS;
24503 std::string tmp;
24504 rc = Serialize_UINT32(authorization_section_bytes.size(),
24505 &authorization_size_bytes);
24506 if (rc != TPM_RC_SUCCESS) {
24507 return rc;
24508 }
24509 command_size +=
24510 authorization_size_bytes.size() + authorization_section_bytes.size();
24511 }
24512 }
24513 std::string tag_bytes;
24514 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24515 if (rc != TPM_RC_SUCCESS) {
24516 return rc;
24517 }
24518 std::string command_size_bytes;
24519 rc = Serialize_UINT32(command_size, &command_size_bytes);
24520 if (rc != TPM_RC_SUCCESS) {
24521 return rc;
24522 }
24523 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24524 handle_section_bytes + authorization_size_bytes +
24525 authorization_section_bytes + parameter_section_bytes;
24526 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24527 VLOG(2) << "Command: "
24528 << base::HexEncode(serialized_command->data(),
24529 serialized_command->size());
24530 return TPM_RC_SUCCESS;
24531 }
24532
ParseResponse_PolicyAuthValue(const std::string & response,AuthorizationDelegate * authorization_delegate)24533 TPM_RC Tpm::ParseResponse_PolicyAuthValue(
24534 const std::string& response,
24535 AuthorizationDelegate* authorization_delegate) {
24536 VLOG(3) << __func__;
24537 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24538 TPM_RC rc = TPM_RC_SUCCESS;
24539 std::string buffer(response);
24540 TPM_ST tag;
24541 std::string tag_bytes;
24542 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24543 if (rc != TPM_RC_SUCCESS) {
24544 return rc;
24545 }
24546 UINT32 response_size;
24547 std::string response_size_bytes;
24548 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24549 if (rc != TPM_RC_SUCCESS) {
24550 return rc;
24551 }
24552 TPM_RC response_code;
24553 std::string response_code_bytes;
24554 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24555 if (rc != TPM_RC_SUCCESS) {
24556 return rc;
24557 }
24558 if (response_size != response.size()) {
24559 return TPM_RC_SIZE;
24560 }
24561 if (response_code != TPM_RC_SUCCESS) {
24562 return response_code;
24563 }
24564 TPM_CC command_code = TPM_CC_PolicyAuthValue;
24565 std::string command_code_bytes;
24566 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24567 if (rc != TPM_RC_SUCCESS) {
24568 return rc;
24569 }
24570 std::string authorization_section_bytes;
24571 if (tag == TPM_ST_SESSIONS) {
24572 UINT32 parameter_section_size = buffer.size();
24573 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
24574 if (rc != TPM_RC_SUCCESS) {
24575 return rc;
24576 }
24577 if (parameter_section_size > buffer.size()) {
24578 return TPM_RC_INSUFFICIENT;
24579 }
24580 authorization_section_bytes = buffer.substr(parameter_section_size);
24581 // Keep the parameter section in |buffer|.
24582 buffer.erase(parameter_section_size);
24583 }
24584 std::unique_ptr<crypto::SecureHash> hash(
24585 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24586 hash->Update(response_code_bytes.data(), response_code_bytes.size());
24587 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24588 hash->Update(buffer.data(), buffer.size());
24589 std::string response_hash(32, 0);
24590 hash->Finish(std::data(response_hash), response_hash.size());
24591 if (tag == TPM_ST_SESSIONS) {
24592 if (!authorization_delegate)
24593 return TRUNKS_RC_AUTHORIZATION_FAILED;
24594 if (!authorization_delegate->CheckResponseAuthorization(
24595 response_hash, authorization_section_bytes)) {
24596 return TRUNKS_RC_AUTHORIZATION_FAILED;
24597 }
24598 }
24599 return TPM_RC_SUCCESS;
24600 }
24601
PolicyAuthValueErrorCallback(Tpm::PolicyAuthValueResponse callback,TPM_RC response_code)24602 void PolicyAuthValueErrorCallback(Tpm::PolicyAuthValueResponse callback,
24603 TPM_RC response_code) {
24604 VLOG(1) << __func__;
24605 std::move(callback).Run(response_code);
24606 }
24607
PolicyAuthValueResponseParser(Tpm::PolicyAuthValueResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24608 void PolicyAuthValueResponseParser(
24609 Tpm::PolicyAuthValueResponse callback,
24610 AuthorizationDelegate* authorization_delegate,
24611 const std::string& response) {
24612 VLOG(1) << __func__;
24613 TPM_RC rc =
24614 Tpm::ParseResponse_PolicyAuthValue(response, authorization_delegate);
24615 if (rc != TPM_RC_SUCCESS) {
24616 base::OnceCallback<void(TPM_RC)> error_reporter =
24617 base::BindOnce(PolicyAuthValueErrorCallback, std::move(callback));
24618 std::move(error_reporter).Run(rc);
24619 return;
24620 }
24621 std::move(callback).Run(rc);
24622 }
24623
PolicyAuthValue(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyAuthValueResponse callback)24624 void Tpm::PolicyAuthValue(const TPMI_SH_POLICY& policy_session,
24625 const std::string& policy_session_name,
24626 AuthorizationDelegate* authorization_delegate,
24627 PolicyAuthValueResponse callback) {
24628 VLOG(1) << __func__;
24629 std::string command;
24630 TPM_RC rc = SerializeCommand_PolicyAuthValue(
24631 policy_session, policy_session_name, &command, authorization_delegate);
24632 if (rc != TPM_RC_SUCCESS) {
24633 base::OnceCallback<void(TPM_RC)> error_reporter =
24634 base::BindOnce(PolicyAuthValueErrorCallback, std::move(callback));
24635 std::move(error_reporter).Run(rc);
24636 return;
24637 }
24638 base::OnceCallback<void(const std::string&)> parser =
24639 base::BindOnce(PolicyAuthValueResponseParser, std::move(callback),
24640 authorization_delegate);
24641 transceiver_->SendCommand(command, std::move(parser));
24642 }
24643
PolicyAuthValueSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)24644 TPM_RC Tpm::PolicyAuthValueSync(const TPMI_SH_POLICY& policy_session,
24645 const std::string& policy_session_name,
24646 AuthorizationDelegate* authorization_delegate) {
24647 VLOG(1) << __func__;
24648 std::string command;
24649 TPM_RC rc = SerializeCommand_PolicyAuthValue(
24650 policy_session, policy_session_name, &command, authorization_delegate);
24651 if (rc != TPM_RC_SUCCESS) {
24652 return rc;
24653 }
24654 std::string response = transceiver_->SendCommandAndWait(command);
24655 rc = ParseResponse_PolicyAuthValue(response, authorization_delegate);
24656 return rc;
24657 }
24658
SerializeCommand_PolicyPassword(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24659 TPM_RC Tpm::SerializeCommand_PolicyPassword(
24660 const TPMI_SH_POLICY& policy_session,
24661 const std::string& policy_session_name,
24662 std::string* serialized_command,
24663 AuthorizationDelegate* authorization_delegate) {
24664 VLOG(3) << __func__;
24665 TPM_RC rc = TPM_RC_SUCCESS;
24666 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24667 UINT32 command_size = 10; // Header size.
24668 std::string handle_section_bytes;
24669 std::string parameter_section_bytes;
24670 TPM_CC command_code = TPM_CC_PolicyPassword;
24671 bool is_command_parameter_encryption_possible = false;
24672 bool is_response_parameter_encryption_possible = false;
24673 std::string command_code_bytes;
24674 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24675 if (rc != TPM_RC_SUCCESS) {
24676 return rc;
24677 }
24678 std::string policy_session_bytes;
24679 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24680 if (rc != TPM_RC_SUCCESS) {
24681 return rc;
24682 }
24683 std::unique_ptr<crypto::SecureHash> hash(
24684 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24685 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24686 hash->Update(policy_session_name.data(), policy_session_name.size());
24687 handle_section_bytes += policy_session_bytes;
24688 command_size += policy_session_bytes.size();
24689 std::string command_hash(32, 0);
24690 hash->Finish(std::data(command_hash), command_hash.size());
24691 std::string authorization_section_bytes;
24692 std::string authorization_size_bytes;
24693 if (authorization_delegate) {
24694 if (!authorization_delegate->GetCommandAuthorization(
24695 command_hash, is_command_parameter_encryption_possible,
24696 is_response_parameter_encryption_possible,
24697 &authorization_section_bytes)) {
24698 return TRUNKS_RC_AUTHORIZATION_FAILED;
24699 }
24700 if (!authorization_section_bytes.empty()) {
24701 tag = TPM_ST_SESSIONS;
24702 std::string tmp;
24703 rc = Serialize_UINT32(authorization_section_bytes.size(),
24704 &authorization_size_bytes);
24705 if (rc != TPM_RC_SUCCESS) {
24706 return rc;
24707 }
24708 command_size +=
24709 authorization_size_bytes.size() + authorization_section_bytes.size();
24710 }
24711 }
24712 std::string tag_bytes;
24713 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24714 if (rc != TPM_RC_SUCCESS) {
24715 return rc;
24716 }
24717 std::string command_size_bytes;
24718 rc = Serialize_UINT32(command_size, &command_size_bytes);
24719 if (rc != TPM_RC_SUCCESS) {
24720 return rc;
24721 }
24722 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24723 handle_section_bytes + authorization_size_bytes +
24724 authorization_section_bytes + parameter_section_bytes;
24725 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24726 VLOG(2) << "Command: "
24727 << base::HexEncode(serialized_command->data(),
24728 serialized_command->size());
24729 return TPM_RC_SUCCESS;
24730 }
24731
ParseResponse_PolicyPassword(const std::string & response,AuthorizationDelegate * authorization_delegate)24732 TPM_RC Tpm::ParseResponse_PolicyPassword(
24733 const std::string& response,
24734 AuthorizationDelegate* authorization_delegate) {
24735 VLOG(3) << __func__;
24736 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24737 TPM_RC rc = TPM_RC_SUCCESS;
24738 std::string buffer(response);
24739 TPM_ST tag;
24740 std::string tag_bytes;
24741 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24742 if (rc != TPM_RC_SUCCESS) {
24743 return rc;
24744 }
24745 UINT32 response_size;
24746 std::string response_size_bytes;
24747 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24748 if (rc != TPM_RC_SUCCESS) {
24749 return rc;
24750 }
24751 TPM_RC response_code;
24752 std::string response_code_bytes;
24753 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24754 if (rc != TPM_RC_SUCCESS) {
24755 return rc;
24756 }
24757 if (response_size != response.size()) {
24758 return TPM_RC_SIZE;
24759 }
24760 if (response_code != TPM_RC_SUCCESS) {
24761 return response_code;
24762 }
24763 TPM_CC command_code = TPM_CC_PolicyPassword;
24764 std::string command_code_bytes;
24765 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24766 if (rc != TPM_RC_SUCCESS) {
24767 return rc;
24768 }
24769 std::string authorization_section_bytes;
24770 if (tag == TPM_ST_SESSIONS) {
24771 UINT32 parameter_section_size = buffer.size();
24772 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
24773 if (rc != TPM_RC_SUCCESS) {
24774 return rc;
24775 }
24776 if (parameter_section_size > buffer.size()) {
24777 return TPM_RC_INSUFFICIENT;
24778 }
24779 authorization_section_bytes = buffer.substr(parameter_section_size);
24780 // Keep the parameter section in |buffer|.
24781 buffer.erase(parameter_section_size);
24782 }
24783 std::unique_ptr<crypto::SecureHash> hash(
24784 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24785 hash->Update(response_code_bytes.data(), response_code_bytes.size());
24786 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24787 hash->Update(buffer.data(), buffer.size());
24788 std::string response_hash(32, 0);
24789 hash->Finish(std::data(response_hash), response_hash.size());
24790 if (tag == TPM_ST_SESSIONS) {
24791 if (!authorization_delegate)
24792 return TRUNKS_RC_AUTHORIZATION_FAILED;
24793 if (!authorization_delegate->CheckResponseAuthorization(
24794 response_hash, authorization_section_bytes)) {
24795 return TRUNKS_RC_AUTHORIZATION_FAILED;
24796 }
24797 }
24798 return TPM_RC_SUCCESS;
24799 }
24800
PolicyPasswordErrorCallback(Tpm::PolicyPasswordResponse callback,TPM_RC response_code)24801 void PolicyPasswordErrorCallback(Tpm::PolicyPasswordResponse callback,
24802 TPM_RC response_code) {
24803 VLOG(1) << __func__;
24804 std::move(callback).Run(response_code);
24805 }
24806
PolicyPasswordResponseParser(Tpm::PolicyPasswordResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24807 void PolicyPasswordResponseParser(Tpm::PolicyPasswordResponse callback,
24808 AuthorizationDelegate* authorization_delegate,
24809 const std::string& response) {
24810 VLOG(1) << __func__;
24811 TPM_RC rc =
24812 Tpm::ParseResponse_PolicyPassword(response, authorization_delegate);
24813 if (rc != TPM_RC_SUCCESS) {
24814 base::OnceCallback<void(TPM_RC)> error_reporter =
24815 base::BindOnce(PolicyPasswordErrorCallback, std::move(callback));
24816 std::move(error_reporter).Run(rc);
24817 return;
24818 }
24819 std::move(callback).Run(rc);
24820 }
24821
PolicyPassword(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyPasswordResponse callback)24822 void Tpm::PolicyPassword(const TPMI_SH_POLICY& policy_session,
24823 const std::string& policy_session_name,
24824 AuthorizationDelegate* authorization_delegate,
24825 PolicyPasswordResponse callback) {
24826 VLOG(1) << __func__;
24827 std::string command;
24828 TPM_RC rc = SerializeCommand_PolicyPassword(
24829 policy_session, policy_session_name, &command, authorization_delegate);
24830 if (rc != TPM_RC_SUCCESS) {
24831 base::OnceCallback<void(TPM_RC)> error_reporter =
24832 base::BindOnce(PolicyPasswordErrorCallback, std::move(callback));
24833 std::move(error_reporter).Run(rc);
24834 return;
24835 }
24836 base::OnceCallback<void(const std::string&)> parser =
24837 base::BindOnce(PolicyPasswordResponseParser, std::move(callback),
24838 authorization_delegate);
24839 transceiver_->SendCommand(command, std::move(parser));
24840 }
24841
PolicyPasswordSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)24842 TPM_RC Tpm::PolicyPasswordSync(const TPMI_SH_POLICY& policy_session,
24843 const std::string& policy_session_name,
24844 AuthorizationDelegate* authorization_delegate) {
24845 VLOG(1) << __func__;
24846 std::string command;
24847 TPM_RC rc = SerializeCommand_PolicyPassword(
24848 policy_session, policy_session_name, &command, authorization_delegate);
24849 if (rc != TPM_RC_SUCCESS) {
24850 return rc;
24851 }
24852 std::string response = transceiver_->SendCommandAndWait(command);
24853 rc = ParseResponse_PolicyPassword(response, authorization_delegate);
24854 return rc;
24855 }
24856
SerializeCommand_PolicyGetDigest(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24857 TPM_RC Tpm::SerializeCommand_PolicyGetDigest(
24858 const TPMI_SH_POLICY& policy_session,
24859 const std::string& policy_session_name,
24860 std::string* serialized_command,
24861 AuthorizationDelegate* authorization_delegate) {
24862 VLOG(3) << __func__;
24863 TPM_RC rc = TPM_RC_SUCCESS;
24864 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24865 UINT32 command_size = 10; // Header size.
24866 std::string handle_section_bytes;
24867 std::string parameter_section_bytes;
24868 TPM_CC command_code = TPM_CC_PolicyGetDigest;
24869 bool is_command_parameter_encryption_possible = false;
24870 bool is_response_parameter_encryption_possible = true;
24871 std::string command_code_bytes;
24872 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24873 if (rc != TPM_RC_SUCCESS) {
24874 return rc;
24875 }
24876 std::string policy_session_bytes;
24877 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24878 if (rc != TPM_RC_SUCCESS) {
24879 return rc;
24880 }
24881 std::unique_ptr<crypto::SecureHash> hash(
24882 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24883 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24884 hash->Update(policy_session_name.data(), policy_session_name.size());
24885 handle_section_bytes += policy_session_bytes;
24886 command_size += policy_session_bytes.size();
24887 std::string command_hash(32, 0);
24888 hash->Finish(std::data(command_hash), command_hash.size());
24889 std::string authorization_section_bytes;
24890 std::string authorization_size_bytes;
24891 if (authorization_delegate) {
24892 if (!authorization_delegate->GetCommandAuthorization(
24893 command_hash, is_command_parameter_encryption_possible,
24894 is_response_parameter_encryption_possible,
24895 &authorization_section_bytes)) {
24896 return TRUNKS_RC_AUTHORIZATION_FAILED;
24897 }
24898 if (!authorization_section_bytes.empty()) {
24899 tag = TPM_ST_SESSIONS;
24900 std::string tmp;
24901 rc = Serialize_UINT32(authorization_section_bytes.size(),
24902 &authorization_size_bytes);
24903 if (rc != TPM_RC_SUCCESS) {
24904 return rc;
24905 }
24906 command_size +=
24907 authorization_size_bytes.size() + authorization_section_bytes.size();
24908 }
24909 }
24910 std::string tag_bytes;
24911 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24912 if (rc != TPM_RC_SUCCESS) {
24913 return rc;
24914 }
24915 std::string command_size_bytes;
24916 rc = Serialize_UINT32(command_size, &command_size_bytes);
24917 if (rc != TPM_RC_SUCCESS) {
24918 return rc;
24919 }
24920 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24921 handle_section_bytes + authorization_size_bytes +
24922 authorization_section_bytes + parameter_section_bytes;
24923 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24924 VLOG(2) << "Command: "
24925 << base::HexEncode(serialized_command->data(),
24926 serialized_command->size());
24927 return TPM_RC_SUCCESS;
24928 }
24929
ParseResponse_PolicyGetDigest(const std::string & response,TPM2B_DIGEST * policy_digest,AuthorizationDelegate * authorization_delegate)24930 TPM_RC Tpm::ParseResponse_PolicyGetDigest(
24931 const std::string& response,
24932 TPM2B_DIGEST* policy_digest,
24933 AuthorizationDelegate* authorization_delegate) {
24934 VLOG(3) << __func__;
24935 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24936 TPM_RC rc = TPM_RC_SUCCESS;
24937 std::string buffer(response);
24938 TPM_ST tag;
24939 std::string tag_bytes;
24940 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24941 if (rc != TPM_RC_SUCCESS) {
24942 return rc;
24943 }
24944 UINT32 response_size;
24945 std::string response_size_bytes;
24946 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24947 if (rc != TPM_RC_SUCCESS) {
24948 return rc;
24949 }
24950 TPM_RC response_code;
24951 std::string response_code_bytes;
24952 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24953 if (rc != TPM_RC_SUCCESS) {
24954 return rc;
24955 }
24956 if (response_size != response.size()) {
24957 return TPM_RC_SIZE;
24958 }
24959 if (response_code != TPM_RC_SUCCESS) {
24960 return response_code;
24961 }
24962 TPM_CC command_code = TPM_CC_PolicyGetDigest;
24963 std::string command_code_bytes;
24964 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24965 if (rc != TPM_RC_SUCCESS) {
24966 return rc;
24967 }
24968 std::string authorization_section_bytes;
24969 if (tag == TPM_ST_SESSIONS) {
24970 UINT32 parameter_section_size = buffer.size();
24971 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
24972 if (rc != TPM_RC_SUCCESS) {
24973 return rc;
24974 }
24975 if (parameter_section_size > buffer.size()) {
24976 return TPM_RC_INSUFFICIENT;
24977 }
24978 authorization_section_bytes = buffer.substr(parameter_section_size);
24979 // Keep the parameter section in |buffer|.
24980 buffer.erase(parameter_section_size);
24981 }
24982 std::unique_ptr<crypto::SecureHash> hash(
24983 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24984 hash->Update(response_code_bytes.data(), response_code_bytes.size());
24985 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24986 hash->Update(buffer.data(), buffer.size());
24987 std::string response_hash(32, 0);
24988 hash->Finish(std::data(response_hash), response_hash.size());
24989 if (tag == TPM_ST_SESSIONS) {
24990 if (!authorization_delegate)
24991 return TRUNKS_RC_AUTHORIZATION_FAILED;
24992 if (!authorization_delegate->CheckResponseAuthorization(
24993 response_hash, authorization_section_bytes)) {
24994 return TRUNKS_RC_AUTHORIZATION_FAILED;
24995 }
24996 }
24997 if (tag == TPM_ST_SESSIONS) {
24998 if (!authorization_delegate)
24999 return TRUNKS_RC_AUTHORIZATION_FAILED;
25000
25001 // Parse the encrypted parameter size.
25002 UINT16 size;
25003 std::string size_buffer = buffer.substr(0, 2);
25004 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
25005 return result;
25006 }
25007 if (buffer.size() < 2 + size) {
25008 return TPM_RC_INSUFFICIENT;
25009 }
25010
25011 // Decrypt just the parameter data, not the size.
25012 std::string decrypted_data = buffer.substr(2, size);
25013 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
25014 return TRUNKS_RC_ENCRYPTION_FAILED;
25015 }
25016 buffer.replace(2, size, decrypted_data);
25017 }
25018 std::string policy_digest_bytes;
25019 rc = Parse_TPM2B_DIGEST(&buffer, policy_digest, &policy_digest_bytes);
25020 if (rc != TPM_RC_SUCCESS) {
25021 return rc;
25022 }
25023 return TPM_RC_SUCCESS;
25024 }
25025
PolicyGetDigestErrorCallback(Tpm::PolicyGetDigestResponse callback,TPM_RC response_code)25026 void PolicyGetDigestErrorCallback(Tpm::PolicyGetDigestResponse callback,
25027 TPM_RC response_code) {
25028 VLOG(1) << __func__;
25029 std::move(callback).Run(response_code, TPM2B_DIGEST());
25030 }
25031
PolicyGetDigestResponseParser(Tpm::PolicyGetDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25032 void PolicyGetDigestResponseParser(
25033 Tpm::PolicyGetDigestResponse callback,
25034 AuthorizationDelegate* authorization_delegate,
25035 const std::string& response) {
25036 VLOG(1) << __func__;
25037 TPM2B_DIGEST policy_digest;
25038 TPM_RC rc = Tpm::ParseResponse_PolicyGetDigest(response, &policy_digest,
25039 authorization_delegate);
25040 if (rc != TPM_RC_SUCCESS) {
25041 base::OnceCallback<void(TPM_RC)> error_reporter =
25042 base::BindOnce(PolicyGetDigestErrorCallback, std::move(callback));
25043 std::move(error_reporter).Run(rc);
25044 return;
25045 }
25046 std::move(callback).Run(rc, policy_digest);
25047 }
25048
PolicyGetDigest(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyGetDigestResponse callback)25049 void Tpm::PolicyGetDigest(const TPMI_SH_POLICY& policy_session,
25050 const std::string& policy_session_name,
25051 AuthorizationDelegate* authorization_delegate,
25052 PolicyGetDigestResponse callback) {
25053 VLOG(1) << __func__;
25054 std::string command;
25055 TPM_RC rc = SerializeCommand_PolicyGetDigest(
25056 policy_session, policy_session_name, &command, authorization_delegate);
25057 if (rc != TPM_RC_SUCCESS) {
25058 base::OnceCallback<void(TPM_RC)> error_reporter =
25059 base::BindOnce(PolicyGetDigestErrorCallback, std::move(callback));
25060 std::move(error_reporter).Run(rc);
25061 return;
25062 }
25063 base::OnceCallback<void(const std::string&)> parser =
25064 base::BindOnce(PolicyGetDigestResponseParser, std::move(callback),
25065 authorization_delegate);
25066 transceiver_->SendCommand(command, std::move(parser));
25067 }
25068
PolicyGetDigestSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,TPM2B_DIGEST * policy_digest,AuthorizationDelegate * authorization_delegate)25069 TPM_RC Tpm::PolicyGetDigestSync(const TPMI_SH_POLICY& policy_session,
25070 const std::string& policy_session_name,
25071 TPM2B_DIGEST* policy_digest,
25072 AuthorizationDelegate* authorization_delegate) {
25073 VLOG(1) << __func__;
25074 std::string command;
25075 TPM_RC rc = SerializeCommand_PolicyGetDigest(
25076 policy_session, policy_session_name, &command, authorization_delegate);
25077 if (rc != TPM_RC_SUCCESS) {
25078 return rc;
25079 }
25080 std::string response = transceiver_->SendCommandAndWait(command);
25081 rc = ParseResponse_PolicyGetDigest(response, policy_digest,
25082 authorization_delegate);
25083 return rc;
25084 }
25085
SerializeCommand_PolicyNvWritten(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25086 TPM_RC Tpm::SerializeCommand_PolicyNvWritten(
25087 const TPMI_SH_POLICY& policy_session,
25088 const std::string& policy_session_name,
25089 const TPMI_YES_NO& written_set,
25090 std::string* serialized_command,
25091 AuthorizationDelegate* authorization_delegate) {
25092 VLOG(3) << __func__;
25093 TPM_RC rc = TPM_RC_SUCCESS;
25094 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25095 UINT32 command_size = 10; // Header size.
25096 std::string handle_section_bytes;
25097 std::string parameter_section_bytes;
25098 TPM_CC command_code = TPM_CC_PolicyNvWritten;
25099 bool is_command_parameter_encryption_possible = false;
25100 bool is_response_parameter_encryption_possible = false;
25101 std::string command_code_bytes;
25102 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25103 if (rc != TPM_RC_SUCCESS) {
25104 return rc;
25105 }
25106 std::string policy_session_bytes;
25107 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
25108 if (rc != TPM_RC_SUCCESS) {
25109 return rc;
25110 }
25111 std::string written_set_bytes;
25112 rc = Serialize_TPMI_YES_NO(written_set, &written_set_bytes);
25113 if (rc != TPM_RC_SUCCESS) {
25114 return rc;
25115 }
25116 std::unique_ptr<crypto::SecureHash> hash(
25117 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25118 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25119 hash->Update(policy_session_name.data(), policy_session_name.size());
25120 handle_section_bytes += policy_session_bytes;
25121 command_size += policy_session_bytes.size();
25122 hash->Update(written_set_bytes.data(), written_set_bytes.size());
25123 parameter_section_bytes += written_set_bytes;
25124 command_size += written_set_bytes.size();
25125 std::string command_hash(32, 0);
25126 hash->Finish(std::data(command_hash), command_hash.size());
25127 std::string authorization_section_bytes;
25128 std::string authorization_size_bytes;
25129 if (authorization_delegate) {
25130 if (!authorization_delegate->GetCommandAuthorization(
25131 command_hash, is_command_parameter_encryption_possible,
25132 is_response_parameter_encryption_possible,
25133 &authorization_section_bytes)) {
25134 return TRUNKS_RC_AUTHORIZATION_FAILED;
25135 }
25136 if (!authorization_section_bytes.empty()) {
25137 tag = TPM_ST_SESSIONS;
25138 std::string tmp;
25139 rc = Serialize_UINT32(authorization_section_bytes.size(),
25140 &authorization_size_bytes);
25141 if (rc != TPM_RC_SUCCESS) {
25142 return rc;
25143 }
25144 command_size +=
25145 authorization_size_bytes.size() + authorization_section_bytes.size();
25146 }
25147 }
25148 std::string tag_bytes;
25149 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25150 if (rc != TPM_RC_SUCCESS) {
25151 return rc;
25152 }
25153 std::string command_size_bytes;
25154 rc = Serialize_UINT32(command_size, &command_size_bytes);
25155 if (rc != TPM_RC_SUCCESS) {
25156 return rc;
25157 }
25158 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25159 handle_section_bytes + authorization_size_bytes +
25160 authorization_section_bytes + parameter_section_bytes;
25161 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25162 VLOG(2) << "Command: "
25163 << base::HexEncode(serialized_command->data(),
25164 serialized_command->size());
25165 return TPM_RC_SUCCESS;
25166 }
25167
ParseResponse_PolicyNvWritten(const std::string & response,AuthorizationDelegate * authorization_delegate)25168 TPM_RC Tpm::ParseResponse_PolicyNvWritten(
25169 const std::string& response,
25170 AuthorizationDelegate* authorization_delegate) {
25171 VLOG(3) << __func__;
25172 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25173 TPM_RC rc = TPM_RC_SUCCESS;
25174 std::string buffer(response);
25175 TPM_ST tag;
25176 std::string tag_bytes;
25177 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25178 if (rc != TPM_RC_SUCCESS) {
25179 return rc;
25180 }
25181 UINT32 response_size;
25182 std::string response_size_bytes;
25183 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25184 if (rc != TPM_RC_SUCCESS) {
25185 return rc;
25186 }
25187 TPM_RC response_code;
25188 std::string response_code_bytes;
25189 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25190 if (rc != TPM_RC_SUCCESS) {
25191 return rc;
25192 }
25193 if (response_size != response.size()) {
25194 return TPM_RC_SIZE;
25195 }
25196 if (response_code != TPM_RC_SUCCESS) {
25197 return response_code;
25198 }
25199 TPM_CC command_code = TPM_CC_PolicyNvWritten;
25200 std::string command_code_bytes;
25201 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25202 if (rc != TPM_RC_SUCCESS) {
25203 return rc;
25204 }
25205 std::string authorization_section_bytes;
25206 if (tag == TPM_ST_SESSIONS) {
25207 UINT32 parameter_section_size = buffer.size();
25208 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
25209 if (rc != TPM_RC_SUCCESS) {
25210 return rc;
25211 }
25212 if (parameter_section_size > buffer.size()) {
25213 return TPM_RC_INSUFFICIENT;
25214 }
25215 authorization_section_bytes = buffer.substr(parameter_section_size);
25216 // Keep the parameter section in |buffer|.
25217 buffer.erase(parameter_section_size);
25218 }
25219 std::unique_ptr<crypto::SecureHash> hash(
25220 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25221 hash->Update(response_code_bytes.data(), response_code_bytes.size());
25222 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25223 hash->Update(buffer.data(), buffer.size());
25224 std::string response_hash(32, 0);
25225 hash->Finish(std::data(response_hash), response_hash.size());
25226 if (tag == TPM_ST_SESSIONS) {
25227 if (!authorization_delegate)
25228 return TRUNKS_RC_AUTHORIZATION_FAILED;
25229 if (!authorization_delegate->CheckResponseAuthorization(
25230 response_hash, authorization_section_bytes)) {
25231 return TRUNKS_RC_AUTHORIZATION_FAILED;
25232 }
25233 }
25234 return TPM_RC_SUCCESS;
25235 }
25236
PolicyNvWrittenErrorCallback(Tpm::PolicyNvWrittenResponse callback,TPM_RC response_code)25237 void PolicyNvWrittenErrorCallback(Tpm::PolicyNvWrittenResponse callback,
25238 TPM_RC response_code) {
25239 VLOG(1) << __func__;
25240 std::move(callback).Run(response_code);
25241 }
25242
PolicyNvWrittenResponseParser(Tpm::PolicyNvWrittenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25243 void PolicyNvWrittenResponseParser(
25244 Tpm::PolicyNvWrittenResponse callback,
25245 AuthorizationDelegate* authorization_delegate,
25246 const std::string& response) {
25247 VLOG(1) << __func__;
25248 TPM_RC rc =
25249 Tpm::ParseResponse_PolicyNvWritten(response, authorization_delegate);
25250 if (rc != TPM_RC_SUCCESS) {
25251 base::OnceCallback<void(TPM_RC)> error_reporter =
25252 base::BindOnce(PolicyNvWrittenErrorCallback, std::move(callback));
25253 std::move(error_reporter).Run(rc);
25254 return;
25255 }
25256 std::move(callback).Run(rc);
25257 }
25258
PolicyNvWritten(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,AuthorizationDelegate * authorization_delegate,PolicyNvWrittenResponse callback)25259 void Tpm::PolicyNvWritten(const TPMI_SH_POLICY& policy_session,
25260 const std::string& policy_session_name,
25261 const TPMI_YES_NO& written_set,
25262 AuthorizationDelegate* authorization_delegate,
25263 PolicyNvWrittenResponse callback) {
25264 VLOG(1) << __func__;
25265 std::string command;
25266 TPM_RC rc = SerializeCommand_PolicyNvWritten(
25267 policy_session, policy_session_name, written_set, &command,
25268 authorization_delegate);
25269 if (rc != TPM_RC_SUCCESS) {
25270 base::OnceCallback<void(TPM_RC)> error_reporter =
25271 base::BindOnce(PolicyNvWrittenErrorCallback, std::move(callback));
25272 std::move(error_reporter).Run(rc);
25273 return;
25274 }
25275 base::OnceCallback<void(const std::string&)> parser =
25276 base::BindOnce(PolicyNvWrittenResponseParser, std::move(callback),
25277 authorization_delegate);
25278 transceiver_->SendCommand(command, std::move(parser));
25279 }
25280
PolicyNvWrittenSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,AuthorizationDelegate * authorization_delegate)25281 TPM_RC Tpm::PolicyNvWrittenSync(const TPMI_SH_POLICY& policy_session,
25282 const std::string& policy_session_name,
25283 const TPMI_YES_NO& written_set,
25284 AuthorizationDelegate* authorization_delegate) {
25285 VLOG(1) << __func__;
25286 std::string command;
25287 TPM_RC rc = SerializeCommand_PolicyNvWritten(
25288 policy_session, policy_session_name, written_set, &command,
25289 authorization_delegate);
25290 if (rc != TPM_RC_SUCCESS) {
25291 return rc;
25292 }
25293 std::string response = transceiver_->SendCommandAndWait(command);
25294 rc = ParseResponse_PolicyNvWritten(response, authorization_delegate);
25295 return rc;
25296 }
25297
SerializeCommand_CreatePrimary(const TPMI_RH_HIERARCHY & primary_handle,const std::string & primary_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25298 TPM_RC Tpm::SerializeCommand_CreatePrimary(
25299 const TPMI_RH_HIERARCHY& primary_handle,
25300 const std::string& primary_handle_name,
25301 const TPM2B_SENSITIVE_CREATE& in_sensitive,
25302 const TPM2B_PUBLIC& in_public,
25303 const TPM2B_DATA& outside_info,
25304 const TPML_PCR_SELECTION& creation_pcr,
25305 std::string* serialized_command,
25306 AuthorizationDelegate* authorization_delegate) {
25307 VLOG(3) << __func__;
25308 TPM_RC rc = TPM_RC_SUCCESS;
25309 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25310 UINT32 command_size = 10; // Header size.
25311 std::string handle_section_bytes;
25312 std::string parameter_section_bytes;
25313 TPM_CC command_code = TPM_CC_CreatePrimary;
25314 bool is_command_parameter_encryption_possible = true;
25315 bool is_response_parameter_encryption_possible = true;
25316 std::string command_code_bytes;
25317 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25318 if (rc != TPM_RC_SUCCESS) {
25319 return rc;
25320 }
25321 std::string primary_handle_bytes;
25322 rc = Serialize_TPMI_RH_HIERARCHY(primary_handle, &primary_handle_bytes);
25323 if (rc != TPM_RC_SUCCESS) {
25324 return rc;
25325 }
25326 std::string in_sensitive_bytes;
25327 rc = Serialize_TPM2B_SENSITIVE_CREATE(in_sensitive, &in_sensitive_bytes);
25328 if (rc != TPM_RC_SUCCESS) {
25329 return rc;
25330 }
25331 std::string in_public_bytes;
25332 rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
25333 if (rc != TPM_RC_SUCCESS) {
25334 return rc;
25335 }
25336 std::string outside_info_bytes;
25337 rc = Serialize_TPM2B_DATA(outside_info, &outside_info_bytes);
25338 if (rc != TPM_RC_SUCCESS) {
25339 return rc;
25340 }
25341 std::string creation_pcr_bytes;
25342 rc = Serialize_TPML_PCR_SELECTION(creation_pcr, &creation_pcr_bytes);
25343 if (rc != TPM_RC_SUCCESS) {
25344 return rc;
25345 }
25346 if (authorization_delegate) {
25347 // Encrypt just the parameter data, not the size.
25348 std::string tmp = in_sensitive_bytes.substr(2);
25349 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
25350 return TRUNKS_RC_ENCRYPTION_FAILED;
25351 }
25352 in_sensitive_bytes.replace(2, std::string::npos, tmp);
25353 }
25354 std::unique_ptr<crypto::SecureHash> hash(
25355 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25356 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25357 hash->Update(primary_handle_name.data(), primary_handle_name.size());
25358 handle_section_bytes += primary_handle_bytes;
25359 command_size += primary_handle_bytes.size();
25360 hash->Update(in_sensitive_bytes.data(), in_sensitive_bytes.size());
25361 parameter_section_bytes += in_sensitive_bytes;
25362 command_size += in_sensitive_bytes.size();
25363 hash->Update(in_public_bytes.data(), in_public_bytes.size());
25364 parameter_section_bytes += in_public_bytes;
25365 command_size += in_public_bytes.size();
25366 hash->Update(outside_info_bytes.data(), outside_info_bytes.size());
25367 parameter_section_bytes += outside_info_bytes;
25368 command_size += outside_info_bytes.size();
25369 hash->Update(creation_pcr_bytes.data(), creation_pcr_bytes.size());
25370 parameter_section_bytes += creation_pcr_bytes;
25371 command_size += creation_pcr_bytes.size();
25372 std::string command_hash(32, 0);
25373 hash->Finish(std::data(command_hash), command_hash.size());
25374 std::string authorization_section_bytes;
25375 std::string authorization_size_bytes;
25376 if (authorization_delegate) {
25377 if (!authorization_delegate->GetCommandAuthorization(
25378 command_hash, is_command_parameter_encryption_possible,
25379 is_response_parameter_encryption_possible,
25380 &authorization_section_bytes)) {
25381 return TRUNKS_RC_AUTHORIZATION_FAILED;
25382 }
25383 if (!authorization_section_bytes.empty()) {
25384 tag = TPM_ST_SESSIONS;
25385 std::string tmp;
25386 rc = Serialize_UINT32(authorization_section_bytes.size(),
25387 &authorization_size_bytes);
25388 if (rc != TPM_RC_SUCCESS) {
25389 return rc;
25390 }
25391 command_size +=
25392 authorization_size_bytes.size() + authorization_section_bytes.size();
25393 }
25394 }
25395 std::string tag_bytes;
25396 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25397 if (rc != TPM_RC_SUCCESS) {
25398 return rc;
25399 }
25400 std::string command_size_bytes;
25401 rc = Serialize_UINT32(command_size, &command_size_bytes);
25402 if (rc != TPM_RC_SUCCESS) {
25403 return rc;
25404 }
25405 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25406 handle_section_bytes + authorization_size_bytes +
25407 authorization_section_bytes + parameter_section_bytes;
25408 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25409 VLOG(2) << "Command: "
25410 << base::HexEncode(serialized_command->data(),
25411 serialized_command->size());
25412 return TPM_RC_SUCCESS;
25413 }
25414
ParseResponse_CreatePrimary(const std::string & response,TPM_HANDLE * object_handle,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)25415 TPM_RC Tpm::ParseResponse_CreatePrimary(
25416 const std::string& response,
25417 TPM_HANDLE* object_handle,
25418 TPM2B_PUBLIC* out_public,
25419 TPM2B_CREATION_DATA* creation_data,
25420 TPM2B_DIGEST* creation_hash,
25421 TPMT_TK_CREATION* creation_ticket,
25422 TPM2B_NAME* name,
25423 AuthorizationDelegate* authorization_delegate) {
25424 VLOG(3) << __func__;
25425 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25426 TPM_RC rc = TPM_RC_SUCCESS;
25427 std::string buffer(response);
25428 TPM_ST tag;
25429 std::string tag_bytes;
25430 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25431 if (rc != TPM_RC_SUCCESS) {
25432 return rc;
25433 }
25434 UINT32 response_size;
25435 std::string response_size_bytes;
25436 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25437 if (rc != TPM_RC_SUCCESS) {
25438 return rc;
25439 }
25440 TPM_RC response_code;
25441 std::string response_code_bytes;
25442 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25443 if (rc != TPM_RC_SUCCESS) {
25444 return rc;
25445 }
25446 if (response_size != response.size()) {
25447 return TPM_RC_SIZE;
25448 }
25449 if (response_code != TPM_RC_SUCCESS) {
25450 return response_code;
25451 }
25452 std::string object_handle_bytes;
25453 rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
25454 if (rc != TPM_RC_SUCCESS) {
25455 return rc;
25456 }
25457 TPM_CC command_code = TPM_CC_CreatePrimary;
25458 std::string command_code_bytes;
25459 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25460 if (rc != TPM_RC_SUCCESS) {
25461 return rc;
25462 }
25463 std::string authorization_section_bytes;
25464 if (tag == TPM_ST_SESSIONS) {
25465 UINT32 parameter_section_size = buffer.size();
25466 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
25467 if (rc != TPM_RC_SUCCESS) {
25468 return rc;
25469 }
25470 if (parameter_section_size > buffer.size()) {
25471 return TPM_RC_INSUFFICIENT;
25472 }
25473 authorization_section_bytes = buffer.substr(parameter_section_size);
25474 // Keep the parameter section in |buffer|.
25475 buffer.erase(parameter_section_size);
25476 }
25477 std::unique_ptr<crypto::SecureHash> hash(
25478 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25479 hash->Update(response_code_bytes.data(), response_code_bytes.size());
25480 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25481 hash->Update(buffer.data(), buffer.size());
25482 std::string response_hash(32, 0);
25483 hash->Finish(std::data(response_hash), response_hash.size());
25484 if (tag == TPM_ST_SESSIONS) {
25485 if (!authorization_delegate)
25486 return TRUNKS_RC_AUTHORIZATION_FAILED;
25487 if (!authorization_delegate->CheckResponseAuthorization(
25488 response_hash, authorization_section_bytes)) {
25489 return TRUNKS_RC_AUTHORIZATION_FAILED;
25490 }
25491 }
25492 if (tag == TPM_ST_SESSIONS) {
25493 if (!authorization_delegate)
25494 return TRUNKS_RC_AUTHORIZATION_FAILED;
25495
25496 // Parse the encrypted parameter size.
25497 UINT16 size;
25498 std::string size_buffer = buffer.substr(0, 2);
25499 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
25500 return result;
25501 }
25502 if (buffer.size() < 2 + size) {
25503 return TPM_RC_INSUFFICIENT;
25504 }
25505
25506 // Decrypt just the parameter data, not the size.
25507 std::string decrypted_data = buffer.substr(2, size);
25508 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
25509 return TRUNKS_RC_ENCRYPTION_FAILED;
25510 }
25511 buffer.replace(2, size, decrypted_data);
25512 }
25513 std::string out_public_bytes;
25514 rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
25515 if (rc != TPM_RC_SUCCESS) {
25516 return rc;
25517 }
25518 std::string creation_data_bytes;
25519 rc = Parse_TPM2B_CREATION_DATA(&buffer, creation_data, &creation_data_bytes);
25520 if (rc != TPM_RC_SUCCESS) {
25521 return rc;
25522 }
25523 std::string creation_hash_bytes;
25524 rc = Parse_TPM2B_DIGEST(&buffer, creation_hash, &creation_hash_bytes);
25525 if (rc != TPM_RC_SUCCESS) {
25526 return rc;
25527 }
25528 std::string creation_ticket_bytes;
25529 rc = Parse_TPMT_TK_CREATION(&buffer, creation_ticket, &creation_ticket_bytes);
25530 if (rc != TPM_RC_SUCCESS) {
25531 return rc;
25532 }
25533 std::string name_bytes;
25534 rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
25535 if (rc != TPM_RC_SUCCESS) {
25536 return rc;
25537 }
25538 return TPM_RC_SUCCESS;
25539 }
25540
CreatePrimaryErrorCallback(Tpm::CreatePrimaryResponse callback,TPM_RC response_code)25541 void CreatePrimaryErrorCallback(Tpm::CreatePrimaryResponse callback,
25542 TPM_RC response_code) {
25543 VLOG(1) << __func__;
25544 std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_PUBLIC(),
25545 TPM2B_CREATION_DATA(), TPM2B_DIGEST(),
25546 TPMT_TK_CREATION(), TPM2B_NAME());
25547 }
25548
CreatePrimaryResponseParser(Tpm::CreatePrimaryResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25549 void CreatePrimaryResponseParser(Tpm::CreatePrimaryResponse callback,
25550 AuthorizationDelegate* authorization_delegate,
25551 const std::string& response) {
25552 VLOG(1) << __func__;
25553 TPM_HANDLE object_handle;
25554 TPM2B_PUBLIC out_public;
25555 TPM2B_CREATION_DATA creation_data;
25556 TPM2B_DIGEST creation_hash;
25557 TPMT_TK_CREATION creation_ticket;
25558 TPM2B_NAME name;
25559 TPM_RC rc = Tpm::ParseResponse_CreatePrimary(
25560 response, &object_handle, &out_public, &creation_data, &creation_hash,
25561 &creation_ticket, &name, authorization_delegate);
25562 if (rc != TPM_RC_SUCCESS) {
25563 base::OnceCallback<void(TPM_RC)> error_reporter =
25564 base::BindOnce(CreatePrimaryErrorCallback, std::move(callback));
25565 std::move(error_reporter).Run(rc);
25566 return;
25567 }
25568 std::move(callback).Run(rc, object_handle, out_public, creation_data,
25569 creation_hash, creation_ticket, name);
25570 }
25571
CreatePrimary(const TPMI_RH_HIERARCHY & primary_handle,const std::string & primary_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,AuthorizationDelegate * authorization_delegate,CreatePrimaryResponse callback)25572 void Tpm::CreatePrimary(const TPMI_RH_HIERARCHY& primary_handle,
25573 const std::string& primary_handle_name,
25574 const TPM2B_SENSITIVE_CREATE& in_sensitive,
25575 const TPM2B_PUBLIC& in_public,
25576 const TPM2B_DATA& outside_info,
25577 const TPML_PCR_SELECTION& creation_pcr,
25578 AuthorizationDelegate* authorization_delegate,
25579 CreatePrimaryResponse callback) {
25580 VLOG(1) << __func__;
25581 std::string command;
25582 TPM_RC rc = SerializeCommand_CreatePrimary(
25583 primary_handle, primary_handle_name, in_sensitive, in_public,
25584 outside_info, creation_pcr, &command, authorization_delegate);
25585 if (rc != TPM_RC_SUCCESS) {
25586 base::OnceCallback<void(TPM_RC)> error_reporter =
25587 base::BindOnce(CreatePrimaryErrorCallback, std::move(callback));
25588 std::move(error_reporter).Run(rc);
25589 return;
25590 }
25591 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
25592 CreatePrimaryResponseParser, std::move(callback), authorization_delegate);
25593 transceiver_->SendCommand(command, std::move(parser));
25594 }
25595
CreatePrimarySync(const TPMI_RH_HIERARCHY & primary_handle,const std::string & primary_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,TPM_HANDLE * object_handle,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)25596 TPM_RC Tpm::CreatePrimarySync(const TPMI_RH_HIERARCHY& primary_handle,
25597 const std::string& primary_handle_name,
25598 const TPM2B_SENSITIVE_CREATE& in_sensitive,
25599 const TPM2B_PUBLIC& in_public,
25600 const TPM2B_DATA& outside_info,
25601 const TPML_PCR_SELECTION& creation_pcr,
25602 TPM_HANDLE* object_handle,
25603 TPM2B_PUBLIC* out_public,
25604 TPM2B_CREATION_DATA* creation_data,
25605 TPM2B_DIGEST* creation_hash,
25606 TPMT_TK_CREATION* creation_ticket,
25607 TPM2B_NAME* name,
25608 AuthorizationDelegate* authorization_delegate) {
25609 VLOG(1) << __func__;
25610 std::string command;
25611 TPM_RC rc = SerializeCommand_CreatePrimary(
25612 primary_handle, primary_handle_name, in_sensitive, in_public,
25613 outside_info, creation_pcr, &command, authorization_delegate);
25614 if (rc != TPM_RC_SUCCESS) {
25615 return rc;
25616 }
25617 std::string response = transceiver_->SendCommandAndWait(command);
25618 rc = ParseResponse_CreatePrimary(
25619 response, object_handle, out_public, creation_data, creation_hash,
25620 creation_ticket, name, authorization_delegate);
25621 return rc;
25622 }
25623
SerializeCommand_HierarchyControl(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPMI_RH_ENABLES & enable,const TPMI_YES_NO & state,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25624 TPM_RC Tpm::SerializeCommand_HierarchyControl(
25625 const TPMI_RH_HIERARCHY& auth_handle,
25626 const std::string& auth_handle_name,
25627 const TPMI_RH_ENABLES& enable,
25628 const TPMI_YES_NO& state,
25629 std::string* serialized_command,
25630 AuthorizationDelegate* authorization_delegate) {
25631 VLOG(3) << __func__;
25632 TPM_RC rc = TPM_RC_SUCCESS;
25633 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25634 UINT32 command_size = 10; // Header size.
25635 std::string handle_section_bytes;
25636 std::string parameter_section_bytes;
25637 TPM_CC command_code = TPM_CC_HierarchyControl;
25638 bool is_command_parameter_encryption_possible = false;
25639 bool is_response_parameter_encryption_possible = false;
25640 std::string command_code_bytes;
25641 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25642 if (rc != TPM_RC_SUCCESS) {
25643 return rc;
25644 }
25645 std::string auth_handle_bytes;
25646 rc = Serialize_TPMI_RH_HIERARCHY(auth_handle, &auth_handle_bytes);
25647 if (rc != TPM_RC_SUCCESS) {
25648 return rc;
25649 }
25650 std::string enable_bytes;
25651 rc = Serialize_TPMI_RH_ENABLES(enable, &enable_bytes);
25652 if (rc != TPM_RC_SUCCESS) {
25653 return rc;
25654 }
25655 std::string state_bytes;
25656 rc = Serialize_TPMI_YES_NO(state, &state_bytes);
25657 if (rc != TPM_RC_SUCCESS) {
25658 return rc;
25659 }
25660 std::unique_ptr<crypto::SecureHash> hash(
25661 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25662 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25663 hash->Update(auth_handle_name.data(), auth_handle_name.size());
25664 handle_section_bytes += auth_handle_bytes;
25665 command_size += auth_handle_bytes.size();
25666 hash->Update(enable_bytes.data(), enable_bytes.size());
25667 parameter_section_bytes += enable_bytes;
25668 command_size += enable_bytes.size();
25669 hash->Update(state_bytes.data(), state_bytes.size());
25670 parameter_section_bytes += state_bytes;
25671 command_size += state_bytes.size();
25672 std::string command_hash(32, 0);
25673 hash->Finish(std::data(command_hash), command_hash.size());
25674 std::string authorization_section_bytes;
25675 std::string authorization_size_bytes;
25676 if (authorization_delegate) {
25677 if (!authorization_delegate->GetCommandAuthorization(
25678 command_hash, is_command_parameter_encryption_possible,
25679 is_response_parameter_encryption_possible,
25680 &authorization_section_bytes)) {
25681 return TRUNKS_RC_AUTHORIZATION_FAILED;
25682 }
25683 if (!authorization_section_bytes.empty()) {
25684 tag = TPM_ST_SESSIONS;
25685 std::string tmp;
25686 rc = Serialize_UINT32(authorization_section_bytes.size(),
25687 &authorization_size_bytes);
25688 if (rc != TPM_RC_SUCCESS) {
25689 return rc;
25690 }
25691 command_size +=
25692 authorization_size_bytes.size() + authorization_section_bytes.size();
25693 }
25694 }
25695 std::string tag_bytes;
25696 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25697 if (rc != TPM_RC_SUCCESS) {
25698 return rc;
25699 }
25700 std::string command_size_bytes;
25701 rc = Serialize_UINT32(command_size, &command_size_bytes);
25702 if (rc != TPM_RC_SUCCESS) {
25703 return rc;
25704 }
25705 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25706 handle_section_bytes + authorization_size_bytes +
25707 authorization_section_bytes + parameter_section_bytes;
25708 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25709 VLOG(2) << "Command: "
25710 << base::HexEncode(serialized_command->data(),
25711 serialized_command->size());
25712 return TPM_RC_SUCCESS;
25713 }
25714
ParseResponse_HierarchyControl(const std::string & response,AuthorizationDelegate * authorization_delegate)25715 TPM_RC Tpm::ParseResponse_HierarchyControl(
25716 const std::string& response,
25717 AuthorizationDelegate* authorization_delegate) {
25718 VLOG(3) << __func__;
25719 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25720 TPM_RC rc = TPM_RC_SUCCESS;
25721 std::string buffer(response);
25722 TPM_ST tag;
25723 std::string tag_bytes;
25724 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25725 if (rc != TPM_RC_SUCCESS) {
25726 return rc;
25727 }
25728 UINT32 response_size;
25729 std::string response_size_bytes;
25730 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25731 if (rc != TPM_RC_SUCCESS) {
25732 return rc;
25733 }
25734 TPM_RC response_code;
25735 std::string response_code_bytes;
25736 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25737 if (rc != TPM_RC_SUCCESS) {
25738 return rc;
25739 }
25740 if (response_size != response.size()) {
25741 return TPM_RC_SIZE;
25742 }
25743 if (response_code != TPM_RC_SUCCESS) {
25744 return response_code;
25745 }
25746 TPM_CC command_code = TPM_CC_HierarchyControl;
25747 std::string command_code_bytes;
25748 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25749 if (rc != TPM_RC_SUCCESS) {
25750 return rc;
25751 }
25752 std::string authorization_section_bytes;
25753 if (tag == TPM_ST_SESSIONS) {
25754 UINT32 parameter_section_size = buffer.size();
25755 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
25756 if (rc != TPM_RC_SUCCESS) {
25757 return rc;
25758 }
25759 if (parameter_section_size > buffer.size()) {
25760 return TPM_RC_INSUFFICIENT;
25761 }
25762 authorization_section_bytes = buffer.substr(parameter_section_size);
25763 // Keep the parameter section in |buffer|.
25764 buffer.erase(parameter_section_size);
25765 }
25766 std::unique_ptr<crypto::SecureHash> hash(
25767 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25768 hash->Update(response_code_bytes.data(), response_code_bytes.size());
25769 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25770 hash->Update(buffer.data(), buffer.size());
25771 std::string response_hash(32, 0);
25772 hash->Finish(std::data(response_hash), response_hash.size());
25773 if (tag == TPM_ST_SESSIONS) {
25774 if (!authorization_delegate)
25775 return TRUNKS_RC_AUTHORIZATION_FAILED;
25776 if (!authorization_delegate->CheckResponseAuthorization(
25777 response_hash, authorization_section_bytes)) {
25778 return TRUNKS_RC_AUTHORIZATION_FAILED;
25779 }
25780 }
25781 return TPM_RC_SUCCESS;
25782 }
25783
HierarchyControlErrorCallback(Tpm::HierarchyControlResponse callback,TPM_RC response_code)25784 void HierarchyControlErrorCallback(Tpm::HierarchyControlResponse callback,
25785 TPM_RC response_code) {
25786 VLOG(1) << __func__;
25787 std::move(callback).Run(response_code);
25788 }
25789
HierarchyControlResponseParser(Tpm::HierarchyControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25790 void HierarchyControlResponseParser(
25791 Tpm::HierarchyControlResponse callback,
25792 AuthorizationDelegate* authorization_delegate,
25793 const std::string& response) {
25794 VLOG(1) << __func__;
25795 TPM_RC rc =
25796 Tpm::ParseResponse_HierarchyControl(response, authorization_delegate);
25797 if (rc != TPM_RC_SUCCESS) {
25798 base::OnceCallback<void(TPM_RC)> error_reporter =
25799 base::BindOnce(HierarchyControlErrorCallback, std::move(callback));
25800 std::move(error_reporter).Run(rc);
25801 return;
25802 }
25803 std::move(callback).Run(rc);
25804 }
25805
HierarchyControl(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPMI_RH_ENABLES & enable,const TPMI_YES_NO & state,AuthorizationDelegate * authorization_delegate,HierarchyControlResponse callback)25806 void Tpm::HierarchyControl(const TPMI_RH_HIERARCHY& auth_handle,
25807 const std::string& auth_handle_name,
25808 const TPMI_RH_ENABLES& enable,
25809 const TPMI_YES_NO& state,
25810 AuthorizationDelegate* authorization_delegate,
25811 HierarchyControlResponse callback) {
25812 VLOG(1) << __func__;
25813 std::string command;
25814 TPM_RC rc = SerializeCommand_HierarchyControl(auth_handle, auth_handle_name,
25815 enable, state, &command,
25816 authorization_delegate);
25817 if (rc != TPM_RC_SUCCESS) {
25818 base::OnceCallback<void(TPM_RC)> error_reporter =
25819 base::BindOnce(HierarchyControlErrorCallback, std::move(callback));
25820 std::move(error_reporter).Run(rc);
25821 return;
25822 }
25823 base::OnceCallback<void(const std::string&)> parser =
25824 base::BindOnce(HierarchyControlResponseParser, std::move(callback),
25825 authorization_delegate);
25826 transceiver_->SendCommand(command, std::move(parser));
25827 }
25828
HierarchyControlSync(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPMI_RH_ENABLES & enable,const TPMI_YES_NO & state,AuthorizationDelegate * authorization_delegate)25829 TPM_RC Tpm::HierarchyControlSync(
25830 const TPMI_RH_HIERARCHY& auth_handle,
25831 const std::string& auth_handle_name,
25832 const TPMI_RH_ENABLES& enable,
25833 const TPMI_YES_NO& state,
25834 AuthorizationDelegate* authorization_delegate) {
25835 VLOG(1) << __func__;
25836 std::string command;
25837 TPM_RC rc = SerializeCommand_HierarchyControl(auth_handle, auth_handle_name,
25838 enable, state, &command,
25839 authorization_delegate);
25840 if (rc != TPM_RC_SUCCESS) {
25841 return rc;
25842 }
25843 std::string response = transceiver_->SendCommandAndWait(command);
25844 rc = ParseResponse_HierarchyControl(response, authorization_delegate);
25845 return rc;
25846 }
25847
SerializeCommand_SetPrimaryPolicy(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25848 TPM_RC Tpm::SerializeCommand_SetPrimaryPolicy(
25849 const TPMI_RH_HIERARCHY& auth_handle,
25850 const std::string& auth_handle_name,
25851 const TPM2B_DIGEST& auth_policy,
25852 const TPMI_ALG_HASH& hash_alg,
25853 std::string* serialized_command,
25854 AuthorizationDelegate* authorization_delegate) {
25855 VLOG(3) << __func__;
25856 TPM_RC rc = TPM_RC_SUCCESS;
25857 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25858 UINT32 command_size = 10; // Header size.
25859 std::string handle_section_bytes;
25860 std::string parameter_section_bytes;
25861 TPM_CC command_code = TPM_CC_SetPrimaryPolicy;
25862 bool is_command_parameter_encryption_possible = true;
25863 bool is_response_parameter_encryption_possible = false;
25864 std::string command_code_bytes;
25865 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25866 if (rc != TPM_RC_SUCCESS) {
25867 return rc;
25868 }
25869 std::string auth_handle_bytes;
25870 rc = Serialize_TPMI_RH_HIERARCHY(auth_handle, &auth_handle_bytes);
25871 if (rc != TPM_RC_SUCCESS) {
25872 return rc;
25873 }
25874 std::string auth_policy_bytes;
25875 rc = Serialize_TPM2B_DIGEST(auth_policy, &auth_policy_bytes);
25876 if (rc != TPM_RC_SUCCESS) {
25877 return rc;
25878 }
25879 std::string hash_alg_bytes;
25880 rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
25881 if (rc != TPM_RC_SUCCESS) {
25882 return rc;
25883 }
25884 if (authorization_delegate) {
25885 // Encrypt just the parameter data, not the size.
25886 std::string tmp = auth_policy_bytes.substr(2);
25887 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
25888 return TRUNKS_RC_ENCRYPTION_FAILED;
25889 }
25890 auth_policy_bytes.replace(2, std::string::npos, tmp);
25891 }
25892 std::unique_ptr<crypto::SecureHash> hash(
25893 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25894 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25895 hash->Update(auth_handle_name.data(), auth_handle_name.size());
25896 handle_section_bytes += auth_handle_bytes;
25897 command_size += auth_handle_bytes.size();
25898 hash->Update(auth_policy_bytes.data(), auth_policy_bytes.size());
25899 parameter_section_bytes += auth_policy_bytes;
25900 command_size += auth_policy_bytes.size();
25901 hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
25902 parameter_section_bytes += hash_alg_bytes;
25903 command_size += hash_alg_bytes.size();
25904 std::string command_hash(32, 0);
25905 hash->Finish(std::data(command_hash), command_hash.size());
25906 std::string authorization_section_bytes;
25907 std::string authorization_size_bytes;
25908 if (authorization_delegate) {
25909 if (!authorization_delegate->GetCommandAuthorization(
25910 command_hash, is_command_parameter_encryption_possible,
25911 is_response_parameter_encryption_possible,
25912 &authorization_section_bytes)) {
25913 return TRUNKS_RC_AUTHORIZATION_FAILED;
25914 }
25915 if (!authorization_section_bytes.empty()) {
25916 tag = TPM_ST_SESSIONS;
25917 std::string tmp;
25918 rc = Serialize_UINT32(authorization_section_bytes.size(),
25919 &authorization_size_bytes);
25920 if (rc != TPM_RC_SUCCESS) {
25921 return rc;
25922 }
25923 command_size +=
25924 authorization_size_bytes.size() + authorization_section_bytes.size();
25925 }
25926 }
25927 std::string tag_bytes;
25928 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25929 if (rc != TPM_RC_SUCCESS) {
25930 return rc;
25931 }
25932 std::string command_size_bytes;
25933 rc = Serialize_UINT32(command_size, &command_size_bytes);
25934 if (rc != TPM_RC_SUCCESS) {
25935 return rc;
25936 }
25937 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25938 handle_section_bytes + authorization_size_bytes +
25939 authorization_section_bytes + parameter_section_bytes;
25940 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25941 VLOG(2) << "Command: "
25942 << base::HexEncode(serialized_command->data(),
25943 serialized_command->size());
25944 return TPM_RC_SUCCESS;
25945 }
25946
ParseResponse_SetPrimaryPolicy(const std::string & response,AuthorizationDelegate * authorization_delegate)25947 TPM_RC Tpm::ParseResponse_SetPrimaryPolicy(
25948 const std::string& response,
25949 AuthorizationDelegate* authorization_delegate) {
25950 VLOG(3) << __func__;
25951 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25952 TPM_RC rc = TPM_RC_SUCCESS;
25953 std::string buffer(response);
25954 TPM_ST tag;
25955 std::string tag_bytes;
25956 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25957 if (rc != TPM_RC_SUCCESS) {
25958 return rc;
25959 }
25960 UINT32 response_size;
25961 std::string response_size_bytes;
25962 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25963 if (rc != TPM_RC_SUCCESS) {
25964 return rc;
25965 }
25966 TPM_RC response_code;
25967 std::string response_code_bytes;
25968 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25969 if (rc != TPM_RC_SUCCESS) {
25970 return rc;
25971 }
25972 if (response_size != response.size()) {
25973 return TPM_RC_SIZE;
25974 }
25975 if (response_code != TPM_RC_SUCCESS) {
25976 return response_code;
25977 }
25978 TPM_CC command_code = TPM_CC_SetPrimaryPolicy;
25979 std::string command_code_bytes;
25980 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25981 if (rc != TPM_RC_SUCCESS) {
25982 return rc;
25983 }
25984 std::string authorization_section_bytes;
25985 if (tag == TPM_ST_SESSIONS) {
25986 UINT32 parameter_section_size = buffer.size();
25987 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
25988 if (rc != TPM_RC_SUCCESS) {
25989 return rc;
25990 }
25991 if (parameter_section_size > buffer.size()) {
25992 return TPM_RC_INSUFFICIENT;
25993 }
25994 authorization_section_bytes = buffer.substr(parameter_section_size);
25995 // Keep the parameter section in |buffer|.
25996 buffer.erase(parameter_section_size);
25997 }
25998 std::unique_ptr<crypto::SecureHash> hash(
25999 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26000 hash->Update(response_code_bytes.data(), response_code_bytes.size());
26001 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26002 hash->Update(buffer.data(), buffer.size());
26003 std::string response_hash(32, 0);
26004 hash->Finish(std::data(response_hash), response_hash.size());
26005 if (tag == TPM_ST_SESSIONS) {
26006 if (!authorization_delegate)
26007 return TRUNKS_RC_AUTHORIZATION_FAILED;
26008 if (!authorization_delegate->CheckResponseAuthorization(
26009 response_hash, authorization_section_bytes)) {
26010 return TRUNKS_RC_AUTHORIZATION_FAILED;
26011 }
26012 }
26013 return TPM_RC_SUCCESS;
26014 }
26015
SetPrimaryPolicyErrorCallback(Tpm::SetPrimaryPolicyResponse callback,TPM_RC response_code)26016 void SetPrimaryPolicyErrorCallback(Tpm::SetPrimaryPolicyResponse callback,
26017 TPM_RC response_code) {
26018 VLOG(1) << __func__;
26019 std::move(callback).Run(response_code);
26020 }
26021
SetPrimaryPolicyResponseParser(Tpm::SetPrimaryPolicyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26022 void SetPrimaryPolicyResponseParser(
26023 Tpm::SetPrimaryPolicyResponse callback,
26024 AuthorizationDelegate* authorization_delegate,
26025 const std::string& response) {
26026 VLOG(1) << __func__;
26027 TPM_RC rc =
26028 Tpm::ParseResponse_SetPrimaryPolicy(response, authorization_delegate);
26029 if (rc != TPM_RC_SUCCESS) {
26030 base::OnceCallback<void(TPM_RC)> error_reporter =
26031 base::BindOnce(SetPrimaryPolicyErrorCallback, std::move(callback));
26032 std::move(error_reporter).Run(rc);
26033 return;
26034 }
26035 std::move(callback).Run(rc);
26036 }
26037
SetPrimaryPolicy(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,SetPrimaryPolicyResponse callback)26038 void Tpm::SetPrimaryPolicy(const TPMI_RH_HIERARCHY& auth_handle,
26039 const std::string& auth_handle_name,
26040 const TPM2B_DIGEST& auth_policy,
26041 const TPMI_ALG_HASH& hash_alg,
26042 AuthorizationDelegate* authorization_delegate,
26043 SetPrimaryPolicyResponse callback) {
26044 VLOG(1) << __func__;
26045 std::string command;
26046 TPM_RC rc = SerializeCommand_SetPrimaryPolicy(auth_handle, auth_handle_name,
26047 auth_policy, hash_alg, &command,
26048 authorization_delegate);
26049 if (rc != TPM_RC_SUCCESS) {
26050 base::OnceCallback<void(TPM_RC)> error_reporter =
26051 base::BindOnce(SetPrimaryPolicyErrorCallback, std::move(callback));
26052 std::move(error_reporter).Run(rc);
26053 return;
26054 }
26055 base::OnceCallback<void(const std::string&)> parser =
26056 base::BindOnce(SetPrimaryPolicyResponseParser, std::move(callback),
26057 authorization_delegate);
26058 transceiver_->SendCommand(command, std::move(parser));
26059 }
26060
SetPrimaryPolicySync(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate)26061 TPM_RC Tpm::SetPrimaryPolicySync(
26062 const TPMI_RH_HIERARCHY& auth_handle,
26063 const std::string& auth_handle_name,
26064 const TPM2B_DIGEST& auth_policy,
26065 const TPMI_ALG_HASH& hash_alg,
26066 AuthorizationDelegate* authorization_delegate) {
26067 VLOG(1) << __func__;
26068 std::string command;
26069 TPM_RC rc = SerializeCommand_SetPrimaryPolicy(auth_handle, auth_handle_name,
26070 auth_policy, hash_alg, &command,
26071 authorization_delegate);
26072 if (rc != TPM_RC_SUCCESS) {
26073 return rc;
26074 }
26075 std::string response = transceiver_->SendCommandAndWait(command);
26076 rc = ParseResponse_SetPrimaryPolicy(response, authorization_delegate);
26077 return rc;
26078 }
26079
SerializeCommand_ChangePPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26080 TPM_RC Tpm::SerializeCommand_ChangePPS(
26081 const TPMI_RH_PLATFORM& auth_handle,
26082 const std::string& auth_handle_name,
26083 std::string* serialized_command,
26084 AuthorizationDelegate* authorization_delegate) {
26085 VLOG(3) << __func__;
26086 TPM_RC rc = TPM_RC_SUCCESS;
26087 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26088 UINT32 command_size = 10; // Header size.
26089 std::string handle_section_bytes;
26090 std::string parameter_section_bytes;
26091 TPM_CC command_code = TPM_CC_ChangePPS;
26092 bool is_command_parameter_encryption_possible = false;
26093 bool is_response_parameter_encryption_possible = false;
26094 std::string command_code_bytes;
26095 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26096 if (rc != TPM_RC_SUCCESS) {
26097 return rc;
26098 }
26099 std::string auth_handle_bytes;
26100 rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
26101 if (rc != TPM_RC_SUCCESS) {
26102 return rc;
26103 }
26104 std::unique_ptr<crypto::SecureHash> hash(
26105 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26106 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26107 hash->Update(auth_handle_name.data(), auth_handle_name.size());
26108 handle_section_bytes += auth_handle_bytes;
26109 command_size += auth_handle_bytes.size();
26110 std::string command_hash(32, 0);
26111 hash->Finish(std::data(command_hash), command_hash.size());
26112 std::string authorization_section_bytes;
26113 std::string authorization_size_bytes;
26114 if (authorization_delegate) {
26115 if (!authorization_delegate->GetCommandAuthorization(
26116 command_hash, is_command_parameter_encryption_possible,
26117 is_response_parameter_encryption_possible,
26118 &authorization_section_bytes)) {
26119 return TRUNKS_RC_AUTHORIZATION_FAILED;
26120 }
26121 if (!authorization_section_bytes.empty()) {
26122 tag = TPM_ST_SESSIONS;
26123 std::string tmp;
26124 rc = Serialize_UINT32(authorization_section_bytes.size(),
26125 &authorization_size_bytes);
26126 if (rc != TPM_RC_SUCCESS) {
26127 return rc;
26128 }
26129 command_size +=
26130 authorization_size_bytes.size() + authorization_section_bytes.size();
26131 }
26132 }
26133 std::string tag_bytes;
26134 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26135 if (rc != TPM_RC_SUCCESS) {
26136 return rc;
26137 }
26138 std::string command_size_bytes;
26139 rc = Serialize_UINT32(command_size, &command_size_bytes);
26140 if (rc != TPM_RC_SUCCESS) {
26141 return rc;
26142 }
26143 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26144 handle_section_bytes + authorization_size_bytes +
26145 authorization_section_bytes + parameter_section_bytes;
26146 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26147 VLOG(2) << "Command: "
26148 << base::HexEncode(serialized_command->data(),
26149 serialized_command->size());
26150 return TPM_RC_SUCCESS;
26151 }
26152
ParseResponse_ChangePPS(const std::string & response,AuthorizationDelegate * authorization_delegate)26153 TPM_RC Tpm::ParseResponse_ChangePPS(
26154 const std::string& response,
26155 AuthorizationDelegate* authorization_delegate) {
26156 VLOG(3) << __func__;
26157 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26158 TPM_RC rc = TPM_RC_SUCCESS;
26159 std::string buffer(response);
26160 TPM_ST tag;
26161 std::string tag_bytes;
26162 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26163 if (rc != TPM_RC_SUCCESS) {
26164 return rc;
26165 }
26166 UINT32 response_size;
26167 std::string response_size_bytes;
26168 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26169 if (rc != TPM_RC_SUCCESS) {
26170 return rc;
26171 }
26172 TPM_RC response_code;
26173 std::string response_code_bytes;
26174 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26175 if (rc != TPM_RC_SUCCESS) {
26176 return rc;
26177 }
26178 if (response_size != response.size()) {
26179 return TPM_RC_SIZE;
26180 }
26181 if (response_code != TPM_RC_SUCCESS) {
26182 return response_code;
26183 }
26184 TPM_CC command_code = TPM_CC_ChangePPS;
26185 std::string command_code_bytes;
26186 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26187 if (rc != TPM_RC_SUCCESS) {
26188 return rc;
26189 }
26190 std::string authorization_section_bytes;
26191 if (tag == TPM_ST_SESSIONS) {
26192 UINT32 parameter_section_size = buffer.size();
26193 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
26194 if (rc != TPM_RC_SUCCESS) {
26195 return rc;
26196 }
26197 if (parameter_section_size > buffer.size()) {
26198 return TPM_RC_INSUFFICIENT;
26199 }
26200 authorization_section_bytes = buffer.substr(parameter_section_size);
26201 // Keep the parameter section in |buffer|.
26202 buffer.erase(parameter_section_size);
26203 }
26204 std::unique_ptr<crypto::SecureHash> hash(
26205 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26206 hash->Update(response_code_bytes.data(), response_code_bytes.size());
26207 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26208 hash->Update(buffer.data(), buffer.size());
26209 std::string response_hash(32, 0);
26210 hash->Finish(std::data(response_hash), response_hash.size());
26211 if (tag == TPM_ST_SESSIONS) {
26212 if (!authorization_delegate)
26213 return TRUNKS_RC_AUTHORIZATION_FAILED;
26214 if (!authorization_delegate->CheckResponseAuthorization(
26215 response_hash, authorization_section_bytes)) {
26216 return TRUNKS_RC_AUTHORIZATION_FAILED;
26217 }
26218 }
26219 return TPM_RC_SUCCESS;
26220 }
26221
ChangePPSErrorCallback(Tpm::ChangePPSResponse callback,TPM_RC response_code)26222 void ChangePPSErrorCallback(Tpm::ChangePPSResponse callback,
26223 TPM_RC response_code) {
26224 VLOG(1) << __func__;
26225 std::move(callback).Run(response_code);
26226 }
26227
ChangePPSResponseParser(Tpm::ChangePPSResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26228 void ChangePPSResponseParser(Tpm::ChangePPSResponse callback,
26229 AuthorizationDelegate* authorization_delegate,
26230 const std::string& response) {
26231 VLOG(1) << __func__;
26232 TPM_RC rc = Tpm::ParseResponse_ChangePPS(response, authorization_delegate);
26233 if (rc != TPM_RC_SUCCESS) {
26234 base::OnceCallback<void(TPM_RC)> error_reporter =
26235 base::BindOnce(ChangePPSErrorCallback, std::move(callback));
26236 std::move(error_reporter).Run(rc);
26237 return;
26238 }
26239 std::move(callback).Run(rc);
26240 }
26241
ChangePPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ChangePPSResponse callback)26242 void Tpm::ChangePPS(const TPMI_RH_PLATFORM& auth_handle,
26243 const std::string& auth_handle_name,
26244 AuthorizationDelegate* authorization_delegate,
26245 ChangePPSResponse callback) {
26246 VLOG(1) << __func__;
26247 std::string command;
26248 TPM_RC rc = SerializeCommand_ChangePPS(auth_handle, auth_handle_name,
26249 &command, authorization_delegate);
26250 if (rc != TPM_RC_SUCCESS) {
26251 base::OnceCallback<void(TPM_RC)> error_reporter =
26252 base::BindOnce(ChangePPSErrorCallback, std::move(callback));
26253 std::move(error_reporter).Run(rc);
26254 return;
26255 }
26256 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26257 ChangePPSResponseParser, std::move(callback), authorization_delegate);
26258 transceiver_->SendCommand(command, std::move(parser));
26259 }
26260
ChangePPSSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26261 TPM_RC Tpm::ChangePPSSync(const TPMI_RH_PLATFORM& auth_handle,
26262 const std::string& auth_handle_name,
26263 AuthorizationDelegate* authorization_delegate) {
26264 VLOG(1) << __func__;
26265 std::string command;
26266 TPM_RC rc = SerializeCommand_ChangePPS(auth_handle, auth_handle_name,
26267 &command, authorization_delegate);
26268 if (rc != TPM_RC_SUCCESS) {
26269 return rc;
26270 }
26271 std::string response = transceiver_->SendCommandAndWait(command);
26272 rc = ParseResponse_ChangePPS(response, authorization_delegate);
26273 return rc;
26274 }
26275
SerializeCommand_ChangeEPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26276 TPM_RC Tpm::SerializeCommand_ChangeEPS(
26277 const TPMI_RH_PLATFORM& auth_handle,
26278 const std::string& auth_handle_name,
26279 std::string* serialized_command,
26280 AuthorizationDelegate* authorization_delegate) {
26281 VLOG(3) << __func__;
26282 TPM_RC rc = TPM_RC_SUCCESS;
26283 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26284 UINT32 command_size = 10; // Header size.
26285 std::string handle_section_bytes;
26286 std::string parameter_section_bytes;
26287 TPM_CC command_code = TPM_CC_ChangeEPS;
26288 bool is_command_parameter_encryption_possible = false;
26289 bool is_response_parameter_encryption_possible = false;
26290 std::string command_code_bytes;
26291 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26292 if (rc != TPM_RC_SUCCESS) {
26293 return rc;
26294 }
26295 std::string auth_handle_bytes;
26296 rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
26297 if (rc != TPM_RC_SUCCESS) {
26298 return rc;
26299 }
26300 std::unique_ptr<crypto::SecureHash> hash(
26301 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26302 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26303 hash->Update(auth_handle_name.data(), auth_handle_name.size());
26304 handle_section_bytes += auth_handle_bytes;
26305 command_size += auth_handle_bytes.size();
26306 std::string command_hash(32, 0);
26307 hash->Finish(std::data(command_hash), command_hash.size());
26308 std::string authorization_section_bytes;
26309 std::string authorization_size_bytes;
26310 if (authorization_delegate) {
26311 if (!authorization_delegate->GetCommandAuthorization(
26312 command_hash, is_command_parameter_encryption_possible,
26313 is_response_parameter_encryption_possible,
26314 &authorization_section_bytes)) {
26315 return TRUNKS_RC_AUTHORIZATION_FAILED;
26316 }
26317 if (!authorization_section_bytes.empty()) {
26318 tag = TPM_ST_SESSIONS;
26319 std::string tmp;
26320 rc = Serialize_UINT32(authorization_section_bytes.size(),
26321 &authorization_size_bytes);
26322 if (rc != TPM_RC_SUCCESS) {
26323 return rc;
26324 }
26325 command_size +=
26326 authorization_size_bytes.size() + authorization_section_bytes.size();
26327 }
26328 }
26329 std::string tag_bytes;
26330 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26331 if (rc != TPM_RC_SUCCESS) {
26332 return rc;
26333 }
26334 std::string command_size_bytes;
26335 rc = Serialize_UINT32(command_size, &command_size_bytes);
26336 if (rc != TPM_RC_SUCCESS) {
26337 return rc;
26338 }
26339 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26340 handle_section_bytes + authorization_size_bytes +
26341 authorization_section_bytes + parameter_section_bytes;
26342 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26343 VLOG(2) << "Command: "
26344 << base::HexEncode(serialized_command->data(),
26345 serialized_command->size());
26346 return TPM_RC_SUCCESS;
26347 }
26348
ParseResponse_ChangeEPS(const std::string & response,AuthorizationDelegate * authorization_delegate)26349 TPM_RC Tpm::ParseResponse_ChangeEPS(
26350 const std::string& response,
26351 AuthorizationDelegate* authorization_delegate) {
26352 VLOG(3) << __func__;
26353 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26354 TPM_RC rc = TPM_RC_SUCCESS;
26355 std::string buffer(response);
26356 TPM_ST tag;
26357 std::string tag_bytes;
26358 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26359 if (rc != TPM_RC_SUCCESS) {
26360 return rc;
26361 }
26362 UINT32 response_size;
26363 std::string response_size_bytes;
26364 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26365 if (rc != TPM_RC_SUCCESS) {
26366 return rc;
26367 }
26368 TPM_RC response_code;
26369 std::string response_code_bytes;
26370 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26371 if (rc != TPM_RC_SUCCESS) {
26372 return rc;
26373 }
26374 if (response_size != response.size()) {
26375 return TPM_RC_SIZE;
26376 }
26377 if (response_code != TPM_RC_SUCCESS) {
26378 return response_code;
26379 }
26380 TPM_CC command_code = TPM_CC_ChangeEPS;
26381 std::string command_code_bytes;
26382 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26383 if (rc != TPM_RC_SUCCESS) {
26384 return rc;
26385 }
26386 std::string authorization_section_bytes;
26387 if (tag == TPM_ST_SESSIONS) {
26388 UINT32 parameter_section_size = buffer.size();
26389 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
26390 if (rc != TPM_RC_SUCCESS) {
26391 return rc;
26392 }
26393 if (parameter_section_size > buffer.size()) {
26394 return TPM_RC_INSUFFICIENT;
26395 }
26396 authorization_section_bytes = buffer.substr(parameter_section_size);
26397 // Keep the parameter section in |buffer|.
26398 buffer.erase(parameter_section_size);
26399 }
26400 std::unique_ptr<crypto::SecureHash> hash(
26401 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26402 hash->Update(response_code_bytes.data(), response_code_bytes.size());
26403 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26404 hash->Update(buffer.data(), buffer.size());
26405 std::string response_hash(32, 0);
26406 hash->Finish(std::data(response_hash), response_hash.size());
26407 if (tag == TPM_ST_SESSIONS) {
26408 if (!authorization_delegate)
26409 return TRUNKS_RC_AUTHORIZATION_FAILED;
26410 if (!authorization_delegate->CheckResponseAuthorization(
26411 response_hash, authorization_section_bytes)) {
26412 return TRUNKS_RC_AUTHORIZATION_FAILED;
26413 }
26414 }
26415 return TPM_RC_SUCCESS;
26416 }
26417
ChangeEPSErrorCallback(Tpm::ChangeEPSResponse callback,TPM_RC response_code)26418 void ChangeEPSErrorCallback(Tpm::ChangeEPSResponse callback,
26419 TPM_RC response_code) {
26420 VLOG(1) << __func__;
26421 std::move(callback).Run(response_code);
26422 }
26423
ChangeEPSResponseParser(Tpm::ChangeEPSResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26424 void ChangeEPSResponseParser(Tpm::ChangeEPSResponse callback,
26425 AuthorizationDelegate* authorization_delegate,
26426 const std::string& response) {
26427 VLOG(1) << __func__;
26428 TPM_RC rc = Tpm::ParseResponse_ChangeEPS(response, authorization_delegate);
26429 if (rc != TPM_RC_SUCCESS) {
26430 base::OnceCallback<void(TPM_RC)> error_reporter =
26431 base::BindOnce(ChangeEPSErrorCallback, std::move(callback));
26432 std::move(error_reporter).Run(rc);
26433 return;
26434 }
26435 std::move(callback).Run(rc);
26436 }
26437
ChangeEPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ChangeEPSResponse callback)26438 void Tpm::ChangeEPS(const TPMI_RH_PLATFORM& auth_handle,
26439 const std::string& auth_handle_name,
26440 AuthorizationDelegate* authorization_delegate,
26441 ChangeEPSResponse callback) {
26442 VLOG(1) << __func__;
26443 std::string command;
26444 TPM_RC rc = SerializeCommand_ChangeEPS(auth_handle, auth_handle_name,
26445 &command, authorization_delegate);
26446 if (rc != TPM_RC_SUCCESS) {
26447 base::OnceCallback<void(TPM_RC)> error_reporter =
26448 base::BindOnce(ChangeEPSErrorCallback, std::move(callback));
26449 std::move(error_reporter).Run(rc);
26450 return;
26451 }
26452 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26453 ChangeEPSResponseParser, std::move(callback), authorization_delegate);
26454 transceiver_->SendCommand(command, std::move(parser));
26455 }
26456
ChangeEPSSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26457 TPM_RC Tpm::ChangeEPSSync(const TPMI_RH_PLATFORM& auth_handle,
26458 const std::string& auth_handle_name,
26459 AuthorizationDelegate* authorization_delegate) {
26460 VLOG(1) << __func__;
26461 std::string command;
26462 TPM_RC rc = SerializeCommand_ChangeEPS(auth_handle, auth_handle_name,
26463 &command, authorization_delegate);
26464 if (rc != TPM_RC_SUCCESS) {
26465 return rc;
26466 }
26467 std::string response = transceiver_->SendCommandAndWait(command);
26468 rc = ParseResponse_ChangeEPS(response, authorization_delegate);
26469 return rc;
26470 }
26471
SerializeCommand_Clear(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26472 TPM_RC Tpm::SerializeCommand_Clear(
26473 const TPMI_RH_CLEAR& auth_handle,
26474 const std::string& auth_handle_name,
26475 std::string* serialized_command,
26476 AuthorizationDelegate* authorization_delegate) {
26477 VLOG(3) << __func__;
26478 TPM_RC rc = TPM_RC_SUCCESS;
26479 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26480 UINT32 command_size = 10; // Header size.
26481 std::string handle_section_bytes;
26482 std::string parameter_section_bytes;
26483 TPM_CC command_code = TPM_CC_Clear;
26484 bool is_command_parameter_encryption_possible = false;
26485 bool is_response_parameter_encryption_possible = false;
26486 std::string command_code_bytes;
26487 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26488 if (rc != TPM_RC_SUCCESS) {
26489 return rc;
26490 }
26491 std::string auth_handle_bytes;
26492 rc = Serialize_TPMI_RH_CLEAR(auth_handle, &auth_handle_bytes);
26493 if (rc != TPM_RC_SUCCESS) {
26494 return rc;
26495 }
26496 std::unique_ptr<crypto::SecureHash> hash(
26497 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26498 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26499 hash->Update(auth_handle_name.data(), auth_handle_name.size());
26500 handle_section_bytes += auth_handle_bytes;
26501 command_size += auth_handle_bytes.size();
26502 std::string command_hash(32, 0);
26503 hash->Finish(std::data(command_hash), command_hash.size());
26504 std::string authorization_section_bytes;
26505 std::string authorization_size_bytes;
26506 if (authorization_delegate) {
26507 if (!authorization_delegate->GetCommandAuthorization(
26508 command_hash, is_command_parameter_encryption_possible,
26509 is_response_parameter_encryption_possible,
26510 &authorization_section_bytes)) {
26511 return TRUNKS_RC_AUTHORIZATION_FAILED;
26512 }
26513 if (!authorization_section_bytes.empty()) {
26514 tag = TPM_ST_SESSIONS;
26515 std::string tmp;
26516 rc = Serialize_UINT32(authorization_section_bytes.size(),
26517 &authorization_size_bytes);
26518 if (rc != TPM_RC_SUCCESS) {
26519 return rc;
26520 }
26521 command_size +=
26522 authorization_size_bytes.size() + authorization_section_bytes.size();
26523 }
26524 }
26525 std::string tag_bytes;
26526 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26527 if (rc != TPM_RC_SUCCESS) {
26528 return rc;
26529 }
26530 std::string command_size_bytes;
26531 rc = Serialize_UINT32(command_size, &command_size_bytes);
26532 if (rc != TPM_RC_SUCCESS) {
26533 return rc;
26534 }
26535 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26536 handle_section_bytes + authorization_size_bytes +
26537 authorization_section_bytes + parameter_section_bytes;
26538 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26539 VLOG(2) << "Command: "
26540 << base::HexEncode(serialized_command->data(),
26541 serialized_command->size());
26542 return TPM_RC_SUCCESS;
26543 }
26544
ParseResponse_Clear(const std::string & response,AuthorizationDelegate * authorization_delegate)26545 TPM_RC Tpm::ParseResponse_Clear(const std::string& response,
26546 AuthorizationDelegate* authorization_delegate) {
26547 VLOG(3) << __func__;
26548 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26549 TPM_RC rc = TPM_RC_SUCCESS;
26550 std::string buffer(response);
26551 TPM_ST tag;
26552 std::string tag_bytes;
26553 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26554 if (rc != TPM_RC_SUCCESS) {
26555 return rc;
26556 }
26557 UINT32 response_size;
26558 std::string response_size_bytes;
26559 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26560 if (rc != TPM_RC_SUCCESS) {
26561 return rc;
26562 }
26563 TPM_RC response_code;
26564 std::string response_code_bytes;
26565 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26566 if (rc != TPM_RC_SUCCESS) {
26567 return rc;
26568 }
26569 if (response_size != response.size()) {
26570 return TPM_RC_SIZE;
26571 }
26572 if (response_code != TPM_RC_SUCCESS) {
26573 return response_code;
26574 }
26575 TPM_CC command_code = TPM_CC_Clear;
26576 std::string command_code_bytes;
26577 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26578 if (rc != TPM_RC_SUCCESS) {
26579 return rc;
26580 }
26581 std::string authorization_section_bytes;
26582 if (tag == TPM_ST_SESSIONS) {
26583 UINT32 parameter_section_size = buffer.size();
26584 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
26585 if (rc != TPM_RC_SUCCESS) {
26586 return rc;
26587 }
26588 if (parameter_section_size > buffer.size()) {
26589 return TPM_RC_INSUFFICIENT;
26590 }
26591 authorization_section_bytes = buffer.substr(parameter_section_size);
26592 // Keep the parameter section in |buffer|.
26593 buffer.erase(parameter_section_size);
26594 }
26595 std::unique_ptr<crypto::SecureHash> hash(
26596 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26597 hash->Update(response_code_bytes.data(), response_code_bytes.size());
26598 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26599 hash->Update(buffer.data(), buffer.size());
26600 std::string response_hash(32, 0);
26601 hash->Finish(std::data(response_hash), response_hash.size());
26602 if (tag == TPM_ST_SESSIONS) {
26603 if (!authorization_delegate)
26604 return TRUNKS_RC_AUTHORIZATION_FAILED;
26605 if (!authorization_delegate->CheckResponseAuthorization(
26606 response_hash, authorization_section_bytes)) {
26607 return TRUNKS_RC_AUTHORIZATION_FAILED;
26608 }
26609 }
26610 return TPM_RC_SUCCESS;
26611 }
26612
ClearErrorCallback(Tpm::ClearResponse callback,TPM_RC response_code)26613 void ClearErrorCallback(Tpm::ClearResponse callback, TPM_RC response_code) {
26614 VLOG(1) << __func__;
26615 std::move(callback).Run(response_code);
26616 }
26617
ClearResponseParser(Tpm::ClearResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26618 void ClearResponseParser(Tpm::ClearResponse callback,
26619 AuthorizationDelegate* authorization_delegate,
26620 const std::string& response) {
26621 VLOG(1) << __func__;
26622 TPM_RC rc = Tpm::ParseResponse_Clear(response, authorization_delegate);
26623 if (rc != TPM_RC_SUCCESS) {
26624 base::OnceCallback<void(TPM_RC)> error_reporter =
26625 base::BindOnce(ClearErrorCallback, std::move(callback));
26626 std::move(error_reporter).Run(rc);
26627 return;
26628 }
26629 std::move(callback).Run(rc);
26630 }
26631
Clear(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ClearResponse callback)26632 void Tpm::Clear(const TPMI_RH_CLEAR& auth_handle,
26633 const std::string& auth_handle_name,
26634 AuthorizationDelegate* authorization_delegate,
26635 ClearResponse callback) {
26636 VLOG(1) << __func__;
26637 std::string command;
26638 TPM_RC rc = SerializeCommand_Clear(auth_handle, auth_handle_name, &command,
26639 authorization_delegate);
26640 if (rc != TPM_RC_SUCCESS) {
26641 base::OnceCallback<void(TPM_RC)> error_reporter =
26642 base::BindOnce(ClearErrorCallback, std::move(callback));
26643 std::move(error_reporter).Run(rc);
26644 return;
26645 }
26646 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26647 ClearResponseParser, std::move(callback), authorization_delegate);
26648 transceiver_->SendCommand(command, std::move(parser));
26649 }
26650
ClearSync(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26651 TPM_RC Tpm::ClearSync(const TPMI_RH_CLEAR& auth_handle,
26652 const std::string& auth_handle_name,
26653 AuthorizationDelegate* authorization_delegate) {
26654 VLOG(1) << __func__;
26655 std::string command;
26656 TPM_RC rc = SerializeCommand_Clear(auth_handle, auth_handle_name, &command,
26657 authorization_delegate);
26658 if (rc != TPM_RC_SUCCESS) {
26659 return rc;
26660 }
26661 std::string response = transceiver_->SendCommandAndWait(command);
26662 rc = ParseResponse_Clear(response, authorization_delegate);
26663 return rc;
26664 }
26665
SerializeCommand_ClearControl(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26666 TPM_RC Tpm::SerializeCommand_ClearControl(
26667 const TPMI_RH_CLEAR& auth,
26668 const std::string& auth_name,
26669 const TPMI_YES_NO& disable,
26670 std::string* serialized_command,
26671 AuthorizationDelegate* authorization_delegate) {
26672 VLOG(3) << __func__;
26673 TPM_RC rc = TPM_RC_SUCCESS;
26674 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26675 UINT32 command_size = 10; // Header size.
26676 std::string handle_section_bytes;
26677 std::string parameter_section_bytes;
26678 TPM_CC command_code = TPM_CC_ClearControl;
26679 bool is_command_parameter_encryption_possible = false;
26680 bool is_response_parameter_encryption_possible = false;
26681 std::string command_code_bytes;
26682 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26683 if (rc != TPM_RC_SUCCESS) {
26684 return rc;
26685 }
26686 std::string auth_bytes;
26687 rc = Serialize_TPMI_RH_CLEAR(auth, &auth_bytes);
26688 if (rc != TPM_RC_SUCCESS) {
26689 return rc;
26690 }
26691 std::string disable_bytes;
26692 rc = Serialize_TPMI_YES_NO(disable, &disable_bytes);
26693 if (rc != TPM_RC_SUCCESS) {
26694 return rc;
26695 }
26696 std::unique_ptr<crypto::SecureHash> hash(
26697 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26698 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26699 hash->Update(auth_name.data(), auth_name.size());
26700 handle_section_bytes += auth_bytes;
26701 command_size += auth_bytes.size();
26702 hash->Update(disable_bytes.data(), disable_bytes.size());
26703 parameter_section_bytes += disable_bytes;
26704 command_size += disable_bytes.size();
26705 std::string command_hash(32, 0);
26706 hash->Finish(std::data(command_hash), command_hash.size());
26707 std::string authorization_section_bytes;
26708 std::string authorization_size_bytes;
26709 if (authorization_delegate) {
26710 if (!authorization_delegate->GetCommandAuthorization(
26711 command_hash, is_command_parameter_encryption_possible,
26712 is_response_parameter_encryption_possible,
26713 &authorization_section_bytes)) {
26714 return TRUNKS_RC_AUTHORIZATION_FAILED;
26715 }
26716 if (!authorization_section_bytes.empty()) {
26717 tag = TPM_ST_SESSIONS;
26718 std::string tmp;
26719 rc = Serialize_UINT32(authorization_section_bytes.size(),
26720 &authorization_size_bytes);
26721 if (rc != TPM_RC_SUCCESS) {
26722 return rc;
26723 }
26724 command_size +=
26725 authorization_size_bytes.size() + authorization_section_bytes.size();
26726 }
26727 }
26728 std::string tag_bytes;
26729 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26730 if (rc != TPM_RC_SUCCESS) {
26731 return rc;
26732 }
26733 std::string command_size_bytes;
26734 rc = Serialize_UINT32(command_size, &command_size_bytes);
26735 if (rc != TPM_RC_SUCCESS) {
26736 return rc;
26737 }
26738 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26739 handle_section_bytes + authorization_size_bytes +
26740 authorization_section_bytes + parameter_section_bytes;
26741 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26742 VLOG(2) << "Command: "
26743 << base::HexEncode(serialized_command->data(),
26744 serialized_command->size());
26745 return TPM_RC_SUCCESS;
26746 }
26747
ParseResponse_ClearControl(const std::string & response,AuthorizationDelegate * authorization_delegate)26748 TPM_RC Tpm::ParseResponse_ClearControl(
26749 const std::string& response,
26750 AuthorizationDelegate* authorization_delegate) {
26751 VLOG(3) << __func__;
26752 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26753 TPM_RC rc = TPM_RC_SUCCESS;
26754 std::string buffer(response);
26755 TPM_ST tag;
26756 std::string tag_bytes;
26757 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26758 if (rc != TPM_RC_SUCCESS) {
26759 return rc;
26760 }
26761 UINT32 response_size;
26762 std::string response_size_bytes;
26763 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26764 if (rc != TPM_RC_SUCCESS) {
26765 return rc;
26766 }
26767 TPM_RC response_code;
26768 std::string response_code_bytes;
26769 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26770 if (rc != TPM_RC_SUCCESS) {
26771 return rc;
26772 }
26773 if (response_size != response.size()) {
26774 return TPM_RC_SIZE;
26775 }
26776 if (response_code != TPM_RC_SUCCESS) {
26777 return response_code;
26778 }
26779 TPM_CC command_code = TPM_CC_ClearControl;
26780 std::string command_code_bytes;
26781 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26782 if (rc != TPM_RC_SUCCESS) {
26783 return rc;
26784 }
26785 std::string authorization_section_bytes;
26786 if (tag == TPM_ST_SESSIONS) {
26787 UINT32 parameter_section_size = buffer.size();
26788 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
26789 if (rc != TPM_RC_SUCCESS) {
26790 return rc;
26791 }
26792 if (parameter_section_size > buffer.size()) {
26793 return TPM_RC_INSUFFICIENT;
26794 }
26795 authorization_section_bytes = buffer.substr(parameter_section_size);
26796 // Keep the parameter section in |buffer|.
26797 buffer.erase(parameter_section_size);
26798 }
26799 std::unique_ptr<crypto::SecureHash> hash(
26800 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26801 hash->Update(response_code_bytes.data(), response_code_bytes.size());
26802 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26803 hash->Update(buffer.data(), buffer.size());
26804 std::string response_hash(32, 0);
26805 hash->Finish(std::data(response_hash), response_hash.size());
26806 if (tag == TPM_ST_SESSIONS) {
26807 if (!authorization_delegate)
26808 return TRUNKS_RC_AUTHORIZATION_FAILED;
26809 if (!authorization_delegate->CheckResponseAuthorization(
26810 response_hash, authorization_section_bytes)) {
26811 return TRUNKS_RC_AUTHORIZATION_FAILED;
26812 }
26813 }
26814 return TPM_RC_SUCCESS;
26815 }
26816
ClearControlErrorCallback(Tpm::ClearControlResponse callback,TPM_RC response_code)26817 void ClearControlErrorCallback(Tpm::ClearControlResponse callback,
26818 TPM_RC response_code) {
26819 VLOG(1) << __func__;
26820 std::move(callback).Run(response_code);
26821 }
26822
ClearControlResponseParser(Tpm::ClearControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26823 void ClearControlResponseParser(Tpm::ClearControlResponse callback,
26824 AuthorizationDelegate* authorization_delegate,
26825 const std::string& response) {
26826 VLOG(1) << __func__;
26827 TPM_RC rc = Tpm::ParseResponse_ClearControl(response, authorization_delegate);
26828 if (rc != TPM_RC_SUCCESS) {
26829 base::OnceCallback<void(TPM_RC)> error_reporter =
26830 base::BindOnce(ClearControlErrorCallback, std::move(callback));
26831 std::move(error_reporter).Run(rc);
26832 return;
26833 }
26834 std::move(callback).Run(rc);
26835 }
26836
ClearControl(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,AuthorizationDelegate * authorization_delegate,ClearControlResponse callback)26837 void Tpm::ClearControl(const TPMI_RH_CLEAR& auth,
26838 const std::string& auth_name,
26839 const TPMI_YES_NO& disable,
26840 AuthorizationDelegate* authorization_delegate,
26841 ClearControlResponse callback) {
26842 VLOG(1) << __func__;
26843 std::string command;
26844 TPM_RC rc = SerializeCommand_ClearControl(auth, auth_name, disable, &command,
26845 authorization_delegate);
26846 if (rc != TPM_RC_SUCCESS) {
26847 base::OnceCallback<void(TPM_RC)> error_reporter =
26848 base::BindOnce(ClearControlErrorCallback, std::move(callback));
26849 std::move(error_reporter).Run(rc);
26850 return;
26851 }
26852 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26853 ClearControlResponseParser, std::move(callback), authorization_delegate);
26854 transceiver_->SendCommand(command, std::move(parser));
26855 }
26856
ClearControlSync(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,AuthorizationDelegate * authorization_delegate)26857 TPM_RC Tpm::ClearControlSync(const TPMI_RH_CLEAR& auth,
26858 const std::string& auth_name,
26859 const TPMI_YES_NO& disable,
26860 AuthorizationDelegate* authorization_delegate) {
26861 VLOG(1) << __func__;
26862 std::string command;
26863 TPM_RC rc = SerializeCommand_ClearControl(auth, auth_name, disable, &command,
26864 authorization_delegate);
26865 if (rc != TPM_RC_SUCCESS) {
26866 return rc;
26867 }
26868 std::string response = transceiver_->SendCommandAndWait(command);
26869 rc = ParseResponse_ClearControl(response, authorization_delegate);
26870 return rc;
26871 }
26872
SerializeCommand_HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26873 TPM_RC Tpm::SerializeCommand_HierarchyChangeAuth(
26874 const TPMI_RH_HIERARCHY_AUTH& auth_handle,
26875 const std::string& auth_handle_name,
26876 const TPM2B_AUTH& new_auth,
26877 std::string* serialized_command,
26878 AuthorizationDelegate* authorization_delegate) {
26879 VLOG(3) << __func__;
26880 TPM_RC rc = TPM_RC_SUCCESS;
26881 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26882 UINT32 command_size = 10; // Header size.
26883 std::string handle_section_bytes;
26884 std::string parameter_section_bytes;
26885 TPM_CC command_code = TPM_CC_HierarchyChangeAuth;
26886 bool is_command_parameter_encryption_possible = true;
26887 bool is_response_parameter_encryption_possible = false;
26888 std::string command_code_bytes;
26889 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26890 if (rc != TPM_RC_SUCCESS) {
26891 return rc;
26892 }
26893 std::string auth_handle_bytes;
26894 rc = Serialize_TPMI_RH_HIERARCHY_AUTH(auth_handle, &auth_handle_bytes);
26895 if (rc != TPM_RC_SUCCESS) {
26896 return rc;
26897 }
26898 std::string new_auth_bytes;
26899 rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
26900 if (rc != TPM_RC_SUCCESS) {
26901 return rc;
26902 }
26903 if (authorization_delegate) {
26904 // Encrypt just the parameter data, not the size.
26905 std::string tmp = new_auth_bytes.substr(2);
26906 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
26907 return TRUNKS_RC_ENCRYPTION_FAILED;
26908 }
26909 new_auth_bytes.replace(2, std::string::npos, tmp);
26910 }
26911 std::unique_ptr<crypto::SecureHash> hash(
26912 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26913 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26914 hash->Update(auth_handle_name.data(), auth_handle_name.size());
26915 handle_section_bytes += auth_handle_bytes;
26916 command_size += auth_handle_bytes.size();
26917 hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
26918 parameter_section_bytes += new_auth_bytes;
26919 command_size += new_auth_bytes.size();
26920 std::string command_hash(32, 0);
26921 hash->Finish(std::data(command_hash), command_hash.size());
26922 std::string authorization_section_bytes;
26923 std::string authorization_size_bytes;
26924 if (authorization_delegate) {
26925 if (!authorization_delegate->GetCommandAuthorization(
26926 command_hash, is_command_parameter_encryption_possible,
26927 is_response_parameter_encryption_possible,
26928 &authorization_section_bytes)) {
26929 return TRUNKS_RC_AUTHORIZATION_FAILED;
26930 }
26931 if (!authorization_section_bytes.empty()) {
26932 tag = TPM_ST_SESSIONS;
26933 std::string tmp;
26934 rc = Serialize_UINT32(authorization_section_bytes.size(),
26935 &authorization_size_bytes);
26936 if (rc != TPM_RC_SUCCESS) {
26937 return rc;
26938 }
26939 command_size +=
26940 authorization_size_bytes.size() + authorization_section_bytes.size();
26941 }
26942 }
26943 std::string tag_bytes;
26944 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26945 if (rc != TPM_RC_SUCCESS) {
26946 return rc;
26947 }
26948 std::string command_size_bytes;
26949 rc = Serialize_UINT32(command_size, &command_size_bytes);
26950 if (rc != TPM_RC_SUCCESS) {
26951 return rc;
26952 }
26953 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26954 handle_section_bytes + authorization_size_bytes +
26955 authorization_section_bytes + parameter_section_bytes;
26956 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26957 VLOG(2) << "Command: "
26958 << base::HexEncode(serialized_command->data(),
26959 serialized_command->size());
26960 return TPM_RC_SUCCESS;
26961 }
26962
ParseResponse_HierarchyChangeAuth(const std::string & response,AuthorizationDelegate * authorization_delegate)26963 TPM_RC Tpm::ParseResponse_HierarchyChangeAuth(
26964 const std::string& response,
26965 AuthorizationDelegate* authorization_delegate) {
26966 VLOG(3) << __func__;
26967 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26968 TPM_RC rc = TPM_RC_SUCCESS;
26969 std::string buffer(response);
26970 TPM_ST tag;
26971 std::string tag_bytes;
26972 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26973 if (rc != TPM_RC_SUCCESS) {
26974 return rc;
26975 }
26976 UINT32 response_size;
26977 std::string response_size_bytes;
26978 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26979 if (rc != TPM_RC_SUCCESS) {
26980 return rc;
26981 }
26982 TPM_RC response_code;
26983 std::string response_code_bytes;
26984 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26985 if (rc != TPM_RC_SUCCESS) {
26986 return rc;
26987 }
26988 if (response_size != response.size()) {
26989 return TPM_RC_SIZE;
26990 }
26991 if (response_code != TPM_RC_SUCCESS) {
26992 return response_code;
26993 }
26994 TPM_CC command_code = TPM_CC_HierarchyChangeAuth;
26995 std::string command_code_bytes;
26996 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26997 if (rc != TPM_RC_SUCCESS) {
26998 return rc;
26999 }
27000 std::string authorization_section_bytes;
27001 if (tag == TPM_ST_SESSIONS) {
27002 UINT32 parameter_section_size = buffer.size();
27003 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
27004 if (rc != TPM_RC_SUCCESS) {
27005 return rc;
27006 }
27007 if (parameter_section_size > buffer.size()) {
27008 return TPM_RC_INSUFFICIENT;
27009 }
27010 authorization_section_bytes = buffer.substr(parameter_section_size);
27011 // Keep the parameter section in |buffer|.
27012 buffer.erase(parameter_section_size);
27013 }
27014 std::unique_ptr<crypto::SecureHash> hash(
27015 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27016 hash->Update(response_code_bytes.data(), response_code_bytes.size());
27017 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27018 hash->Update(buffer.data(), buffer.size());
27019 std::string response_hash(32, 0);
27020 hash->Finish(std::data(response_hash), response_hash.size());
27021 if (tag == TPM_ST_SESSIONS) {
27022 if (!authorization_delegate)
27023 return TRUNKS_RC_AUTHORIZATION_FAILED;
27024 if (!authorization_delegate->CheckResponseAuthorization(
27025 response_hash, authorization_section_bytes)) {
27026 return TRUNKS_RC_AUTHORIZATION_FAILED;
27027 }
27028 }
27029 return TPM_RC_SUCCESS;
27030 }
27031
HierarchyChangeAuthErrorCallback(Tpm::HierarchyChangeAuthResponse callback,TPM_RC response_code)27032 void HierarchyChangeAuthErrorCallback(Tpm::HierarchyChangeAuthResponse callback,
27033 TPM_RC response_code) {
27034 VLOG(1) << __func__;
27035 std::move(callback).Run(response_code);
27036 }
27037
HierarchyChangeAuthResponseParser(Tpm::HierarchyChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27038 void HierarchyChangeAuthResponseParser(
27039 Tpm::HierarchyChangeAuthResponse callback,
27040 AuthorizationDelegate* authorization_delegate,
27041 const std::string& response) {
27042 VLOG(1) << __func__;
27043 TPM_RC rc =
27044 Tpm::ParseResponse_HierarchyChangeAuth(response, authorization_delegate);
27045 if (rc != TPM_RC_SUCCESS) {
27046 base::OnceCallback<void(TPM_RC)> error_reporter =
27047 base::BindOnce(HierarchyChangeAuthErrorCallback, std::move(callback));
27048 std::move(error_reporter).Run(rc);
27049 return;
27050 }
27051 std::move(callback).Run(rc);
27052 }
27053
HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate,HierarchyChangeAuthResponse callback)27054 void Tpm::HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH& auth_handle,
27055 const std::string& auth_handle_name,
27056 const TPM2B_AUTH& new_auth,
27057 AuthorizationDelegate* authorization_delegate,
27058 HierarchyChangeAuthResponse callback) {
27059 VLOG(1) << __func__;
27060 std::string command;
27061 TPM_RC rc = SerializeCommand_HierarchyChangeAuth(
27062 auth_handle, auth_handle_name, new_auth, &command,
27063 authorization_delegate);
27064 if (rc != TPM_RC_SUCCESS) {
27065 base::OnceCallback<void(TPM_RC)> error_reporter =
27066 base::BindOnce(HierarchyChangeAuthErrorCallback, std::move(callback));
27067 std::move(error_reporter).Run(rc);
27068 return;
27069 }
27070 base::OnceCallback<void(const std::string&)> parser =
27071 base::BindOnce(HierarchyChangeAuthResponseParser, std::move(callback),
27072 authorization_delegate);
27073 transceiver_->SendCommand(command, std::move(parser));
27074 }
27075
HierarchyChangeAuthSync(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate)27076 TPM_RC Tpm::HierarchyChangeAuthSync(
27077 const TPMI_RH_HIERARCHY_AUTH& auth_handle,
27078 const std::string& auth_handle_name,
27079 const TPM2B_AUTH& new_auth,
27080 AuthorizationDelegate* authorization_delegate) {
27081 VLOG(1) << __func__;
27082 std::string command;
27083 TPM_RC rc = SerializeCommand_HierarchyChangeAuth(
27084 auth_handle, auth_handle_name, new_auth, &command,
27085 authorization_delegate);
27086 if (rc != TPM_RC_SUCCESS) {
27087 return rc;
27088 }
27089 std::string response = transceiver_->SendCommandAndWait(command);
27090 rc = ParseResponse_HierarchyChangeAuth(response, authorization_delegate);
27091 return rc;
27092 }
27093
SerializeCommand_DictionaryAttackLockReset(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27094 TPM_RC Tpm::SerializeCommand_DictionaryAttackLockReset(
27095 const TPMI_RH_LOCKOUT& lock_handle,
27096 const std::string& lock_handle_name,
27097 std::string* serialized_command,
27098 AuthorizationDelegate* authorization_delegate) {
27099 VLOG(3) << __func__;
27100 TPM_RC rc = TPM_RC_SUCCESS;
27101 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27102 UINT32 command_size = 10; // Header size.
27103 std::string handle_section_bytes;
27104 std::string parameter_section_bytes;
27105 TPM_CC command_code = TPM_CC_DictionaryAttackLockReset;
27106 bool is_command_parameter_encryption_possible = false;
27107 bool is_response_parameter_encryption_possible = false;
27108 std::string command_code_bytes;
27109 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27110 if (rc != TPM_RC_SUCCESS) {
27111 return rc;
27112 }
27113 std::string lock_handle_bytes;
27114 rc = Serialize_TPMI_RH_LOCKOUT(lock_handle, &lock_handle_bytes);
27115 if (rc != TPM_RC_SUCCESS) {
27116 return rc;
27117 }
27118 std::unique_ptr<crypto::SecureHash> hash(
27119 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27120 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27121 hash->Update(lock_handle_name.data(), lock_handle_name.size());
27122 handle_section_bytes += lock_handle_bytes;
27123 command_size += lock_handle_bytes.size();
27124 std::string command_hash(32, 0);
27125 hash->Finish(std::data(command_hash), command_hash.size());
27126 std::string authorization_section_bytes;
27127 std::string authorization_size_bytes;
27128 if (authorization_delegate) {
27129 if (!authorization_delegate->GetCommandAuthorization(
27130 command_hash, is_command_parameter_encryption_possible,
27131 is_response_parameter_encryption_possible,
27132 &authorization_section_bytes)) {
27133 return TRUNKS_RC_AUTHORIZATION_FAILED;
27134 }
27135 if (!authorization_section_bytes.empty()) {
27136 tag = TPM_ST_SESSIONS;
27137 std::string tmp;
27138 rc = Serialize_UINT32(authorization_section_bytes.size(),
27139 &authorization_size_bytes);
27140 if (rc != TPM_RC_SUCCESS) {
27141 return rc;
27142 }
27143 command_size +=
27144 authorization_size_bytes.size() + authorization_section_bytes.size();
27145 }
27146 }
27147 std::string tag_bytes;
27148 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27149 if (rc != TPM_RC_SUCCESS) {
27150 return rc;
27151 }
27152 std::string command_size_bytes;
27153 rc = Serialize_UINT32(command_size, &command_size_bytes);
27154 if (rc != TPM_RC_SUCCESS) {
27155 return rc;
27156 }
27157 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27158 handle_section_bytes + authorization_size_bytes +
27159 authorization_section_bytes + parameter_section_bytes;
27160 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27161 VLOG(2) << "Command: "
27162 << base::HexEncode(serialized_command->data(),
27163 serialized_command->size());
27164 return TPM_RC_SUCCESS;
27165 }
27166
ParseResponse_DictionaryAttackLockReset(const std::string & response,AuthorizationDelegate * authorization_delegate)27167 TPM_RC Tpm::ParseResponse_DictionaryAttackLockReset(
27168 const std::string& response,
27169 AuthorizationDelegate* authorization_delegate) {
27170 VLOG(3) << __func__;
27171 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27172 TPM_RC rc = TPM_RC_SUCCESS;
27173 std::string buffer(response);
27174 TPM_ST tag;
27175 std::string tag_bytes;
27176 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27177 if (rc != TPM_RC_SUCCESS) {
27178 return rc;
27179 }
27180 UINT32 response_size;
27181 std::string response_size_bytes;
27182 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27183 if (rc != TPM_RC_SUCCESS) {
27184 return rc;
27185 }
27186 TPM_RC response_code;
27187 std::string response_code_bytes;
27188 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27189 if (rc != TPM_RC_SUCCESS) {
27190 return rc;
27191 }
27192 if (response_size != response.size()) {
27193 return TPM_RC_SIZE;
27194 }
27195 if (response_code != TPM_RC_SUCCESS) {
27196 return response_code;
27197 }
27198 TPM_CC command_code = TPM_CC_DictionaryAttackLockReset;
27199 std::string command_code_bytes;
27200 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27201 if (rc != TPM_RC_SUCCESS) {
27202 return rc;
27203 }
27204 std::string authorization_section_bytes;
27205 if (tag == TPM_ST_SESSIONS) {
27206 UINT32 parameter_section_size = buffer.size();
27207 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
27208 if (rc != TPM_RC_SUCCESS) {
27209 return rc;
27210 }
27211 if (parameter_section_size > buffer.size()) {
27212 return TPM_RC_INSUFFICIENT;
27213 }
27214 authorization_section_bytes = buffer.substr(parameter_section_size);
27215 // Keep the parameter section in |buffer|.
27216 buffer.erase(parameter_section_size);
27217 }
27218 std::unique_ptr<crypto::SecureHash> hash(
27219 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27220 hash->Update(response_code_bytes.data(), response_code_bytes.size());
27221 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27222 hash->Update(buffer.data(), buffer.size());
27223 std::string response_hash(32, 0);
27224 hash->Finish(std::data(response_hash), response_hash.size());
27225 if (tag == TPM_ST_SESSIONS) {
27226 if (!authorization_delegate)
27227 return TRUNKS_RC_AUTHORIZATION_FAILED;
27228 if (!authorization_delegate->CheckResponseAuthorization(
27229 response_hash, authorization_section_bytes)) {
27230 return TRUNKS_RC_AUTHORIZATION_FAILED;
27231 }
27232 }
27233 return TPM_RC_SUCCESS;
27234 }
27235
DictionaryAttackLockResetErrorCallback(Tpm::DictionaryAttackLockResetResponse callback,TPM_RC response_code)27236 void DictionaryAttackLockResetErrorCallback(
27237 Tpm::DictionaryAttackLockResetResponse callback, TPM_RC response_code) {
27238 VLOG(1) << __func__;
27239 std::move(callback).Run(response_code);
27240 }
27241
DictionaryAttackLockResetResponseParser(Tpm::DictionaryAttackLockResetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27242 void DictionaryAttackLockResetResponseParser(
27243 Tpm::DictionaryAttackLockResetResponse callback,
27244 AuthorizationDelegate* authorization_delegate,
27245 const std::string& response) {
27246 VLOG(1) << __func__;
27247 TPM_RC rc = Tpm::ParseResponse_DictionaryAttackLockReset(
27248 response, authorization_delegate);
27249 if (rc != TPM_RC_SUCCESS) {
27250 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27251 DictionaryAttackLockResetErrorCallback, std::move(callback));
27252 std::move(error_reporter).Run(rc);
27253 return;
27254 }
27255 std::move(callback).Run(rc);
27256 }
27257
DictionaryAttackLockReset(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,AuthorizationDelegate * authorization_delegate,DictionaryAttackLockResetResponse callback)27258 void Tpm::DictionaryAttackLockReset(
27259 const TPMI_RH_LOCKOUT& lock_handle,
27260 const std::string& lock_handle_name,
27261 AuthorizationDelegate* authorization_delegate,
27262 DictionaryAttackLockResetResponse callback) {
27263 VLOG(1) << __func__;
27264 std::string command;
27265 TPM_RC rc = SerializeCommand_DictionaryAttackLockReset(
27266 lock_handle, lock_handle_name, &command, authorization_delegate);
27267 if (rc != TPM_RC_SUCCESS) {
27268 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27269 DictionaryAttackLockResetErrorCallback, std::move(callback));
27270 std::move(error_reporter).Run(rc);
27271 return;
27272 }
27273 base::OnceCallback<void(const std::string&)> parser =
27274 base::BindOnce(DictionaryAttackLockResetResponseParser,
27275 std::move(callback), authorization_delegate);
27276 transceiver_->SendCommand(command, std::move(parser));
27277 }
27278
DictionaryAttackLockResetSync(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,AuthorizationDelegate * authorization_delegate)27279 TPM_RC Tpm::DictionaryAttackLockResetSync(
27280 const TPMI_RH_LOCKOUT& lock_handle,
27281 const std::string& lock_handle_name,
27282 AuthorizationDelegate* authorization_delegate) {
27283 VLOG(1) << __func__;
27284 std::string command;
27285 TPM_RC rc = SerializeCommand_DictionaryAttackLockReset(
27286 lock_handle, lock_handle_name, &command, authorization_delegate);
27287 if (rc != TPM_RC_SUCCESS) {
27288 return rc;
27289 }
27290 std::string response = transceiver_->SendCommandAndWait(command);
27291 rc =
27292 ParseResponse_DictionaryAttackLockReset(response, authorization_delegate);
27293 return rc;
27294 }
27295
SerializeCommand_DictionaryAttackParameters(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,const UINT32 & new_max_tries,const UINT32 & new_recovery_time,const UINT32 & lockout_recovery,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27296 TPM_RC Tpm::SerializeCommand_DictionaryAttackParameters(
27297 const TPMI_RH_LOCKOUT& lock_handle,
27298 const std::string& lock_handle_name,
27299 const UINT32& new_max_tries,
27300 const UINT32& new_recovery_time,
27301 const UINT32& lockout_recovery,
27302 std::string* serialized_command,
27303 AuthorizationDelegate* authorization_delegate) {
27304 VLOG(3) << __func__;
27305 TPM_RC rc = TPM_RC_SUCCESS;
27306 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27307 UINT32 command_size = 10; // Header size.
27308 std::string handle_section_bytes;
27309 std::string parameter_section_bytes;
27310 TPM_CC command_code = TPM_CC_DictionaryAttackParameters;
27311 bool is_command_parameter_encryption_possible = false;
27312 bool is_response_parameter_encryption_possible = false;
27313 std::string command_code_bytes;
27314 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27315 if (rc != TPM_RC_SUCCESS) {
27316 return rc;
27317 }
27318 std::string lock_handle_bytes;
27319 rc = Serialize_TPMI_RH_LOCKOUT(lock_handle, &lock_handle_bytes);
27320 if (rc != TPM_RC_SUCCESS) {
27321 return rc;
27322 }
27323 std::string new_max_tries_bytes;
27324 rc = Serialize_UINT32(new_max_tries, &new_max_tries_bytes);
27325 if (rc != TPM_RC_SUCCESS) {
27326 return rc;
27327 }
27328 std::string new_recovery_time_bytes;
27329 rc = Serialize_UINT32(new_recovery_time, &new_recovery_time_bytes);
27330 if (rc != TPM_RC_SUCCESS) {
27331 return rc;
27332 }
27333 std::string lockout_recovery_bytes;
27334 rc = Serialize_UINT32(lockout_recovery, &lockout_recovery_bytes);
27335 if (rc != TPM_RC_SUCCESS) {
27336 return rc;
27337 }
27338 std::unique_ptr<crypto::SecureHash> hash(
27339 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27340 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27341 hash->Update(lock_handle_name.data(), lock_handle_name.size());
27342 handle_section_bytes += lock_handle_bytes;
27343 command_size += lock_handle_bytes.size();
27344 hash->Update(new_max_tries_bytes.data(), new_max_tries_bytes.size());
27345 parameter_section_bytes += new_max_tries_bytes;
27346 command_size += new_max_tries_bytes.size();
27347 hash->Update(new_recovery_time_bytes.data(), new_recovery_time_bytes.size());
27348 parameter_section_bytes += new_recovery_time_bytes;
27349 command_size += new_recovery_time_bytes.size();
27350 hash->Update(lockout_recovery_bytes.data(), lockout_recovery_bytes.size());
27351 parameter_section_bytes += lockout_recovery_bytes;
27352 command_size += lockout_recovery_bytes.size();
27353 std::string command_hash(32, 0);
27354 hash->Finish(std::data(command_hash), command_hash.size());
27355 std::string authorization_section_bytes;
27356 std::string authorization_size_bytes;
27357 if (authorization_delegate) {
27358 if (!authorization_delegate->GetCommandAuthorization(
27359 command_hash, is_command_parameter_encryption_possible,
27360 is_response_parameter_encryption_possible,
27361 &authorization_section_bytes)) {
27362 return TRUNKS_RC_AUTHORIZATION_FAILED;
27363 }
27364 if (!authorization_section_bytes.empty()) {
27365 tag = TPM_ST_SESSIONS;
27366 std::string tmp;
27367 rc = Serialize_UINT32(authorization_section_bytes.size(),
27368 &authorization_size_bytes);
27369 if (rc != TPM_RC_SUCCESS) {
27370 return rc;
27371 }
27372 command_size +=
27373 authorization_size_bytes.size() + authorization_section_bytes.size();
27374 }
27375 }
27376 std::string tag_bytes;
27377 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27378 if (rc != TPM_RC_SUCCESS) {
27379 return rc;
27380 }
27381 std::string command_size_bytes;
27382 rc = Serialize_UINT32(command_size, &command_size_bytes);
27383 if (rc != TPM_RC_SUCCESS) {
27384 return rc;
27385 }
27386 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27387 handle_section_bytes + authorization_size_bytes +
27388 authorization_section_bytes + parameter_section_bytes;
27389 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27390 VLOG(2) << "Command: "
27391 << base::HexEncode(serialized_command->data(),
27392 serialized_command->size());
27393 return TPM_RC_SUCCESS;
27394 }
27395
ParseResponse_DictionaryAttackParameters(const std::string & response,AuthorizationDelegate * authorization_delegate)27396 TPM_RC Tpm::ParseResponse_DictionaryAttackParameters(
27397 const std::string& response,
27398 AuthorizationDelegate* authorization_delegate) {
27399 VLOG(3) << __func__;
27400 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27401 TPM_RC rc = TPM_RC_SUCCESS;
27402 std::string buffer(response);
27403 TPM_ST tag;
27404 std::string tag_bytes;
27405 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27406 if (rc != TPM_RC_SUCCESS) {
27407 return rc;
27408 }
27409 UINT32 response_size;
27410 std::string response_size_bytes;
27411 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27412 if (rc != TPM_RC_SUCCESS) {
27413 return rc;
27414 }
27415 TPM_RC response_code;
27416 std::string response_code_bytes;
27417 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27418 if (rc != TPM_RC_SUCCESS) {
27419 return rc;
27420 }
27421 if (response_size != response.size()) {
27422 return TPM_RC_SIZE;
27423 }
27424 if (response_code != TPM_RC_SUCCESS) {
27425 return response_code;
27426 }
27427 TPM_CC command_code = TPM_CC_DictionaryAttackParameters;
27428 std::string command_code_bytes;
27429 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27430 if (rc != TPM_RC_SUCCESS) {
27431 return rc;
27432 }
27433 std::string authorization_section_bytes;
27434 if (tag == TPM_ST_SESSIONS) {
27435 UINT32 parameter_section_size = buffer.size();
27436 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
27437 if (rc != TPM_RC_SUCCESS) {
27438 return rc;
27439 }
27440 if (parameter_section_size > buffer.size()) {
27441 return TPM_RC_INSUFFICIENT;
27442 }
27443 authorization_section_bytes = buffer.substr(parameter_section_size);
27444 // Keep the parameter section in |buffer|.
27445 buffer.erase(parameter_section_size);
27446 }
27447 std::unique_ptr<crypto::SecureHash> hash(
27448 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27449 hash->Update(response_code_bytes.data(), response_code_bytes.size());
27450 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27451 hash->Update(buffer.data(), buffer.size());
27452 std::string response_hash(32, 0);
27453 hash->Finish(std::data(response_hash), response_hash.size());
27454 if (tag == TPM_ST_SESSIONS) {
27455 if (!authorization_delegate)
27456 return TRUNKS_RC_AUTHORIZATION_FAILED;
27457 if (!authorization_delegate->CheckResponseAuthorization(
27458 response_hash, authorization_section_bytes)) {
27459 return TRUNKS_RC_AUTHORIZATION_FAILED;
27460 }
27461 }
27462 return TPM_RC_SUCCESS;
27463 }
27464
DictionaryAttackParametersErrorCallback(Tpm::DictionaryAttackParametersResponse callback,TPM_RC response_code)27465 void DictionaryAttackParametersErrorCallback(
27466 Tpm::DictionaryAttackParametersResponse callback, TPM_RC response_code) {
27467 VLOG(1) << __func__;
27468 std::move(callback).Run(response_code);
27469 }
27470
DictionaryAttackParametersResponseParser(Tpm::DictionaryAttackParametersResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27471 void DictionaryAttackParametersResponseParser(
27472 Tpm::DictionaryAttackParametersResponse callback,
27473 AuthorizationDelegate* authorization_delegate,
27474 const std::string& response) {
27475 VLOG(1) << __func__;
27476 TPM_RC rc = Tpm::ParseResponse_DictionaryAttackParameters(
27477 response, authorization_delegate);
27478 if (rc != TPM_RC_SUCCESS) {
27479 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27480 DictionaryAttackParametersErrorCallback, std::move(callback));
27481 std::move(error_reporter).Run(rc);
27482 return;
27483 }
27484 std::move(callback).Run(rc);
27485 }
27486
DictionaryAttackParameters(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,const UINT32 & new_max_tries,const UINT32 & new_recovery_time,const UINT32 & lockout_recovery,AuthorizationDelegate * authorization_delegate,DictionaryAttackParametersResponse callback)27487 void Tpm::DictionaryAttackParameters(
27488 const TPMI_RH_LOCKOUT& lock_handle,
27489 const std::string& lock_handle_name,
27490 const UINT32& new_max_tries,
27491 const UINT32& new_recovery_time,
27492 const UINT32& lockout_recovery,
27493 AuthorizationDelegate* authorization_delegate,
27494 DictionaryAttackParametersResponse callback) {
27495 VLOG(1) << __func__;
27496 std::string command;
27497 TPM_RC rc = SerializeCommand_DictionaryAttackParameters(
27498 lock_handle, lock_handle_name, new_max_tries, new_recovery_time,
27499 lockout_recovery, &command, authorization_delegate);
27500 if (rc != TPM_RC_SUCCESS) {
27501 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27502 DictionaryAttackParametersErrorCallback, std::move(callback));
27503 std::move(error_reporter).Run(rc);
27504 return;
27505 }
27506 base::OnceCallback<void(const std::string&)> parser =
27507 base::BindOnce(DictionaryAttackParametersResponseParser,
27508 std::move(callback), authorization_delegate);
27509 transceiver_->SendCommand(command, std::move(parser));
27510 }
27511
DictionaryAttackParametersSync(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,const UINT32 & new_max_tries,const UINT32 & new_recovery_time,const UINT32 & lockout_recovery,AuthorizationDelegate * authorization_delegate)27512 TPM_RC Tpm::DictionaryAttackParametersSync(
27513 const TPMI_RH_LOCKOUT& lock_handle,
27514 const std::string& lock_handle_name,
27515 const UINT32& new_max_tries,
27516 const UINT32& new_recovery_time,
27517 const UINT32& lockout_recovery,
27518 AuthorizationDelegate* authorization_delegate) {
27519 VLOG(1) << __func__;
27520 std::string command;
27521 TPM_RC rc = SerializeCommand_DictionaryAttackParameters(
27522 lock_handle, lock_handle_name, new_max_tries, new_recovery_time,
27523 lockout_recovery, &command, authorization_delegate);
27524 if (rc != TPM_RC_SUCCESS) {
27525 return rc;
27526 }
27527 std::string response = transceiver_->SendCommandAndWait(command);
27528 rc = ParseResponse_DictionaryAttackParameters(response,
27529 authorization_delegate);
27530 return rc;
27531 }
27532
SerializeCommand_PP_Commands(const TPMI_RH_PLATFORM & auth,const std::string & auth_name,const TPML_CC & set_list,const TPML_CC & clear_list,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27533 TPM_RC Tpm::SerializeCommand_PP_Commands(
27534 const TPMI_RH_PLATFORM& auth,
27535 const std::string& auth_name,
27536 const TPML_CC& set_list,
27537 const TPML_CC& clear_list,
27538 std::string* serialized_command,
27539 AuthorizationDelegate* authorization_delegate) {
27540 VLOG(3) << __func__;
27541 TPM_RC rc = TPM_RC_SUCCESS;
27542 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27543 UINT32 command_size = 10; // Header size.
27544 std::string handle_section_bytes;
27545 std::string parameter_section_bytes;
27546 TPM_CC command_code = TPM_CC_PP_Commands;
27547 bool is_command_parameter_encryption_possible = false;
27548 bool is_response_parameter_encryption_possible = false;
27549 std::string command_code_bytes;
27550 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27551 if (rc != TPM_RC_SUCCESS) {
27552 return rc;
27553 }
27554 std::string auth_bytes;
27555 rc = Serialize_TPMI_RH_PLATFORM(auth, &auth_bytes);
27556 if (rc != TPM_RC_SUCCESS) {
27557 return rc;
27558 }
27559 std::string set_list_bytes;
27560 rc = Serialize_TPML_CC(set_list, &set_list_bytes);
27561 if (rc != TPM_RC_SUCCESS) {
27562 return rc;
27563 }
27564 std::string clear_list_bytes;
27565 rc = Serialize_TPML_CC(clear_list, &clear_list_bytes);
27566 if (rc != TPM_RC_SUCCESS) {
27567 return rc;
27568 }
27569 std::unique_ptr<crypto::SecureHash> hash(
27570 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27571 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27572 hash->Update(auth_name.data(), auth_name.size());
27573 handle_section_bytes += auth_bytes;
27574 command_size += auth_bytes.size();
27575 hash->Update(set_list_bytes.data(), set_list_bytes.size());
27576 parameter_section_bytes += set_list_bytes;
27577 command_size += set_list_bytes.size();
27578 hash->Update(clear_list_bytes.data(), clear_list_bytes.size());
27579 parameter_section_bytes += clear_list_bytes;
27580 command_size += clear_list_bytes.size();
27581 std::string command_hash(32, 0);
27582 hash->Finish(std::data(command_hash), command_hash.size());
27583 std::string authorization_section_bytes;
27584 std::string authorization_size_bytes;
27585 if (authorization_delegate) {
27586 if (!authorization_delegate->GetCommandAuthorization(
27587 command_hash, is_command_parameter_encryption_possible,
27588 is_response_parameter_encryption_possible,
27589 &authorization_section_bytes)) {
27590 return TRUNKS_RC_AUTHORIZATION_FAILED;
27591 }
27592 if (!authorization_section_bytes.empty()) {
27593 tag = TPM_ST_SESSIONS;
27594 std::string tmp;
27595 rc = Serialize_UINT32(authorization_section_bytes.size(),
27596 &authorization_size_bytes);
27597 if (rc != TPM_RC_SUCCESS) {
27598 return rc;
27599 }
27600 command_size +=
27601 authorization_size_bytes.size() + authorization_section_bytes.size();
27602 }
27603 }
27604 std::string tag_bytes;
27605 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27606 if (rc != TPM_RC_SUCCESS) {
27607 return rc;
27608 }
27609 std::string command_size_bytes;
27610 rc = Serialize_UINT32(command_size, &command_size_bytes);
27611 if (rc != TPM_RC_SUCCESS) {
27612 return rc;
27613 }
27614 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27615 handle_section_bytes + authorization_size_bytes +
27616 authorization_section_bytes + parameter_section_bytes;
27617 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27618 VLOG(2) << "Command: "
27619 << base::HexEncode(serialized_command->data(),
27620 serialized_command->size());
27621 return TPM_RC_SUCCESS;
27622 }
27623
ParseResponse_PP_Commands(const std::string & response,AuthorizationDelegate * authorization_delegate)27624 TPM_RC Tpm::ParseResponse_PP_Commands(
27625 const std::string& response,
27626 AuthorizationDelegate* authorization_delegate) {
27627 VLOG(3) << __func__;
27628 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27629 TPM_RC rc = TPM_RC_SUCCESS;
27630 std::string buffer(response);
27631 TPM_ST tag;
27632 std::string tag_bytes;
27633 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27634 if (rc != TPM_RC_SUCCESS) {
27635 return rc;
27636 }
27637 UINT32 response_size;
27638 std::string response_size_bytes;
27639 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27640 if (rc != TPM_RC_SUCCESS) {
27641 return rc;
27642 }
27643 TPM_RC response_code;
27644 std::string response_code_bytes;
27645 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27646 if (rc != TPM_RC_SUCCESS) {
27647 return rc;
27648 }
27649 if (response_size != response.size()) {
27650 return TPM_RC_SIZE;
27651 }
27652 if (response_code != TPM_RC_SUCCESS) {
27653 return response_code;
27654 }
27655 TPM_CC command_code = TPM_CC_PP_Commands;
27656 std::string command_code_bytes;
27657 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27658 if (rc != TPM_RC_SUCCESS) {
27659 return rc;
27660 }
27661 std::string authorization_section_bytes;
27662 if (tag == TPM_ST_SESSIONS) {
27663 UINT32 parameter_section_size = buffer.size();
27664 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
27665 if (rc != TPM_RC_SUCCESS) {
27666 return rc;
27667 }
27668 if (parameter_section_size > buffer.size()) {
27669 return TPM_RC_INSUFFICIENT;
27670 }
27671 authorization_section_bytes = buffer.substr(parameter_section_size);
27672 // Keep the parameter section in |buffer|.
27673 buffer.erase(parameter_section_size);
27674 }
27675 std::unique_ptr<crypto::SecureHash> hash(
27676 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27677 hash->Update(response_code_bytes.data(), response_code_bytes.size());
27678 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27679 hash->Update(buffer.data(), buffer.size());
27680 std::string response_hash(32, 0);
27681 hash->Finish(std::data(response_hash), response_hash.size());
27682 if (tag == TPM_ST_SESSIONS) {
27683 if (!authorization_delegate)
27684 return TRUNKS_RC_AUTHORIZATION_FAILED;
27685 if (!authorization_delegate->CheckResponseAuthorization(
27686 response_hash, authorization_section_bytes)) {
27687 return TRUNKS_RC_AUTHORIZATION_FAILED;
27688 }
27689 }
27690 return TPM_RC_SUCCESS;
27691 }
27692
PP_CommandsErrorCallback(Tpm::PP_CommandsResponse callback,TPM_RC response_code)27693 void PP_CommandsErrorCallback(Tpm::PP_CommandsResponse callback,
27694 TPM_RC response_code) {
27695 VLOG(1) << __func__;
27696 std::move(callback).Run(response_code);
27697 }
27698
PP_CommandsResponseParser(Tpm::PP_CommandsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27699 void PP_CommandsResponseParser(Tpm::PP_CommandsResponse callback,
27700 AuthorizationDelegate* authorization_delegate,
27701 const std::string& response) {
27702 VLOG(1) << __func__;
27703 TPM_RC rc = Tpm::ParseResponse_PP_Commands(response, authorization_delegate);
27704 if (rc != TPM_RC_SUCCESS) {
27705 base::OnceCallback<void(TPM_RC)> error_reporter =
27706 base::BindOnce(PP_CommandsErrorCallback, std::move(callback));
27707 std::move(error_reporter).Run(rc);
27708 return;
27709 }
27710 std::move(callback).Run(rc);
27711 }
27712
PP_Commands(const TPMI_RH_PLATFORM & auth,const std::string & auth_name,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate,PP_CommandsResponse callback)27713 void Tpm::PP_Commands(const TPMI_RH_PLATFORM& auth,
27714 const std::string& auth_name,
27715 const TPML_CC& set_list,
27716 const TPML_CC& clear_list,
27717 AuthorizationDelegate* authorization_delegate,
27718 PP_CommandsResponse callback) {
27719 VLOG(1) << __func__;
27720 std::string command;
27721 TPM_RC rc = SerializeCommand_PP_Commands(
27722 auth, auth_name, set_list, clear_list, &command, authorization_delegate);
27723 if (rc != TPM_RC_SUCCESS) {
27724 base::OnceCallback<void(TPM_RC)> error_reporter =
27725 base::BindOnce(PP_CommandsErrorCallback, std::move(callback));
27726 std::move(error_reporter).Run(rc);
27727 return;
27728 }
27729 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
27730 PP_CommandsResponseParser, std::move(callback), authorization_delegate);
27731 transceiver_->SendCommand(command, std::move(parser));
27732 }
27733
PP_CommandsSync(const TPMI_RH_PLATFORM & auth,const std::string & auth_name,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate)27734 TPM_RC Tpm::PP_CommandsSync(const TPMI_RH_PLATFORM& auth,
27735 const std::string& auth_name,
27736 const TPML_CC& set_list,
27737 const TPML_CC& clear_list,
27738 AuthorizationDelegate* authorization_delegate) {
27739 VLOG(1) << __func__;
27740 std::string command;
27741 TPM_RC rc = SerializeCommand_PP_Commands(
27742 auth, auth_name, set_list, clear_list, &command, authorization_delegate);
27743 if (rc != TPM_RC_SUCCESS) {
27744 return rc;
27745 }
27746 std::string response = transceiver_->SendCommandAndWait(command);
27747 rc = ParseResponse_PP_Commands(response, authorization_delegate);
27748 return rc;
27749 }
27750
SerializeCommand_SetAlgorithmSet(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27751 TPM_RC Tpm::SerializeCommand_SetAlgorithmSet(
27752 const TPMI_RH_PLATFORM& auth_handle,
27753 const std::string& auth_handle_name,
27754 const UINT32& algorithm_set,
27755 std::string* serialized_command,
27756 AuthorizationDelegate* authorization_delegate) {
27757 VLOG(3) << __func__;
27758 TPM_RC rc = TPM_RC_SUCCESS;
27759 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27760 UINT32 command_size = 10; // Header size.
27761 std::string handle_section_bytes;
27762 std::string parameter_section_bytes;
27763 TPM_CC command_code = TPM_CC_SetAlgorithmSet;
27764 bool is_command_parameter_encryption_possible = false;
27765 bool is_response_parameter_encryption_possible = false;
27766 std::string command_code_bytes;
27767 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27768 if (rc != TPM_RC_SUCCESS) {
27769 return rc;
27770 }
27771 std::string auth_handle_bytes;
27772 rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
27773 if (rc != TPM_RC_SUCCESS) {
27774 return rc;
27775 }
27776 std::string algorithm_set_bytes;
27777 rc = Serialize_UINT32(algorithm_set, &algorithm_set_bytes);
27778 if (rc != TPM_RC_SUCCESS) {
27779 return rc;
27780 }
27781 std::unique_ptr<crypto::SecureHash> hash(
27782 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27783 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27784 hash->Update(auth_handle_name.data(), auth_handle_name.size());
27785 handle_section_bytes += auth_handle_bytes;
27786 command_size += auth_handle_bytes.size();
27787 hash->Update(algorithm_set_bytes.data(), algorithm_set_bytes.size());
27788 parameter_section_bytes += algorithm_set_bytes;
27789 command_size += algorithm_set_bytes.size();
27790 std::string command_hash(32, 0);
27791 hash->Finish(std::data(command_hash), command_hash.size());
27792 std::string authorization_section_bytes;
27793 std::string authorization_size_bytes;
27794 if (authorization_delegate) {
27795 if (!authorization_delegate->GetCommandAuthorization(
27796 command_hash, is_command_parameter_encryption_possible,
27797 is_response_parameter_encryption_possible,
27798 &authorization_section_bytes)) {
27799 return TRUNKS_RC_AUTHORIZATION_FAILED;
27800 }
27801 if (!authorization_section_bytes.empty()) {
27802 tag = TPM_ST_SESSIONS;
27803 std::string tmp;
27804 rc = Serialize_UINT32(authorization_section_bytes.size(),
27805 &authorization_size_bytes);
27806 if (rc != TPM_RC_SUCCESS) {
27807 return rc;
27808 }
27809 command_size +=
27810 authorization_size_bytes.size() + authorization_section_bytes.size();
27811 }
27812 }
27813 std::string tag_bytes;
27814 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27815 if (rc != TPM_RC_SUCCESS) {
27816 return rc;
27817 }
27818 std::string command_size_bytes;
27819 rc = Serialize_UINT32(command_size, &command_size_bytes);
27820 if (rc != TPM_RC_SUCCESS) {
27821 return rc;
27822 }
27823 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27824 handle_section_bytes + authorization_size_bytes +
27825 authorization_section_bytes + parameter_section_bytes;
27826 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27827 VLOG(2) << "Command: "
27828 << base::HexEncode(serialized_command->data(),
27829 serialized_command->size());
27830 return TPM_RC_SUCCESS;
27831 }
27832
ParseResponse_SetAlgorithmSet(const std::string & response,AuthorizationDelegate * authorization_delegate)27833 TPM_RC Tpm::ParseResponse_SetAlgorithmSet(
27834 const std::string& response,
27835 AuthorizationDelegate* authorization_delegate) {
27836 VLOG(3) << __func__;
27837 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27838 TPM_RC rc = TPM_RC_SUCCESS;
27839 std::string buffer(response);
27840 TPM_ST tag;
27841 std::string tag_bytes;
27842 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27843 if (rc != TPM_RC_SUCCESS) {
27844 return rc;
27845 }
27846 UINT32 response_size;
27847 std::string response_size_bytes;
27848 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27849 if (rc != TPM_RC_SUCCESS) {
27850 return rc;
27851 }
27852 TPM_RC response_code;
27853 std::string response_code_bytes;
27854 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27855 if (rc != TPM_RC_SUCCESS) {
27856 return rc;
27857 }
27858 if (response_size != response.size()) {
27859 return TPM_RC_SIZE;
27860 }
27861 if (response_code != TPM_RC_SUCCESS) {
27862 return response_code;
27863 }
27864 TPM_CC command_code = TPM_CC_SetAlgorithmSet;
27865 std::string command_code_bytes;
27866 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27867 if (rc != TPM_RC_SUCCESS) {
27868 return rc;
27869 }
27870 std::string authorization_section_bytes;
27871 if (tag == TPM_ST_SESSIONS) {
27872 UINT32 parameter_section_size = buffer.size();
27873 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
27874 if (rc != TPM_RC_SUCCESS) {
27875 return rc;
27876 }
27877 if (parameter_section_size > buffer.size()) {
27878 return TPM_RC_INSUFFICIENT;
27879 }
27880 authorization_section_bytes = buffer.substr(parameter_section_size);
27881 // Keep the parameter section in |buffer|.
27882 buffer.erase(parameter_section_size);
27883 }
27884 std::unique_ptr<crypto::SecureHash> hash(
27885 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27886 hash->Update(response_code_bytes.data(), response_code_bytes.size());
27887 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27888 hash->Update(buffer.data(), buffer.size());
27889 std::string response_hash(32, 0);
27890 hash->Finish(std::data(response_hash), response_hash.size());
27891 if (tag == TPM_ST_SESSIONS) {
27892 if (!authorization_delegate)
27893 return TRUNKS_RC_AUTHORIZATION_FAILED;
27894 if (!authorization_delegate->CheckResponseAuthorization(
27895 response_hash, authorization_section_bytes)) {
27896 return TRUNKS_RC_AUTHORIZATION_FAILED;
27897 }
27898 }
27899 return TPM_RC_SUCCESS;
27900 }
27901
SetAlgorithmSetErrorCallback(Tpm::SetAlgorithmSetResponse callback,TPM_RC response_code)27902 void SetAlgorithmSetErrorCallback(Tpm::SetAlgorithmSetResponse callback,
27903 TPM_RC response_code) {
27904 VLOG(1) << __func__;
27905 std::move(callback).Run(response_code);
27906 }
27907
SetAlgorithmSetResponseParser(Tpm::SetAlgorithmSetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27908 void SetAlgorithmSetResponseParser(
27909 Tpm::SetAlgorithmSetResponse callback,
27910 AuthorizationDelegate* authorization_delegate,
27911 const std::string& response) {
27912 VLOG(1) << __func__;
27913 TPM_RC rc =
27914 Tpm::ParseResponse_SetAlgorithmSet(response, authorization_delegate);
27915 if (rc != TPM_RC_SUCCESS) {
27916 base::OnceCallback<void(TPM_RC)> error_reporter =
27917 base::BindOnce(SetAlgorithmSetErrorCallback, std::move(callback));
27918 std::move(error_reporter).Run(rc);
27919 return;
27920 }
27921 std::move(callback).Run(rc);
27922 }
27923
SetAlgorithmSet(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,AuthorizationDelegate * authorization_delegate,SetAlgorithmSetResponse callback)27924 void Tpm::SetAlgorithmSet(const TPMI_RH_PLATFORM& auth_handle,
27925 const std::string& auth_handle_name,
27926 const UINT32& algorithm_set,
27927 AuthorizationDelegate* authorization_delegate,
27928 SetAlgorithmSetResponse callback) {
27929 VLOG(1) << __func__;
27930 std::string command;
27931 TPM_RC rc = SerializeCommand_SetAlgorithmSet(auth_handle, auth_handle_name,
27932 algorithm_set, &command,
27933 authorization_delegate);
27934 if (rc != TPM_RC_SUCCESS) {
27935 base::OnceCallback<void(TPM_RC)> error_reporter =
27936 base::BindOnce(SetAlgorithmSetErrorCallback, std::move(callback));
27937 std::move(error_reporter).Run(rc);
27938 return;
27939 }
27940 base::OnceCallback<void(const std::string&)> parser =
27941 base::BindOnce(SetAlgorithmSetResponseParser, std::move(callback),
27942 authorization_delegate);
27943 transceiver_->SendCommand(command, std::move(parser));
27944 }
27945
SetAlgorithmSetSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,AuthorizationDelegate * authorization_delegate)27946 TPM_RC Tpm::SetAlgorithmSetSync(const TPMI_RH_PLATFORM& auth_handle,
27947 const std::string& auth_handle_name,
27948 const UINT32& algorithm_set,
27949 AuthorizationDelegate* authorization_delegate) {
27950 VLOG(1) << __func__;
27951 std::string command;
27952 TPM_RC rc = SerializeCommand_SetAlgorithmSet(auth_handle, auth_handle_name,
27953 algorithm_set, &command,
27954 authorization_delegate);
27955 if (rc != TPM_RC_SUCCESS) {
27956 return rc;
27957 }
27958 std::string response = transceiver_->SendCommandAndWait(command);
27959 rc = ParseResponse_SetAlgorithmSet(response, authorization_delegate);
27960 return rc;
27961 }
27962
SerializeCommand_FieldUpgradeStart(const TPMI_RH_PLATFORM & authorization,const std::string & authorization_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & fu_digest,const TPMT_SIGNATURE & manifest_signature,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27963 TPM_RC Tpm::SerializeCommand_FieldUpgradeStart(
27964 const TPMI_RH_PLATFORM& authorization,
27965 const std::string& authorization_name,
27966 const TPMI_DH_OBJECT& key_handle,
27967 const std::string& key_handle_name,
27968 const TPM2B_DIGEST& fu_digest,
27969 const TPMT_SIGNATURE& manifest_signature,
27970 std::string* serialized_command,
27971 AuthorizationDelegate* authorization_delegate) {
27972 VLOG(3) << __func__;
27973 TPM_RC rc = TPM_RC_SUCCESS;
27974 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27975 UINT32 command_size = 10; // Header size.
27976 std::string handle_section_bytes;
27977 std::string parameter_section_bytes;
27978 TPM_CC command_code = TPM_CC_FieldUpgradeStart;
27979 bool is_command_parameter_encryption_possible = true;
27980 bool is_response_parameter_encryption_possible = false;
27981 std::string command_code_bytes;
27982 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27983 if (rc != TPM_RC_SUCCESS) {
27984 return rc;
27985 }
27986 std::string authorization_bytes;
27987 rc = Serialize_TPMI_RH_PLATFORM(authorization, &authorization_bytes);
27988 if (rc != TPM_RC_SUCCESS) {
27989 return rc;
27990 }
27991 std::string key_handle_bytes;
27992 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
27993 if (rc != TPM_RC_SUCCESS) {
27994 return rc;
27995 }
27996 std::string fu_digest_bytes;
27997 rc = Serialize_TPM2B_DIGEST(fu_digest, &fu_digest_bytes);
27998 if (rc != TPM_RC_SUCCESS) {
27999 return rc;
28000 }
28001 std::string manifest_signature_bytes;
28002 rc = Serialize_TPMT_SIGNATURE(manifest_signature, &manifest_signature_bytes);
28003 if (rc != TPM_RC_SUCCESS) {
28004 return rc;
28005 }
28006 if (authorization_delegate) {
28007 // Encrypt just the parameter data, not the size.
28008 std::string tmp = fu_digest_bytes.substr(2);
28009 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
28010 return TRUNKS_RC_ENCRYPTION_FAILED;
28011 }
28012 fu_digest_bytes.replace(2, std::string::npos, tmp);
28013 }
28014 std::unique_ptr<crypto::SecureHash> hash(
28015 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28016 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28017 hash->Update(authorization_name.data(), authorization_name.size());
28018 handle_section_bytes += authorization_bytes;
28019 command_size += authorization_bytes.size();
28020 hash->Update(key_handle_name.data(), key_handle_name.size());
28021 handle_section_bytes += key_handle_bytes;
28022 command_size += key_handle_bytes.size();
28023 hash->Update(fu_digest_bytes.data(), fu_digest_bytes.size());
28024 parameter_section_bytes += fu_digest_bytes;
28025 command_size += fu_digest_bytes.size();
28026 hash->Update(manifest_signature_bytes.data(),
28027 manifest_signature_bytes.size());
28028 parameter_section_bytes += manifest_signature_bytes;
28029 command_size += manifest_signature_bytes.size();
28030 std::string command_hash(32, 0);
28031 hash->Finish(std::data(command_hash), command_hash.size());
28032 std::string authorization_section_bytes;
28033 std::string authorization_size_bytes;
28034 if (authorization_delegate) {
28035 if (!authorization_delegate->GetCommandAuthorization(
28036 command_hash, is_command_parameter_encryption_possible,
28037 is_response_parameter_encryption_possible,
28038 &authorization_section_bytes)) {
28039 return TRUNKS_RC_AUTHORIZATION_FAILED;
28040 }
28041 if (!authorization_section_bytes.empty()) {
28042 tag = TPM_ST_SESSIONS;
28043 std::string tmp;
28044 rc = Serialize_UINT32(authorization_section_bytes.size(),
28045 &authorization_size_bytes);
28046 if (rc != TPM_RC_SUCCESS) {
28047 return rc;
28048 }
28049 command_size +=
28050 authorization_size_bytes.size() + authorization_section_bytes.size();
28051 }
28052 }
28053 std::string tag_bytes;
28054 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28055 if (rc != TPM_RC_SUCCESS) {
28056 return rc;
28057 }
28058 std::string command_size_bytes;
28059 rc = Serialize_UINT32(command_size, &command_size_bytes);
28060 if (rc != TPM_RC_SUCCESS) {
28061 return rc;
28062 }
28063 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28064 handle_section_bytes + authorization_size_bytes +
28065 authorization_section_bytes + parameter_section_bytes;
28066 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28067 VLOG(2) << "Command: "
28068 << base::HexEncode(serialized_command->data(),
28069 serialized_command->size());
28070 return TPM_RC_SUCCESS;
28071 }
28072
ParseResponse_FieldUpgradeStart(const std::string & response,AuthorizationDelegate * authorization_delegate)28073 TPM_RC Tpm::ParseResponse_FieldUpgradeStart(
28074 const std::string& response,
28075 AuthorizationDelegate* authorization_delegate) {
28076 VLOG(3) << __func__;
28077 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28078 TPM_RC rc = TPM_RC_SUCCESS;
28079 std::string buffer(response);
28080 TPM_ST tag;
28081 std::string tag_bytes;
28082 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28083 if (rc != TPM_RC_SUCCESS) {
28084 return rc;
28085 }
28086 UINT32 response_size;
28087 std::string response_size_bytes;
28088 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28089 if (rc != TPM_RC_SUCCESS) {
28090 return rc;
28091 }
28092 TPM_RC response_code;
28093 std::string response_code_bytes;
28094 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28095 if (rc != TPM_RC_SUCCESS) {
28096 return rc;
28097 }
28098 if (response_size != response.size()) {
28099 return TPM_RC_SIZE;
28100 }
28101 if (response_code != TPM_RC_SUCCESS) {
28102 return response_code;
28103 }
28104 TPM_CC command_code = TPM_CC_FieldUpgradeStart;
28105 std::string command_code_bytes;
28106 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28107 if (rc != TPM_RC_SUCCESS) {
28108 return rc;
28109 }
28110 std::string authorization_section_bytes;
28111 if (tag == TPM_ST_SESSIONS) {
28112 UINT32 parameter_section_size = buffer.size();
28113 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
28114 if (rc != TPM_RC_SUCCESS) {
28115 return rc;
28116 }
28117 if (parameter_section_size > buffer.size()) {
28118 return TPM_RC_INSUFFICIENT;
28119 }
28120 authorization_section_bytes = buffer.substr(parameter_section_size);
28121 // Keep the parameter section in |buffer|.
28122 buffer.erase(parameter_section_size);
28123 }
28124 std::unique_ptr<crypto::SecureHash> hash(
28125 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28126 hash->Update(response_code_bytes.data(), response_code_bytes.size());
28127 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28128 hash->Update(buffer.data(), buffer.size());
28129 std::string response_hash(32, 0);
28130 hash->Finish(std::data(response_hash), response_hash.size());
28131 if (tag == TPM_ST_SESSIONS) {
28132 if (!authorization_delegate)
28133 return TRUNKS_RC_AUTHORIZATION_FAILED;
28134 if (!authorization_delegate->CheckResponseAuthorization(
28135 response_hash, authorization_section_bytes)) {
28136 return TRUNKS_RC_AUTHORIZATION_FAILED;
28137 }
28138 }
28139 return TPM_RC_SUCCESS;
28140 }
28141
FieldUpgradeStartErrorCallback(Tpm::FieldUpgradeStartResponse callback,TPM_RC response_code)28142 void FieldUpgradeStartErrorCallback(Tpm::FieldUpgradeStartResponse callback,
28143 TPM_RC response_code) {
28144 VLOG(1) << __func__;
28145 std::move(callback).Run(response_code);
28146 }
28147
FieldUpgradeStartResponseParser(Tpm::FieldUpgradeStartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28148 void FieldUpgradeStartResponseParser(
28149 Tpm::FieldUpgradeStartResponse callback,
28150 AuthorizationDelegate* authorization_delegate,
28151 const std::string& response) {
28152 VLOG(1) << __func__;
28153 TPM_RC rc =
28154 Tpm::ParseResponse_FieldUpgradeStart(response, authorization_delegate);
28155 if (rc != TPM_RC_SUCCESS) {
28156 base::OnceCallback<void(TPM_RC)> error_reporter =
28157 base::BindOnce(FieldUpgradeStartErrorCallback, std::move(callback));
28158 std::move(error_reporter).Run(rc);
28159 return;
28160 }
28161 std::move(callback).Run(rc);
28162 }
28163
FieldUpgradeStart(const TPMI_RH_PLATFORM & authorization,const std::string & authorization_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & fu_digest,const TPMT_SIGNATURE & manifest_signature,AuthorizationDelegate * authorization_delegate,FieldUpgradeStartResponse callback)28164 void Tpm::FieldUpgradeStart(const TPMI_RH_PLATFORM& authorization,
28165 const std::string& authorization_name,
28166 const TPMI_DH_OBJECT& key_handle,
28167 const std::string& key_handle_name,
28168 const TPM2B_DIGEST& fu_digest,
28169 const TPMT_SIGNATURE& manifest_signature,
28170 AuthorizationDelegate* authorization_delegate,
28171 FieldUpgradeStartResponse callback) {
28172 VLOG(1) << __func__;
28173 std::string command;
28174 TPM_RC rc = SerializeCommand_FieldUpgradeStart(
28175 authorization, authorization_name, key_handle, key_handle_name, fu_digest,
28176 manifest_signature, &command, authorization_delegate);
28177 if (rc != TPM_RC_SUCCESS) {
28178 base::OnceCallback<void(TPM_RC)> error_reporter =
28179 base::BindOnce(FieldUpgradeStartErrorCallback, std::move(callback));
28180 std::move(error_reporter).Run(rc);
28181 return;
28182 }
28183 base::OnceCallback<void(const std::string&)> parser =
28184 base::BindOnce(FieldUpgradeStartResponseParser, std::move(callback),
28185 authorization_delegate);
28186 transceiver_->SendCommand(command, std::move(parser));
28187 }
28188
FieldUpgradeStartSync(const TPMI_RH_PLATFORM & authorization,const std::string & authorization_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & fu_digest,const TPMT_SIGNATURE & manifest_signature,AuthorizationDelegate * authorization_delegate)28189 TPM_RC Tpm::FieldUpgradeStartSync(
28190 const TPMI_RH_PLATFORM& authorization,
28191 const std::string& authorization_name,
28192 const TPMI_DH_OBJECT& key_handle,
28193 const std::string& key_handle_name,
28194 const TPM2B_DIGEST& fu_digest,
28195 const TPMT_SIGNATURE& manifest_signature,
28196 AuthorizationDelegate* authorization_delegate) {
28197 VLOG(1) << __func__;
28198 std::string command;
28199 TPM_RC rc = SerializeCommand_FieldUpgradeStart(
28200 authorization, authorization_name, key_handle, key_handle_name, fu_digest,
28201 manifest_signature, &command, authorization_delegate);
28202 if (rc != TPM_RC_SUCCESS) {
28203 return rc;
28204 }
28205 std::string response = transceiver_->SendCommandAndWait(command);
28206 rc = ParseResponse_FieldUpgradeStart(response, authorization_delegate);
28207 return rc;
28208 }
28209
SerializeCommand_FieldUpgradeData(const TPM2B_MAX_BUFFER & fu_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28210 TPM_RC Tpm::SerializeCommand_FieldUpgradeData(
28211 const TPM2B_MAX_BUFFER& fu_data,
28212 std::string* serialized_command,
28213 AuthorizationDelegate* authorization_delegate) {
28214 VLOG(3) << __func__;
28215 TPM_RC rc = TPM_RC_SUCCESS;
28216 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28217 UINT32 command_size = 10; // Header size.
28218 std::string handle_section_bytes;
28219 std::string parameter_section_bytes;
28220 TPM_CC command_code = TPM_CC_FieldUpgradeData;
28221 bool is_command_parameter_encryption_possible = true;
28222 bool is_response_parameter_encryption_possible = false;
28223 std::string command_code_bytes;
28224 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28225 if (rc != TPM_RC_SUCCESS) {
28226 return rc;
28227 }
28228 std::string fu_data_bytes;
28229 rc = Serialize_TPM2B_MAX_BUFFER(fu_data, &fu_data_bytes);
28230 if (rc != TPM_RC_SUCCESS) {
28231 return rc;
28232 }
28233 if (authorization_delegate) {
28234 // Encrypt just the parameter data, not the size.
28235 std::string tmp = fu_data_bytes.substr(2);
28236 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
28237 return TRUNKS_RC_ENCRYPTION_FAILED;
28238 }
28239 fu_data_bytes.replace(2, std::string::npos, tmp);
28240 }
28241 std::unique_ptr<crypto::SecureHash> hash(
28242 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28243 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28244 hash->Update(fu_data_bytes.data(), fu_data_bytes.size());
28245 parameter_section_bytes += fu_data_bytes;
28246 command_size += fu_data_bytes.size();
28247 std::string command_hash(32, 0);
28248 hash->Finish(std::data(command_hash), command_hash.size());
28249 std::string authorization_section_bytes;
28250 std::string authorization_size_bytes;
28251 if (authorization_delegate) {
28252 if (!authorization_delegate->GetCommandAuthorization(
28253 command_hash, is_command_parameter_encryption_possible,
28254 is_response_parameter_encryption_possible,
28255 &authorization_section_bytes)) {
28256 return TRUNKS_RC_AUTHORIZATION_FAILED;
28257 }
28258 if (!authorization_section_bytes.empty()) {
28259 tag = TPM_ST_SESSIONS;
28260 std::string tmp;
28261 rc = Serialize_UINT32(authorization_section_bytes.size(),
28262 &authorization_size_bytes);
28263 if (rc != TPM_RC_SUCCESS) {
28264 return rc;
28265 }
28266 command_size +=
28267 authorization_size_bytes.size() + authorization_section_bytes.size();
28268 }
28269 }
28270 std::string tag_bytes;
28271 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28272 if (rc != TPM_RC_SUCCESS) {
28273 return rc;
28274 }
28275 std::string command_size_bytes;
28276 rc = Serialize_UINT32(command_size, &command_size_bytes);
28277 if (rc != TPM_RC_SUCCESS) {
28278 return rc;
28279 }
28280 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28281 handle_section_bytes + authorization_size_bytes +
28282 authorization_section_bytes + parameter_section_bytes;
28283 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28284 VLOG(2) << "Command: "
28285 << base::HexEncode(serialized_command->data(),
28286 serialized_command->size());
28287 return TPM_RC_SUCCESS;
28288 }
28289
ParseResponse_FieldUpgradeData(const std::string & response,TPMT_HA * next_digest,TPMT_HA * first_digest,AuthorizationDelegate * authorization_delegate)28290 TPM_RC Tpm::ParseResponse_FieldUpgradeData(
28291 const std::string& response,
28292 TPMT_HA* next_digest,
28293 TPMT_HA* first_digest,
28294 AuthorizationDelegate* authorization_delegate) {
28295 VLOG(3) << __func__;
28296 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28297 TPM_RC rc = TPM_RC_SUCCESS;
28298 std::string buffer(response);
28299 TPM_ST tag;
28300 std::string tag_bytes;
28301 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28302 if (rc != TPM_RC_SUCCESS) {
28303 return rc;
28304 }
28305 UINT32 response_size;
28306 std::string response_size_bytes;
28307 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28308 if (rc != TPM_RC_SUCCESS) {
28309 return rc;
28310 }
28311 TPM_RC response_code;
28312 std::string response_code_bytes;
28313 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28314 if (rc != TPM_RC_SUCCESS) {
28315 return rc;
28316 }
28317 if (response_size != response.size()) {
28318 return TPM_RC_SIZE;
28319 }
28320 if (response_code != TPM_RC_SUCCESS) {
28321 return response_code;
28322 }
28323 TPM_CC command_code = TPM_CC_FieldUpgradeData;
28324 std::string command_code_bytes;
28325 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28326 if (rc != TPM_RC_SUCCESS) {
28327 return rc;
28328 }
28329 std::string authorization_section_bytes;
28330 if (tag == TPM_ST_SESSIONS) {
28331 UINT32 parameter_section_size = buffer.size();
28332 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
28333 if (rc != TPM_RC_SUCCESS) {
28334 return rc;
28335 }
28336 if (parameter_section_size > buffer.size()) {
28337 return TPM_RC_INSUFFICIENT;
28338 }
28339 authorization_section_bytes = buffer.substr(parameter_section_size);
28340 // Keep the parameter section in |buffer|.
28341 buffer.erase(parameter_section_size);
28342 }
28343 std::unique_ptr<crypto::SecureHash> hash(
28344 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28345 hash->Update(response_code_bytes.data(), response_code_bytes.size());
28346 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28347 hash->Update(buffer.data(), buffer.size());
28348 std::string response_hash(32, 0);
28349 hash->Finish(std::data(response_hash), response_hash.size());
28350 if (tag == TPM_ST_SESSIONS) {
28351 if (!authorization_delegate)
28352 return TRUNKS_RC_AUTHORIZATION_FAILED;
28353 if (!authorization_delegate->CheckResponseAuthorization(
28354 response_hash, authorization_section_bytes)) {
28355 return TRUNKS_RC_AUTHORIZATION_FAILED;
28356 }
28357 }
28358 std::string next_digest_bytes;
28359 rc = Parse_TPMT_HA(&buffer, next_digest, &next_digest_bytes);
28360 if (rc != TPM_RC_SUCCESS) {
28361 return rc;
28362 }
28363 std::string first_digest_bytes;
28364 rc = Parse_TPMT_HA(&buffer, first_digest, &first_digest_bytes);
28365 if (rc != TPM_RC_SUCCESS) {
28366 return rc;
28367 }
28368 return TPM_RC_SUCCESS;
28369 }
28370
FieldUpgradeDataErrorCallback(Tpm::FieldUpgradeDataResponse callback,TPM_RC response_code)28371 void FieldUpgradeDataErrorCallback(Tpm::FieldUpgradeDataResponse callback,
28372 TPM_RC response_code) {
28373 VLOG(1) << __func__;
28374 std::move(callback).Run(response_code, TPMT_HA(), TPMT_HA());
28375 }
28376
FieldUpgradeDataResponseParser(Tpm::FieldUpgradeDataResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28377 void FieldUpgradeDataResponseParser(
28378 Tpm::FieldUpgradeDataResponse callback,
28379 AuthorizationDelegate* authorization_delegate,
28380 const std::string& response) {
28381 VLOG(1) << __func__;
28382 TPMT_HA next_digest;
28383 TPMT_HA first_digest;
28384 TPM_RC rc = Tpm::ParseResponse_FieldUpgradeData(
28385 response, &next_digest, &first_digest, authorization_delegate);
28386 if (rc != TPM_RC_SUCCESS) {
28387 base::OnceCallback<void(TPM_RC)> error_reporter =
28388 base::BindOnce(FieldUpgradeDataErrorCallback, std::move(callback));
28389 std::move(error_reporter).Run(rc);
28390 return;
28391 }
28392 std::move(callback).Run(rc, next_digest, first_digest);
28393 }
28394
FieldUpgradeData(const TPM2B_MAX_BUFFER & fu_data,AuthorizationDelegate * authorization_delegate,FieldUpgradeDataResponse callback)28395 void Tpm::FieldUpgradeData(const TPM2B_MAX_BUFFER& fu_data,
28396 AuthorizationDelegate* authorization_delegate,
28397 FieldUpgradeDataResponse callback) {
28398 VLOG(1) << __func__;
28399 std::string command;
28400 TPM_RC rc = SerializeCommand_FieldUpgradeData(fu_data, &command,
28401 authorization_delegate);
28402 if (rc != TPM_RC_SUCCESS) {
28403 base::OnceCallback<void(TPM_RC)> error_reporter =
28404 base::BindOnce(FieldUpgradeDataErrorCallback, std::move(callback));
28405 std::move(error_reporter).Run(rc);
28406 return;
28407 }
28408 base::OnceCallback<void(const std::string&)> parser =
28409 base::BindOnce(FieldUpgradeDataResponseParser, std::move(callback),
28410 authorization_delegate);
28411 transceiver_->SendCommand(command, std::move(parser));
28412 }
28413
FieldUpgradeDataSync(const TPM2B_MAX_BUFFER & fu_data,TPMT_HA * next_digest,TPMT_HA * first_digest,AuthorizationDelegate * authorization_delegate)28414 TPM_RC Tpm::FieldUpgradeDataSync(
28415 const TPM2B_MAX_BUFFER& fu_data,
28416 TPMT_HA* next_digest,
28417 TPMT_HA* first_digest,
28418 AuthorizationDelegate* authorization_delegate) {
28419 VLOG(1) << __func__;
28420 std::string command;
28421 TPM_RC rc = SerializeCommand_FieldUpgradeData(fu_data, &command,
28422 authorization_delegate);
28423 if (rc != TPM_RC_SUCCESS) {
28424 return rc;
28425 }
28426 std::string response = transceiver_->SendCommandAndWait(command);
28427 rc = ParseResponse_FieldUpgradeData(response, next_digest, first_digest,
28428 authorization_delegate);
28429 return rc;
28430 }
28431
SerializeCommand_FirmwareRead(const UINT32 & sequence_number,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28432 TPM_RC Tpm::SerializeCommand_FirmwareRead(
28433 const UINT32& sequence_number,
28434 std::string* serialized_command,
28435 AuthorizationDelegate* authorization_delegate) {
28436 VLOG(3) << __func__;
28437 TPM_RC rc = TPM_RC_SUCCESS;
28438 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28439 UINT32 command_size = 10; // Header size.
28440 std::string handle_section_bytes;
28441 std::string parameter_section_bytes;
28442 TPM_CC command_code = TPM_CC_FirmwareRead;
28443 bool is_command_parameter_encryption_possible = false;
28444 bool is_response_parameter_encryption_possible = true;
28445 std::string command_code_bytes;
28446 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28447 if (rc != TPM_RC_SUCCESS) {
28448 return rc;
28449 }
28450 std::string sequence_number_bytes;
28451 rc = Serialize_UINT32(sequence_number, &sequence_number_bytes);
28452 if (rc != TPM_RC_SUCCESS) {
28453 return rc;
28454 }
28455 std::unique_ptr<crypto::SecureHash> hash(
28456 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28457 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28458 hash->Update(sequence_number_bytes.data(), sequence_number_bytes.size());
28459 parameter_section_bytes += sequence_number_bytes;
28460 command_size += sequence_number_bytes.size();
28461 std::string command_hash(32, 0);
28462 hash->Finish(std::data(command_hash), command_hash.size());
28463 std::string authorization_section_bytes;
28464 std::string authorization_size_bytes;
28465 if (authorization_delegate) {
28466 if (!authorization_delegate->GetCommandAuthorization(
28467 command_hash, is_command_parameter_encryption_possible,
28468 is_response_parameter_encryption_possible,
28469 &authorization_section_bytes)) {
28470 return TRUNKS_RC_AUTHORIZATION_FAILED;
28471 }
28472 if (!authorization_section_bytes.empty()) {
28473 tag = TPM_ST_SESSIONS;
28474 std::string tmp;
28475 rc = Serialize_UINT32(authorization_section_bytes.size(),
28476 &authorization_size_bytes);
28477 if (rc != TPM_RC_SUCCESS) {
28478 return rc;
28479 }
28480 command_size +=
28481 authorization_size_bytes.size() + authorization_section_bytes.size();
28482 }
28483 }
28484 std::string tag_bytes;
28485 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28486 if (rc != TPM_RC_SUCCESS) {
28487 return rc;
28488 }
28489 std::string command_size_bytes;
28490 rc = Serialize_UINT32(command_size, &command_size_bytes);
28491 if (rc != TPM_RC_SUCCESS) {
28492 return rc;
28493 }
28494 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28495 handle_section_bytes + authorization_size_bytes +
28496 authorization_section_bytes + parameter_section_bytes;
28497 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28498 VLOG(2) << "Command: "
28499 << base::HexEncode(serialized_command->data(),
28500 serialized_command->size());
28501 return TPM_RC_SUCCESS;
28502 }
28503
ParseResponse_FirmwareRead(const std::string & response,TPM2B_MAX_BUFFER * fu_data,AuthorizationDelegate * authorization_delegate)28504 TPM_RC Tpm::ParseResponse_FirmwareRead(
28505 const std::string& response,
28506 TPM2B_MAX_BUFFER* fu_data,
28507 AuthorizationDelegate* authorization_delegate) {
28508 VLOG(3) << __func__;
28509 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28510 TPM_RC rc = TPM_RC_SUCCESS;
28511 std::string buffer(response);
28512 TPM_ST tag;
28513 std::string tag_bytes;
28514 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28515 if (rc != TPM_RC_SUCCESS) {
28516 return rc;
28517 }
28518 UINT32 response_size;
28519 std::string response_size_bytes;
28520 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28521 if (rc != TPM_RC_SUCCESS) {
28522 return rc;
28523 }
28524 TPM_RC response_code;
28525 std::string response_code_bytes;
28526 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28527 if (rc != TPM_RC_SUCCESS) {
28528 return rc;
28529 }
28530 if (response_size != response.size()) {
28531 return TPM_RC_SIZE;
28532 }
28533 if (response_code != TPM_RC_SUCCESS) {
28534 return response_code;
28535 }
28536 TPM_CC command_code = TPM_CC_FirmwareRead;
28537 std::string command_code_bytes;
28538 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28539 if (rc != TPM_RC_SUCCESS) {
28540 return rc;
28541 }
28542 std::string authorization_section_bytes;
28543 if (tag == TPM_ST_SESSIONS) {
28544 UINT32 parameter_section_size = buffer.size();
28545 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
28546 if (rc != TPM_RC_SUCCESS) {
28547 return rc;
28548 }
28549 if (parameter_section_size > buffer.size()) {
28550 return TPM_RC_INSUFFICIENT;
28551 }
28552 authorization_section_bytes = buffer.substr(parameter_section_size);
28553 // Keep the parameter section in |buffer|.
28554 buffer.erase(parameter_section_size);
28555 }
28556 std::unique_ptr<crypto::SecureHash> hash(
28557 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28558 hash->Update(response_code_bytes.data(), response_code_bytes.size());
28559 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28560 hash->Update(buffer.data(), buffer.size());
28561 std::string response_hash(32, 0);
28562 hash->Finish(std::data(response_hash), response_hash.size());
28563 if (tag == TPM_ST_SESSIONS) {
28564 if (!authorization_delegate)
28565 return TRUNKS_RC_AUTHORIZATION_FAILED;
28566 if (!authorization_delegate->CheckResponseAuthorization(
28567 response_hash, authorization_section_bytes)) {
28568 return TRUNKS_RC_AUTHORIZATION_FAILED;
28569 }
28570 }
28571 if (tag == TPM_ST_SESSIONS) {
28572 if (!authorization_delegate)
28573 return TRUNKS_RC_AUTHORIZATION_FAILED;
28574
28575 // Parse the encrypted parameter size.
28576 UINT16 size;
28577 std::string size_buffer = buffer.substr(0, 2);
28578 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
28579 return result;
28580 }
28581 if (buffer.size() < 2 + size) {
28582 return TPM_RC_INSUFFICIENT;
28583 }
28584
28585 // Decrypt just the parameter data, not the size.
28586 std::string decrypted_data = buffer.substr(2, size);
28587 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
28588 return TRUNKS_RC_ENCRYPTION_FAILED;
28589 }
28590 buffer.replace(2, size, decrypted_data);
28591 }
28592 std::string fu_data_bytes;
28593 rc = Parse_TPM2B_MAX_BUFFER(&buffer, fu_data, &fu_data_bytes);
28594 if (rc != TPM_RC_SUCCESS) {
28595 return rc;
28596 }
28597 return TPM_RC_SUCCESS;
28598 }
28599
FirmwareReadErrorCallback(Tpm::FirmwareReadResponse callback,TPM_RC response_code)28600 void FirmwareReadErrorCallback(Tpm::FirmwareReadResponse callback,
28601 TPM_RC response_code) {
28602 VLOG(1) << __func__;
28603 std::move(callback).Run(response_code, TPM2B_MAX_BUFFER());
28604 }
28605
FirmwareReadResponseParser(Tpm::FirmwareReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28606 void FirmwareReadResponseParser(Tpm::FirmwareReadResponse callback,
28607 AuthorizationDelegate* authorization_delegate,
28608 const std::string& response) {
28609 VLOG(1) << __func__;
28610 TPM2B_MAX_BUFFER fu_data;
28611 TPM_RC rc = Tpm::ParseResponse_FirmwareRead(response, &fu_data,
28612 authorization_delegate);
28613 if (rc != TPM_RC_SUCCESS) {
28614 base::OnceCallback<void(TPM_RC)> error_reporter =
28615 base::BindOnce(FirmwareReadErrorCallback, std::move(callback));
28616 std::move(error_reporter).Run(rc);
28617 return;
28618 }
28619 std::move(callback).Run(rc, fu_data);
28620 }
28621
FirmwareRead(const UINT32 & sequence_number,AuthorizationDelegate * authorization_delegate,FirmwareReadResponse callback)28622 void Tpm::FirmwareRead(const UINT32& sequence_number,
28623 AuthorizationDelegate* authorization_delegate,
28624 FirmwareReadResponse callback) {
28625 VLOG(1) << __func__;
28626 std::string command;
28627 TPM_RC rc = SerializeCommand_FirmwareRead(sequence_number, &command,
28628 authorization_delegate);
28629 if (rc != TPM_RC_SUCCESS) {
28630 base::OnceCallback<void(TPM_RC)> error_reporter =
28631 base::BindOnce(FirmwareReadErrorCallback, std::move(callback));
28632 std::move(error_reporter).Run(rc);
28633 return;
28634 }
28635 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
28636 FirmwareReadResponseParser, std::move(callback), authorization_delegate);
28637 transceiver_->SendCommand(command, std::move(parser));
28638 }
28639
FirmwareReadSync(const UINT32 & sequence_number,TPM2B_MAX_BUFFER * fu_data,AuthorizationDelegate * authorization_delegate)28640 TPM_RC Tpm::FirmwareReadSync(const UINT32& sequence_number,
28641 TPM2B_MAX_BUFFER* fu_data,
28642 AuthorizationDelegate* authorization_delegate) {
28643 VLOG(1) << __func__;
28644 std::string command;
28645 TPM_RC rc = SerializeCommand_FirmwareRead(sequence_number, &command,
28646 authorization_delegate);
28647 if (rc != TPM_RC_SUCCESS) {
28648 return rc;
28649 }
28650 std::string response = transceiver_->SendCommandAndWait(command);
28651 rc = ParseResponse_FirmwareRead(response, fu_data, authorization_delegate);
28652 return rc;
28653 }
28654
SerializeCommand_ContextSave(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28655 TPM_RC Tpm::SerializeCommand_ContextSave(
28656 const TPMI_DH_CONTEXT& save_handle,
28657 const std::string& save_handle_name,
28658 std::string* serialized_command,
28659 AuthorizationDelegate* authorization_delegate) {
28660 VLOG(3) << __func__;
28661 TPM_RC rc = TPM_RC_SUCCESS;
28662 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28663 UINT32 command_size = 10; // Header size.
28664 std::string handle_section_bytes;
28665 std::string parameter_section_bytes;
28666 TPM_CC command_code = TPM_CC_ContextSave;
28667 bool is_command_parameter_encryption_possible = false;
28668 bool is_response_parameter_encryption_possible = false;
28669 std::string command_code_bytes;
28670 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28671 if (rc != TPM_RC_SUCCESS) {
28672 return rc;
28673 }
28674 std::string save_handle_bytes;
28675 rc = Serialize_TPMI_DH_CONTEXT(save_handle, &save_handle_bytes);
28676 if (rc != TPM_RC_SUCCESS) {
28677 return rc;
28678 }
28679 std::unique_ptr<crypto::SecureHash> hash(
28680 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28681 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28682 hash->Update(save_handle_name.data(), save_handle_name.size());
28683 handle_section_bytes += save_handle_bytes;
28684 command_size += save_handle_bytes.size();
28685 std::string command_hash(32, 0);
28686 hash->Finish(std::data(command_hash), command_hash.size());
28687 std::string authorization_section_bytes;
28688 std::string authorization_size_bytes;
28689 if (authorization_delegate) {
28690 if (!authorization_delegate->GetCommandAuthorization(
28691 command_hash, is_command_parameter_encryption_possible,
28692 is_response_parameter_encryption_possible,
28693 &authorization_section_bytes)) {
28694 return TRUNKS_RC_AUTHORIZATION_FAILED;
28695 }
28696 if (!authorization_section_bytes.empty()) {
28697 tag = TPM_ST_SESSIONS;
28698 std::string tmp;
28699 rc = Serialize_UINT32(authorization_section_bytes.size(),
28700 &authorization_size_bytes);
28701 if (rc != TPM_RC_SUCCESS) {
28702 return rc;
28703 }
28704 command_size +=
28705 authorization_size_bytes.size() + authorization_section_bytes.size();
28706 }
28707 }
28708 std::string tag_bytes;
28709 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28710 if (rc != TPM_RC_SUCCESS) {
28711 return rc;
28712 }
28713 std::string command_size_bytes;
28714 rc = Serialize_UINT32(command_size, &command_size_bytes);
28715 if (rc != TPM_RC_SUCCESS) {
28716 return rc;
28717 }
28718 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28719 handle_section_bytes + authorization_size_bytes +
28720 authorization_section_bytes + parameter_section_bytes;
28721 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28722 VLOG(2) << "Command: "
28723 << base::HexEncode(serialized_command->data(),
28724 serialized_command->size());
28725 return TPM_RC_SUCCESS;
28726 }
28727
ParseResponse_ContextSave(const std::string & response,TPMS_CONTEXT * context,AuthorizationDelegate * authorization_delegate)28728 TPM_RC Tpm::ParseResponse_ContextSave(
28729 const std::string& response,
28730 TPMS_CONTEXT* context,
28731 AuthorizationDelegate* authorization_delegate) {
28732 VLOG(3) << __func__;
28733 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28734 TPM_RC rc = TPM_RC_SUCCESS;
28735 std::string buffer(response);
28736 TPM_ST tag;
28737 std::string tag_bytes;
28738 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28739 if (rc != TPM_RC_SUCCESS) {
28740 return rc;
28741 }
28742 UINT32 response_size;
28743 std::string response_size_bytes;
28744 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28745 if (rc != TPM_RC_SUCCESS) {
28746 return rc;
28747 }
28748 TPM_RC response_code;
28749 std::string response_code_bytes;
28750 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28751 if (rc != TPM_RC_SUCCESS) {
28752 return rc;
28753 }
28754 if (response_size != response.size()) {
28755 return TPM_RC_SIZE;
28756 }
28757 if (response_code != TPM_RC_SUCCESS) {
28758 return response_code;
28759 }
28760 TPM_CC command_code = TPM_CC_ContextSave;
28761 std::string command_code_bytes;
28762 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28763 if (rc != TPM_RC_SUCCESS) {
28764 return rc;
28765 }
28766 std::string authorization_section_bytes;
28767 if (tag == TPM_ST_SESSIONS) {
28768 UINT32 parameter_section_size = buffer.size();
28769 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
28770 if (rc != TPM_RC_SUCCESS) {
28771 return rc;
28772 }
28773 if (parameter_section_size > buffer.size()) {
28774 return TPM_RC_INSUFFICIENT;
28775 }
28776 authorization_section_bytes = buffer.substr(parameter_section_size);
28777 // Keep the parameter section in |buffer|.
28778 buffer.erase(parameter_section_size);
28779 }
28780 std::unique_ptr<crypto::SecureHash> hash(
28781 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28782 hash->Update(response_code_bytes.data(), response_code_bytes.size());
28783 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28784 hash->Update(buffer.data(), buffer.size());
28785 std::string response_hash(32, 0);
28786 hash->Finish(std::data(response_hash), response_hash.size());
28787 if (tag == TPM_ST_SESSIONS) {
28788 if (!authorization_delegate)
28789 return TRUNKS_RC_AUTHORIZATION_FAILED;
28790 if (!authorization_delegate->CheckResponseAuthorization(
28791 response_hash, authorization_section_bytes)) {
28792 return TRUNKS_RC_AUTHORIZATION_FAILED;
28793 }
28794 }
28795 std::string context_bytes;
28796 rc = Parse_TPMS_CONTEXT(&buffer, context, &context_bytes);
28797 if (rc != TPM_RC_SUCCESS) {
28798 return rc;
28799 }
28800 return TPM_RC_SUCCESS;
28801 }
28802
ContextSaveErrorCallback(Tpm::ContextSaveResponse callback,TPM_RC response_code)28803 void ContextSaveErrorCallback(Tpm::ContextSaveResponse callback,
28804 TPM_RC response_code) {
28805 VLOG(1) << __func__;
28806 std::move(callback).Run(response_code, TPMS_CONTEXT());
28807 }
28808
ContextSaveResponseParser(Tpm::ContextSaveResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28809 void ContextSaveResponseParser(Tpm::ContextSaveResponse callback,
28810 AuthorizationDelegate* authorization_delegate,
28811 const std::string& response) {
28812 VLOG(1) << __func__;
28813 TPMS_CONTEXT context;
28814 TPM_RC rc = Tpm::ParseResponse_ContextSave(response, &context,
28815 authorization_delegate);
28816 if (rc != TPM_RC_SUCCESS) {
28817 base::OnceCallback<void(TPM_RC)> error_reporter =
28818 base::BindOnce(ContextSaveErrorCallback, std::move(callback));
28819 std::move(error_reporter).Run(rc);
28820 return;
28821 }
28822 std::move(callback).Run(rc, context);
28823 }
28824
ContextSave(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,AuthorizationDelegate * authorization_delegate,ContextSaveResponse callback)28825 void Tpm::ContextSave(const TPMI_DH_CONTEXT& save_handle,
28826 const std::string& save_handle_name,
28827 AuthorizationDelegate* authorization_delegate,
28828 ContextSaveResponse callback) {
28829 VLOG(1) << __func__;
28830 std::string command;
28831 TPM_RC rc = SerializeCommand_ContextSave(save_handle, save_handle_name,
28832 &command, authorization_delegate);
28833 if (rc != TPM_RC_SUCCESS) {
28834 base::OnceCallback<void(TPM_RC)> error_reporter =
28835 base::BindOnce(ContextSaveErrorCallback, std::move(callback));
28836 std::move(error_reporter).Run(rc);
28837 return;
28838 }
28839 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
28840 ContextSaveResponseParser, std::move(callback), authorization_delegate);
28841 transceiver_->SendCommand(command, std::move(parser));
28842 }
28843
ContextSaveSync(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,TPMS_CONTEXT * context,AuthorizationDelegate * authorization_delegate)28844 TPM_RC Tpm::ContextSaveSync(const TPMI_DH_CONTEXT& save_handle,
28845 const std::string& save_handle_name,
28846 TPMS_CONTEXT* context,
28847 AuthorizationDelegate* authorization_delegate) {
28848 VLOG(1) << __func__;
28849 std::string command;
28850 TPM_RC rc = SerializeCommand_ContextSave(save_handle, save_handle_name,
28851 &command, authorization_delegate);
28852 if (rc != TPM_RC_SUCCESS) {
28853 return rc;
28854 }
28855 std::string response = transceiver_->SendCommandAndWait(command);
28856 rc = ParseResponse_ContextSave(response, context, authorization_delegate);
28857 return rc;
28858 }
28859
SerializeCommand_ContextLoad(const TPMS_CONTEXT & context,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28860 TPM_RC Tpm::SerializeCommand_ContextLoad(
28861 const TPMS_CONTEXT& context,
28862 std::string* serialized_command,
28863 AuthorizationDelegate* authorization_delegate) {
28864 VLOG(3) << __func__;
28865 TPM_RC rc = TPM_RC_SUCCESS;
28866 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28867 UINT32 command_size = 10; // Header size.
28868 std::string handle_section_bytes;
28869 std::string parameter_section_bytes;
28870 TPM_CC command_code = TPM_CC_ContextLoad;
28871 bool is_command_parameter_encryption_possible = false;
28872 bool is_response_parameter_encryption_possible = false;
28873 std::string command_code_bytes;
28874 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28875 if (rc != TPM_RC_SUCCESS) {
28876 return rc;
28877 }
28878 std::string context_bytes;
28879 rc = Serialize_TPMS_CONTEXT(context, &context_bytes);
28880 if (rc != TPM_RC_SUCCESS) {
28881 return rc;
28882 }
28883 std::unique_ptr<crypto::SecureHash> hash(
28884 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28885 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28886 hash->Update(context_bytes.data(), context_bytes.size());
28887 parameter_section_bytes += context_bytes;
28888 command_size += context_bytes.size();
28889 std::string command_hash(32, 0);
28890 hash->Finish(std::data(command_hash), command_hash.size());
28891 std::string authorization_section_bytes;
28892 std::string authorization_size_bytes;
28893 if (authorization_delegate) {
28894 if (!authorization_delegate->GetCommandAuthorization(
28895 command_hash, is_command_parameter_encryption_possible,
28896 is_response_parameter_encryption_possible,
28897 &authorization_section_bytes)) {
28898 return TRUNKS_RC_AUTHORIZATION_FAILED;
28899 }
28900 if (!authorization_section_bytes.empty()) {
28901 tag = TPM_ST_SESSIONS;
28902 std::string tmp;
28903 rc = Serialize_UINT32(authorization_section_bytes.size(),
28904 &authorization_size_bytes);
28905 if (rc != TPM_RC_SUCCESS) {
28906 return rc;
28907 }
28908 command_size +=
28909 authorization_size_bytes.size() + authorization_section_bytes.size();
28910 }
28911 }
28912 std::string tag_bytes;
28913 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28914 if (rc != TPM_RC_SUCCESS) {
28915 return rc;
28916 }
28917 std::string command_size_bytes;
28918 rc = Serialize_UINT32(command_size, &command_size_bytes);
28919 if (rc != TPM_RC_SUCCESS) {
28920 return rc;
28921 }
28922 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28923 handle_section_bytes + authorization_size_bytes +
28924 authorization_section_bytes + parameter_section_bytes;
28925 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28926 VLOG(2) << "Command: "
28927 << base::HexEncode(serialized_command->data(),
28928 serialized_command->size());
28929 return TPM_RC_SUCCESS;
28930 }
28931
ParseResponse_ContextLoad(const std::string & response,TPMI_DH_CONTEXT * loaded_handle,AuthorizationDelegate * authorization_delegate)28932 TPM_RC Tpm::ParseResponse_ContextLoad(
28933 const std::string& response,
28934 TPMI_DH_CONTEXT* loaded_handle,
28935 AuthorizationDelegate* authorization_delegate) {
28936 VLOG(3) << __func__;
28937 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28938 TPM_RC rc = TPM_RC_SUCCESS;
28939 std::string buffer(response);
28940 TPM_ST tag;
28941 std::string tag_bytes;
28942 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28943 if (rc != TPM_RC_SUCCESS) {
28944 return rc;
28945 }
28946 UINT32 response_size;
28947 std::string response_size_bytes;
28948 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28949 if (rc != TPM_RC_SUCCESS) {
28950 return rc;
28951 }
28952 TPM_RC response_code;
28953 std::string response_code_bytes;
28954 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28955 if (rc != TPM_RC_SUCCESS) {
28956 return rc;
28957 }
28958 if (response_size != response.size()) {
28959 return TPM_RC_SIZE;
28960 }
28961 if (response_code != TPM_RC_SUCCESS) {
28962 return response_code;
28963 }
28964 std::string loaded_handle_bytes;
28965 rc = Parse_TPMI_DH_CONTEXT(&buffer, loaded_handle, &loaded_handle_bytes);
28966 if (rc != TPM_RC_SUCCESS) {
28967 return rc;
28968 }
28969 TPM_CC command_code = TPM_CC_ContextLoad;
28970 std::string command_code_bytes;
28971 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28972 if (rc != TPM_RC_SUCCESS) {
28973 return rc;
28974 }
28975 std::string authorization_section_bytes;
28976 if (tag == TPM_ST_SESSIONS) {
28977 UINT32 parameter_section_size = buffer.size();
28978 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
28979 if (rc != TPM_RC_SUCCESS) {
28980 return rc;
28981 }
28982 if (parameter_section_size > buffer.size()) {
28983 return TPM_RC_INSUFFICIENT;
28984 }
28985 authorization_section_bytes = buffer.substr(parameter_section_size);
28986 // Keep the parameter section in |buffer|.
28987 buffer.erase(parameter_section_size);
28988 }
28989 std::unique_ptr<crypto::SecureHash> hash(
28990 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28991 hash->Update(response_code_bytes.data(), response_code_bytes.size());
28992 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28993 hash->Update(buffer.data(), buffer.size());
28994 std::string response_hash(32, 0);
28995 hash->Finish(std::data(response_hash), response_hash.size());
28996 if (tag == TPM_ST_SESSIONS) {
28997 if (!authorization_delegate)
28998 return TRUNKS_RC_AUTHORIZATION_FAILED;
28999 if (!authorization_delegate->CheckResponseAuthorization(
29000 response_hash, authorization_section_bytes)) {
29001 return TRUNKS_RC_AUTHORIZATION_FAILED;
29002 }
29003 }
29004 return TPM_RC_SUCCESS;
29005 }
29006
ContextLoadErrorCallback(Tpm::ContextLoadResponse callback,TPM_RC response_code)29007 void ContextLoadErrorCallback(Tpm::ContextLoadResponse callback,
29008 TPM_RC response_code) {
29009 VLOG(1) << __func__;
29010 std::move(callback).Run(response_code, TPMI_DH_CONTEXT());
29011 }
29012
ContextLoadResponseParser(Tpm::ContextLoadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29013 void ContextLoadResponseParser(Tpm::ContextLoadResponse callback,
29014 AuthorizationDelegate* authorization_delegate,
29015 const std::string& response) {
29016 VLOG(1) << __func__;
29017 TPMI_DH_CONTEXT loaded_handle;
29018 TPM_RC rc = Tpm::ParseResponse_ContextLoad(response, &loaded_handle,
29019 authorization_delegate);
29020 if (rc != TPM_RC_SUCCESS) {
29021 base::OnceCallback<void(TPM_RC)> error_reporter =
29022 base::BindOnce(ContextLoadErrorCallback, std::move(callback));
29023 std::move(error_reporter).Run(rc);
29024 return;
29025 }
29026 std::move(callback).Run(rc, loaded_handle);
29027 }
29028
ContextLoad(const TPMS_CONTEXT & context,AuthorizationDelegate * authorization_delegate,ContextLoadResponse callback)29029 void Tpm::ContextLoad(const TPMS_CONTEXT& context,
29030 AuthorizationDelegate* authorization_delegate,
29031 ContextLoadResponse callback) {
29032 VLOG(1) << __func__;
29033 std::string command;
29034 TPM_RC rc =
29035 SerializeCommand_ContextLoad(context, &command, authorization_delegate);
29036 if (rc != TPM_RC_SUCCESS) {
29037 base::OnceCallback<void(TPM_RC)> error_reporter =
29038 base::BindOnce(ContextLoadErrorCallback, std::move(callback));
29039 std::move(error_reporter).Run(rc);
29040 return;
29041 }
29042 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29043 ContextLoadResponseParser, std::move(callback), authorization_delegate);
29044 transceiver_->SendCommand(command, std::move(parser));
29045 }
29046
ContextLoadSync(const TPMS_CONTEXT & context,TPMI_DH_CONTEXT * loaded_handle,AuthorizationDelegate * authorization_delegate)29047 TPM_RC Tpm::ContextLoadSync(const TPMS_CONTEXT& context,
29048 TPMI_DH_CONTEXT* loaded_handle,
29049 AuthorizationDelegate* authorization_delegate) {
29050 VLOG(1) << __func__;
29051 std::string command;
29052 TPM_RC rc =
29053 SerializeCommand_ContextLoad(context, &command, authorization_delegate);
29054 if (rc != TPM_RC_SUCCESS) {
29055 return rc;
29056 }
29057 std::string response = transceiver_->SendCommandAndWait(command);
29058 rc = ParseResponse_ContextLoad(response, loaded_handle,
29059 authorization_delegate);
29060 return rc;
29061 }
29062
SerializeCommand_FlushContext(const TPMI_DH_CONTEXT & flush_handle,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29063 TPM_RC Tpm::SerializeCommand_FlushContext(
29064 const TPMI_DH_CONTEXT& flush_handle,
29065 std::string* serialized_command,
29066 AuthorizationDelegate* authorization_delegate) {
29067 VLOG(3) << __func__;
29068 TPM_RC rc = TPM_RC_SUCCESS;
29069 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29070 UINT32 command_size = 10; // Header size.
29071 std::string handle_section_bytes;
29072 std::string parameter_section_bytes;
29073 TPM_CC command_code = TPM_CC_FlushContext;
29074 bool is_command_parameter_encryption_possible = false;
29075 bool is_response_parameter_encryption_possible = false;
29076 std::string command_code_bytes;
29077 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29078 if (rc != TPM_RC_SUCCESS) {
29079 return rc;
29080 }
29081 std::string flush_handle_bytes;
29082 rc = Serialize_TPMI_DH_CONTEXT(flush_handle, &flush_handle_bytes);
29083 if (rc != TPM_RC_SUCCESS) {
29084 return rc;
29085 }
29086 std::unique_ptr<crypto::SecureHash> hash(
29087 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29088 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29089 hash->Update(flush_handle_bytes.data(), flush_handle_bytes.size());
29090 parameter_section_bytes += flush_handle_bytes;
29091 command_size += flush_handle_bytes.size();
29092 std::string command_hash(32, 0);
29093 hash->Finish(std::data(command_hash), command_hash.size());
29094 std::string authorization_section_bytes;
29095 std::string authorization_size_bytes;
29096 if (authorization_delegate) {
29097 if (!authorization_delegate->GetCommandAuthorization(
29098 command_hash, is_command_parameter_encryption_possible,
29099 is_response_parameter_encryption_possible,
29100 &authorization_section_bytes)) {
29101 return TRUNKS_RC_AUTHORIZATION_FAILED;
29102 }
29103 if (!authorization_section_bytes.empty()) {
29104 tag = TPM_ST_SESSIONS;
29105 std::string tmp;
29106 rc = Serialize_UINT32(authorization_section_bytes.size(),
29107 &authorization_size_bytes);
29108 if (rc != TPM_RC_SUCCESS) {
29109 return rc;
29110 }
29111 command_size +=
29112 authorization_size_bytes.size() + authorization_section_bytes.size();
29113 }
29114 }
29115 std::string tag_bytes;
29116 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29117 if (rc != TPM_RC_SUCCESS) {
29118 return rc;
29119 }
29120 std::string command_size_bytes;
29121 rc = Serialize_UINT32(command_size, &command_size_bytes);
29122 if (rc != TPM_RC_SUCCESS) {
29123 return rc;
29124 }
29125 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29126 handle_section_bytes + authorization_size_bytes +
29127 authorization_section_bytes + parameter_section_bytes;
29128 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29129 VLOG(2) << "Command: "
29130 << base::HexEncode(serialized_command->data(),
29131 serialized_command->size());
29132 return TPM_RC_SUCCESS;
29133 }
29134
ParseResponse_FlushContext(const std::string & response,AuthorizationDelegate * authorization_delegate)29135 TPM_RC Tpm::ParseResponse_FlushContext(
29136 const std::string& response,
29137 AuthorizationDelegate* authorization_delegate) {
29138 VLOG(3) << __func__;
29139 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29140 TPM_RC rc = TPM_RC_SUCCESS;
29141 std::string buffer(response);
29142 TPM_ST tag;
29143 std::string tag_bytes;
29144 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29145 if (rc != TPM_RC_SUCCESS) {
29146 return rc;
29147 }
29148 UINT32 response_size;
29149 std::string response_size_bytes;
29150 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29151 if (rc != TPM_RC_SUCCESS) {
29152 return rc;
29153 }
29154 TPM_RC response_code;
29155 std::string response_code_bytes;
29156 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29157 if (rc != TPM_RC_SUCCESS) {
29158 return rc;
29159 }
29160 if (response_size != response.size()) {
29161 return TPM_RC_SIZE;
29162 }
29163 if (response_code != TPM_RC_SUCCESS) {
29164 return response_code;
29165 }
29166 TPM_CC command_code = TPM_CC_FlushContext;
29167 std::string command_code_bytes;
29168 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29169 if (rc != TPM_RC_SUCCESS) {
29170 return rc;
29171 }
29172 std::string authorization_section_bytes;
29173 if (tag == TPM_ST_SESSIONS) {
29174 UINT32 parameter_section_size = buffer.size();
29175 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
29176 if (rc != TPM_RC_SUCCESS) {
29177 return rc;
29178 }
29179 if (parameter_section_size > buffer.size()) {
29180 return TPM_RC_INSUFFICIENT;
29181 }
29182 authorization_section_bytes = buffer.substr(parameter_section_size);
29183 // Keep the parameter section in |buffer|.
29184 buffer.erase(parameter_section_size);
29185 }
29186 std::unique_ptr<crypto::SecureHash> hash(
29187 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29188 hash->Update(response_code_bytes.data(), response_code_bytes.size());
29189 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29190 hash->Update(buffer.data(), buffer.size());
29191 std::string response_hash(32, 0);
29192 hash->Finish(std::data(response_hash), response_hash.size());
29193 if (tag == TPM_ST_SESSIONS) {
29194 if (!authorization_delegate)
29195 return TRUNKS_RC_AUTHORIZATION_FAILED;
29196 if (!authorization_delegate->CheckResponseAuthorization(
29197 response_hash, authorization_section_bytes)) {
29198 return TRUNKS_RC_AUTHORIZATION_FAILED;
29199 }
29200 }
29201 return TPM_RC_SUCCESS;
29202 }
29203
FlushContextErrorCallback(Tpm::FlushContextResponse callback,TPM_RC response_code)29204 void FlushContextErrorCallback(Tpm::FlushContextResponse callback,
29205 TPM_RC response_code) {
29206 VLOG(1) << __func__;
29207 std::move(callback).Run(response_code);
29208 }
29209
FlushContextResponseParser(Tpm::FlushContextResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29210 void FlushContextResponseParser(Tpm::FlushContextResponse callback,
29211 AuthorizationDelegate* authorization_delegate,
29212 const std::string& response) {
29213 VLOG(1) << __func__;
29214 TPM_RC rc = Tpm::ParseResponse_FlushContext(response, authorization_delegate);
29215 if (rc != TPM_RC_SUCCESS) {
29216 base::OnceCallback<void(TPM_RC)> error_reporter =
29217 base::BindOnce(FlushContextErrorCallback, std::move(callback));
29218 std::move(error_reporter).Run(rc);
29219 return;
29220 }
29221 std::move(callback).Run(rc);
29222 }
29223
FlushContext(const TPMI_DH_CONTEXT & flush_handle,AuthorizationDelegate * authorization_delegate,FlushContextResponse callback)29224 void Tpm::FlushContext(const TPMI_DH_CONTEXT& flush_handle,
29225 AuthorizationDelegate* authorization_delegate,
29226 FlushContextResponse callback) {
29227 VLOG(1) << __func__;
29228 std::string command;
29229 TPM_RC rc = SerializeCommand_FlushContext(flush_handle, &command,
29230 authorization_delegate);
29231 if (rc != TPM_RC_SUCCESS) {
29232 base::OnceCallback<void(TPM_RC)> error_reporter =
29233 base::BindOnce(FlushContextErrorCallback, std::move(callback));
29234 std::move(error_reporter).Run(rc);
29235 return;
29236 }
29237 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29238 FlushContextResponseParser, std::move(callback), authorization_delegate);
29239 transceiver_->SendCommand(command, std::move(parser));
29240 }
29241
FlushContextSync(const TPMI_DH_CONTEXT & flush_handle,AuthorizationDelegate * authorization_delegate)29242 TPM_RC Tpm::FlushContextSync(const TPMI_DH_CONTEXT& flush_handle,
29243 AuthorizationDelegate* authorization_delegate) {
29244 VLOG(1) << __func__;
29245 std::string command;
29246 TPM_RC rc = SerializeCommand_FlushContext(flush_handle, &command,
29247 authorization_delegate);
29248 if (rc != TPM_RC_SUCCESS) {
29249 return rc;
29250 }
29251 std::string response = transceiver_->SendCommandAndWait(command);
29252 rc = ParseResponse_FlushContext(response, authorization_delegate);
29253 return rc;
29254 }
29255
SerializeCommand_EvictControl(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_PERSISTENT & persistent_handle,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29256 TPM_RC Tpm::SerializeCommand_EvictControl(
29257 const TPMI_RH_PROVISION& auth,
29258 const std::string& auth_name,
29259 const TPMI_DH_OBJECT& object_handle,
29260 const std::string& object_handle_name,
29261 const TPMI_DH_PERSISTENT& persistent_handle,
29262 std::string* serialized_command,
29263 AuthorizationDelegate* authorization_delegate) {
29264 VLOG(3) << __func__;
29265 TPM_RC rc = TPM_RC_SUCCESS;
29266 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29267 UINT32 command_size = 10; // Header size.
29268 std::string handle_section_bytes;
29269 std::string parameter_section_bytes;
29270 TPM_CC command_code = TPM_CC_EvictControl;
29271 bool is_command_parameter_encryption_possible = false;
29272 bool is_response_parameter_encryption_possible = false;
29273 std::string command_code_bytes;
29274 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29275 if (rc != TPM_RC_SUCCESS) {
29276 return rc;
29277 }
29278 std::string auth_bytes;
29279 rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29280 if (rc != TPM_RC_SUCCESS) {
29281 return rc;
29282 }
29283 std::string object_handle_bytes;
29284 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
29285 if (rc != TPM_RC_SUCCESS) {
29286 return rc;
29287 }
29288 std::string persistent_handle_bytes;
29289 rc =
29290 Serialize_TPMI_DH_PERSISTENT(persistent_handle, &persistent_handle_bytes);
29291 if (rc != TPM_RC_SUCCESS) {
29292 return rc;
29293 }
29294 std::unique_ptr<crypto::SecureHash> hash(
29295 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29296 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29297 hash->Update(auth_name.data(), auth_name.size());
29298 handle_section_bytes += auth_bytes;
29299 command_size += auth_bytes.size();
29300 hash->Update(object_handle_name.data(), object_handle_name.size());
29301 handle_section_bytes += object_handle_bytes;
29302 command_size += object_handle_bytes.size();
29303 hash->Update(persistent_handle_bytes.data(), persistent_handle_bytes.size());
29304 parameter_section_bytes += persistent_handle_bytes;
29305 command_size += persistent_handle_bytes.size();
29306 std::string command_hash(32, 0);
29307 hash->Finish(std::data(command_hash), command_hash.size());
29308 std::string authorization_section_bytes;
29309 std::string authorization_size_bytes;
29310 if (authorization_delegate) {
29311 if (!authorization_delegate->GetCommandAuthorization(
29312 command_hash, is_command_parameter_encryption_possible,
29313 is_response_parameter_encryption_possible,
29314 &authorization_section_bytes)) {
29315 return TRUNKS_RC_AUTHORIZATION_FAILED;
29316 }
29317 if (!authorization_section_bytes.empty()) {
29318 tag = TPM_ST_SESSIONS;
29319 std::string tmp;
29320 rc = Serialize_UINT32(authorization_section_bytes.size(),
29321 &authorization_size_bytes);
29322 if (rc != TPM_RC_SUCCESS) {
29323 return rc;
29324 }
29325 command_size +=
29326 authorization_size_bytes.size() + authorization_section_bytes.size();
29327 }
29328 }
29329 std::string tag_bytes;
29330 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29331 if (rc != TPM_RC_SUCCESS) {
29332 return rc;
29333 }
29334 std::string command_size_bytes;
29335 rc = Serialize_UINT32(command_size, &command_size_bytes);
29336 if (rc != TPM_RC_SUCCESS) {
29337 return rc;
29338 }
29339 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29340 handle_section_bytes + authorization_size_bytes +
29341 authorization_section_bytes + parameter_section_bytes;
29342 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29343 VLOG(2) << "Command: "
29344 << base::HexEncode(serialized_command->data(),
29345 serialized_command->size());
29346 return TPM_RC_SUCCESS;
29347 }
29348
ParseResponse_EvictControl(const std::string & response,AuthorizationDelegate * authorization_delegate)29349 TPM_RC Tpm::ParseResponse_EvictControl(
29350 const std::string& response,
29351 AuthorizationDelegate* authorization_delegate) {
29352 VLOG(3) << __func__;
29353 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29354 TPM_RC rc = TPM_RC_SUCCESS;
29355 std::string buffer(response);
29356 TPM_ST tag;
29357 std::string tag_bytes;
29358 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29359 if (rc != TPM_RC_SUCCESS) {
29360 return rc;
29361 }
29362 UINT32 response_size;
29363 std::string response_size_bytes;
29364 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29365 if (rc != TPM_RC_SUCCESS) {
29366 return rc;
29367 }
29368 TPM_RC response_code;
29369 std::string response_code_bytes;
29370 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29371 if (rc != TPM_RC_SUCCESS) {
29372 return rc;
29373 }
29374 if (response_size != response.size()) {
29375 return TPM_RC_SIZE;
29376 }
29377 if (response_code != TPM_RC_SUCCESS) {
29378 return response_code;
29379 }
29380 TPM_CC command_code = TPM_CC_EvictControl;
29381 std::string command_code_bytes;
29382 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29383 if (rc != TPM_RC_SUCCESS) {
29384 return rc;
29385 }
29386 std::string authorization_section_bytes;
29387 if (tag == TPM_ST_SESSIONS) {
29388 UINT32 parameter_section_size = buffer.size();
29389 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
29390 if (rc != TPM_RC_SUCCESS) {
29391 return rc;
29392 }
29393 if (parameter_section_size > buffer.size()) {
29394 return TPM_RC_INSUFFICIENT;
29395 }
29396 authorization_section_bytes = buffer.substr(parameter_section_size);
29397 // Keep the parameter section in |buffer|.
29398 buffer.erase(parameter_section_size);
29399 }
29400 std::unique_ptr<crypto::SecureHash> hash(
29401 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29402 hash->Update(response_code_bytes.data(), response_code_bytes.size());
29403 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29404 hash->Update(buffer.data(), buffer.size());
29405 std::string response_hash(32, 0);
29406 hash->Finish(std::data(response_hash), response_hash.size());
29407 if (tag == TPM_ST_SESSIONS) {
29408 if (!authorization_delegate)
29409 return TRUNKS_RC_AUTHORIZATION_FAILED;
29410 if (!authorization_delegate->CheckResponseAuthorization(
29411 response_hash, authorization_section_bytes)) {
29412 return TRUNKS_RC_AUTHORIZATION_FAILED;
29413 }
29414 }
29415 return TPM_RC_SUCCESS;
29416 }
29417
EvictControlErrorCallback(Tpm::EvictControlResponse callback,TPM_RC response_code)29418 void EvictControlErrorCallback(Tpm::EvictControlResponse callback,
29419 TPM_RC response_code) {
29420 VLOG(1) << __func__;
29421 std::move(callback).Run(response_code);
29422 }
29423
EvictControlResponseParser(Tpm::EvictControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29424 void EvictControlResponseParser(Tpm::EvictControlResponse callback,
29425 AuthorizationDelegate* authorization_delegate,
29426 const std::string& response) {
29427 VLOG(1) << __func__;
29428 TPM_RC rc = Tpm::ParseResponse_EvictControl(response, authorization_delegate);
29429 if (rc != TPM_RC_SUCCESS) {
29430 base::OnceCallback<void(TPM_RC)> error_reporter =
29431 base::BindOnce(EvictControlErrorCallback, std::move(callback));
29432 std::move(error_reporter).Run(rc);
29433 return;
29434 }
29435 std::move(callback).Run(rc);
29436 }
29437
EvictControl(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_PERSISTENT & persistent_handle,AuthorizationDelegate * authorization_delegate,EvictControlResponse callback)29438 void Tpm::EvictControl(const TPMI_RH_PROVISION& auth,
29439 const std::string& auth_name,
29440 const TPMI_DH_OBJECT& object_handle,
29441 const std::string& object_handle_name,
29442 const TPMI_DH_PERSISTENT& persistent_handle,
29443 AuthorizationDelegate* authorization_delegate,
29444 EvictControlResponse callback) {
29445 VLOG(1) << __func__;
29446 std::string command;
29447 TPM_RC rc = SerializeCommand_EvictControl(
29448 auth, auth_name, object_handle, object_handle_name, persistent_handle,
29449 &command, authorization_delegate);
29450 if (rc != TPM_RC_SUCCESS) {
29451 base::OnceCallback<void(TPM_RC)> error_reporter =
29452 base::BindOnce(EvictControlErrorCallback, std::move(callback));
29453 std::move(error_reporter).Run(rc);
29454 return;
29455 }
29456 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29457 EvictControlResponseParser, std::move(callback), authorization_delegate);
29458 transceiver_->SendCommand(command, std::move(parser));
29459 }
29460
EvictControlSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_PERSISTENT & persistent_handle,AuthorizationDelegate * authorization_delegate)29461 TPM_RC Tpm::EvictControlSync(const TPMI_RH_PROVISION& auth,
29462 const std::string& auth_name,
29463 const TPMI_DH_OBJECT& object_handle,
29464 const std::string& object_handle_name,
29465 const TPMI_DH_PERSISTENT& persistent_handle,
29466 AuthorizationDelegate* authorization_delegate) {
29467 VLOG(1) << __func__;
29468 std::string command;
29469 TPM_RC rc = SerializeCommand_EvictControl(
29470 auth, auth_name, object_handle, object_handle_name, persistent_handle,
29471 &command, authorization_delegate);
29472 if (rc != TPM_RC_SUCCESS) {
29473 return rc;
29474 }
29475 std::string response = transceiver_->SendCommandAndWait(command);
29476 rc = ParseResponse_EvictControl(response, authorization_delegate);
29477 return rc;
29478 }
29479
SerializeCommand_ReadClock(std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29480 TPM_RC Tpm::SerializeCommand_ReadClock(
29481 std::string* serialized_command,
29482 AuthorizationDelegate* authorization_delegate) {
29483 VLOG(3) << __func__;
29484 TPM_RC rc = TPM_RC_SUCCESS;
29485 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29486 UINT32 command_size = 10; // Header size.
29487 std::string handle_section_bytes;
29488 std::string parameter_section_bytes;
29489 TPM_CC command_code = TPM_CC_ReadClock;
29490 bool is_command_parameter_encryption_possible = false;
29491 bool is_response_parameter_encryption_possible = false;
29492 std::string command_code_bytes;
29493 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29494 if (rc != TPM_RC_SUCCESS) {
29495 return rc;
29496 }
29497 std::unique_ptr<crypto::SecureHash> hash(
29498 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29499 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29500 std::string command_hash(32, 0);
29501 hash->Finish(std::data(command_hash), command_hash.size());
29502 std::string authorization_section_bytes;
29503 std::string authorization_size_bytes;
29504 if (authorization_delegate) {
29505 if (!authorization_delegate->GetCommandAuthorization(
29506 command_hash, is_command_parameter_encryption_possible,
29507 is_response_parameter_encryption_possible,
29508 &authorization_section_bytes)) {
29509 return TRUNKS_RC_AUTHORIZATION_FAILED;
29510 }
29511 if (!authorization_section_bytes.empty()) {
29512 tag = TPM_ST_SESSIONS;
29513 std::string tmp;
29514 rc = Serialize_UINT32(authorization_section_bytes.size(),
29515 &authorization_size_bytes);
29516 if (rc != TPM_RC_SUCCESS) {
29517 return rc;
29518 }
29519 command_size +=
29520 authorization_size_bytes.size() + authorization_section_bytes.size();
29521 }
29522 }
29523 std::string tag_bytes;
29524 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29525 if (rc != TPM_RC_SUCCESS) {
29526 return rc;
29527 }
29528 std::string command_size_bytes;
29529 rc = Serialize_UINT32(command_size, &command_size_bytes);
29530 if (rc != TPM_RC_SUCCESS) {
29531 return rc;
29532 }
29533 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29534 handle_section_bytes + authorization_size_bytes +
29535 authorization_section_bytes + parameter_section_bytes;
29536 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29537 VLOG(2) << "Command: "
29538 << base::HexEncode(serialized_command->data(),
29539 serialized_command->size());
29540 return TPM_RC_SUCCESS;
29541 }
29542
ParseResponse_ReadClock(const std::string & response,TPMS_TIME_INFO * current_time,AuthorizationDelegate * authorization_delegate)29543 TPM_RC Tpm::ParseResponse_ReadClock(
29544 const std::string& response,
29545 TPMS_TIME_INFO* current_time,
29546 AuthorizationDelegate* authorization_delegate) {
29547 VLOG(3) << __func__;
29548 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29549 TPM_RC rc = TPM_RC_SUCCESS;
29550 std::string buffer(response);
29551 TPM_ST tag;
29552 std::string tag_bytes;
29553 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29554 if (rc != TPM_RC_SUCCESS) {
29555 return rc;
29556 }
29557 UINT32 response_size;
29558 std::string response_size_bytes;
29559 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29560 if (rc != TPM_RC_SUCCESS) {
29561 return rc;
29562 }
29563 TPM_RC response_code;
29564 std::string response_code_bytes;
29565 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29566 if (rc != TPM_RC_SUCCESS) {
29567 return rc;
29568 }
29569 if (response_size != response.size()) {
29570 return TPM_RC_SIZE;
29571 }
29572 if (response_code != TPM_RC_SUCCESS) {
29573 return response_code;
29574 }
29575 TPM_CC command_code = TPM_CC_ReadClock;
29576 std::string command_code_bytes;
29577 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29578 if (rc != TPM_RC_SUCCESS) {
29579 return rc;
29580 }
29581 std::string authorization_section_bytes;
29582 if (tag == TPM_ST_SESSIONS) {
29583 UINT32 parameter_section_size = buffer.size();
29584 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
29585 if (rc != TPM_RC_SUCCESS) {
29586 return rc;
29587 }
29588 if (parameter_section_size > buffer.size()) {
29589 return TPM_RC_INSUFFICIENT;
29590 }
29591 authorization_section_bytes = buffer.substr(parameter_section_size);
29592 // Keep the parameter section in |buffer|.
29593 buffer.erase(parameter_section_size);
29594 }
29595 std::unique_ptr<crypto::SecureHash> hash(
29596 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29597 hash->Update(response_code_bytes.data(), response_code_bytes.size());
29598 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29599 hash->Update(buffer.data(), buffer.size());
29600 std::string response_hash(32, 0);
29601 hash->Finish(std::data(response_hash), response_hash.size());
29602 if (tag == TPM_ST_SESSIONS) {
29603 if (!authorization_delegate)
29604 return TRUNKS_RC_AUTHORIZATION_FAILED;
29605 if (!authorization_delegate->CheckResponseAuthorization(
29606 response_hash, authorization_section_bytes)) {
29607 return TRUNKS_RC_AUTHORIZATION_FAILED;
29608 }
29609 }
29610 std::string current_time_bytes;
29611 rc = Parse_TPMS_TIME_INFO(&buffer, current_time, ¤t_time_bytes);
29612 if (rc != TPM_RC_SUCCESS) {
29613 return rc;
29614 }
29615 return TPM_RC_SUCCESS;
29616 }
29617
ReadClockErrorCallback(Tpm::ReadClockResponse callback,TPM_RC response_code)29618 void ReadClockErrorCallback(Tpm::ReadClockResponse callback,
29619 TPM_RC response_code) {
29620 VLOG(1) << __func__;
29621 std::move(callback).Run(response_code, TPMS_TIME_INFO());
29622 }
29623
ReadClockResponseParser(Tpm::ReadClockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29624 void ReadClockResponseParser(Tpm::ReadClockResponse callback,
29625 AuthorizationDelegate* authorization_delegate,
29626 const std::string& response) {
29627 VLOG(1) << __func__;
29628 TPMS_TIME_INFO current_time;
29629 TPM_RC rc = Tpm::ParseResponse_ReadClock(response, ¤t_time,
29630 authorization_delegate);
29631 if (rc != TPM_RC_SUCCESS) {
29632 base::OnceCallback<void(TPM_RC)> error_reporter =
29633 base::BindOnce(ReadClockErrorCallback, std::move(callback));
29634 std::move(error_reporter).Run(rc);
29635 return;
29636 }
29637 std::move(callback).Run(rc, current_time);
29638 }
29639
ReadClock(AuthorizationDelegate * authorization_delegate,ReadClockResponse callback)29640 void Tpm::ReadClock(AuthorizationDelegate* authorization_delegate,
29641 ReadClockResponse callback) {
29642 VLOG(1) << __func__;
29643 std::string command;
29644 TPM_RC rc = SerializeCommand_ReadClock(&command, authorization_delegate);
29645 if (rc != TPM_RC_SUCCESS) {
29646 base::OnceCallback<void(TPM_RC)> error_reporter =
29647 base::BindOnce(ReadClockErrorCallback, std::move(callback));
29648 std::move(error_reporter).Run(rc);
29649 return;
29650 }
29651 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29652 ReadClockResponseParser, std::move(callback), authorization_delegate);
29653 transceiver_->SendCommand(command, std::move(parser));
29654 }
29655
ReadClockSync(TPMS_TIME_INFO * current_time,AuthorizationDelegate * authorization_delegate)29656 TPM_RC Tpm::ReadClockSync(TPMS_TIME_INFO* current_time,
29657 AuthorizationDelegate* authorization_delegate) {
29658 VLOG(1) << __func__;
29659 std::string command;
29660 TPM_RC rc = SerializeCommand_ReadClock(&command, authorization_delegate);
29661 if (rc != TPM_RC_SUCCESS) {
29662 return rc;
29663 }
29664 std::string response = transceiver_->SendCommandAndWait(command);
29665 rc = ParseResponse_ReadClock(response, current_time, authorization_delegate);
29666 return rc;
29667 }
29668
SerializeCommand_ClockSet(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29669 TPM_RC Tpm::SerializeCommand_ClockSet(
29670 const TPMI_RH_PROVISION& auth,
29671 const std::string& auth_name,
29672 const UINT64& new_time,
29673 std::string* serialized_command,
29674 AuthorizationDelegate* authorization_delegate) {
29675 VLOG(3) << __func__;
29676 TPM_RC rc = TPM_RC_SUCCESS;
29677 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29678 UINT32 command_size = 10; // Header size.
29679 std::string handle_section_bytes;
29680 std::string parameter_section_bytes;
29681 TPM_CC command_code = TPM_CC_ClockSet;
29682 bool is_command_parameter_encryption_possible = false;
29683 bool is_response_parameter_encryption_possible = false;
29684 std::string command_code_bytes;
29685 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29686 if (rc != TPM_RC_SUCCESS) {
29687 return rc;
29688 }
29689 std::string auth_bytes;
29690 rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29691 if (rc != TPM_RC_SUCCESS) {
29692 return rc;
29693 }
29694 std::string new_time_bytes;
29695 rc = Serialize_UINT64(new_time, &new_time_bytes);
29696 if (rc != TPM_RC_SUCCESS) {
29697 return rc;
29698 }
29699 std::unique_ptr<crypto::SecureHash> hash(
29700 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29701 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29702 hash->Update(auth_name.data(), auth_name.size());
29703 handle_section_bytes += auth_bytes;
29704 command_size += auth_bytes.size();
29705 hash->Update(new_time_bytes.data(), new_time_bytes.size());
29706 parameter_section_bytes += new_time_bytes;
29707 command_size += new_time_bytes.size();
29708 std::string command_hash(32, 0);
29709 hash->Finish(std::data(command_hash), command_hash.size());
29710 std::string authorization_section_bytes;
29711 std::string authorization_size_bytes;
29712 if (authorization_delegate) {
29713 if (!authorization_delegate->GetCommandAuthorization(
29714 command_hash, is_command_parameter_encryption_possible,
29715 is_response_parameter_encryption_possible,
29716 &authorization_section_bytes)) {
29717 return TRUNKS_RC_AUTHORIZATION_FAILED;
29718 }
29719 if (!authorization_section_bytes.empty()) {
29720 tag = TPM_ST_SESSIONS;
29721 std::string tmp;
29722 rc = Serialize_UINT32(authorization_section_bytes.size(),
29723 &authorization_size_bytes);
29724 if (rc != TPM_RC_SUCCESS) {
29725 return rc;
29726 }
29727 command_size +=
29728 authorization_size_bytes.size() + authorization_section_bytes.size();
29729 }
29730 }
29731 std::string tag_bytes;
29732 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29733 if (rc != TPM_RC_SUCCESS) {
29734 return rc;
29735 }
29736 std::string command_size_bytes;
29737 rc = Serialize_UINT32(command_size, &command_size_bytes);
29738 if (rc != TPM_RC_SUCCESS) {
29739 return rc;
29740 }
29741 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29742 handle_section_bytes + authorization_size_bytes +
29743 authorization_section_bytes + parameter_section_bytes;
29744 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29745 VLOG(2) << "Command: "
29746 << base::HexEncode(serialized_command->data(),
29747 serialized_command->size());
29748 return TPM_RC_SUCCESS;
29749 }
29750
ParseResponse_ClockSet(const std::string & response,AuthorizationDelegate * authorization_delegate)29751 TPM_RC Tpm::ParseResponse_ClockSet(
29752 const std::string& response,
29753 AuthorizationDelegate* authorization_delegate) {
29754 VLOG(3) << __func__;
29755 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29756 TPM_RC rc = TPM_RC_SUCCESS;
29757 std::string buffer(response);
29758 TPM_ST tag;
29759 std::string tag_bytes;
29760 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29761 if (rc != TPM_RC_SUCCESS) {
29762 return rc;
29763 }
29764 UINT32 response_size;
29765 std::string response_size_bytes;
29766 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29767 if (rc != TPM_RC_SUCCESS) {
29768 return rc;
29769 }
29770 TPM_RC response_code;
29771 std::string response_code_bytes;
29772 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29773 if (rc != TPM_RC_SUCCESS) {
29774 return rc;
29775 }
29776 if (response_size != response.size()) {
29777 return TPM_RC_SIZE;
29778 }
29779 if (response_code != TPM_RC_SUCCESS) {
29780 return response_code;
29781 }
29782 TPM_CC command_code = TPM_CC_ClockSet;
29783 std::string command_code_bytes;
29784 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29785 if (rc != TPM_RC_SUCCESS) {
29786 return rc;
29787 }
29788 std::string authorization_section_bytes;
29789 if (tag == TPM_ST_SESSIONS) {
29790 UINT32 parameter_section_size = buffer.size();
29791 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
29792 if (rc != TPM_RC_SUCCESS) {
29793 return rc;
29794 }
29795 if (parameter_section_size > buffer.size()) {
29796 return TPM_RC_INSUFFICIENT;
29797 }
29798 authorization_section_bytes = buffer.substr(parameter_section_size);
29799 // Keep the parameter section in |buffer|.
29800 buffer.erase(parameter_section_size);
29801 }
29802 std::unique_ptr<crypto::SecureHash> hash(
29803 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29804 hash->Update(response_code_bytes.data(), response_code_bytes.size());
29805 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29806 hash->Update(buffer.data(), buffer.size());
29807 std::string response_hash(32, 0);
29808 hash->Finish(std::data(response_hash), response_hash.size());
29809 if (tag == TPM_ST_SESSIONS) {
29810 if (!authorization_delegate)
29811 return TRUNKS_RC_AUTHORIZATION_FAILED;
29812 if (!authorization_delegate->CheckResponseAuthorization(
29813 response_hash, authorization_section_bytes)) {
29814 return TRUNKS_RC_AUTHORIZATION_FAILED;
29815 }
29816 }
29817 return TPM_RC_SUCCESS;
29818 }
29819
ClockSetErrorCallback(Tpm::ClockSetResponse callback,TPM_RC response_code)29820 void ClockSetErrorCallback(Tpm::ClockSetResponse callback,
29821 TPM_RC response_code) {
29822 VLOG(1) << __func__;
29823 std::move(callback).Run(response_code);
29824 }
29825
ClockSetResponseParser(Tpm::ClockSetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29826 void ClockSetResponseParser(Tpm::ClockSetResponse callback,
29827 AuthorizationDelegate* authorization_delegate,
29828 const std::string& response) {
29829 VLOG(1) << __func__;
29830 TPM_RC rc = Tpm::ParseResponse_ClockSet(response, authorization_delegate);
29831 if (rc != TPM_RC_SUCCESS) {
29832 base::OnceCallback<void(TPM_RC)> error_reporter =
29833 base::BindOnce(ClockSetErrorCallback, std::move(callback));
29834 std::move(error_reporter).Run(rc);
29835 return;
29836 }
29837 std::move(callback).Run(rc);
29838 }
29839
ClockSet(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,AuthorizationDelegate * authorization_delegate,ClockSetResponse callback)29840 void Tpm::ClockSet(const TPMI_RH_PROVISION& auth,
29841 const std::string& auth_name,
29842 const UINT64& new_time,
29843 AuthorizationDelegate* authorization_delegate,
29844 ClockSetResponse callback) {
29845 VLOG(1) << __func__;
29846 std::string command;
29847 TPM_RC rc = SerializeCommand_ClockSet(auth, auth_name, new_time, &command,
29848 authorization_delegate);
29849 if (rc != TPM_RC_SUCCESS) {
29850 base::OnceCallback<void(TPM_RC)> error_reporter =
29851 base::BindOnce(ClockSetErrorCallback, std::move(callback));
29852 std::move(error_reporter).Run(rc);
29853 return;
29854 }
29855 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29856 ClockSetResponseParser, std::move(callback), authorization_delegate);
29857 transceiver_->SendCommand(command, std::move(parser));
29858 }
29859
ClockSetSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,AuthorizationDelegate * authorization_delegate)29860 TPM_RC Tpm::ClockSetSync(const TPMI_RH_PROVISION& auth,
29861 const std::string& auth_name,
29862 const UINT64& new_time,
29863 AuthorizationDelegate* authorization_delegate) {
29864 VLOG(1) << __func__;
29865 std::string command;
29866 TPM_RC rc = SerializeCommand_ClockSet(auth, auth_name, new_time, &command,
29867 authorization_delegate);
29868 if (rc != TPM_RC_SUCCESS) {
29869 return rc;
29870 }
29871 std::string response = transceiver_->SendCommandAndWait(command);
29872 rc = ParseResponse_ClockSet(response, authorization_delegate);
29873 return rc;
29874 }
29875
SerializeCommand_ClockRateAdjust(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29876 TPM_RC Tpm::SerializeCommand_ClockRateAdjust(
29877 const TPMI_RH_PROVISION& auth,
29878 const std::string& auth_name,
29879 const TPM_CLOCK_ADJUST& rate_adjust,
29880 std::string* serialized_command,
29881 AuthorizationDelegate* authorization_delegate) {
29882 VLOG(3) << __func__;
29883 TPM_RC rc = TPM_RC_SUCCESS;
29884 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29885 UINT32 command_size = 10; // Header size.
29886 std::string handle_section_bytes;
29887 std::string parameter_section_bytes;
29888 TPM_CC command_code = TPM_CC_ClockRateAdjust;
29889 bool is_command_parameter_encryption_possible = false;
29890 bool is_response_parameter_encryption_possible = false;
29891 std::string command_code_bytes;
29892 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29893 if (rc != TPM_RC_SUCCESS) {
29894 return rc;
29895 }
29896 std::string auth_bytes;
29897 rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29898 if (rc != TPM_RC_SUCCESS) {
29899 return rc;
29900 }
29901 std::string rate_adjust_bytes;
29902 rc = Serialize_TPM_CLOCK_ADJUST(rate_adjust, &rate_adjust_bytes);
29903 if (rc != TPM_RC_SUCCESS) {
29904 return rc;
29905 }
29906 std::unique_ptr<crypto::SecureHash> hash(
29907 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29908 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29909 hash->Update(auth_name.data(), auth_name.size());
29910 handle_section_bytes += auth_bytes;
29911 command_size += auth_bytes.size();
29912 hash->Update(rate_adjust_bytes.data(), rate_adjust_bytes.size());
29913 parameter_section_bytes += rate_adjust_bytes;
29914 command_size += rate_adjust_bytes.size();
29915 std::string command_hash(32, 0);
29916 hash->Finish(std::data(command_hash), command_hash.size());
29917 std::string authorization_section_bytes;
29918 std::string authorization_size_bytes;
29919 if (authorization_delegate) {
29920 if (!authorization_delegate->GetCommandAuthorization(
29921 command_hash, is_command_parameter_encryption_possible,
29922 is_response_parameter_encryption_possible,
29923 &authorization_section_bytes)) {
29924 return TRUNKS_RC_AUTHORIZATION_FAILED;
29925 }
29926 if (!authorization_section_bytes.empty()) {
29927 tag = TPM_ST_SESSIONS;
29928 std::string tmp;
29929 rc = Serialize_UINT32(authorization_section_bytes.size(),
29930 &authorization_size_bytes);
29931 if (rc != TPM_RC_SUCCESS) {
29932 return rc;
29933 }
29934 command_size +=
29935 authorization_size_bytes.size() + authorization_section_bytes.size();
29936 }
29937 }
29938 std::string tag_bytes;
29939 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29940 if (rc != TPM_RC_SUCCESS) {
29941 return rc;
29942 }
29943 std::string command_size_bytes;
29944 rc = Serialize_UINT32(command_size, &command_size_bytes);
29945 if (rc != TPM_RC_SUCCESS) {
29946 return rc;
29947 }
29948 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29949 handle_section_bytes + authorization_size_bytes +
29950 authorization_section_bytes + parameter_section_bytes;
29951 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29952 VLOG(2) << "Command: "
29953 << base::HexEncode(serialized_command->data(),
29954 serialized_command->size());
29955 return TPM_RC_SUCCESS;
29956 }
29957
ParseResponse_ClockRateAdjust(const std::string & response,AuthorizationDelegate * authorization_delegate)29958 TPM_RC Tpm::ParseResponse_ClockRateAdjust(
29959 const std::string& response,
29960 AuthorizationDelegate* authorization_delegate) {
29961 VLOG(3) << __func__;
29962 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29963 TPM_RC rc = TPM_RC_SUCCESS;
29964 std::string buffer(response);
29965 TPM_ST tag;
29966 std::string tag_bytes;
29967 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29968 if (rc != TPM_RC_SUCCESS) {
29969 return rc;
29970 }
29971 UINT32 response_size;
29972 std::string response_size_bytes;
29973 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29974 if (rc != TPM_RC_SUCCESS) {
29975 return rc;
29976 }
29977 TPM_RC response_code;
29978 std::string response_code_bytes;
29979 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29980 if (rc != TPM_RC_SUCCESS) {
29981 return rc;
29982 }
29983 if (response_size != response.size()) {
29984 return TPM_RC_SIZE;
29985 }
29986 if (response_code != TPM_RC_SUCCESS) {
29987 return response_code;
29988 }
29989 TPM_CC command_code = TPM_CC_ClockRateAdjust;
29990 std::string command_code_bytes;
29991 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29992 if (rc != TPM_RC_SUCCESS) {
29993 return rc;
29994 }
29995 std::string authorization_section_bytes;
29996 if (tag == TPM_ST_SESSIONS) {
29997 UINT32 parameter_section_size = buffer.size();
29998 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
29999 if (rc != TPM_RC_SUCCESS) {
30000 return rc;
30001 }
30002 if (parameter_section_size > buffer.size()) {
30003 return TPM_RC_INSUFFICIENT;
30004 }
30005 authorization_section_bytes = buffer.substr(parameter_section_size);
30006 // Keep the parameter section in |buffer|.
30007 buffer.erase(parameter_section_size);
30008 }
30009 std::unique_ptr<crypto::SecureHash> hash(
30010 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30011 hash->Update(response_code_bytes.data(), response_code_bytes.size());
30012 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30013 hash->Update(buffer.data(), buffer.size());
30014 std::string response_hash(32, 0);
30015 hash->Finish(std::data(response_hash), response_hash.size());
30016 if (tag == TPM_ST_SESSIONS) {
30017 if (!authorization_delegate)
30018 return TRUNKS_RC_AUTHORIZATION_FAILED;
30019 if (!authorization_delegate->CheckResponseAuthorization(
30020 response_hash, authorization_section_bytes)) {
30021 return TRUNKS_RC_AUTHORIZATION_FAILED;
30022 }
30023 }
30024 return TPM_RC_SUCCESS;
30025 }
30026
ClockRateAdjustErrorCallback(Tpm::ClockRateAdjustResponse callback,TPM_RC response_code)30027 void ClockRateAdjustErrorCallback(Tpm::ClockRateAdjustResponse callback,
30028 TPM_RC response_code) {
30029 VLOG(1) << __func__;
30030 std::move(callback).Run(response_code);
30031 }
30032
ClockRateAdjustResponseParser(Tpm::ClockRateAdjustResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30033 void ClockRateAdjustResponseParser(
30034 Tpm::ClockRateAdjustResponse callback,
30035 AuthorizationDelegate* authorization_delegate,
30036 const std::string& response) {
30037 VLOG(1) << __func__;
30038 TPM_RC rc =
30039 Tpm::ParseResponse_ClockRateAdjust(response, authorization_delegate);
30040 if (rc != TPM_RC_SUCCESS) {
30041 base::OnceCallback<void(TPM_RC)> error_reporter =
30042 base::BindOnce(ClockRateAdjustErrorCallback, std::move(callback));
30043 std::move(error_reporter).Run(rc);
30044 return;
30045 }
30046 std::move(callback).Run(rc);
30047 }
30048
ClockRateAdjust(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,AuthorizationDelegate * authorization_delegate,ClockRateAdjustResponse callback)30049 void Tpm::ClockRateAdjust(const TPMI_RH_PROVISION& auth,
30050 const std::string& auth_name,
30051 const TPM_CLOCK_ADJUST& rate_adjust,
30052 AuthorizationDelegate* authorization_delegate,
30053 ClockRateAdjustResponse callback) {
30054 VLOG(1) << __func__;
30055 std::string command;
30056 TPM_RC rc = SerializeCommand_ClockRateAdjust(
30057 auth, auth_name, rate_adjust, &command, authorization_delegate);
30058 if (rc != TPM_RC_SUCCESS) {
30059 base::OnceCallback<void(TPM_RC)> error_reporter =
30060 base::BindOnce(ClockRateAdjustErrorCallback, std::move(callback));
30061 std::move(error_reporter).Run(rc);
30062 return;
30063 }
30064 base::OnceCallback<void(const std::string&)> parser =
30065 base::BindOnce(ClockRateAdjustResponseParser, std::move(callback),
30066 authorization_delegate);
30067 transceiver_->SendCommand(command, std::move(parser));
30068 }
30069
ClockRateAdjustSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,AuthorizationDelegate * authorization_delegate)30070 TPM_RC Tpm::ClockRateAdjustSync(const TPMI_RH_PROVISION& auth,
30071 const std::string& auth_name,
30072 const TPM_CLOCK_ADJUST& rate_adjust,
30073 AuthorizationDelegate* authorization_delegate) {
30074 VLOG(1) << __func__;
30075 std::string command;
30076 TPM_RC rc = SerializeCommand_ClockRateAdjust(
30077 auth, auth_name, rate_adjust, &command, authorization_delegate);
30078 if (rc != TPM_RC_SUCCESS) {
30079 return rc;
30080 }
30081 std::string response = transceiver_->SendCommandAndWait(command);
30082 rc = ParseResponse_ClockRateAdjust(response, authorization_delegate);
30083 return rc;
30084 }
30085
SerializeCommand_GetCapability(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30086 TPM_RC Tpm::SerializeCommand_GetCapability(
30087 const TPM_CAP& capability,
30088 const UINT32& property,
30089 const UINT32& property_count,
30090 std::string* serialized_command,
30091 AuthorizationDelegate* authorization_delegate) {
30092 VLOG(3) << __func__;
30093 TPM_RC rc = TPM_RC_SUCCESS;
30094 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30095 UINT32 command_size = 10; // Header size.
30096 std::string handle_section_bytes;
30097 std::string parameter_section_bytes;
30098 TPM_CC command_code = TPM_CC_GetCapability;
30099 bool is_command_parameter_encryption_possible = false;
30100 bool is_response_parameter_encryption_possible = false;
30101 std::string command_code_bytes;
30102 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30103 if (rc != TPM_RC_SUCCESS) {
30104 return rc;
30105 }
30106 std::string capability_bytes;
30107 rc = Serialize_TPM_CAP(capability, &capability_bytes);
30108 if (rc != TPM_RC_SUCCESS) {
30109 return rc;
30110 }
30111 std::string property_bytes;
30112 rc = Serialize_UINT32(property, &property_bytes);
30113 if (rc != TPM_RC_SUCCESS) {
30114 return rc;
30115 }
30116 std::string property_count_bytes;
30117 rc = Serialize_UINT32(property_count, &property_count_bytes);
30118 if (rc != TPM_RC_SUCCESS) {
30119 return rc;
30120 }
30121 std::unique_ptr<crypto::SecureHash> hash(
30122 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30123 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30124 hash->Update(capability_bytes.data(), capability_bytes.size());
30125 parameter_section_bytes += capability_bytes;
30126 command_size += capability_bytes.size();
30127 hash->Update(property_bytes.data(), property_bytes.size());
30128 parameter_section_bytes += property_bytes;
30129 command_size += property_bytes.size();
30130 hash->Update(property_count_bytes.data(), property_count_bytes.size());
30131 parameter_section_bytes += property_count_bytes;
30132 command_size += property_count_bytes.size();
30133 std::string command_hash(32, 0);
30134 hash->Finish(std::data(command_hash), command_hash.size());
30135 std::string authorization_section_bytes;
30136 std::string authorization_size_bytes;
30137 if (authorization_delegate) {
30138 if (!authorization_delegate->GetCommandAuthorization(
30139 command_hash, is_command_parameter_encryption_possible,
30140 is_response_parameter_encryption_possible,
30141 &authorization_section_bytes)) {
30142 return TRUNKS_RC_AUTHORIZATION_FAILED;
30143 }
30144 if (!authorization_section_bytes.empty()) {
30145 tag = TPM_ST_SESSIONS;
30146 std::string tmp;
30147 rc = Serialize_UINT32(authorization_section_bytes.size(),
30148 &authorization_size_bytes);
30149 if (rc != TPM_RC_SUCCESS) {
30150 return rc;
30151 }
30152 command_size +=
30153 authorization_size_bytes.size() + authorization_section_bytes.size();
30154 }
30155 }
30156 std::string tag_bytes;
30157 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30158 if (rc != TPM_RC_SUCCESS) {
30159 return rc;
30160 }
30161 std::string command_size_bytes;
30162 rc = Serialize_UINT32(command_size, &command_size_bytes);
30163 if (rc != TPM_RC_SUCCESS) {
30164 return rc;
30165 }
30166 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30167 handle_section_bytes + authorization_size_bytes +
30168 authorization_section_bytes + parameter_section_bytes;
30169 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30170 VLOG(2) << "Command: "
30171 << base::HexEncode(serialized_command->data(),
30172 serialized_command->size());
30173 return TPM_RC_SUCCESS;
30174 }
30175
ParseResponse_GetCapability(const std::string & response,TPMI_YES_NO * more_data,TPMS_CAPABILITY_DATA * capability_data,AuthorizationDelegate * authorization_delegate)30176 TPM_RC Tpm::ParseResponse_GetCapability(
30177 const std::string& response,
30178 TPMI_YES_NO* more_data,
30179 TPMS_CAPABILITY_DATA* capability_data,
30180 AuthorizationDelegate* authorization_delegate) {
30181 VLOG(3) << __func__;
30182 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30183 TPM_RC rc = TPM_RC_SUCCESS;
30184 std::string buffer(response);
30185 TPM_ST tag;
30186 std::string tag_bytes;
30187 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30188 if (rc != TPM_RC_SUCCESS) {
30189 return rc;
30190 }
30191 UINT32 response_size;
30192 std::string response_size_bytes;
30193 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30194 if (rc != TPM_RC_SUCCESS) {
30195 return rc;
30196 }
30197 TPM_RC response_code;
30198 std::string response_code_bytes;
30199 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30200 if (rc != TPM_RC_SUCCESS) {
30201 return rc;
30202 }
30203 if (response_size != response.size()) {
30204 return TPM_RC_SIZE;
30205 }
30206 if (response_code != TPM_RC_SUCCESS) {
30207 return response_code;
30208 }
30209 TPM_CC command_code = TPM_CC_GetCapability;
30210 std::string command_code_bytes;
30211 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30212 if (rc != TPM_RC_SUCCESS) {
30213 return rc;
30214 }
30215 std::string authorization_section_bytes;
30216 if (tag == TPM_ST_SESSIONS) {
30217 UINT32 parameter_section_size = buffer.size();
30218 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
30219 if (rc != TPM_RC_SUCCESS) {
30220 return rc;
30221 }
30222 if (parameter_section_size > buffer.size()) {
30223 return TPM_RC_INSUFFICIENT;
30224 }
30225 authorization_section_bytes = buffer.substr(parameter_section_size);
30226 // Keep the parameter section in |buffer|.
30227 buffer.erase(parameter_section_size);
30228 }
30229 std::unique_ptr<crypto::SecureHash> hash(
30230 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30231 hash->Update(response_code_bytes.data(), response_code_bytes.size());
30232 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30233 hash->Update(buffer.data(), buffer.size());
30234 std::string response_hash(32, 0);
30235 hash->Finish(std::data(response_hash), response_hash.size());
30236 if (tag == TPM_ST_SESSIONS) {
30237 if (!authorization_delegate)
30238 return TRUNKS_RC_AUTHORIZATION_FAILED;
30239 if (!authorization_delegate->CheckResponseAuthorization(
30240 response_hash, authorization_section_bytes)) {
30241 return TRUNKS_RC_AUTHORIZATION_FAILED;
30242 }
30243 }
30244 std::string more_data_bytes;
30245 rc = Parse_TPMI_YES_NO(&buffer, more_data, &more_data_bytes);
30246 if (rc != TPM_RC_SUCCESS) {
30247 return rc;
30248 }
30249 std::string capability_data_bytes;
30250 rc = Parse_TPMS_CAPABILITY_DATA(&buffer, capability_data,
30251 &capability_data_bytes);
30252 if (rc != TPM_RC_SUCCESS) {
30253 return rc;
30254 }
30255 return TPM_RC_SUCCESS;
30256 }
30257
GetCapabilityErrorCallback(Tpm::GetCapabilityResponse callback,TPM_RC response_code)30258 void GetCapabilityErrorCallback(Tpm::GetCapabilityResponse callback,
30259 TPM_RC response_code) {
30260 VLOG(1) << __func__;
30261 std::move(callback).Run(response_code, TPMI_YES_NO(), TPMS_CAPABILITY_DATA());
30262 }
30263
GetCapabilityResponseParser(Tpm::GetCapabilityResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30264 void GetCapabilityResponseParser(Tpm::GetCapabilityResponse callback,
30265 AuthorizationDelegate* authorization_delegate,
30266 const std::string& response) {
30267 VLOG(1) << __func__;
30268 TPMI_YES_NO more_data;
30269 TPMS_CAPABILITY_DATA capability_data;
30270 TPM_RC rc = Tpm::ParseResponse_GetCapability(
30271 response, &more_data, &capability_data, authorization_delegate);
30272 if (rc != TPM_RC_SUCCESS) {
30273 base::OnceCallback<void(TPM_RC)> error_reporter =
30274 base::BindOnce(GetCapabilityErrorCallback, std::move(callback));
30275 std::move(error_reporter).Run(rc);
30276 return;
30277 }
30278 std::move(callback).Run(rc, more_data, capability_data);
30279 }
30280
GetCapability(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,AuthorizationDelegate * authorization_delegate,GetCapabilityResponse callback)30281 void Tpm::GetCapability(const TPM_CAP& capability,
30282 const UINT32& property,
30283 const UINT32& property_count,
30284 AuthorizationDelegate* authorization_delegate,
30285 GetCapabilityResponse callback) {
30286 VLOG(1) << __func__;
30287 std::string command;
30288 TPM_RC rc = SerializeCommand_GetCapability(
30289 capability, property, property_count, &command, authorization_delegate);
30290 if (rc != TPM_RC_SUCCESS) {
30291 base::OnceCallback<void(TPM_RC)> error_reporter =
30292 base::BindOnce(GetCapabilityErrorCallback, std::move(callback));
30293 std::move(error_reporter).Run(rc);
30294 return;
30295 }
30296 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
30297 GetCapabilityResponseParser, std::move(callback), authorization_delegate);
30298 transceiver_->SendCommand(command, std::move(parser));
30299 }
30300
GetCapabilitySync(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,TPMI_YES_NO * more_data,TPMS_CAPABILITY_DATA * capability_data,AuthorizationDelegate * authorization_delegate)30301 TPM_RC Tpm::GetCapabilitySync(const TPM_CAP& capability,
30302 const UINT32& property,
30303 const UINT32& property_count,
30304 TPMI_YES_NO* more_data,
30305 TPMS_CAPABILITY_DATA* capability_data,
30306 AuthorizationDelegate* authorization_delegate) {
30307 VLOG(1) << __func__;
30308 std::string command;
30309 TPM_RC rc = SerializeCommand_GetCapability(
30310 capability, property, property_count, &command, authorization_delegate);
30311 if (rc != TPM_RC_SUCCESS) {
30312 return rc;
30313 }
30314 std::string response = transceiver_->SendCommandAndWait(command);
30315 rc = ParseResponse_GetCapability(response, more_data, capability_data,
30316 authorization_delegate);
30317 return rc;
30318 }
30319
SerializeCommand_TestParms(const TPMT_PUBLIC_PARMS & parameters,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30320 TPM_RC Tpm::SerializeCommand_TestParms(
30321 const TPMT_PUBLIC_PARMS& parameters,
30322 std::string* serialized_command,
30323 AuthorizationDelegate* authorization_delegate) {
30324 VLOG(3) << __func__;
30325 TPM_RC rc = TPM_RC_SUCCESS;
30326 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30327 UINT32 command_size = 10; // Header size.
30328 std::string handle_section_bytes;
30329 std::string parameter_section_bytes;
30330 TPM_CC command_code = TPM_CC_TestParms;
30331 bool is_command_parameter_encryption_possible = false;
30332 bool is_response_parameter_encryption_possible = false;
30333 std::string command_code_bytes;
30334 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30335 if (rc != TPM_RC_SUCCESS) {
30336 return rc;
30337 }
30338 std::string parameters_bytes;
30339 rc = Serialize_TPMT_PUBLIC_PARMS(parameters, ¶meters_bytes);
30340 if (rc != TPM_RC_SUCCESS) {
30341 return rc;
30342 }
30343 std::unique_ptr<crypto::SecureHash> hash(
30344 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30345 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30346 hash->Update(parameters_bytes.data(), parameters_bytes.size());
30347 parameter_section_bytes += parameters_bytes;
30348 command_size += parameters_bytes.size();
30349 std::string command_hash(32, 0);
30350 hash->Finish(std::data(command_hash), command_hash.size());
30351 std::string authorization_section_bytes;
30352 std::string authorization_size_bytes;
30353 if (authorization_delegate) {
30354 if (!authorization_delegate->GetCommandAuthorization(
30355 command_hash, is_command_parameter_encryption_possible,
30356 is_response_parameter_encryption_possible,
30357 &authorization_section_bytes)) {
30358 return TRUNKS_RC_AUTHORIZATION_FAILED;
30359 }
30360 if (!authorization_section_bytes.empty()) {
30361 tag = TPM_ST_SESSIONS;
30362 std::string tmp;
30363 rc = Serialize_UINT32(authorization_section_bytes.size(),
30364 &authorization_size_bytes);
30365 if (rc != TPM_RC_SUCCESS) {
30366 return rc;
30367 }
30368 command_size +=
30369 authorization_size_bytes.size() + authorization_section_bytes.size();
30370 }
30371 }
30372 std::string tag_bytes;
30373 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30374 if (rc != TPM_RC_SUCCESS) {
30375 return rc;
30376 }
30377 std::string command_size_bytes;
30378 rc = Serialize_UINT32(command_size, &command_size_bytes);
30379 if (rc != TPM_RC_SUCCESS) {
30380 return rc;
30381 }
30382 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30383 handle_section_bytes + authorization_size_bytes +
30384 authorization_section_bytes + parameter_section_bytes;
30385 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30386 VLOG(2) << "Command: "
30387 << base::HexEncode(serialized_command->data(),
30388 serialized_command->size());
30389 return TPM_RC_SUCCESS;
30390 }
30391
ParseResponse_TestParms(const std::string & response,AuthorizationDelegate * authorization_delegate)30392 TPM_RC Tpm::ParseResponse_TestParms(
30393 const std::string& response,
30394 AuthorizationDelegate* authorization_delegate) {
30395 VLOG(3) << __func__;
30396 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30397 TPM_RC rc = TPM_RC_SUCCESS;
30398 std::string buffer(response);
30399 TPM_ST tag;
30400 std::string tag_bytes;
30401 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30402 if (rc != TPM_RC_SUCCESS) {
30403 return rc;
30404 }
30405 UINT32 response_size;
30406 std::string response_size_bytes;
30407 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30408 if (rc != TPM_RC_SUCCESS) {
30409 return rc;
30410 }
30411 TPM_RC response_code;
30412 std::string response_code_bytes;
30413 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30414 if (rc != TPM_RC_SUCCESS) {
30415 return rc;
30416 }
30417 if (response_size != response.size()) {
30418 return TPM_RC_SIZE;
30419 }
30420 if (response_code != TPM_RC_SUCCESS) {
30421 return response_code;
30422 }
30423 TPM_CC command_code = TPM_CC_TestParms;
30424 std::string command_code_bytes;
30425 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30426 if (rc != TPM_RC_SUCCESS) {
30427 return rc;
30428 }
30429 std::string authorization_section_bytes;
30430 if (tag == TPM_ST_SESSIONS) {
30431 UINT32 parameter_section_size = buffer.size();
30432 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
30433 if (rc != TPM_RC_SUCCESS) {
30434 return rc;
30435 }
30436 if (parameter_section_size > buffer.size()) {
30437 return TPM_RC_INSUFFICIENT;
30438 }
30439 authorization_section_bytes = buffer.substr(parameter_section_size);
30440 // Keep the parameter section in |buffer|.
30441 buffer.erase(parameter_section_size);
30442 }
30443 std::unique_ptr<crypto::SecureHash> hash(
30444 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30445 hash->Update(response_code_bytes.data(), response_code_bytes.size());
30446 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30447 hash->Update(buffer.data(), buffer.size());
30448 std::string response_hash(32, 0);
30449 hash->Finish(std::data(response_hash), response_hash.size());
30450 if (tag == TPM_ST_SESSIONS) {
30451 if (!authorization_delegate)
30452 return TRUNKS_RC_AUTHORIZATION_FAILED;
30453 if (!authorization_delegate->CheckResponseAuthorization(
30454 response_hash, authorization_section_bytes)) {
30455 return TRUNKS_RC_AUTHORIZATION_FAILED;
30456 }
30457 }
30458 return TPM_RC_SUCCESS;
30459 }
30460
TestParmsErrorCallback(Tpm::TestParmsResponse callback,TPM_RC response_code)30461 void TestParmsErrorCallback(Tpm::TestParmsResponse callback,
30462 TPM_RC response_code) {
30463 VLOG(1) << __func__;
30464 std::move(callback).Run(response_code);
30465 }
30466
TestParmsResponseParser(Tpm::TestParmsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30467 void TestParmsResponseParser(Tpm::TestParmsResponse callback,
30468 AuthorizationDelegate* authorization_delegate,
30469 const std::string& response) {
30470 VLOG(1) << __func__;
30471 TPM_RC rc = Tpm::ParseResponse_TestParms(response, authorization_delegate);
30472 if (rc != TPM_RC_SUCCESS) {
30473 base::OnceCallback<void(TPM_RC)> error_reporter =
30474 base::BindOnce(TestParmsErrorCallback, std::move(callback));
30475 std::move(error_reporter).Run(rc);
30476 return;
30477 }
30478 std::move(callback).Run(rc);
30479 }
30480
TestParms(const TPMT_PUBLIC_PARMS & parameters,AuthorizationDelegate * authorization_delegate,TestParmsResponse callback)30481 void Tpm::TestParms(const TPMT_PUBLIC_PARMS& parameters,
30482 AuthorizationDelegate* authorization_delegate,
30483 TestParmsResponse callback) {
30484 VLOG(1) << __func__;
30485 std::string command;
30486 TPM_RC rc =
30487 SerializeCommand_TestParms(parameters, &command, authorization_delegate);
30488 if (rc != TPM_RC_SUCCESS) {
30489 base::OnceCallback<void(TPM_RC)> error_reporter =
30490 base::BindOnce(TestParmsErrorCallback, std::move(callback));
30491 std::move(error_reporter).Run(rc);
30492 return;
30493 }
30494 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
30495 TestParmsResponseParser, std::move(callback), authorization_delegate);
30496 transceiver_->SendCommand(command, std::move(parser));
30497 }
30498
TestParmsSync(const TPMT_PUBLIC_PARMS & parameters,AuthorizationDelegate * authorization_delegate)30499 TPM_RC Tpm::TestParmsSync(const TPMT_PUBLIC_PARMS& parameters,
30500 AuthorizationDelegate* authorization_delegate) {
30501 VLOG(1) << __func__;
30502 std::string command;
30503 TPM_RC rc =
30504 SerializeCommand_TestParms(parameters, &command, authorization_delegate);
30505 if (rc != TPM_RC_SUCCESS) {
30506 return rc;
30507 }
30508 std::string response = transceiver_->SendCommandAndWait(command);
30509 rc = ParseResponse_TestParms(response, authorization_delegate);
30510 return rc;
30511 }
30512
SerializeCommand_NV_DefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & auth,const TPM2B_NV_PUBLIC & public_info,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30513 TPM_RC Tpm::SerializeCommand_NV_DefineSpace(
30514 const TPMI_RH_PROVISION& auth_handle,
30515 const std::string& auth_handle_name,
30516 const TPM2B_AUTH& auth,
30517 const TPM2B_NV_PUBLIC& public_info,
30518 std::string* serialized_command,
30519 AuthorizationDelegate* authorization_delegate) {
30520 VLOG(3) << __func__;
30521 TPM_RC rc = TPM_RC_SUCCESS;
30522 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30523 UINT32 command_size = 10; // Header size.
30524 std::string handle_section_bytes;
30525 std::string parameter_section_bytes;
30526 TPM_CC command_code = TPM_CC_NV_DefineSpace;
30527 bool is_command_parameter_encryption_possible = true;
30528 bool is_response_parameter_encryption_possible = false;
30529 std::string command_code_bytes;
30530 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30531 if (rc != TPM_RC_SUCCESS) {
30532 return rc;
30533 }
30534 std::string auth_handle_bytes;
30535 rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
30536 if (rc != TPM_RC_SUCCESS) {
30537 return rc;
30538 }
30539 std::string auth_bytes;
30540 rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
30541 if (rc != TPM_RC_SUCCESS) {
30542 return rc;
30543 }
30544 std::string public_info_bytes;
30545 rc = Serialize_TPM2B_NV_PUBLIC(public_info, &public_info_bytes);
30546 if (rc != TPM_RC_SUCCESS) {
30547 return rc;
30548 }
30549 if (authorization_delegate) {
30550 // Encrypt just the parameter data, not the size.
30551 std::string tmp = auth_bytes.substr(2);
30552 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
30553 return TRUNKS_RC_ENCRYPTION_FAILED;
30554 }
30555 auth_bytes.replace(2, std::string::npos, tmp);
30556 }
30557 std::unique_ptr<crypto::SecureHash> hash(
30558 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30559 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30560 hash->Update(auth_handle_name.data(), auth_handle_name.size());
30561 handle_section_bytes += auth_handle_bytes;
30562 command_size += auth_handle_bytes.size();
30563 hash->Update(auth_bytes.data(), auth_bytes.size());
30564 parameter_section_bytes += auth_bytes;
30565 command_size += auth_bytes.size();
30566 hash->Update(public_info_bytes.data(), public_info_bytes.size());
30567 parameter_section_bytes += public_info_bytes;
30568 command_size += public_info_bytes.size();
30569 std::string command_hash(32, 0);
30570 hash->Finish(std::data(command_hash), command_hash.size());
30571 std::string authorization_section_bytes;
30572 std::string authorization_size_bytes;
30573 if (authorization_delegate) {
30574 if (!authorization_delegate->GetCommandAuthorization(
30575 command_hash, is_command_parameter_encryption_possible,
30576 is_response_parameter_encryption_possible,
30577 &authorization_section_bytes)) {
30578 return TRUNKS_RC_AUTHORIZATION_FAILED;
30579 }
30580 if (!authorization_section_bytes.empty()) {
30581 tag = TPM_ST_SESSIONS;
30582 std::string tmp;
30583 rc = Serialize_UINT32(authorization_section_bytes.size(),
30584 &authorization_size_bytes);
30585 if (rc != TPM_RC_SUCCESS) {
30586 return rc;
30587 }
30588 command_size +=
30589 authorization_size_bytes.size() + authorization_section_bytes.size();
30590 }
30591 }
30592 std::string tag_bytes;
30593 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30594 if (rc != TPM_RC_SUCCESS) {
30595 return rc;
30596 }
30597 std::string command_size_bytes;
30598 rc = Serialize_UINT32(command_size, &command_size_bytes);
30599 if (rc != TPM_RC_SUCCESS) {
30600 return rc;
30601 }
30602 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30603 handle_section_bytes + authorization_size_bytes +
30604 authorization_section_bytes + parameter_section_bytes;
30605 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30606 VLOG(2) << "Command: "
30607 << base::HexEncode(serialized_command->data(),
30608 serialized_command->size());
30609 return TPM_RC_SUCCESS;
30610 }
30611
ParseResponse_NV_DefineSpace(const std::string & response,AuthorizationDelegate * authorization_delegate)30612 TPM_RC Tpm::ParseResponse_NV_DefineSpace(
30613 const std::string& response,
30614 AuthorizationDelegate* authorization_delegate) {
30615 VLOG(3) << __func__;
30616 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30617 TPM_RC rc = TPM_RC_SUCCESS;
30618 std::string buffer(response);
30619 TPM_ST tag;
30620 std::string tag_bytes;
30621 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30622 if (rc != TPM_RC_SUCCESS) {
30623 return rc;
30624 }
30625 UINT32 response_size;
30626 std::string response_size_bytes;
30627 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30628 if (rc != TPM_RC_SUCCESS) {
30629 return rc;
30630 }
30631 TPM_RC response_code;
30632 std::string response_code_bytes;
30633 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30634 if (rc != TPM_RC_SUCCESS) {
30635 return rc;
30636 }
30637 if (response_size != response.size()) {
30638 return TPM_RC_SIZE;
30639 }
30640 if (response_code != TPM_RC_SUCCESS) {
30641 return response_code;
30642 }
30643 TPM_CC command_code = TPM_CC_NV_DefineSpace;
30644 std::string command_code_bytes;
30645 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30646 if (rc != TPM_RC_SUCCESS) {
30647 return rc;
30648 }
30649 std::string authorization_section_bytes;
30650 if (tag == TPM_ST_SESSIONS) {
30651 UINT32 parameter_section_size = buffer.size();
30652 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
30653 if (rc != TPM_RC_SUCCESS) {
30654 return rc;
30655 }
30656 if (parameter_section_size > buffer.size()) {
30657 return TPM_RC_INSUFFICIENT;
30658 }
30659 authorization_section_bytes = buffer.substr(parameter_section_size);
30660 // Keep the parameter section in |buffer|.
30661 buffer.erase(parameter_section_size);
30662 }
30663 std::unique_ptr<crypto::SecureHash> hash(
30664 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30665 hash->Update(response_code_bytes.data(), response_code_bytes.size());
30666 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30667 hash->Update(buffer.data(), buffer.size());
30668 std::string response_hash(32, 0);
30669 hash->Finish(std::data(response_hash), response_hash.size());
30670 if (tag == TPM_ST_SESSIONS) {
30671 if (!authorization_delegate)
30672 return TRUNKS_RC_AUTHORIZATION_FAILED;
30673 if (!authorization_delegate->CheckResponseAuthorization(
30674 response_hash, authorization_section_bytes)) {
30675 return TRUNKS_RC_AUTHORIZATION_FAILED;
30676 }
30677 }
30678 return TPM_RC_SUCCESS;
30679 }
30680
NV_DefineSpaceErrorCallback(Tpm::NV_DefineSpaceResponse callback,TPM_RC response_code)30681 void NV_DefineSpaceErrorCallback(Tpm::NV_DefineSpaceResponse callback,
30682 TPM_RC response_code) {
30683 VLOG(1) << __func__;
30684 std::move(callback).Run(response_code);
30685 }
30686
NV_DefineSpaceResponseParser(Tpm::NV_DefineSpaceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30687 void NV_DefineSpaceResponseParser(Tpm::NV_DefineSpaceResponse callback,
30688 AuthorizationDelegate* authorization_delegate,
30689 const std::string& response) {
30690 VLOG(1) << __func__;
30691 TPM_RC rc =
30692 Tpm::ParseResponse_NV_DefineSpace(response, authorization_delegate);
30693 if (rc != TPM_RC_SUCCESS) {
30694 base::OnceCallback<void(TPM_RC)> error_reporter =
30695 base::BindOnce(NV_DefineSpaceErrorCallback, std::move(callback));
30696 std::move(error_reporter).Run(rc);
30697 return;
30698 }
30699 std::move(callback).Run(rc);
30700 }
30701
NV_DefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & auth,const TPM2B_NV_PUBLIC & public_info,AuthorizationDelegate * authorization_delegate,NV_DefineSpaceResponse callback)30702 void Tpm::NV_DefineSpace(const TPMI_RH_PROVISION& auth_handle,
30703 const std::string& auth_handle_name,
30704 const TPM2B_AUTH& auth,
30705 const TPM2B_NV_PUBLIC& public_info,
30706 AuthorizationDelegate* authorization_delegate,
30707 NV_DefineSpaceResponse callback) {
30708 VLOG(1) << __func__;
30709 std::string command;
30710 TPM_RC rc = SerializeCommand_NV_DefineSpace(auth_handle, auth_handle_name,
30711 auth, public_info, &command,
30712 authorization_delegate);
30713 if (rc != TPM_RC_SUCCESS) {
30714 base::OnceCallback<void(TPM_RC)> error_reporter =
30715 base::BindOnce(NV_DefineSpaceErrorCallback, std::move(callback));
30716 std::move(error_reporter).Run(rc);
30717 return;
30718 }
30719 base::OnceCallback<void(const std::string&)> parser =
30720 base::BindOnce(NV_DefineSpaceResponseParser, std::move(callback),
30721 authorization_delegate);
30722 transceiver_->SendCommand(command, std::move(parser));
30723 }
30724
NV_DefineSpaceSync(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & auth,const TPM2B_NV_PUBLIC & public_info,AuthorizationDelegate * authorization_delegate)30725 TPM_RC Tpm::NV_DefineSpaceSync(const TPMI_RH_PROVISION& auth_handle,
30726 const std::string& auth_handle_name,
30727 const TPM2B_AUTH& auth,
30728 const TPM2B_NV_PUBLIC& public_info,
30729 AuthorizationDelegate* authorization_delegate) {
30730 VLOG(1) << __func__;
30731 std::string command;
30732 TPM_RC rc = SerializeCommand_NV_DefineSpace(auth_handle, auth_handle_name,
30733 auth, public_info, &command,
30734 authorization_delegate);
30735 if (rc != TPM_RC_SUCCESS) {
30736 return rc;
30737 }
30738 std::string response = transceiver_->SendCommandAndWait(command);
30739 rc = ParseResponse_NV_DefineSpace(response, authorization_delegate);
30740 return rc;
30741 }
30742
SerializeCommand_NV_UndefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30743 TPM_RC Tpm::SerializeCommand_NV_UndefineSpace(
30744 const TPMI_RH_PROVISION& auth_handle,
30745 const std::string& auth_handle_name,
30746 const TPMI_RH_NV_INDEX& nv_index,
30747 const std::string& nv_index_name,
30748 std::string* serialized_command,
30749 AuthorizationDelegate* authorization_delegate) {
30750 VLOG(3) << __func__;
30751 TPM_RC rc = TPM_RC_SUCCESS;
30752 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30753 UINT32 command_size = 10; // Header size.
30754 std::string handle_section_bytes;
30755 std::string parameter_section_bytes;
30756 TPM_CC command_code = TPM_CC_NV_UndefineSpace;
30757 bool is_command_parameter_encryption_possible = false;
30758 bool is_response_parameter_encryption_possible = false;
30759 std::string command_code_bytes;
30760 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30761 if (rc != TPM_RC_SUCCESS) {
30762 return rc;
30763 }
30764 std::string auth_handle_bytes;
30765 rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
30766 if (rc != TPM_RC_SUCCESS) {
30767 return rc;
30768 }
30769 std::string nv_index_bytes;
30770 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30771 if (rc != TPM_RC_SUCCESS) {
30772 return rc;
30773 }
30774 std::unique_ptr<crypto::SecureHash> hash(
30775 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30776 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30777 hash->Update(auth_handle_name.data(), auth_handle_name.size());
30778 handle_section_bytes += auth_handle_bytes;
30779 command_size += auth_handle_bytes.size();
30780 hash->Update(nv_index_name.data(), nv_index_name.size());
30781 handle_section_bytes += nv_index_bytes;
30782 command_size += nv_index_bytes.size();
30783 std::string command_hash(32, 0);
30784 hash->Finish(std::data(command_hash), command_hash.size());
30785 std::string authorization_section_bytes;
30786 std::string authorization_size_bytes;
30787 if (authorization_delegate) {
30788 if (!authorization_delegate->GetCommandAuthorization(
30789 command_hash, is_command_parameter_encryption_possible,
30790 is_response_parameter_encryption_possible,
30791 &authorization_section_bytes)) {
30792 return TRUNKS_RC_AUTHORIZATION_FAILED;
30793 }
30794 if (!authorization_section_bytes.empty()) {
30795 tag = TPM_ST_SESSIONS;
30796 std::string tmp;
30797 rc = Serialize_UINT32(authorization_section_bytes.size(),
30798 &authorization_size_bytes);
30799 if (rc != TPM_RC_SUCCESS) {
30800 return rc;
30801 }
30802 command_size +=
30803 authorization_size_bytes.size() + authorization_section_bytes.size();
30804 }
30805 }
30806 std::string tag_bytes;
30807 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30808 if (rc != TPM_RC_SUCCESS) {
30809 return rc;
30810 }
30811 std::string command_size_bytes;
30812 rc = Serialize_UINT32(command_size, &command_size_bytes);
30813 if (rc != TPM_RC_SUCCESS) {
30814 return rc;
30815 }
30816 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30817 handle_section_bytes + authorization_size_bytes +
30818 authorization_section_bytes + parameter_section_bytes;
30819 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30820 VLOG(2) << "Command: "
30821 << base::HexEncode(serialized_command->data(),
30822 serialized_command->size());
30823 return TPM_RC_SUCCESS;
30824 }
30825
ParseResponse_NV_UndefineSpace(const std::string & response,AuthorizationDelegate * authorization_delegate)30826 TPM_RC Tpm::ParseResponse_NV_UndefineSpace(
30827 const std::string& response,
30828 AuthorizationDelegate* authorization_delegate) {
30829 VLOG(3) << __func__;
30830 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30831 TPM_RC rc = TPM_RC_SUCCESS;
30832 std::string buffer(response);
30833 TPM_ST tag;
30834 std::string tag_bytes;
30835 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30836 if (rc != TPM_RC_SUCCESS) {
30837 return rc;
30838 }
30839 UINT32 response_size;
30840 std::string response_size_bytes;
30841 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30842 if (rc != TPM_RC_SUCCESS) {
30843 return rc;
30844 }
30845 TPM_RC response_code;
30846 std::string response_code_bytes;
30847 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30848 if (rc != TPM_RC_SUCCESS) {
30849 return rc;
30850 }
30851 if (response_size != response.size()) {
30852 return TPM_RC_SIZE;
30853 }
30854 if (response_code != TPM_RC_SUCCESS) {
30855 return response_code;
30856 }
30857 TPM_CC command_code = TPM_CC_NV_UndefineSpace;
30858 std::string command_code_bytes;
30859 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30860 if (rc != TPM_RC_SUCCESS) {
30861 return rc;
30862 }
30863 std::string authorization_section_bytes;
30864 if (tag == TPM_ST_SESSIONS) {
30865 UINT32 parameter_section_size = buffer.size();
30866 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
30867 if (rc != TPM_RC_SUCCESS) {
30868 return rc;
30869 }
30870 if (parameter_section_size > buffer.size()) {
30871 return TPM_RC_INSUFFICIENT;
30872 }
30873 authorization_section_bytes = buffer.substr(parameter_section_size);
30874 // Keep the parameter section in |buffer|.
30875 buffer.erase(parameter_section_size);
30876 }
30877 std::unique_ptr<crypto::SecureHash> hash(
30878 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30879 hash->Update(response_code_bytes.data(), response_code_bytes.size());
30880 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30881 hash->Update(buffer.data(), buffer.size());
30882 std::string response_hash(32, 0);
30883 hash->Finish(std::data(response_hash), response_hash.size());
30884 if (tag == TPM_ST_SESSIONS) {
30885 if (!authorization_delegate)
30886 return TRUNKS_RC_AUTHORIZATION_FAILED;
30887 if (!authorization_delegate->CheckResponseAuthorization(
30888 response_hash, authorization_section_bytes)) {
30889 return TRUNKS_RC_AUTHORIZATION_FAILED;
30890 }
30891 }
30892 return TPM_RC_SUCCESS;
30893 }
30894
NV_UndefineSpaceErrorCallback(Tpm::NV_UndefineSpaceResponse callback,TPM_RC response_code)30895 void NV_UndefineSpaceErrorCallback(Tpm::NV_UndefineSpaceResponse callback,
30896 TPM_RC response_code) {
30897 VLOG(1) << __func__;
30898 std::move(callback).Run(response_code);
30899 }
30900
NV_UndefineSpaceResponseParser(Tpm::NV_UndefineSpaceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30901 void NV_UndefineSpaceResponseParser(
30902 Tpm::NV_UndefineSpaceResponse callback,
30903 AuthorizationDelegate* authorization_delegate,
30904 const std::string& response) {
30905 VLOG(1) << __func__;
30906 TPM_RC rc =
30907 Tpm::ParseResponse_NV_UndefineSpace(response, authorization_delegate);
30908 if (rc != TPM_RC_SUCCESS) {
30909 base::OnceCallback<void(TPM_RC)> error_reporter =
30910 base::BindOnce(NV_UndefineSpaceErrorCallback, std::move(callback));
30911 std::move(error_reporter).Run(rc);
30912 return;
30913 }
30914 std::move(callback).Run(rc);
30915 }
30916
NV_UndefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_UndefineSpaceResponse callback)30917 void Tpm::NV_UndefineSpace(const TPMI_RH_PROVISION& auth_handle,
30918 const std::string& auth_handle_name,
30919 const TPMI_RH_NV_INDEX& nv_index,
30920 const std::string& nv_index_name,
30921 AuthorizationDelegate* authorization_delegate,
30922 NV_UndefineSpaceResponse callback) {
30923 VLOG(1) << __func__;
30924 std::string command;
30925 TPM_RC rc = SerializeCommand_NV_UndefineSpace(
30926 auth_handle, auth_handle_name, nv_index, nv_index_name, &command,
30927 authorization_delegate);
30928 if (rc != TPM_RC_SUCCESS) {
30929 base::OnceCallback<void(TPM_RC)> error_reporter =
30930 base::BindOnce(NV_UndefineSpaceErrorCallback, std::move(callback));
30931 std::move(error_reporter).Run(rc);
30932 return;
30933 }
30934 base::OnceCallback<void(const std::string&)> parser =
30935 base::BindOnce(NV_UndefineSpaceResponseParser, std::move(callback),
30936 authorization_delegate);
30937 transceiver_->SendCommand(command, std::move(parser));
30938 }
30939
NV_UndefineSpaceSync(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)30940 TPM_RC Tpm::NV_UndefineSpaceSync(
30941 const TPMI_RH_PROVISION& auth_handle,
30942 const std::string& auth_handle_name,
30943 const TPMI_RH_NV_INDEX& nv_index,
30944 const std::string& nv_index_name,
30945 AuthorizationDelegate* authorization_delegate) {
30946 VLOG(1) << __func__;
30947 std::string command;
30948 TPM_RC rc = SerializeCommand_NV_UndefineSpace(
30949 auth_handle, auth_handle_name, nv_index, nv_index_name, &command,
30950 authorization_delegate);
30951 if (rc != TPM_RC_SUCCESS) {
30952 return rc;
30953 }
30954 std::string response = transceiver_->SendCommandAndWait(command);
30955 rc = ParseResponse_NV_UndefineSpace(response, authorization_delegate);
30956 return rc;
30957 }
30958
SerializeCommand_NV_UndefineSpaceSpecial(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_RH_PLATFORM & platform,const std::string & platform_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30959 TPM_RC Tpm::SerializeCommand_NV_UndefineSpaceSpecial(
30960 const TPMI_RH_NV_INDEX& nv_index,
30961 const std::string& nv_index_name,
30962 const TPMI_RH_PLATFORM& platform,
30963 const std::string& platform_name,
30964 std::string* serialized_command,
30965 AuthorizationDelegate* authorization_delegate) {
30966 VLOG(3) << __func__;
30967 TPM_RC rc = TPM_RC_SUCCESS;
30968 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30969 UINT32 command_size = 10; // Header size.
30970 std::string handle_section_bytes;
30971 std::string parameter_section_bytes;
30972 TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial;
30973 bool is_command_parameter_encryption_possible = false;
30974 bool is_response_parameter_encryption_possible = false;
30975 std::string command_code_bytes;
30976 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30977 if (rc != TPM_RC_SUCCESS) {
30978 return rc;
30979 }
30980 std::string nv_index_bytes;
30981 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30982 if (rc != TPM_RC_SUCCESS) {
30983 return rc;
30984 }
30985 std::string platform_bytes;
30986 rc = Serialize_TPMI_RH_PLATFORM(platform, &platform_bytes);
30987 if (rc != TPM_RC_SUCCESS) {
30988 return rc;
30989 }
30990 std::unique_ptr<crypto::SecureHash> hash(
30991 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30992 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30993 hash->Update(nv_index_name.data(), nv_index_name.size());
30994 handle_section_bytes += nv_index_bytes;
30995 command_size += nv_index_bytes.size();
30996 hash->Update(platform_name.data(), platform_name.size());
30997 handle_section_bytes += platform_bytes;
30998 command_size += platform_bytes.size();
30999 std::string command_hash(32, 0);
31000 hash->Finish(std::data(command_hash), command_hash.size());
31001 std::string authorization_section_bytes;
31002 std::string authorization_size_bytes;
31003 if (authorization_delegate) {
31004 if (!authorization_delegate->GetCommandAuthorization(
31005 command_hash, is_command_parameter_encryption_possible,
31006 is_response_parameter_encryption_possible,
31007 &authorization_section_bytes)) {
31008 return TRUNKS_RC_AUTHORIZATION_FAILED;
31009 }
31010 if (!authorization_section_bytes.empty()) {
31011 tag = TPM_ST_SESSIONS;
31012 std::string tmp;
31013 rc = Serialize_UINT32(authorization_section_bytes.size(),
31014 &authorization_size_bytes);
31015 if (rc != TPM_RC_SUCCESS) {
31016 return rc;
31017 }
31018 command_size +=
31019 authorization_size_bytes.size() + authorization_section_bytes.size();
31020 }
31021 }
31022 std::string tag_bytes;
31023 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31024 if (rc != TPM_RC_SUCCESS) {
31025 return rc;
31026 }
31027 std::string command_size_bytes;
31028 rc = Serialize_UINT32(command_size, &command_size_bytes);
31029 if (rc != TPM_RC_SUCCESS) {
31030 return rc;
31031 }
31032 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31033 handle_section_bytes + authorization_size_bytes +
31034 authorization_section_bytes + parameter_section_bytes;
31035 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31036 VLOG(2) << "Command: "
31037 << base::HexEncode(serialized_command->data(),
31038 serialized_command->size());
31039 return TPM_RC_SUCCESS;
31040 }
31041
ParseResponse_NV_UndefineSpaceSpecial(const std::string & response,AuthorizationDelegate * authorization_delegate)31042 TPM_RC Tpm::ParseResponse_NV_UndefineSpaceSpecial(
31043 const std::string& response,
31044 AuthorizationDelegate* authorization_delegate) {
31045 VLOG(3) << __func__;
31046 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31047 TPM_RC rc = TPM_RC_SUCCESS;
31048 std::string buffer(response);
31049 TPM_ST tag;
31050 std::string tag_bytes;
31051 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31052 if (rc != TPM_RC_SUCCESS) {
31053 return rc;
31054 }
31055 UINT32 response_size;
31056 std::string response_size_bytes;
31057 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31058 if (rc != TPM_RC_SUCCESS) {
31059 return rc;
31060 }
31061 TPM_RC response_code;
31062 std::string response_code_bytes;
31063 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31064 if (rc != TPM_RC_SUCCESS) {
31065 return rc;
31066 }
31067 if (response_size != response.size()) {
31068 return TPM_RC_SIZE;
31069 }
31070 if (response_code != TPM_RC_SUCCESS) {
31071 return response_code;
31072 }
31073 TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial;
31074 std::string command_code_bytes;
31075 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31076 if (rc != TPM_RC_SUCCESS) {
31077 return rc;
31078 }
31079 std::string authorization_section_bytes;
31080 if (tag == TPM_ST_SESSIONS) {
31081 UINT32 parameter_section_size = buffer.size();
31082 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
31083 if (rc != TPM_RC_SUCCESS) {
31084 return rc;
31085 }
31086 if (parameter_section_size > buffer.size()) {
31087 return TPM_RC_INSUFFICIENT;
31088 }
31089 authorization_section_bytes = buffer.substr(parameter_section_size);
31090 // Keep the parameter section in |buffer|.
31091 buffer.erase(parameter_section_size);
31092 }
31093 std::unique_ptr<crypto::SecureHash> hash(
31094 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31095 hash->Update(response_code_bytes.data(), response_code_bytes.size());
31096 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31097 hash->Update(buffer.data(), buffer.size());
31098 std::string response_hash(32, 0);
31099 hash->Finish(std::data(response_hash), response_hash.size());
31100 if (tag == TPM_ST_SESSIONS) {
31101 if (!authorization_delegate)
31102 return TRUNKS_RC_AUTHORIZATION_FAILED;
31103 if (!authorization_delegate->CheckResponseAuthorization(
31104 response_hash, authorization_section_bytes)) {
31105 return TRUNKS_RC_AUTHORIZATION_FAILED;
31106 }
31107 }
31108 return TPM_RC_SUCCESS;
31109 }
31110
NV_UndefineSpaceSpecialErrorCallback(Tpm::NV_UndefineSpaceSpecialResponse callback,TPM_RC response_code)31111 void NV_UndefineSpaceSpecialErrorCallback(
31112 Tpm::NV_UndefineSpaceSpecialResponse callback, TPM_RC response_code) {
31113 VLOG(1) << __func__;
31114 std::move(callback).Run(response_code);
31115 }
31116
NV_UndefineSpaceSpecialResponseParser(Tpm::NV_UndefineSpaceSpecialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31117 void NV_UndefineSpaceSpecialResponseParser(
31118 Tpm::NV_UndefineSpaceSpecialResponse callback,
31119 AuthorizationDelegate* authorization_delegate,
31120 const std::string& response) {
31121 VLOG(1) << __func__;
31122 TPM_RC rc = Tpm::ParseResponse_NV_UndefineSpaceSpecial(
31123 response, authorization_delegate);
31124 if (rc != TPM_RC_SUCCESS) {
31125 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
31126 NV_UndefineSpaceSpecialErrorCallback, std::move(callback));
31127 std::move(error_reporter).Run(rc);
31128 return;
31129 }
31130 std::move(callback).Run(rc);
31131 }
31132
NV_UndefineSpaceSpecial(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_RH_PLATFORM & platform,const std::string & platform_name,AuthorizationDelegate * authorization_delegate,NV_UndefineSpaceSpecialResponse callback)31133 void Tpm::NV_UndefineSpaceSpecial(const TPMI_RH_NV_INDEX& nv_index,
31134 const std::string& nv_index_name,
31135 const TPMI_RH_PLATFORM& platform,
31136 const std::string& platform_name,
31137 AuthorizationDelegate* authorization_delegate,
31138 NV_UndefineSpaceSpecialResponse callback) {
31139 VLOG(1) << __func__;
31140 std::string command;
31141 TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial(
31142 nv_index, nv_index_name, platform, platform_name, &command,
31143 authorization_delegate);
31144 if (rc != TPM_RC_SUCCESS) {
31145 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
31146 NV_UndefineSpaceSpecialErrorCallback, std::move(callback));
31147 std::move(error_reporter).Run(rc);
31148 return;
31149 }
31150 base::OnceCallback<void(const std::string&)> parser =
31151 base::BindOnce(NV_UndefineSpaceSpecialResponseParser, std::move(callback),
31152 authorization_delegate);
31153 transceiver_->SendCommand(command, std::move(parser));
31154 }
31155
NV_UndefineSpaceSpecialSync(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_RH_PLATFORM & platform,const std::string & platform_name,AuthorizationDelegate * authorization_delegate)31156 TPM_RC Tpm::NV_UndefineSpaceSpecialSync(
31157 const TPMI_RH_NV_INDEX& nv_index,
31158 const std::string& nv_index_name,
31159 const TPMI_RH_PLATFORM& platform,
31160 const std::string& platform_name,
31161 AuthorizationDelegate* authorization_delegate) {
31162 VLOG(1) << __func__;
31163 std::string command;
31164 TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial(
31165 nv_index, nv_index_name, platform, platform_name, &command,
31166 authorization_delegate);
31167 if (rc != TPM_RC_SUCCESS) {
31168 return rc;
31169 }
31170 std::string response = transceiver_->SendCommandAndWait(command);
31171 rc = ParseResponse_NV_UndefineSpaceSpecial(response, authorization_delegate);
31172 return rc;
31173 }
31174
SerializeCommand_NV_ReadPublic(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31175 TPM_RC Tpm::SerializeCommand_NV_ReadPublic(
31176 const TPMI_RH_NV_INDEX& nv_index,
31177 const std::string& nv_index_name,
31178 std::string* serialized_command,
31179 AuthorizationDelegate* authorization_delegate) {
31180 VLOG(3) << __func__;
31181 TPM_RC rc = TPM_RC_SUCCESS;
31182 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31183 UINT32 command_size = 10; // Header size.
31184 std::string handle_section_bytes;
31185 std::string parameter_section_bytes;
31186 TPM_CC command_code = TPM_CC_NV_ReadPublic;
31187 bool is_command_parameter_encryption_possible = false;
31188 bool is_response_parameter_encryption_possible = true;
31189 std::string command_code_bytes;
31190 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31191 if (rc != TPM_RC_SUCCESS) {
31192 return rc;
31193 }
31194 std::string nv_index_bytes;
31195 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31196 if (rc != TPM_RC_SUCCESS) {
31197 return rc;
31198 }
31199 std::unique_ptr<crypto::SecureHash> hash(
31200 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31201 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31202 hash->Update(nv_index_name.data(), nv_index_name.size());
31203 handle_section_bytes += nv_index_bytes;
31204 command_size += nv_index_bytes.size();
31205 std::string command_hash(32, 0);
31206 hash->Finish(std::data(command_hash), command_hash.size());
31207 std::string authorization_section_bytes;
31208 std::string authorization_size_bytes;
31209 if (authorization_delegate) {
31210 if (!authorization_delegate->GetCommandAuthorization(
31211 command_hash, is_command_parameter_encryption_possible,
31212 is_response_parameter_encryption_possible,
31213 &authorization_section_bytes)) {
31214 return TRUNKS_RC_AUTHORIZATION_FAILED;
31215 }
31216 if (!authorization_section_bytes.empty()) {
31217 tag = TPM_ST_SESSIONS;
31218 std::string tmp;
31219 rc = Serialize_UINT32(authorization_section_bytes.size(),
31220 &authorization_size_bytes);
31221 if (rc != TPM_RC_SUCCESS) {
31222 return rc;
31223 }
31224 command_size +=
31225 authorization_size_bytes.size() + authorization_section_bytes.size();
31226 }
31227 }
31228 std::string tag_bytes;
31229 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31230 if (rc != TPM_RC_SUCCESS) {
31231 return rc;
31232 }
31233 std::string command_size_bytes;
31234 rc = Serialize_UINT32(command_size, &command_size_bytes);
31235 if (rc != TPM_RC_SUCCESS) {
31236 return rc;
31237 }
31238 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31239 handle_section_bytes + authorization_size_bytes +
31240 authorization_section_bytes + parameter_section_bytes;
31241 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31242 VLOG(2) << "Command: "
31243 << base::HexEncode(serialized_command->data(),
31244 serialized_command->size());
31245 return TPM_RC_SUCCESS;
31246 }
31247
ParseResponse_NV_ReadPublic(const std::string & response,TPM2B_NV_PUBLIC * nv_public,TPM2B_NAME * nv_name,AuthorizationDelegate * authorization_delegate)31248 TPM_RC Tpm::ParseResponse_NV_ReadPublic(
31249 const std::string& response,
31250 TPM2B_NV_PUBLIC* nv_public,
31251 TPM2B_NAME* nv_name,
31252 AuthorizationDelegate* authorization_delegate) {
31253 VLOG(3) << __func__;
31254 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31255 TPM_RC rc = TPM_RC_SUCCESS;
31256 std::string buffer(response);
31257 TPM_ST tag;
31258 std::string tag_bytes;
31259 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31260 if (rc != TPM_RC_SUCCESS) {
31261 return rc;
31262 }
31263 UINT32 response_size;
31264 std::string response_size_bytes;
31265 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31266 if (rc != TPM_RC_SUCCESS) {
31267 return rc;
31268 }
31269 TPM_RC response_code;
31270 std::string response_code_bytes;
31271 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31272 if (rc != TPM_RC_SUCCESS) {
31273 return rc;
31274 }
31275 if (response_size != response.size()) {
31276 return TPM_RC_SIZE;
31277 }
31278 if (response_code != TPM_RC_SUCCESS) {
31279 return response_code;
31280 }
31281 TPM_CC command_code = TPM_CC_NV_ReadPublic;
31282 std::string command_code_bytes;
31283 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31284 if (rc != TPM_RC_SUCCESS) {
31285 return rc;
31286 }
31287 std::string authorization_section_bytes;
31288 if (tag == TPM_ST_SESSIONS) {
31289 UINT32 parameter_section_size = buffer.size();
31290 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
31291 if (rc != TPM_RC_SUCCESS) {
31292 return rc;
31293 }
31294 if (parameter_section_size > buffer.size()) {
31295 return TPM_RC_INSUFFICIENT;
31296 }
31297 authorization_section_bytes = buffer.substr(parameter_section_size);
31298 // Keep the parameter section in |buffer|.
31299 buffer.erase(parameter_section_size);
31300 }
31301 std::unique_ptr<crypto::SecureHash> hash(
31302 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31303 hash->Update(response_code_bytes.data(), response_code_bytes.size());
31304 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31305 hash->Update(buffer.data(), buffer.size());
31306 std::string response_hash(32, 0);
31307 hash->Finish(std::data(response_hash), response_hash.size());
31308 if (tag == TPM_ST_SESSIONS) {
31309 if (!authorization_delegate)
31310 return TRUNKS_RC_AUTHORIZATION_FAILED;
31311 if (!authorization_delegate->CheckResponseAuthorization(
31312 response_hash, authorization_section_bytes)) {
31313 return TRUNKS_RC_AUTHORIZATION_FAILED;
31314 }
31315 }
31316 if (tag == TPM_ST_SESSIONS) {
31317 if (!authorization_delegate)
31318 return TRUNKS_RC_AUTHORIZATION_FAILED;
31319
31320 // Parse the encrypted parameter size.
31321 UINT16 size;
31322 std::string size_buffer = buffer.substr(0, 2);
31323 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
31324 return result;
31325 }
31326 if (buffer.size() < 2 + size) {
31327 return TPM_RC_INSUFFICIENT;
31328 }
31329
31330 // Decrypt just the parameter data, not the size.
31331 std::string decrypted_data = buffer.substr(2, size);
31332 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
31333 return TRUNKS_RC_ENCRYPTION_FAILED;
31334 }
31335 buffer.replace(2, size, decrypted_data);
31336 }
31337 std::string nv_public_bytes;
31338 rc = Parse_TPM2B_NV_PUBLIC(&buffer, nv_public, &nv_public_bytes);
31339 if (rc != TPM_RC_SUCCESS) {
31340 return rc;
31341 }
31342 std::string nv_name_bytes;
31343 rc = Parse_TPM2B_NAME(&buffer, nv_name, &nv_name_bytes);
31344 if (rc != TPM_RC_SUCCESS) {
31345 return rc;
31346 }
31347 return TPM_RC_SUCCESS;
31348 }
31349
NV_ReadPublicErrorCallback(Tpm::NV_ReadPublicResponse callback,TPM_RC response_code)31350 void NV_ReadPublicErrorCallback(Tpm::NV_ReadPublicResponse callback,
31351 TPM_RC response_code) {
31352 VLOG(1) << __func__;
31353 std::move(callback).Run(response_code, TPM2B_NV_PUBLIC(), TPM2B_NAME());
31354 }
31355
NV_ReadPublicResponseParser(Tpm::NV_ReadPublicResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31356 void NV_ReadPublicResponseParser(Tpm::NV_ReadPublicResponse callback,
31357 AuthorizationDelegate* authorization_delegate,
31358 const std::string& response) {
31359 VLOG(1) << __func__;
31360 TPM2B_NV_PUBLIC nv_public;
31361 TPM2B_NAME nv_name;
31362 TPM_RC rc = Tpm::ParseResponse_NV_ReadPublic(response, &nv_public, &nv_name,
31363 authorization_delegate);
31364 if (rc != TPM_RC_SUCCESS) {
31365 base::OnceCallback<void(TPM_RC)> error_reporter =
31366 base::BindOnce(NV_ReadPublicErrorCallback, std::move(callback));
31367 std::move(error_reporter).Run(rc);
31368 return;
31369 }
31370 std::move(callback).Run(rc, nv_public, nv_name);
31371 }
31372
NV_ReadPublic(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_ReadPublicResponse callback)31373 void Tpm::NV_ReadPublic(const TPMI_RH_NV_INDEX& nv_index,
31374 const std::string& nv_index_name,
31375 AuthorizationDelegate* authorization_delegate,
31376 NV_ReadPublicResponse callback) {
31377 VLOG(1) << __func__;
31378 std::string command;
31379 TPM_RC rc = SerializeCommand_NV_ReadPublic(nv_index, nv_index_name, &command,
31380 authorization_delegate);
31381 if (rc != TPM_RC_SUCCESS) {
31382 base::OnceCallback<void(TPM_RC)> error_reporter =
31383 base::BindOnce(NV_ReadPublicErrorCallback, std::move(callback));
31384 std::move(error_reporter).Run(rc);
31385 return;
31386 }
31387 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31388 NV_ReadPublicResponseParser, std::move(callback), authorization_delegate);
31389 transceiver_->SendCommand(command, std::move(parser));
31390 }
31391
NV_ReadPublicSync(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,TPM2B_NV_PUBLIC * nv_public,TPM2B_NAME * nv_name,AuthorizationDelegate * authorization_delegate)31392 TPM_RC Tpm::NV_ReadPublicSync(const TPMI_RH_NV_INDEX& nv_index,
31393 const std::string& nv_index_name,
31394 TPM2B_NV_PUBLIC* nv_public,
31395 TPM2B_NAME* nv_name,
31396 AuthorizationDelegate* authorization_delegate) {
31397 VLOG(1) << __func__;
31398 std::string command;
31399 TPM_RC rc = SerializeCommand_NV_ReadPublic(nv_index, nv_index_name, &command,
31400 authorization_delegate);
31401 if (rc != TPM_RC_SUCCESS) {
31402 return rc;
31403 }
31404 std::string response = transceiver_->SendCommandAndWait(command);
31405 rc = ParseResponse_NV_ReadPublic(response, nv_public, nv_name,
31406 authorization_delegate);
31407 return rc;
31408 }
31409
SerializeCommand_NV_Write(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,const UINT16 & offset,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31410 TPM_RC Tpm::SerializeCommand_NV_Write(
31411 const TPMI_RH_NV_AUTH& auth_handle,
31412 const std::string& auth_handle_name,
31413 const TPMI_RH_NV_INDEX& nv_index,
31414 const std::string& nv_index_name,
31415 const TPM2B_MAX_NV_BUFFER& data,
31416 const UINT16& offset,
31417 std::string* serialized_command,
31418 AuthorizationDelegate* authorization_delegate) {
31419 VLOG(3) << __func__;
31420 TPM_RC rc = TPM_RC_SUCCESS;
31421 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31422 UINT32 command_size = 10; // Header size.
31423 std::string handle_section_bytes;
31424 std::string parameter_section_bytes;
31425 TPM_CC command_code = TPM_CC_NV_Write;
31426 bool is_command_parameter_encryption_possible = true;
31427 bool is_response_parameter_encryption_possible = false;
31428 std::string command_code_bytes;
31429 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31430 if (rc != TPM_RC_SUCCESS) {
31431 return rc;
31432 }
31433 std::string auth_handle_bytes;
31434 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31435 if (rc != TPM_RC_SUCCESS) {
31436 return rc;
31437 }
31438 std::string nv_index_bytes;
31439 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31440 if (rc != TPM_RC_SUCCESS) {
31441 return rc;
31442 }
31443 std::string data_bytes;
31444 rc = Serialize_TPM2B_MAX_NV_BUFFER(data, &data_bytes);
31445 if (rc != TPM_RC_SUCCESS) {
31446 return rc;
31447 }
31448 std::string offset_bytes;
31449 rc = Serialize_UINT16(offset, &offset_bytes);
31450 if (rc != TPM_RC_SUCCESS) {
31451 return rc;
31452 }
31453 if (authorization_delegate) {
31454 // Encrypt just the parameter data, not the size.
31455 std::string tmp = data_bytes.substr(2);
31456 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
31457 return TRUNKS_RC_ENCRYPTION_FAILED;
31458 }
31459 data_bytes.replace(2, std::string::npos, tmp);
31460 }
31461 std::unique_ptr<crypto::SecureHash> hash(
31462 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31463 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31464 hash->Update(auth_handle_name.data(), auth_handle_name.size());
31465 handle_section_bytes += auth_handle_bytes;
31466 command_size += auth_handle_bytes.size();
31467 hash->Update(nv_index_name.data(), nv_index_name.size());
31468 handle_section_bytes += nv_index_bytes;
31469 command_size += nv_index_bytes.size();
31470 hash->Update(data_bytes.data(), data_bytes.size());
31471 parameter_section_bytes += data_bytes;
31472 command_size += data_bytes.size();
31473 hash->Update(offset_bytes.data(), offset_bytes.size());
31474 parameter_section_bytes += offset_bytes;
31475 command_size += offset_bytes.size();
31476 std::string command_hash(32, 0);
31477 hash->Finish(std::data(command_hash), command_hash.size());
31478 std::string authorization_section_bytes;
31479 std::string authorization_size_bytes;
31480 if (authorization_delegate) {
31481 if (!authorization_delegate->GetCommandAuthorization(
31482 command_hash, is_command_parameter_encryption_possible,
31483 is_response_parameter_encryption_possible,
31484 &authorization_section_bytes)) {
31485 return TRUNKS_RC_AUTHORIZATION_FAILED;
31486 }
31487 if (!authorization_section_bytes.empty()) {
31488 tag = TPM_ST_SESSIONS;
31489 std::string tmp;
31490 rc = Serialize_UINT32(authorization_section_bytes.size(),
31491 &authorization_size_bytes);
31492 if (rc != TPM_RC_SUCCESS) {
31493 return rc;
31494 }
31495 command_size +=
31496 authorization_size_bytes.size() + authorization_section_bytes.size();
31497 }
31498 }
31499 std::string tag_bytes;
31500 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31501 if (rc != TPM_RC_SUCCESS) {
31502 return rc;
31503 }
31504 std::string command_size_bytes;
31505 rc = Serialize_UINT32(command_size, &command_size_bytes);
31506 if (rc != TPM_RC_SUCCESS) {
31507 return rc;
31508 }
31509 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31510 handle_section_bytes + authorization_size_bytes +
31511 authorization_section_bytes + parameter_section_bytes;
31512 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31513 VLOG(2) << "Command: "
31514 << base::HexEncode(serialized_command->data(),
31515 serialized_command->size());
31516 return TPM_RC_SUCCESS;
31517 }
31518
ParseResponse_NV_Write(const std::string & response,AuthorizationDelegate * authorization_delegate)31519 TPM_RC Tpm::ParseResponse_NV_Write(
31520 const std::string& response,
31521 AuthorizationDelegate* authorization_delegate) {
31522 VLOG(3) << __func__;
31523 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31524 TPM_RC rc = TPM_RC_SUCCESS;
31525 std::string buffer(response);
31526 TPM_ST tag;
31527 std::string tag_bytes;
31528 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31529 if (rc != TPM_RC_SUCCESS) {
31530 return rc;
31531 }
31532 UINT32 response_size;
31533 std::string response_size_bytes;
31534 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31535 if (rc != TPM_RC_SUCCESS) {
31536 return rc;
31537 }
31538 TPM_RC response_code;
31539 std::string response_code_bytes;
31540 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31541 if (rc != TPM_RC_SUCCESS) {
31542 return rc;
31543 }
31544 if (response_size != response.size()) {
31545 return TPM_RC_SIZE;
31546 }
31547 if (response_code != TPM_RC_SUCCESS) {
31548 return response_code;
31549 }
31550 TPM_CC command_code = TPM_CC_NV_Write;
31551 std::string command_code_bytes;
31552 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31553 if (rc != TPM_RC_SUCCESS) {
31554 return rc;
31555 }
31556 std::string authorization_section_bytes;
31557 if (tag == TPM_ST_SESSIONS) {
31558 UINT32 parameter_section_size = buffer.size();
31559 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
31560 if (rc != TPM_RC_SUCCESS) {
31561 return rc;
31562 }
31563 if (parameter_section_size > buffer.size()) {
31564 return TPM_RC_INSUFFICIENT;
31565 }
31566 authorization_section_bytes = buffer.substr(parameter_section_size);
31567 // Keep the parameter section in |buffer|.
31568 buffer.erase(parameter_section_size);
31569 }
31570 std::unique_ptr<crypto::SecureHash> hash(
31571 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31572 hash->Update(response_code_bytes.data(), response_code_bytes.size());
31573 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31574 hash->Update(buffer.data(), buffer.size());
31575 std::string response_hash(32, 0);
31576 hash->Finish(std::data(response_hash), response_hash.size());
31577 if (tag == TPM_ST_SESSIONS) {
31578 if (!authorization_delegate)
31579 return TRUNKS_RC_AUTHORIZATION_FAILED;
31580 if (!authorization_delegate->CheckResponseAuthorization(
31581 response_hash, authorization_section_bytes)) {
31582 return TRUNKS_RC_AUTHORIZATION_FAILED;
31583 }
31584 }
31585 return TPM_RC_SUCCESS;
31586 }
31587
NV_WriteErrorCallback(Tpm::NV_WriteResponse callback,TPM_RC response_code)31588 void NV_WriteErrorCallback(Tpm::NV_WriteResponse callback,
31589 TPM_RC response_code) {
31590 VLOG(1) << __func__;
31591 std::move(callback).Run(response_code);
31592 }
31593
NV_WriteResponseParser(Tpm::NV_WriteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31594 void NV_WriteResponseParser(Tpm::NV_WriteResponse callback,
31595 AuthorizationDelegate* authorization_delegate,
31596 const std::string& response) {
31597 VLOG(1) << __func__;
31598 TPM_RC rc = Tpm::ParseResponse_NV_Write(response, authorization_delegate);
31599 if (rc != TPM_RC_SUCCESS) {
31600 base::OnceCallback<void(TPM_RC)> error_reporter =
31601 base::BindOnce(NV_WriteErrorCallback, std::move(callback));
31602 std::move(error_reporter).Run(rc);
31603 return;
31604 }
31605 std::move(callback).Run(rc);
31606 }
31607
NV_Write(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,const UINT16 & offset,AuthorizationDelegate * authorization_delegate,NV_WriteResponse callback)31608 void Tpm::NV_Write(const TPMI_RH_NV_AUTH& auth_handle,
31609 const std::string& auth_handle_name,
31610 const TPMI_RH_NV_INDEX& nv_index,
31611 const std::string& nv_index_name,
31612 const TPM2B_MAX_NV_BUFFER& data,
31613 const UINT16& offset,
31614 AuthorizationDelegate* authorization_delegate,
31615 NV_WriteResponse callback) {
31616 VLOG(1) << __func__;
31617 std::string command;
31618 TPM_RC rc = SerializeCommand_NV_Write(auth_handle, auth_handle_name, nv_index,
31619 nv_index_name, data, offset, &command,
31620 authorization_delegate);
31621 if (rc != TPM_RC_SUCCESS) {
31622 base::OnceCallback<void(TPM_RC)> error_reporter =
31623 base::BindOnce(NV_WriteErrorCallback, std::move(callback));
31624 std::move(error_reporter).Run(rc);
31625 return;
31626 }
31627 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31628 NV_WriteResponseParser, std::move(callback), authorization_delegate);
31629 transceiver_->SendCommand(command, std::move(parser));
31630 }
31631
NV_WriteSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,const UINT16 & offset,AuthorizationDelegate * authorization_delegate)31632 TPM_RC Tpm::NV_WriteSync(const TPMI_RH_NV_AUTH& auth_handle,
31633 const std::string& auth_handle_name,
31634 const TPMI_RH_NV_INDEX& nv_index,
31635 const std::string& nv_index_name,
31636 const TPM2B_MAX_NV_BUFFER& data,
31637 const UINT16& offset,
31638 AuthorizationDelegate* authorization_delegate) {
31639 VLOG(1) << __func__;
31640 std::string command;
31641 TPM_RC rc = SerializeCommand_NV_Write(auth_handle, auth_handle_name, nv_index,
31642 nv_index_name, data, offset, &command,
31643 authorization_delegate);
31644 if (rc != TPM_RC_SUCCESS) {
31645 return rc;
31646 }
31647 std::string response = transceiver_->SendCommandAndWait(command);
31648 rc = ParseResponse_NV_Write(response, authorization_delegate);
31649 return rc;
31650 }
31651
SerializeCommand_NV_Increment(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31652 TPM_RC Tpm::SerializeCommand_NV_Increment(
31653 const TPMI_RH_NV_AUTH& auth_handle,
31654 const std::string& auth_handle_name,
31655 const TPMI_RH_NV_INDEX& nv_index,
31656 const std::string& nv_index_name,
31657 std::string* serialized_command,
31658 AuthorizationDelegate* authorization_delegate) {
31659 VLOG(3) << __func__;
31660 TPM_RC rc = TPM_RC_SUCCESS;
31661 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31662 UINT32 command_size = 10; // Header size.
31663 std::string handle_section_bytes;
31664 std::string parameter_section_bytes;
31665 TPM_CC command_code = TPM_CC_NV_Increment;
31666 bool is_command_parameter_encryption_possible = false;
31667 bool is_response_parameter_encryption_possible = false;
31668 std::string command_code_bytes;
31669 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31670 if (rc != TPM_RC_SUCCESS) {
31671 return rc;
31672 }
31673 std::string auth_handle_bytes;
31674 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31675 if (rc != TPM_RC_SUCCESS) {
31676 return rc;
31677 }
31678 std::string nv_index_bytes;
31679 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31680 if (rc != TPM_RC_SUCCESS) {
31681 return rc;
31682 }
31683 std::unique_ptr<crypto::SecureHash> hash(
31684 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31685 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31686 hash->Update(auth_handle_name.data(), auth_handle_name.size());
31687 handle_section_bytes += auth_handle_bytes;
31688 command_size += auth_handle_bytes.size();
31689 hash->Update(nv_index_name.data(), nv_index_name.size());
31690 handle_section_bytes += nv_index_bytes;
31691 command_size += nv_index_bytes.size();
31692 std::string command_hash(32, 0);
31693 hash->Finish(std::data(command_hash), command_hash.size());
31694 std::string authorization_section_bytes;
31695 std::string authorization_size_bytes;
31696 if (authorization_delegate) {
31697 if (!authorization_delegate->GetCommandAuthorization(
31698 command_hash, is_command_parameter_encryption_possible,
31699 is_response_parameter_encryption_possible,
31700 &authorization_section_bytes)) {
31701 return TRUNKS_RC_AUTHORIZATION_FAILED;
31702 }
31703 if (!authorization_section_bytes.empty()) {
31704 tag = TPM_ST_SESSIONS;
31705 std::string tmp;
31706 rc = Serialize_UINT32(authorization_section_bytes.size(),
31707 &authorization_size_bytes);
31708 if (rc != TPM_RC_SUCCESS) {
31709 return rc;
31710 }
31711 command_size +=
31712 authorization_size_bytes.size() + authorization_section_bytes.size();
31713 }
31714 }
31715 std::string tag_bytes;
31716 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31717 if (rc != TPM_RC_SUCCESS) {
31718 return rc;
31719 }
31720 std::string command_size_bytes;
31721 rc = Serialize_UINT32(command_size, &command_size_bytes);
31722 if (rc != TPM_RC_SUCCESS) {
31723 return rc;
31724 }
31725 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31726 handle_section_bytes + authorization_size_bytes +
31727 authorization_section_bytes + parameter_section_bytes;
31728 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31729 VLOG(2) << "Command: "
31730 << base::HexEncode(serialized_command->data(),
31731 serialized_command->size());
31732 return TPM_RC_SUCCESS;
31733 }
31734
ParseResponse_NV_Increment(const std::string & response,AuthorizationDelegate * authorization_delegate)31735 TPM_RC Tpm::ParseResponse_NV_Increment(
31736 const std::string& response,
31737 AuthorizationDelegate* authorization_delegate) {
31738 VLOG(3) << __func__;
31739 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31740 TPM_RC rc = TPM_RC_SUCCESS;
31741 std::string buffer(response);
31742 TPM_ST tag;
31743 std::string tag_bytes;
31744 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31745 if (rc != TPM_RC_SUCCESS) {
31746 return rc;
31747 }
31748 UINT32 response_size;
31749 std::string response_size_bytes;
31750 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31751 if (rc != TPM_RC_SUCCESS) {
31752 return rc;
31753 }
31754 TPM_RC response_code;
31755 std::string response_code_bytes;
31756 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31757 if (rc != TPM_RC_SUCCESS) {
31758 return rc;
31759 }
31760 if (response_size != response.size()) {
31761 return TPM_RC_SIZE;
31762 }
31763 if (response_code != TPM_RC_SUCCESS) {
31764 return response_code;
31765 }
31766 TPM_CC command_code = TPM_CC_NV_Increment;
31767 std::string command_code_bytes;
31768 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31769 if (rc != TPM_RC_SUCCESS) {
31770 return rc;
31771 }
31772 std::string authorization_section_bytes;
31773 if (tag == TPM_ST_SESSIONS) {
31774 UINT32 parameter_section_size = buffer.size();
31775 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
31776 if (rc != TPM_RC_SUCCESS) {
31777 return rc;
31778 }
31779 if (parameter_section_size > buffer.size()) {
31780 return TPM_RC_INSUFFICIENT;
31781 }
31782 authorization_section_bytes = buffer.substr(parameter_section_size);
31783 // Keep the parameter section in |buffer|.
31784 buffer.erase(parameter_section_size);
31785 }
31786 std::unique_ptr<crypto::SecureHash> hash(
31787 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31788 hash->Update(response_code_bytes.data(), response_code_bytes.size());
31789 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31790 hash->Update(buffer.data(), buffer.size());
31791 std::string response_hash(32, 0);
31792 hash->Finish(std::data(response_hash), response_hash.size());
31793 if (tag == TPM_ST_SESSIONS) {
31794 if (!authorization_delegate)
31795 return TRUNKS_RC_AUTHORIZATION_FAILED;
31796 if (!authorization_delegate->CheckResponseAuthorization(
31797 response_hash, authorization_section_bytes)) {
31798 return TRUNKS_RC_AUTHORIZATION_FAILED;
31799 }
31800 }
31801 return TPM_RC_SUCCESS;
31802 }
31803
NV_IncrementErrorCallback(Tpm::NV_IncrementResponse callback,TPM_RC response_code)31804 void NV_IncrementErrorCallback(Tpm::NV_IncrementResponse callback,
31805 TPM_RC response_code) {
31806 VLOG(1) << __func__;
31807 std::move(callback).Run(response_code);
31808 }
31809
NV_IncrementResponseParser(Tpm::NV_IncrementResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31810 void NV_IncrementResponseParser(Tpm::NV_IncrementResponse callback,
31811 AuthorizationDelegate* authorization_delegate,
31812 const std::string& response) {
31813 VLOG(1) << __func__;
31814 TPM_RC rc = Tpm::ParseResponse_NV_Increment(response, authorization_delegate);
31815 if (rc != TPM_RC_SUCCESS) {
31816 base::OnceCallback<void(TPM_RC)> error_reporter =
31817 base::BindOnce(NV_IncrementErrorCallback, std::move(callback));
31818 std::move(error_reporter).Run(rc);
31819 return;
31820 }
31821 std::move(callback).Run(rc);
31822 }
31823
NV_Increment(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_IncrementResponse callback)31824 void Tpm::NV_Increment(const TPMI_RH_NV_AUTH& auth_handle,
31825 const std::string& auth_handle_name,
31826 const TPMI_RH_NV_INDEX& nv_index,
31827 const std::string& nv_index_name,
31828 AuthorizationDelegate* authorization_delegate,
31829 NV_IncrementResponse callback) {
31830 VLOG(1) << __func__;
31831 std::string command;
31832 TPM_RC rc = SerializeCommand_NV_Increment(auth_handle, auth_handle_name,
31833 nv_index, nv_index_name, &command,
31834 authorization_delegate);
31835 if (rc != TPM_RC_SUCCESS) {
31836 base::OnceCallback<void(TPM_RC)> error_reporter =
31837 base::BindOnce(NV_IncrementErrorCallback, std::move(callback));
31838 std::move(error_reporter).Run(rc);
31839 return;
31840 }
31841 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31842 NV_IncrementResponseParser, std::move(callback), authorization_delegate);
31843 transceiver_->SendCommand(command, std::move(parser));
31844 }
31845
NV_IncrementSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)31846 TPM_RC Tpm::NV_IncrementSync(const TPMI_RH_NV_AUTH& auth_handle,
31847 const std::string& auth_handle_name,
31848 const TPMI_RH_NV_INDEX& nv_index,
31849 const std::string& nv_index_name,
31850 AuthorizationDelegate* authorization_delegate) {
31851 VLOG(1) << __func__;
31852 std::string command;
31853 TPM_RC rc = SerializeCommand_NV_Increment(auth_handle, auth_handle_name,
31854 nv_index, nv_index_name, &command,
31855 authorization_delegate);
31856 if (rc != TPM_RC_SUCCESS) {
31857 return rc;
31858 }
31859 std::string response = transceiver_->SendCommandAndWait(command);
31860 rc = ParseResponse_NV_Increment(response, authorization_delegate);
31861 return rc;
31862 }
31863
SerializeCommand_NV_Extend(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31864 TPM_RC Tpm::SerializeCommand_NV_Extend(
31865 const TPMI_RH_NV_AUTH& auth_handle,
31866 const std::string& auth_handle_name,
31867 const TPMI_RH_NV_INDEX& nv_index,
31868 const std::string& nv_index_name,
31869 const TPM2B_MAX_NV_BUFFER& data,
31870 std::string* serialized_command,
31871 AuthorizationDelegate* authorization_delegate) {
31872 VLOG(3) << __func__;
31873 TPM_RC rc = TPM_RC_SUCCESS;
31874 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31875 UINT32 command_size = 10; // Header size.
31876 std::string handle_section_bytes;
31877 std::string parameter_section_bytes;
31878 TPM_CC command_code = TPM_CC_NV_Extend;
31879 bool is_command_parameter_encryption_possible = true;
31880 bool is_response_parameter_encryption_possible = false;
31881 std::string command_code_bytes;
31882 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31883 if (rc != TPM_RC_SUCCESS) {
31884 return rc;
31885 }
31886 std::string auth_handle_bytes;
31887 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31888 if (rc != TPM_RC_SUCCESS) {
31889 return rc;
31890 }
31891 std::string nv_index_bytes;
31892 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31893 if (rc != TPM_RC_SUCCESS) {
31894 return rc;
31895 }
31896 std::string data_bytes;
31897 rc = Serialize_TPM2B_MAX_NV_BUFFER(data, &data_bytes);
31898 if (rc != TPM_RC_SUCCESS) {
31899 return rc;
31900 }
31901 if (authorization_delegate) {
31902 // Encrypt just the parameter data, not the size.
31903 std::string tmp = data_bytes.substr(2);
31904 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
31905 return TRUNKS_RC_ENCRYPTION_FAILED;
31906 }
31907 data_bytes.replace(2, std::string::npos, tmp);
31908 }
31909 std::unique_ptr<crypto::SecureHash> hash(
31910 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31911 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31912 hash->Update(auth_handle_name.data(), auth_handle_name.size());
31913 handle_section_bytes += auth_handle_bytes;
31914 command_size += auth_handle_bytes.size();
31915 hash->Update(nv_index_name.data(), nv_index_name.size());
31916 handle_section_bytes += nv_index_bytes;
31917 command_size += nv_index_bytes.size();
31918 hash->Update(data_bytes.data(), data_bytes.size());
31919 parameter_section_bytes += data_bytes;
31920 command_size += data_bytes.size();
31921 std::string command_hash(32, 0);
31922 hash->Finish(std::data(command_hash), command_hash.size());
31923 std::string authorization_section_bytes;
31924 std::string authorization_size_bytes;
31925 if (authorization_delegate) {
31926 if (!authorization_delegate->GetCommandAuthorization(
31927 command_hash, is_command_parameter_encryption_possible,
31928 is_response_parameter_encryption_possible,
31929 &authorization_section_bytes)) {
31930 return TRUNKS_RC_AUTHORIZATION_FAILED;
31931 }
31932 if (!authorization_section_bytes.empty()) {
31933 tag = TPM_ST_SESSIONS;
31934 std::string tmp;
31935 rc = Serialize_UINT32(authorization_section_bytes.size(),
31936 &authorization_size_bytes);
31937 if (rc != TPM_RC_SUCCESS) {
31938 return rc;
31939 }
31940 command_size +=
31941 authorization_size_bytes.size() + authorization_section_bytes.size();
31942 }
31943 }
31944 std::string tag_bytes;
31945 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31946 if (rc != TPM_RC_SUCCESS) {
31947 return rc;
31948 }
31949 std::string command_size_bytes;
31950 rc = Serialize_UINT32(command_size, &command_size_bytes);
31951 if (rc != TPM_RC_SUCCESS) {
31952 return rc;
31953 }
31954 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31955 handle_section_bytes + authorization_size_bytes +
31956 authorization_section_bytes + parameter_section_bytes;
31957 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31958 VLOG(2) << "Command: "
31959 << base::HexEncode(serialized_command->data(),
31960 serialized_command->size());
31961 return TPM_RC_SUCCESS;
31962 }
31963
ParseResponse_NV_Extend(const std::string & response,AuthorizationDelegate * authorization_delegate)31964 TPM_RC Tpm::ParseResponse_NV_Extend(
31965 const std::string& response,
31966 AuthorizationDelegate* authorization_delegate) {
31967 VLOG(3) << __func__;
31968 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31969 TPM_RC rc = TPM_RC_SUCCESS;
31970 std::string buffer(response);
31971 TPM_ST tag;
31972 std::string tag_bytes;
31973 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31974 if (rc != TPM_RC_SUCCESS) {
31975 return rc;
31976 }
31977 UINT32 response_size;
31978 std::string response_size_bytes;
31979 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31980 if (rc != TPM_RC_SUCCESS) {
31981 return rc;
31982 }
31983 TPM_RC response_code;
31984 std::string response_code_bytes;
31985 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31986 if (rc != TPM_RC_SUCCESS) {
31987 return rc;
31988 }
31989 if (response_size != response.size()) {
31990 return TPM_RC_SIZE;
31991 }
31992 if (response_code != TPM_RC_SUCCESS) {
31993 return response_code;
31994 }
31995 TPM_CC command_code = TPM_CC_NV_Extend;
31996 std::string command_code_bytes;
31997 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31998 if (rc != TPM_RC_SUCCESS) {
31999 return rc;
32000 }
32001 std::string authorization_section_bytes;
32002 if (tag == TPM_ST_SESSIONS) {
32003 UINT32 parameter_section_size = buffer.size();
32004 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
32005 if (rc != TPM_RC_SUCCESS) {
32006 return rc;
32007 }
32008 if (parameter_section_size > buffer.size()) {
32009 return TPM_RC_INSUFFICIENT;
32010 }
32011 authorization_section_bytes = buffer.substr(parameter_section_size);
32012 // Keep the parameter section in |buffer|.
32013 buffer.erase(parameter_section_size);
32014 }
32015 std::unique_ptr<crypto::SecureHash> hash(
32016 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32017 hash->Update(response_code_bytes.data(), response_code_bytes.size());
32018 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32019 hash->Update(buffer.data(), buffer.size());
32020 std::string response_hash(32, 0);
32021 hash->Finish(std::data(response_hash), response_hash.size());
32022 if (tag == TPM_ST_SESSIONS) {
32023 if (!authorization_delegate)
32024 return TRUNKS_RC_AUTHORIZATION_FAILED;
32025 if (!authorization_delegate->CheckResponseAuthorization(
32026 response_hash, authorization_section_bytes)) {
32027 return TRUNKS_RC_AUTHORIZATION_FAILED;
32028 }
32029 }
32030 return TPM_RC_SUCCESS;
32031 }
32032
NV_ExtendErrorCallback(Tpm::NV_ExtendResponse callback,TPM_RC response_code)32033 void NV_ExtendErrorCallback(Tpm::NV_ExtendResponse callback,
32034 TPM_RC response_code) {
32035 VLOG(1) << __func__;
32036 std::move(callback).Run(response_code);
32037 }
32038
NV_ExtendResponseParser(Tpm::NV_ExtendResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32039 void NV_ExtendResponseParser(Tpm::NV_ExtendResponse callback,
32040 AuthorizationDelegate* authorization_delegate,
32041 const std::string& response) {
32042 VLOG(1) << __func__;
32043 TPM_RC rc = Tpm::ParseResponse_NV_Extend(response, authorization_delegate);
32044 if (rc != TPM_RC_SUCCESS) {
32045 base::OnceCallback<void(TPM_RC)> error_reporter =
32046 base::BindOnce(NV_ExtendErrorCallback, std::move(callback));
32047 std::move(error_reporter).Run(rc);
32048 return;
32049 }
32050 std::move(callback).Run(rc);
32051 }
32052
NV_Extend(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,AuthorizationDelegate * authorization_delegate,NV_ExtendResponse callback)32053 void Tpm::NV_Extend(const TPMI_RH_NV_AUTH& auth_handle,
32054 const std::string& auth_handle_name,
32055 const TPMI_RH_NV_INDEX& nv_index,
32056 const std::string& nv_index_name,
32057 const TPM2B_MAX_NV_BUFFER& data,
32058 AuthorizationDelegate* authorization_delegate,
32059 NV_ExtendResponse callback) {
32060 VLOG(1) << __func__;
32061 std::string command;
32062 TPM_RC rc = SerializeCommand_NV_Extend(auth_handle, auth_handle_name,
32063 nv_index, nv_index_name, data,
32064 &command, authorization_delegate);
32065 if (rc != TPM_RC_SUCCESS) {
32066 base::OnceCallback<void(TPM_RC)> error_reporter =
32067 base::BindOnce(NV_ExtendErrorCallback, std::move(callback));
32068 std::move(error_reporter).Run(rc);
32069 return;
32070 }
32071 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32072 NV_ExtendResponseParser, std::move(callback), authorization_delegate);
32073 transceiver_->SendCommand(command, std::move(parser));
32074 }
32075
NV_ExtendSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,AuthorizationDelegate * authorization_delegate)32076 TPM_RC Tpm::NV_ExtendSync(const TPMI_RH_NV_AUTH& auth_handle,
32077 const std::string& auth_handle_name,
32078 const TPMI_RH_NV_INDEX& nv_index,
32079 const std::string& nv_index_name,
32080 const TPM2B_MAX_NV_BUFFER& data,
32081 AuthorizationDelegate* authorization_delegate) {
32082 VLOG(1) << __func__;
32083 std::string command;
32084 TPM_RC rc = SerializeCommand_NV_Extend(auth_handle, auth_handle_name,
32085 nv_index, nv_index_name, data,
32086 &command, authorization_delegate);
32087 if (rc != TPM_RC_SUCCESS) {
32088 return rc;
32089 }
32090 std::string response = transceiver_->SendCommandAndWait(command);
32091 rc = ParseResponse_NV_Extend(response, authorization_delegate);
32092 return rc;
32093 }
32094
SerializeCommand_NV_SetBits(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT64 & bits,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32095 TPM_RC Tpm::SerializeCommand_NV_SetBits(
32096 const TPMI_RH_NV_AUTH& auth_handle,
32097 const std::string& auth_handle_name,
32098 const TPMI_RH_NV_INDEX& nv_index,
32099 const std::string& nv_index_name,
32100 const UINT64& bits,
32101 std::string* serialized_command,
32102 AuthorizationDelegate* authorization_delegate) {
32103 VLOG(3) << __func__;
32104 TPM_RC rc = TPM_RC_SUCCESS;
32105 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32106 UINT32 command_size = 10; // Header size.
32107 std::string handle_section_bytes;
32108 std::string parameter_section_bytes;
32109 TPM_CC command_code = TPM_CC_NV_SetBits;
32110 bool is_command_parameter_encryption_possible = false;
32111 bool is_response_parameter_encryption_possible = false;
32112 std::string command_code_bytes;
32113 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32114 if (rc != TPM_RC_SUCCESS) {
32115 return rc;
32116 }
32117 std::string auth_handle_bytes;
32118 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32119 if (rc != TPM_RC_SUCCESS) {
32120 return rc;
32121 }
32122 std::string nv_index_bytes;
32123 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32124 if (rc != TPM_RC_SUCCESS) {
32125 return rc;
32126 }
32127 std::string bits_bytes;
32128 rc = Serialize_UINT64(bits, &bits_bytes);
32129 if (rc != TPM_RC_SUCCESS) {
32130 return rc;
32131 }
32132 std::unique_ptr<crypto::SecureHash> hash(
32133 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32134 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32135 hash->Update(auth_handle_name.data(), auth_handle_name.size());
32136 handle_section_bytes += auth_handle_bytes;
32137 command_size += auth_handle_bytes.size();
32138 hash->Update(nv_index_name.data(), nv_index_name.size());
32139 handle_section_bytes += nv_index_bytes;
32140 command_size += nv_index_bytes.size();
32141 hash->Update(bits_bytes.data(), bits_bytes.size());
32142 parameter_section_bytes += bits_bytes;
32143 command_size += bits_bytes.size();
32144 std::string command_hash(32, 0);
32145 hash->Finish(std::data(command_hash), command_hash.size());
32146 std::string authorization_section_bytes;
32147 std::string authorization_size_bytes;
32148 if (authorization_delegate) {
32149 if (!authorization_delegate->GetCommandAuthorization(
32150 command_hash, is_command_parameter_encryption_possible,
32151 is_response_parameter_encryption_possible,
32152 &authorization_section_bytes)) {
32153 return TRUNKS_RC_AUTHORIZATION_FAILED;
32154 }
32155 if (!authorization_section_bytes.empty()) {
32156 tag = TPM_ST_SESSIONS;
32157 std::string tmp;
32158 rc = Serialize_UINT32(authorization_section_bytes.size(),
32159 &authorization_size_bytes);
32160 if (rc != TPM_RC_SUCCESS) {
32161 return rc;
32162 }
32163 command_size +=
32164 authorization_size_bytes.size() + authorization_section_bytes.size();
32165 }
32166 }
32167 std::string tag_bytes;
32168 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32169 if (rc != TPM_RC_SUCCESS) {
32170 return rc;
32171 }
32172 std::string command_size_bytes;
32173 rc = Serialize_UINT32(command_size, &command_size_bytes);
32174 if (rc != TPM_RC_SUCCESS) {
32175 return rc;
32176 }
32177 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32178 handle_section_bytes + authorization_size_bytes +
32179 authorization_section_bytes + parameter_section_bytes;
32180 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32181 VLOG(2) << "Command: "
32182 << base::HexEncode(serialized_command->data(),
32183 serialized_command->size());
32184 return TPM_RC_SUCCESS;
32185 }
32186
ParseResponse_NV_SetBits(const std::string & response,AuthorizationDelegate * authorization_delegate)32187 TPM_RC Tpm::ParseResponse_NV_SetBits(
32188 const std::string& response,
32189 AuthorizationDelegate* authorization_delegate) {
32190 VLOG(3) << __func__;
32191 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32192 TPM_RC rc = TPM_RC_SUCCESS;
32193 std::string buffer(response);
32194 TPM_ST tag;
32195 std::string tag_bytes;
32196 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32197 if (rc != TPM_RC_SUCCESS) {
32198 return rc;
32199 }
32200 UINT32 response_size;
32201 std::string response_size_bytes;
32202 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32203 if (rc != TPM_RC_SUCCESS) {
32204 return rc;
32205 }
32206 TPM_RC response_code;
32207 std::string response_code_bytes;
32208 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32209 if (rc != TPM_RC_SUCCESS) {
32210 return rc;
32211 }
32212 if (response_size != response.size()) {
32213 return TPM_RC_SIZE;
32214 }
32215 if (response_code != TPM_RC_SUCCESS) {
32216 return response_code;
32217 }
32218 TPM_CC command_code = TPM_CC_NV_SetBits;
32219 std::string command_code_bytes;
32220 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32221 if (rc != TPM_RC_SUCCESS) {
32222 return rc;
32223 }
32224 std::string authorization_section_bytes;
32225 if (tag == TPM_ST_SESSIONS) {
32226 UINT32 parameter_section_size = buffer.size();
32227 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
32228 if (rc != TPM_RC_SUCCESS) {
32229 return rc;
32230 }
32231 if (parameter_section_size > buffer.size()) {
32232 return TPM_RC_INSUFFICIENT;
32233 }
32234 authorization_section_bytes = buffer.substr(parameter_section_size);
32235 // Keep the parameter section in |buffer|.
32236 buffer.erase(parameter_section_size);
32237 }
32238 std::unique_ptr<crypto::SecureHash> hash(
32239 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32240 hash->Update(response_code_bytes.data(), response_code_bytes.size());
32241 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32242 hash->Update(buffer.data(), buffer.size());
32243 std::string response_hash(32, 0);
32244 hash->Finish(std::data(response_hash), response_hash.size());
32245 if (tag == TPM_ST_SESSIONS) {
32246 if (!authorization_delegate)
32247 return TRUNKS_RC_AUTHORIZATION_FAILED;
32248 if (!authorization_delegate->CheckResponseAuthorization(
32249 response_hash, authorization_section_bytes)) {
32250 return TRUNKS_RC_AUTHORIZATION_FAILED;
32251 }
32252 }
32253 return TPM_RC_SUCCESS;
32254 }
32255
NV_SetBitsErrorCallback(Tpm::NV_SetBitsResponse callback,TPM_RC response_code)32256 void NV_SetBitsErrorCallback(Tpm::NV_SetBitsResponse callback,
32257 TPM_RC response_code) {
32258 VLOG(1) << __func__;
32259 std::move(callback).Run(response_code);
32260 }
32261
NV_SetBitsResponseParser(Tpm::NV_SetBitsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32262 void NV_SetBitsResponseParser(Tpm::NV_SetBitsResponse callback,
32263 AuthorizationDelegate* authorization_delegate,
32264 const std::string& response) {
32265 VLOG(1) << __func__;
32266 TPM_RC rc = Tpm::ParseResponse_NV_SetBits(response, authorization_delegate);
32267 if (rc != TPM_RC_SUCCESS) {
32268 base::OnceCallback<void(TPM_RC)> error_reporter =
32269 base::BindOnce(NV_SetBitsErrorCallback, std::move(callback));
32270 std::move(error_reporter).Run(rc);
32271 return;
32272 }
32273 std::move(callback).Run(rc);
32274 }
32275
NV_SetBits(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT64 & bits,AuthorizationDelegate * authorization_delegate,NV_SetBitsResponse callback)32276 void Tpm::NV_SetBits(const TPMI_RH_NV_AUTH& auth_handle,
32277 const std::string& auth_handle_name,
32278 const TPMI_RH_NV_INDEX& nv_index,
32279 const std::string& nv_index_name,
32280 const UINT64& bits,
32281 AuthorizationDelegate* authorization_delegate,
32282 NV_SetBitsResponse callback) {
32283 VLOG(1) << __func__;
32284 std::string command;
32285 TPM_RC rc = SerializeCommand_NV_SetBits(auth_handle, auth_handle_name,
32286 nv_index, nv_index_name, bits,
32287 &command, authorization_delegate);
32288 if (rc != TPM_RC_SUCCESS) {
32289 base::OnceCallback<void(TPM_RC)> error_reporter =
32290 base::BindOnce(NV_SetBitsErrorCallback, std::move(callback));
32291 std::move(error_reporter).Run(rc);
32292 return;
32293 }
32294 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32295 NV_SetBitsResponseParser, std::move(callback), authorization_delegate);
32296 transceiver_->SendCommand(command, std::move(parser));
32297 }
32298
NV_SetBitsSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT64 & bits,AuthorizationDelegate * authorization_delegate)32299 TPM_RC Tpm::NV_SetBitsSync(const TPMI_RH_NV_AUTH& auth_handle,
32300 const std::string& auth_handle_name,
32301 const TPMI_RH_NV_INDEX& nv_index,
32302 const std::string& nv_index_name,
32303 const UINT64& bits,
32304 AuthorizationDelegate* authorization_delegate) {
32305 VLOG(1) << __func__;
32306 std::string command;
32307 TPM_RC rc = SerializeCommand_NV_SetBits(auth_handle, auth_handle_name,
32308 nv_index, nv_index_name, bits,
32309 &command, authorization_delegate);
32310 if (rc != TPM_RC_SUCCESS) {
32311 return rc;
32312 }
32313 std::string response = transceiver_->SendCommandAndWait(command);
32314 rc = ParseResponse_NV_SetBits(response, authorization_delegate);
32315 return rc;
32316 }
32317
SerializeCommand_NV_WriteLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32318 TPM_RC Tpm::SerializeCommand_NV_WriteLock(
32319 const TPMI_RH_NV_AUTH& auth_handle,
32320 const std::string& auth_handle_name,
32321 const TPMI_RH_NV_INDEX& nv_index,
32322 const std::string& nv_index_name,
32323 std::string* serialized_command,
32324 AuthorizationDelegate* authorization_delegate) {
32325 VLOG(3) << __func__;
32326 TPM_RC rc = TPM_RC_SUCCESS;
32327 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32328 UINT32 command_size = 10; // Header size.
32329 std::string handle_section_bytes;
32330 std::string parameter_section_bytes;
32331 TPM_CC command_code = TPM_CC_NV_WriteLock;
32332 bool is_command_parameter_encryption_possible = false;
32333 bool is_response_parameter_encryption_possible = false;
32334 std::string command_code_bytes;
32335 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32336 if (rc != TPM_RC_SUCCESS) {
32337 return rc;
32338 }
32339 std::string auth_handle_bytes;
32340 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32341 if (rc != TPM_RC_SUCCESS) {
32342 return rc;
32343 }
32344 std::string nv_index_bytes;
32345 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32346 if (rc != TPM_RC_SUCCESS) {
32347 return rc;
32348 }
32349 std::unique_ptr<crypto::SecureHash> hash(
32350 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32351 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32352 hash->Update(auth_handle_name.data(), auth_handle_name.size());
32353 handle_section_bytes += auth_handle_bytes;
32354 command_size += auth_handle_bytes.size();
32355 hash->Update(nv_index_name.data(), nv_index_name.size());
32356 handle_section_bytes += nv_index_bytes;
32357 command_size += nv_index_bytes.size();
32358 std::string command_hash(32, 0);
32359 hash->Finish(std::data(command_hash), command_hash.size());
32360 std::string authorization_section_bytes;
32361 std::string authorization_size_bytes;
32362 if (authorization_delegate) {
32363 if (!authorization_delegate->GetCommandAuthorization(
32364 command_hash, is_command_parameter_encryption_possible,
32365 is_response_parameter_encryption_possible,
32366 &authorization_section_bytes)) {
32367 return TRUNKS_RC_AUTHORIZATION_FAILED;
32368 }
32369 if (!authorization_section_bytes.empty()) {
32370 tag = TPM_ST_SESSIONS;
32371 std::string tmp;
32372 rc = Serialize_UINT32(authorization_section_bytes.size(),
32373 &authorization_size_bytes);
32374 if (rc != TPM_RC_SUCCESS) {
32375 return rc;
32376 }
32377 command_size +=
32378 authorization_size_bytes.size() + authorization_section_bytes.size();
32379 }
32380 }
32381 std::string tag_bytes;
32382 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32383 if (rc != TPM_RC_SUCCESS) {
32384 return rc;
32385 }
32386 std::string command_size_bytes;
32387 rc = Serialize_UINT32(command_size, &command_size_bytes);
32388 if (rc != TPM_RC_SUCCESS) {
32389 return rc;
32390 }
32391 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32392 handle_section_bytes + authorization_size_bytes +
32393 authorization_section_bytes + parameter_section_bytes;
32394 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32395 VLOG(2) << "Command: "
32396 << base::HexEncode(serialized_command->data(),
32397 serialized_command->size());
32398 return TPM_RC_SUCCESS;
32399 }
32400
ParseResponse_NV_WriteLock(const std::string & response,AuthorizationDelegate * authorization_delegate)32401 TPM_RC Tpm::ParseResponse_NV_WriteLock(
32402 const std::string& response,
32403 AuthorizationDelegate* authorization_delegate) {
32404 VLOG(3) << __func__;
32405 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32406 TPM_RC rc = TPM_RC_SUCCESS;
32407 std::string buffer(response);
32408 TPM_ST tag;
32409 std::string tag_bytes;
32410 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32411 if (rc != TPM_RC_SUCCESS) {
32412 return rc;
32413 }
32414 UINT32 response_size;
32415 std::string response_size_bytes;
32416 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32417 if (rc != TPM_RC_SUCCESS) {
32418 return rc;
32419 }
32420 TPM_RC response_code;
32421 std::string response_code_bytes;
32422 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32423 if (rc != TPM_RC_SUCCESS) {
32424 return rc;
32425 }
32426 if (response_size != response.size()) {
32427 return TPM_RC_SIZE;
32428 }
32429 if (response_code != TPM_RC_SUCCESS) {
32430 return response_code;
32431 }
32432 TPM_CC command_code = TPM_CC_NV_WriteLock;
32433 std::string command_code_bytes;
32434 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32435 if (rc != TPM_RC_SUCCESS) {
32436 return rc;
32437 }
32438 std::string authorization_section_bytes;
32439 if (tag == TPM_ST_SESSIONS) {
32440 UINT32 parameter_section_size = buffer.size();
32441 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
32442 if (rc != TPM_RC_SUCCESS) {
32443 return rc;
32444 }
32445 if (parameter_section_size > buffer.size()) {
32446 return TPM_RC_INSUFFICIENT;
32447 }
32448 authorization_section_bytes = buffer.substr(parameter_section_size);
32449 // Keep the parameter section in |buffer|.
32450 buffer.erase(parameter_section_size);
32451 }
32452 std::unique_ptr<crypto::SecureHash> hash(
32453 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32454 hash->Update(response_code_bytes.data(), response_code_bytes.size());
32455 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32456 hash->Update(buffer.data(), buffer.size());
32457 std::string response_hash(32, 0);
32458 hash->Finish(std::data(response_hash), response_hash.size());
32459 if (tag == TPM_ST_SESSIONS) {
32460 if (!authorization_delegate)
32461 return TRUNKS_RC_AUTHORIZATION_FAILED;
32462 if (!authorization_delegate->CheckResponseAuthorization(
32463 response_hash, authorization_section_bytes)) {
32464 return TRUNKS_RC_AUTHORIZATION_FAILED;
32465 }
32466 }
32467 return TPM_RC_SUCCESS;
32468 }
32469
NV_WriteLockErrorCallback(Tpm::NV_WriteLockResponse callback,TPM_RC response_code)32470 void NV_WriteLockErrorCallback(Tpm::NV_WriteLockResponse callback,
32471 TPM_RC response_code) {
32472 VLOG(1) << __func__;
32473 std::move(callback).Run(response_code);
32474 }
32475
NV_WriteLockResponseParser(Tpm::NV_WriteLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32476 void NV_WriteLockResponseParser(Tpm::NV_WriteLockResponse callback,
32477 AuthorizationDelegate* authorization_delegate,
32478 const std::string& response) {
32479 VLOG(1) << __func__;
32480 TPM_RC rc = Tpm::ParseResponse_NV_WriteLock(response, authorization_delegate);
32481 if (rc != TPM_RC_SUCCESS) {
32482 base::OnceCallback<void(TPM_RC)> error_reporter =
32483 base::BindOnce(NV_WriteLockErrorCallback, std::move(callback));
32484 std::move(error_reporter).Run(rc);
32485 return;
32486 }
32487 std::move(callback).Run(rc);
32488 }
32489
NV_WriteLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_WriteLockResponse callback)32490 void Tpm::NV_WriteLock(const TPMI_RH_NV_AUTH& auth_handle,
32491 const std::string& auth_handle_name,
32492 const TPMI_RH_NV_INDEX& nv_index,
32493 const std::string& nv_index_name,
32494 AuthorizationDelegate* authorization_delegate,
32495 NV_WriteLockResponse callback) {
32496 VLOG(1) << __func__;
32497 std::string command;
32498 TPM_RC rc = SerializeCommand_NV_WriteLock(auth_handle, auth_handle_name,
32499 nv_index, nv_index_name, &command,
32500 authorization_delegate);
32501 if (rc != TPM_RC_SUCCESS) {
32502 base::OnceCallback<void(TPM_RC)> error_reporter =
32503 base::BindOnce(NV_WriteLockErrorCallback, std::move(callback));
32504 std::move(error_reporter).Run(rc);
32505 return;
32506 }
32507 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32508 NV_WriteLockResponseParser, std::move(callback), authorization_delegate);
32509 transceiver_->SendCommand(command, std::move(parser));
32510 }
32511
NV_WriteLockSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)32512 TPM_RC Tpm::NV_WriteLockSync(const TPMI_RH_NV_AUTH& auth_handle,
32513 const std::string& auth_handle_name,
32514 const TPMI_RH_NV_INDEX& nv_index,
32515 const std::string& nv_index_name,
32516 AuthorizationDelegate* authorization_delegate) {
32517 VLOG(1) << __func__;
32518 std::string command;
32519 TPM_RC rc = SerializeCommand_NV_WriteLock(auth_handle, auth_handle_name,
32520 nv_index, nv_index_name, &command,
32521 authorization_delegate);
32522 if (rc != TPM_RC_SUCCESS) {
32523 return rc;
32524 }
32525 std::string response = transceiver_->SendCommandAndWait(command);
32526 rc = ParseResponse_NV_WriteLock(response, authorization_delegate);
32527 return rc;
32528 }
32529
SerializeCommand_NV_GlobalWriteLock(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32530 TPM_RC Tpm::SerializeCommand_NV_GlobalWriteLock(
32531 const TPMI_RH_PROVISION& auth_handle,
32532 const std::string& auth_handle_name,
32533 std::string* serialized_command,
32534 AuthorizationDelegate* authorization_delegate) {
32535 VLOG(3) << __func__;
32536 TPM_RC rc = TPM_RC_SUCCESS;
32537 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32538 UINT32 command_size = 10; // Header size.
32539 std::string handle_section_bytes;
32540 std::string parameter_section_bytes;
32541 TPM_CC command_code = TPM_CC_NV_GlobalWriteLock;
32542 bool is_command_parameter_encryption_possible = false;
32543 bool is_response_parameter_encryption_possible = false;
32544 std::string command_code_bytes;
32545 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32546 if (rc != TPM_RC_SUCCESS) {
32547 return rc;
32548 }
32549 std::string auth_handle_bytes;
32550 rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
32551 if (rc != TPM_RC_SUCCESS) {
32552 return rc;
32553 }
32554 std::unique_ptr<crypto::SecureHash> hash(
32555 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32556 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32557 hash->Update(auth_handle_name.data(), auth_handle_name.size());
32558 handle_section_bytes += auth_handle_bytes;
32559 command_size += auth_handle_bytes.size();
32560 std::string command_hash(32, 0);
32561 hash->Finish(std::data(command_hash), command_hash.size());
32562 std::string authorization_section_bytes;
32563 std::string authorization_size_bytes;
32564 if (authorization_delegate) {
32565 if (!authorization_delegate->GetCommandAuthorization(
32566 command_hash, is_command_parameter_encryption_possible,
32567 is_response_parameter_encryption_possible,
32568 &authorization_section_bytes)) {
32569 return TRUNKS_RC_AUTHORIZATION_FAILED;
32570 }
32571 if (!authorization_section_bytes.empty()) {
32572 tag = TPM_ST_SESSIONS;
32573 std::string tmp;
32574 rc = Serialize_UINT32(authorization_section_bytes.size(),
32575 &authorization_size_bytes);
32576 if (rc != TPM_RC_SUCCESS) {
32577 return rc;
32578 }
32579 command_size +=
32580 authorization_size_bytes.size() + authorization_section_bytes.size();
32581 }
32582 }
32583 std::string tag_bytes;
32584 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32585 if (rc != TPM_RC_SUCCESS) {
32586 return rc;
32587 }
32588 std::string command_size_bytes;
32589 rc = Serialize_UINT32(command_size, &command_size_bytes);
32590 if (rc != TPM_RC_SUCCESS) {
32591 return rc;
32592 }
32593 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32594 handle_section_bytes + authorization_size_bytes +
32595 authorization_section_bytes + parameter_section_bytes;
32596 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32597 VLOG(2) << "Command: "
32598 << base::HexEncode(serialized_command->data(),
32599 serialized_command->size());
32600 return TPM_RC_SUCCESS;
32601 }
32602
ParseResponse_NV_GlobalWriteLock(const std::string & response,AuthorizationDelegate * authorization_delegate)32603 TPM_RC Tpm::ParseResponse_NV_GlobalWriteLock(
32604 const std::string& response,
32605 AuthorizationDelegate* authorization_delegate) {
32606 VLOG(3) << __func__;
32607 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32608 TPM_RC rc = TPM_RC_SUCCESS;
32609 std::string buffer(response);
32610 TPM_ST tag;
32611 std::string tag_bytes;
32612 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32613 if (rc != TPM_RC_SUCCESS) {
32614 return rc;
32615 }
32616 UINT32 response_size;
32617 std::string response_size_bytes;
32618 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32619 if (rc != TPM_RC_SUCCESS) {
32620 return rc;
32621 }
32622 TPM_RC response_code;
32623 std::string response_code_bytes;
32624 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32625 if (rc != TPM_RC_SUCCESS) {
32626 return rc;
32627 }
32628 if (response_size != response.size()) {
32629 return TPM_RC_SIZE;
32630 }
32631 if (response_code != TPM_RC_SUCCESS) {
32632 return response_code;
32633 }
32634 TPM_CC command_code = TPM_CC_NV_GlobalWriteLock;
32635 std::string command_code_bytes;
32636 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32637 if (rc != TPM_RC_SUCCESS) {
32638 return rc;
32639 }
32640 std::string authorization_section_bytes;
32641 if (tag == TPM_ST_SESSIONS) {
32642 UINT32 parameter_section_size = buffer.size();
32643 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
32644 if (rc != TPM_RC_SUCCESS) {
32645 return rc;
32646 }
32647 if (parameter_section_size > buffer.size()) {
32648 return TPM_RC_INSUFFICIENT;
32649 }
32650 authorization_section_bytes = buffer.substr(parameter_section_size);
32651 // Keep the parameter section in |buffer|.
32652 buffer.erase(parameter_section_size);
32653 }
32654 std::unique_ptr<crypto::SecureHash> hash(
32655 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32656 hash->Update(response_code_bytes.data(), response_code_bytes.size());
32657 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32658 hash->Update(buffer.data(), buffer.size());
32659 std::string response_hash(32, 0);
32660 hash->Finish(std::data(response_hash), response_hash.size());
32661 if (tag == TPM_ST_SESSIONS) {
32662 if (!authorization_delegate)
32663 return TRUNKS_RC_AUTHORIZATION_FAILED;
32664 if (!authorization_delegate->CheckResponseAuthorization(
32665 response_hash, authorization_section_bytes)) {
32666 return TRUNKS_RC_AUTHORIZATION_FAILED;
32667 }
32668 }
32669 return TPM_RC_SUCCESS;
32670 }
32671
NV_GlobalWriteLockErrorCallback(Tpm::NV_GlobalWriteLockResponse callback,TPM_RC response_code)32672 void NV_GlobalWriteLockErrorCallback(Tpm::NV_GlobalWriteLockResponse callback,
32673 TPM_RC response_code) {
32674 VLOG(1) << __func__;
32675 std::move(callback).Run(response_code);
32676 }
32677
NV_GlobalWriteLockResponseParser(Tpm::NV_GlobalWriteLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32678 void NV_GlobalWriteLockResponseParser(
32679 Tpm::NV_GlobalWriteLockResponse callback,
32680 AuthorizationDelegate* authorization_delegate,
32681 const std::string& response) {
32682 VLOG(1) << __func__;
32683 TPM_RC rc =
32684 Tpm::ParseResponse_NV_GlobalWriteLock(response, authorization_delegate);
32685 if (rc != TPM_RC_SUCCESS) {
32686 base::OnceCallback<void(TPM_RC)> error_reporter =
32687 base::BindOnce(NV_GlobalWriteLockErrorCallback, std::move(callback));
32688 std::move(error_reporter).Run(rc);
32689 return;
32690 }
32691 std::move(callback).Run(rc);
32692 }
32693
NV_GlobalWriteLock(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,NV_GlobalWriteLockResponse callback)32694 void Tpm::NV_GlobalWriteLock(const TPMI_RH_PROVISION& auth_handle,
32695 const std::string& auth_handle_name,
32696 AuthorizationDelegate* authorization_delegate,
32697 NV_GlobalWriteLockResponse callback) {
32698 VLOG(1) << __func__;
32699 std::string command;
32700 TPM_RC rc = SerializeCommand_NV_GlobalWriteLock(
32701 auth_handle, auth_handle_name, &command, authorization_delegate);
32702 if (rc != TPM_RC_SUCCESS) {
32703 base::OnceCallback<void(TPM_RC)> error_reporter =
32704 base::BindOnce(NV_GlobalWriteLockErrorCallback, std::move(callback));
32705 std::move(error_reporter).Run(rc);
32706 return;
32707 }
32708 base::OnceCallback<void(const std::string&)> parser =
32709 base::BindOnce(NV_GlobalWriteLockResponseParser, std::move(callback),
32710 authorization_delegate);
32711 transceiver_->SendCommand(command, std::move(parser));
32712 }
32713
NV_GlobalWriteLockSync(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)32714 TPM_RC Tpm::NV_GlobalWriteLockSync(
32715 const TPMI_RH_PROVISION& auth_handle,
32716 const std::string& auth_handle_name,
32717 AuthorizationDelegate* authorization_delegate) {
32718 VLOG(1) << __func__;
32719 std::string command;
32720 TPM_RC rc = SerializeCommand_NV_GlobalWriteLock(
32721 auth_handle, auth_handle_name, &command, authorization_delegate);
32722 if (rc != TPM_RC_SUCCESS) {
32723 return rc;
32724 }
32725 std::string response = transceiver_->SendCommandAndWait(command);
32726 rc = ParseResponse_NV_GlobalWriteLock(response, authorization_delegate);
32727 return rc;
32728 }
32729
SerializeCommand_NV_Read(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT16 & size,const UINT16 & offset,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32730 TPM_RC Tpm::SerializeCommand_NV_Read(
32731 const TPMI_RH_NV_AUTH& auth_handle,
32732 const std::string& auth_handle_name,
32733 const TPMI_RH_NV_INDEX& nv_index,
32734 const std::string& nv_index_name,
32735 const UINT16& size,
32736 const UINT16& offset,
32737 std::string* serialized_command,
32738 AuthorizationDelegate* authorization_delegate) {
32739 VLOG(3) << __func__;
32740 TPM_RC rc = TPM_RC_SUCCESS;
32741 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32742 UINT32 command_size = 10; // Header size.
32743 std::string handle_section_bytes;
32744 std::string parameter_section_bytes;
32745 TPM_CC command_code = TPM_CC_NV_Read;
32746 bool is_command_parameter_encryption_possible = false;
32747 bool is_response_parameter_encryption_possible = true;
32748 std::string command_code_bytes;
32749 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32750 if (rc != TPM_RC_SUCCESS) {
32751 return rc;
32752 }
32753 std::string auth_handle_bytes;
32754 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32755 if (rc != TPM_RC_SUCCESS) {
32756 return rc;
32757 }
32758 std::string nv_index_bytes;
32759 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32760 if (rc != TPM_RC_SUCCESS) {
32761 return rc;
32762 }
32763 std::string size_bytes;
32764 rc = Serialize_UINT16(size, &size_bytes);
32765 if (rc != TPM_RC_SUCCESS) {
32766 return rc;
32767 }
32768 std::string offset_bytes;
32769 rc = Serialize_UINT16(offset, &offset_bytes);
32770 if (rc != TPM_RC_SUCCESS) {
32771 return rc;
32772 }
32773 std::unique_ptr<crypto::SecureHash> hash(
32774 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32775 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32776 hash->Update(auth_handle_name.data(), auth_handle_name.size());
32777 handle_section_bytes += auth_handle_bytes;
32778 command_size += auth_handle_bytes.size();
32779 hash->Update(nv_index_name.data(), nv_index_name.size());
32780 handle_section_bytes += nv_index_bytes;
32781 command_size += nv_index_bytes.size();
32782 hash->Update(size_bytes.data(), size_bytes.size());
32783 parameter_section_bytes += size_bytes;
32784 command_size += size_bytes.size();
32785 hash->Update(offset_bytes.data(), offset_bytes.size());
32786 parameter_section_bytes += offset_bytes;
32787 command_size += offset_bytes.size();
32788 std::string command_hash(32, 0);
32789 hash->Finish(std::data(command_hash), command_hash.size());
32790 std::string authorization_section_bytes;
32791 std::string authorization_size_bytes;
32792 if (authorization_delegate) {
32793 if (!authorization_delegate->GetCommandAuthorization(
32794 command_hash, is_command_parameter_encryption_possible,
32795 is_response_parameter_encryption_possible,
32796 &authorization_section_bytes)) {
32797 return TRUNKS_RC_AUTHORIZATION_FAILED;
32798 }
32799 if (!authorization_section_bytes.empty()) {
32800 tag = TPM_ST_SESSIONS;
32801 std::string tmp;
32802 rc = Serialize_UINT32(authorization_section_bytes.size(),
32803 &authorization_size_bytes);
32804 if (rc != TPM_RC_SUCCESS) {
32805 return rc;
32806 }
32807 command_size +=
32808 authorization_size_bytes.size() + authorization_section_bytes.size();
32809 }
32810 }
32811 std::string tag_bytes;
32812 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32813 if (rc != TPM_RC_SUCCESS) {
32814 return rc;
32815 }
32816 std::string command_size_bytes;
32817 rc = Serialize_UINT32(command_size, &command_size_bytes);
32818 if (rc != TPM_RC_SUCCESS) {
32819 return rc;
32820 }
32821 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32822 handle_section_bytes + authorization_size_bytes +
32823 authorization_section_bytes + parameter_section_bytes;
32824 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32825 VLOG(2) << "Command: "
32826 << base::HexEncode(serialized_command->data(),
32827 serialized_command->size());
32828 return TPM_RC_SUCCESS;
32829 }
32830
ParseResponse_NV_Read(const std::string & response,TPM2B_MAX_NV_BUFFER * data,AuthorizationDelegate * authorization_delegate)32831 TPM_RC Tpm::ParseResponse_NV_Read(
32832 const std::string& response,
32833 TPM2B_MAX_NV_BUFFER* data,
32834 AuthorizationDelegate* authorization_delegate) {
32835 VLOG(3) << __func__;
32836 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32837 TPM_RC rc = TPM_RC_SUCCESS;
32838 std::string buffer(response);
32839 TPM_ST tag;
32840 std::string tag_bytes;
32841 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32842 if (rc != TPM_RC_SUCCESS) {
32843 return rc;
32844 }
32845 UINT32 response_size;
32846 std::string response_size_bytes;
32847 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32848 if (rc != TPM_RC_SUCCESS) {
32849 return rc;
32850 }
32851 TPM_RC response_code;
32852 std::string response_code_bytes;
32853 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32854 if (rc != TPM_RC_SUCCESS) {
32855 return rc;
32856 }
32857 if (response_size != response.size()) {
32858 return TPM_RC_SIZE;
32859 }
32860 if (response_code != TPM_RC_SUCCESS) {
32861 return response_code;
32862 }
32863 TPM_CC command_code = TPM_CC_NV_Read;
32864 std::string command_code_bytes;
32865 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32866 if (rc != TPM_RC_SUCCESS) {
32867 return rc;
32868 }
32869 std::string authorization_section_bytes;
32870 if (tag == TPM_ST_SESSIONS) {
32871 UINT32 parameter_section_size = buffer.size();
32872 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
32873 if (rc != TPM_RC_SUCCESS) {
32874 return rc;
32875 }
32876 if (parameter_section_size > buffer.size()) {
32877 return TPM_RC_INSUFFICIENT;
32878 }
32879 authorization_section_bytes = buffer.substr(parameter_section_size);
32880 // Keep the parameter section in |buffer|.
32881 buffer.erase(parameter_section_size);
32882 }
32883 std::unique_ptr<crypto::SecureHash> hash(
32884 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32885 hash->Update(response_code_bytes.data(), response_code_bytes.size());
32886 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32887 hash->Update(buffer.data(), buffer.size());
32888 std::string response_hash(32, 0);
32889 hash->Finish(std::data(response_hash), response_hash.size());
32890 if (tag == TPM_ST_SESSIONS) {
32891 if (!authorization_delegate)
32892 return TRUNKS_RC_AUTHORIZATION_FAILED;
32893 if (!authorization_delegate->CheckResponseAuthorization(
32894 response_hash, authorization_section_bytes)) {
32895 return TRUNKS_RC_AUTHORIZATION_FAILED;
32896 }
32897 }
32898 if (tag == TPM_ST_SESSIONS) {
32899 if (!authorization_delegate)
32900 return TRUNKS_RC_AUTHORIZATION_FAILED;
32901
32902 // Parse the encrypted parameter size.
32903 UINT16 size;
32904 std::string size_buffer = buffer.substr(0, 2);
32905 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
32906 return result;
32907 }
32908 if (buffer.size() < 2 + size) {
32909 return TPM_RC_INSUFFICIENT;
32910 }
32911
32912 // Decrypt just the parameter data, not the size.
32913 std::string decrypted_data = buffer.substr(2, size);
32914 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
32915 return TRUNKS_RC_ENCRYPTION_FAILED;
32916 }
32917 buffer.replace(2, size, decrypted_data);
32918 }
32919 std::string data_bytes;
32920 rc = Parse_TPM2B_MAX_NV_BUFFER(&buffer, data, &data_bytes);
32921 if (rc != TPM_RC_SUCCESS) {
32922 return rc;
32923 }
32924 return TPM_RC_SUCCESS;
32925 }
32926
NV_ReadErrorCallback(Tpm::NV_ReadResponse callback,TPM_RC response_code)32927 void NV_ReadErrorCallback(Tpm::NV_ReadResponse callback, TPM_RC response_code) {
32928 VLOG(1) << __func__;
32929 std::move(callback).Run(response_code, TPM2B_MAX_NV_BUFFER());
32930 }
32931
NV_ReadResponseParser(Tpm::NV_ReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32932 void NV_ReadResponseParser(Tpm::NV_ReadResponse callback,
32933 AuthorizationDelegate* authorization_delegate,
32934 const std::string& response) {
32935 VLOG(1) << __func__;
32936 TPM2B_MAX_NV_BUFFER data;
32937 TPM_RC rc =
32938 Tpm::ParseResponse_NV_Read(response, &data, authorization_delegate);
32939 if (rc != TPM_RC_SUCCESS) {
32940 base::OnceCallback<void(TPM_RC)> error_reporter =
32941 base::BindOnce(NV_ReadErrorCallback, std::move(callback));
32942 std::move(error_reporter).Run(rc);
32943 return;
32944 }
32945 std::move(callback).Run(rc, data);
32946 }
32947
NV_Read(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT16 & size,const UINT16 & offset,AuthorizationDelegate * authorization_delegate,NV_ReadResponse callback)32948 void Tpm::NV_Read(const TPMI_RH_NV_AUTH& auth_handle,
32949 const std::string& auth_handle_name,
32950 const TPMI_RH_NV_INDEX& nv_index,
32951 const std::string& nv_index_name,
32952 const UINT16& size,
32953 const UINT16& offset,
32954 AuthorizationDelegate* authorization_delegate,
32955 NV_ReadResponse callback) {
32956 VLOG(1) << __func__;
32957 std::string command;
32958 TPM_RC rc = SerializeCommand_NV_Read(auth_handle, auth_handle_name, nv_index,
32959 nv_index_name, size, offset, &command,
32960 authorization_delegate);
32961 if (rc != TPM_RC_SUCCESS) {
32962 base::OnceCallback<void(TPM_RC)> error_reporter =
32963 base::BindOnce(NV_ReadErrorCallback, std::move(callback));
32964 std::move(error_reporter).Run(rc);
32965 return;
32966 }
32967 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32968 NV_ReadResponseParser, std::move(callback), authorization_delegate);
32969 transceiver_->SendCommand(command, std::move(parser));
32970 }
32971
NV_ReadSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT16 & size,const UINT16 & offset,TPM2B_MAX_NV_BUFFER * data,AuthorizationDelegate * authorization_delegate)32972 TPM_RC Tpm::NV_ReadSync(const TPMI_RH_NV_AUTH& auth_handle,
32973 const std::string& auth_handle_name,
32974 const TPMI_RH_NV_INDEX& nv_index,
32975 const std::string& nv_index_name,
32976 const UINT16& size,
32977 const UINT16& offset,
32978 TPM2B_MAX_NV_BUFFER* data,
32979 AuthorizationDelegate* authorization_delegate) {
32980 VLOG(1) << __func__;
32981 std::string command;
32982 TPM_RC rc = SerializeCommand_NV_Read(auth_handle, auth_handle_name, nv_index,
32983 nv_index_name, size, offset, &command,
32984 authorization_delegate);
32985 if (rc != TPM_RC_SUCCESS) {
32986 return rc;
32987 }
32988 std::string response = transceiver_->SendCommandAndWait(command);
32989 rc = ParseResponse_NV_Read(response, data, authorization_delegate);
32990 return rc;
32991 }
32992
SerializeCommand_NV_ReadLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32993 TPM_RC Tpm::SerializeCommand_NV_ReadLock(
32994 const TPMI_RH_NV_AUTH& auth_handle,
32995 const std::string& auth_handle_name,
32996 const TPMI_RH_NV_INDEX& nv_index,
32997 const std::string& nv_index_name,
32998 std::string* serialized_command,
32999 AuthorizationDelegate* authorization_delegate) {
33000 VLOG(3) << __func__;
33001 TPM_RC rc = TPM_RC_SUCCESS;
33002 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33003 UINT32 command_size = 10; // Header size.
33004 std::string handle_section_bytes;
33005 std::string parameter_section_bytes;
33006 TPM_CC command_code = TPM_CC_NV_ReadLock;
33007 bool is_command_parameter_encryption_possible = false;
33008 bool is_response_parameter_encryption_possible = false;
33009 std::string command_code_bytes;
33010 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33011 if (rc != TPM_RC_SUCCESS) {
33012 return rc;
33013 }
33014 std::string auth_handle_bytes;
33015 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
33016 if (rc != TPM_RC_SUCCESS) {
33017 return rc;
33018 }
33019 std::string nv_index_bytes;
33020 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33021 if (rc != TPM_RC_SUCCESS) {
33022 return rc;
33023 }
33024 std::unique_ptr<crypto::SecureHash> hash(
33025 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33026 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33027 hash->Update(auth_handle_name.data(), auth_handle_name.size());
33028 handle_section_bytes += auth_handle_bytes;
33029 command_size += auth_handle_bytes.size();
33030 hash->Update(nv_index_name.data(), nv_index_name.size());
33031 handle_section_bytes += nv_index_bytes;
33032 command_size += nv_index_bytes.size();
33033 std::string command_hash(32, 0);
33034 hash->Finish(std::data(command_hash), command_hash.size());
33035 std::string authorization_section_bytes;
33036 std::string authorization_size_bytes;
33037 if (authorization_delegate) {
33038 if (!authorization_delegate->GetCommandAuthorization(
33039 command_hash, is_command_parameter_encryption_possible,
33040 is_response_parameter_encryption_possible,
33041 &authorization_section_bytes)) {
33042 return TRUNKS_RC_AUTHORIZATION_FAILED;
33043 }
33044 if (!authorization_section_bytes.empty()) {
33045 tag = TPM_ST_SESSIONS;
33046 std::string tmp;
33047 rc = Serialize_UINT32(authorization_section_bytes.size(),
33048 &authorization_size_bytes);
33049 if (rc != TPM_RC_SUCCESS) {
33050 return rc;
33051 }
33052 command_size +=
33053 authorization_size_bytes.size() + authorization_section_bytes.size();
33054 }
33055 }
33056 std::string tag_bytes;
33057 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33058 if (rc != TPM_RC_SUCCESS) {
33059 return rc;
33060 }
33061 std::string command_size_bytes;
33062 rc = Serialize_UINT32(command_size, &command_size_bytes);
33063 if (rc != TPM_RC_SUCCESS) {
33064 return rc;
33065 }
33066 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33067 handle_section_bytes + authorization_size_bytes +
33068 authorization_section_bytes + parameter_section_bytes;
33069 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33070 VLOG(2) << "Command: "
33071 << base::HexEncode(serialized_command->data(),
33072 serialized_command->size());
33073 return TPM_RC_SUCCESS;
33074 }
33075
ParseResponse_NV_ReadLock(const std::string & response,AuthorizationDelegate * authorization_delegate)33076 TPM_RC Tpm::ParseResponse_NV_ReadLock(
33077 const std::string& response,
33078 AuthorizationDelegate* authorization_delegate) {
33079 VLOG(3) << __func__;
33080 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33081 TPM_RC rc = TPM_RC_SUCCESS;
33082 std::string buffer(response);
33083 TPM_ST tag;
33084 std::string tag_bytes;
33085 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33086 if (rc != TPM_RC_SUCCESS) {
33087 return rc;
33088 }
33089 UINT32 response_size;
33090 std::string response_size_bytes;
33091 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33092 if (rc != TPM_RC_SUCCESS) {
33093 return rc;
33094 }
33095 TPM_RC response_code;
33096 std::string response_code_bytes;
33097 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33098 if (rc != TPM_RC_SUCCESS) {
33099 return rc;
33100 }
33101 if (response_size != response.size()) {
33102 return TPM_RC_SIZE;
33103 }
33104 if (response_code != TPM_RC_SUCCESS) {
33105 return response_code;
33106 }
33107 TPM_CC command_code = TPM_CC_NV_ReadLock;
33108 std::string command_code_bytes;
33109 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33110 if (rc != TPM_RC_SUCCESS) {
33111 return rc;
33112 }
33113 std::string authorization_section_bytes;
33114 if (tag == TPM_ST_SESSIONS) {
33115 UINT32 parameter_section_size = buffer.size();
33116 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
33117 if (rc != TPM_RC_SUCCESS) {
33118 return rc;
33119 }
33120 if (parameter_section_size > buffer.size()) {
33121 return TPM_RC_INSUFFICIENT;
33122 }
33123 authorization_section_bytes = buffer.substr(parameter_section_size);
33124 // Keep the parameter section in |buffer|.
33125 buffer.erase(parameter_section_size);
33126 }
33127 std::unique_ptr<crypto::SecureHash> hash(
33128 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33129 hash->Update(response_code_bytes.data(), response_code_bytes.size());
33130 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33131 hash->Update(buffer.data(), buffer.size());
33132 std::string response_hash(32, 0);
33133 hash->Finish(std::data(response_hash), response_hash.size());
33134 if (tag == TPM_ST_SESSIONS) {
33135 if (!authorization_delegate)
33136 return TRUNKS_RC_AUTHORIZATION_FAILED;
33137 if (!authorization_delegate->CheckResponseAuthorization(
33138 response_hash, authorization_section_bytes)) {
33139 return TRUNKS_RC_AUTHORIZATION_FAILED;
33140 }
33141 }
33142 return TPM_RC_SUCCESS;
33143 }
33144
NV_ReadLockErrorCallback(Tpm::NV_ReadLockResponse callback,TPM_RC response_code)33145 void NV_ReadLockErrorCallback(Tpm::NV_ReadLockResponse callback,
33146 TPM_RC response_code) {
33147 VLOG(1) << __func__;
33148 std::move(callback).Run(response_code);
33149 }
33150
NV_ReadLockResponseParser(Tpm::NV_ReadLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33151 void NV_ReadLockResponseParser(Tpm::NV_ReadLockResponse callback,
33152 AuthorizationDelegate* authorization_delegate,
33153 const std::string& response) {
33154 VLOG(1) << __func__;
33155 TPM_RC rc = Tpm::ParseResponse_NV_ReadLock(response, authorization_delegate);
33156 if (rc != TPM_RC_SUCCESS) {
33157 base::OnceCallback<void(TPM_RC)> error_reporter =
33158 base::BindOnce(NV_ReadLockErrorCallback, std::move(callback));
33159 std::move(error_reporter).Run(rc);
33160 return;
33161 }
33162 std::move(callback).Run(rc);
33163 }
33164
NV_ReadLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_ReadLockResponse callback)33165 void Tpm::NV_ReadLock(const TPMI_RH_NV_AUTH& auth_handle,
33166 const std::string& auth_handle_name,
33167 const TPMI_RH_NV_INDEX& nv_index,
33168 const std::string& nv_index_name,
33169 AuthorizationDelegate* authorization_delegate,
33170 NV_ReadLockResponse callback) {
33171 VLOG(1) << __func__;
33172 std::string command;
33173 TPM_RC rc = SerializeCommand_NV_ReadLock(auth_handle, auth_handle_name,
33174 nv_index, nv_index_name, &command,
33175 authorization_delegate);
33176 if (rc != TPM_RC_SUCCESS) {
33177 base::OnceCallback<void(TPM_RC)> error_reporter =
33178 base::BindOnce(NV_ReadLockErrorCallback, std::move(callback));
33179 std::move(error_reporter).Run(rc);
33180 return;
33181 }
33182 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33183 NV_ReadLockResponseParser, std::move(callback), authorization_delegate);
33184 transceiver_->SendCommand(command, std::move(parser));
33185 }
33186
NV_ReadLockSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)33187 TPM_RC Tpm::NV_ReadLockSync(const TPMI_RH_NV_AUTH& auth_handle,
33188 const std::string& auth_handle_name,
33189 const TPMI_RH_NV_INDEX& nv_index,
33190 const std::string& nv_index_name,
33191 AuthorizationDelegate* authorization_delegate) {
33192 VLOG(1) << __func__;
33193 std::string command;
33194 TPM_RC rc = SerializeCommand_NV_ReadLock(auth_handle, auth_handle_name,
33195 nv_index, nv_index_name, &command,
33196 authorization_delegate);
33197 if (rc != TPM_RC_SUCCESS) {
33198 return rc;
33199 }
33200 std::string response = transceiver_->SendCommandAndWait(command);
33201 rc = ParseResponse_NV_ReadLock(response, authorization_delegate);
33202 return rc;
33203 }
33204
SerializeCommand_NV_ChangeAuth(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_AUTH & new_auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)33205 TPM_RC Tpm::SerializeCommand_NV_ChangeAuth(
33206 const TPMI_RH_NV_INDEX& nv_index,
33207 const std::string& nv_index_name,
33208 const TPM2B_AUTH& new_auth,
33209 std::string* serialized_command,
33210 AuthorizationDelegate* authorization_delegate) {
33211 VLOG(3) << __func__;
33212 TPM_RC rc = TPM_RC_SUCCESS;
33213 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33214 UINT32 command_size = 10; // Header size.
33215 std::string handle_section_bytes;
33216 std::string parameter_section_bytes;
33217 TPM_CC command_code = TPM_CC_NV_ChangeAuth;
33218 bool is_command_parameter_encryption_possible = true;
33219 bool is_response_parameter_encryption_possible = false;
33220 std::string command_code_bytes;
33221 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33222 if (rc != TPM_RC_SUCCESS) {
33223 return rc;
33224 }
33225 std::string nv_index_bytes;
33226 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33227 if (rc != TPM_RC_SUCCESS) {
33228 return rc;
33229 }
33230 std::string new_auth_bytes;
33231 rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
33232 if (rc != TPM_RC_SUCCESS) {
33233 return rc;
33234 }
33235 if (authorization_delegate) {
33236 // Encrypt just the parameter data, not the size.
33237 std::string tmp = new_auth_bytes.substr(2);
33238 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
33239 return TRUNKS_RC_ENCRYPTION_FAILED;
33240 }
33241 new_auth_bytes.replace(2, std::string::npos, tmp);
33242 }
33243 std::unique_ptr<crypto::SecureHash> hash(
33244 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33245 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33246 hash->Update(nv_index_name.data(), nv_index_name.size());
33247 handle_section_bytes += nv_index_bytes;
33248 command_size += nv_index_bytes.size();
33249 hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
33250 parameter_section_bytes += new_auth_bytes;
33251 command_size += new_auth_bytes.size();
33252 std::string command_hash(32, 0);
33253 hash->Finish(std::data(command_hash), command_hash.size());
33254 std::string authorization_section_bytes;
33255 std::string authorization_size_bytes;
33256 if (authorization_delegate) {
33257 if (!authorization_delegate->GetCommandAuthorization(
33258 command_hash, is_command_parameter_encryption_possible,
33259 is_response_parameter_encryption_possible,
33260 &authorization_section_bytes)) {
33261 return TRUNKS_RC_AUTHORIZATION_FAILED;
33262 }
33263 if (!authorization_section_bytes.empty()) {
33264 tag = TPM_ST_SESSIONS;
33265 std::string tmp;
33266 rc = Serialize_UINT32(authorization_section_bytes.size(),
33267 &authorization_size_bytes);
33268 if (rc != TPM_RC_SUCCESS) {
33269 return rc;
33270 }
33271 command_size +=
33272 authorization_size_bytes.size() + authorization_section_bytes.size();
33273 }
33274 }
33275 std::string tag_bytes;
33276 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33277 if (rc != TPM_RC_SUCCESS) {
33278 return rc;
33279 }
33280 std::string command_size_bytes;
33281 rc = Serialize_UINT32(command_size, &command_size_bytes);
33282 if (rc != TPM_RC_SUCCESS) {
33283 return rc;
33284 }
33285 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33286 handle_section_bytes + authorization_size_bytes +
33287 authorization_section_bytes + parameter_section_bytes;
33288 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33289 VLOG(2) << "Command: "
33290 << base::HexEncode(serialized_command->data(),
33291 serialized_command->size());
33292 return TPM_RC_SUCCESS;
33293 }
33294
ParseResponse_NV_ChangeAuth(const std::string & response,AuthorizationDelegate * authorization_delegate)33295 TPM_RC Tpm::ParseResponse_NV_ChangeAuth(
33296 const std::string& response,
33297 AuthorizationDelegate* authorization_delegate) {
33298 VLOG(3) << __func__;
33299 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33300 TPM_RC rc = TPM_RC_SUCCESS;
33301 std::string buffer(response);
33302 TPM_ST tag;
33303 std::string tag_bytes;
33304 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33305 if (rc != TPM_RC_SUCCESS) {
33306 return rc;
33307 }
33308 UINT32 response_size;
33309 std::string response_size_bytes;
33310 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33311 if (rc != TPM_RC_SUCCESS) {
33312 return rc;
33313 }
33314 TPM_RC response_code;
33315 std::string response_code_bytes;
33316 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33317 if (rc != TPM_RC_SUCCESS) {
33318 return rc;
33319 }
33320 if (response_size != response.size()) {
33321 return TPM_RC_SIZE;
33322 }
33323 if (response_code != TPM_RC_SUCCESS) {
33324 return response_code;
33325 }
33326 TPM_CC command_code = TPM_CC_NV_ChangeAuth;
33327 std::string command_code_bytes;
33328 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33329 if (rc != TPM_RC_SUCCESS) {
33330 return rc;
33331 }
33332 std::string authorization_section_bytes;
33333 if (tag == TPM_ST_SESSIONS) {
33334 UINT32 parameter_section_size = buffer.size();
33335 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
33336 if (rc != TPM_RC_SUCCESS) {
33337 return rc;
33338 }
33339 if (parameter_section_size > buffer.size()) {
33340 return TPM_RC_INSUFFICIENT;
33341 }
33342 authorization_section_bytes = buffer.substr(parameter_section_size);
33343 // Keep the parameter section in |buffer|.
33344 buffer.erase(parameter_section_size);
33345 }
33346 std::unique_ptr<crypto::SecureHash> hash(
33347 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33348 hash->Update(response_code_bytes.data(), response_code_bytes.size());
33349 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33350 hash->Update(buffer.data(), buffer.size());
33351 std::string response_hash(32, 0);
33352 hash->Finish(std::data(response_hash), response_hash.size());
33353 if (tag == TPM_ST_SESSIONS) {
33354 if (!authorization_delegate)
33355 return TRUNKS_RC_AUTHORIZATION_FAILED;
33356 if (!authorization_delegate->CheckResponseAuthorization(
33357 response_hash, authorization_section_bytes)) {
33358 return TRUNKS_RC_AUTHORIZATION_FAILED;
33359 }
33360 }
33361 return TPM_RC_SUCCESS;
33362 }
33363
NV_ChangeAuthErrorCallback(Tpm::NV_ChangeAuthResponse callback,TPM_RC response_code)33364 void NV_ChangeAuthErrorCallback(Tpm::NV_ChangeAuthResponse callback,
33365 TPM_RC response_code) {
33366 VLOG(1) << __func__;
33367 std::move(callback).Run(response_code);
33368 }
33369
NV_ChangeAuthResponseParser(Tpm::NV_ChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33370 void NV_ChangeAuthResponseParser(Tpm::NV_ChangeAuthResponse callback,
33371 AuthorizationDelegate* authorization_delegate,
33372 const std::string& response) {
33373 VLOG(1) << __func__;
33374 TPM_RC rc =
33375 Tpm::ParseResponse_NV_ChangeAuth(response, authorization_delegate);
33376 if (rc != TPM_RC_SUCCESS) {
33377 base::OnceCallback<void(TPM_RC)> error_reporter =
33378 base::BindOnce(NV_ChangeAuthErrorCallback, std::move(callback));
33379 std::move(error_reporter).Run(rc);
33380 return;
33381 }
33382 std::move(callback).Run(rc);
33383 }
33384
NV_ChangeAuth(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate,NV_ChangeAuthResponse callback)33385 void Tpm::NV_ChangeAuth(const TPMI_RH_NV_INDEX& nv_index,
33386 const std::string& nv_index_name,
33387 const TPM2B_AUTH& new_auth,
33388 AuthorizationDelegate* authorization_delegate,
33389 NV_ChangeAuthResponse callback) {
33390 VLOG(1) << __func__;
33391 std::string command;
33392 TPM_RC rc = SerializeCommand_NV_ChangeAuth(nv_index, nv_index_name, new_auth,
33393 &command, authorization_delegate);
33394 if (rc != TPM_RC_SUCCESS) {
33395 base::OnceCallback<void(TPM_RC)> error_reporter =
33396 base::BindOnce(NV_ChangeAuthErrorCallback, std::move(callback));
33397 std::move(error_reporter).Run(rc);
33398 return;
33399 }
33400 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33401 NV_ChangeAuthResponseParser, std::move(callback), authorization_delegate);
33402 transceiver_->SendCommand(command, std::move(parser));
33403 }
33404
NV_ChangeAuthSync(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate)33405 TPM_RC Tpm::NV_ChangeAuthSync(const TPMI_RH_NV_INDEX& nv_index,
33406 const std::string& nv_index_name,
33407 const TPM2B_AUTH& new_auth,
33408 AuthorizationDelegate* authorization_delegate) {
33409 VLOG(1) << __func__;
33410 std::string command;
33411 TPM_RC rc = SerializeCommand_NV_ChangeAuth(nv_index, nv_index_name, new_auth,
33412 &command, authorization_delegate);
33413 if (rc != TPM_RC_SUCCESS) {
33414 return rc;
33415 }
33416 std::string response = transceiver_->SendCommandAndWait(command);
33417 rc = ParseResponse_NV_ChangeAuth(response, authorization_delegate);
33418 return rc;
33419 }
33420
SerializeCommand_NV_Certify(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const UINT16 & size,const UINT16 & offset,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)33421 TPM_RC Tpm::SerializeCommand_NV_Certify(
33422 const TPMI_DH_OBJECT& sign_handle,
33423 const std::string& sign_handle_name,
33424 const TPMI_RH_NV_AUTH& auth_handle,
33425 const std::string& auth_handle_name,
33426 const TPMI_RH_NV_INDEX& nv_index,
33427 const std::string& nv_index_name,
33428 const TPM2B_DATA& qualifying_data,
33429 const TPMT_SIG_SCHEME& in_scheme,
33430 const UINT16& size,
33431 const UINT16& offset,
33432 std::string* serialized_command,
33433 AuthorizationDelegate* authorization_delegate) {
33434 VLOG(3) << __func__;
33435 TPM_RC rc = TPM_RC_SUCCESS;
33436 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33437 UINT32 command_size = 10; // Header size.
33438 std::string handle_section_bytes;
33439 std::string parameter_section_bytes;
33440 TPM_CC command_code = TPM_CC_NV_Certify;
33441 bool is_command_parameter_encryption_possible = true;
33442 bool is_response_parameter_encryption_possible = true;
33443 std::string command_code_bytes;
33444 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33445 if (rc != TPM_RC_SUCCESS) {
33446 return rc;
33447 }
33448 std::string sign_handle_bytes;
33449 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
33450 if (rc != TPM_RC_SUCCESS) {
33451 return rc;
33452 }
33453 std::string auth_handle_bytes;
33454 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
33455 if (rc != TPM_RC_SUCCESS) {
33456 return rc;
33457 }
33458 std::string nv_index_bytes;
33459 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33460 if (rc != TPM_RC_SUCCESS) {
33461 return rc;
33462 }
33463 std::string qualifying_data_bytes;
33464 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
33465 if (rc != TPM_RC_SUCCESS) {
33466 return rc;
33467 }
33468 std::string in_scheme_bytes;
33469 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
33470 if (rc != TPM_RC_SUCCESS) {
33471 return rc;
33472 }
33473 std::string size_bytes;
33474 rc = Serialize_UINT16(size, &size_bytes);
33475 if (rc != TPM_RC_SUCCESS) {
33476 return rc;
33477 }
33478 std::string offset_bytes;
33479 rc = Serialize_UINT16(offset, &offset_bytes);
33480 if (rc != TPM_RC_SUCCESS) {
33481 return rc;
33482 }
33483 if (authorization_delegate) {
33484 // Encrypt just the parameter data, not the size.
33485 std::string tmp = qualifying_data_bytes.substr(2);
33486 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
33487 return TRUNKS_RC_ENCRYPTION_FAILED;
33488 }
33489 qualifying_data_bytes.replace(2, std::string::npos, tmp);
33490 }
33491 std::unique_ptr<crypto::SecureHash> hash(
33492 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33493 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33494 hash->Update(sign_handle_name.data(), sign_handle_name.size());
33495 handle_section_bytes += sign_handle_bytes;
33496 command_size += sign_handle_bytes.size();
33497 hash->Update(auth_handle_name.data(), auth_handle_name.size());
33498 handle_section_bytes += auth_handle_bytes;
33499 command_size += auth_handle_bytes.size();
33500 hash->Update(nv_index_name.data(), nv_index_name.size());
33501 handle_section_bytes += nv_index_bytes;
33502 command_size += nv_index_bytes.size();
33503 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
33504 parameter_section_bytes += qualifying_data_bytes;
33505 command_size += qualifying_data_bytes.size();
33506 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
33507 parameter_section_bytes += in_scheme_bytes;
33508 command_size += in_scheme_bytes.size();
33509 hash->Update(size_bytes.data(), size_bytes.size());
33510 parameter_section_bytes += size_bytes;
33511 command_size += size_bytes.size();
33512 hash->Update(offset_bytes.data(), offset_bytes.size());
33513 parameter_section_bytes += offset_bytes;
33514 command_size += offset_bytes.size();
33515 std::string command_hash(32, 0);
33516 hash->Finish(std::data(command_hash), command_hash.size());
33517 std::string authorization_section_bytes;
33518 std::string authorization_size_bytes;
33519 if (authorization_delegate) {
33520 if (!authorization_delegate->GetCommandAuthorization(
33521 command_hash, is_command_parameter_encryption_possible,
33522 is_response_parameter_encryption_possible,
33523 &authorization_section_bytes)) {
33524 return TRUNKS_RC_AUTHORIZATION_FAILED;
33525 }
33526 if (!authorization_section_bytes.empty()) {
33527 tag = TPM_ST_SESSIONS;
33528 std::string tmp;
33529 rc = Serialize_UINT32(authorization_section_bytes.size(),
33530 &authorization_size_bytes);
33531 if (rc != TPM_RC_SUCCESS) {
33532 return rc;
33533 }
33534 command_size +=
33535 authorization_size_bytes.size() + authorization_section_bytes.size();
33536 }
33537 }
33538 std::string tag_bytes;
33539 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33540 if (rc != TPM_RC_SUCCESS) {
33541 return rc;
33542 }
33543 std::string command_size_bytes;
33544 rc = Serialize_UINT32(command_size, &command_size_bytes);
33545 if (rc != TPM_RC_SUCCESS) {
33546 return rc;
33547 }
33548 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33549 handle_section_bytes + authorization_size_bytes +
33550 authorization_section_bytes + parameter_section_bytes;
33551 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33552 VLOG(2) << "Command: "
33553 << base::HexEncode(serialized_command->data(),
33554 serialized_command->size());
33555 return TPM_RC_SUCCESS;
33556 }
33557
ParseResponse_NV_Certify(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)33558 TPM_RC Tpm::ParseResponse_NV_Certify(
33559 const std::string& response,
33560 TPM2B_ATTEST* certify_info,
33561 TPMT_SIGNATURE* signature,
33562 AuthorizationDelegate* authorization_delegate) {
33563 VLOG(3) << __func__;
33564 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33565 TPM_RC rc = TPM_RC_SUCCESS;
33566 std::string buffer(response);
33567 TPM_ST tag;
33568 std::string tag_bytes;
33569 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33570 if (rc != TPM_RC_SUCCESS) {
33571 return rc;
33572 }
33573 UINT32 response_size;
33574 std::string response_size_bytes;
33575 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33576 if (rc != TPM_RC_SUCCESS) {
33577 return rc;
33578 }
33579 TPM_RC response_code;
33580 std::string response_code_bytes;
33581 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33582 if (rc != TPM_RC_SUCCESS) {
33583 return rc;
33584 }
33585 if (response_size != response.size()) {
33586 return TPM_RC_SIZE;
33587 }
33588 if (response_code != TPM_RC_SUCCESS) {
33589 return response_code;
33590 }
33591 TPM_CC command_code = TPM_CC_NV_Certify;
33592 std::string command_code_bytes;
33593 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33594 if (rc != TPM_RC_SUCCESS) {
33595 return rc;
33596 }
33597 std::string authorization_section_bytes;
33598 if (tag == TPM_ST_SESSIONS) {
33599 UINT32 parameter_section_size = buffer.size();
33600 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
33601 if (rc != TPM_RC_SUCCESS) {
33602 return rc;
33603 }
33604 if (parameter_section_size > buffer.size()) {
33605 return TPM_RC_INSUFFICIENT;
33606 }
33607 authorization_section_bytes = buffer.substr(parameter_section_size);
33608 // Keep the parameter section in |buffer|.
33609 buffer.erase(parameter_section_size);
33610 }
33611 std::unique_ptr<crypto::SecureHash> hash(
33612 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33613 hash->Update(response_code_bytes.data(), response_code_bytes.size());
33614 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33615 hash->Update(buffer.data(), buffer.size());
33616 std::string response_hash(32, 0);
33617 hash->Finish(std::data(response_hash), response_hash.size());
33618 if (tag == TPM_ST_SESSIONS) {
33619 if (!authorization_delegate)
33620 return TRUNKS_RC_AUTHORIZATION_FAILED;
33621 if (!authorization_delegate->CheckResponseAuthorization(
33622 response_hash, authorization_section_bytes)) {
33623 return TRUNKS_RC_AUTHORIZATION_FAILED;
33624 }
33625 }
33626 if (tag == TPM_ST_SESSIONS) {
33627 if (!authorization_delegate)
33628 return TRUNKS_RC_AUTHORIZATION_FAILED;
33629
33630 // Parse the encrypted parameter size.
33631 UINT16 size;
33632 std::string size_buffer = buffer.substr(0, 2);
33633 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
33634 return result;
33635 }
33636 if (buffer.size() < 2 + size) {
33637 return TPM_RC_INSUFFICIENT;
33638 }
33639
33640 // Decrypt just the parameter data, not the size.
33641 std::string decrypted_data = buffer.substr(2, size);
33642 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
33643 return TRUNKS_RC_ENCRYPTION_FAILED;
33644 }
33645 buffer.replace(2, size, decrypted_data);
33646 }
33647 std::string certify_info_bytes;
33648 rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
33649 if (rc != TPM_RC_SUCCESS) {
33650 return rc;
33651 }
33652 std::string signature_bytes;
33653 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
33654 if (rc != TPM_RC_SUCCESS) {
33655 return rc;
33656 }
33657 return TPM_RC_SUCCESS;
33658 }
33659
NV_CertifyErrorCallback(Tpm::NV_CertifyResponse callback,TPM_RC response_code)33660 void NV_CertifyErrorCallback(Tpm::NV_CertifyResponse callback,
33661 TPM_RC response_code) {
33662 VLOG(1) << __func__;
33663 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
33664 }
33665
NV_CertifyResponseParser(Tpm::NV_CertifyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33666 void NV_CertifyResponseParser(Tpm::NV_CertifyResponse callback,
33667 AuthorizationDelegate* authorization_delegate,
33668 const std::string& response) {
33669 VLOG(1) << __func__;
33670 TPM2B_ATTEST certify_info;
33671 TPMT_SIGNATURE signature;
33672 TPM_RC rc = Tpm::ParseResponse_NV_Certify(response, &certify_info, &signature,
33673 authorization_delegate);
33674 if (rc != TPM_RC_SUCCESS) {
33675 base::OnceCallback<void(TPM_RC)> error_reporter =
33676 base::BindOnce(NV_CertifyErrorCallback, std::move(callback));
33677 std::move(error_reporter).Run(rc);
33678 return;
33679 }
33680 std::move(callback).Run(rc, certify_info, signature);
33681 }
33682
NV_Certify(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const UINT16 & size,const UINT16 & offset,AuthorizationDelegate * authorization_delegate,NV_CertifyResponse callback)33683 void Tpm::NV_Certify(const TPMI_DH_OBJECT& sign_handle,
33684 const std::string& sign_handle_name,
33685 const TPMI_RH_NV_AUTH& auth_handle,
33686 const std::string& auth_handle_name,
33687 const TPMI_RH_NV_INDEX& nv_index,
33688 const std::string& nv_index_name,
33689 const TPM2B_DATA& qualifying_data,
33690 const TPMT_SIG_SCHEME& in_scheme,
33691 const UINT16& size,
33692 const UINT16& offset,
33693 AuthorizationDelegate* authorization_delegate,
33694 NV_CertifyResponse callback) {
33695 VLOG(1) << __func__;
33696 std::string command;
33697 TPM_RC rc = SerializeCommand_NV_Certify(
33698 sign_handle, sign_handle_name, auth_handle, auth_handle_name, nv_index,
33699 nv_index_name, qualifying_data, in_scheme, size, offset, &command,
33700 authorization_delegate);
33701 if (rc != TPM_RC_SUCCESS) {
33702 base::OnceCallback<void(TPM_RC)> error_reporter =
33703 base::BindOnce(NV_CertifyErrorCallback, std::move(callback));
33704 std::move(error_reporter).Run(rc);
33705 return;
33706 }
33707 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33708 NV_CertifyResponseParser, std::move(callback), authorization_delegate);
33709 transceiver_->SendCommand(command, std::move(parser));
33710 }
33711
NV_CertifySync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const UINT16 & size,const UINT16 & offset,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)33712 TPM_RC Tpm::NV_CertifySync(const TPMI_DH_OBJECT& sign_handle,
33713 const std::string& sign_handle_name,
33714 const TPMI_RH_NV_AUTH& auth_handle,
33715 const std::string& auth_handle_name,
33716 const TPMI_RH_NV_INDEX& nv_index,
33717 const std::string& nv_index_name,
33718 const TPM2B_DATA& qualifying_data,
33719 const TPMT_SIG_SCHEME& in_scheme,
33720 const UINT16& size,
33721 const UINT16& offset,
33722 TPM2B_ATTEST* certify_info,
33723 TPMT_SIGNATURE* signature,
33724 AuthorizationDelegate* authorization_delegate) {
33725 VLOG(1) << __func__;
33726 std::string command;
33727 TPM_RC rc = SerializeCommand_NV_Certify(
33728 sign_handle, sign_handle_name, auth_handle, auth_handle_name, nv_index,
33729 nv_index_name, qualifying_data, in_scheme, size, offset, &command,
33730 authorization_delegate);
33731 if (rc != TPM_RC_SUCCESS) {
33732 return rc;
33733 }
33734 std::string response = transceiver_->SendCommandAndWait(command);
33735 rc = ParseResponse_NV_Certify(response, certify_info, signature,
33736 authorization_delegate);
33737 return rc;
33738 }
33739
33740 } // namespace trunks
33741