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 // The severities are not compatible with each other (e.g. libchrome's INFO is 0
24 // but android-base's is 2), so we drop the severity information. This code can
25 // generate tons of output so we map everything to VERBOSE so it can easily be
26 // filtered out.
27 #define VLOG(x) LOG(VERBOSE)
28
29 namespace trunks {
30
GetNumberOfRequestHandles(TPM_CC command_code)31 size_t GetNumberOfRequestHandles(TPM_CC command_code) {
32 switch (command_code) {
33 case TPM_CC_Startup:
34 return 0;
35 case TPM_CC_Shutdown:
36 return 0;
37 case TPM_CC_SelfTest:
38 return 0;
39 case TPM_CC_IncrementalSelfTest:
40 return 0;
41 case TPM_CC_GetTestResult:
42 return 0;
43 case TPM_CC_StartAuthSession:
44 return 2;
45 case TPM_CC_PolicyRestart:
46 return 1;
47 case TPM_CC_Create:
48 return 1;
49 case TPM_CC_Load:
50 return 1;
51 case TPM_CC_LoadExternal:
52 return 0;
53 case TPM_CC_ReadPublic:
54 return 1;
55 case TPM_CC_ActivateCredential:
56 return 2;
57 case TPM_CC_MakeCredential:
58 return 1;
59 case TPM_CC_Unseal:
60 return 1;
61 case TPM_CC_ObjectChangeAuth:
62 return 2;
63 case TPM_CC_Duplicate:
64 return 2;
65 case TPM_CC_Rewrap:
66 return 2;
67 case TPM_CC_Import:
68 return 1;
69 case TPM_CC_RSA_Encrypt:
70 return 1;
71 case TPM_CC_RSA_Decrypt:
72 return 1;
73 case TPM_CC_ECDH_KeyGen:
74 return 1;
75 case TPM_CC_ECDH_ZGen:
76 return 1;
77 case TPM_CC_ECC_Parameters:
78 return 0;
79 case TPM_CC_ZGen_2Phase:
80 return 1;
81 case TPM_CC_EncryptDecrypt:
82 return 1;
83 case TPM_CC_Hash:
84 return 0;
85 case TPM_CC_HMAC:
86 return 1;
87 case TPM_CC_GetRandom:
88 return 0;
89 case TPM_CC_StirRandom:
90 return 0;
91 case TPM_CC_HMAC_Start:
92 return 1;
93 case TPM_CC_HashSequenceStart:
94 return 0;
95 case TPM_CC_SequenceUpdate:
96 return 1;
97 case TPM_CC_SequenceComplete:
98 return 1;
99 case TPM_CC_EventSequenceComplete:
100 return 2;
101 case TPM_CC_Certify:
102 return 2;
103 case TPM_CC_CertifyCreation:
104 return 2;
105 case TPM_CC_Quote:
106 return 1;
107 case TPM_CC_GetSessionAuditDigest:
108 return 3;
109 case TPM_CC_GetCommandAuditDigest:
110 return 2;
111 case TPM_CC_GetTime:
112 return 2;
113 case TPM_CC_Commit:
114 return 1;
115 case TPM_CC_EC_Ephemeral:
116 return 0;
117 case TPM_CC_VerifySignature:
118 return 1;
119 case TPM_CC_Sign:
120 return 1;
121 case TPM_CC_SetCommandCodeAuditStatus:
122 return 1;
123 case TPM_CC_PCR_Extend:
124 return 1;
125 case TPM_CC_PCR_Event:
126 return 1;
127 case TPM_CC_PCR_Read:
128 return 0;
129 case TPM_CC_PCR_Allocate:
130 return 1;
131 case TPM_CC_PCR_SetAuthPolicy:
132 return 2;
133 case TPM_CC_PCR_SetAuthValue:
134 return 1;
135 case TPM_CC_PCR_Reset:
136 return 1;
137 case TPM_CC_PolicySigned:
138 return 2;
139 case TPM_CC_PolicySecret:
140 return 2;
141 case TPM_CC_PolicyTicket:
142 return 1;
143 case TPM_CC_PolicyOR:
144 return 1;
145 case TPM_CC_PolicyPCR:
146 return 1;
147 case TPM_CC_PolicyLocality:
148 return 1;
149 case TPM_CC_PolicyNV:
150 return 3;
151 case TPM_CC_PolicyCounterTimer:
152 return 1;
153 case TPM_CC_PolicyCommandCode:
154 return 1;
155 case TPM_CC_PolicyPhysicalPresence:
156 return 1;
157 case TPM_CC_PolicyCpHash:
158 return 1;
159 case TPM_CC_PolicyNameHash:
160 return 1;
161 case TPM_CC_PolicyDuplicationSelect:
162 return 1;
163 case TPM_CC_PolicyAuthorize:
164 return 1;
165 case TPM_CC_PolicyAuthValue:
166 return 1;
167 case TPM_CC_PolicyPassword:
168 return 1;
169 case TPM_CC_PolicyGetDigest:
170 return 1;
171 case TPM_CC_PolicyNvWritten:
172 return 1;
173 case TPM_CC_CreatePrimary:
174 return 1;
175 case TPM_CC_HierarchyControl:
176 return 1;
177 case TPM_CC_SetPrimaryPolicy:
178 return 1;
179 case TPM_CC_ChangePPS:
180 return 1;
181 case TPM_CC_ChangeEPS:
182 return 1;
183 case TPM_CC_Clear:
184 return 1;
185 case TPM_CC_ClearControl:
186 return 1;
187 case TPM_CC_HierarchyChangeAuth:
188 return 1;
189 case TPM_CC_DictionaryAttackLockReset:
190 return 1;
191 case TPM_CC_DictionaryAttackParameters:
192 return 1;
193 case TPM_CC_PP_Commands:
194 return 1;
195 case TPM_CC_SetAlgorithmSet:
196 return 1;
197 case TPM_CC_FieldUpgradeStart:
198 return 2;
199 case TPM_CC_FieldUpgradeData:
200 return 0;
201 case TPM_CC_FirmwareRead:
202 return 0;
203 case TPM_CC_ContextSave:
204 return 1;
205 case TPM_CC_ContextLoad:
206 return 0;
207 case TPM_CC_FlushContext:
208 return 0;
209 case TPM_CC_EvictControl:
210 return 2;
211 case TPM_CC_ReadClock:
212 return 0;
213 case TPM_CC_ClockSet:
214 return 1;
215 case TPM_CC_ClockRateAdjust:
216 return 1;
217 case TPM_CC_GetCapability:
218 return 0;
219 case TPM_CC_TestParms:
220 return 0;
221 case TPM_CC_NV_DefineSpace:
222 return 1;
223 case TPM_CC_NV_UndefineSpace:
224 return 2;
225 case TPM_CC_NV_UndefineSpaceSpecial:
226 return 2;
227 case TPM_CC_NV_ReadPublic:
228 return 1;
229 case TPM_CC_NV_Write:
230 return 2;
231 case TPM_CC_NV_Increment:
232 return 2;
233 case TPM_CC_NV_Extend:
234 return 2;
235 case TPM_CC_NV_SetBits:
236 return 2;
237 case TPM_CC_NV_WriteLock:
238 return 2;
239 case TPM_CC_NV_GlobalWriteLock:
240 return 1;
241 case TPM_CC_NV_Read:
242 return 2;
243 case TPM_CC_NV_ReadLock:
244 return 2;
245 case TPM_CC_NV_ChangeAuth:
246 return 1;
247 case TPM_CC_NV_Certify:
248 return 3;
249 case TPM_CCE_PolicyFidoSigned:
250 return 2;
251 default:
252 LOG(WARNING) << "Unknown command code: " << command_code;
253 }
254 return 0;
255 }
256
GetNumberOfResponseHandles(TPM_CC command_code)257 size_t GetNumberOfResponseHandles(TPM_CC command_code) {
258 switch (command_code) {
259 case TPM_CC_Startup:
260 return 0;
261 case TPM_CC_Shutdown:
262 return 0;
263 case TPM_CC_SelfTest:
264 return 0;
265 case TPM_CC_IncrementalSelfTest:
266 return 0;
267 case TPM_CC_GetTestResult:
268 return 0;
269 case TPM_CC_StartAuthSession:
270 return 1;
271 case TPM_CC_PolicyRestart:
272 return 0;
273 case TPM_CC_Create:
274 return 0;
275 case TPM_CC_Load:
276 return 1;
277 case TPM_CC_LoadExternal:
278 return 1;
279 case TPM_CC_ReadPublic:
280 return 0;
281 case TPM_CC_ActivateCredential:
282 return 0;
283 case TPM_CC_MakeCredential:
284 return 0;
285 case TPM_CC_Unseal:
286 return 0;
287 case TPM_CC_ObjectChangeAuth:
288 return 0;
289 case TPM_CC_Duplicate:
290 return 0;
291 case TPM_CC_Rewrap:
292 return 0;
293 case TPM_CC_Import:
294 return 0;
295 case TPM_CC_RSA_Encrypt:
296 return 0;
297 case TPM_CC_RSA_Decrypt:
298 return 0;
299 case TPM_CC_ECDH_KeyGen:
300 return 0;
301 case TPM_CC_ECDH_ZGen:
302 return 0;
303 case TPM_CC_ECC_Parameters:
304 return 0;
305 case TPM_CC_ZGen_2Phase:
306 return 0;
307 case TPM_CC_EncryptDecrypt:
308 return 0;
309 case TPM_CC_Hash:
310 return 0;
311 case TPM_CC_HMAC:
312 return 0;
313 case TPM_CC_GetRandom:
314 return 0;
315 case TPM_CC_StirRandom:
316 return 0;
317 case TPM_CC_HMAC_Start:
318 return 1;
319 case TPM_CC_HashSequenceStart:
320 return 1;
321 case TPM_CC_SequenceUpdate:
322 return 0;
323 case TPM_CC_SequenceComplete:
324 return 0;
325 case TPM_CC_EventSequenceComplete:
326 return 0;
327 case TPM_CC_Certify:
328 return 0;
329 case TPM_CC_CertifyCreation:
330 return 0;
331 case TPM_CC_Quote:
332 return 0;
333 case TPM_CC_GetSessionAuditDigest:
334 return 0;
335 case TPM_CC_GetCommandAuditDigest:
336 return 0;
337 case TPM_CC_GetTime:
338 return 0;
339 case TPM_CC_Commit:
340 return 0;
341 case TPM_CC_EC_Ephemeral:
342 return 0;
343 case TPM_CC_VerifySignature:
344 return 0;
345 case TPM_CC_Sign:
346 return 0;
347 case TPM_CC_SetCommandCodeAuditStatus:
348 return 0;
349 case TPM_CC_PCR_Extend:
350 return 0;
351 case TPM_CC_PCR_Event:
352 return 0;
353 case TPM_CC_PCR_Read:
354 return 0;
355 case TPM_CC_PCR_Allocate:
356 return 0;
357 case TPM_CC_PCR_SetAuthPolicy:
358 return 0;
359 case TPM_CC_PCR_SetAuthValue:
360 return 0;
361 case TPM_CC_PCR_Reset:
362 return 0;
363 case TPM_CC_PolicySigned:
364 return 0;
365 case TPM_CC_PolicySecret:
366 return 0;
367 case TPM_CC_PolicyTicket:
368 return 0;
369 case TPM_CC_PolicyOR:
370 return 0;
371 case TPM_CC_PolicyPCR:
372 return 0;
373 case TPM_CC_PolicyLocality:
374 return 0;
375 case TPM_CC_PolicyNV:
376 return 0;
377 case TPM_CC_PolicyCounterTimer:
378 return 0;
379 case TPM_CC_PolicyCommandCode:
380 return 0;
381 case TPM_CC_PolicyPhysicalPresence:
382 return 0;
383 case TPM_CC_PolicyCpHash:
384 return 0;
385 case TPM_CC_PolicyNameHash:
386 return 0;
387 case TPM_CC_PolicyDuplicationSelect:
388 return 0;
389 case TPM_CC_PolicyAuthorize:
390 return 0;
391 case TPM_CC_PolicyAuthValue:
392 return 0;
393 case TPM_CC_PolicyPassword:
394 return 0;
395 case TPM_CC_PolicyGetDigest:
396 return 0;
397 case TPM_CC_PolicyNvWritten:
398 return 0;
399 case TPM_CC_CreatePrimary:
400 return 1;
401 case TPM_CC_HierarchyControl:
402 return 0;
403 case TPM_CC_SetPrimaryPolicy:
404 return 0;
405 case TPM_CC_ChangePPS:
406 return 0;
407 case TPM_CC_ChangeEPS:
408 return 0;
409 case TPM_CC_Clear:
410 return 0;
411 case TPM_CC_ClearControl:
412 return 0;
413 case TPM_CC_HierarchyChangeAuth:
414 return 0;
415 case TPM_CC_DictionaryAttackLockReset:
416 return 0;
417 case TPM_CC_DictionaryAttackParameters:
418 return 0;
419 case TPM_CC_PP_Commands:
420 return 0;
421 case TPM_CC_SetAlgorithmSet:
422 return 0;
423 case TPM_CC_FieldUpgradeStart:
424 return 0;
425 case TPM_CC_FieldUpgradeData:
426 return 0;
427 case TPM_CC_FirmwareRead:
428 return 0;
429 case TPM_CC_ContextSave:
430 return 0;
431 case TPM_CC_ContextLoad:
432 return 1;
433 case TPM_CC_FlushContext:
434 return 0;
435 case TPM_CC_EvictControl:
436 return 0;
437 case TPM_CC_ReadClock:
438 return 0;
439 case TPM_CC_ClockSet:
440 return 0;
441 case TPM_CC_ClockRateAdjust:
442 return 0;
443 case TPM_CC_GetCapability:
444 return 0;
445 case TPM_CC_TestParms:
446 return 0;
447 case TPM_CC_NV_DefineSpace:
448 return 0;
449 case TPM_CC_NV_UndefineSpace:
450 return 0;
451 case TPM_CC_NV_UndefineSpaceSpecial:
452 return 0;
453 case TPM_CC_NV_ReadPublic:
454 return 0;
455 case TPM_CC_NV_Write:
456 return 0;
457 case TPM_CC_NV_Increment:
458 return 0;
459 case TPM_CC_NV_Extend:
460 return 0;
461 case TPM_CC_NV_SetBits:
462 return 0;
463 case TPM_CC_NV_WriteLock:
464 return 0;
465 case TPM_CC_NV_GlobalWriteLock:
466 return 0;
467 case TPM_CC_NV_Read:
468 return 0;
469 case TPM_CC_NV_ReadLock:
470 return 0;
471 case TPM_CC_NV_ChangeAuth:
472 return 0;
473 case TPM_CC_NV_Certify:
474 return 0;
475 case TPM_CCE_PolicyFidoSigned:
476 return 0;
477 default:
478 LOG(WARNING) << "Unknown command code: " << command_code;
479 }
480 return 0;
481 }
482
Serialize_uint8_t(const uint8_t & value,std::string * buffer)483 TPM_RC Serialize_uint8_t(const uint8_t& value, std::string* buffer) {
484 VLOG(3) << __func__;
485 uint8_t value_net = value;
486 switch (sizeof(uint8_t)) {
487 case 2:
488 value_net = htons(value);
489 break;
490 case 4:
491 value_net = htonl(value);
492 break;
493 case 8:
494 value_net = htonq(value);
495 break;
496 default:
497 break;
498 }
499 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
500 buffer->append(value_bytes, sizeof(uint8_t));
501 return TPM_RC_SUCCESS;
502 }
503
Parse_uint8_t(std::string * buffer,uint8_t * value,std::string * value_bytes)504 TPM_RC Parse_uint8_t(std::string* buffer,
505 uint8_t* value,
506 std::string* value_bytes) {
507 VLOG(3) << __func__;
508 if (buffer->size() < sizeof(uint8_t))
509 return TPM_RC_INSUFFICIENT;
510 uint8_t value_net = 0;
511 memcpy(&value_net, buffer->data(), sizeof(uint8_t));
512 switch (sizeof(uint8_t)) {
513 case 2:
514 *value = ntohs(value_net);
515 break;
516 case 4:
517 *value = ntohl(value_net);
518 break;
519 case 8:
520 *value = ntohq(value_net);
521 break;
522 default:
523 *value = value_net;
524 }
525 if (value_bytes) {
526 value_bytes->append(buffer->substr(0, sizeof(uint8_t)));
527 }
528 buffer->erase(0, sizeof(uint8_t));
529 return TPM_RC_SUCCESS;
530 }
531
Serialize_int8_t(const int8_t & value,std::string * buffer)532 TPM_RC Serialize_int8_t(const int8_t& value, std::string* buffer) {
533 VLOG(3) << __func__;
534 int8_t value_net = value;
535 switch (sizeof(int8_t)) {
536 case 2:
537 value_net = htons(value);
538 break;
539 case 4:
540 value_net = htonl(value);
541 break;
542 case 8:
543 value_net = htonq(value);
544 break;
545 default:
546 break;
547 }
548 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
549 buffer->append(value_bytes, sizeof(int8_t));
550 return TPM_RC_SUCCESS;
551 }
552
Parse_int8_t(std::string * buffer,int8_t * value,std::string * value_bytes)553 TPM_RC Parse_int8_t(std::string* buffer,
554 int8_t* value,
555 std::string* value_bytes) {
556 VLOG(3) << __func__;
557 if (buffer->size() < sizeof(int8_t))
558 return TPM_RC_INSUFFICIENT;
559 int8_t value_net = 0;
560 memcpy(&value_net, buffer->data(), sizeof(int8_t));
561 switch (sizeof(int8_t)) {
562 case 2:
563 *value = ntohs(value_net);
564 break;
565 case 4:
566 *value = ntohl(value_net);
567 break;
568 case 8:
569 *value = ntohq(value_net);
570 break;
571 default:
572 *value = value_net;
573 }
574 if (value_bytes) {
575 value_bytes->append(buffer->substr(0, sizeof(int8_t)));
576 }
577 buffer->erase(0, sizeof(int8_t));
578 return TPM_RC_SUCCESS;
579 }
580
Serialize_int(const int & value,std::string * buffer)581 TPM_RC Serialize_int(const int& value, std::string* buffer) {
582 VLOG(3) << __func__;
583 int value_net = value;
584 switch (sizeof(int)) {
585 case 2:
586 value_net = htons(value);
587 break;
588 case 4:
589 value_net = htonl(value);
590 break;
591 case 8:
592 value_net = htonq(value);
593 break;
594 default:
595 break;
596 }
597 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
598 buffer->append(value_bytes, sizeof(int));
599 return TPM_RC_SUCCESS;
600 }
601
Parse_int(std::string * buffer,int * value,std::string * value_bytes)602 TPM_RC Parse_int(std::string* buffer, int* value, std::string* value_bytes) {
603 VLOG(3) << __func__;
604 if (buffer->size() < sizeof(int))
605 return TPM_RC_INSUFFICIENT;
606 int value_net = 0;
607 memcpy(&value_net, buffer->data(), sizeof(int));
608 switch (sizeof(int)) {
609 case 2:
610 *value = ntohs(value_net);
611 break;
612 case 4:
613 *value = ntohl(value_net);
614 break;
615 case 8:
616 *value = ntohq(value_net);
617 break;
618 default:
619 *value = value_net;
620 }
621 if (value_bytes) {
622 value_bytes->append(buffer->substr(0, sizeof(int)));
623 }
624 buffer->erase(0, sizeof(int));
625 return TPM_RC_SUCCESS;
626 }
627
Serialize_uint16_t(const uint16_t & value,std::string * buffer)628 TPM_RC Serialize_uint16_t(const uint16_t& value, std::string* buffer) {
629 VLOG(3) << __func__;
630 uint16_t value_net = value;
631 switch (sizeof(uint16_t)) {
632 case 2:
633 value_net = htons(value);
634 break;
635 case 4:
636 value_net = htonl(value);
637 break;
638 case 8:
639 value_net = htonq(value);
640 break;
641 default:
642 break;
643 }
644 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
645 buffer->append(value_bytes, sizeof(uint16_t));
646 return TPM_RC_SUCCESS;
647 }
648
Parse_uint16_t(std::string * buffer,uint16_t * value,std::string * value_bytes)649 TPM_RC Parse_uint16_t(std::string* buffer,
650 uint16_t* value,
651 std::string* value_bytes) {
652 VLOG(3) << __func__;
653 if (buffer->size() < sizeof(uint16_t))
654 return TPM_RC_INSUFFICIENT;
655 uint16_t value_net = 0;
656 memcpy(&value_net, buffer->data(), sizeof(uint16_t));
657 switch (sizeof(uint16_t)) {
658 case 2:
659 *value = ntohs(value_net);
660 break;
661 case 4:
662 *value = ntohl(value_net);
663 break;
664 case 8:
665 *value = ntohq(value_net);
666 break;
667 default:
668 *value = value_net;
669 }
670 if (value_bytes) {
671 value_bytes->append(buffer->substr(0, sizeof(uint16_t)));
672 }
673 buffer->erase(0, sizeof(uint16_t));
674 return TPM_RC_SUCCESS;
675 }
676
Serialize_int16_t(const int16_t & value,std::string * buffer)677 TPM_RC Serialize_int16_t(const int16_t& value, std::string* buffer) {
678 VLOG(3) << __func__;
679 int16_t value_net = value;
680 switch (sizeof(int16_t)) {
681 case 2:
682 value_net = htons(value);
683 break;
684 case 4:
685 value_net = htonl(value);
686 break;
687 case 8:
688 value_net = htonq(value);
689 break;
690 default:
691 break;
692 }
693 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
694 buffer->append(value_bytes, sizeof(int16_t));
695 return TPM_RC_SUCCESS;
696 }
697
Parse_int16_t(std::string * buffer,int16_t * value,std::string * value_bytes)698 TPM_RC Parse_int16_t(std::string* buffer,
699 int16_t* value,
700 std::string* value_bytes) {
701 VLOG(3) << __func__;
702 if (buffer->size() < sizeof(int16_t))
703 return TPM_RC_INSUFFICIENT;
704 int16_t value_net = 0;
705 memcpy(&value_net, buffer->data(), sizeof(int16_t));
706 switch (sizeof(int16_t)) {
707 case 2:
708 *value = ntohs(value_net);
709 break;
710 case 4:
711 *value = ntohl(value_net);
712 break;
713 case 8:
714 *value = ntohq(value_net);
715 break;
716 default:
717 *value = value_net;
718 }
719 if (value_bytes) {
720 value_bytes->append(buffer->substr(0, sizeof(int16_t)));
721 }
722 buffer->erase(0, sizeof(int16_t));
723 return TPM_RC_SUCCESS;
724 }
725
Serialize_uint32_t(const uint32_t & value,std::string * buffer)726 TPM_RC Serialize_uint32_t(const uint32_t& value, std::string* buffer) {
727 VLOG(3) << __func__;
728 uint32_t value_net = value;
729 switch (sizeof(uint32_t)) {
730 case 2:
731 value_net = htons(value);
732 break;
733 case 4:
734 value_net = htonl(value);
735 break;
736 case 8:
737 value_net = htonq(value);
738 break;
739 default:
740 break;
741 }
742 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
743 buffer->append(value_bytes, sizeof(uint32_t));
744 return TPM_RC_SUCCESS;
745 }
746
Parse_uint32_t(std::string * buffer,uint32_t * value,std::string * value_bytes)747 TPM_RC Parse_uint32_t(std::string* buffer,
748 uint32_t* value,
749 std::string* value_bytes) {
750 VLOG(3) << __func__;
751 if (buffer->size() < sizeof(uint32_t))
752 return TPM_RC_INSUFFICIENT;
753 uint32_t value_net = 0;
754 memcpy(&value_net, buffer->data(), sizeof(uint32_t));
755 switch (sizeof(uint32_t)) {
756 case 2:
757 *value = ntohs(value_net);
758 break;
759 case 4:
760 *value = ntohl(value_net);
761 break;
762 case 8:
763 *value = ntohq(value_net);
764 break;
765 default:
766 *value = value_net;
767 }
768 if (value_bytes) {
769 value_bytes->append(buffer->substr(0, sizeof(uint32_t)));
770 }
771 buffer->erase(0, sizeof(uint32_t));
772 return TPM_RC_SUCCESS;
773 }
774
Serialize_int32_t(const int32_t & value,std::string * buffer)775 TPM_RC Serialize_int32_t(const int32_t& value, std::string* buffer) {
776 VLOG(3) << __func__;
777 int32_t value_net = value;
778 switch (sizeof(int32_t)) {
779 case 2:
780 value_net = htons(value);
781 break;
782 case 4:
783 value_net = htonl(value);
784 break;
785 case 8:
786 value_net = htonq(value);
787 break;
788 default:
789 break;
790 }
791 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
792 buffer->append(value_bytes, sizeof(int32_t));
793 return TPM_RC_SUCCESS;
794 }
795
Parse_int32_t(std::string * buffer,int32_t * value,std::string * value_bytes)796 TPM_RC Parse_int32_t(std::string* buffer,
797 int32_t* value,
798 std::string* value_bytes) {
799 VLOG(3) << __func__;
800 if (buffer->size() < sizeof(int32_t))
801 return TPM_RC_INSUFFICIENT;
802 int32_t value_net = 0;
803 memcpy(&value_net, buffer->data(), sizeof(int32_t));
804 switch (sizeof(int32_t)) {
805 case 2:
806 *value = ntohs(value_net);
807 break;
808 case 4:
809 *value = ntohl(value_net);
810 break;
811 case 8:
812 *value = ntohq(value_net);
813 break;
814 default:
815 *value = value_net;
816 }
817 if (value_bytes) {
818 value_bytes->append(buffer->substr(0, sizeof(int32_t)));
819 }
820 buffer->erase(0, sizeof(int32_t));
821 return TPM_RC_SUCCESS;
822 }
823
Serialize_uint64_t(const uint64_t & value,std::string * buffer)824 TPM_RC Serialize_uint64_t(const uint64_t& value, std::string* buffer) {
825 VLOG(3) << __func__;
826 uint64_t value_net = value;
827 switch (sizeof(uint64_t)) {
828 case 2:
829 value_net = htons(value);
830 break;
831 case 4:
832 value_net = htonl(value);
833 break;
834 case 8:
835 value_net = htonq(value);
836 break;
837 default:
838 break;
839 }
840 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
841 buffer->append(value_bytes, sizeof(uint64_t));
842 return TPM_RC_SUCCESS;
843 }
844
Parse_uint64_t(std::string * buffer,uint64_t * value,std::string * value_bytes)845 TPM_RC Parse_uint64_t(std::string* buffer,
846 uint64_t* value,
847 std::string* value_bytes) {
848 VLOG(3) << __func__;
849 if (buffer->size() < sizeof(uint64_t))
850 return TPM_RC_INSUFFICIENT;
851 uint64_t value_net = 0;
852 memcpy(&value_net, buffer->data(), sizeof(uint64_t));
853 switch (sizeof(uint64_t)) {
854 case 2:
855 *value = ntohs(value_net);
856 break;
857 case 4:
858 *value = ntohl(value_net);
859 break;
860 case 8:
861 *value = ntohq(value_net);
862 break;
863 default:
864 *value = value_net;
865 }
866 if (value_bytes) {
867 value_bytes->append(buffer->substr(0, sizeof(uint64_t)));
868 }
869 buffer->erase(0, sizeof(uint64_t));
870 return TPM_RC_SUCCESS;
871 }
872
Serialize_int64_t(const int64_t & value,std::string * buffer)873 TPM_RC Serialize_int64_t(const int64_t& value, std::string* buffer) {
874 VLOG(3) << __func__;
875 int64_t value_net = value;
876 switch (sizeof(int64_t)) {
877 case 2:
878 value_net = htons(value);
879 break;
880 case 4:
881 value_net = htonl(value);
882 break;
883 case 8:
884 value_net = htonq(value);
885 break;
886 default:
887 break;
888 }
889 const char* value_bytes = reinterpret_cast<const char*>(&value_net);
890 buffer->append(value_bytes, sizeof(int64_t));
891 return TPM_RC_SUCCESS;
892 }
893
Parse_int64_t(std::string * buffer,int64_t * value,std::string * value_bytes)894 TPM_RC Parse_int64_t(std::string* buffer,
895 int64_t* value,
896 std::string* value_bytes) {
897 VLOG(3) << __func__;
898 if (buffer->size() < sizeof(int64_t))
899 return TPM_RC_INSUFFICIENT;
900 int64_t value_net = 0;
901 memcpy(&value_net, buffer->data(), sizeof(int64_t));
902 switch (sizeof(int64_t)) {
903 case 2:
904 *value = ntohs(value_net);
905 break;
906 case 4:
907 *value = ntohl(value_net);
908 break;
909 case 8:
910 *value = ntohq(value_net);
911 break;
912 default:
913 *value = value_net;
914 }
915 if (value_bytes) {
916 value_bytes->append(buffer->substr(0, sizeof(int64_t)));
917 }
918 buffer->erase(0, sizeof(int64_t));
919 return TPM_RC_SUCCESS;
920 }
921
Serialize_UINT8(const UINT8 & value,std::string * buffer)922 TPM_RC Serialize_UINT8(const UINT8& value, std::string* buffer) {
923 VLOG(3) << __func__;
924 return Serialize_uint8_t(value, buffer);
925 }
926
Parse_UINT8(std::string * buffer,UINT8 * value,std::string * value_bytes)927 TPM_RC Parse_UINT8(std::string* buffer,
928 UINT8* value,
929 std::string* value_bytes) {
930 VLOG(3) << __func__;
931 return Parse_uint8_t(buffer, value, value_bytes);
932 }
933
Serialize_BYTE(const BYTE & value,std::string * buffer)934 TPM_RC Serialize_BYTE(const BYTE& value, std::string* buffer) {
935 VLOG(3) << __func__;
936 return Serialize_uint8_t(value, buffer);
937 }
938
Parse_BYTE(std::string * buffer,BYTE * value,std::string * value_bytes)939 TPM_RC Parse_BYTE(std::string* buffer, BYTE* value, std::string* value_bytes) {
940 VLOG(3) << __func__;
941 return Parse_uint8_t(buffer, value, value_bytes);
942 }
943
Serialize_INT8(const INT8 & value,std::string * buffer)944 TPM_RC Serialize_INT8(const INT8& value, std::string* buffer) {
945 VLOG(3) << __func__;
946 return Serialize_int8_t(value, buffer);
947 }
948
Parse_INT8(std::string * buffer,INT8 * value,std::string * value_bytes)949 TPM_RC Parse_INT8(std::string* buffer, INT8* value, std::string* value_bytes) {
950 VLOG(3) << __func__;
951 return Parse_int8_t(buffer, value, value_bytes);
952 }
953
Serialize_BOOL(const BOOL & value,std::string * buffer)954 TPM_RC Serialize_BOOL(const BOOL& value, std::string* buffer) {
955 VLOG(3) << __func__;
956 return Serialize_int(value, buffer);
957 }
958
Parse_BOOL(std::string * buffer,BOOL * value,std::string * value_bytes)959 TPM_RC Parse_BOOL(std::string* buffer, BOOL* value, std::string* value_bytes) {
960 VLOG(3) << __func__;
961 return Parse_int(buffer, value, value_bytes);
962 }
963
Serialize_UINT16(const UINT16 & value,std::string * buffer)964 TPM_RC Serialize_UINT16(const UINT16& value, std::string* buffer) {
965 VLOG(3) << __func__;
966 return Serialize_uint16_t(value, buffer);
967 }
968
Parse_UINT16(std::string * buffer,UINT16 * value,std::string * value_bytes)969 TPM_RC Parse_UINT16(std::string* buffer,
970 UINT16* value,
971 std::string* value_bytes) {
972 VLOG(3) << __func__;
973 return Parse_uint16_t(buffer, value, value_bytes);
974 }
975
Serialize_INT16(const INT16 & value,std::string * buffer)976 TPM_RC Serialize_INT16(const INT16& value, std::string* buffer) {
977 VLOG(3) << __func__;
978 return Serialize_int16_t(value, buffer);
979 }
980
Parse_INT16(std::string * buffer,INT16 * value,std::string * value_bytes)981 TPM_RC Parse_INT16(std::string* buffer,
982 INT16* value,
983 std::string* value_bytes) {
984 VLOG(3) << __func__;
985 return Parse_int16_t(buffer, value, value_bytes);
986 }
987
Serialize_UINT32(const UINT32 & value,std::string * buffer)988 TPM_RC Serialize_UINT32(const UINT32& value, std::string* buffer) {
989 VLOG(3) << __func__;
990 return Serialize_uint32_t(value, buffer);
991 }
992
Parse_UINT32(std::string * buffer,UINT32 * value,std::string * value_bytes)993 TPM_RC Parse_UINT32(std::string* buffer,
994 UINT32* value,
995 std::string* value_bytes) {
996 VLOG(3) << __func__;
997 return Parse_uint32_t(buffer, value, value_bytes);
998 }
999
Serialize_INT32(const INT32 & value,std::string * buffer)1000 TPM_RC Serialize_INT32(const INT32& value, std::string* buffer) {
1001 VLOG(3) << __func__;
1002 return Serialize_int32_t(value, buffer);
1003 }
1004
Parse_INT32(std::string * buffer,INT32 * value,std::string * value_bytes)1005 TPM_RC Parse_INT32(std::string* buffer,
1006 INT32* value,
1007 std::string* value_bytes) {
1008 VLOG(3) << __func__;
1009 return Parse_int32_t(buffer, value, value_bytes);
1010 }
1011
Serialize_UINT64(const UINT64 & value,std::string * buffer)1012 TPM_RC Serialize_UINT64(const UINT64& value, std::string* buffer) {
1013 VLOG(3) << __func__;
1014 return Serialize_uint64_t(value, buffer);
1015 }
1016
Parse_UINT64(std::string * buffer,UINT64 * value,std::string * value_bytes)1017 TPM_RC Parse_UINT64(std::string* buffer,
1018 UINT64* value,
1019 std::string* value_bytes) {
1020 VLOG(3) << __func__;
1021 return Parse_uint64_t(buffer, value, value_bytes);
1022 }
1023
Serialize_INT64(const INT64 & value,std::string * buffer)1024 TPM_RC Serialize_INT64(const INT64& value, std::string* buffer) {
1025 VLOG(3) << __func__;
1026 return Serialize_int64_t(value, buffer);
1027 }
1028
Parse_INT64(std::string * buffer,INT64 * value,std::string * value_bytes)1029 TPM_RC Parse_INT64(std::string* buffer,
1030 INT64* value,
1031 std::string* value_bytes) {
1032 VLOG(3) << __func__;
1033 return Parse_int64_t(buffer, value, value_bytes);
1034 }
1035
Serialize_TPM_ALGORITHM_ID(const TPM_ALGORITHM_ID & value,std::string * buffer)1036 TPM_RC Serialize_TPM_ALGORITHM_ID(const TPM_ALGORITHM_ID& value,
1037 std::string* buffer) {
1038 VLOG(3) << __func__;
1039 return Serialize_UINT32(value, buffer);
1040 }
1041
Parse_TPM_ALGORITHM_ID(std::string * buffer,TPM_ALGORITHM_ID * value,std::string * value_bytes)1042 TPM_RC Parse_TPM_ALGORITHM_ID(std::string* buffer,
1043 TPM_ALGORITHM_ID* value,
1044 std::string* value_bytes) {
1045 VLOG(3) << __func__;
1046 return Parse_UINT32(buffer, value, value_bytes);
1047 }
1048
Serialize_TPM_MODIFIER_INDICATOR(const TPM_MODIFIER_INDICATOR & value,std::string * buffer)1049 TPM_RC Serialize_TPM_MODIFIER_INDICATOR(const TPM_MODIFIER_INDICATOR& value,
1050 std::string* buffer) {
1051 VLOG(3) << __func__;
1052 return Serialize_UINT32(value, buffer);
1053 }
1054
Parse_TPM_MODIFIER_INDICATOR(std::string * buffer,TPM_MODIFIER_INDICATOR * value,std::string * value_bytes)1055 TPM_RC Parse_TPM_MODIFIER_INDICATOR(std::string* buffer,
1056 TPM_MODIFIER_INDICATOR* value,
1057 std::string* value_bytes) {
1058 VLOG(3) << __func__;
1059 return Parse_UINT32(buffer, value, value_bytes);
1060 }
1061
Serialize_TPM_AUTHORIZATION_SIZE(const TPM_AUTHORIZATION_SIZE & value,std::string * buffer)1062 TPM_RC Serialize_TPM_AUTHORIZATION_SIZE(const TPM_AUTHORIZATION_SIZE& value,
1063 std::string* buffer) {
1064 VLOG(3) << __func__;
1065 return Serialize_UINT32(value, buffer);
1066 }
1067
Parse_TPM_AUTHORIZATION_SIZE(std::string * buffer,TPM_AUTHORIZATION_SIZE * value,std::string * value_bytes)1068 TPM_RC Parse_TPM_AUTHORIZATION_SIZE(std::string* buffer,
1069 TPM_AUTHORIZATION_SIZE* value,
1070 std::string* value_bytes) {
1071 VLOG(3) << __func__;
1072 return Parse_UINT32(buffer, value, value_bytes);
1073 }
1074
Serialize_TPM_PARAMETER_SIZE(const TPM_PARAMETER_SIZE & value,std::string * buffer)1075 TPM_RC Serialize_TPM_PARAMETER_SIZE(const TPM_PARAMETER_SIZE& value,
1076 std::string* buffer) {
1077 VLOG(3) << __func__;
1078 return Serialize_UINT32(value, buffer);
1079 }
1080
Parse_TPM_PARAMETER_SIZE(std::string * buffer,TPM_PARAMETER_SIZE * value,std::string * value_bytes)1081 TPM_RC Parse_TPM_PARAMETER_SIZE(std::string* buffer,
1082 TPM_PARAMETER_SIZE* value,
1083 std::string* value_bytes) {
1084 VLOG(3) << __func__;
1085 return Parse_UINT32(buffer, value, value_bytes);
1086 }
1087
Serialize_TPM_KEY_SIZE(const TPM_KEY_SIZE & value,std::string * buffer)1088 TPM_RC Serialize_TPM_KEY_SIZE(const TPM_KEY_SIZE& value, std::string* buffer) {
1089 VLOG(3) << __func__;
1090 return Serialize_UINT16(value, buffer);
1091 }
1092
Parse_TPM_KEY_SIZE(std::string * buffer,TPM_KEY_SIZE * value,std::string * value_bytes)1093 TPM_RC Parse_TPM_KEY_SIZE(std::string* buffer,
1094 TPM_KEY_SIZE* value,
1095 std::string* value_bytes) {
1096 VLOG(3) << __func__;
1097 return Parse_UINT16(buffer, value, value_bytes);
1098 }
1099
Serialize_TPM_KEY_BITS(const TPM_KEY_BITS & value,std::string * buffer)1100 TPM_RC Serialize_TPM_KEY_BITS(const TPM_KEY_BITS& value, std::string* buffer) {
1101 VLOG(3) << __func__;
1102 return Serialize_UINT16(value, buffer);
1103 }
1104
Parse_TPM_KEY_BITS(std::string * buffer,TPM_KEY_BITS * value,std::string * value_bytes)1105 TPM_RC Parse_TPM_KEY_BITS(std::string* buffer,
1106 TPM_KEY_BITS* value,
1107 std::string* value_bytes) {
1108 VLOG(3) << __func__;
1109 return Parse_UINT16(buffer, value, value_bytes);
1110 }
1111
Serialize_TPM_HANDLE(const TPM_HANDLE & value,std::string * buffer)1112 TPM_RC Serialize_TPM_HANDLE(const TPM_HANDLE& value, std::string* buffer) {
1113 VLOG(3) << __func__;
1114 return Serialize_UINT32(value, buffer);
1115 }
1116
Parse_TPM_HANDLE(std::string * buffer,TPM_HANDLE * value,std::string * value_bytes)1117 TPM_RC Parse_TPM_HANDLE(std::string* buffer,
1118 TPM_HANDLE* value,
1119 std::string* value_bytes) {
1120 VLOG(3) << __func__;
1121 return Parse_UINT32(buffer, value, value_bytes);
1122 }
1123
Serialize_TPM2B_DIGEST(const TPM2B_DIGEST & value,std::string * buffer)1124 TPM_RC Serialize_TPM2B_DIGEST(const TPM2B_DIGEST& value, std::string* buffer) {
1125 TPM_RC result = TPM_RC_SUCCESS;
1126 VLOG(3) << __func__;
1127
1128 result = Serialize_UINT16(value.size, buffer);
1129 if (result) {
1130 return result;
1131 }
1132
1133 if (std::size(value.buffer) < value.size) {
1134 return TPM_RC_INSUFFICIENT;
1135 }
1136 for (uint32_t i = 0; i < value.size; ++i) {
1137 result = Serialize_BYTE(value.buffer[i], buffer);
1138 if (result) {
1139 return result;
1140 }
1141 }
1142 return result;
1143 }
1144
Parse_TPM2B_DIGEST(std::string * buffer,TPM2B_DIGEST * value,std::string * value_bytes)1145 TPM_RC Parse_TPM2B_DIGEST(std::string* buffer,
1146 TPM2B_DIGEST* value,
1147 std::string* value_bytes) {
1148 TPM_RC result = TPM_RC_SUCCESS;
1149 VLOG(3) << __func__;
1150
1151 result = Parse_UINT16(buffer, &value->size, value_bytes);
1152 if (result) {
1153 return result;
1154 }
1155
1156 if (std::size(value->buffer) < value->size) {
1157 return TPM_RC_INSUFFICIENT;
1158 }
1159 for (uint32_t i = 0; i < value->size; ++i) {
1160 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
1161 if (result) {
1162 return result;
1163 }
1164 }
1165 return result;
1166 }
1167
Make_TPM2B_DIGEST(const std::string & bytes)1168 TPM2B_DIGEST Make_TPM2B_DIGEST(const std::string& bytes) {
1169 TPM2B_DIGEST tpm2b;
1170 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
1171 memset(&tpm2b, 0, sizeof(TPM2B_DIGEST));
1172 tpm2b.size = bytes.size();
1173 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
1174 return tpm2b;
1175 }
1176
StringFrom_TPM2B_DIGEST(const TPM2B_DIGEST & tpm2b)1177 std::string StringFrom_TPM2B_DIGEST(const TPM2B_DIGEST& tpm2b) {
1178 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
1179 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
1180 return std::string(char_buffer, tpm2b.size);
1181 }
1182
Serialize_TPM2B_NONCE(const TPM2B_NONCE & value,std::string * buffer)1183 TPM_RC Serialize_TPM2B_NONCE(const TPM2B_NONCE& value, std::string* buffer) {
1184 VLOG(3) << __func__;
1185 return Serialize_TPM2B_DIGEST(value, buffer);
1186 }
1187
Parse_TPM2B_NONCE(std::string * buffer,TPM2B_NONCE * value,std::string * value_bytes)1188 TPM_RC Parse_TPM2B_NONCE(std::string* buffer,
1189 TPM2B_NONCE* value,
1190 std::string* value_bytes) {
1191 VLOG(3) << __func__;
1192 return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1193 }
1194
Serialize_TPM2B_AUTH(const TPM2B_AUTH & value,std::string * buffer)1195 TPM_RC Serialize_TPM2B_AUTH(const TPM2B_AUTH& value, std::string* buffer) {
1196 VLOG(3) << __func__;
1197 return Serialize_TPM2B_DIGEST(value, buffer);
1198 }
1199
Parse_TPM2B_AUTH(std::string * buffer,TPM2B_AUTH * value,std::string * value_bytes)1200 TPM_RC Parse_TPM2B_AUTH(std::string* buffer,
1201 TPM2B_AUTH* value,
1202 std::string* value_bytes) {
1203 VLOG(3) << __func__;
1204 return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1205 }
1206
Serialize_TPM2B_OPERAND(const TPM2B_OPERAND & value,std::string * buffer)1207 TPM_RC Serialize_TPM2B_OPERAND(const TPM2B_OPERAND& value,
1208 std::string* buffer) {
1209 VLOG(3) << __func__;
1210 return Serialize_TPM2B_DIGEST(value, buffer);
1211 }
1212
Parse_TPM2B_OPERAND(std::string * buffer,TPM2B_OPERAND * value,std::string * value_bytes)1213 TPM_RC Parse_TPM2B_OPERAND(std::string* buffer,
1214 TPM2B_OPERAND* value,
1215 std::string* value_bytes) {
1216 VLOG(3) << __func__;
1217 return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1218 }
1219
Serialize_TPM_ALG_ID(const TPM_ALG_ID & value,std::string * buffer)1220 TPM_RC Serialize_TPM_ALG_ID(const TPM_ALG_ID& value, std::string* buffer) {
1221 VLOG(3) << __func__;
1222 return Serialize_UINT16(value, buffer);
1223 }
1224
Parse_TPM_ALG_ID(std::string * buffer,TPM_ALG_ID * value,std::string * value_bytes)1225 TPM_RC Parse_TPM_ALG_ID(std::string* buffer,
1226 TPM_ALG_ID* value,
1227 std::string* value_bytes) {
1228 VLOG(3) << __func__;
1229 return Parse_UINT16(buffer, value, value_bytes);
1230 }
1231
Serialize_TPMI_ALG_HASH(const TPMI_ALG_HASH & value,std::string * buffer)1232 TPM_RC Serialize_TPMI_ALG_HASH(const TPMI_ALG_HASH& value,
1233 std::string* buffer) {
1234 VLOG(3) << __func__;
1235 return Serialize_TPM_ALG_ID(value, buffer);
1236 }
1237
Parse_TPMI_ALG_HASH(std::string * buffer,TPMI_ALG_HASH * value,std::string * value_bytes)1238 TPM_RC Parse_TPMI_ALG_HASH(std::string* buffer,
1239 TPMI_ALG_HASH* value,
1240 std::string* value_bytes) {
1241 VLOG(3) << __func__;
1242 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1243 }
1244
Serialize_TPMS_SCHEME_SIGHASH(const TPMS_SCHEME_SIGHASH & value,std::string * buffer)1245 TPM_RC Serialize_TPMS_SCHEME_SIGHASH(const TPMS_SCHEME_SIGHASH& value,
1246 std::string* buffer) {
1247 TPM_RC result = TPM_RC_SUCCESS;
1248 VLOG(3) << __func__;
1249
1250 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
1251 if (result) {
1252 return result;
1253 }
1254 return result;
1255 }
1256
Parse_TPMS_SCHEME_SIGHASH(std::string * buffer,TPMS_SCHEME_SIGHASH * value,std::string * value_bytes)1257 TPM_RC Parse_TPMS_SCHEME_SIGHASH(std::string* buffer,
1258 TPMS_SCHEME_SIGHASH* value,
1259 std::string* value_bytes) {
1260 TPM_RC result = TPM_RC_SUCCESS;
1261 VLOG(3) << __func__;
1262
1263 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
1264 if (result) {
1265 return result;
1266 }
1267 return result;
1268 }
1269
Serialize_TPMS_SCHEME_HMAC(const TPMS_SCHEME_HMAC & value,std::string * buffer)1270 TPM_RC Serialize_TPMS_SCHEME_HMAC(const TPMS_SCHEME_HMAC& value,
1271 std::string* buffer) {
1272 VLOG(3) << __func__;
1273 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1274 }
1275
Parse_TPMS_SCHEME_HMAC(std::string * buffer,TPMS_SCHEME_HMAC * value,std::string * value_bytes)1276 TPM_RC Parse_TPMS_SCHEME_HMAC(std::string* buffer,
1277 TPMS_SCHEME_HMAC* value,
1278 std::string* value_bytes) {
1279 VLOG(3) << __func__;
1280 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1281 }
1282
Serialize_TPMS_SCHEME_RSASSA(const TPMS_SCHEME_RSASSA & value,std::string * buffer)1283 TPM_RC Serialize_TPMS_SCHEME_RSASSA(const TPMS_SCHEME_RSASSA& value,
1284 std::string* buffer) {
1285 VLOG(3) << __func__;
1286 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1287 }
1288
Parse_TPMS_SCHEME_RSASSA(std::string * buffer,TPMS_SCHEME_RSASSA * value,std::string * value_bytes)1289 TPM_RC Parse_TPMS_SCHEME_RSASSA(std::string* buffer,
1290 TPMS_SCHEME_RSASSA* value,
1291 std::string* value_bytes) {
1292 VLOG(3) << __func__;
1293 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1294 }
1295
Serialize_TPMS_SCHEME_RSAPSS(const TPMS_SCHEME_RSAPSS & value,std::string * buffer)1296 TPM_RC Serialize_TPMS_SCHEME_RSAPSS(const TPMS_SCHEME_RSAPSS& value,
1297 std::string* buffer) {
1298 VLOG(3) << __func__;
1299 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1300 }
1301
Parse_TPMS_SCHEME_RSAPSS(std::string * buffer,TPMS_SCHEME_RSAPSS * value,std::string * value_bytes)1302 TPM_RC Parse_TPMS_SCHEME_RSAPSS(std::string* buffer,
1303 TPMS_SCHEME_RSAPSS* value,
1304 std::string* value_bytes) {
1305 VLOG(3) << __func__;
1306 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1307 }
1308
Serialize_TPMS_SCHEME_ECDSA(const TPMS_SCHEME_ECDSA & value,std::string * buffer)1309 TPM_RC Serialize_TPMS_SCHEME_ECDSA(const TPMS_SCHEME_ECDSA& value,
1310 std::string* buffer) {
1311 VLOG(3) << __func__;
1312 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1313 }
1314
Parse_TPMS_SCHEME_ECDSA(std::string * buffer,TPMS_SCHEME_ECDSA * value,std::string * value_bytes)1315 TPM_RC Parse_TPMS_SCHEME_ECDSA(std::string* buffer,
1316 TPMS_SCHEME_ECDSA* value,
1317 std::string* value_bytes) {
1318 VLOG(3) << __func__;
1319 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1320 }
1321
Serialize_TPMS_SCHEME_SM2(const TPMS_SCHEME_SM2 & value,std::string * buffer)1322 TPM_RC Serialize_TPMS_SCHEME_SM2(const TPMS_SCHEME_SM2& value,
1323 std::string* buffer) {
1324 VLOG(3) << __func__;
1325 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1326 }
1327
Parse_TPMS_SCHEME_SM2(std::string * buffer,TPMS_SCHEME_SM2 * value,std::string * value_bytes)1328 TPM_RC Parse_TPMS_SCHEME_SM2(std::string* buffer,
1329 TPMS_SCHEME_SM2* value,
1330 std::string* value_bytes) {
1331 VLOG(3) << __func__;
1332 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1333 }
1334
Serialize_TPMS_SCHEME_ECSCHNORR(const TPMS_SCHEME_ECSCHNORR & value,std::string * buffer)1335 TPM_RC Serialize_TPMS_SCHEME_ECSCHNORR(const TPMS_SCHEME_ECSCHNORR& value,
1336 std::string* buffer) {
1337 VLOG(3) << __func__;
1338 return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1339 }
1340
Parse_TPMS_SCHEME_ECSCHNORR(std::string * buffer,TPMS_SCHEME_ECSCHNORR * value,std::string * value_bytes)1341 TPM_RC Parse_TPMS_SCHEME_ECSCHNORR(std::string* buffer,
1342 TPMS_SCHEME_ECSCHNORR* value,
1343 std::string* value_bytes) {
1344 VLOG(3) << __func__;
1345 return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1346 }
1347
Serialize_TPMI_YES_NO(const TPMI_YES_NO & value,std::string * buffer)1348 TPM_RC Serialize_TPMI_YES_NO(const TPMI_YES_NO& value, std::string* buffer) {
1349 VLOG(3) << __func__;
1350 return Serialize_BYTE(value, buffer);
1351 }
1352
Parse_TPMI_YES_NO(std::string * buffer,TPMI_YES_NO * value,std::string * value_bytes)1353 TPM_RC Parse_TPMI_YES_NO(std::string* buffer,
1354 TPMI_YES_NO* value,
1355 std::string* value_bytes) {
1356 VLOG(3) << __func__;
1357 return Parse_BYTE(buffer, value, value_bytes);
1358 }
1359
Serialize_TPMI_DH_OBJECT(const TPMI_DH_OBJECT & value,std::string * buffer)1360 TPM_RC Serialize_TPMI_DH_OBJECT(const TPMI_DH_OBJECT& value,
1361 std::string* buffer) {
1362 VLOG(3) << __func__;
1363 return Serialize_TPM_HANDLE(value, buffer);
1364 }
1365
Parse_TPMI_DH_OBJECT(std::string * buffer,TPMI_DH_OBJECT * value,std::string * value_bytes)1366 TPM_RC Parse_TPMI_DH_OBJECT(std::string* buffer,
1367 TPMI_DH_OBJECT* value,
1368 std::string* value_bytes) {
1369 VLOG(3) << __func__;
1370 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1371 }
1372
Serialize_TPMI_DH_PERSISTENT(const TPMI_DH_PERSISTENT & value,std::string * buffer)1373 TPM_RC Serialize_TPMI_DH_PERSISTENT(const TPMI_DH_PERSISTENT& value,
1374 std::string* buffer) {
1375 VLOG(3) << __func__;
1376 return Serialize_TPM_HANDLE(value, buffer);
1377 }
1378
Parse_TPMI_DH_PERSISTENT(std::string * buffer,TPMI_DH_PERSISTENT * value,std::string * value_bytes)1379 TPM_RC Parse_TPMI_DH_PERSISTENT(std::string* buffer,
1380 TPMI_DH_PERSISTENT* value,
1381 std::string* value_bytes) {
1382 VLOG(3) << __func__;
1383 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1384 }
1385
Serialize_TPMI_DH_ENTITY(const TPMI_DH_ENTITY & value,std::string * buffer)1386 TPM_RC Serialize_TPMI_DH_ENTITY(const TPMI_DH_ENTITY& value,
1387 std::string* buffer) {
1388 VLOG(3) << __func__;
1389 return Serialize_TPM_HANDLE(value, buffer);
1390 }
1391
Parse_TPMI_DH_ENTITY(std::string * buffer,TPMI_DH_ENTITY * value,std::string * value_bytes)1392 TPM_RC Parse_TPMI_DH_ENTITY(std::string* buffer,
1393 TPMI_DH_ENTITY* value,
1394 std::string* value_bytes) {
1395 VLOG(3) << __func__;
1396 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1397 }
1398
Serialize_TPMI_DH_PCR(const TPMI_DH_PCR & value,std::string * buffer)1399 TPM_RC Serialize_TPMI_DH_PCR(const TPMI_DH_PCR& value, std::string* buffer) {
1400 VLOG(3) << __func__;
1401 return Serialize_TPM_HANDLE(value, buffer);
1402 }
1403
Parse_TPMI_DH_PCR(std::string * buffer,TPMI_DH_PCR * value,std::string * value_bytes)1404 TPM_RC Parse_TPMI_DH_PCR(std::string* buffer,
1405 TPMI_DH_PCR* value,
1406 std::string* value_bytes) {
1407 VLOG(3) << __func__;
1408 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1409 }
1410
Serialize_TPMI_SH_AUTH_SESSION(const TPMI_SH_AUTH_SESSION & value,std::string * buffer)1411 TPM_RC Serialize_TPMI_SH_AUTH_SESSION(const TPMI_SH_AUTH_SESSION& value,
1412 std::string* buffer) {
1413 VLOG(3) << __func__;
1414 return Serialize_TPM_HANDLE(value, buffer);
1415 }
1416
Parse_TPMI_SH_AUTH_SESSION(std::string * buffer,TPMI_SH_AUTH_SESSION * value,std::string * value_bytes)1417 TPM_RC Parse_TPMI_SH_AUTH_SESSION(std::string* buffer,
1418 TPMI_SH_AUTH_SESSION* value,
1419 std::string* value_bytes) {
1420 VLOG(3) << __func__;
1421 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1422 }
1423
Serialize_TPMI_SH_HMAC(const TPMI_SH_HMAC & value,std::string * buffer)1424 TPM_RC Serialize_TPMI_SH_HMAC(const TPMI_SH_HMAC& value, std::string* buffer) {
1425 VLOG(3) << __func__;
1426 return Serialize_TPM_HANDLE(value, buffer);
1427 }
1428
Parse_TPMI_SH_HMAC(std::string * buffer,TPMI_SH_HMAC * value,std::string * value_bytes)1429 TPM_RC Parse_TPMI_SH_HMAC(std::string* buffer,
1430 TPMI_SH_HMAC* value,
1431 std::string* value_bytes) {
1432 VLOG(3) << __func__;
1433 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1434 }
1435
Serialize_TPMI_SH_POLICY(const TPMI_SH_POLICY & value,std::string * buffer)1436 TPM_RC Serialize_TPMI_SH_POLICY(const TPMI_SH_POLICY& value,
1437 std::string* buffer) {
1438 VLOG(3) << __func__;
1439 return Serialize_TPM_HANDLE(value, buffer);
1440 }
1441
Parse_TPMI_SH_POLICY(std::string * buffer,TPMI_SH_POLICY * value,std::string * value_bytes)1442 TPM_RC Parse_TPMI_SH_POLICY(std::string* buffer,
1443 TPMI_SH_POLICY* value,
1444 std::string* value_bytes) {
1445 VLOG(3) << __func__;
1446 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1447 }
1448
Serialize_TPMI_DH_CONTEXT(const TPMI_DH_CONTEXT & value,std::string * buffer)1449 TPM_RC Serialize_TPMI_DH_CONTEXT(const TPMI_DH_CONTEXT& value,
1450 std::string* buffer) {
1451 VLOG(3) << __func__;
1452 return Serialize_TPM_HANDLE(value, buffer);
1453 }
1454
Parse_TPMI_DH_CONTEXT(std::string * buffer,TPMI_DH_CONTEXT * value,std::string * value_bytes)1455 TPM_RC Parse_TPMI_DH_CONTEXT(std::string* buffer,
1456 TPMI_DH_CONTEXT* value,
1457 std::string* value_bytes) {
1458 VLOG(3) << __func__;
1459 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1460 }
1461
Serialize_TPMI_RH_HIERARCHY(const TPMI_RH_HIERARCHY & value,std::string * buffer)1462 TPM_RC Serialize_TPMI_RH_HIERARCHY(const TPMI_RH_HIERARCHY& value,
1463 std::string* buffer) {
1464 VLOG(3) << __func__;
1465 return Serialize_TPM_HANDLE(value, buffer);
1466 }
1467
Parse_TPMI_RH_HIERARCHY(std::string * buffer,TPMI_RH_HIERARCHY * value,std::string * value_bytes)1468 TPM_RC Parse_TPMI_RH_HIERARCHY(std::string* buffer,
1469 TPMI_RH_HIERARCHY* value,
1470 std::string* value_bytes) {
1471 VLOG(3) << __func__;
1472 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1473 }
1474
Serialize_TPMI_RH_ENABLES(const TPMI_RH_ENABLES & value,std::string * buffer)1475 TPM_RC Serialize_TPMI_RH_ENABLES(const TPMI_RH_ENABLES& value,
1476 std::string* buffer) {
1477 VLOG(3) << __func__;
1478 return Serialize_TPM_HANDLE(value, buffer);
1479 }
1480
Parse_TPMI_RH_ENABLES(std::string * buffer,TPMI_RH_ENABLES * value,std::string * value_bytes)1481 TPM_RC Parse_TPMI_RH_ENABLES(std::string* buffer,
1482 TPMI_RH_ENABLES* value,
1483 std::string* value_bytes) {
1484 VLOG(3) << __func__;
1485 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1486 }
1487
Serialize_TPMI_RH_HIERARCHY_AUTH(const TPMI_RH_HIERARCHY_AUTH & value,std::string * buffer)1488 TPM_RC Serialize_TPMI_RH_HIERARCHY_AUTH(const TPMI_RH_HIERARCHY_AUTH& value,
1489 std::string* buffer) {
1490 VLOG(3) << __func__;
1491 return Serialize_TPM_HANDLE(value, buffer);
1492 }
1493
Parse_TPMI_RH_HIERARCHY_AUTH(std::string * buffer,TPMI_RH_HIERARCHY_AUTH * value,std::string * value_bytes)1494 TPM_RC Parse_TPMI_RH_HIERARCHY_AUTH(std::string* buffer,
1495 TPMI_RH_HIERARCHY_AUTH* value,
1496 std::string* value_bytes) {
1497 VLOG(3) << __func__;
1498 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1499 }
1500
Serialize_TPMI_RH_PLATFORM(const TPMI_RH_PLATFORM & value,std::string * buffer)1501 TPM_RC Serialize_TPMI_RH_PLATFORM(const TPMI_RH_PLATFORM& value,
1502 std::string* buffer) {
1503 VLOG(3) << __func__;
1504 return Serialize_TPM_HANDLE(value, buffer);
1505 }
1506
Parse_TPMI_RH_PLATFORM(std::string * buffer,TPMI_RH_PLATFORM * value,std::string * value_bytes)1507 TPM_RC Parse_TPMI_RH_PLATFORM(std::string* buffer,
1508 TPMI_RH_PLATFORM* value,
1509 std::string* value_bytes) {
1510 VLOG(3) << __func__;
1511 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1512 }
1513
Serialize_TPMI_RH_OWNER(const TPMI_RH_OWNER & value,std::string * buffer)1514 TPM_RC Serialize_TPMI_RH_OWNER(const TPMI_RH_OWNER& value,
1515 std::string* buffer) {
1516 VLOG(3) << __func__;
1517 return Serialize_TPM_HANDLE(value, buffer);
1518 }
1519
Parse_TPMI_RH_OWNER(std::string * buffer,TPMI_RH_OWNER * value,std::string * value_bytes)1520 TPM_RC Parse_TPMI_RH_OWNER(std::string* buffer,
1521 TPMI_RH_OWNER* value,
1522 std::string* value_bytes) {
1523 VLOG(3) << __func__;
1524 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1525 }
1526
Serialize_TPMI_RH_ENDORSEMENT(const TPMI_RH_ENDORSEMENT & value,std::string * buffer)1527 TPM_RC Serialize_TPMI_RH_ENDORSEMENT(const TPMI_RH_ENDORSEMENT& value,
1528 std::string* buffer) {
1529 VLOG(3) << __func__;
1530 return Serialize_TPM_HANDLE(value, buffer);
1531 }
1532
Parse_TPMI_RH_ENDORSEMENT(std::string * buffer,TPMI_RH_ENDORSEMENT * value,std::string * value_bytes)1533 TPM_RC Parse_TPMI_RH_ENDORSEMENT(std::string* buffer,
1534 TPMI_RH_ENDORSEMENT* value,
1535 std::string* value_bytes) {
1536 VLOG(3) << __func__;
1537 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1538 }
1539
Serialize_TPMI_RH_PROVISION(const TPMI_RH_PROVISION & value,std::string * buffer)1540 TPM_RC Serialize_TPMI_RH_PROVISION(const TPMI_RH_PROVISION& value,
1541 std::string* buffer) {
1542 VLOG(3) << __func__;
1543 return Serialize_TPM_HANDLE(value, buffer);
1544 }
1545
Parse_TPMI_RH_PROVISION(std::string * buffer,TPMI_RH_PROVISION * value,std::string * value_bytes)1546 TPM_RC Parse_TPMI_RH_PROVISION(std::string* buffer,
1547 TPMI_RH_PROVISION* value,
1548 std::string* value_bytes) {
1549 VLOG(3) << __func__;
1550 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1551 }
1552
Serialize_TPMI_RH_CLEAR(const TPMI_RH_CLEAR & value,std::string * buffer)1553 TPM_RC Serialize_TPMI_RH_CLEAR(const TPMI_RH_CLEAR& value,
1554 std::string* buffer) {
1555 VLOG(3) << __func__;
1556 return Serialize_TPM_HANDLE(value, buffer);
1557 }
1558
Parse_TPMI_RH_CLEAR(std::string * buffer,TPMI_RH_CLEAR * value,std::string * value_bytes)1559 TPM_RC Parse_TPMI_RH_CLEAR(std::string* buffer,
1560 TPMI_RH_CLEAR* value,
1561 std::string* value_bytes) {
1562 VLOG(3) << __func__;
1563 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1564 }
1565
Serialize_TPMI_RH_NV_AUTH(const TPMI_RH_NV_AUTH & value,std::string * buffer)1566 TPM_RC Serialize_TPMI_RH_NV_AUTH(const TPMI_RH_NV_AUTH& value,
1567 std::string* buffer) {
1568 VLOG(3) << __func__;
1569 return Serialize_TPM_HANDLE(value, buffer);
1570 }
1571
Parse_TPMI_RH_NV_AUTH(std::string * buffer,TPMI_RH_NV_AUTH * value,std::string * value_bytes)1572 TPM_RC Parse_TPMI_RH_NV_AUTH(std::string* buffer,
1573 TPMI_RH_NV_AUTH* value,
1574 std::string* value_bytes) {
1575 VLOG(3) << __func__;
1576 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1577 }
1578
Serialize_TPMI_RH_LOCKOUT(const TPMI_RH_LOCKOUT & value,std::string * buffer)1579 TPM_RC Serialize_TPMI_RH_LOCKOUT(const TPMI_RH_LOCKOUT& value,
1580 std::string* buffer) {
1581 VLOG(3) << __func__;
1582 return Serialize_TPM_HANDLE(value, buffer);
1583 }
1584
Parse_TPMI_RH_LOCKOUT(std::string * buffer,TPMI_RH_LOCKOUT * value,std::string * value_bytes)1585 TPM_RC Parse_TPMI_RH_LOCKOUT(std::string* buffer,
1586 TPMI_RH_LOCKOUT* value,
1587 std::string* value_bytes) {
1588 VLOG(3) << __func__;
1589 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1590 }
1591
Serialize_TPMI_RH_NV_INDEX(const TPMI_RH_NV_INDEX & value,std::string * buffer)1592 TPM_RC Serialize_TPMI_RH_NV_INDEX(const TPMI_RH_NV_INDEX& value,
1593 std::string* buffer) {
1594 VLOG(3) << __func__;
1595 return Serialize_TPM_HANDLE(value, buffer);
1596 }
1597
Parse_TPMI_RH_NV_INDEX(std::string * buffer,TPMI_RH_NV_INDEX * value,std::string * value_bytes)1598 TPM_RC Parse_TPMI_RH_NV_INDEX(std::string* buffer,
1599 TPMI_RH_NV_INDEX* value,
1600 std::string* value_bytes) {
1601 VLOG(3) << __func__;
1602 return Parse_TPM_HANDLE(buffer, value, value_bytes);
1603 }
1604
Serialize_TPMI_ALG_ASYM(const TPMI_ALG_ASYM & value,std::string * buffer)1605 TPM_RC Serialize_TPMI_ALG_ASYM(const TPMI_ALG_ASYM& value,
1606 std::string* buffer) {
1607 VLOG(3) << __func__;
1608 return Serialize_TPM_ALG_ID(value, buffer);
1609 }
1610
Parse_TPMI_ALG_ASYM(std::string * buffer,TPMI_ALG_ASYM * value,std::string * value_bytes)1611 TPM_RC Parse_TPMI_ALG_ASYM(std::string* buffer,
1612 TPMI_ALG_ASYM* value,
1613 std::string* value_bytes) {
1614 VLOG(3) << __func__;
1615 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1616 }
1617
Serialize_TPMI_ALG_SYM(const TPMI_ALG_SYM & value,std::string * buffer)1618 TPM_RC Serialize_TPMI_ALG_SYM(const TPMI_ALG_SYM& value, std::string* buffer) {
1619 VLOG(3) << __func__;
1620 return Serialize_TPM_ALG_ID(value, buffer);
1621 }
1622
Parse_TPMI_ALG_SYM(std::string * buffer,TPMI_ALG_SYM * value,std::string * value_bytes)1623 TPM_RC Parse_TPMI_ALG_SYM(std::string* buffer,
1624 TPMI_ALG_SYM* value,
1625 std::string* value_bytes) {
1626 VLOG(3) << __func__;
1627 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1628 }
1629
Serialize_TPMI_ALG_SYM_OBJECT(const TPMI_ALG_SYM_OBJECT & value,std::string * buffer)1630 TPM_RC Serialize_TPMI_ALG_SYM_OBJECT(const TPMI_ALG_SYM_OBJECT& value,
1631 std::string* buffer) {
1632 VLOG(3) << __func__;
1633 return Serialize_TPM_ALG_ID(value, buffer);
1634 }
1635
Parse_TPMI_ALG_SYM_OBJECT(std::string * buffer,TPMI_ALG_SYM_OBJECT * value,std::string * value_bytes)1636 TPM_RC Parse_TPMI_ALG_SYM_OBJECT(std::string* buffer,
1637 TPMI_ALG_SYM_OBJECT* value,
1638 std::string* value_bytes) {
1639 VLOG(3) << __func__;
1640 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1641 }
1642
Serialize_TPMI_ALG_SYM_MODE(const TPMI_ALG_SYM_MODE & value,std::string * buffer)1643 TPM_RC Serialize_TPMI_ALG_SYM_MODE(const TPMI_ALG_SYM_MODE& value,
1644 std::string* buffer) {
1645 VLOG(3) << __func__;
1646 return Serialize_TPM_ALG_ID(value, buffer);
1647 }
1648
Parse_TPMI_ALG_SYM_MODE(std::string * buffer,TPMI_ALG_SYM_MODE * value,std::string * value_bytes)1649 TPM_RC Parse_TPMI_ALG_SYM_MODE(std::string* buffer,
1650 TPMI_ALG_SYM_MODE* value,
1651 std::string* value_bytes) {
1652 VLOG(3) << __func__;
1653 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1654 }
1655
Serialize_TPMI_ALG_KDF(const TPMI_ALG_KDF & value,std::string * buffer)1656 TPM_RC Serialize_TPMI_ALG_KDF(const TPMI_ALG_KDF& value, std::string* buffer) {
1657 VLOG(3) << __func__;
1658 return Serialize_TPM_ALG_ID(value, buffer);
1659 }
1660
Parse_TPMI_ALG_KDF(std::string * buffer,TPMI_ALG_KDF * value,std::string * value_bytes)1661 TPM_RC Parse_TPMI_ALG_KDF(std::string* buffer,
1662 TPMI_ALG_KDF* value,
1663 std::string* value_bytes) {
1664 VLOG(3) << __func__;
1665 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1666 }
1667
Serialize_TPMI_ALG_SIG_SCHEME(const TPMI_ALG_SIG_SCHEME & value,std::string * buffer)1668 TPM_RC Serialize_TPMI_ALG_SIG_SCHEME(const TPMI_ALG_SIG_SCHEME& value,
1669 std::string* buffer) {
1670 VLOG(3) << __func__;
1671 return Serialize_TPM_ALG_ID(value, buffer);
1672 }
1673
Parse_TPMI_ALG_SIG_SCHEME(std::string * buffer,TPMI_ALG_SIG_SCHEME * value,std::string * value_bytes)1674 TPM_RC Parse_TPMI_ALG_SIG_SCHEME(std::string* buffer,
1675 TPMI_ALG_SIG_SCHEME* value,
1676 std::string* value_bytes) {
1677 VLOG(3) << __func__;
1678 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1679 }
1680
Serialize_TPMI_ECC_KEY_EXCHANGE(const TPMI_ECC_KEY_EXCHANGE & value,std::string * buffer)1681 TPM_RC Serialize_TPMI_ECC_KEY_EXCHANGE(const TPMI_ECC_KEY_EXCHANGE& value,
1682 std::string* buffer) {
1683 VLOG(3) << __func__;
1684 return Serialize_TPM_ALG_ID(value, buffer);
1685 }
1686
Parse_TPMI_ECC_KEY_EXCHANGE(std::string * buffer,TPMI_ECC_KEY_EXCHANGE * value,std::string * value_bytes)1687 TPM_RC Parse_TPMI_ECC_KEY_EXCHANGE(std::string* buffer,
1688 TPMI_ECC_KEY_EXCHANGE* value,
1689 std::string* value_bytes) {
1690 VLOG(3) << __func__;
1691 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1692 }
1693
Serialize_TPM_ST(const TPM_ST & value,std::string * buffer)1694 TPM_RC Serialize_TPM_ST(const TPM_ST& value, std::string* buffer) {
1695 VLOG(3) << __func__;
1696 return Serialize_UINT16(value, buffer);
1697 }
1698
Parse_TPM_ST(std::string * buffer,TPM_ST * value,std::string * value_bytes)1699 TPM_RC Parse_TPM_ST(std::string* buffer,
1700 TPM_ST* value,
1701 std::string* value_bytes) {
1702 VLOG(3) << __func__;
1703 return Parse_UINT16(buffer, value, value_bytes);
1704 }
1705
Serialize_TPMI_ST_COMMAND_TAG(const TPMI_ST_COMMAND_TAG & value,std::string * buffer)1706 TPM_RC Serialize_TPMI_ST_COMMAND_TAG(const TPMI_ST_COMMAND_TAG& value,
1707 std::string* buffer) {
1708 VLOG(3) << __func__;
1709 return Serialize_TPM_ST(value, buffer);
1710 }
1711
Parse_TPMI_ST_COMMAND_TAG(std::string * buffer,TPMI_ST_COMMAND_TAG * value,std::string * value_bytes)1712 TPM_RC Parse_TPMI_ST_COMMAND_TAG(std::string* buffer,
1713 TPMI_ST_COMMAND_TAG* value,
1714 std::string* value_bytes) {
1715 VLOG(3) << __func__;
1716 return Parse_TPM_ST(buffer, value, value_bytes);
1717 }
1718
Serialize_TPMI_ST_ATTEST(const TPMI_ST_ATTEST & value,std::string * buffer)1719 TPM_RC Serialize_TPMI_ST_ATTEST(const TPMI_ST_ATTEST& value,
1720 std::string* buffer) {
1721 VLOG(3) << __func__;
1722 return Serialize_TPM_ST(value, buffer);
1723 }
1724
Parse_TPMI_ST_ATTEST(std::string * buffer,TPMI_ST_ATTEST * value,std::string * value_bytes)1725 TPM_RC Parse_TPMI_ST_ATTEST(std::string* buffer,
1726 TPMI_ST_ATTEST* value,
1727 std::string* value_bytes) {
1728 VLOG(3) << __func__;
1729 return Parse_TPM_ST(buffer, value, value_bytes);
1730 }
1731
Serialize_TPMI_AES_KEY_BITS(const TPMI_AES_KEY_BITS & value,std::string * buffer)1732 TPM_RC Serialize_TPMI_AES_KEY_BITS(const TPMI_AES_KEY_BITS& value,
1733 std::string* buffer) {
1734 VLOG(3) << __func__;
1735 return Serialize_TPM_KEY_BITS(value, buffer);
1736 }
1737
Parse_TPMI_AES_KEY_BITS(std::string * buffer,TPMI_AES_KEY_BITS * value,std::string * value_bytes)1738 TPM_RC Parse_TPMI_AES_KEY_BITS(std::string* buffer,
1739 TPMI_AES_KEY_BITS* value,
1740 std::string* value_bytes) {
1741 VLOG(3) << __func__;
1742 return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1743 }
1744
Serialize_TPMI_SM4_KEY_BITS(const TPMI_SM4_KEY_BITS & value,std::string * buffer)1745 TPM_RC Serialize_TPMI_SM4_KEY_BITS(const TPMI_SM4_KEY_BITS& value,
1746 std::string* buffer) {
1747 VLOG(3) << __func__;
1748 return Serialize_TPM_KEY_BITS(value, buffer);
1749 }
1750
Parse_TPMI_SM4_KEY_BITS(std::string * buffer,TPMI_SM4_KEY_BITS * value,std::string * value_bytes)1751 TPM_RC Parse_TPMI_SM4_KEY_BITS(std::string* buffer,
1752 TPMI_SM4_KEY_BITS* value,
1753 std::string* value_bytes) {
1754 VLOG(3) << __func__;
1755 return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1756 }
1757
Serialize_TPMI_ALG_KEYEDHASH_SCHEME(const TPMI_ALG_KEYEDHASH_SCHEME & value,std::string * buffer)1758 TPM_RC Serialize_TPMI_ALG_KEYEDHASH_SCHEME(
1759 const TPMI_ALG_KEYEDHASH_SCHEME& value, std::string* buffer) {
1760 VLOG(3) << __func__;
1761 return Serialize_TPM_ALG_ID(value, buffer);
1762 }
1763
Parse_TPMI_ALG_KEYEDHASH_SCHEME(std::string * buffer,TPMI_ALG_KEYEDHASH_SCHEME * value,std::string * value_bytes)1764 TPM_RC Parse_TPMI_ALG_KEYEDHASH_SCHEME(std::string* buffer,
1765 TPMI_ALG_KEYEDHASH_SCHEME* value,
1766 std::string* value_bytes) {
1767 VLOG(3) << __func__;
1768 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1769 }
1770
Serialize_TPMI_ALG_ASYM_SCHEME(const TPMI_ALG_ASYM_SCHEME & value,std::string * buffer)1771 TPM_RC Serialize_TPMI_ALG_ASYM_SCHEME(const TPMI_ALG_ASYM_SCHEME& value,
1772 std::string* buffer) {
1773 VLOG(3) << __func__;
1774 return Serialize_TPM_ALG_ID(value, buffer);
1775 }
1776
Parse_TPMI_ALG_ASYM_SCHEME(std::string * buffer,TPMI_ALG_ASYM_SCHEME * value,std::string * value_bytes)1777 TPM_RC Parse_TPMI_ALG_ASYM_SCHEME(std::string* buffer,
1778 TPMI_ALG_ASYM_SCHEME* value,
1779 std::string* value_bytes) {
1780 VLOG(3) << __func__;
1781 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1782 }
1783
Serialize_TPMI_ALG_RSA_SCHEME(const TPMI_ALG_RSA_SCHEME & value,std::string * buffer)1784 TPM_RC Serialize_TPMI_ALG_RSA_SCHEME(const TPMI_ALG_RSA_SCHEME& value,
1785 std::string* buffer) {
1786 VLOG(3) << __func__;
1787 return Serialize_TPM_ALG_ID(value, buffer);
1788 }
1789
Parse_TPMI_ALG_RSA_SCHEME(std::string * buffer,TPMI_ALG_RSA_SCHEME * value,std::string * value_bytes)1790 TPM_RC Parse_TPMI_ALG_RSA_SCHEME(std::string* buffer,
1791 TPMI_ALG_RSA_SCHEME* value,
1792 std::string* value_bytes) {
1793 VLOG(3) << __func__;
1794 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1795 }
1796
Serialize_TPMI_ALG_RSA_DECRYPT(const TPMI_ALG_RSA_DECRYPT & value,std::string * buffer)1797 TPM_RC Serialize_TPMI_ALG_RSA_DECRYPT(const TPMI_ALG_RSA_DECRYPT& value,
1798 std::string* buffer) {
1799 VLOG(3) << __func__;
1800 return Serialize_TPM_ALG_ID(value, buffer);
1801 }
1802
Parse_TPMI_ALG_RSA_DECRYPT(std::string * buffer,TPMI_ALG_RSA_DECRYPT * value,std::string * value_bytes)1803 TPM_RC Parse_TPMI_ALG_RSA_DECRYPT(std::string* buffer,
1804 TPMI_ALG_RSA_DECRYPT* value,
1805 std::string* value_bytes) {
1806 VLOG(3) << __func__;
1807 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1808 }
1809
Serialize_TPMI_RSA_KEY_BITS(const TPMI_RSA_KEY_BITS & value,std::string * buffer)1810 TPM_RC Serialize_TPMI_RSA_KEY_BITS(const TPMI_RSA_KEY_BITS& value,
1811 std::string* buffer) {
1812 VLOG(3) << __func__;
1813 return Serialize_TPM_KEY_BITS(value, buffer);
1814 }
1815
Parse_TPMI_RSA_KEY_BITS(std::string * buffer,TPMI_RSA_KEY_BITS * value,std::string * value_bytes)1816 TPM_RC Parse_TPMI_RSA_KEY_BITS(std::string* buffer,
1817 TPMI_RSA_KEY_BITS* value,
1818 std::string* value_bytes) {
1819 VLOG(3) << __func__;
1820 return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1821 }
1822
Serialize_TPMI_ALG_ECC_SCHEME(const TPMI_ALG_ECC_SCHEME & value,std::string * buffer)1823 TPM_RC Serialize_TPMI_ALG_ECC_SCHEME(const TPMI_ALG_ECC_SCHEME& value,
1824 std::string* buffer) {
1825 VLOG(3) << __func__;
1826 return Serialize_TPM_ALG_ID(value, buffer);
1827 }
1828
Parse_TPMI_ALG_ECC_SCHEME(std::string * buffer,TPMI_ALG_ECC_SCHEME * value,std::string * value_bytes)1829 TPM_RC Parse_TPMI_ALG_ECC_SCHEME(std::string* buffer,
1830 TPMI_ALG_ECC_SCHEME* value,
1831 std::string* value_bytes) {
1832 VLOG(3) << __func__;
1833 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1834 }
1835
Serialize_TPM_ECC_CURVE(const TPM_ECC_CURVE & value,std::string * buffer)1836 TPM_RC Serialize_TPM_ECC_CURVE(const TPM_ECC_CURVE& value,
1837 std::string* buffer) {
1838 VLOG(3) << __func__;
1839 return Serialize_UINT16(value, buffer);
1840 }
1841
Parse_TPM_ECC_CURVE(std::string * buffer,TPM_ECC_CURVE * value,std::string * value_bytes)1842 TPM_RC Parse_TPM_ECC_CURVE(std::string* buffer,
1843 TPM_ECC_CURVE* value,
1844 std::string* value_bytes) {
1845 VLOG(3) << __func__;
1846 return Parse_UINT16(buffer, value, value_bytes);
1847 }
1848
Serialize_TPMI_ECC_CURVE(const TPMI_ECC_CURVE & value,std::string * buffer)1849 TPM_RC Serialize_TPMI_ECC_CURVE(const TPMI_ECC_CURVE& value,
1850 std::string* buffer) {
1851 VLOG(3) << __func__;
1852 return Serialize_TPM_ECC_CURVE(value, buffer);
1853 }
1854
Parse_TPMI_ECC_CURVE(std::string * buffer,TPMI_ECC_CURVE * value,std::string * value_bytes)1855 TPM_RC Parse_TPMI_ECC_CURVE(std::string* buffer,
1856 TPMI_ECC_CURVE* value,
1857 std::string* value_bytes) {
1858 VLOG(3) << __func__;
1859 return Parse_TPM_ECC_CURVE(buffer, value, value_bytes);
1860 }
1861
Serialize_TPMI_ALG_PUBLIC(const TPMI_ALG_PUBLIC & value,std::string * buffer)1862 TPM_RC Serialize_TPMI_ALG_PUBLIC(const TPMI_ALG_PUBLIC& value,
1863 std::string* buffer) {
1864 VLOG(3) << __func__;
1865 return Serialize_TPM_ALG_ID(value, buffer);
1866 }
1867
Parse_TPMI_ALG_PUBLIC(std::string * buffer,TPMI_ALG_PUBLIC * value,std::string * value_bytes)1868 TPM_RC Parse_TPMI_ALG_PUBLIC(std::string* buffer,
1869 TPMI_ALG_PUBLIC* value,
1870 std::string* value_bytes) {
1871 VLOG(3) << __func__;
1872 return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1873 }
1874
Serialize_TPMA_ALGORITHM(const TPMA_ALGORITHM & value,std::string * buffer)1875 TPM_RC Serialize_TPMA_ALGORITHM(const TPMA_ALGORITHM& value,
1876 std::string* buffer) {
1877 VLOG(3) << __func__;
1878 return Serialize_UINT32(value, buffer);
1879 }
1880
Parse_TPMA_ALGORITHM(std::string * buffer,TPMA_ALGORITHM * value,std::string * value_bytes)1881 TPM_RC Parse_TPMA_ALGORITHM(std::string* buffer,
1882 TPMA_ALGORITHM* value,
1883 std::string* value_bytes) {
1884 VLOG(3) << __func__;
1885 return Parse_UINT32(buffer, value, value_bytes);
1886 }
1887
Serialize_TPMA_OBJECT(const TPMA_OBJECT & value,std::string * buffer)1888 TPM_RC Serialize_TPMA_OBJECT(const TPMA_OBJECT& value, std::string* buffer) {
1889 VLOG(3) << __func__;
1890 return Serialize_UINT32(value, buffer);
1891 }
1892
Parse_TPMA_OBJECT(std::string * buffer,TPMA_OBJECT * value,std::string * value_bytes)1893 TPM_RC Parse_TPMA_OBJECT(std::string* buffer,
1894 TPMA_OBJECT* value,
1895 std::string* value_bytes) {
1896 VLOG(3) << __func__;
1897 return Parse_UINT32(buffer, value, value_bytes);
1898 }
1899
Serialize_TPMA_SESSION(const TPMA_SESSION & value,std::string * buffer)1900 TPM_RC Serialize_TPMA_SESSION(const TPMA_SESSION& value, std::string* buffer) {
1901 VLOG(3) << __func__;
1902 return Serialize_UINT8(value, buffer);
1903 }
1904
Parse_TPMA_SESSION(std::string * buffer,TPMA_SESSION * value,std::string * value_bytes)1905 TPM_RC Parse_TPMA_SESSION(std::string* buffer,
1906 TPMA_SESSION* value,
1907 std::string* value_bytes) {
1908 VLOG(3) << __func__;
1909 return Parse_UINT8(buffer, value, value_bytes);
1910 }
1911
Serialize_TPMA_LOCALITY(const TPMA_LOCALITY & value,std::string * buffer)1912 TPM_RC Serialize_TPMA_LOCALITY(const TPMA_LOCALITY& value,
1913 std::string* buffer) {
1914 VLOG(3) << __func__;
1915 return Serialize_UINT8(value, buffer);
1916 }
1917
Parse_TPMA_LOCALITY(std::string * buffer,TPMA_LOCALITY * value,std::string * value_bytes)1918 TPM_RC Parse_TPMA_LOCALITY(std::string* buffer,
1919 TPMA_LOCALITY* value,
1920 std::string* value_bytes) {
1921 VLOG(3) << __func__;
1922 return Parse_UINT8(buffer, value, value_bytes);
1923 }
1924
Serialize_TPMA_PERMANENT(const TPMA_PERMANENT & value,std::string * buffer)1925 TPM_RC Serialize_TPMA_PERMANENT(const TPMA_PERMANENT& value,
1926 std::string* buffer) {
1927 VLOG(3) << __func__;
1928 return Serialize_UINT32(value, buffer);
1929 }
1930
Parse_TPMA_PERMANENT(std::string * buffer,TPMA_PERMANENT * value,std::string * value_bytes)1931 TPM_RC Parse_TPMA_PERMANENT(std::string* buffer,
1932 TPMA_PERMANENT* value,
1933 std::string* value_bytes) {
1934 VLOG(3) << __func__;
1935 return Parse_UINT32(buffer, value, value_bytes);
1936 }
1937
Serialize_TPMA_STARTUP_CLEAR(const TPMA_STARTUP_CLEAR & value,std::string * buffer)1938 TPM_RC Serialize_TPMA_STARTUP_CLEAR(const TPMA_STARTUP_CLEAR& value,
1939 std::string* buffer) {
1940 VLOG(3) << __func__;
1941 return Serialize_UINT32(value, buffer);
1942 }
1943
Parse_TPMA_STARTUP_CLEAR(std::string * buffer,TPMA_STARTUP_CLEAR * value,std::string * value_bytes)1944 TPM_RC Parse_TPMA_STARTUP_CLEAR(std::string* buffer,
1945 TPMA_STARTUP_CLEAR* value,
1946 std::string* value_bytes) {
1947 VLOG(3) << __func__;
1948 return Parse_UINT32(buffer, value, value_bytes);
1949 }
1950
Serialize_TPMA_MEMORY(const TPMA_MEMORY & value,std::string * buffer)1951 TPM_RC Serialize_TPMA_MEMORY(const TPMA_MEMORY& value, std::string* buffer) {
1952 VLOG(3) << __func__;
1953 return Serialize_UINT32(value, buffer);
1954 }
1955
Parse_TPMA_MEMORY(std::string * buffer,TPMA_MEMORY * value,std::string * value_bytes)1956 TPM_RC Parse_TPMA_MEMORY(std::string* buffer,
1957 TPMA_MEMORY* value,
1958 std::string* value_bytes) {
1959 VLOG(3) << __func__;
1960 return Parse_UINT32(buffer, value, value_bytes);
1961 }
1962
Serialize_TPM_CC(const TPM_CC & value,std::string * buffer)1963 TPM_RC Serialize_TPM_CC(const TPM_CC& value, std::string* buffer) {
1964 VLOG(3) << __func__;
1965 return Serialize_UINT32(value, buffer);
1966 }
1967
Parse_TPM_CC(std::string * buffer,TPM_CC * value,std::string * value_bytes)1968 TPM_RC Parse_TPM_CC(std::string* buffer,
1969 TPM_CC* value,
1970 std::string* value_bytes) {
1971 VLOG(3) << __func__;
1972 return Parse_UINT32(buffer, value, value_bytes);
1973 }
1974
Serialize_TPMA_CC(const TPMA_CC & value,std::string * buffer)1975 TPM_RC Serialize_TPMA_CC(const TPMA_CC& value, std::string* buffer) {
1976 VLOG(3) << __func__;
1977 return Serialize_TPM_CC(value, buffer);
1978 }
1979
Parse_TPMA_CC(std::string * buffer,TPMA_CC * value,std::string * value_bytes)1980 TPM_RC Parse_TPMA_CC(std::string* buffer,
1981 TPMA_CC* value,
1982 std::string* value_bytes) {
1983 VLOG(3) << __func__;
1984 return Parse_TPM_CC(buffer, value, value_bytes);
1985 }
1986
Serialize_TPM_NV_INDEX(const TPM_NV_INDEX & value,std::string * buffer)1987 TPM_RC Serialize_TPM_NV_INDEX(const TPM_NV_INDEX& value, std::string* buffer) {
1988 VLOG(3) << __func__;
1989 return Serialize_UINT32(value, buffer);
1990 }
1991
Parse_TPM_NV_INDEX(std::string * buffer,TPM_NV_INDEX * value,std::string * value_bytes)1992 TPM_RC Parse_TPM_NV_INDEX(std::string* buffer,
1993 TPM_NV_INDEX* value,
1994 std::string* value_bytes) {
1995 VLOG(3) << __func__;
1996 return Parse_UINT32(buffer, value, value_bytes);
1997 }
1998
Serialize_TPMA_NV(const TPMA_NV & value,std::string * buffer)1999 TPM_RC Serialize_TPMA_NV(const TPMA_NV& value, std::string* buffer) {
2000 VLOG(3) << __func__;
2001 return Serialize_UINT32(value, buffer);
2002 }
2003
Parse_TPMA_NV(std::string * buffer,TPMA_NV * value,std::string * value_bytes)2004 TPM_RC Parse_TPMA_NV(std::string* buffer,
2005 TPMA_NV* value,
2006 std::string* value_bytes) {
2007 VLOG(3) << __func__;
2008 return Parse_UINT32(buffer, value, value_bytes);
2009 }
2010
Serialize_TPM_SPEC(const TPM_SPEC & value,std::string * buffer)2011 TPM_RC Serialize_TPM_SPEC(const TPM_SPEC& value, std::string* buffer) {
2012 VLOG(3) << __func__;
2013 return Serialize_UINT32(value, buffer);
2014 }
2015
Parse_TPM_SPEC(std::string * buffer,TPM_SPEC * value,std::string * value_bytes)2016 TPM_RC Parse_TPM_SPEC(std::string* buffer,
2017 TPM_SPEC* value,
2018 std::string* value_bytes) {
2019 VLOG(3) << __func__;
2020 return Parse_UINT32(buffer, value, value_bytes);
2021 }
2022
Serialize_TPM_GENERATED(const TPM_GENERATED & value,std::string * buffer)2023 TPM_RC Serialize_TPM_GENERATED(const TPM_GENERATED& value,
2024 std::string* buffer) {
2025 VLOG(3) << __func__;
2026 return Serialize_UINT32(value, buffer);
2027 }
2028
Parse_TPM_GENERATED(std::string * buffer,TPM_GENERATED * value,std::string * value_bytes)2029 TPM_RC Parse_TPM_GENERATED(std::string* buffer,
2030 TPM_GENERATED* value,
2031 std::string* value_bytes) {
2032 VLOG(3) << __func__;
2033 return Parse_UINT32(buffer, value, value_bytes);
2034 }
2035
Serialize_TPM_RC(const TPM_RC & value,std::string * buffer)2036 TPM_RC Serialize_TPM_RC(const TPM_RC& value, std::string* buffer) {
2037 VLOG(3) << __func__;
2038 return Serialize_UINT32(value, buffer);
2039 }
2040
Parse_TPM_RC(std::string * buffer,TPM_RC * value,std::string * value_bytes)2041 TPM_RC Parse_TPM_RC(std::string* buffer,
2042 TPM_RC* value,
2043 std::string* value_bytes) {
2044 VLOG(3) << __func__;
2045 return Parse_UINT32(buffer, value, value_bytes);
2046 }
2047
Serialize_TPM_CLOCK_ADJUST(const TPM_CLOCK_ADJUST & value,std::string * buffer)2048 TPM_RC Serialize_TPM_CLOCK_ADJUST(const TPM_CLOCK_ADJUST& value,
2049 std::string* buffer) {
2050 VLOG(3) << __func__;
2051 return Serialize_INT8(value, buffer);
2052 }
2053
Parse_TPM_CLOCK_ADJUST(std::string * buffer,TPM_CLOCK_ADJUST * value,std::string * value_bytes)2054 TPM_RC Parse_TPM_CLOCK_ADJUST(std::string* buffer,
2055 TPM_CLOCK_ADJUST* value,
2056 std::string* value_bytes) {
2057 VLOG(3) << __func__;
2058 return Parse_INT8(buffer, value, value_bytes);
2059 }
2060
Serialize_TPM_EO(const TPM_EO & value,std::string * buffer)2061 TPM_RC Serialize_TPM_EO(const TPM_EO& value, std::string* buffer) {
2062 VLOG(3) << __func__;
2063 return Serialize_UINT16(value, buffer);
2064 }
2065
Parse_TPM_EO(std::string * buffer,TPM_EO * value,std::string * value_bytes)2066 TPM_RC Parse_TPM_EO(std::string* buffer,
2067 TPM_EO* value,
2068 std::string* value_bytes) {
2069 VLOG(3) << __func__;
2070 return Parse_UINT16(buffer, value, value_bytes);
2071 }
2072
Serialize_TPM_SU(const TPM_SU & value,std::string * buffer)2073 TPM_RC Serialize_TPM_SU(const TPM_SU& value, std::string* buffer) {
2074 VLOG(3) << __func__;
2075 return Serialize_UINT16(value, buffer);
2076 }
2077
Parse_TPM_SU(std::string * buffer,TPM_SU * value,std::string * value_bytes)2078 TPM_RC Parse_TPM_SU(std::string* buffer,
2079 TPM_SU* value,
2080 std::string* value_bytes) {
2081 VLOG(3) << __func__;
2082 return Parse_UINT16(buffer, value, value_bytes);
2083 }
2084
Serialize_TPM_SE(const TPM_SE & value,std::string * buffer)2085 TPM_RC Serialize_TPM_SE(const TPM_SE& value, std::string* buffer) {
2086 VLOG(3) << __func__;
2087 return Serialize_UINT8(value, buffer);
2088 }
2089
Parse_TPM_SE(std::string * buffer,TPM_SE * value,std::string * value_bytes)2090 TPM_RC Parse_TPM_SE(std::string* buffer,
2091 TPM_SE* value,
2092 std::string* value_bytes) {
2093 VLOG(3) << __func__;
2094 return Parse_UINT8(buffer, value, value_bytes);
2095 }
2096
Serialize_TPM_CAP(const TPM_CAP & value,std::string * buffer)2097 TPM_RC Serialize_TPM_CAP(const TPM_CAP& value, std::string* buffer) {
2098 VLOG(3) << __func__;
2099 return Serialize_UINT32(value, buffer);
2100 }
2101
Parse_TPM_CAP(std::string * buffer,TPM_CAP * value,std::string * value_bytes)2102 TPM_RC Parse_TPM_CAP(std::string* buffer,
2103 TPM_CAP* value,
2104 std::string* value_bytes) {
2105 VLOG(3) << __func__;
2106 return Parse_UINT32(buffer, value, value_bytes);
2107 }
2108
Serialize_TPM_PT(const TPM_PT & value,std::string * buffer)2109 TPM_RC Serialize_TPM_PT(const TPM_PT& value, std::string* buffer) {
2110 VLOG(3) << __func__;
2111 return Serialize_UINT32(value, buffer);
2112 }
2113
Parse_TPM_PT(std::string * buffer,TPM_PT * value,std::string * value_bytes)2114 TPM_RC Parse_TPM_PT(std::string* buffer,
2115 TPM_PT* value,
2116 std::string* value_bytes) {
2117 VLOG(3) << __func__;
2118 return Parse_UINT32(buffer, value, value_bytes);
2119 }
2120
Serialize_TPM_PT_PCR(const TPM_PT_PCR & value,std::string * buffer)2121 TPM_RC Serialize_TPM_PT_PCR(const TPM_PT_PCR& value, std::string* buffer) {
2122 VLOG(3) << __func__;
2123 return Serialize_UINT32(value, buffer);
2124 }
2125
Parse_TPM_PT_PCR(std::string * buffer,TPM_PT_PCR * value,std::string * value_bytes)2126 TPM_RC Parse_TPM_PT_PCR(std::string* buffer,
2127 TPM_PT_PCR* value,
2128 std::string* value_bytes) {
2129 VLOG(3) << __func__;
2130 return Parse_UINT32(buffer, value, value_bytes);
2131 }
2132
Serialize_TPM_PS(const TPM_PS & value,std::string * buffer)2133 TPM_RC Serialize_TPM_PS(const TPM_PS& value, std::string* buffer) {
2134 VLOG(3) << __func__;
2135 return Serialize_UINT32(value, buffer);
2136 }
2137
Parse_TPM_PS(std::string * buffer,TPM_PS * value,std::string * value_bytes)2138 TPM_RC Parse_TPM_PS(std::string* buffer,
2139 TPM_PS* value,
2140 std::string* value_bytes) {
2141 VLOG(3) << __func__;
2142 return Parse_UINT32(buffer, value, value_bytes);
2143 }
2144
Serialize_TPM_HT(const TPM_HT & value,std::string * buffer)2145 TPM_RC Serialize_TPM_HT(const TPM_HT& value, std::string* buffer) {
2146 VLOG(3) << __func__;
2147 return Serialize_UINT8(value, buffer);
2148 }
2149
Parse_TPM_HT(std::string * buffer,TPM_HT * value,std::string * value_bytes)2150 TPM_RC Parse_TPM_HT(std::string* buffer,
2151 TPM_HT* value,
2152 std::string* value_bytes) {
2153 VLOG(3) << __func__;
2154 return Parse_UINT8(buffer, value, value_bytes);
2155 }
2156
Serialize_TPM_RH(const TPM_RH & value,std::string * buffer)2157 TPM_RC Serialize_TPM_RH(const TPM_RH& value, std::string* buffer) {
2158 VLOG(3) << __func__;
2159 return Serialize_UINT32(value, buffer);
2160 }
2161
Parse_TPM_RH(std::string * buffer,TPM_RH * value,std::string * value_bytes)2162 TPM_RC Parse_TPM_RH(std::string* buffer,
2163 TPM_RH* value,
2164 std::string* value_bytes) {
2165 VLOG(3) << __func__;
2166 return Parse_UINT32(buffer, value, value_bytes);
2167 }
2168
Serialize_TPM_HC(const TPM_HC & value,std::string * buffer)2169 TPM_RC Serialize_TPM_HC(const TPM_HC& value, std::string* buffer) {
2170 VLOG(3) << __func__;
2171 return Serialize_TPM_HANDLE(value, buffer);
2172 }
2173
Parse_TPM_HC(std::string * buffer,TPM_HC * value,std::string * value_bytes)2174 TPM_RC Parse_TPM_HC(std::string* buffer,
2175 TPM_HC* value,
2176 std::string* value_bytes) {
2177 VLOG(3) << __func__;
2178 return Parse_TPM_HANDLE(buffer, value, value_bytes);
2179 }
2180
Serialize_TPMS_ALGORITHM_DESCRIPTION(const TPMS_ALGORITHM_DESCRIPTION & value,std::string * buffer)2181 TPM_RC Serialize_TPMS_ALGORITHM_DESCRIPTION(
2182 const TPMS_ALGORITHM_DESCRIPTION& value, std::string* buffer) {
2183 TPM_RC result = TPM_RC_SUCCESS;
2184 VLOG(3) << __func__;
2185
2186 result = Serialize_TPM_ALG_ID(value.alg, buffer);
2187 if (result) {
2188 return result;
2189 }
2190
2191 result = Serialize_TPMA_ALGORITHM(value.attributes, buffer);
2192 if (result) {
2193 return result;
2194 }
2195 return result;
2196 }
2197
Parse_TPMS_ALGORITHM_DESCRIPTION(std::string * buffer,TPMS_ALGORITHM_DESCRIPTION * value,std::string * value_bytes)2198 TPM_RC Parse_TPMS_ALGORITHM_DESCRIPTION(std::string* buffer,
2199 TPMS_ALGORITHM_DESCRIPTION* value,
2200 std::string* value_bytes) {
2201 TPM_RC result = TPM_RC_SUCCESS;
2202 VLOG(3) << __func__;
2203
2204 result = Parse_TPM_ALG_ID(buffer, &value->alg, value_bytes);
2205 if (result) {
2206 return result;
2207 }
2208
2209 result = Parse_TPMA_ALGORITHM(buffer, &value->attributes, value_bytes);
2210 if (result) {
2211 return result;
2212 }
2213 return result;
2214 }
2215
Serialize_TPMU_HA(const TPMU_HA & value,TPMI_ALG_HASH selector,std::string * buffer)2216 TPM_RC Serialize_TPMU_HA(const TPMU_HA& value,
2217 TPMI_ALG_HASH selector,
2218 std::string* buffer) {
2219 TPM_RC result = TPM_RC_SUCCESS;
2220 VLOG(3) << __func__;
2221
2222 if (selector == TPM_ALG_SHA384) {
2223 if (std::size(value.sha384) < SHA384_DIGEST_SIZE) {
2224 return TPM_RC_INSUFFICIENT;
2225 }
2226 for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) {
2227 result = Serialize_BYTE(value.sha384[i], buffer);
2228 if (result) {
2229 return result;
2230 }
2231 }
2232 }
2233
2234 if (selector == TPM_ALG_SHA1) {
2235 if (std::size(value.sha1) < SHA1_DIGEST_SIZE) {
2236 return TPM_RC_INSUFFICIENT;
2237 }
2238 for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) {
2239 result = Serialize_BYTE(value.sha1[i], buffer);
2240 if (result) {
2241 return result;
2242 }
2243 }
2244 }
2245
2246 if (selector == TPM_ALG_SM3_256) {
2247 if (std::size(value.sm3_256) < SM3_256_DIGEST_SIZE) {
2248 return TPM_RC_INSUFFICIENT;
2249 }
2250 for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) {
2251 result = Serialize_BYTE(value.sm3_256[i], buffer);
2252 if (result) {
2253 return result;
2254 }
2255 }
2256 }
2257
2258 if (selector == TPM_ALG_NULL) {
2259 // Do nothing.
2260 }
2261
2262 if (selector == TPM_ALG_SHA256) {
2263 if (std::size(value.sha256) < SHA256_DIGEST_SIZE) {
2264 return TPM_RC_INSUFFICIENT;
2265 }
2266 for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) {
2267 result = Serialize_BYTE(value.sha256[i], buffer);
2268 if (result) {
2269 return result;
2270 }
2271 }
2272 }
2273
2274 if (selector == TPM_ALG_SHA512) {
2275 if (std::size(value.sha512) < SHA512_DIGEST_SIZE) {
2276 return TPM_RC_INSUFFICIENT;
2277 }
2278 for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) {
2279 result = Serialize_BYTE(value.sha512[i], buffer);
2280 if (result) {
2281 return result;
2282 }
2283 }
2284 }
2285 return result;
2286 }
2287
Parse_TPMU_HA(std::string * buffer,TPMI_ALG_HASH selector,TPMU_HA * value,std::string * value_bytes)2288 TPM_RC Parse_TPMU_HA(std::string* buffer,
2289 TPMI_ALG_HASH selector,
2290 TPMU_HA* value,
2291 std::string* value_bytes) {
2292 TPM_RC result = TPM_RC_SUCCESS;
2293 VLOG(3) << __func__;
2294
2295 if (selector == TPM_ALG_SHA384) {
2296 if (std::size(value->sha384) < SHA384_DIGEST_SIZE) {
2297 return TPM_RC_INSUFFICIENT;
2298 }
2299 for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) {
2300 result = Parse_BYTE(buffer, &value->sha384[i], value_bytes);
2301 if (result) {
2302 return result;
2303 }
2304 }
2305 }
2306
2307 if (selector == TPM_ALG_SHA1) {
2308 if (std::size(value->sha1) < SHA1_DIGEST_SIZE) {
2309 return TPM_RC_INSUFFICIENT;
2310 }
2311 for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) {
2312 result = Parse_BYTE(buffer, &value->sha1[i], value_bytes);
2313 if (result) {
2314 return result;
2315 }
2316 }
2317 }
2318
2319 if (selector == TPM_ALG_SM3_256) {
2320 if (std::size(value->sm3_256) < SM3_256_DIGEST_SIZE) {
2321 return TPM_RC_INSUFFICIENT;
2322 }
2323 for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) {
2324 result = Parse_BYTE(buffer, &value->sm3_256[i], value_bytes);
2325 if (result) {
2326 return result;
2327 }
2328 }
2329 }
2330
2331 if (selector == TPM_ALG_NULL) {
2332 // Do nothing.
2333 }
2334
2335 if (selector == TPM_ALG_SHA256) {
2336 if (std::size(value->sha256) < SHA256_DIGEST_SIZE) {
2337 return TPM_RC_INSUFFICIENT;
2338 }
2339 for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) {
2340 result = Parse_BYTE(buffer, &value->sha256[i], value_bytes);
2341 if (result) {
2342 return result;
2343 }
2344 }
2345 }
2346
2347 if (selector == TPM_ALG_SHA512) {
2348 if (std::size(value->sha512) < SHA512_DIGEST_SIZE) {
2349 return TPM_RC_INSUFFICIENT;
2350 }
2351 for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) {
2352 result = Parse_BYTE(buffer, &value->sha512[i], value_bytes);
2353 if (result) {
2354 return result;
2355 }
2356 }
2357 }
2358 return result;
2359 }
2360
Serialize_TPMT_HA(const TPMT_HA & value,std::string * buffer)2361 TPM_RC Serialize_TPMT_HA(const TPMT_HA& value, std::string* buffer) {
2362 TPM_RC result = TPM_RC_SUCCESS;
2363 VLOG(3) << __func__;
2364
2365 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
2366 if (result) {
2367 return result;
2368 }
2369
2370 result = Serialize_TPMU_HA(value.digest, value.hash_alg, buffer);
2371 if (result) {
2372 return result;
2373 }
2374 return result;
2375 }
2376
Parse_TPMT_HA(std::string * buffer,TPMT_HA * value,std::string * value_bytes)2377 TPM_RC Parse_TPMT_HA(std::string* buffer,
2378 TPMT_HA* value,
2379 std::string* value_bytes) {
2380 TPM_RC result = TPM_RC_SUCCESS;
2381 VLOG(3) << __func__;
2382
2383 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
2384 if (result) {
2385 return result;
2386 }
2387
2388 result = Parse_TPMU_HA(buffer, value->hash_alg, &value->digest, value_bytes);
2389 if (result) {
2390 return result;
2391 }
2392 return result;
2393 }
2394
Serialize_TPM2B_DATA(const TPM2B_DATA & value,std::string * buffer)2395 TPM_RC Serialize_TPM2B_DATA(const TPM2B_DATA& value, std::string* buffer) {
2396 TPM_RC result = TPM_RC_SUCCESS;
2397 VLOG(3) << __func__;
2398
2399 result = Serialize_UINT16(value.size, buffer);
2400 if (result) {
2401 return result;
2402 }
2403
2404 if (std::size(value.buffer) < value.size) {
2405 return TPM_RC_INSUFFICIENT;
2406 }
2407 for (uint32_t i = 0; i < value.size; ++i) {
2408 result = Serialize_BYTE(value.buffer[i], buffer);
2409 if (result) {
2410 return result;
2411 }
2412 }
2413 return result;
2414 }
2415
Parse_TPM2B_DATA(std::string * buffer,TPM2B_DATA * value,std::string * value_bytes)2416 TPM_RC Parse_TPM2B_DATA(std::string* buffer,
2417 TPM2B_DATA* value,
2418 std::string* value_bytes) {
2419 TPM_RC result = TPM_RC_SUCCESS;
2420 VLOG(3) << __func__;
2421
2422 result = Parse_UINT16(buffer, &value->size, value_bytes);
2423 if (result) {
2424 return result;
2425 }
2426
2427 if (std::size(value->buffer) < value->size) {
2428 return TPM_RC_INSUFFICIENT;
2429 }
2430 for (uint32_t i = 0; i < value->size; ++i) {
2431 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2432 if (result) {
2433 return result;
2434 }
2435 }
2436 return result;
2437 }
2438
Make_TPM2B_DATA(const std::string & bytes)2439 TPM2B_DATA Make_TPM2B_DATA(const std::string& bytes) {
2440 TPM2B_DATA tpm2b;
2441 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2442 memset(&tpm2b, 0, sizeof(TPM2B_DATA));
2443 tpm2b.size = bytes.size();
2444 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2445 return tpm2b;
2446 }
2447
StringFrom_TPM2B_DATA(const TPM2B_DATA & tpm2b)2448 std::string StringFrom_TPM2B_DATA(const TPM2B_DATA& tpm2b) {
2449 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2450 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2451 return std::string(char_buffer, tpm2b.size);
2452 }
2453
Serialize_TPM2B_EVENT(const TPM2B_EVENT & value,std::string * buffer)2454 TPM_RC Serialize_TPM2B_EVENT(const TPM2B_EVENT& value, std::string* buffer) {
2455 TPM_RC result = TPM_RC_SUCCESS;
2456 VLOG(3) << __func__;
2457
2458 result = Serialize_UINT16(value.size, buffer);
2459 if (result) {
2460 return result;
2461 }
2462
2463 if (std::size(value.buffer) < value.size) {
2464 return TPM_RC_INSUFFICIENT;
2465 }
2466 for (uint32_t i = 0; i < value.size; ++i) {
2467 result = Serialize_BYTE(value.buffer[i], buffer);
2468 if (result) {
2469 return result;
2470 }
2471 }
2472 return result;
2473 }
2474
Parse_TPM2B_EVENT(std::string * buffer,TPM2B_EVENT * value,std::string * value_bytes)2475 TPM_RC Parse_TPM2B_EVENT(std::string* buffer,
2476 TPM2B_EVENT* value,
2477 std::string* value_bytes) {
2478 TPM_RC result = TPM_RC_SUCCESS;
2479 VLOG(3) << __func__;
2480
2481 result = Parse_UINT16(buffer, &value->size, value_bytes);
2482 if (result) {
2483 return result;
2484 }
2485
2486 if (std::size(value->buffer) < value->size) {
2487 return TPM_RC_INSUFFICIENT;
2488 }
2489 for (uint32_t i = 0; i < value->size; ++i) {
2490 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2491 if (result) {
2492 return result;
2493 }
2494 }
2495 return result;
2496 }
2497
Make_TPM2B_EVENT(const std::string & bytes)2498 TPM2B_EVENT Make_TPM2B_EVENT(const std::string& bytes) {
2499 TPM2B_EVENT tpm2b;
2500 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2501 memset(&tpm2b, 0, sizeof(TPM2B_EVENT));
2502 tpm2b.size = bytes.size();
2503 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2504 return tpm2b;
2505 }
2506
StringFrom_TPM2B_EVENT(const TPM2B_EVENT & tpm2b)2507 std::string StringFrom_TPM2B_EVENT(const TPM2B_EVENT& tpm2b) {
2508 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2509 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2510 return std::string(char_buffer, tpm2b.size);
2511 }
2512
Serialize_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER & value,std::string * buffer)2513 TPM_RC Serialize_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER& value,
2514 std::string* buffer) {
2515 TPM_RC result = TPM_RC_SUCCESS;
2516 VLOG(3) << __func__;
2517
2518 result = Serialize_UINT16(value.size, buffer);
2519 if (result) {
2520 return result;
2521 }
2522
2523 if (std::size(value.buffer) < value.size) {
2524 return TPM_RC_INSUFFICIENT;
2525 }
2526 for (uint32_t i = 0; i < value.size; ++i) {
2527 result = Serialize_BYTE(value.buffer[i], buffer);
2528 if (result) {
2529 return result;
2530 }
2531 }
2532 return result;
2533 }
2534
Parse_TPM2B_MAX_BUFFER(std::string * buffer,TPM2B_MAX_BUFFER * value,std::string * value_bytes)2535 TPM_RC Parse_TPM2B_MAX_BUFFER(std::string* buffer,
2536 TPM2B_MAX_BUFFER* value,
2537 std::string* value_bytes) {
2538 TPM_RC result = TPM_RC_SUCCESS;
2539 VLOG(3) << __func__;
2540
2541 result = Parse_UINT16(buffer, &value->size, value_bytes);
2542 if (result) {
2543 return result;
2544 }
2545
2546 if (std::size(value->buffer) < value->size) {
2547 return TPM_RC_INSUFFICIENT;
2548 }
2549 for (uint32_t i = 0; i < value->size; ++i) {
2550 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2551 if (result) {
2552 return result;
2553 }
2554 }
2555 return result;
2556 }
2557
Make_TPM2B_MAX_BUFFER(const std::string & bytes)2558 TPM2B_MAX_BUFFER Make_TPM2B_MAX_BUFFER(const std::string& bytes) {
2559 TPM2B_MAX_BUFFER tpm2b;
2560 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2561 memset(&tpm2b, 0, sizeof(TPM2B_MAX_BUFFER));
2562 tpm2b.size = bytes.size();
2563 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2564 return tpm2b;
2565 }
2566
StringFrom_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER & tpm2b)2567 std::string StringFrom_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER& tpm2b) {
2568 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2569 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2570 return std::string(char_buffer, tpm2b.size);
2571 }
2572
Serialize_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER & value,std::string * buffer)2573 TPM_RC Serialize_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER& value,
2574 std::string* buffer) {
2575 TPM_RC result = TPM_RC_SUCCESS;
2576 VLOG(3) << __func__;
2577
2578 result = Serialize_UINT16(value.size, buffer);
2579 if (result) {
2580 return result;
2581 }
2582
2583 if (std::size(value.buffer) < value.size) {
2584 return TPM_RC_INSUFFICIENT;
2585 }
2586 for (uint32_t i = 0; i < value.size; ++i) {
2587 result = Serialize_BYTE(value.buffer[i], buffer);
2588 if (result) {
2589 return result;
2590 }
2591 }
2592 return result;
2593 }
2594
Parse_TPM2B_MAX_NV_BUFFER(std::string * buffer,TPM2B_MAX_NV_BUFFER * value,std::string * value_bytes)2595 TPM_RC Parse_TPM2B_MAX_NV_BUFFER(std::string* buffer,
2596 TPM2B_MAX_NV_BUFFER* value,
2597 std::string* value_bytes) {
2598 TPM_RC result = TPM_RC_SUCCESS;
2599 VLOG(3) << __func__;
2600
2601 result = Parse_UINT16(buffer, &value->size, value_bytes);
2602 if (result) {
2603 return result;
2604 }
2605
2606 if (std::size(value->buffer) < value->size) {
2607 return TPM_RC_INSUFFICIENT;
2608 }
2609 for (uint32_t i = 0; i < value->size; ++i) {
2610 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2611 if (result) {
2612 return result;
2613 }
2614 }
2615 return result;
2616 }
2617
Make_TPM2B_MAX_NV_BUFFER(const std::string & bytes)2618 TPM2B_MAX_NV_BUFFER Make_TPM2B_MAX_NV_BUFFER(const std::string& bytes) {
2619 TPM2B_MAX_NV_BUFFER tpm2b;
2620 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2621 memset(&tpm2b, 0, sizeof(TPM2B_MAX_NV_BUFFER));
2622 tpm2b.size = bytes.size();
2623 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2624 return tpm2b;
2625 }
2626
StringFrom_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER & tpm2b)2627 std::string StringFrom_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER& tpm2b) {
2628 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2629 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2630 return std::string(char_buffer, tpm2b.size);
2631 }
2632
Serialize_TPM2B_TIMEOUT(const TPM2B_TIMEOUT & value,std::string * buffer)2633 TPM_RC Serialize_TPM2B_TIMEOUT(const TPM2B_TIMEOUT& value,
2634 std::string* buffer) {
2635 TPM_RC result = TPM_RC_SUCCESS;
2636 VLOG(3) << __func__;
2637
2638 result = Serialize_UINT16(value.size, buffer);
2639 if (result) {
2640 return result;
2641 }
2642
2643 if (std::size(value.buffer) < value.size) {
2644 return TPM_RC_INSUFFICIENT;
2645 }
2646 for (uint32_t i = 0; i < value.size; ++i) {
2647 result = Serialize_BYTE(value.buffer[i], buffer);
2648 if (result) {
2649 return result;
2650 }
2651 }
2652 return result;
2653 }
2654
Parse_TPM2B_TIMEOUT(std::string * buffer,TPM2B_TIMEOUT * value,std::string * value_bytes)2655 TPM_RC Parse_TPM2B_TIMEOUT(std::string* buffer,
2656 TPM2B_TIMEOUT* value,
2657 std::string* value_bytes) {
2658 TPM_RC result = TPM_RC_SUCCESS;
2659 VLOG(3) << __func__;
2660
2661 result = Parse_UINT16(buffer, &value->size, value_bytes);
2662 if (result) {
2663 return result;
2664 }
2665
2666 if (std::size(value->buffer) < value->size) {
2667 return TPM_RC_INSUFFICIENT;
2668 }
2669 for (uint32_t i = 0; i < value->size; ++i) {
2670 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2671 if (result) {
2672 return result;
2673 }
2674 }
2675 return result;
2676 }
2677
Make_TPM2B_TIMEOUT(const std::string & bytes)2678 TPM2B_TIMEOUT Make_TPM2B_TIMEOUT(const std::string& bytes) {
2679 TPM2B_TIMEOUT tpm2b;
2680 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2681 memset(&tpm2b, 0, sizeof(TPM2B_TIMEOUT));
2682 tpm2b.size = bytes.size();
2683 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2684 return tpm2b;
2685 }
2686
StringFrom_TPM2B_TIMEOUT(const TPM2B_TIMEOUT & tpm2b)2687 std::string StringFrom_TPM2B_TIMEOUT(const TPM2B_TIMEOUT& tpm2b) {
2688 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2689 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2690 return std::string(char_buffer, tpm2b.size);
2691 }
2692
Serialize_TPM2B_IV(const TPM2B_IV & value,std::string * buffer)2693 TPM_RC Serialize_TPM2B_IV(const TPM2B_IV& value, std::string* buffer) {
2694 TPM_RC result = TPM_RC_SUCCESS;
2695 VLOG(3) << __func__;
2696
2697 result = Serialize_UINT16(value.size, buffer);
2698 if (result) {
2699 return result;
2700 }
2701
2702 if (std::size(value.buffer) < value.size) {
2703 return TPM_RC_INSUFFICIENT;
2704 }
2705 for (uint32_t i = 0; i < value.size; ++i) {
2706 result = Serialize_BYTE(value.buffer[i], buffer);
2707 if (result) {
2708 return result;
2709 }
2710 }
2711 return result;
2712 }
2713
Parse_TPM2B_IV(std::string * buffer,TPM2B_IV * value,std::string * value_bytes)2714 TPM_RC Parse_TPM2B_IV(std::string* buffer,
2715 TPM2B_IV* value,
2716 std::string* value_bytes) {
2717 TPM_RC result = TPM_RC_SUCCESS;
2718 VLOG(3) << __func__;
2719
2720 result = Parse_UINT16(buffer, &value->size, value_bytes);
2721 if (result) {
2722 return result;
2723 }
2724
2725 if (std::size(value->buffer) < value->size) {
2726 return TPM_RC_INSUFFICIENT;
2727 }
2728 for (uint32_t i = 0; i < value->size; ++i) {
2729 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2730 if (result) {
2731 return result;
2732 }
2733 }
2734 return result;
2735 }
2736
Make_TPM2B_IV(const std::string & bytes)2737 TPM2B_IV Make_TPM2B_IV(const std::string& bytes) {
2738 TPM2B_IV tpm2b;
2739 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2740 memset(&tpm2b, 0, sizeof(TPM2B_IV));
2741 tpm2b.size = bytes.size();
2742 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2743 return tpm2b;
2744 }
2745
StringFrom_TPM2B_IV(const TPM2B_IV & tpm2b)2746 std::string StringFrom_TPM2B_IV(const TPM2B_IV& tpm2b) {
2747 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2748 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2749 return std::string(char_buffer, tpm2b.size);
2750 }
2751
Serialize_TPM2B_NAME(const TPM2B_NAME & value,std::string * buffer)2752 TPM_RC Serialize_TPM2B_NAME(const TPM2B_NAME& value, std::string* buffer) {
2753 TPM_RC result = TPM_RC_SUCCESS;
2754 VLOG(3) << __func__;
2755
2756 result = Serialize_UINT16(value.size, buffer);
2757 if (result) {
2758 return result;
2759 }
2760
2761 if (std::size(value.name) < value.size) {
2762 return TPM_RC_INSUFFICIENT;
2763 }
2764 for (uint32_t i = 0; i < value.size; ++i) {
2765 result = Serialize_BYTE(value.name[i], buffer);
2766 if (result) {
2767 return result;
2768 }
2769 }
2770 return result;
2771 }
2772
Parse_TPM2B_NAME(std::string * buffer,TPM2B_NAME * value,std::string * value_bytes)2773 TPM_RC Parse_TPM2B_NAME(std::string* buffer,
2774 TPM2B_NAME* value,
2775 std::string* value_bytes) {
2776 TPM_RC result = TPM_RC_SUCCESS;
2777 VLOG(3) << __func__;
2778
2779 result = Parse_UINT16(buffer, &value->size, value_bytes);
2780 if (result) {
2781 return result;
2782 }
2783
2784 if (std::size(value->name) < value->size) {
2785 return TPM_RC_INSUFFICIENT;
2786 }
2787 for (uint32_t i = 0; i < value->size; ++i) {
2788 result = Parse_BYTE(buffer, &value->name[i], value_bytes);
2789 if (result) {
2790 return result;
2791 }
2792 }
2793 return result;
2794 }
2795
Make_TPM2B_NAME(const std::string & bytes)2796 TPM2B_NAME Make_TPM2B_NAME(const std::string& bytes) {
2797 TPM2B_NAME tpm2b;
2798 CHECK(bytes.size() <= sizeof(tpm2b.name));
2799 memset(&tpm2b, 0, sizeof(TPM2B_NAME));
2800 tpm2b.size = bytes.size();
2801 memcpy(tpm2b.name, bytes.data(), bytes.size());
2802 return tpm2b;
2803 }
2804
StringFrom_TPM2B_NAME(const TPM2B_NAME & tpm2b)2805 std::string StringFrom_TPM2B_NAME(const TPM2B_NAME& tpm2b) {
2806 CHECK(tpm2b.size <= std::size(tpm2b.name));
2807 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.name);
2808 return std::string(char_buffer, tpm2b.size);
2809 }
2810
Serialize_TPMS_PCR_SELECT(const TPMS_PCR_SELECT & value,std::string * buffer)2811 TPM_RC Serialize_TPMS_PCR_SELECT(const TPMS_PCR_SELECT& value,
2812 std::string* buffer) {
2813 TPM_RC result = TPM_RC_SUCCESS;
2814 VLOG(3) << __func__;
2815
2816 result = Serialize_UINT8(value.sizeof_select, buffer);
2817 if (result) {
2818 return result;
2819 }
2820
2821 if (std::size(value.pcr_select) < value.sizeof_select) {
2822 return TPM_RC_INSUFFICIENT;
2823 }
2824 for (uint32_t i = 0; i < value.sizeof_select; ++i) {
2825 result = Serialize_BYTE(value.pcr_select[i], buffer);
2826 if (result) {
2827 return result;
2828 }
2829 }
2830 return result;
2831 }
2832
Parse_TPMS_PCR_SELECT(std::string * buffer,TPMS_PCR_SELECT * value,std::string * value_bytes)2833 TPM_RC Parse_TPMS_PCR_SELECT(std::string* buffer,
2834 TPMS_PCR_SELECT* value,
2835 std::string* value_bytes) {
2836 TPM_RC result = TPM_RC_SUCCESS;
2837 VLOG(3) << __func__;
2838
2839 result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
2840 if (result) {
2841 return result;
2842 }
2843
2844 if (std::size(value->pcr_select) < value->sizeof_select) {
2845 return TPM_RC_INSUFFICIENT;
2846 }
2847 for (uint32_t i = 0; i < value->sizeof_select; ++i) {
2848 result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
2849 if (result) {
2850 return result;
2851 }
2852 }
2853 return result;
2854 }
2855
Serialize_TPMS_PCR_SELECTION(const TPMS_PCR_SELECTION & value,std::string * buffer)2856 TPM_RC Serialize_TPMS_PCR_SELECTION(const TPMS_PCR_SELECTION& value,
2857 std::string* buffer) {
2858 TPM_RC result = TPM_RC_SUCCESS;
2859 VLOG(3) << __func__;
2860
2861 result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
2862 if (result) {
2863 return result;
2864 }
2865
2866 result = Serialize_UINT8(value.sizeof_select, buffer);
2867 if (result) {
2868 return result;
2869 }
2870
2871 if (std::size(value.pcr_select) < value.sizeof_select) {
2872 return TPM_RC_INSUFFICIENT;
2873 }
2874 for (uint32_t i = 0; i < value.sizeof_select; ++i) {
2875 result = Serialize_BYTE(value.pcr_select[i], buffer);
2876 if (result) {
2877 return result;
2878 }
2879 }
2880 return result;
2881 }
2882
Parse_TPMS_PCR_SELECTION(std::string * buffer,TPMS_PCR_SELECTION * value,std::string * value_bytes)2883 TPM_RC Parse_TPMS_PCR_SELECTION(std::string* buffer,
2884 TPMS_PCR_SELECTION* value,
2885 std::string* value_bytes) {
2886 TPM_RC result = TPM_RC_SUCCESS;
2887 VLOG(3) << __func__;
2888
2889 result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
2890 if (result) {
2891 return result;
2892 }
2893
2894 result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
2895 if (result) {
2896 return result;
2897 }
2898
2899 if (std::size(value->pcr_select) < value->sizeof_select) {
2900 return TPM_RC_INSUFFICIENT;
2901 }
2902 for (uint32_t i = 0; i < value->sizeof_select; ++i) {
2903 result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
2904 if (result) {
2905 return result;
2906 }
2907 }
2908 return result;
2909 }
2910
Serialize_TPMT_TK_CREATION(const TPMT_TK_CREATION & value,std::string * buffer)2911 TPM_RC Serialize_TPMT_TK_CREATION(const TPMT_TK_CREATION& value,
2912 std::string* buffer) {
2913 TPM_RC result = TPM_RC_SUCCESS;
2914 VLOG(3) << __func__;
2915
2916 result = Serialize_TPM_ST(value.tag, buffer);
2917 if (result) {
2918 return result;
2919 }
2920
2921 result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
2922 if (result) {
2923 return result;
2924 }
2925
2926 result = Serialize_TPM2B_DIGEST(value.digest, buffer);
2927 if (result) {
2928 return result;
2929 }
2930 return result;
2931 }
2932
Parse_TPMT_TK_CREATION(std::string * buffer,TPMT_TK_CREATION * value,std::string * value_bytes)2933 TPM_RC Parse_TPMT_TK_CREATION(std::string* buffer,
2934 TPMT_TK_CREATION* value,
2935 std::string* value_bytes) {
2936 TPM_RC result = TPM_RC_SUCCESS;
2937 VLOG(3) << __func__;
2938
2939 result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
2940 if (result) {
2941 return result;
2942 }
2943
2944 result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
2945 if (result) {
2946 return result;
2947 }
2948
2949 result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
2950 if (result) {
2951 return result;
2952 }
2953 return result;
2954 }
2955
Serialize_TPMT_TK_VERIFIED(const TPMT_TK_VERIFIED & value,std::string * buffer)2956 TPM_RC Serialize_TPMT_TK_VERIFIED(const TPMT_TK_VERIFIED& value,
2957 std::string* buffer) {
2958 TPM_RC result = TPM_RC_SUCCESS;
2959 VLOG(3) << __func__;
2960
2961 result = Serialize_TPM_ST(value.tag, buffer);
2962 if (result) {
2963 return result;
2964 }
2965
2966 result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
2967 if (result) {
2968 return result;
2969 }
2970
2971 result = Serialize_TPM2B_DIGEST(value.digest, buffer);
2972 if (result) {
2973 return result;
2974 }
2975 return result;
2976 }
2977
Parse_TPMT_TK_VERIFIED(std::string * buffer,TPMT_TK_VERIFIED * value,std::string * value_bytes)2978 TPM_RC Parse_TPMT_TK_VERIFIED(std::string* buffer,
2979 TPMT_TK_VERIFIED* value,
2980 std::string* value_bytes) {
2981 TPM_RC result = TPM_RC_SUCCESS;
2982 VLOG(3) << __func__;
2983
2984 result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
2985 if (result) {
2986 return result;
2987 }
2988
2989 result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
2990 if (result) {
2991 return result;
2992 }
2993
2994 result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
2995 if (result) {
2996 return result;
2997 }
2998 return result;
2999 }
3000
Serialize_TPMT_TK_AUTH(const TPMT_TK_AUTH & value,std::string * buffer)3001 TPM_RC Serialize_TPMT_TK_AUTH(const TPMT_TK_AUTH& value, std::string* buffer) {
3002 TPM_RC result = TPM_RC_SUCCESS;
3003 VLOG(3) << __func__;
3004
3005 result = Serialize_TPM_ST(value.tag, buffer);
3006 if (result) {
3007 return result;
3008 }
3009
3010 result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
3011 if (result) {
3012 return result;
3013 }
3014
3015 result = Serialize_TPM2B_DIGEST(value.digest, buffer);
3016 if (result) {
3017 return result;
3018 }
3019 return result;
3020 }
3021
Parse_TPMT_TK_AUTH(std::string * buffer,TPMT_TK_AUTH * value,std::string * value_bytes)3022 TPM_RC Parse_TPMT_TK_AUTH(std::string* buffer,
3023 TPMT_TK_AUTH* value,
3024 std::string* value_bytes) {
3025 TPM_RC result = TPM_RC_SUCCESS;
3026 VLOG(3) << __func__;
3027
3028 result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
3029 if (result) {
3030 return result;
3031 }
3032
3033 result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
3034 if (result) {
3035 return result;
3036 }
3037
3038 result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
3039 if (result) {
3040 return result;
3041 }
3042 return result;
3043 }
3044
Serialize_TPMT_TK_HASHCHECK(const TPMT_TK_HASHCHECK & value,std::string * buffer)3045 TPM_RC Serialize_TPMT_TK_HASHCHECK(const TPMT_TK_HASHCHECK& value,
3046 std::string* buffer) {
3047 TPM_RC result = TPM_RC_SUCCESS;
3048 VLOG(3) << __func__;
3049
3050 result = Serialize_TPM_ST(value.tag, buffer);
3051 if (result) {
3052 return result;
3053 }
3054
3055 result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
3056 if (result) {
3057 return result;
3058 }
3059
3060 result = Serialize_TPM2B_DIGEST(value.digest, buffer);
3061 if (result) {
3062 return result;
3063 }
3064 return result;
3065 }
3066
Parse_TPMT_TK_HASHCHECK(std::string * buffer,TPMT_TK_HASHCHECK * value,std::string * value_bytes)3067 TPM_RC Parse_TPMT_TK_HASHCHECK(std::string* buffer,
3068 TPMT_TK_HASHCHECK* value,
3069 std::string* value_bytes) {
3070 TPM_RC result = TPM_RC_SUCCESS;
3071 VLOG(3) << __func__;
3072
3073 result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
3074 if (result) {
3075 return result;
3076 }
3077
3078 result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
3079 if (result) {
3080 return result;
3081 }
3082
3083 result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
3084 if (result) {
3085 return result;
3086 }
3087 return result;
3088 }
3089
Serialize_TPMS_ALG_PROPERTY(const TPMS_ALG_PROPERTY & value,std::string * buffer)3090 TPM_RC Serialize_TPMS_ALG_PROPERTY(const TPMS_ALG_PROPERTY& value,
3091 std::string* buffer) {
3092 TPM_RC result = TPM_RC_SUCCESS;
3093 VLOG(3) << __func__;
3094
3095 result = Serialize_TPM_ALG_ID(value.alg, buffer);
3096 if (result) {
3097 return result;
3098 }
3099
3100 result = Serialize_TPMA_ALGORITHM(value.alg_properties, buffer);
3101 if (result) {
3102 return result;
3103 }
3104 return result;
3105 }
3106
Parse_TPMS_ALG_PROPERTY(std::string * buffer,TPMS_ALG_PROPERTY * value,std::string * value_bytes)3107 TPM_RC Parse_TPMS_ALG_PROPERTY(std::string* buffer,
3108 TPMS_ALG_PROPERTY* value,
3109 std::string* value_bytes) {
3110 TPM_RC result = TPM_RC_SUCCESS;
3111 VLOG(3) << __func__;
3112
3113 result = Parse_TPM_ALG_ID(buffer, &value->alg, value_bytes);
3114 if (result) {
3115 return result;
3116 }
3117
3118 result = Parse_TPMA_ALGORITHM(buffer, &value->alg_properties, value_bytes);
3119 if (result) {
3120 return result;
3121 }
3122 return result;
3123 }
3124
Serialize_TPMS_TAGGED_PROPERTY(const TPMS_TAGGED_PROPERTY & value,std::string * buffer)3125 TPM_RC Serialize_TPMS_TAGGED_PROPERTY(const TPMS_TAGGED_PROPERTY& value,
3126 std::string* buffer) {
3127 TPM_RC result = TPM_RC_SUCCESS;
3128 VLOG(3) << __func__;
3129
3130 result = Serialize_TPM_PT(value.property, buffer);
3131 if (result) {
3132 return result;
3133 }
3134
3135 result = Serialize_UINT32(value.value, buffer);
3136 if (result) {
3137 return result;
3138 }
3139 return result;
3140 }
3141
Parse_TPMS_TAGGED_PROPERTY(std::string * buffer,TPMS_TAGGED_PROPERTY * value,std::string * value_bytes)3142 TPM_RC Parse_TPMS_TAGGED_PROPERTY(std::string* buffer,
3143 TPMS_TAGGED_PROPERTY* value,
3144 std::string* value_bytes) {
3145 TPM_RC result = TPM_RC_SUCCESS;
3146 VLOG(3) << __func__;
3147
3148 result = Parse_TPM_PT(buffer, &value->property, value_bytes);
3149 if (result) {
3150 return result;
3151 }
3152
3153 result = Parse_UINT32(buffer, &value->value, value_bytes);
3154 if (result) {
3155 return result;
3156 }
3157 return result;
3158 }
3159
Serialize_TPMS_TAGGED_PCR_SELECT(const TPMS_TAGGED_PCR_SELECT & value,std::string * buffer)3160 TPM_RC Serialize_TPMS_TAGGED_PCR_SELECT(const TPMS_TAGGED_PCR_SELECT& value,
3161 std::string* buffer) {
3162 TPM_RC result = TPM_RC_SUCCESS;
3163 VLOG(3) << __func__;
3164
3165 result = Serialize_TPM_PT(value.tag, buffer);
3166 if (result) {
3167 return result;
3168 }
3169
3170 result = Serialize_UINT8(value.sizeof_select, buffer);
3171 if (result) {
3172 return result;
3173 }
3174
3175 if (std::size(value.pcr_select) < value.sizeof_select) {
3176 return TPM_RC_INSUFFICIENT;
3177 }
3178 for (uint32_t i = 0; i < value.sizeof_select; ++i) {
3179 result = Serialize_BYTE(value.pcr_select[i], buffer);
3180 if (result) {
3181 return result;
3182 }
3183 }
3184 return result;
3185 }
3186
Parse_TPMS_TAGGED_PCR_SELECT(std::string * buffer,TPMS_TAGGED_PCR_SELECT * value,std::string * value_bytes)3187 TPM_RC Parse_TPMS_TAGGED_PCR_SELECT(std::string* buffer,
3188 TPMS_TAGGED_PCR_SELECT* value,
3189 std::string* value_bytes) {
3190 TPM_RC result = TPM_RC_SUCCESS;
3191 VLOG(3) << __func__;
3192
3193 result = Parse_TPM_PT(buffer, &value->tag, value_bytes);
3194 if (result) {
3195 return result;
3196 }
3197
3198 result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
3199 if (result) {
3200 return result;
3201 }
3202
3203 if (std::size(value->pcr_select) < value->sizeof_select) {
3204 return TPM_RC_INSUFFICIENT;
3205 }
3206 for (uint32_t i = 0; i < value->sizeof_select; ++i) {
3207 result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
3208 if (result) {
3209 return result;
3210 }
3211 }
3212 return result;
3213 }
3214
Serialize_TPML_CC(const TPML_CC & value,std::string * buffer)3215 TPM_RC Serialize_TPML_CC(const TPML_CC& value, std::string* buffer) {
3216 TPM_RC result = TPM_RC_SUCCESS;
3217 VLOG(3) << __func__;
3218
3219 result = Serialize_UINT32(value.count, buffer);
3220 if (result) {
3221 return result;
3222 }
3223
3224 if (std::size(value.command_codes) < value.count) {
3225 return TPM_RC_INSUFFICIENT;
3226 }
3227 for (uint32_t i = 0; i < value.count; ++i) {
3228 result = Serialize_TPM_CC(value.command_codes[i], buffer);
3229 if (result) {
3230 return result;
3231 }
3232 }
3233 return result;
3234 }
3235
Parse_TPML_CC(std::string * buffer,TPML_CC * value,std::string * value_bytes)3236 TPM_RC Parse_TPML_CC(std::string* buffer,
3237 TPML_CC* value,
3238 std::string* value_bytes) {
3239 TPM_RC result = TPM_RC_SUCCESS;
3240 VLOG(3) << __func__;
3241
3242 result = Parse_UINT32(buffer, &value->count, value_bytes);
3243 if (result) {
3244 return result;
3245 }
3246
3247 if (std::size(value->command_codes) < value->count) {
3248 return TPM_RC_INSUFFICIENT;
3249 }
3250 for (uint32_t i = 0; i < value->count; ++i) {
3251 result = Parse_TPM_CC(buffer, &value->command_codes[i], value_bytes);
3252 if (result) {
3253 return result;
3254 }
3255 }
3256 return result;
3257 }
3258
Serialize_TPML_CCA(const TPML_CCA & value,std::string * buffer)3259 TPM_RC Serialize_TPML_CCA(const TPML_CCA& value, std::string* buffer) {
3260 TPM_RC result = TPM_RC_SUCCESS;
3261 VLOG(3) << __func__;
3262
3263 result = Serialize_UINT32(value.count, buffer);
3264 if (result) {
3265 return result;
3266 }
3267
3268 if (std::size(value.command_attributes) < value.count) {
3269 return TPM_RC_INSUFFICIENT;
3270 }
3271 for (uint32_t i = 0; i < value.count; ++i) {
3272 result = Serialize_TPMA_CC(value.command_attributes[i], buffer);
3273 if (result) {
3274 return result;
3275 }
3276 }
3277 return result;
3278 }
3279
Parse_TPML_CCA(std::string * buffer,TPML_CCA * value,std::string * value_bytes)3280 TPM_RC Parse_TPML_CCA(std::string* buffer,
3281 TPML_CCA* value,
3282 std::string* value_bytes) {
3283 TPM_RC result = TPM_RC_SUCCESS;
3284 VLOG(3) << __func__;
3285
3286 result = Parse_UINT32(buffer, &value->count, value_bytes);
3287 if (result) {
3288 return result;
3289 }
3290
3291 if (std::size(value->command_attributes) < value->count) {
3292 return TPM_RC_INSUFFICIENT;
3293 }
3294 for (uint32_t i = 0; i < value->count; ++i) {
3295 result = Parse_TPMA_CC(buffer, &value->command_attributes[i], value_bytes);
3296 if (result) {
3297 return result;
3298 }
3299 }
3300 return result;
3301 }
3302
Serialize_TPML_ALG(const TPML_ALG & value,std::string * buffer)3303 TPM_RC Serialize_TPML_ALG(const TPML_ALG& value, std::string* buffer) {
3304 TPM_RC result = TPM_RC_SUCCESS;
3305 VLOG(3) << __func__;
3306
3307 result = Serialize_UINT32(value.count, buffer);
3308 if (result) {
3309 return result;
3310 }
3311
3312 if (std::size(value.algorithms) < value.count) {
3313 return TPM_RC_INSUFFICIENT;
3314 }
3315 for (uint32_t i = 0; i < value.count; ++i) {
3316 result = Serialize_TPM_ALG_ID(value.algorithms[i], buffer);
3317 if (result) {
3318 return result;
3319 }
3320 }
3321 return result;
3322 }
3323
Parse_TPML_ALG(std::string * buffer,TPML_ALG * value,std::string * value_bytes)3324 TPM_RC Parse_TPML_ALG(std::string* buffer,
3325 TPML_ALG* value,
3326 std::string* value_bytes) {
3327 TPM_RC result = TPM_RC_SUCCESS;
3328 VLOG(3) << __func__;
3329
3330 result = Parse_UINT32(buffer, &value->count, value_bytes);
3331 if (result) {
3332 return result;
3333 }
3334
3335 if (std::size(value->algorithms) < value->count) {
3336 return TPM_RC_INSUFFICIENT;
3337 }
3338 for (uint32_t i = 0; i < value->count; ++i) {
3339 result = Parse_TPM_ALG_ID(buffer, &value->algorithms[i], value_bytes);
3340 if (result) {
3341 return result;
3342 }
3343 }
3344 return result;
3345 }
3346
Serialize_TPML_HANDLE(const TPML_HANDLE & value,std::string * buffer)3347 TPM_RC Serialize_TPML_HANDLE(const TPML_HANDLE& value, std::string* buffer) {
3348 TPM_RC result = TPM_RC_SUCCESS;
3349 VLOG(3) << __func__;
3350
3351 result = Serialize_UINT32(value.count, buffer);
3352 if (result) {
3353 return result;
3354 }
3355
3356 if (std::size(value.handle) < value.count) {
3357 return TPM_RC_INSUFFICIENT;
3358 }
3359 for (uint32_t i = 0; i < value.count; ++i) {
3360 result = Serialize_TPM_HANDLE(value.handle[i], buffer);
3361 if (result) {
3362 return result;
3363 }
3364 }
3365 return result;
3366 }
3367
Parse_TPML_HANDLE(std::string * buffer,TPML_HANDLE * value,std::string * value_bytes)3368 TPM_RC Parse_TPML_HANDLE(std::string* buffer,
3369 TPML_HANDLE* value,
3370 std::string* value_bytes) {
3371 TPM_RC result = TPM_RC_SUCCESS;
3372 VLOG(3) << __func__;
3373
3374 result = Parse_UINT32(buffer, &value->count, value_bytes);
3375 if (result) {
3376 return result;
3377 }
3378
3379 if (std::size(value->handle) < value->count) {
3380 return TPM_RC_INSUFFICIENT;
3381 }
3382 for (uint32_t i = 0; i < value->count; ++i) {
3383 result = Parse_TPM_HANDLE(buffer, &value->handle[i], value_bytes);
3384 if (result) {
3385 return result;
3386 }
3387 }
3388 return result;
3389 }
3390
Serialize_TPML_DIGEST(const TPML_DIGEST & value,std::string * buffer)3391 TPM_RC Serialize_TPML_DIGEST(const TPML_DIGEST& value, std::string* buffer) {
3392 TPM_RC result = TPM_RC_SUCCESS;
3393 VLOG(3) << __func__;
3394
3395 result = Serialize_UINT32(value.count, buffer);
3396 if (result) {
3397 return result;
3398 }
3399
3400 if (std::size(value.digests) < value.count) {
3401 return TPM_RC_INSUFFICIENT;
3402 }
3403 for (uint32_t i = 0; i < value.count; ++i) {
3404 result = Serialize_TPM2B_DIGEST(value.digests[i], buffer);
3405 if (result) {
3406 return result;
3407 }
3408 }
3409 return result;
3410 }
3411
Parse_TPML_DIGEST(std::string * buffer,TPML_DIGEST * value,std::string * value_bytes)3412 TPM_RC Parse_TPML_DIGEST(std::string* buffer,
3413 TPML_DIGEST* value,
3414 std::string* value_bytes) {
3415 TPM_RC result = TPM_RC_SUCCESS;
3416 VLOG(3) << __func__;
3417
3418 result = Parse_UINT32(buffer, &value->count, value_bytes);
3419 if (result) {
3420 return result;
3421 }
3422
3423 if (std::size(value->digests) < value->count) {
3424 return TPM_RC_INSUFFICIENT;
3425 }
3426 for (uint32_t i = 0; i < value->count; ++i) {
3427 result = Parse_TPM2B_DIGEST(buffer, &value->digests[i], value_bytes);
3428 if (result) {
3429 return result;
3430 }
3431 }
3432 return result;
3433 }
3434
Serialize_TPML_DIGEST_VALUES(const TPML_DIGEST_VALUES & value,std::string * buffer)3435 TPM_RC Serialize_TPML_DIGEST_VALUES(const TPML_DIGEST_VALUES& value,
3436 std::string* buffer) {
3437 TPM_RC result = TPM_RC_SUCCESS;
3438 VLOG(3) << __func__;
3439
3440 result = Serialize_UINT32(value.count, buffer);
3441 if (result) {
3442 return result;
3443 }
3444
3445 if (std::size(value.digests) < value.count) {
3446 return TPM_RC_INSUFFICIENT;
3447 }
3448 for (uint32_t i = 0; i < value.count; ++i) {
3449 result = Serialize_TPMT_HA(value.digests[i], buffer);
3450 if (result) {
3451 return result;
3452 }
3453 }
3454 return result;
3455 }
3456
Parse_TPML_DIGEST_VALUES(std::string * buffer,TPML_DIGEST_VALUES * value,std::string * value_bytes)3457 TPM_RC Parse_TPML_DIGEST_VALUES(std::string* buffer,
3458 TPML_DIGEST_VALUES* value,
3459 std::string* value_bytes) {
3460 TPM_RC result = TPM_RC_SUCCESS;
3461 VLOG(3) << __func__;
3462
3463 result = Parse_UINT32(buffer, &value->count, value_bytes);
3464 if (result) {
3465 return result;
3466 }
3467
3468 if (std::size(value->digests) < value->count) {
3469 return TPM_RC_INSUFFICIENT;
3470 }
3471 for (uint32_t i = 0; i < value->count; ++i) {
3472 result = Parse_TPMT_HA(buffer, &value->digests[i], value_bytes);
3473 if (result) {
3474 return result;
3475 }
3476 }
3477 return result;
3478 }
3479
Serialize_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES & value,std::string * buffer)3480 TPM_RC Serialize_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES& value,
3481 std::string* buffer) {
3482 TPM_RC result = TPM_RC_SUCCESS;
3483 VLOG(3) << __func__;
3484
3485 result = Serialize_UINT16(value.size, buffer);
3486 if (result) {
3487 return result;
3488 }
3489
3490 if (std::size(value.buffer) < value.size) {
3491 return TPM_RC_INSUFFICIENT;
3492 }
3493 for (uint32_t i = 0; i < value.size; ++i) {
3494 result = Serialize_BYTE(value.buffer[i], buffer);
3495 if (result) {
3496 return result;
3497 }
3498 }
3499 return result;
3500 }
3501
Parse_TPM2B_DIGEST_VALUES(std::string * buffer,TPM2B_DIGEST_VALUES * value,std::string * value_bytes)3502 TPM_RC Parse_TPM2B_DIGEST_VALUES(std::string* buffer,
3503 TPM2B_DIGEST_VALUES* value,
3504 std::string* value_bytes) {
3505 TPM_RC result = TPM_RC_SUCCESS;
3506 VLOG(3) << __func__;
3507
3508 result = Parse_UINT16(buffer, &value->size, value_bytes);
3509 if (result) {
3510 return result;
3511 }
3512
3513 if (std::size(value->buffer) < value->size) {
3514 return TPM_RC_INSUFFICIENT;
3515 }
3516 for (uint32_t i = 0; i < value->size; ++i) {
3517 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
3518 if (result) {
3519 return result;
3520 }
3521 }
3522 return result;
3523 }
3524
Make_TPM2B_DIGEST_VALUES(const std::string & bytes)3525 TPM2B_DIGEST_VALUES Make_TPM2B_DIGEST_VALUES(const std::string& bytes) {
3526 TPM2B_DIGEST_VALUES tpm2b;
3527 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
3528 memset(&tpm2b, 0, sizeof(TPM2B_DIGEST_VALUES));
3529 tpm2b.size = bytes.size();
3530 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
3531 return tpm2b;
3532 }
3533
StringFrom_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES & tpm2b)3534 std::string StringFrom_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES& tpm2b) {
3535 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
3536 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
3537 return std::string(char_buffer, tpm2b.size);
3538 }
3539
Serialize_TPML_PCR_SELECTION(const TPML_PCR_SELECTION & value,std::string * buffer)3540 TPM_RC Serialize_TPML_PCR_SELECTION(const TPML_PCR_SELECTION& value,
3541 std::string* buffer) {
3542 TPM_RC result = TPM_RC_SUCCESS;
3543 VLOG(3) << __func__;
3544
3545 result = Serialize_UINT32(value.count, buffer);
3546 if (result) {
3547 return result;
3548 }
3549
3550 if (std::size(value.pcr_selections) < value.count) {
3551 return TPM_RC_INSUFFICIENT;
3552 }
3553 for (uint32_t i = 0; i < value.count; ++i) {
3554 result = Serialize_TPMS_PCR_SELECTION(value.pcr_selections[i], buffer);
3555 if (result) {
3556 return result;
3557 }
3558 }
3559 return result;
3560 }
3561
Parse_TPML_PCR_SELECTION(std::string * buffer,TPML_PCR_SELECTION * value,std::string * value_bytes)3562 TPM_RC Parse_TPML_PCR_SELECTION(std::string* buffer,
3563 TPML_PCR_SELECTION* value,
3564 std::string* value_bytes) {
3565 TPM_RC result = TPM_RC_SUCCESS;
3566 VLOG(3) << __func__;
3567
3568 result = Parse_UINT32(buffer, &value->count, value_bytes);
3569 if (result) {
3570 return result;
3571 }
3572
3573 if (std::size(value->pcr_selections) < value->count) {
3574 return TPM_RC_INSUFFICIENT;
3575 }
3576 for (uint32_t i = 0; i < value->count; ++i) {
3577 result = Parse_TPMS_PCR_SELECTION(buffer, &value->pcr_selections[i],
3578 value_bytes);
3579 if (result) {
3580 return result;
3581 }
3582 }
3583 return result;
3584 }
3585
Serialize_TPML_ALG_PROPERTY(const TPML_ALG_PROPERTY & value,std::string * buffer)3586 TPM_RC Serialize_TPML_ALG_PROPERTY(const TPML_ALG_PROPERTY& value,
3587 std::string* buffer) {
3588 TPM_RC result = TPM_RC_SUCCESS;
3589 VLOG(3) << __func__;
3590
3591 result = Serialize_UINT32(value.count, buffer);
3592 if (result) {
3593 return result;
3594 }
3595
3596 if (std::size(value.alg_properties) < value.count) {
3597 return TPM_RC_INSUFFICIENT;
3598 }
3599 for (uint32_t i = 0; i < value.count; ++i) {
3600 result = Serialize_TPMS_ALG_PROPERTY(value.alg_properties[i], buffer);
3601 if (result) {
3602 return result;
3603 }
3604 }
3605 return result;
3606 }
3607
Parse_TPML_ALG_PROPERTY(std::string * buffer,TPML_ALG_PROPERTY * value,std::string * value_bytes)3608 TPM_RC Parse_TPML_ALG_PROPERTY(std::string* buffer,
3609 TPML_ALG_PROPERTY* value,
3610 std::string* value_bytes) {
3611 TPM_RC result = TPM_RC_SUCCESS;
3612 VLOG(3) << __func__;
3613
3614 result = Parse_UINT32(buffer, &value->count, value_bytes);
3615 if (result) {
3616 return result;
3617 }
3618
3619 if (std::size(value->alg_properties) < value->count) {
3620 return TPM_RC_INSUFFICIENT;
3621 }
3622 for (uint32_t i = 0; i < value->count; ++i) {
3623 result =
3624 Parse_TPMS_ALG_PROPERTY(buffer, &value->alg_properties[i], value_bytes);
3625 if (result) {
3626 return result;
3627 }
3628 }
3629 return result;
3630 }
3631
Serialize_TPML_TAGGED_TPM_PROPERTY(const TPML_TAGGED_TPM_PROPERTY & value,std::string * buffer)3632 TPM_RC Serialize_TPML_TAGGED_TPM_PROPERTY(const TPML_TAGGED_TPM_PROPERTY& value,
3633 std::string* buffer) {
3634 TPM_RC result = TPM_RC_SUCCESS;
3635 VLOG(3) << __func__;
3636
3637 result = Serialize_UINT32(value.count, buffer);
3638 if (result) {
3639 return result;
3640 }
3641
3642 if (std::size(value.tpm_property) < value.count) {
3643 return TPM_RC_INSUFFICIENT;
3644 }
3645 for (uint32_t i = 0; i < value.count; ++i) {
3646 result = Serialize_TPMS_TAGGED_PROPERTY(value.tpm_property[i], buffer);
3647 if (result) {
3648 return result;
3649 }
3650 }
3651 return result;
3652 }
3653
Parse_TPML_TAGGED_TPM_PROPERTY(std::string * buffer,TPML_TAGGED_TPM_PROPERTY * value,std::string * value_bytes)3654 TPM_RC Parse_TPML_TAGGED_TPM_PROPERTY(std::string* buffer,
3655 TPML_TAGGED_TPM_PROPERTY* value,
3656 std::string* value_bytes) {
3657 TPM_RC result = TPM_RC_SUCCESS;
3658 VLOG(3) << __func__;
3659
3660 result = Parse_UINT32(buffer, &value->count, value_bytes);
3661 if (result) {
3662 return result;
3663 }
3664
3665 if (std::size(value->tpm_property) < value->count) {
3666 return TPM_RC_INSUFFICIENT;
3667 }
3668 for (uint32_t i = 0; i < value->count; ++i) {
3669 result = Parse_TPMS_TAGGED_PROPERTY(buffer, &value->tpm_property[i],
3670 value_bytes);
3671 if (result) {
3672 return result;
3673 }
3674 }
3675 return result;
3676 }
3677
Serialize_TPML_TAGGED_PCR_PROPERTY(const TPML_TAGGED_PCR_PROPERTY & value,std::string * buffer)3678 TPM_RC Serialize_TPML_TAGGED_PCR_PROPERTY(const TPML_TAGGED_PCR_PROPERTY& value,
3679 std::string* buffer) {
3680 TPM_RC result = TPM_RC_SUCCESS;
3681 VLOG(3) << __func__;
3682
3683 result = Serialize_UINT32(value.count, buffer);
3684 if (result) {
3685 return result;
3686 }
3687
3688 if (std::size(value.pcr_property) < value.count) {
3689 return TPM_RC_INSUFFICIENT;
3690 }
3691 for (uint32_t i = 0; i < value.count; ++i) {
3692 result = Serialize_TPMS_TAGGED_PCR_SELECT(value.pcr_property[i], buffer);
3693 if (result) {
3694 return result;
3695 }
3696 }
3697 return result;
3698 }
3699
Parse_TPML_TAGGED_PCR_PROPERTY(std::string * buffer,TPML_TAGGED_PCR_PROPERTY * value,std::string * value_bytes)3700 TPM_RC Parse_TPML_TAGGED_PCR_PROPERTY(std::string* buffer,
3701 TPML_TAGGED_PCR_PROPERTY* value,
3702 std::string* value_bytes) {
3703 TPM_RC result = TPM_RC_SUCCESS;
3704 VLOG(3) << __func__;
3705
3706 result = Parse_UINT32(buffer, &value->count, value_bytes);
3707 if (result) {
3708 return result;
3709 }
3710
3711 if (std::size(value->pcr_property) < value->count) {
3712 return TPM_RC_INSUFFICIENT;
3713 }
3714 for (uint32_t i = 0; i < value->count; ++i) {
3715 result = Parse_TPMS_TAGGED_PCR_SELECT(buffer, &value->pcr_property[i],
3716 value_bytes);
3717 if (result) {
3718 return result;
3719 }
3720 }
3721 return result;
3722 }
3723
Serialize_TPML_ECC_CURVE(const TPML_ECC_CURVE & value,std::string * buffer)3724 TPM_RC Serialize_TPML_ECC_CURVE(const TPML_ECC_CURVE& value,
3725 std::string* buffer) {
3726 TPM_RC result = TPM_RC_SUCCESS;
3727 VLOG(3) << __func__;
3728
3729 result = Serialize_UINT32(value.count, buffer);
3730 if (result) {
3731 return result;
3732 }
3733
3734 if (std::size(value.ecc_curves) < value.count) {
3735 return TPM_RC_INSUFFICIENT;
3736 }
3737 for (uint32_t i = 0; i < value.count; ++i) {
3738 result = Serialize_TPM_ECC_CURVE(value.ecc_curves[i], buffer);
3739 if (result) {
3740 return result;
3741 }
3742 }
3743 return result;
3744 }
3745
Parse_TPML_ECC_CURVE(std::string * buffer,TPML_ECC_CURVE * value,std::string * value_bytes)3746 TPM_RC Parse_TPML_ECC_CURVE(std::string* buffer,
3747 TPML_ECC_CURVE* value,
3748 std::string* value_bytes) {
3749 TPM_RC result = TPM_RC_SUCCESS;
3750 VLOG(3) << __func__;
3751
3752 result = Parse_UINT32(buffer, &value->count, value_bytes);
3753 if (result) {
3754 return result;
3755 }
3756
3757 if (std::size(value->ecc_curves) < value->count) {
3758 return TPM_RC_INSUFFICIENT;
3759 }
3760 for (uint32_t i = 0; i < value->count; ++i) {
3761 result = Parse_TPM_ECC_CURVE(buffer, &value->ecc_curves[i], value_bytes);
3762 if (result) {
3763 return result;
3764 }
3765 }
3766 return result;
3767 }
3768
Serialize_TPMU_CAPABILITIES(const TPMU_CAPABILITIES & value,TPM_CAP selector,std::string * buffer)3769 TPM_RC Serialize_TPMU_CAPABILITIES(const TPMU_CAPABILITIES& value,
3770 TPM_CAP selector,
3771 std::string* buffer) {
3772 TPM_RC result = TPM_RC_SUCCESS;
3773 VLOG(3) << __func__;
3774
3775 if (selector == TPM_CAP_PCRS) {
3776 result = Serialize_TPML_PCR_SELECTION(value.assigned_pcr, buffer);
3777 if (result) {
3778 return result;
3779 }
3780 }
3781
3782 if (selector == TPM_CAP_TPM_PROPERTIES) {
3783 result = Serialize_TPML_TAGGED_TPM_PROPERTY(value.tpm_properties, buffer);
3784 if (result) {
3785 return result;
3786 }
3787 }
3788
3789 if (selector == TPM_CAP_PP_COMMANDS) {
3790 result = Serialize_TPML_CC(value.pp_commands, buffer);
3791 if (result) {
3792 return result;
3793 }
3794 }
3795
3796 if (selector == TPM_CAP_AUDIT_COMMANDS) {
3797 result = Serialize_TPML_CC(value.audit_commands, buffer);
3798 if (result) {
3799 return result;
3800 }
3801 }
3802
3803 if (selector == TPM_CAP_COMMANDS) {
3804 result = Serialize_TPML_CCA(value.command, buffer);
3805 if (result) {
3806 return result;
3807 }
3808 }
3809
3810 if (selector == TPM_CAP_ECC_CURVES) {
3811 result = Serialize_TPML_ECC_CURVE(value.ecc_curves, buffer);
3812 if (result) {
3813 return result;
3814 }
3815 }
3816
3817 if (selector == TPM_CAP_PCR_PROPERTIES) {
3818 result = Serialize_TPML_TAGGED_PCR_PROPERTY(value.pcr_properties, buffer);
3819 if (result) {
3820 return result;
3821 }
3822 }
3823
3824 if (selector == TPM_CAP_HANDLES) {
3825 result = Serialize_TPML_HANDLE(value.handles, buffer);
3826 if (result) {
3827 return result;
3828 }
3829 }
3830
3831 if (selector == TPM_CAP_ALGS) {
3832 result = Serialize_TPML_ALG_PROPERTY(value.algorithms, buffer);
3833 if (result) {
3834 return result;
3835 }
3836 }
3837 return result;
3838 }
3839
Parse_TPMU_CAPABILITIES(std::string * buffer,TPM_CAP selector,TPMU_CAPABILITIES * value,std::string * value_bytes)3840 TPM_RC Parse_TPMU_CAPABILITIES(std::string* buffer,
3841 TPM_CAP selector,
3842 TPMU_CAPABILITIES* value,
3843 std::string* value_bytes) {
3844 TPM_RC result = TPM_RC_SUCCESS;
3845 VLOG(3) << __func__;
3846
3847 if (selector == TPM_CAP_PCRS) {
3848 result =
3849 Parse_TPML_PCR_SELECTION(buffer, &value->assigned_pcr, value_bytes);
3850 if (result) {
3851 return result;
3852 }
3853 }
3854
3855 if (selector == TPM_CAP_TPM_PROPERTIES) {
3856 result = Parse_TPML_TAGGED_TPM_PROPERTY(buffer, &value->tpm_properties,
3857 value_bytes);
3858 if (result) {
3859 return result;
3860 }
3861 }
3862
3863 if (selector == TPM_CAP_PP_COMMANDS) {
3864 result = Parse_TPML_CC(buffer, &value->pp_commands, value_bytes);
3865 if (result) {
3866 return result;
3867 }
3868 }
3869
3870 if (selector == TPM_CAP_AUDIT_COMMANDS) {
3871 result = Parse_TPML_CC(buffer, &value->audit_commands, value_bytes);
3872 if (result) {
3873 return result;
3874 }
3875 }
3876
3877 if (selector == TPM_CAP_COMMANDS) {
3878 result = Parse_TPML_CCA(buffer, &value->command, value_bytes);
3879 if (result) {
3880 return result;
3881 }
3882 }
3883
3884 if (selector == TPM_CAP_ECC_CURVES) {
3885 result = Parse_TPML_ECC_CURVE(buffer, &value->ecc_curves, value_bytes);
3886 if (result) {
3887 return result;
3888 }
3889 }
3890
3891 if (selector == TPM_CAP_PCR_PROPERTIES) {
3892 result = Parse_TPML_TAGGED_PCR_PROPERTY(buffer, &value->pcr_properties,
3893 value_bytes);
3894 if (result) {
3895 return result;
3896 }
3897 }
3898
3899 if (selector == TPM_CAP_HANDLES) {
3900 result = Parse_TPML_HANDLE(buffer, &value->handles, value_bytes);
3901 if (result) {
3902 return result;
3903 }
3904 }
3905
3906 if (selector == TPM_CAP_ALGS) {
3907 result = Parse_TPML_ALG_PROPERTY(buffer, &value->algorithms, value_bytes);
3908 if (result) {
3909 return result;
3910 }
3911 }
3912 return result;
3913 }
3914
Serialize_TPMS_CAPABILITY_DATA(const TPMS_CAPABILITY_DATA & value,std::string * buffer)3915 TPM_RC Serialize_TPMS_CAPABILITY_DATA(const TPMS_CAPABILITY_DATA& value,
3916 std::string* buffer) {
3917 TPM_RC result = TPM_RC_SUCCESS;
3918 VLOG(3) << __func__;
3919
3920 result = Serialize_TPM_CAP(value.capability, buffer);
3921 if (result) {
3922 return result;
3923 }
3924
3925 result = Serialize_TPMU_CAPABILITIES(value.data, value.capability, buffer);
3926 if (result) {
3927 return result;
3928 }
3929 return result;
3930 }
3931
Parse_TPMS_CAPABILITY_DATA(std::string * buffer,TPMS_CAPABILITY_DATA * value,std::string * value_bytes)3932 TPM_RC Parse_TPMS_CAPABILITY_DATA(std::string* buffer,
3933 TPMS_CAPABILITY_DATA* value,
3934 std::string* value_bytes) {
3935 TPM_RC result = TPM_RC_SUCCESS;
3936 VLOG(3) << __func__;
3937
3938 result = Parse_TPM_CAP(buffer, &value->capability, value_bytes);
3939 if (result) {
3940 return result;
3941 }
3942
3943 result = Parse_TPMU_CAPABILITIES(buffer, value->capability, &value->data,
3944 value_bytes);
3945 if (result) {
3946 return result;
3947 }
3948 return result;
3949 }
3950
Serialize_TPMS_CLOCK_INFO(const TPMS_CLOCK_INFO & value,std::string * buffer)3951 TPM_RC Serialize_TPMS_CLOCK_INFO(const TPMS_CLOCK_INFO& value,
3952 std::string* buffer) {
3953 TPM_RC result = TPM_RC_SUCCESS;
3954 VLOG(3) << __func__;
3955
3956 result = Serialize_UINT64(value.clock, buffer);
3957 if (result) {
3958 return result;
3959 }
3960
3961 result = Serialize_UINT32(value.reset_count, buffer);
3962 if (result) {
3963 return result;
3964 }
3965
3966 result = Serialize_UINT32(value.restart_count, buffer);
3967 if (result) {
3968 return result;
3969 }
3970
3971 result = Serialize_TPMI_YES_NO(value.safe, buffer);
3972 if (result) {
3973 return result;
3974 }
3975 return result;
3976 }
3977
Parse_TPMS_CLOCK_INFO(std::string * buffer,TPMS_CLOCK_INFO * value,std::string * value_bytes)3978 TPM_RC Parse_TPMS_CLOCK_INFO(std::string* buffer,
3979 TPMS_CLOCK_INFO* value,
3980 std::string* value_bytes) {
3981 TPM_RC result = TPM_RC_SUCCESS;
3982 VLOG(3) << __func__;
3983
3984 result = Parse_UINT64(buffer, &value->clock, value_bytes);
3985 if (result) {
3986 return result;
3987 }
3988
3989 result = Parse_UINT32(buffer, &value->reset_count, value_bytes);
3990 if (result) {
3991 return result;
3992 }
3993
3994 result = Parse_UINT32(buffer, &value->restart_count, value_bytes);
3995 if (result) {
3996 return result;
3997 }
3998
3999 result = Parse_TPMI_YES_NO(buffer, &value->safe, value_bytes);
4000 if (result) {
4001 return result;
4002 }
4003 return result;
4004 }
4005
Serialize_TPMS_TIME_INFO(const TPMS_TIME_INFO & value,std::string * buffer)4006 TPM_RC Serialize_TPMS_TIME_INFO(const TPMS_TIME_INFO& value,
4007 std::string* buffer) {
4008 TPM_RC result = TPM_RC_SUCCESS;
4009 VLOG(3) << __func__;
4010
4011 result = Serialize_UINT64(value.time, buffer);
4012 if (result) {
4013 return result;
4014 }
4015
4016 result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer);
4017 if (result) {
4018 return result;
4019 }
4020 return result;
4021 }
4022
Parse_TPMS_TIME_INFO(std::string * buffer,TPMS_TIME_INFO * value,std::string * value_bytes)4023 TPM_RC Parse_TPMS_TIME_INFO(std::string* buffer,
4024 TPMS_TIME_INFO* value,
4025 std::string* value_bytes) {
4026 TPM_RC result = TPM_RC_SUCCESS;
4027 VLOG(3) << __func__;
4028
4029 result = Parse_UINT64(buffer, &value->time, value_bytes);
4030 if (result) {
4031 return result;
4032 }
4033
4034 result = Parse_TPMS_CLOCK_INFO(buffer, &value->clock_info, value_bytes);
4035 if (result) {
4036 return result;
4037 }
4038 return result;
4039 }
4040
Serialize_TPMS_TIME_ATTEST_INFO(const TPMS_TIME_ATTEST_INFO & value,std::string * buffer)4041 TPM_RC Serialize_TPMS_TIME_ATTEST_INFO(const TPMS_TIME_ATTEST_INFO& value,
4042 std::string* buffer) {
4043 TPM_RC result = TPM_RC_SUCCESS;
4044 VLOG(3) << __func__;
4045
4046 result = Serialize_TPMS_TIME_INFO(value.time, buffer);
4047 if (result) {
4048 return result;
4049 }
4050
4051 result = Serialize_UINT64(value.firmware_version, buffer);
4052 if (result) {
4053 return result;
4054 }
4055 return result;
4056 }
4057
Parse_TPMS_TIME_ATTEST_INFO(std::string * buffer,TPMS_TIME_ATTEST_INFO * value,std::string * value_bytes)4058 TPM_RC Parse_TPMS_TIME_ATTEST_INFO(std::string* buffer,
4059 TPMS_TIME_ATTEST_INFO* value,
4060 std::string* value_bytes) {
4061 TPM_RC result = TPM_RC_SUCCESS;
4062 VLOG(3) << __func__;
4063
4064 result = Parse_TPMS_TIME_INFO(buffer, &value->time, value_bytes);
4065 if (result) {
4066 return result;
4067 }
4068
4069 result = Parse_UINT64(buffer, &value->firmware_version, value_bytes);
4070 if (result) {
4071 return result;
4072 }
4073 return result;
4074 }
4075
Serialize_TPMS_CERTIFY_INFO(const TPMS_CERTIFY_INFO & value,std::string * buffer)4076 TPM_RC Serialize_TPMS_CERTIFY_INFO(const TPMS_CERTIFY_INFO& value,
4077 std::string* buffer) {
4078 TPM_RC result = TPM_RC_SUCCESS;
4079 VLOG(3) << __func__;
4080
4081 result = Serialize_TPM2B_NAME(value.name, buffer);
4082 if (result) {
4083 return result;
4084 }
4085
4086 result = Serialize_TPM2B_NAME(value.qualified_name, buffer);
4087 if (result) {
4088 return result;
4089 }
4090 return result;
4091 }
4092
Parse_TPMS_CERTIFY_INFO(std::string * buffer,TPMS_CERTIFY_INFO * value,std::string * value_bytes)4093 TPM_RC Parse_TPMS_CERTIFY_INFO(std::string* buffer,
4094 TPMS_CERTIFY_INFO* value,
4095 std::string* value_bytes) {
4096 TPM_RC result = TPM_RC_SUCCESS;
4097 VLOG(3) << __func__;
4098
4099 result = Parse_TPM2B_NAME(buffer, &value->name, value_bytes);
4100 if (result) {
4101 return result;
4102 }
4103
4104 result = Parse_TPM2B_NAME(buffer, &value->qualified_name, value_bytes);
4105 if (result) {
4106 return result;
4107 }
4108 return result;
4109 }
4110
Serialize_TPMS_QUOTE_INFO(const TPMS_QUOTE_INFO & value,std::string * buffer)4111 TPM_RC Serialize_TPMS_QUOTE_INFO(const TPMS_QUOTE_INFO& value,
4112 std::string* buffer) {
4113 TPM_RC result = TPM_RC_SUCCESS;
4114 VLOG(3) << __func__;
4115
4116 result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer);
4117 if (result) {
4118 return result;
4119 }
4120
4121 result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer);
4122 if (result) {
4123 return result;
4124 }
4125 return result;
4126 }
4127
Parse_TPMS_QUOTE_INFO(std::string * buffer,TPMS_QUOTE_INFO * value,std::string * value_bytes)4128 TPM_RC Parse_TPMS_QUOTE_INFO(std::string* buffer,
4129 TPMS_QUOTE_INFO* value,
4130 std::string* value_bytes) {
4131 TPM_RC result = TPM_RC_SUCCESS;
4132 VLOG(3) << __func__;
4133
4134 result = Parse_TPML_PCR_SELECTION(buffer, &value->pcr_select, value_bytes);
4135 if (result) {
4136 return result;
4137 }
4138
4139 result = Parse_TPM2B_DIGEST(buffer, &value->pcr_digest, value_bytes);
4140 if (result) {
4141 return result;
4142 }
4143 return result;
4144 }
4145
Serialize_TPMS_COMMAND_AUDIT_INFO(const TPMS_COMMAND_AUDIT_INFO & value,std::string * buffer)4146 TPM_RC Serialize_TPMS_COMMAND_AUDIT_INFO(const TPMS_COMMAND_AUDIT_INFO& value,
4147 std::string* buffer) {
4148 TPM_RC result = TPM_RC_SUCCESS;
4149 VLOG(3) << __func__;
4150
4151 result = Serialize_UINT64(value.audit_counter, buffer);
4152 if (result) {
4153 return result;
4154 }
4155
4156 result = Serialize_TPM_ALG_ID(value.digest_alg, buffer);
4157 if (result) {
4158 return result;
4159 }
4160
4161 result = Serialize_TPM2B_DIGEST(value.audit_digest, buffer);
4162 if (result) {
4163 return result;
4164 }
4165
4166 result = Serialize_TPM2B_DIGEST(value.command_digest, buffer);
4167 if (result) {
4168 return result;
4169 }
4170 return result;
4171 }
4172
Parse_TPMS_COMMAND_AUDIT_INFO(std::string * buffer,TPMS_COMMAND_AUDIT_INFO * value,std::string * value_bytes)4173 TPM_RC Parse_TPMS_COMMAND_AUDIT_INFO(std::string* buffer,
4174 TPMS_COMMAND_AUDIT_INFO* value,
4175 std::string* value_bytes) {
4176 TPM_RC result = TPM_RC_SUCCESS;
4177 VLOG(3) << __func__;
4178
4179 result = Parse_UINT64(buffer, &value->audit_counter, value_bytes);
4180 if (result) {
4181 return result;
4182 }
4183
4184 result = Parse_TPM_ALG_ID(buffer, &value->digest_alg, value_bytes);
4185 if (result) {
4186 return result;
4187 }
4188
4189 result = Parse_TPM2B_DIGEST(buffer, &value->audit_digest, value_bytes);
4190 if (result) {
4191 return result;
4192 }
4193
4194 result = Parse_TPM2B_DIGEST(buffer, &value->command_digest, value_bytes);
4195 if (result) {
4196 return result;
4197 }
4198 return result;
4199 }
4200
Serialize_TPMS_SESSION_AUDIT_INFO(const TPMS_SESSION_AUDIT_INFO & value,std::string * buffer)4201 TPM_RC Serialize_TPMS_SESSION_AUDIT_INFO(const TPMS_SESSION_AUDIT_INFO& value,
4202 std::string* buffer) {
4203 TPM_RC result = TPM_RC_SUCCESS;
4204 VLOG(3) << __func__;
4205
4206 result = Serialize_TPMI_YES_NO(value.exclusive_session, buffer);
4207 if (result) {
4208 return result;
4209 }
4210
4211 result = Serialize_TPM2B_DIGEST(value.session_digest, buffer);
4212 if (result) {
4213 return result;
4214 }
4215 return result;
4216 }
4217
Parse_TPMS_SESSION_AUDIT_INFO(std::string * buffer,TPMS_SESSION_AUDIT_INFO * value,std::string * value_bytes)4218 TPM_RC Parse_TPMS_SESSION_AUDIT_INFO(std::string* buffer,
4219 TPMS_SESSION_AUDIT_INFO* value,
4220 std::string* value_bytes) {
4221 TPM_RC result = TPM_RC_SUCCESS;
4222 VLOG(3) << __func__;
4223
4224 result = Parse_TPMI_YES_NO(buffer, &value->exclusive_session, value_bytes);
4225 if (result) {
4226 return result;
4227 }
4228
4229 result = Parse_TPM2B_DIGEST(buffer, &value->session_digest, value_bytes);
4230 if (result) {
4231 return result;
4232 }
4233 return result;
4234 }
4235
Serialize_TPMS_CREATION_INFO(const TPMS_CREATION_INFO & value,std::string * buffer)4236 TPM_RC Serialize_TPMS_CREATION_INFO(const TPMS_CREATION_INFO& value,
4237 std::string* buffer) {
4238 TPM_RC result = TPM_RC_SUCCESS;
4239 VLOG(3) << __func__;
4240
4241 result = Serialize_TPM2B_NAME(value.object_name, buffer);
4242 if (result) {
4243 return result;
4244 }
4245
4246 result = Serialize_TPM2B_DIGEST(value.creation_hash, buffer);
4247 if (result) {
4248 return result;
4249 }
4250 return result;
4251 }
4252
Parse_TPMS_CREATION_INFO(std::string * buffer,TPMS_CREATION_INFO * value,std::string * value_bytes)4253 TPM_RC Parse_TPMS_CREATION_INFO(std::string* buffer,
4254 TPMS_CREATION_INFO* value,
4255 std::string* value_bytes) {
4256 TPM_RC result = TPM_RC_SUCCESS;
4257 VLOG(3) << __func__;
4258
4259 result = Parse_TPM2B_NAME(buffer, &value->object_name, value_bytes);
4260 if (result) {
4261 return result;
4262 }
4263
4264 result = Parse_TPM2B_DIGEST(buffer, &value->creation_hash, value_bytes);
4265 if (result) {
4266 return result;
4267 }
4268 return result;
4269 }
4270
Serialize_TPMS_NV_CERTIFY_INFO(const TPMS_NV_CERTIFY_INFO & value,std::string * buffer)4271 TPM_RC Serialize_TPMS_NV_CERTIFY_INFO(const TPMS_NV_CERTIFY_INFO& value,
4272 std::string* buffer) {
4273 TPM_RC result = TPM_RC_SUCCESS;
4274 VLOG(3) << __func__;
4275
4276 result = Serialize_TPM2B_NAME(value.index_name, buffer);
4277 if (result) {
4278 return result;
4279 }
4280
4281 result = Serialize_UINT16(value.offset, buffer);
4282 if (result) {
4283 return result;
4284 }
4285
4286 result = Serialize_TPM2B_MAX_NV_BUFFER(value.nv_contents, buffer);
4287 if (result) {
4288 return result;
4289 }
4290 return result;
4291 }
4292
Parse_TPMS_NV_CERTIFY_INFO(std::string * buffer,TPMS_NV_CERTIFY_INFO * value,std::string * value_bytes)4293 TPM_RC Parse_TPMS_NV_CERTIFY_INFO(std::string* buffer,
4294 TPMS_NV_CERTIFY_INFO* value,
4295 std::string* value_bytes) {
4296 TPM_RC result = TPM_RC_SUCCESS;
4297 VLOG(3) << __func__;
4298
4299 result = Parse_TPM2B_NAME(buffer, &value->index_name, value_bytes);
4300 if (result) {
4301 return result;
4302 }
4303
4304 result = Parse_UINT16(buffer, &value->offset, value_bytes);
4305 if (result) {
4306 return result;
4307 }
4308
4309 result = Parse_TPM2B_MAX_NV_BUFFER(buffer, &value->nv_contents, value_bytes);
4310 if (result) {
4311 return result;
4312 }
4313 return result;
4314 }
4315
Serialize_TPMU_ATTEST(const TPMU_ATTEST & value,TPMI_ST_ATTEST selector,std::string * buffer)4316 TPM_RC Serialize_TPMU_ATTEST(const TPMU_ATTEST& value,
4317 TPMI_ST_ATTEST selector,
4318 std::string* buffer) {
4319 TPM_RC result = TPM_RC_SUCCESS;
4320 VLOG(3) << __func__;
4321
4322 if (selector == TPM_ST_ATTEST_SESSION_AUDIT) {
4323 result = Serialize_TPMS_SESSION_AUDIT_INFO(value.session_audit, buffer);
4324 if (result) {
4325 return result;
4326 }
4327 }
4328
4329 if (selector == TPM_ST_ATTEST_QUOTE) {
4330 result = Serialize_TPMS_QUOTE_INFO(value.quote, buffer);
4331 if (result) {
4332 return result;
4333 }
4334 }
4335
4336 if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) {
4337 result = Serialize_TPMS_COMMAND_AUDIT_INFO(value.command_audit, buffer);
4338 if (result) {
4339 return result;
4340 }
4341 }
4342
4343 if (selector == TPM_ST_ATTEST_CERTIFY) {
4344 result = Serialize_TPMS_CERTIFY_INFO(value.certify, buffer);
4345 if (result) {
4346 return result;
4347 }
4348 }
4349
4350 if (selector == TPM_ST_ATTEST_NV) {
4351 result = Serialize_TPMS_NV_CERTIFY_INFO(value.nv, buffer);
4352 if (result) {
4353 return result;
4354 }
4355 }
4356
4357 if (selector == TPM_ST_ATTEST_TIME) {
4358 result = Serialize_TPMS_TIME_ATTEST_INFO(value.time, buffer);
4359 if (result) {
4360 return result;
4361 }
4362 }
4363
4364 if (selector == TPM_ST_ATTEST_CREATION) {
4365 result = Serialize_TPMS_CREATION_INFO(value.creation, buffer);
4366 if (result) {
4367 return result;
4368 }
4369 }
4370 return result;
4371 }
4372
Parse_TPMU_ATTEST(std::string * buffer,TPMI_ST_ATTEST selector,TPMU_ATTEST * value,std::string * value_bytes)4373 TPM_RC Parse_TPMU_ATTEST(std::string* buffer,
4374 TPMI_ST_ATTEST selector,
4375 TPMU_ATTEST* value,
4376 std::string* value_bytes) {
4377 TPM_RC result = TPM_RC_SUCCESS;
4378 VLOG(3) << __func__;
4379
4380 if (selector == TPM_ST_ATTEST_SESSION_AUDIT) {
4381 result = Parse_TPMS_SESSION_AUDIT_INFO(buffer, &value->session_audit,
4382 value_bytes);
4383 if (result) {
4384 return result;
4385 }
4386 }
4387
4388 if (selector == TPM_ST_ATTEST_QUOTE) {
4389 result = Parse_TPMS_QUOTE_INFO(buffer, &value->quote, value_bytes);
4390 if (result) {
4391 return result;
4392 }
4393 }
4394
4395 if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) {
4396 result = Parse_TPMS_COMMAND_AUDIT_INFO(buffer, &value->command_audit,
4397 value_bytes);
4398 if (result) {
4399 return result;
4400 }
4401 }
4402
4403 if (selector == TPM_ST_ATTEST_CERTIFY) {
4404 result = Parse_TPMS_CERTIFY_INFO(buffer, &value->certify, value_bytes);
4405 if (result) {
4406 return result;
4407 }
4408 }
4409
4410 if (selector == TPM_ST_ATTEST_NV) {
4411 result = Parse_TPMS_NV_CERTIFY_INFO(buffer, &value->nv, value_bytes);
4412 if (result) {
4413 return result;
4414 }
4415 }
4416
4417 if (selector == TPM_ST_ATTEST_TIME) {
4418 result = Parse_TPMS_TIME_ATTEST_INFO(buffer, &value->time, value_bytes);
4419 if (result) {
4420 return result;
4421 }
4422 }
4423
4424 if (selector == TPM_ST_ATTEST_CREATION) {
4425 result = Parse_TPMS_CREATION_INFO(buffer, &value->creation, value_bytes);
4426 if (result) {
4427 return result;
4428 }
4429 }
4430 return result;
4431 }
4432
Serialize_TPMS_ATTEST(const TPMS_ATTEST & value,std::string * buffer)4433 TPM_RC Serialize_TPMS_ATTEST(const TPMS_ATTEST& value, std::string* buffer) {
4434 TPM_RC result = TPM_RC_SUCCESS;
4435 VLOG(3) << __func__;
4436
4437 result = Serialize_TPM_GENERATED(value.magic, buffer);
4438 if (result) {
4439 return result;
4440 }
4441
4442 result = Serialize_TPMI_ST_ATTEST(value.type, buffer);
4443 if (result) {
4444 return result;
4445 }
4446
4447 result = Serialize_TPM2B_NAME(value.qualified_signer, buffer);
4448 if (result) {
4449 return result;
4450 }
4451
4452 result = Serialize_TPM2B_DATA(value.extra_data, buffer);
4453 if (result) {
4454 return result;
4455 }
4456
4457 result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer);
4458 if (result) {
4459 return result;
4460 }
4461
4462 result = Serialize_UINT64(value.firmware_version, buffer);
4463 if (result) {
4464 return result;
4465 }
4466
4467 result = Serialize_TPMU_ATTEST(value.attested, value.type, buffer);
4468 if (result) {
4469 return result;
4470 }
4471 return result;
4472 }
4473
Parse_TPMS_ATTEST(std::string * buffer,TPMS_ATTEST * value,std::string * value_bytes)4474 TPM_RC Parse_TPMS_ATTEST(std::string* buffer,
4475 TPMS_ATTEST* value,
4476 std::string* value_bytes) {
4477 TPM_RC result = TPM_RC_SUCCESS;
4478 VLOG(3) << __func__;
4479
4480 result = Parse_TPM_GENERATED(buffer, &value->magic, value_bytes);
4481 if (result) {
4482 return result;
4483 }
4484
4485 result = Parse_TPMI_ST_ATTEST(buffer, &value->type, value_bytes);
4486 if (result) {
4487 return result;
4488 }
4489
4490 result = Parse_TPM2B_NAME(buffer, &value->qualified_signer, value_bytes);
4491 if (result) {
4492 return result;
4493 }
4494
4495 result = Parse_TPM2B_DATA(buffer, &value->extra_data, value_bytes);
4496 if (result) {
4497 return result;
4498 }
4499
4500 result = Parse_TPMS_CLOCK_INFO(buffer, &value->clock_info, value_bytes);
4501 if (result) {
4502 return result;
4503 }
4504
4505 result = Parse_UINT64(buffer, &value->firmware_version, value_bytes);
4506 if (result) {
4507 return result;
4508 }
4509
4510 result =
4511 Parse_TPMU_ATTEST(buffer, value->type, &value->attested, value_bytes);
4512 if (result) {
4513 return result;
4514 }
4515 return result;
4516 }
4517
Serialize_TPM2B_ATTEST(const TPM2B_ATTEST & value,std::string * buffer)4518 TPM_RC Serialize_TPM2B_ATTEST(const TPM2B_ATTEST& value, std::string* buffer) {
4519 TPM_RC result = TPM_RC_SUCCESS;
4520 VLOG(3) << __func__;
4521
4522 result = Serialize_UINT16(value.size, buffer);
4523 if (result) {
4524 return result;
4525 }
4526
4527 if (std::size(value.attestation_data) < value.size) {
4528 return TPM_RC_INSUFFICIENT;
4529 }
4530 for (uint32_t i = 0; i < value.size; ++i) {
4531 result = Serialize_BYTE(value.attestation_data[i], buffer);
4532 if (result) {
4533 return result;
4534 }
4535 }
4536 return result;
4537 }
4538
Parse_TPM2B_ATTEST(std::string * buffer,TPM2B_ATTEST * value,std::string * value_bytes)4539 TPM_RC Parse_TPM2B_ATTEST(std::string* buffer,
4540 TPM2B_ATTEST* value,
4541 std::string* value_bytes) {
4542 TPM_RC result = TPM_RC_SUCCESS;
4543 VLOG(3) << __func__;
4544
4545 result = Parse_UINT16(buffer, &value->size, value_bytes);
4546 if (result) {
4547 return result;
4548 }
4549
4550 if (std::size(value->attestation_data) < value->size) {
4551 return TPM_RC_INSUFFICIENT;
4552 }
4553 for (uint32_t i = 0; i < value->size; ++i) {
4554 result = Parse_BYTE(buffer, &value->attestation_data[i], value_bytes);
4555 if (result) {
4556 return result;
4557 }
4558 }
4559 return result;
4560 }
4561
Make_TPM2B_ATTEST(const std::string & bytes)4562 TPM2B_ATTEST Make_TPM2B_ATTEST(const std::string& bytes) {
4563 TPM2B_ATTEST tpm2b;
4564 CHECK(bytes.size() <= sizeof(tpm2b.attestation_data));
4565 memset(&tpm2b, 0, sizeof(TPM2B_ATTEST));
4566 tpm2b.size = bytes.size();
4567 memcpy(tpm2b.attestation_data, bytes.data(), bytes.size());
4568 return tpm2b;
4569 }
4570
StringFrom_TPM2B_ATTEST(const TPM2B_ATTEST & tpm2b)4571 std::string StringFrom_TPM2B_ATTEST(const TPM2B_ATTEST& tpm2b) {
4572 CHECK(tpm2b.size <= std::size(tpm2b.attestation_data));
4573 const char* char_buffer =
4574 reinterpret_cast<const char*>(tpm2b.attestation_data);
4575 return std::string(char_buffer, tpm2b.size);
4576 }
4577
Serialize_TPMS_AUTH_COMMAND(const TPMS_AUTH_COMMAND & value,std::string * buffer)4578 TPM_RC Serialize_TPMS_AUTH_COMMAND(const TPMS_AUTH_COMMAND& value,
4579 std::string* buffer) {
4580 TPM_RC result = TPM_RC_SUCCESS;
4581 VLOG(3) << __func__;
4582
4583 result = Serialize_TPMI_SH_AUTH_SESSION(value.session_handle, buffer);
4584 if (result) {
4585 return result;
4586 }
4587
4588 result = Serialize_TPM2B_NONCE(value.nonce, buffer);
4589 if (result) {
4590 return result;
4591 }
4592
4593 result = Serialize_TPMA_SESSION(value.session_attributes, buffer);
4594 if (result) {
4595 return result;
4596 }
4597
4598 result = Serialize_TPM2B_AUTH(value.hmac, buffer);
4599 if (result) {
4600 return result;
4601 }
4602 return result;
4603 }
4604
Parse_TPMS_AUTH_COMMAND(std::string * buffer,TPMS_AUTH_COMMAND * value,std::string * value_bytes)4605 TPM_RC Parse_TPMS_AUTH_COMMAND(std::string* buffer,
4606 TPMS_AUTH_COMMAND* value,
4607 std::string* value_bytes) {
4608 TPM_RC result = TPM_RC_SUCCESS;
4609 VLOG(3) << __func__;
4610
4611 result =
4612 Parse_TPMI_SH_AUTH_SESSION(buffer, &value->session_handle, value_bytes);
4613 if (result) {
4614 return result;
4615 }
4616
4617 result = Parse_TPM2B_NONCE(buffer, &value->nonce, value_bytes);
4618 if (result) {
4619 return result;
4620 }
4621
4622 result = Parse_TPMA_SESSION(buffer, &value->session_attributes, value_bytes);
4623 if (result) {
4624 return result;
4625 }
4626
4627 result = Parse_TPM2B_AUTH(buffer, &value->hmac, value_bytes);
4628 if (result) {
4629 return result;
4630 }
4631 return result;
4632 }
4633
Serialize_TPMS_AUTH_RESPONSE(const TPMS_AUTH_RESPONSE & value,std::string * buffer)4634 TPM_RC Serialize_TPMS_AUTH_RESPONSE(const TPMS_AUTH_RESPONSE& value,
4635 std::string* buffer) {
4636 TPM_RC result = TPM_RC_SUCCESS;
4637 VLOG(3) << __func__;
4638
4639 result = Serialize_TPM2B_NONCE(value.nonce, buffer);
4640 if (result) {
4641 return result;
4642 }
4643
4644 result = Serialize_TPMA_SESSION(value.session_attributes, buffer);
4645 if (result) {
4646 return result;
4647 }
4648
4649 result = Serialize_TPM2B_AUTH(value.hmac, buffer);
4650 if (result) {
4651 return result;
4652 }
4653 return result;
4654 }
4655
Parse_TPMS_AUTH_RESPONSE(std::string * buffer,TPMS_AUTH_RESPONSE * value,std::string * value_bytes)4656 TPM_RC Parse_TPMS_AUTH_RESPONSE(std::string* buffer,
4657 TPMS_AUTH_RESPONSE* value,
4658 std::string* value_bytes) {
4659 TPM_RC result = TPM_RC_SUCCESS;
4660 VLOG(3) << __func__;
4661
4662 result = Parse_TPM2B_NONCE(buffer, &value->nonce, value_bytes);
4663 if (result) {
4664 return result;
4665 }
4666
4667 result = Parse_TPMA_SESSION(buffer, &value->session_attributes, value_bytes);
4668 if (result) {
4669 return result;
4670 }
4671
4672 result = Parse_TPM2B_AUTH(buffer, &value->hmac, value_bytes);
4673 if (result) {
4674 return result;
4675 }
4676 return result;
4677 }
4678
Serialize_TPMU_SYM_KEY_BITS(const TPMU_SYM_KEY_BITS & value,TPMI_ALG_SYM selector,std::string * buffer)4679 TPM_RC Serialize_TPMU_SYM_KEY_BITS(const TPMU_SYM_KEY_BITS& value,
4680 TPMI_ALG_SYM selector,
4681 std::string* buffer) {
4682 TPM_RC result = TPM_RC_SUCCESS;
4683 VLOG(3) << __func__;
4684
4685 if (selector == TPM_ALG_NULL) {
4686 // Do nothing.
4687 }
4688
4689 if (selector == TPM_ALG_SM4) {
4690 result = Serialize_TPMI_SM4_KEY_BITS(value.sm4, buffer);
4691 if (result) {
4692 return result;
4693 }
4694 }
4695
4696 if (selector == TPM_ALG_AES) {
4697 result = Serialize_TPMI_AES_KEY_BITS(value.aes, buffer);
4698 if (result) {
4699 return result;
4700 }
4701 }
4702
4703 if (selector == TPM_ALG_XOR) {
4704 result = Serialize_TPMI_ALG_HASH(value.xor_, buffer);
4705 if (result) {
4706 return result;
4707 }
4708 }
4709 return result;
4710 }
4711
Parse_TPMU_SYM_KEY_BITS(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_KEY_BITS * value,std::string * value_bytes)4712 TPM_RC Parse_TPMU_SYM_KEY_BITS(std::string* buffer,
4713 TPMI_ALG_SYM selector,
4714 TPMU_SYM_KEY_BITS* value,
4715 std::string* value_bytes) {
4716 TPM_RC result = TPM_RC_SUCCESS;
4717 VLOG(3) << __func__;
4718
4719 if (selector == TPM_ALG_NULL) {
4720 // Do nothing.
4721 }
4722
4723 if (selector == TPM_ALG_SM4) {
4724 result = Parse_TPMI_SM4_KEY_BITS(buffer, &value->sm4, value_bytes);
4725 if (result) {
4726 return result;
4727 }
4728 }
4729
4730 if (selector == TPM_ALG_AES) {
4731 result = Parse_TPMI_AES_KEY_BITS(buffer, &value->aes, value_bytes);
4732 if (result) {
4733 return result;
4734 }
4735 }
4736
4737 if (selector == TPM_ALG_XOR) {
4738 result = Parse_TPMI_ALG_HASH(buffer, &value->xor_, value_bytes);
4739 if (result) {
4740 return result;
4741 }
4742 }
4743 return result;
4744 }
4745
Serialize_TPMU_SYM_MODE(const TPMU_SYM_MODE & value,TPMI_ALG_SYM selector,std::string * buffer)4746 TPM_RC Serialize_TPMU_SYM_MODE(const TPMU_SYM_MODE& value,
4747 TPMI_ALG_SYM selector,
4748 std::string* buffer) {
4749 TPM_RC result = TPM_RC_SUCCESS;
4750 VLOG(3) << __func__;
4751
4752 if (selector == TPM_ALG_NULL) {
4753 // Do nothing.
4754 }
4755
4756 if (selector == TPM_ALG_SM4) {
4757 result = Serialize_TPMI_ALG_SYM_MODE(value.sm4, buffer);
4758 if (result) {
4759 return result;
4760 }
4761 }
4762
4763 if (selector == TPM_ALG_AES) {
4764 result = Serialize_TPMI_ALG_SYM_MODE(value.aes, buffer);
4765 if (result) {
4766 return result;
4767 }
4768 }
4769
4770 if (selector == TPM_ALG_XOR) {
4771 // Do nothing.
4772 }
4773 return result;
4774 }
4775
Parse_TPMU_SYM_MODE(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_MODE * value,std::string * value_bytes)4776 TPM_RC Parse_TPMU_SYM_MODE(std::string* buffer,
4777 TPMI_ALG_SYM selector,
4778 TPMU_SYM_MODE* value,
4779 std::string* value_bytes) {
4780 TPM_RC result = TPM_RC_SUCCESS;
4781 VLOG(3) << __func__;
4782
4783 if (selector == TPM_ALG_NULL) {
4784 // Do nothing.
4785 }
4786
4787 if (selector == TPM_ALG_SM4) {
4788 result = Parse_TPMI_ALG_SYM_MODE(buffer, &value->sm4, value_bytes);
4789 if (result) {
4790 return result;
4791 }
4792 }
4793
4794 if (selector == TPM_ALG_AES) {
4795 result = Parse_TPMI_ALG_SYM_MODE(buffer, &value->aes, value_bytes);
4796 if (result) {
4797 return result;
4798 }
4799 }
4800
4801 if (selector == TPM_ALG_XOR) {
4802 // Do nothing.
4803 }
4804 return result;
4805 }
4806
Serialize_TPMU_SYM_DETAILS(const TPMU_SYM_DETAILS & value,TPMI_ALG_SYM selector,std::string * buffer)4807 TPM_RC Serialize_TPMU_SYM_DETAILS(const TPMU_SYM_DETAILS& value,
4808 TPMI_ALG_SYM selector,
4809 std::string* buffer) {
4810 TPM_RC result = TPM_RC_SUCCESS;
4811 VLOG(3) << __func__;
4812 return result;
4813 }
4814
Parse_TPMU_SYM_DETAILS(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_DETAILS * value,std::string * value_bytes)4815 TPM_RC Parse_TPMU_SYM_DETAILS(std::string* buffer,
4816 TPMI_ALG_SYM selector,
4817 TPMU_SYM_DETAILS* value,
4818 std::string* value_bytes) {
4819 TPM_RC result = TPM_RC_SUCCESS;
4820 VLOG(3) << __func__;
4821 return result;
4822 }
4823
Serialize_TPMT_SYM_DEF(const TPMT_SYM_DEF & value,std::string * buffer)4824 TPM_RC Serialize_TPMT_SYM_DEF(const TPMT_SYM_DEF& value, std::string* buffer) {
4825 TPM_RC result = TPM_RC_SUCCESS;
4826 VLOG(3) << __func__;
4827
4828 result = Serialize_TPMI_ALG_SYM(value.algorithm, buffer);
4829 if (result) {
4830 return result;
4831 }
4832
4833 result = Serialize_TPMU_SYM_KEY_BITS(value.key_bits, value.algorithm, buffer);
4834 if (result) {
4835 return result;
4836 }
4837
4838 result = Serialize_TPMU_SYM_MODE(value.mode, value.algorithm, buffer);
4839 if (result) {
4840 return result;
4841 }
4842
4843 result = Serialize_TPMU_SYM_DETAILS(value.details, value.algorithm, buffer);
4844 if (result) {
4845 return result;
4846 }
4847 return result;
4848 }
4849
Parse_TPMT_SYM_DEF(std::string * buffer,TPMT_SYM_DEF * value,std::string * value_bytes)4850 TPM_RC Parse_TPMT_SYM_DEF(std::string* buffer,
4851 TPMT_SYM_DEF* value,
4852 std::string* value_bytes) {
4853 TPM_RC result = TPM_RC_SUCCESS;
4854 VLOG(3) << __func__;
4855
4856 result = Parse_TPMI_ALG_SYM(buffer, &value->algorithm, value_bytes);
4857 if (result) {
4858 return result;
4859 }
4860
4861 result = Parse_TPMU_SYM_KEY_BITS(buffer, value->algorithm, &value->key_bits,
4862 value_bytes);
4863 if (result) {
4864 return result;
4865 }
4866
4867 result =
4868 Parse_TPMU_SYM_MODE(buffer, value->algorithm, &value->mode, value_bytes);
4869 if (result) {
4870 return result;
4871 }
4872
4873 result = Parse_TPMU_SYM_DETAILS(buffer, value->algorithm, &value->details,
4874 value_bytes);
4875 if (result) {
4876 return result;
4877 }
4878 return result;
4879 }
4880
Serialize_TPMT_SYM_DEF_OBJECT(const TPMT_SYM_DEF_OBJECT & value,std::string * buffer)4881 TPM_RC Serialize_TPMT_SYM_DEF_OBJECT(const TPMT_SYM_DEF_OBJECT& value,
4882 std::string* buffer) {
4883 TPM_RC result = TPM_RC_SUCCESS;
4884 VLOG(3) << __func__;
4885
4886 result = Serialize_TPMI_ALG_SYM_OBJECT(value.algorithm, buffer);
4887 if (result) {
4888 return result;
4889 }
4890
4891 result = Serialize_TPMU_SYM_KEY_BITS(value.key_bits, value.algorithm, buffer);
4892 if (result) {
4893 return result;
4894 }
4895
4896 result = Serialize_TPMU_SYM_MODE(value.mode, value.algorithm, buffer);
4897 if (result) {
4898 return result;
4899 }
4900
4901 result = Serialize_TPMU_SYM_DETAILS(value.details, value.algorithm, buffer);
4902 if (result) {
4903 return result;
4904 }
4905 return result;
4906 }
4907
Parse_TPMT_SYM_DEF_OBJECT(std::string * buffer,TPMT_SYM_DEF_OBJECT * value,std::string * value_bytes)4908 TPM_RC Parse_TPMT_SYM_DEF_OBJECT(std::string* buffer,
4909 TPMT_SYM_DEF_OBJECT* value,
4910 std::string* value_bytes) {
4911 TPM_RC result = TPM_RC_SUCCESS;
4912 VLOG(3) << __func__;
4913
4914 result = Parse_TPMI_ALG_SYM_OBJECT(buffer, &value->algorithm, value_bytes);
4915 if (result) {
4916 return result;
4917 }
4918
4919 result = Parse_TPMU_SYM_KEY_BITS(buffer, value->algorithm, &value->key_bits,
4920 value_bytes);
4921 if (result) {
4922 return result;
4923 }
4924
4925 result =
4926 Parse_TPMU_SYM_MODE(buffer, value->algorithm, &value->mode, value_bytes);
4927 if (result) {
4928 return result;
4929 }
4930
4931 result = Parse_TPMU_SYM_DETAILS(buffer, value->algorithm, &value->details,
4932 value_bytes);
4933 if (result) {
4934 return result;
4935 }
4936 return result;
4937 }
4938
Serialize_TPM2B_SYM_KEY(const TPM2B_SYM_KEY & value,std::string * buffer)4939 TPM_RC Serialize_TPM2B_SYM_KEY(const TPM2B_SYM_KEY& value,
4940 std::string* buffer) {
4941 TPM_RC result = TPM_RC_SUCCESS;
4942 VLOG(3) << __func__;
4943
4944 result = Serialize_UINT16(value.size, buffer);
4945 if (result) {
4946 return result;
4947 }
4948
4949 if (std::size(value.buffer) < value.size) {
4950 return TPM_RC_INSUFFICIENT;
4951 }
4952 for (uint32_t i = 0; i < value.size; ++i) {
4953 result = Serialize_BYTE(value.buffer[i], buffer);
4954 if (result) {
4955 return result;
4956 }
4957 }
4958 return result;
4959 }
4960
Parse_TPM2B_SYM_KEY(std::string * buffer,TPM2B_SYM_KEY * value,std::string * value_bytes)4961 TPM_RC Parse_TPM2B_SYM_KEY(std::string* buffer,
4962 TPM2B_SYM_KEY* value,
4963 std::string* value_bytes) {
4964 TPM_RC result = TPM_RC_SUCCESS;
4965 VLOG(3) << __func__;
4966
4967 result = Parse_UINT16(buffer, &value->size, value_bytes);
4968 if (result) {
4969 return result;
4970 }
4971
4972 if (std::size(value->buffer) < value->size) {
4973 return TPM_RC_INSUFFICIENT;
4974 }
4975 for (uint32_t i = 0; i < value->size; ++i) {
4976 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
4977 if (result) {
4978 return result;
4979 }
4980 }
4981 return result;
4982 }
4983
Make_TPM2B_SYM_KEY(const std::string & bytes)4984 TPM2B_SYM_KEY Make_TPM2B_SYM_KEY(const std::string& bytes) {
4985 TPM2B_SYM_KEY tpm2b;
4986 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
4987 memset(&tpm2b, 0, sizeof(TPM2B_SYM_KEY));
4988 tpm2b.size = bytes.size();
4989 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
4990 return tpm2b;
4991 }
4992
StringFrom_TPM2B_SYM_KEY(const TPM2B_SYM_KEY & tpm2b)4993 std::string StringFrom_TPM2B_SYM_KEY(const TPM2B_SYM_KEY& tpm2b) {
4994 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
4995 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
4996 return std::string(char_buffer, tpm2b.size);
4997 }
4998
Serialize_TPMS_SYMCIPHER_PARMS(const TPMS_SYMCIPHER_PARMS & value,std::string * buffer)4999 TPM_RC Serialize_TPMS_SYMCIPHER_PARMS(const TPMS_SYMCIPHER_PARMS& value,
5000 std::string* buffer) {
5001 TPM_RC result = TPM_RC_SUCCESS;
5002 VLOG(3) << __func__;
5003
5004 result = Serialize_TPMT_SYM_DEF_OBJECT(value.sym, buffer);
5005 if (result) {
5006 return result;
5007 }
5008 return result;
5009 }
5010
Parse_TPMS_SYMCIPHER_PARMS(std::string * buffer,TPMS_SYMCIPHER_PARMS * value,std::string * value_bytes)5011 TPM_RC Parse_TPMS_SYMCIPHER_PARMS(std::string* buffer,
5012 TPMS_SYMCIPHER_PARMS* value,
5013 std::string* value_bytes) {
5014 TPM_RC result = TPM_RC_SUCCESS;
5015 VLOG(3) << __func__;
5016
5017 result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->sym, value_bytes);
5018 if (result) {
5019 return result;
5020 }
5021 return result;
5022 }
5023
Serialize_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA & value,std::string * buffer)5024 TPM_RC Serialize_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA& value,
5025 std::string* buffer) {
5026 TPM_RC result = TPM_RC_SUCCESS;
5027 VLOG(3) << __func__;
5028
5029 result = Serialize_UINT16(value.size, buffer);
5030 if (result) {
5031 return result;
5032 }
5033
5034 if (std::size(value.buffer) < value.size) {
5035 return TPM_RC_INSUFFICIENT;
5036 }
5037 for (uint32_t i = 0; i < value.size; ++i) {
5038 result = Serialize_BYTE(value.buffer[i], buffer);
5039 if (result) {
5040 return result;
5041 }
5042 }
5043 return result;
5044 }
5045
Parse_TPM2B_SENSITIVE_DATA(std::string * buffer,TPM2B_SENSITIVE_DATA * value,std::string * value_bytes)5046 TPM_RC Parse_TPM2B_SENSITIVE_DATA(std::string* buffer,
5047 TPM2B_SENSITIVE_DATA* value,
5048 std::string* value_bytes) {
5049 TPM_RC result = TPM_RC_SUCCESS;
5050 VLOG(3) << __func__;
5051
5052 result = Parse_UINT16(buffer, &value->size, value_bytes);
5053 if (result) {
5054 return result;
5055 }
5056
5057 if (std::size(value->buffer) < value->size) {
5058 return TPM_RC_INSUFFICIENT;
5059 }
5060 for (uint32_t i = 0; i < value->size; ++i) {
5061 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
5062 if (result) {
5063 return result;
5064 }
5065 }
5066 return result;
5067 }
5068
Make_TPM2B_SENSITIVE_DATA(const std::string & bytes)5069 TPM2B_SENSITIVE_DATA Make_TPM2B_SENSITIVE_DATA(const std::string& bytes) {
5070 TPM2B_SENSITIVE_DATA tpm2b;
5071 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
5072 memset(&tpm2b, 0, sizeof(TPM2B_SENSITIVE_DATA));
5073 tpm2b.size = bytes.size();
5074 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
5075 return tpm2b;
5076 }
5077
StringFrom_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA & tpm2b)5078 std::string StringFrom_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA& tpm2b) {
5079 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
5080 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
5081 return std::string(char_buffer, tpm2b.size);
5082 }
5083
Serialize_TPMS_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE & value,std::string * buffer)5084 TPM_RC Serialize_TPMS_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE& value,
5085 std::string* buffer) {
5086 TPM_RC result = TPM_RC_SUCCESS;
5087 VLOG(3) << __func__;
5088
5089 result = Serialize_TPM2B_AUTH(value.user_auth, buffer);
5090 if (result) {
5091 return result;
5092 }
5093
5094 result = Serialize_TPM2B_SENSITIVE_DATA(value.data, buffer);
5095 if (result) {
5096 return result;
5097 }
5098 return result;
5099 }
5100
Parse_TPMS_SENSITIVE_CREATE(std::string * buffer,TPMS_SENSITIVE_CREATE * value,std::string * value_bytes)5101 TPM_RC Parse_TPMS_SENSITIVE_CREATE(std::string* buffer,
5102 TPMS_SENSITIVE_CREATE* value,
5103 std::string* value_bytes) {
5104 TPM_RC result = TPM_RC_SUCCESS;
5105 VLOG(3) << __func__;
5106
5107 result = Parse_TPM2B_AUTH(buffer, &value->user_auth, value_bytes);
5108 if (result) {
5109 return result;
5110 }
5111
5112 result = Parse_TPM2B_SENSITIVE_DATA(buffer, &value->data, value_bytes);
5113 if (result) {
5114 return result;
5115 }
5116 return result;
5117 }
5118
Serialize_TPM2B_SENSITIVE_CREATE(const TPM2B_SENSITIVE_CREATE & value,std::string * buffer)5119 TPM_RC Serialize_TPM2B_SENSITIVE_CREATE(const TPM2B_SENSITIVE_CREATE& value,
5120 std::string* buffer) {
5121 TPM_RC result = TPM_RC_SUCCESS;
5122 VLOG(3) << __func__;
5123
5124 std::string field_bytes;
5125 if (value.size) {
5126 if (value.size != sizeof(TPMS_SENSITIVE_CREATE)) {
5127 return TPM_RC_SIZE;
5128 }
5129 result = Serialize_TPMS_SENSITIVE_CREATE(value.sensitive, &field_bytes);
5130 if (result) {
5131 return result;
5132 }
5133 }
5134 std::string size_bytes;
5135 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
5136 if (result) {
5137 return result;
5138 }
5139 buffer->append(size_bytes + field_bytes);
5140 return result;
5141 }
5142
Parse_TPM2B_SENSITIVE_CREATE(std::string * buffer,TPM2B_SENSITIVE_CREATE * value,std::string * value_bytes)5143 TPM_RC Parse_TPM2B_SENSITIVE_CREATE(std::string* buffer,
5144 TPM2B_SENSITIVE_CREATE* value,
5145 std::string* value_bytes) {
5146 TPM_RC result = TPM_RC_SUCCESS;
5147 VLOG(3) << __func__;
5148
5149 UINT16 parsed_size = 0;
5150 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
5151 if (result) {
5152 return result;
5153 }
5154 if (!parsed_size) {
5155 value->size = 0;
5156 } else {
5157 value->size = sizeof(TPMS_SENSITIVE_CREATE);
5158 result =
5159 Parse_TPMS_SENSITIVE_CREATE(buffer, &value->sensitive, value_bytes);
5160 if (result) {
5161 return result;
5162 }
5163 }
5164 return result;
5165 }
5166
Make_TPM2B_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE & inner)5167 TPM2B_SENSITIVE_CREATE Make_TPM2B_SENSITIVE_CREATE(
5168 const TPMS_SENSITIVE_CREATE& inner) {
5169 TPM2B_SENSITIVE_CREATE tpm2b;
5170 tpm2b.size = sizeof(TPMS_SENSITIVE_CREATE);
5171 tpm2b.sensitive = inner;
5172 return tpm2b;
5173 }
5174
Serialize_TPMS_SCHEME_XOR(const TPMS_SCHEME_XOR & value,std::string * buffer)5175 TPM_RC Serialize_TPMS_SCHEME_XOR(const TPMS_SCHEME_XOR& value,
5176 std::string* buffer) {
5177 TPM_RC result = TPM_RC_SUCCESS;
5178 VLOG(3) << __func__;
5179
5180 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5181 if (result) {
5182 return result;
5183 }
5184
5185 result = Serialize_TPMI_ALG_KDF(value.kdf, buffer);
5186 if (result) {
5187 return result;
5188 }
5189 return result;
5190 }
5191
Parse_TPMS_SCHEME_XOR(std::string * buffer,TPMS_SCHEME_XOR * value,std::string * value_bytes)5192 TPM_RC Parse_TPMS_SCHEME_XOR(std::string* buffer,
5193 TPMS_SCHEME_XOR* value,
5194 std::string* value_bytes) {
5195 TPM_RC result = TPM_RC_SUCCESS;
5196 VLOG(3) << __func__;
5197
5198 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5199 if (result) {
5200 return result;
5201 }
5202
5203 result = Parse_TPMI_ALG_KDF(buffer, &value->kdf, value_bytes);
5204 if (result) {
5205 return result;
5206 }
5207 return result;
5208 }
5209
Serialize_TPMU_SCHEME_KEYEDHASH(const TPMU_SCHEME_KEYEDHASH & value,TPMI_ALG_KEYEDHASH_SCHEME selector,std::string * buffer)5210 TPM_RC Serialize_TPMU_SCHEME_KEYEDHASH(const TPMU_SCHEME_KEYEDHASH& value,
5211 TPMI_ALG_KEYEDHASH_SCHEME selector,
5212 std::string* buffer) {
5213 TPM_RC result = TPM_RC_SUCCESS;
5214 VLOG(3) << __func__;
5215
5216 if (selector == TPM_ALG_NULL) {
5217 // Do nothing.
5218 }
5219
5220 if (selector == TPM_ALG_HMAC) {
5221 result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer);
5222 if (result) {
5223 return result;
5224 }
5225 }
5226
5227 if (selector == TPM_ALG_XOR) {
5228 result = Serialize_TPMS_SCHEME_XOR(value.xor_, buffer);
5229 if (result) {
5230 return result;
5231 }
5232 }
5233 return result;
5234 }
5235
Parse_TPMU_SCHEME_KEYEDHASH(std::string * buffer,TPMI_ALG_KEYEDHASH_SCHEME selector,TPMU_SCHEME_KEYEDHASH * value,std::string * value_bytes)5236 TPM_RC Parse_TPMU_SCHEME_KEYEDHASH(std::string* buffer,
5237 TPMI_ALG_KEYEDHASH_SCHEME selector,
5238 TPMU_SCHEME_KEYEDHASH* value,
5239 std::string* value_bytes) {
5240 TPM_RC result = TPM_RC_SUCCESS;
5241 VLOG(3) << __func__;
5242
5243 if (selector == TPM_ALG_NULL) {
5244 // Do nothing.
5245 }
5246
5247 if (selector == TPM_ALG_HMAC) {
5248 result = Parse_TPMS_SCHEME_HMAC(buffer, &value->hmac, value_bytes);
5249 if (result) {
5250 return result;
5251 }
5252 }
5253
5254 if (selector == TPM_ALG_XOR) {
5255 result = Parse_TPMS_SCHEME_XOR(buffer, &value->xor_, value_bytes);
5256 if (result) {
5257 return result;
5258 }
5259 }
5260 return result;
5261 }
5262
Serialize_TPMT_KEYEDHASH_SCHEME(const TPMT_KEYEDHASH_SCHEME & value,std::string * buffer)5263 TPM_RC Serialize_TPMT_KEYEDHASH_SCHEME(const TPMT_KEYEDHASH_SCHEME& value,
5264 std::string* buffer) {
5265 TPM_RC result = TPM_RC_SUCCESS;
5266 VLOG(3) << __func__;
5267
5268 result = Serialize_TPMI_ALG_KEYEDHASH_SCHEME(value.scheme, buffer);
5269 if (result) {
5270 return result;
5271 }
5272
5273 result = Serialize_TPMU_SCHEME_KEYEDHASH(value.details, value.scheme, buffer);
5274 if (result) {
5275 return result;
5276 }
5277 return result;
5278 }
5279
Parse_TPMT_KEYEDHASH_SCHEME(std::string * buffer,TPMT_KEYEDHASH_SCHEME * value,std::string * value_bytes)5280 TPM_RC Parse_TPMT_KEYEDHASH_SCHEME(std::string* buffer,
5281 TPMT_KEYEDHASH_SCHEME* value,
5282 std::string* value_bytes) {
5283 TPM_RC result = TPM_RC_SUCCESS;
5284 VLOG(3) << __func__;
5285
5286 result = Parse_TPMI_ALG_KEYEDHASH_SCHEME(buffer, &value->scheme, value_bytes);
5287 if (result) {
5288 return result;
5289 }
5290
5291 result = Parse_TPMU_SCHEME_KEYEDHASH(buffer, value->scheme, &value->details,
5292 value_bytes);
5293 if (result) {
5294 return result;
5295 }
5296 return result;
5297 }
5298
Serialize_TPMS_SCHEME_ECDAA(const TPMS_SCHEME_ECDAA & value,std::string * buffer)5299 TPM_RC Serialize_TPMS_SCHEME_ECDAA(const TPMS_SCHEME_ECDAA& value,
5300 std::string* buffer) {
5301 TPM_RC result = TPM_RC_SUCCESS;
5302 VLOG(3) << __func__;
5303
5304 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5305 if (result) {
5306 return result;
5307 }
5308
5309 result = Serialize_UINT16(value.count, buffer);
5310 if (result) {
5311 return result;
5312 }
5313 return result;
5314 }
5315
Parse_TPMS_SCHEME_ECDAA(std::string * buffer,TPMS_SCHEME_ECDAA * value,std::string * value_bytes)5316 TPM_RC Parse_TPMS_SCHEME_ECDAA(std::string* buffer,
5317 TPMS_SCHEME_ECDAA* value,
5318 std::string* value_bytes) {
5319 TPM_RC result = TPM_RC_SUCCESS;
5320 VLOG(3) << __func__;
5321
5322 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5323 if (result) {
5324 return result;
5325 }
5326
5327 result = Parse_UINT16(buffer, &value->count, value_bytes);
5328 if (result) {
5329 return result;
5330 }
5331 return result;
5332 }
5333
Serialize_TPMU_SIG_SCHEME(const TPMU_SIG_SCHEME & value,TPMI_ALG_SIG_SCHEME selector,std::string * buffer)5334 TPM_RC Serialize_TPMU_SIG_SCHEME(const TPMU_SIG_SCHEME& value,
5335 TPMI_ALG_SIG_SCHEME selector,
5336 std::string* buffer) {
5337 TPM_RC result = TPM_RC_SUCCESS;
5338 VLOG(3) << __func__;
5339
5340 if (selector == TPM_ALG_HMAC) {
5341 result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer);
5342 if (result) {
5343 return result;
5344 }
5345 }
5346
5347 if (selector == TPM_ALG_ECSCHNORR) {
5348 result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer);
5349 if (result) {
5350 return result;
5351 }
5352 }
5353
5354 if (selector == TPM_ALG_RSAPSS) {
5355 result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer);
5356 if (result) {
5357 return result;
5358 }
5359 }
5360
5361 if (selector == TPM_ALG_ECDAA) {
5362 result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer);
5363 if (result) {
5364 return result;
5365 }
5366 }
5367
5368 if (selector == TPM_ALG_RSASSA) {
5369 result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer);
5370 if (result) {
5371 return result;
5372 }
5373 }
5374
5375 if (selector == TPM_ALG_SM2) {
5376 result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer);
5377 if (result) {
5378 return result;
5379 }
5380 }
5381
5382 if (selector == TPM_ALG_ECDSA) {
5383 result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer);
5384 if (result) {
5385 return result;
5386 }
5387 }
5388
5389 if (selector == TPM_ALG_NULL) {
5390 // Do nothing.
5391 }
5392 return result;
5393 }
5394
Parse_TPMU_SIG_SCHEME(std::string * buffer,TPMI_ALG_SIG_SCHEME selector,TPMU_SIG_SCHEME * value,std::string * value_bytes)5395 TPM_RC Parse_TPMU_SIG_SCHEME(std::string* buffer,
5396 TPMI_ALG_SIG_SCHEME selector,
5397 TPMU_SIG_SCHEME* value,
5398 std::string* value_bytes) {
5399 TPM_RC result = TPM_RC_SUCCESS;
5400 VLOG(3) << __func__;
5401
5402 if (selector == TPM_ALG_HMAC) {
5403 result = Parse_TPMS_SCHEME_HMAC(buffer, &value->hmac, value_bytes);
5404 if (result) {
5405 return result;
5406 }
5407 }
5408
5409 if (selector == TPM_ALG_ECSCHNORR) {
5410 result =
5411 Parse_TPMS_SCHEME_ECSCHNORR(buffer, &value->ec_schnorr, value_bytes);
5412 if (result) {
5413 return result;
5414 }
5415 }
5416
5417 if (selector == TPM_ALG_RSAPSS) {
5418 result = Parse_TPMS_SCHEME_RSAPSS(buffer, &value->rsapss, value_bytes);
5419 if (result) {
5420 return result;
5421 }
5422 }
5423
5424 if (selector == TPM_ALG_ECDAA) {
5425 result = Parse_TPMS_SCHEME_ECDAA(buffer, &value->ecdaa, value_bytes);
5426 if (result) {
5427 return result;
5428 }
5429 }
5430
5431 if (selector == TPM_ALG_RSASSA) {
5432 result = Parse_TPMS_SCHEME_RSASSA(buffer, &value->rsassa, value_bytes);
5433 if (result) {
5434 return result;
5435 }
5436 }
5437
5438 if (selector == TPM_ALG_SM2) {
5439 result = Parse_TPMS_SCHEME_SM2(buffer, &value->sm2, value_bytes);
5440 if (result) {
5441 return result;
5442 }
5443 }
5444
5445 if (selector == TPM_ALG_ECDSA) {
5446 result = Parse_TPMS_SCHEME_ECDSA(buffer, &value->ecdsa, value_bytes);
5447 if (result) {
5448 return result;
5449 }
5450 }
5451
5452 if (selector == TPM_ALG_NULL) {
5453 // Do nothing.
5454 }
5455 return result;
5456 }
5457
Serialize_TPMT_SIG_SCHEME(const TPMT_SIG_SCHEME & value,std::string * buffer)5458 TPM_RC Serialize_TPMT_SIG_SCHEME(const TPMT_SIG_SCHEME& value,
5459 std::string* buffer) {
5460 TPM_RC result = TPM_RC_SUCCESS;
5461 VLOG(3) << __func__;
5462
5463 result = Serialize_TPMI_ALG_SIG_SCHEME(value.scheme, buffer);
5464 if (result) {
5465 return result;
5466 }
5467
5468 result = Serialize_TPMU_SIG_SCHEME(value.details, value.scheme, buffer);
5469 if (result) {
5470 return result;
5471 }
5472 return result;
5473 }
5474
Parse_TPMT_SIG_SCHEME(std::string * buffer,TPMT_SIG_SCHEME * value,std::string * value_bytes)5475 TPM_RC Parse_TPMT_SIG_SCHEME(std::string* buffer,
5476 TPMT_SIG_SCHEME* value,
5477 std::string* value_bytes) {
5478 TPM_RC result = TPM_RC_SUCCESS;
5479 VLOG(3) << __func__;
5480
5481 result = Parse_TPMI_ALG_SIG_SCHEME(buffer, &value->scheme, value_bytes);
5482 if (result) {
5483 return result;
5484 }
5485
5486 result = Parse_TPMU_SIG_SCHEME(buffer, value->scheme, &value->details,
5487 value_bytes);
5488 if (result) {
5489 return result;
5490 }
5491 return result;
5492 }
5493
Serialize_TPMS_SCHEME_OAEP(const TPMS_SCHEME_OAEP & value,std::string * buffer)5494 TPM_RC Serialize_TPMS_SCHEME_OAEP(const TPMS_SCHEME_OAEP& value,
5495 std::string* buffer) {
5496 TPM_RC result = TPM_RC_SUCCESS;
5497 VLOG(3) << __func__;
5498
5499 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5500 if (result) {
5501 return result;
5502 }
5503 return result;
5504 }
5505
Parse_TPMS_SCHEME_OAEP(std::string * buffer,TPMS_SCHEME_OAEP * value,std::string * value_bytes)5506 TPM_RC Parse_TPMS_SCHEME_OAEP(std::string* buffer,
5507 TPMS_SCHEME_OAEP* value,
5508 std::string* value_bytes) {
5509 TPM_RC result = TPM_RC_SUCCESS;
5510 VLOG(3) << __func__;
5511
5512 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5513 if (result) {
5514 return result;
5515 }
5516 return result;
5517 }
5518
Serialize_TPMS_SCHEME_ECDH(const TPMS_SCHEME_ECDH & value,std::string * buffer)5519 TPM_RC Serialize_TPMS_SCHEME_ECDH(const TPMS_SCHEME_ECDH& value,
5520 std::string* buffer) {
5521 TPM_RC result = TPM_RC_SUCCESS;
5522 VLOG(3) << __func__;
5523
5524 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5525 if (result) {
5526 return result;
5527 }
5528 return result;
5529 }
5530
Parse_TPMS_SCHEME_ECDH(std::string * buffer,TPMS_SCHEME_ECDH * value,std::string * value_bytes)5531 TPM_RC Parse_TPMS_SCHEME_ECDH(std::string* buffer,
5532 TPMS_SCHEME_ECDH* value,
5533 std::string* value_bytes) {
5534 TPM_RC result = TPM_RC_SUCCESS;
5535 VLOG(3) << __func__;
5536
5537 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5538 if (result) {
5539 return result;
5540 }
5541 return result;
5542 }
5543
Serialize_TPMS_SCHEME_MGF1(const TPMS_SCHEME_MGF1 & value,std::string * buffer)5544 TPM_RC Serialize_TPMS_SCHEME_MGF1(const TPMS_SCHEME_MGF1& value,
5545 std::string* buffer) {
5546 TPM_RC result = TPM_RC_SUCCESS;
5547 VLOG(3) << __func__;
5548
5549 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5550 if (result) {
5551 return result;
5552 }
5553 return result;
5554 }
5555
Parse_TPMS_SCHEME_MGF1(std::string * buffer,TPMS_SCHEME_MGF1 * value,std::string * value_bytes)5556 TPM_RC Parse_TPMS_SCHEME_MGF1(std::string* buffer,
5557 TPMS_SCHEME_MGF1* value,
5558 std::string* value_bytes) {
5559 TPM_RC result = TPM_RC_SUCCESS;
5560 VLOG(3) << __func__;
5561
5562 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5563 if (result) {
5564 return result;
5565 }
5566 return result;
5567 }
5568
Serialize_TPMS_SCHEME_KDF1_SP800_56a(const TPMS_SCHEME_KDF1_SP800_56a & value,std::string * buffer)5569 TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_56a(
5570 const TPMS_SCHEME_KDF1_SP800_56a& value, std::string* buffer) {
5571 TPM_RC result = TPM_RC_SUCCESS;
5572 VLOG(3) << __func__;
5573
5574 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5575 if (result) {
5576 return result;
5577 }
5578 return result;
5579 }
5580
Parse_TPMS_SCHEME_KDF1_SP800_56a(std::string * buffer,TPMS_SCHEME_KDF1_SP800_56a * value,std::string * value_bytes)5581 TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_56a(std::string* buffer,
5582 TPMS_SCHEME_KDF1_SP800_56a* value,
5583 std::string* value_bytes) {
5584 TPM_RC result = TPM_RC_SUCCESS;
5585 VLOG(3) << __func__;
5586
5587 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5588 if (result) {
5589 return result;
5590 }
5591 return result;
5592 }
5593
Serialize_TPMS_SCHEME_KDF2(const TPMS_SCHEME_KDF2 & value,std::string * buffer)5594 TPM_RC Serialize_TPMS_SCHEME_KDF2(const TPMS_SCHEME_KDF2& value,
5595 std::string* buffer) {
5596 TPM_RC result = TPM_RC_SUCCESS;
5597 VLOG(3) << __func__;
5598
5599 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5600 if (result) {
5601 return result;
5602 }
5603 return result;
5604 }
5605
Parse_TPMS_SCHEME_KDF2(std::string * buffer,TPMS_SCHEME_KDF2 * value,std::string * value_bytes)5606 TPM_RC Parse_TPMS_SCHEME_KDF2(std::string* buffer,
5607 TPMS_SCHEME_KDF2* value,
5608 std::string* value_bytes) {
5609 TPM_RC result = TPM_RC_SUCCESS;
5610 VLOG(3) << __func__;
5611
5612 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5613 if (result) {
5614 return result;
5615 }
5616 return result;
5617 }
5618
Serialize_TPMS_SCHEME_KDF1_SP800_108(const TPMS_SCHEME_KDF1_SP800_108 & value,std::string * buffer)5619 TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_108(
5620 const TPMS_SCHEME_KDF1_SP800_108& value, std::string* buffer) {
5621 TPM_RC result = TPM_RC_SUCCESS;
5622 VLOG(3) << __func__;
5623
5624 result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5625 if (result) {
5626 return result;
5627 }
5628 return result;
5629 }
5630
Parse_TPMS_SCHEME_KDF1_SP800_108(std::string * buffer,TPMS_SCHEME_KDF1_SP800_108 * value,std::string * value_bytes)5631 TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_108(std::string* buffer,
5632 TPMS_SCHEME_KDF1_SP800_108* value,
5633 std::string* value_bytes) {
5634 TPM_RC result = TPM_RC_SUCCESS;
5635 VLOG(3) << __func__;
5636
5637 result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5638 if (result) {
5639 return result;
5640 }
5641 return result;
5642 }
5643
Serialize_TPMU_KDF_SCHEME(const TPMU_KDF_SCHEME & value,TPMI_ALG_KDF selector,std::string * buffer)5644 TPM_RC Serialize_TPMU_KDF_SCHEME(const TPMU_KDF_SCHEME& value,
5645 TPMI_ALG_KDF selector,
5646 std::string* buffer) {
5647 TPM_RC result = TPM_RC_SUCCESS;
5648 VLOG(3) << __func__;
5649
5650 if (selector == TPM_ALG_KDF1_SP800_56a) {
5651 result = Serialize_TPMS_SCHEME_KDF1_SP800_56a(value.kdf1_sp800_56a, buffer);
5652 if (result) {
5653 return result;
5654 }
5655 }
5656
5657 if (selector == TPM_ALG_MGF1) {
5658 result = Serialize_TPMS_SCHEME_MGF1(value.mgf1, buffer);
5659 if (result) {
5660 return result;
5661 }
5662 }
5663
5664 if (selector == TPM_ALG_KDF1_SP800_108) {
5665 result = Serialize_TPMS_SCHEME_KDF1_SP800_108(value.kdf1_sp800_108, buffer);
5666 if (result) {
5667 return result;
5668 }
5669 }
5670
5671 if (selector == TPM_ALG_KDF2) {
5672 result = Serialize_TPMS_SCHEME_KDF2(value.kdf2, buffer);
5673 if (result) {
5674 return result;
5675 }
5676 }
5677
5678 if (selector == TPM_ALG_NULL) {
5679 // Do nothing.
5680 }
5681 return result;
5682 }
5683
Parse_TPMU_KDF_SCHEME(std::string * buffer,TPMI_ALG_KDF selector,TPMU_KDF_SCHEME * value,std::string * value_bytes)5684 TPM_RC Parse_TPMU_KDF_SCHEME(std::string* buffer,
5685 TPMI_ALG_KDF selector,
5686 TPMU_KDF_SCHEME* value,
5687 std::string* value_bytes) {
5688 TPM_RC result = TPM_RC_SUCCESS;
5689 VLOG(3) << __func__;
5690
5691 if (selector == TPM_ALG_KDF1_SP800_56a) {
5692 result = Parse_TPMS_SCHEME_KDF1_SP800_56a(buffer, &value->kdf1_sp800_56a,
5693 value_bytes);
5694 if (result) {
5695 return result;
5696 }
5697 }
5698
5699 if (selector == TPM_ALG_MGF1) {
5700 result = Parse_TPMS_SCHEME_MGF1(buffer, &value->mgf1, value_bytes);
5701 if (result) {
5702 return result;
5703 }
5704 }
5705
5706 if (selector == TPM_ALG_KDF1_SP800_108) {
5707 result = Parse_TPMS_SCHEME_KDF1_SP800_108(buffer, &value->kdf1_sp800_108,
5708 value_bytes);
5709 if (result) {
5710 return result;
5711 }
5712 }
5713
5714 if (selector == TPM_ALG_KDF2) {
5715 result = Parse_TPMS_SCHEME_KDF2(buffer, &value->kdf2, value_bytes);
5716 if (result) {
5717 return result;
5718 }
5719 }
5720
5721 if (selector == TPM_ALG_NULL) {
5722 // Do nothing.
5723 }
5724 return result;
5725 }
5726
Serialize_TPMT_KDF_SCHEME(const TPMT_KDF_SCHEME & value,std::string * buffer)5727 TPM_RC Serialize_TPMT_KDF_SCHEME(const TPMT_KDF_SCHEME& value,
5728 std::string* buffer) {
5729 TPM_RC result = TPM_RC_SUCCESS;
5730 VLOG(3) << __func__;
5731
5732 result = Serialize_TPMI_ALG_KDF(value.scheme, buffer);
5733 if (result) {
5734 return result;
5735 }
5736
5737 result = Serialize_TPMU_KDF_SCHEME(value.details, value.scheme, buffer);
5738 if (result) {
5739 return result;
5740 }
5741 return result;
5742 }
5743
Parse_TPMT_KDF_SCHEME(std::string * buffer,TPMT_KDF_SCHEME * value,std::string * value_bytes)5744 TPM_RC Parse_TPMT_KDF_SCHEME(std::string* buffer,
5745 TPMT_KDF_SCHEME* value,
5746 std::string* value_bytes) {
5747 TPM_RC result = TPM_RC_SUCCESS;
5748 VLOG(3) << __func__;
5749
5750 result = Parse_TPMI_ALG_KDF(buffer, &value->scheme, value_bytes);
5751 if (result) {
5752 return result;
5753 }
5754
5755 result = Parse_TPMU_KDF_SCHEME(buffer, value->scheme, &value->details,
5756 value_bytes);
5757 if (result) {
5758 return result;
5759 }
5760 return result;
5761 }
5762
Serialize_TPMU_ASYM_SCHEME(const TPMU_ASYM_SCHEME & value,TPMI_ALG_ASYM_SCHEME selector,std::string * buffer)5763 TPM_RC Serialize_TPMU_ASYM_SCHEME(const TPMU_ASYM_SCHEME& value,
5764 TPMI_ALG_ASYM_SCHEME selector,
5765 std::string* buffer) {
5766 TPM_RC result = TPM_RC_SUCCESS;
5767 VLOG(3) << __func__;
5768
5769 if (selector == TPM_ALG_RSAES) {
5770 // Do nothing.
5771 }
5772
5773 if (selector == TPM_ALG_ECSCHNORR) {
5774 result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer);
5775 if (result) {
5776 return result;
5777 }
5778 }
5779
5780 if (selector == TPM_ALG_NULL) {
5781 // Do nothing.
5782 }
5783
5784 if (selector == TPM_ALG_ECDH) {
5785 result = Serialize_TPMS_SCHEME_ECDH(value.ecdh, buffer);
5786 if (result) {
5787 return result;
5788 }
5789 }
5790
5791 if (selector == TPM_ALG_OAEP) {
5792 result = Serialize_TPMS_SCHEME_OAEP(value.oaep, buffer);
5793 if (result) {
5794 return result;
5795 }
5796 }
5797
5798 if (selector == TPM_ALG_RSAPSS) {
5799 result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer);
5800 if (result) {
5801 return result;
5802 }
5803 }
5804
5805 if (selector == TPM_ALG_ECDAA) {
5806 result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer);
5807 if (result) {
5808 return result;
5809 }
5810 }
5811
5812 if (selector == TPM_ALG_RSASSA) {
5813 result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer);
5814 if (result) {
5815 return result;
5816 }
5817 }
5818
5819 if (selector == TPM_ALG_SM2) {
5820 result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer);
5821 if (result) {
5822 return result;
5823 }
5824 }
5825
5826 if (selector == TPM_ALG_ECDSA) {
5827 result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer);
5828 if (result) {
5829 return result;
5830 }
5831 }
5832 return result;
5833 }
5834
Parse_TPMU_ASYM_SCHEME(std::string * buffer,TPMI_ALG_ASYM_SCHEME selector,TPMU_ASYM_SCHEME * value,std::string * value_bytes)5835 TPM_RC Parse_TPMU_ASYM_SCHEME(std::string* buffer,
5836 TPMI_ALG_ASYM_SCHEME selector,
5837 TPMU_ASYM_SCHEME* value,
5838 std::string* value_bytes) {
5839 TPM_RC result = TPM_RC_SUCCESS;
5840 VLOG(3) << __func__;
5841
5842 if (selector == TPM_ALG_RSAES) {
5843 // Do nothing.
5844 }
5845
5846 if (selector == TPM_ALG_ECSCHNORR) {
5847 result =
5848 Parse_TPMS_SCHEME_ECSCHNORR(buffer, &value->ec_schnorr, value_bytes);
5849 if (result) {
5850 return result;
5851 }
5852 }
5853
5854 if (selector == TPM_ALG_NULL) {
5855 // Do nothing.
5856 }
5857
5858 if (selector == TPM_ALG_ECDH) {
5859 result = Parse_TPMS_SCHEME_ECDH(buffer, &value->ecdh, value_bytes);
5860 if (result) {
5861 return result;
5862 }
5863 }
5864
5865 if (selector == TPM_ALG_OAEP) {
5866 result = Parse_TPMS_SCHEME_OAEP(buffer, &value->oaep, value_bytes);
5867 if (result) {
5868 return result;
5869 }
5870 }
5871
5872 if (selector == TPM_ALG_RSAPSS) {
5873 result = Parse_TPMS_SCHEME_RSAPSS(buffer, &value->rsapss, value_bytes);
5874 if (result) {
5875 return result;
5876 }
5877 }
5878
5879 if (selector == TPM_ALG_ECDAA) {
5880 result = Parse_TPMS_SCHEME_ECDAA(buffer, &value->ecdaa, value_bytes);
5881 if (result) {
5882 return result;
5883 }
5884 }
5885
5886 if (selector == TPM_ALG_RSASSA) {
5887 result = Parse_TPMS_SCHEME_RSASSA(buffer, &value->rsassa, value_bytes);
5888 if (result) {
5889 return result;
5890 }
5891 }
5892
5893 if (selector == TPM_ALG_SM2) {
5894 result = Parse_TPMS_SCHEME_SM2(buffer, &value->sm2, value_bytes);
5895 if (result) {
5896 return result;
5897 }
5898 }
5899
5900 if (selector == TPM_ALG_ECDSA) {
5901 result = Parse_TPMS_SCHEME_ECDSA(buffer, &value->ecdsa, value_bytes);
5902 if (result) {
5903 return result;
5904 }
5905 }
5906 return result;
5907 }
5908
Serialize_TPMT_ASYM_SCHEME(const TPMT_ASYM_SCHEME & value,std::string * buffer)5909 TPM_RC Serialize_TPMT_ASYM_SCHEME(const TPMT_ASYM_SCHEME& value,
5910 std::string* buffer) {
5911 TPM_RC result = TPM_RC_SUCCESS;
5912 VLOG(3) << __func__;
5913
5914 result = Serialize_TPMI_ALG_ASYM_SCHEME(value.scheme, buffer);
5915 if (result) {
5916 return result;
5917 }
5918
5919 result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5920 if (result) {
5921 return result;
5922 }
5923 return result;
5924 }
5925
Parse_TPMT_ASYM_SCHEME(std::string * buffer,TPMT_ASYM_SCHEME * value,std::string * value_bytes)5926 TPM_RC Parse_TPMT_ASYM_SCHEME(std::string* buffer,
5927 TPMT_ASYM_SCHEME* value,
5928 std::string* value_bytes) {
5929 TPM_RC result = TPM_RC_SUCCESS;
5930 VLOG(3) << __func__;
5931
5932 result = Parse_TPMI_ALG_ASYM_SCHEME(buffer, &value->scheme, value_bytes);
5933 if (result) {
5934 return result;
5935 }
5936
5937 result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5938 value_bytes);
5939 if (result) {
5940 return result;
5941 }
5942 return result;
5943 }
5944
Serialize_TPMT_RSA_SCHEME(const TPMT_RSA_SCHEME & value,std::string * buffer)5945 TPM_RC Serialize_TPMT_RSA_SCHEME(const TPMT_RSA_SCHEME& value,
5946 std::string* buffer) {
5947 TPM_RC result = TPM_RC_SUCCESS;
5948 VLOG(3) << __func__;
5949
5950 result = Serialize_TPMI_ALG_RSA_SCHEME(value.scheme, buffer);
5951 if (result) {
5952 return result;
5953 }
5954
5955 result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5956 if (result) {
5957 return result;
5958 }
5959 return result;
5960 }
5961
Parse_TPMT_RSA_SCHEME(std::string * buffer,TPMT_RSA_SCHEME * value,std::string * value_bytes)5962 TPM_RC Parse_TPMT_RSA_SCHEME(std::string* buffer,
5963 TPMT_RSA_SCHEME* value,
5964 std::string* value_bytes) {
5965 TPM_RC result = TPM_RC_SUCCESS;
5966 VLOG(3) << __func__;
5967
5968 result = Parse_TPMI_ALG_RSA_SCHEME(buffer, &value->scheme, value_bytes);
5969 if (result) {
5970 return result;
5971 }
5972
5973 result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5974 value_bytes);
5975 if (result) {
5976 return result;
5977 }
5978 return result;
5979 }
5980
Serialize_TPMT_RSA_DECRYPT(const TPMT_RSA_DECRYPT & value,std::string * buffer)5981 TPM_RC Serialize_TPMT_RSA_DECRYPT(const TPMT_RSA_DECRYPT& value,
5982 std::string* buffer) {
5983 TPM_RC result = TPM_RC_SUCCESS;
5984 VLOG(3) << __func__;
5985
5986 result = Serialize_TPMI_ALG_RSA_DECRYPT(value.scheme, buffer);
5987 if (result) {
5988 return result;
5989 }
5990
5991 result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5992 if (result) {
5993 return result;
5994 }
5995 return result;
5996 }
5997
Parse_TPMT_RSA_DECRYPT(std::string * buffer,TPMT_RSA_DECRYPT * value,std::string * value_bytes)5998 TPM_RC Parse_TPMT_RSA_DECRYPT(std::string* buffer,
5999 TPMT_RSA_DECRYPT* value,
6000 std::string* value_bytes) {
6001 TPM_RC result = TPM_RC_SUCCESS;
6002 VLOG(3) << __func__;
6003
6004 result = Parse_TPMI_ALG_RSA_DECRYPT(buffer, &value->scheme, value_bytes);
6005 if (result) {
6006 return result;
6007 }
6008
6009 result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
6010 value_bytes);
6011 if (result) {
6012 return result;
6013 }
6014 return result;
6015 }
6016
Serialize_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA & value,std::string * buffer)6017 TPM_RC Serialize_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA& value,
6018 std::string* buffer) {
6019 TPM_RC result = TPM_RC_SUCCESS;
6020 VLOG(3) << __func__;
6021
6022 result = Serialize_UINT16(value.size, buffer);
6023 if (result) {
6024 return result;
6025 }
6026
6027 if (std::size(value.buffer) < value.size) {
6028 return TPM_RC_INSUFFICIENT;
6029 }
6030 for (uint32_t i = 0; i < value.size; ++i) {
6031 result = Serialize_BYTE(value.buffer[i], buffer);
6032 if (result) {
6033 return result;
6034 }
6035 }
6036 return result;
6037 }
6038
Parse_TPM2B_PUBLIC_KEY_RSA(std::string * buffer,TPM2B_PUBLIC_KEY_RSA * value,std::string * value_bytes)6039 TPM_RC Parse_TPM2B_PUBLIC_KEY_RSA(std::string* buffer,
6040 TPM2B_PUBLIC_KEY_RSA* value,
6041 std::string* value_bytes) {
6042 TPM_RC result = TPM_RC_SUCCESS;
6043 VLOG(3) << __func__;
6044
6045 result = Parse_UINT16(buffer, &value->size, value_bytes);
6046 if (result) {
6047 return result;
6048 }
6049
6050 if (std::size(value->buffer) < value->size) {
6051 return TPM_RC_INSUFFICIENT;
6052 }
6053 for (uint32_t i = 0; i < value->size; ++i) {
6054 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6055 if (result) {
6056 return result;
6057 }
6058 }
6059 return result;
6060 }
6061
Make_TPM2B_PUBLIC_KEY_RSA(const std::string & bytes)6062 TPM2B_PUBLIC_KEY_RSA Make_TPM2B_PUBLIC_KEY_RSA(const std::string& bytes) {
6063 TPM2B_PUBLIC_KEY_RSA tpm2b;
6064 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6065 memset(&tpm2b, 0, sizeof(TPM2B_PUBLIC_KEY_RSA));
6066 tpm2b.size = bytes.size();
6067 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6068 return tpm2b;
6069 }
6070
StringFrom_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA & tpm2b)6071 std::string StringFrom_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA& tpm2b) {
6072 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6073 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6074 return std::string(char_buffer, tpm2b.size);
6075 }
6076
Serialize_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA & value,std::string * buffer)6077 TPM_RC Serialize_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA& value,
6078 std::string* buffer) {
6079 TPM_RC result = TPM_RC_SUCCESS;
6080 VLOG(3) << __func__;
6081
6082 result = Serialize_UINT16(value.size, buffer);
6083 if (result) {
6084 return result;
6085 }
6086
6087 if (std::size(value.buffer) < value.size) {
6088 return TPM_RC_INSUFFICIENT;
6089 }
6090 for (uint32_t i = 0; i < value.size; ++i) {
6091 result = Serialize_BYTE(value.buffer[i], buffer);
6092 if (result) {
6093 return result;
6094 }
6095 }
6096 return result;
6097 }
6098
Parse_TPM2B_PRIVATE_KEY_RSA(std::string * buffer,TPM2B_PRIVATE_KEY_RSA * value,std::string * value_bytes)6099 TPM_RC Parse_TPM2B_PRIVATE_KEY_RSA(std::string* buffer,
6100 TPM2B_PRIVATE_KEY_RSA* value,
6101 std::string* value_bytes) {
6102 TPM_RC result = TPM_RC_SUCCESS;
6103 VLOG(3) << __func__;
6104
6105 result = Parse_UINT16(buffer, &value->size, value_bytes);
6106 if (result) {
6107 return result;
6108 }
6109
6110 if (std::size(value->buffer) < value->size) {
6111 return TPM_RC_INSUFFICIENT;
6112 }
6113 for (uint32_t i = 0; i < value->size; ++i) {
6114 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6115 if (result) {
6116 return result;
6117 }
6118 }
6119 return result;
6120 }
6121
Make_TPM2B_PRIVATE_KEY_RSA(const std::string & bytes)6122 TPM2B_PRIVATE_KEY_RSA Make_TPM2B_PRIVATE_KEY_RSA(const std::string& bytes) {
6123 TPM2B_PRIVATE_KEY_RSA tpm2b;
6124 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6125 memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_KEY_RSA));
6126 tpm2b.size = bytes.size();
6127 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6128 return tpm2b;
6129 }
6130
StringFrom_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA & tpm2b)6131 std::string StringFrom_TPM2B_PRIVATE_KEY_RSA(
6132 const TPM2B_PRIVATE_KEY_RSA& tpm2b) {
6133 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6134 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6135 return std::string(char_buffer, tpm2b.size);
6136 }
6137
Serialize_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER & value,std::string * buffer)6138 TPM_RC Serialize_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER& value,
6139 std::string* buffer) {
6140 TPM_RC result = TPM_RC_SUCCESS;
6141 VLOG(3) << __func__;
6142
6143 result = Serialize_UINT16(value.size, buffer);
6144 if (result) {
6145 return result;
6146 }
6147
6148 if (std::size(value.buffer) < value.size) {
6149 return TPM_RC_INSUFFICIENT;
6150 }
6151 for (uint32_t i = 0; i < value.size; ++i) {
6152 result = Serialize_BYTE(value.buffer[i], buffer);
6153 if (result) {
6154 return result;
6155 }
6156 }
6157 return result;
6158 }
6159
Parse_TPM2B_ECC_PARAMETER(std::string * buffer,TPM2B_ECC_PARAMETER * value,std::string * value_bytes)6160 TPM_RC Parse_TPM2B_ECC_PARAMETER(std::string* buffer,
6161 TPM2B_ECC_PARAMETER* value,
6162 std::string* value_bytes) {
6163 TPM_RC result = TPM_RC_SUCCESS;
6164 VLOG(3) << __func__;
6165
6166 result = Parse_UINT16(buffer, &value->size, value_bytes);
6167 if (result) {
6168 return result;
6169 }
6170
6171 if (std::size(value->buffer) < value->size) {
6172 return TPM_RC_INSUFFICIENT;
6173 }
6174 for (uint32_t i = 0; i < value->size; ++i) {
6175 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6176 if (result) {
6177 return result;
6178 }
6179 }
6180 return result;
6181 }
6182
Make_TPM2B_ECC_PARAMETER(const std::string & bytes)6183 TPM2B_ECC_PARAMETER Make_TPM2B_ECC_PARAMETER(const std::string& bytes) {
6184 TPM2B_ECC_PARAMETER tpm2b;
6185 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6186 memset(&tpm2b, 0, sizeof(TPM2B_ECC_PARAMETER));
6187 tpm2b.size = bytes.size();
6188 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6189 return tpm2b;
6190 }
6191
StringFrom_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER & tpm2b)6192 std::string StringFrom_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER& tpm2b) {
6193 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6194 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6195 return std::string(char_buffer, tpm2b.size);
6196 }
6197
Serialize_TPMS_ECC_POINT(const TPMS_ECC_POINT & value,std::string * buffer)6198 TPM_RC Serialize_TPMS_ECC_POINT(const TPMS_ECC_POINT& value,
6199 std::string* buffer) {
6200 TPM_RC result = TPM_RC_SUCCESS;
6201 VLOG(3) << __func__;
6202
6203 result = Serialize_TPM2B_ECC_PARAMETER(value.x, buffer);
6204 if (result) {
6205 return result;
6206 }
6207
6208 result = Serialize_TPM2B_ECC_PARAMETER(value.y, buffer);
6209 if (result) {
6210 return result;
6211 }
6212 return result;
6213 }
6214
Parse_TPMS_ECC_POINT(std::string * buffer,TPMS_ECC_POINT * value,std::string * value_bytes)6215 TPM_RC Parse_TPMS_ECC_POINT(std::string* buffer,
6216 TPMS_ECC_POINT* value,
6217 std::string* value_bytes) {
6218 TPM_RC result = TPM_RC_SUCCESS;
6219 VLOG(3) << __func__;
6220
6221 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->x, value_bytes);
6222 if (result) {
6223 return result;
6224 }
6225
6226 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->y, value_bytes);
6227 if (result) {
6228 return result;
6229 }
6230 return result;
6231 }
6232
Serialize_TPM2B_ECC_POINT(const TPM2B_ECC_POINT & value,std::string * buffer)6233 TPM_RC Serialize_TPM2B_ECC_POINT(const TPM2B_ECC_POINT& value,
6234 std::string* buffer) {
6235 TPM_RC result = TPM_RC_SUCCESS;
6236 VLOG(3) << __func__;
6237
6238 std::string field_bytes;
6239 if (value.size) {
6240 if (value.size != sizeof(TPMS_ECC_POINT)) {
6241 return TPM_RC_SIZE;
6242 }
6243 result = Serialize_TPMS_ECC_POINT(value.point, &field_bytes);
6244 if (result) {
6245 return result;
6246 }
6247 }
6248 std::string size_bytes;
6249 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
6250 if (result) {
6251 return result;
6252 }
6253 buffer->append(size_bytes + field_bytes);
6254 return result;
6255 }
6256
Parse_TPM2B_ECC_POINT(std::string * buffer,TPM2B_ECC_POINT * value,std::string * value_bytes)6257 TPM_RC Parse_TPM2B_ECC_POINT(std::string* buffer,
6258 TPM2B_ECC_POINT* value,
6259 std::string* value_bytes) {
6260 TPM_RC result = TPM_RC_SUCCESS;
6261 VLOG(3) << __func__;
6262
6263 UINT16 parsed_size = 0;
6264 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
6265 if (result) {
6266 return result;
6267 }
6268 if (!parsed_size) {
6269 value->size = 0;
6270 } else {
6271 value->size = sizeof(TPMS_ECC_POINT);
6272 result = Parse_TPMS_ECC_POINT(buffer, &value->point, value_bytes);
6273 if (result) {
6274 return result;
6275 }
6276 }
6277 return result;
6278 }
6279
Make_TPM2B_ECC_POINT(const TPMS_ECC_POINT & inner)6280 TPM2B_ECC_POINT Make_TPM2B_ECC_POINT(const TPMS_ECC_POINT& inner) {
6281 TPM2B_ECC_POINT tpm2b;
6282 tpm2b.size = sizeof(TPMS_ECC_POINT);
6283 tpm2b.point = inner;
6284 return tpm2b;
6285 }
6286
Serialize_TPMT_ECC_SCHEME(const TPMT_ECC_SCHEME & value,std::string * buffer)6287 TPM_RC Serialize_TPMT_ECC_SCHEME(const TPMT_ECC_SCHEME& value,
6288 std::string* buffer) {
6289 TPM_RC result = TPM_RC_SUCCESS;
6290 VLOG(3) << __func__;
6291
6292 result = Serialize_TPMI_ALG_ECC_SCHEME(value.scheme, buffer);
6293 if (result) {
6294 return result;
6295 }
6296
6297 result = Serialize_TPMU_SIG_SCHEME(value.details, value.scheme, buffer);
6298 if (result) {
6299 return result;
6300 }
6301 return result;
6302 }
6303
Parse_TPMT_ECC_SCHEME(std::string * buffer,TPMT_ECC_SCHEME * value,std::string * value_bytes)6304 TPM_RC Parse_TPMT_ECC_SCHEME(std::string* buffer,
6305 TPMT_ECC_SCHEME* value,
6306 std::string* value_bytes) {
6307 TPM_RC result = TPM_RC_SUCCESS;
6308 VLOG(3) << __func__;
6309
6310 result = Parse_TPMI_ALG_ECC_SCHEME(buffer, &value->scheme, value_bytes);
6311 if (result) {
6312 return result;
6313 }
6314
6315 result = Parse_TPMU_SIG_SCHEME(buffer, value->scheme, &value->details,
6316 value_bytes);
6317 if (result) {
6318 return result;
6319 }
6320 return result;
6321 }
6322
Serialize_TPMS_ALGORITHM_DETAIL_ECC(const TPMS_ALGORITHM_DETAIL_ECC & value,std::string * buffer)6323 TPM_RC Serialize_TPMS_ALGORITHM_DETAIL_ECC(
6324 const TPMS_ALGORITHM_DETAIL_ECC& value, std::string* buffer) {
6325 TPM_RC result = TPM_RC_SUCCESS;
6326 VLOG(3) << __func__;
6327
6328 result = Serialize_TPM_ECC_CURVE(value.curve_id, buffer);
6329 if (result) {
6330 return result;
6331 }
6332
6333 result = Serialize_UINT16(value.key_size, buffer);
6334 if (result) {
6335 return result;
6336 }
6337
6338 result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer);
6339 if (result) {
6340 return result;
6341 }
6342
6343 result = Serialize_TPMT_ECC_SCHEME(value.sign, buffer);
6344 if (result) {
6345 return result;
6346 }
6347
6348 result = Serialize_TPM2B_ECC_PARAMETER(value.p, buffer);
6349 if (result) {
6350 return result;
6351 }
6352
6353 result = Serialize_TPM2B_ECC_PARAMETER(value.a, buffer);
6354 if (result) {
6355 return result;
6356 }
6357
6358 result = Serialize_TPM2B_ECC_PARAMETER(value.b, buffer);
6359 if (result) {
6360 return result;
6361 }
6362
6363 result = Serialize_TPM2B_ECC_PARAMETER(value.g_x, buffer);
6364 if (result) {
6365 return result;
6366 }
6367
6368 result = Serialize_TPM2B_ECC_PARAMETER(value.g_y, buffer);
6369 if (result) {
6370 return result;
6371 }
6372
6373 result = Serialize_TPM2B_ECC_PARAMETER(value.n, buffer);
6374 if (result) {
6375 return result;
6376 }
6377
6378 result = Serialize_TPM2B_ECC_PARAMETER(value.h, buffer);
6379 if (result) {
6380 return result;
6381 }
6382 return result;
6383 }
6384
Parse_TPMS_ALGORITHM_DETAIL_ECC(std::string * buffer,TPMS_ALGORITHM_DETAIL_ECC * value,std::string * value_bytes)6385 TPM_RC Parse_TPMS_ALGORITHM_DETAIL_ECC(std::string* buffer,
6386 TPMS_ALGORITHM_DETAIL_ECC* value,
6387 std::string* value_bytes) {
6388 TPM_RC result = TPM_RC_SUCCESS;
6389 VLOG(3) << __func__;
6390
6391 result = Parse_TPM_ECC_CURVE(buffer, &value->curve_id, value_bytes);
6392 if (result) {
6393 return result;
6394 }
6395
6396 result = Parse_UINT16(buffer, &value->key_size, value_bytes);
6397 if (result) {
6398 return result;
6399 }
6400
6401 result = Parse_TPMT_KDF_SCHEME(buffer, &value->kdf, value_bytes);
6402 if (result) {
6403 return result;
6404 }
6405
6406 result = Parse_TPMT_ECC_SCHEME(buffer, &value->sign, value_bytes);
6407 if (result) {
6408 return result;
6409 }
6410
6411 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->p, value_bytes);
6412 if (result) {
6413 return result;
6414 }
6415
6416 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->a, value_bytes);
6417 if (result) {
6418 return result;
6419 }
6420
6421 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->b, value_bytes);
6422 if (result) {
6423 return result;
6424 }
6425
6426 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->g_x, value_bytes);
6427 if (result) {
6428 return result;
6429 }
6430
6431 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->g_y, value_bytes);
6432 if (result) {
6433 return result;
6434 }
6435
6436 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->n, value_bytes);
6437 if (result) {
6438 return result;
6439 }
6440
6441 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->h, value_bytes);
6442 if (result) {
6443 return result;
6444 }
6445 return result;
6446 }
6447
Serialize_TPMS_SIGNATURE_RSASSA(const TPMS_SIGNATURE_RSASSA & value,std::string * buffer)6448 TPM_RC Serialize_TPMS_SIGNATURE_RSASSA(const TPMS_SIGNATURE_RSASSA& value,
6449 std::string* buffer) {
6450 TPM_RC result = TPM_RC_SUCCESS;
6451 VLOG(3) << __func__;
6452
6453 result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6454 if (result) {
6455 return result;
6456 }
6457
6458 result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer);
6459 if (result) {
6460 return result;
6461 }
6462 return result;
6463 }
6464
Parse_TPMS_SIGNATURE_RSASSA(std::string * buffer,TPMS_SIGNATURE_RSASSA * value,std::string * value_bytes)6465 TPM_RC Parse_TPMS_SIGNATURE_RSASSA(std::string* buffer,
6466 TPMS_SIGNATURE_RSASSA* value,
6467 std::string* value_bytes) {
6468 TPM_RC result = TPM_RC_SUCCESS;
6469 VLOG(3) << __func__;
6470
6471 result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6472 if (result) {
6473 return result;
6474 }
6475
6476 result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->sig, value_bytes);
6477 if (result) {
6478 return result;
6479 }
6480 return result;
6481 }
6482
Serialize_TPMS_SIGNATURE_RSAPSS(const TPMS_SIGNATURE_RSAPSS & value,std::string * buffer)6483 TPM_RC Serialize_TPMS_SIGNATURE_RSAPSS(const TPMS_SIGNATURE_RSAPSS& value,
6484 std::string* buffer) {
6485 TPM_RC result = TPM_RC_SUCCESS;
6486 VLOG(3) << __func__;
6487
6488 result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6489 if (result) {
6490 return result;
6491 }
6492
6493 result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer);
6494 if (result) {
6495 return result;
6496 }
6497 return result;
6498 }
6499
Parse_TPMS_SIGNATURE_RSAPSS(std::string * buffer,TPMS_SIGNATURE_RSAPSS * value,std::string * value_bytes)6500 TPM_RC Parse_TPMS_SIGNATURE_RSAPSS(std::string* buffer,
6501 TPMS_SIGNATURE_RSAPSS* value,
6502 std::string* value_bytes) {
6503 TPM_RC result = TPM_RC_SUCCESS;
6504 VLOG(3) << __func__;
6505
6506 result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6507 if (result) {
6508 return result;
6509 }
6510
6511 result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->sig, value_bytes);
6512 if (result) {
6513 return result;
6514 }
6515 return result;
6516 }
6517
Serialize_TPMS_SIGNATURE_ECDSA(const TPMS_SIGNATURE_ECDSA & value,std::string * buffer)6518 TPM_RC Serialize_TPMS_SIGNATURE_ECDSA(const TPMS_SIGNATURE_ECDSA& value,
6519 std::string* buffer) {
6520 TPM_RC result = TPM_RC_SUCCESS;
6521 VLOG(3) << __func__;
6522
6523 result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6524 if (result) {
6525 return result;
6526 }
6527
6528 result = Serialize_TPM2B_ECC_PARAMETER(value.signature_r, buffer);
6529 if (result) {
6530 return result;
6531 }
6532
6533 result = Serialize_TPM2B_ECC_PARAMETER(value.signature_s, buffer);
6534 if (result) {
6535 return result;
6536 }
6537 return result;
6538 }
6539
Parse_TPMS_SIGNATURE_ECDSA(std::string * buffer,TPMS_SIGNATURE_ECDSA * value,std::string * value_bytes)6540 TPM_RC Parse_TPMS_SIGNATURE_ECDSA(std::string* buffer,
6541 TPMS_SIGNATURE_ECDSA* value,
6542 std::string* value_bytes) {
6543 TPM_RC result = TPM_RC_SUCCESS;
6544 VLOG(3) << __func__;
6545
6546 result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6547 if (result) {
6548 return result;
6549 }
6550
6551 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->signature_r, value_bytes);
6552 if (result) {
6553 return result;
6554 }
6555
6556 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->signature_s, value_bytes);
6557 if (result) {
6558 return result;
6559 }
6560 return result;
6561 }
6562
Serialize_TPMU_SIGNATURE(const TPMU_SIGNATURE & value,TPMI_ALG_SIG_SCHEME selector,std::string * buffer)6563 TPM_RC Serialize_TPMU_SIGNATURE(const TPMU_SIGNATURE& value,
6564 TPMI_ALG_SIG_SCHEME selector,
6565 std::string* buffer) {
6566 TPM_RC result = TPM_RC_SUCCESS;
6567 VLOG(3) << __func__;
6568
6569 if (selector == TPM_ALG_HMAC) {
6570 result = Serialize_TPMT_HA(value.hmac, buffer);
6571 if (result) {
6572 return result;
6573 }
6574 }
6575
6576 if (selector == TPM_ALG_ECSCHNORR) {
6577 result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecschnorr, buffer);
6578 if (result) {
6579 return result;
6580 }
6581 }
6582
6583 if (selector == TPM_ALG_RSAPSS) {
6584 result = Serialize_TPMS_SIGNATURE_RSAPSS(value.rsapss, buffer);
6585 if (result) {
6586 return result;
6587 }
6588 }
6589
6590 if (selector == TPM_ALG_ECDAA) {
6591 result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdaa, buffer);
6592 if (result) {
6593 return result;
6594 }
6595 }
6596
6597 if (selector == TPM_ALG_RSASSA) {
6598 result = Serialize_TPMS_SIGNATURE_RSASSA(value.rsassa, buffer);
6599 if (result) {
6600 return result;
6601 }
6602 }
6603
6604 if (selector == TPM_ALG_SM2) {
6605 result = Serialize_TPMS_SIGNATURE_ECDSA(value.sm2, buffer);
6606 if (result) {
6607 return result;
6608 }
6609 }
6610
6611 if (selector == TPM_ALG_ECDSA) {
6612 result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdsa, buffer);
6613 if (result) {
6614 return result;
6615 }
6616 }
6617
6618 if (selector == TPM_ALG_NULL) {
6619 // Do nothing.
6620 }
6621 return result;
6622 }
6623
Parse_TPMU_SIGNATURE(std::string * buffer,TPMI_ALG_SIG_SCHEME selector,TPMU_SIGNATURE * value,std::string * value_bytes)6624 TPM_RC Parse_TPMU_SIGNATURE(std::string* buffer,
6625 TPMI_ALG_SIG_SCHEME selector,
6626 TPMU_SIGNATURE* value,
6627 std::string* value_bytes) {
6628 TPM_RC result = TPM_RC_SUCCESS;
6629 VLOG(3) << __func__;
6630
6631 if (selector == TPM_ALG_HMAC) {
6632 result = Parse_TPMT_HA(buffer, &value->hmac, value_bytes);
6633 if (result) {
6634 return result;
6635 }
6636 }
6637
6638 if (selector == TPM_ALG_ECSCHNORR) {
6639 result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecschnorr, value_bytes);
6640 if (result) {
6641 return result;
6642 }
6643 }
6644
6645 if (selector == TPM_ALG_RSAPSS) {
6646 result = Parse_TPMS_SIGNATURE_RSAPSS(buffer, &value->rsapss, value_bytes);
6647 if (result) {
6648 return result;
6649 }
6650 }
6651
6652 if (selector == TPM_ALG_ECDAA) {
6653 result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecdaa, value_bytes);
6654 if (result) {
6655 return result;
6656 }
6657 }
6658
6659 if (selector == TPM_ALG_RSASSA) {
6660 result = Parse_TPMS_SIGNATURE_RSASSA(buffer, &value->rsassa, value_bytes);
6661 if (result) {
6662 return result;
6663 }
6664 }
6665
6666 if (selector == TPM_ALG_SM2) {
6667 result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->sm2, value_bytes);
6668 if (result) {
6669 return result;
6670 }
6671 }
6672
6673 if (selector == TPM_ALG_ECDSA) {
6674 result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecdsa, value_bytes);
6675 if (result) {
6676 return result;
6677 }
6678 }
6679
6680 if (selector == TPM_ALG_NULL) {
6681 // Do nothing.
6682 }
6683 return result;
6684 }
6685
Serialize_TPMT_SIGNATURE(const TPMT_SIGNATURE & value,std::string * buffer)6686 TPM_RC Serialize_TPMT_SIGNATURE(const TPMT_SIGNATURE& value,
6687 std::string* buffer) {
6688 TPM_RC result = TPM_RC_SUCCESS;
6689 VLOG(3) << __func__;
6690
6691 result = Serialize_TPMI_ALG_SIG_SCHEME(value.sig_alg, buffer);
6692 if (result) {
6693 return result;
6694 }
6695
6696 result = Serialize_TPMU_SIGNATURE(value.signature, value.sig_alg, buffer);
6697 if (result) {
6698 return result;
6699 }
6700 return result;
6701 }
6702
Parse_TPMT_SIGNATURE(std::string * buffer,TPMT_SIGNATURE * value,std::string * value_bytes)6703 TPM_RC Parse_TPMT_SIGNATURE(std::string* buffer,
6704 TPMT_SIGNATURE* value,
6705 std::string* value_bytes) {
6706 TPM_RC result = TPM_RC_SUCCESS;
6707 VLOG(3) << __func__;
6708
6709 result = Parse_TPMI_ALG_SIG_SCHEME(buffer, &value->sig_alg, value_bytes);
6710 if (result) {
6711 return result;
6712 }
6713
6714 result = Parse_TPMU_SIGNATURE(buffer, value->sig_alg, &value->signature,
6715 value_bytes);
6716 if (result) {
6717 return result;
6718 }
6719 return result;
6720 }
6721
Serialize_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET & value,std::string * buffer)6722 TPM_RC Serialize_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET& value,
6723 std::string* buffer) {
6724 TPM_RC result = TPM_RC_SUCCESS;
6725 VLOG(3) << __func__;
6726
6727 result = Serialize_UINT16(value.size, buffer);
6728 if (result) {
6729 return result;
6730 }
6731
6732 if (std::size(value.secret) < value.size) {
6733 return TPM_RC_INSUFFICIENT;
6734 }
6735 for (uint32_t i = 0; i < value.size; ++i) {
6736 result = Serialize_BYTE(value.secret[i], buffer);
6737 if (result) {
6738 return result;
6739 }
6740 }
6741 return result;
6742 }
6743
Parse_TPM2B_ENCRYPTED_SECRET(std::string * buffer,TPM2B_ENCRYPTED_SECRET * value,std::string * value_bytes)6744 TPM_RC Parse_TPM2B_ENCRYPTED_SECRET(std::string* buffer,
6745 TPM2B_ENCRYPTED_SECRET* value,
6746 std::string* value_bytes) {
6747 TPM_RC result = TPM_RC_SUCCESS;
6748 VLOG(3) << __func__;
6749
6750 result = Parse_UINT16(buffer, &value->size, value_bytes);
6751 if (result) {
6752 return result;
6753 }
6754
6755 if (std::size(value->secret) < value->size) {
6756 return TPM_RC_INSUFFICIENT;
6757 }
6758 for (uint32_t i = 0; i < value->size; ++i) {
6759 result = Parse_BYTE(buffer, &value->secret[i], value_bytes);
6760 if (result) {
6761 return result;
6762 }
6763 }
6764 return result;
6765 }
6766
Make_TPM2B_ENCRYPTED_SECRET(const std::string & bytes)6767 TPM2B_ENCRYPTED_SECRET Make_TPM2B_ENCRYPTED_SECRET(const std::string& bytes) {
6768 TPM2B_ENCRYPTED_SECRET tpm2b;
6769 CHECK(bytes.size() <= sizeof(tpm2b.secret));
6770 memset(&tpm2b, 0, sizeof(TPM2B_ENCRYPTED_SECRET));
6771 tpm2b.size = bytes.size();
6772 memcpy(tpm2b.secret, bytes.data(), bytes.size());
6773 return tpm2b;
6774 }
6775
StringFrom_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET & tpm2b)6776 std::string StringFrom_TPM2B_ENCRYPTED_SECRET(
6777 const TPM2B_ENCRYPTED_SECRET& tpm2b) {
6778 CHECK(tpm2b.size <= std::size(tpm2b.secret));
6779 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.secret);
6780 return std::string(char_buffer, tpm2b.size);
6781 }
6782
Serialize_TPMS_KEYEDHASH_PARMS(const TPMS_KEYEDHASH_PARMS & value,std::string * buffer)6783 TPM_RC Serialize_TPMS_KEYEDHASH_PARMS(const TPMS_KEYEDHASH_PARMS& value,
6784 std::string* buffer) {
6785 TPM_RC result = TPM_RC_SUCCESS;
6786 VLOG(3) << __func__;
6787
6788 result = Serialize_TPMT_KEYEDHASH_SCHEME(value.scheme, buffer);
6789 if (result) {
6790 return result;
6791 }
6792 return result;
6793 }
6794
Parse_TPMS_KEYEDHASH_PARMS(std::string * buffer,TPMS_KEYEDHASH_PARMS * value,std::string * value_bytes)6795 TPM_RC Parse_TPMS_KEYEDHASH_PARMS(std::string* buffer,
6796 TPMS_KEYEDHASH_PARMS* value,
6797 std::string* value_bytes) {
6798 TPM_RC result = TPM_RC_SUCCESS;
6799 VLOG(3) << __func__;
6800
6801 result = Parse_TPMT_KEYEDHASH_SCHEME(buffer, &value->scheme, value_bytes);
6802 if (result) {
6803 return result;
6804 }
6805 return result;
6806 }
6807
Serialize_TPMS_ASYM_PARMS(const TPMS_ASYM_PARMS & value,std::string * buffer)6808 TPM_RC Serialize_TPMS_ASYM_PARMS(const TPMS_ASYM_PARMS& value,
6809 std::string* buffer) {
6810 TPM_RC result = TPM_RC_SUCCESS;
6811 VLOG(3) << __func__;
6812
6813 result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6814 if (result) {
6815 return result;
6816 }
6817
6818 result = Serialize_TPMT_ASYM_SCHEME(value.scheme, buffer);
6819 if (result) {
6820 return result;
6821 }
6822 return result;
6823 }
6824
Parse_TPMS_ASYM_PARMS(std::string * buffer,TPMS_ASYM_PARMS * value,std::string * value_bytes)6825 TPM_RC Parse_TPMS_ASYM_PARMS(std::string* buffer,
6826 TPMS_ASYM_PARMS* value,
6827 std::string* value_bytes) {
6828 TPM_RC result = TPM_RC_SUCCESS;
6829 VLOG(3) << __func__;
6830
6831 result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6832 if (result) {
6833 return result;
6834 }
6835
6836 result = Parse_TPMT_ASYM_SCHEME(buffer, &value->scheme, value_bytes);
6837 if (result) {
6838 return result;
6839 }
6840 return result;
6841 }
6842
Serialize_TPMS_RSA_PARMS(const TPMS_RSA_PARMS & value,std::string * buffer)6843 TPM_RC Serialize_TPMS_RSA_PARMS(const TPMS_RSA_PARMS& value,
6844 std::string* buffer) {
6845 TPM_RC result = TPM_RC_SUCCESS;
6846 VLOG(3) << __func__;
6847
6848 result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6849 if (result) {
6850 return result;
6851 }
6852
6853 result = Serialize_TPMT_RSA_SCHEME(value.scheme, buffer);
6854 if (result) {
6855 return result;
6856 }
6857
6858 result = Serialize_TPMI_RSA_KEY_BITS(value.key_bits, buffer);
6859 if (result) {
6860 return result;
6861 }
6862
6863 result = Serialize_UINT32(value.exponent, buffer);
6864 if (result) {
6865 return result;
6866 }
6867 return result;
6868 }
6869
Parse_TPMS_RSA_PARMS(std::string * buffer,TPMS_RSA_PARMS * value,std::string * value_bytes)6870 TPM_RC Parse_TPMS_RSA_PARMS(std::string* buffer,
6871 TPMS_RSA_PARMS* value,
6872 std::string* value_bytes) {
6873 TPM_RC result = TPM_RC_SUCCESS;
6874 VLOG(3) << __func__;
6875
6876 result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6877 if (result) {
6878 return result;
6879 }
6880
6881 result = Parse_TPMT_RSA_SCHEME(buffer, &value->scheme, value_bytes);
6882 if (result) {
6883 return result;
6884 }
6885
6886 result = Parse_TPMI_RSA_KEY_BITS(buffer, &value->key_bits, value_bytes);
6887 if (result) {
6888 return result;
6889 }
6890
6891 result = Parse_UINT32(buffer, &value->exponent, value_bytes);
6892 if (result) {
6893 return result;
6894 }
6895 return result;
6896 }
6897
Serialize_TPMS_ECC_PARMS(const TPMS_ECC_PARMS & value,std::string * buffer)6898 TPM_RC Serialize_TPMS_ECC_PARMS(const TPMS_ECC_PARMS& value,
6899 std::string* buffer) {
6900 TPM_RC result = TPM_RC_SUCCESS;
6901 VLOG(3) << __func__;
6902
6903 result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6904 if (result) {
6905 return result;
6906 }
6907
6908 result = Serialize_TPMT_ECC_SCHEME(value.scheme, buffer);
6909 if (result) {
6910 return result;
6911 }
6912
6913 result = Serialize_TPMI_ECC_CURVE(value.curve_id, buffer);
6914 if (result) {
6915 return result;
6916 }
6917
6918 result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer);
6919 if (result) {
6920 return result;
6921 }
6922 return result;
6923 }
6924
Parse_TPMS_ECC_PARMS(std::string * buffer,TPMS_ECC_PARMS * value,std::string * value_bytes)6925 TPM_RC Parse_TPMS_ECC_PARMS(std::string* buffer,
6926 TPMS_ECC_PARMS* value,
6927 std::string* value_bytes) {
6928 TPM_RC result = TPM_RC_SUCCESS;
6929 VLOG(3) << __func__;
6930
6931 result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6932 if (result) {
6933 return result;
6934 }
6935
6936 result = Parse_TPMT_ECC_SCHEME(buffer, &value->scheme, value_bytes);
6937 if (result) {
6938 return result;
6939 }
6940
6941 result = Parse_TPMI_ECC_CURVE(buffer, &value->curve_id, value_bytes);
6942 if (result) {
6943 return result;
6944 }
6945
6946 result = Parse_TPMT_KDF_SCHEME(buffer, &value->kdf, value_bytes);
6947 if (result) {
6948 return result;
6949 }
6950 return result;
6951 }
6952
Serialize_TPMU_PUBLIC_PARMS(const TPMU_PUBLIC_PARMS & value,TPMI_ALG_PUBLIC selector,std::string * buffer)6953 TPM_RC Serialize_TPMU_PUBLIC_PARMS(const TPMU_PUBLIC_PARMS& value,
6954 TPMI_ALG_PUBLIC selector,
6955 std::string* buffer) {
6956 TPM_RC result = TPM_RC_SUCCESS;
6957 VLOG(3) << __func__;
6958
6959 if (selector == TPM_ALG_KEYEDHASH) {
6960 result = Serialize_TPMS_KEYEDHASH_PARMS(value.keyed_hash_detail, buffer);
6961 if (result) {
6962 return result;
6963 }
6964 }
6965
6966 if (selector == TPM_ALG_RSA) {
6967 result = Serialize_TPMS_RSA_PARMS(value.rsa_detail, buffer);
6968 if (result) {
6969 return result;
6970 }
6971 }
6972
6973 if (selector == TPM_ALG_SYMCIPHER) {
6974 result = Serialize_TPMS_SYMCIPHER_PARMS(value.sym_detail, buffer);
6975 if (result) {
6976 return result;
6977 }
6978 }
6979
6980 if (selector == TPM_ALG_ECC) {
6981 result = Serialize_TPMS_ECC_PARMS(value.ecc_detail, buffer);
6982 if (result) {
6983 return result;
6984 }
6985 }
6986 return result;
6987 }
6988
Parse_TPMU_PUBLIC_PARMS(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_PUBLIC_PARMS * value,std::string * value_bytes)6989 TPM_RC Parse_TPMU_PUBLIC_PARMS(std::string* buffer,
6990 TPMI_ALG_PUBLIC selector,
6991 TPMU_PUBLIC_PARMS* value,
6992 std::string* value_bytes) {
6993 TPM_RC result = TPM_RC_SUCCESS;
6994 VLOG(3) << __func__;
6995
6996 if (selector == TPM_ALG_KEYEDHASH) {
6997 result = Parse_TPMS_KEYEDHASH_PARMS(buffer, &value->keyed_hash_detail,
6998 value_bytes);
6999 if (result) {
7000 return result;
7001 }
7002 }
7003
7004 if (selector == TPM_ALG_RSA) {
7005 result = Parse_TPMS_RSA_PARMS(buffer, &value->rsa_detail, value_bytes);
7006 if (result) {
7007 return result;
7008 }
7009 }
7010
7011 if (selector == TPM_ALG_SYMCIPHER) {
7012 result =
7013 Parse_TPMS_SYMCIPHER_PARMS(buffer, &value->sym_detail, value_bytes);
7014 if (result) {
7015 return result;
7016 }
7017 }
7018
7019 if (selector == TPM_ALG_ECC) {
7020 result = Parse_TPMS_ECC_PARMS(buffer, &value->ecc_detail, value_bytes);
7021 if (result) {
7022 return result;
7023 }
7024 }
7025 return result;
7026 }
7027
Serialize_TPMT_PUBLIC_PARMS(const TPMT_PUBLIC_PARMS & value,std::string * buffer)7028 TPM_RC Serialize_TPMT_PUBLIC_PARMS(const TPMT_PUBLIC_PARMS& value,
7029 std::string* buffer) {
7030 TPM_RC result = TPM_RC_SUCCESS;
7031 VLOG(3) << __func__;
7032
7033 result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer);
7034 if (result) {
7035 return result;
7036 }
7037
7038 result = Serialize_TPMU_PUBLIC_PARMS(value.parameters, value.type, buffer);
7039 if (result) {
7040 return result;
7041 }
7042 return result;
7043 }
7044
Parse_TPMT_PUBLIC_PARMS(std::string * buffer,TPMT_PUBLIC_PARMS * value,std::string * value_bytes)7045 TPM_RC Parse_TPMT_PUBLIC_PARMS(std::string* buffer,
7046 TPMT_PUBLIC_PARMS* value,
7047 std::string* value_bytes) {
7048 TPM_RC result = TPM_RC_SUCCESS;
7049 VLOG(3) << __func__;
7050
7051 result = Parse_TPMI_ALG_PUBLIC(buffer, &value->type, value_bytes);
7052 if (result) {
7053 return result;
7054 }
7055
7056 result = Parse_TPMU_PUBLIC_PARMS(buffer, value->type, &value->parameters,
7057 value_bytes);
7058 if (result) {
7059 return result;
7060 }
7061 return result;
7062 }
7063
Serialize_TPMU_PUBLIC_ID(const TPMU_PUBLIC_ID & value,TPMI_ALG_PUBLIC selector,std::string * buffer)7064 TPM_RC Serialize_TPMU_PUBLIC_ID(const TPMU_PUBLIC_ID& value,
7065 TPMI_ALG_PUBLIC selector,
7066 std::string* buffer) {
7067 TPM_RC result = TPM_RC_SUCCESS;
7068 VLOG(3) << __func__;
7069
7070 if (selector == TPM_ALG_KEYEDHASH) {
7071 result = Serialize_TPM2B_DIGEST(value.keyed_hash, buffer);
7072 if (result) {
7073 return result;
7074 }
7075 }
7076
7077 if (selector == TPM_ALG_RSA) {
7078 result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.rsa, buffer);
7079 if (result) {
7080 return result;
7081 }
7082 }
7083
7084 if (selector == TPM_ALG_SYMCIPHER) {
7085 result = Serialize_TPM2B_DIGEST(value.sym, buffer);
7086 if (result) {
7087 return result;
7088 }
7089 }
7090
7091 if (selector == TPM_ALG_ECC) {
7092 result = Serialize_TPMS_ECC_POINT(value.ecc, buffer);
7093 if (result) {
7094 return result;
7095 }
7096 }
7097 return result;
7098 }
7099
Parse_TPMU_PUBLIC_ID(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_PUBLIC_ID * value,std::string * value_bytes)7100 TPM_RC Parse_TPMU_PUBLIC_ID(std::string* buffer,
7101 TPMI_ALG_PUBLIC selector,
7102 TPMU_PUBLIC_ID* value,
7103 std::string* value_bytes) {
7104 TPM_RC result = TPM_RC_SUCCESS;
7105 VLOG(3) << __func__;
7106
7107 if (selector == TPM_ALG_KEYEDHASH) {
7108 result = Parse_TPM2B_DIGEST(buffer, &value->keyed_hash, value_bytes);
7109 if (result) {
7110 return result;
7111 }
7112 }
7113
7114 if (selector == TPM_ALG_RSA) {
7115 result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->rsa, value_bytes);
7116 if (result) {
7117 return result;
7118 }
7119 }
7120
7121 if (selector == TPM_ALG_SYMCIPHER) {
7122 result = Parse_TPM2B_DIGEST(buffer, &value->sym, value_bytes);
7123 if (result) {
7124 return result;
7125 }
7126 }
7127
7128 if (selector == TPM_ALG_ECC) {
7129 result = Parse_TPMS_ECC_POINT(buffer, &value->ecc, value_bytes);
7130 if (result) {
7131 return result;
7132 }
7133 }
7134 return result;
7135 }
7136
Serialize_TPMT_PUBLIC(const TPMT_PUBLIC & value,std::string * buffer)7137 TPM_RC Serialize_TPMT_PUBLIC(const TPMT_PUBLIC& value, std::string* buffer) {
7138 TPM_RC result = TPM_RC_SUCCESS;
7139 VLOG(3) << __func__;
7140
7141 result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer);
7142 if (result) {
7143 return result;
7144 }
7145
7146 result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer);
7147 if (result) {
7148 return result;
7149 }
7150
7151 result = Serialize_TPMA_OBJECT(value.object_attributes, buffer);
7152 if (result) {
7153 return result;
7154 }
7155
7156 result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer);
7157 if (result) {
7158 return result;
7159 }
7160
7161 result = Serialize_TPMU_PUBLIC_PARMS(value.parameters, value.type, buffer);
7162 if (result) {
7163 return result;
7164 }
7165
7166 result = Serialize_TPMU_PUBLIC_ID(value.unique, value.type, buffer);
7167 if (result) {
7168 return result;
7169 }
7170 return result;
7171 }
7172
Parse_TPMT_PUBLIC(std::string * buffer,TPMT_PUBLIC * value,std::string * value_bytes)7173 TPM_RC Parse_TPMT_PUBLIC(std::string* buffer,
7174 TPMT_PUBLIC* value,
7175 std::string* value_bytes) {
7176 TPM_RC result = TPM_RC_SUCCESS;
7177 VLOG(3) << __func__;
7178
7179 result = Parse_TPMI_ALG_PUBLIC(buffer, &value->type, value_bytes);
7180 if (result) {
7181 return result;
7182 }
7183
7184 result = Parse_TPMI_ALG_HASH(buffer, &value->name_alg, value_bytes);
7185 if (result) {
7186 return result;
7187 }
7188
7189 result = Parse_TPMA_OBJECT(buffer, &value->object_attributes, value_bytes);
7190 if (result) {
7191 return result;
7192 }
7193
7194 result = Parse_TPM2B_DIGEST(buffer, &value->auth_policy, value_bytes);
7195 if (result) {
7196 return result;
7197 }
7198
7199 result = Parse_TPMU_PUBLIC_PARMS(buffer, value->type, &value->parameters,
7200 value_bytes);
7201 if (result) {
7202 return result;
7203 }
7204
7205 result =
7206 Parse_TPMU_PUBLIC_ID(buffer, value->type, &value->unique, value_bytes);
7207 if (result) {
7208 return result;
7209 }
7210 return result;
7211 }
7212
Serialize_TPM2B_PUBLIC(const TPM2B_PUBLIC & value,std::string * buffer)7213 TPM_RC Serialize_TPM2B_PUBLIC(const TPM2B_PUBLIC& value, std::string* buffer) {
7214 TPM_RC result = TPM_RC_SUCCESS;
7215 VLOG(3) << __func__;
7216
7217 std::string field_bytes;
7218 if (value.size) {
7219 if (value.size != sizeof(TPMT_PUBLIC)) {
7220 return TPM_RC_SIZE;
7221 }
7222 result = Serialize_TPMT_PUBLIC(value.public_area, &field_bytes);
7223 if (result) {
7224 return result;
7225 }
7226 }
7227 std::string size_bytes;
7228 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7229 if (result) {
7230 return result;
7231 }
7232 buffer->append(size_bytes + field_bytes);
7233 return result;
7234 }
7235
Parse_TPM2B_PUBLIC(std::string * buffer,TPM2B_PUBLIC * value,std::string * value_bytes)7236 TPM_RC Parse_TPM2B_PUBLIC(std::string* buffer,
7237 TPM2B_PUBLIC* value,
7238 std::string* value_bytes) {
7239 TPM_RC result = TPM_RC_SUCCESS;
7240 VLOG(3) << __func__;
7241
7242 UINT16 parsed_size = 0;
7243 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7244 if (result) {
7245 return result;
7246 }
7247 if (!parsed_size) {
7248 value->size = 0;
7249 } else {
7250 value->size = sizeof(TPMT_PUBLIC);
7251 result = Parse_TPMT_PUBLIC(buffer, &value->public_area, value_bytes);
7252 if (result) {
7253 return result;
7254 }
7255 }
7256 return result;
7257 }
7258
Make_TPM2B_PUBLIC(const TPMT_PUBLIC & inner)7259 TPM2B_PUBLIC Make_TPM2B_PUBLIC(const TPMT_PUBLIC& inner) {
7260 TPM2B_PUBLIC tpm2b;
7261 tpm2b.size = sizeof(TPMT_PUBLIC);
7262 tpm2b.public_area = inner;
7263 return tpm2b;
7264 }
7265
Serialize_TPM2B_PRIVATE_VENDOR_SPECIFIC(const TPM2B_PRIVATE_VENDOR_SPECIFIC & value,std::string * buffer)7266 TPM_RC Serialize_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7267 const TPM2B_PRIVATE_VENDOR_SPECIFIC& value, std::string* buffer) {
7268 TPM_RC result = TPM_RC_SUCCESS;
7269 VLOG(3) << __func__;
7270
7271 result = Serialize_UINT16(value.size, buffer);
7272 if (result) {
7273 return result;
7274 }
7275
7276 if (std::size(value.buffer) < value.size) {
7277 return TPM_RC_INSUFFICIENT;
7278 }
7279 for (uint32_t i = 0; i < value.size; ++i) {
7280 result = Serialize_BYTE(value.buffer[i], buffer);
7281 if (result) {
7282 return result;
7283 }
7284 }
7285 return result;
7286 }
7287
Parse_TPM2B_PRIVATE_VENDOR_SPECIFIC(std::string * buffer,TPM2B_PRIVATE_VENDOR_SPECIFIC * value,std::string * value_bytes)7288 TPM_RC Parse_TPM2B_PRIVATE_VENDOR_SPECIFIC(std::string* buffer,
7289 TPM2B_PRIVATE_VENDOR_SPECIFIC* value,
7290 std::string* value_bytes) {
7291 TPM_RC result = TPM_RC_SUCCESS;
7292 VLOG(3) << __func__;
7293
7294 result = Parse_UINT16(buffer, &value->size, value_bytes);
7295 if (result) {
7296 return result;
7297 }
7298
7299 if (std::size(value->buffer) < value->size) {
7300 return TPM_RC_INSUFFICIENT;
7301 }
7302 for (uint32_t i = 0; i < value->size; ++i) {
7303 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7304 if (result) {
7305 return result;
7306 }
7307 }
7308 return result;
7309 }
7310
Make_TPM2B_PRIVATE_VENDOR_SPECIFIC(const std::string & bytes)7311 TPM2B_PRIVATE_VENDOR_SPECIFIC Make_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7312 const std::string& bytes) {
7313 TPM2B_PRIVATE_VENDOR_SPECIFIC tpm2b;
7314 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7315 memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_VENDOR_SPECIFIC));
7316 tpm2b.size = bytes.size();
7317 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7318 return tpm2b;
7319 }
7320
StringFrom_TPM2B_PRIVATE_VENDOR_SPECIFIC(const TPM2B_PRIVATE_VENDOR_SPECIFIC & tpm2b)7321 std::string StringFrom_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7322 const TPM2B_PRIVATE_VENDOR_SPECIFIC& tpm2b) {
7323 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7324 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7325 return std::string(char_buffer, tpm2b.size);
7326 }
7327
Serialize_TPMU_SENSITIVE_COMPOSITE(const TPMU_SENSITIVE_COMPOSITE & value,TPMI_ALG_PUBLIC selector,std::string * buffer)7328 TPM_RC Serialize_TPMU_SENSITIVE_COMPOSITE(const TPMU_SENSITIVE_COMPOSITE& value,
7329 TPMI_ALG_PUBLIC selector,
7330 std::string* buffer) {
7331 TPM_RC result = TPM_RC_SUCCESS;
7332 VLOG(3) << __func__;
7333
7334 if (selector == TPM_ALG_KEYEDHASH) {
7335 result = Serialize_TPM2B_SENSITIVE_DATA(value.bits, buffer);
7336 if (result) {
7337 return result;
7338 }
7339 }
7340
7341 if (selector == TPM_ALG_RSA) {
7342 result = Serialize_TPM2B_PRIVATE_KEY_RSA(value.rsa, buffer);
7343 if (result) {
7344 return result;
7345 }
7346 }
7347
7348 if (selector == TPM_ALG_SYMCIPHER) {
7349 result = Serialize_TPM2B_SYM_KEY(value.sym, buffer);
7350 if (result) {
7351 return result;
7352 }
7353 }
7354
7355 if (selector == TPM_ALG_ECC) {
7356 result = Serialize_TPM2B_ECC_PARAMETER(value.ecc, buffer);
7357 if (result) {
7358 return result;
7359 }
7360 }
7361 return result;
7362 }
7363
Parse_TPMU_SENSITIVE_COMPOSITE(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_SENSITIVE_COMPOSITE * value,std::string * value_bytes)7364 TPM_RC Parse_TPMU_SENSITIVE_COMPOSITE(std::string* buffer,
7365 TPMI_ALG_PUBLIC selector,
7366 TPMU_SENSITIVE_COMPOSITE* value,
7367 std::string* value_bytes) {
7368 TPM_RC result = TPM_RC_SUCCESS;
7369 VLOG(3) << __func__;
7370
7371 if (selector == TPM_ALG_KEYEDHASH) {
7372 result = Parse_TPM2B_SENSITIVE_DATA(buffer, &value->bits, value_bytes);
7373 if (result) {
7374 return result;
7375 }
7376 }
7377
7378 if (selector == TPM_ALG_RSA) {
7379 result = Parse_TPM2B_PRIVATE_KEY_RSA(buffer, &value->rsa, value_bytes);
7380 if (result) {
7381 return result;
7382 }
7383 }
7384
7385 if (selector == TPM_ALG_SYMCIPHER) {
7386 result = Parse_TPM2B_SYM_KEY(buffer, &value->sym, value_bytes);
7387 if (result) {
7388 return result;
7389 }
7390 }
7391
7392 if (selector == TPM_ALG_ECC) {
7393 result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->ecc, value_bytes);
7394 if (result) {
7395 return result;
7396 }
7397 }
7398 return result;
7399 }
7400
Serialize_TPMT_SENSITIVE(const TPMT_SENSITIVE & value,std::string * buffer)7401 TPM_RC Serialize_TPMT_SENSITIVE(const TPMT_SENSITIVE& value,
7402 std::string* buffer) {
7403 TPM_RC result = TPM_RC_SUCCESS;
7404 VLOG(3) << __func__;
7405
7406 result = Serialize_TPMI_ALG_PUBLIC(value.sensitive_type, buffer);
7407 if (result) {
7408 return result;
7409 }
7410
7411 result = Serialize_TPM2B_AUTH(value.auth_value, buffer);
7412 if (result) {
7413 return result;
7414 }
7415
7416 result = Serialize_TPM2B_DIGEST(value.seed_value, buffer);
7417 if (result) {
7418 return result;
7419 }
7420
7421 result = Serialize_TPMU_SENSITIVE_COMPOSITE(value.sensitive,
7422 value.sensitive_type, buffer);
7423 if (result) {
7424 return result;
7425 }
7426 return result;
7427 }
7428
Parse_TPMT_SENSITIVE(std::string * buffer,TPMT_SENSITIVE * value,std::string * value_bytes)7429 TPM_RC Parse_TPMT_SENSITIVE(std::string* buffer,
7430 TPMT_SENSITIVE* value,
7431 std::string* value_bytes) {
7432 TPM_RC result = TPM_RC_SUCCESS;
7433 VLOG(3) << __func__;
7434
7435 result = Parse_TPMI_ALG_PUBLIC(buffer, &value->sensitive_type, value_bytes);
7436 if (result) {
7437 return result;
7438 }
7439
7440 result = Parse_TPM2B_AUTH(buffer, &value->auth_value, value_bytes);
7441 if (result) {
7442 return result;
7443 }
7444
7445 result = Parse_TPM2B_DIGEST(buffer, &value->seed_value, value_bytes);
7446 if (result) {
7447 return result;
7448 }
7449
7450 result = Parse_TPMU_SENSITIVE_COMPOSITE(buffer, value->sensitive_type,
7451 &value->sensitive, value_bytes);
7452 if (result) {
7453 return result;
7454 }
7455 return result;
7456 }
7457
Serialize_TPM2B_SENSITIVE(const TPM2B_SENSITIVE & value,std::string * buffer)7458 TPM_RC Serialize_TPM2B_SENSITIVE(const TPM2B_SENSITIVE& value,
7459 std::string* buffer) {
7460 TPM_RC result = TPM_RC_SUCCESS;
7461 VLOG(3) << __func__;
7462
7463 std::string field_bytes;
7464 if (value.size) {
7465 if (value.size != sizeof(TPMT_SENSITIVE)) {
7466 return TPM_RC_SIZE;
7467 }
7468 result = Serialize_TPMT_SENSITIVE(value.sensitive_area, &field_bytes);
7469 if (result) {
7470 return result;
7471 }
7472 }
7473 std::string size_bytes;
7474 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7475 if (result) {
7476 return result;
7477 }
7478 buffer->append(size_bytes + field_bytes);
7479 return result;
7480 }
7481
Parse_TPM2B_SENSITIVE(std::string * buffer,TPM2B_SENSITIVE * value,std::string * value_bytes)7482 TPM_RC Parse_TPM2B_SENSITIVE(std::string* buffer,
7483 TPM2B_SENSITIVE* value,
7484 std::string* value_bytes) {
7485 TPM_RC result = TPM_RC_SUCCESS;
7486 VLOG(3) << __func__;
7487
7488 UINT16 parsed_size = 0;
7489 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7490 if (result) {
7491 return result;
7492 }
7493 if (!parsed_size) {
7494 value->size = 0;
7495 } else {
7496 value->size = sizeof(TPMT_SENSITIVE);
7497 result = Parse_TPMT_SENSITIVE(buffer, &value->sensitive_area, value_bytes);
7498 if (result) {
7499 return result;
7500 }
7501 }
7502 return result;
7503 }
7504
Make_TPM2B_SENSITIVE(const TPMT_SENSITIVE & inner)7505 TPM2B_SENSITIVE Make_TPM2B_SENSITIVE(const TPMT_SENSITIVE& inner) {
7506 TPM2B_SENSITIVE tpm2b;
7507 tpm2b.size = sizeof(TPMT_SENSITIVE);
7508 tpm2b.sensitive_area = inner;
7509 return tpm2b;
7510 }
7511
Serialize_TPM2B_PRIVATE(const TPM2B_PRIVATE & value,std::string * buffer)7512 TPM_RC Serialize_TPM2B_PRIVATE(const TPM2B_PRIVATE& value,
7513 std::string* buffer) {
7514 TPM_RC result = TPM_RC_SUCCESS;
7515 VLOG(3) << __func__;
7516
7517 result = Serialize_UINT16(value.size, buffer);
7518 if (result) {
7519 return result;
7520 }
7521
7522 if (std::size(value.buffer) < value.size) {
7523 return TPM_RC_INSUFFICIENT;
7524 }
7525 for (uint32_t i = 0; i < value.size; ++i) {
7526 result = Serialize_BYTE(value.buffer[i], buffer);
7527 if (result) {
7528 return result;
7529 }
7530 }
7531 return result;
7532 }
7533
Parse_TPM2B_PRIVATE(std::string * buffer,TPM2B_PRIVATE * value,std::string * value_bytes)7534 TPM_RC Parse_TPM2B_PRIVATE(std::string* buffer,
7535 TPM2B_PRIVATE* value,
7536 std::string* value_bytes) {
7537 TPM_RC result = TPM_RC_SUCCESS;
7538 VLOG(3) << __func__;
7539
7540 result = Parse_UINT16(buffer, &value->size, value_bytes);
7541 if (result) {
7542 return result;
7543 }
7544
7545 if (std::size(value->buffer) < value->size) {
7546 return TPM_RC_INSUFFICIENT;
7547 }
7548 for (uint32_t i = 0; i < value->size; ++i) {
7549 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7550 if (result) {
7551 return result;
7552 }
7553 }
7554 return result;
7555 }
7556
Make_TPM2B_PRIVATE(const std::string & bytes)7557 TPM2B_PRIVATE Make_TPM2B_PRIVATE(const std::string& bytes) {
7558 TPM2B_PRIVATE tpm2b;
7559 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7560 memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE));
7561 tpm2b.size = bytes.size();
7562 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7563 return tpm2b;
7564 }
7565
StringFrom_TPM2B_PRIVATE(const TPM2B_PRIVATE & tpm2b)7566 std::string StringFrom_TPM2B_PRIVATE(const TPM2B_PRIVATE& tpm2b) {
7567 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7568 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7569 return std::string(char_buffer, tpm2b.size);
7570 }
7571
Serialize_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT & value,std::string * buffer)7572 TPM_RC Serialize_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT& value,
7573 std::string* buffer) {
7574 TPM_RC result = TPM_RC_SUCCESS;
7575 VLOG(3) << __func__;
7576
7577 result = Serialize_UINT16(value.size, buffer);
7578 if (result) {
7579 return result;
7580 }
7581
7582 if (std::size(value.credential) < value.size) {
7583 return TPM_RC_INSUFFICIENT;
7584 }
7585 for (uint32_t i = 0; i < value.size; ++i) {
7586 result = Serialize_BYTE(value.credential[i], buffer);
7587 if (result) {
7588 return result;
7589 }
7590 }
7591 return result;
7592 }
7593
Parse_TPM2B_ID_OBJECT(std::string * buffer,TPM2B_ID_OBJECT * value,std::string * value_bytes)7594 TPM_RC Parse_TPM2B_ID_OBJECT(std::string* buffer,
7595 TPM2B_ID_OBJECT* value,
7596 std::string* value_bytes) {
7597 TPM_RC result = TPM_RC_SUCCESS;
7598 VLOG(3) << __func__;
7599
7600 result = Parse_UINT16(buffer, &value->size, value_bytes);
7601 if (result) {
7602 return result;
7603 }
7604
7605 if (std::size(value->credential) < value->size) {
7606 return TPM_RC_INSUFFICIENT;
7607 }
7608 for (uint32_t i = 0; i < value->size; ++i) {
7609 result = Parse_BYTE(buffer, &value->credential[i], value_bytes);
7610 if (result) {
7611 return result;
7612 }
7613 }
7614 return result;
7615 }
7616
Make_TPM2B_ID_OBJECT(const std::string & bytes)7617 TPM2B_ID_OBJECT Make_TPM2B_ID_OBJECT(const std::string& bytes) {
7618 TPM2B_ID_OBJECT tpm2b;
7619 CHECK(bytes.size() <= sizeof(tpm2b.credential));
7620 memset(&tpm2b, 0, sizeof(TPM2B_ID_OBJECT));
7621 tpm2b.size = bytes.size();
7622 memcpy(tpm2b.credential, bytes.data(), bytes.size());
7623 return tpm2b;
7624 }
7625
StringFrom_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT & tpm2b)7626 std::string StringFrom_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT& tpm2b) {
7627 CHECK(tpm2b.size <= std::size(tpm2b.credential));
7628 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.credential);
7629 return std::string(char_buffer, tpm2b.size);
7630 }
7631
Serialize_TPMS_NV_PUBLIC(const TPMS_NV_PUBLIC & value,std::string * buffer)7632 TPM_RC Serialize_TPMS_NV_PUBLIC(const TPMS_NV_PUBLIC& value,
7633 std::string* buffer) {
7634 TPM_RC result = TPM_RC_SUCCESS;
7635 VLOG(3) << __func__;
7636
7637 result = Serialize_TPMI_RH_NV_INDEX(value.nv_index, buffer);
7638 if (result) {
7639 return result;
7640 }
7641
7642 result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer);
7643 if (result) {
7644 return result;
7645 }
7646
7647 result = Serialize_TPMA_NV(value.attributes, buffer);
7648 if (result) {
7649 return result;
7650 }
7651
7652 result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer);
7653 if (result) {
7654 return result;
7655 }
7656
7657 result = Serialize_UINT16(value.data_size, buffer);
7658 if (result) {
7659 return result;
7660 }
7661 return result;
7662 }
7663
Parse_TPMS_NV_PUBLIC(std::string * buffer,TPMS_NV_PUBLIC * value,std::string * value_bytes)7664 TPM_RC Parse_TPMS_NV_PUBLIC(std::string* buffer,
7665 TPMS_NV_PUBLIC* value,
7666 std::string* value_bytes) {
7667 TPM_RC result = TPM_RC_SUCCESS;
7668 VLOG(3) << __func__;
7669
7670 result = Parse_TPMI_RH_NV_INDEX(buffer, &value->nv_index, value_bytes);
7671 if (result) {
7672 return result;
7673 }
7674
7675 result = Parse_TPMI_ALG_HASH(buffer, &value->name_alg, value_bytes);
7676 if (result) {
7677 return result;
7678 }
7679
7680 result = Parse_TPMA_NV(buffer, &value->attributes, value_bytes);
7681 if (result) {
7682 return result;
7683 }
7684
7685 result = Parse_TPM2B_DIGEST(buffer, &value->auth_policy, value_bytes);
7686 if (result) {
7687 return result;
7688 }
7689
7690 result = Parse_UINT16(buffer, &value->data_size, value_bytes);
7691 if (result) {
7692 return result;
7693 }
7694 return result;
7695 }
7696
Serialize_TPM2B_NV_PUBLIC(const TPM2B_NV_PUBLIC & value,std::string * buffer)7697 TPM_RC Serialize_TPM2B_NV_PUBLIC(const TPM2B_NV_PUBLIC& value,
7698 std::string* buffer) {
7699 TPM_RC result = TPM_RC_SUCCESS;
7700 VLOG(3) << __func__;
7701
7702 std::string field_bytes;
7703 if (value.size) {
7704 if (value.size != sizeof(TPMS_NV_PUBLIC)) {
7705 return TPM_RC_SIZE;
7706 }
7707 result = Serialize_TPMS_NV_PUBLIC(value.nv_public, &field_bytes);
7708 if (result) {
7709 return result;
7710 }
7711 }
7712 std::string size_bytes;
7713 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7714 if (result) {
7715 return result;
7716 }
7717 buffer->append(size_bytes + field_bytes);
7718 return result;
7719 }
7720
Parse_TPM2B_NV_PUBLIC(std::string * buffer,TPM2B_NV_PUBLIC * value,std::string * value_bytes)7721 TPM_RC Parse_TPM2B_NV_PUBLIC(std::string* buffer,
7722 TPM2B_NV_PUBLIC* value,
7723 std::string* value_bytes) {
7724 TPM_RC result = TPM_RC_SUCCESS;
7725 VLOG(3) << __func__;
7726
7727 UINT16 parsed_size = 0;
7728 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7729 if (result) {
7730 return result;
7731 }
7732 if (!parsed_size) {
7733 value->size = 0;
7734 } else {
7735 value->size = sizeof(TPMS_NV_PUBLIC);
7736 result = Parse_TPMS_NV_PUBLIC(buffer, &value->nv_public, value_bytes);
7737 if (result) {
7738 return result;
7739 }
7740 }
7741 return result;
7742 }
7743
Make_TPM2B_NV_PUBLIC(const TPMS_NV_PUBLIC & inner)7744 TPM2B_NV_PUBLIC Make_TPM2B_NV_PUBLIC(const TPMS_NV_PUBLIC& inner) {
7745 TPM2B_NV_PUBLIC tpm2b;
7746 tpm2b.size = sizeof(TPMS_NV_PUBLIC);
7747 tpm2b.nv_public = inner;
7748 return tpm2b;
7749 }
7750
Serialize_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE & value,std::string * buffer)7751 TPM_RC Serialize_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE& value,
7752 std::string* buffer) {
7753 TPM_RC result = TPM_RC_SUCCESS;
7754 VLOG(3) << __func__;
7755
7756 result = Serialize_UINT16(value.size, buffer);
7757 if (result) {
7758 return result;
7759 }
7760
7761 if (std::size(value.buffer) < value.size) {
7762 return TPM_RC_INSUFFICIENT;
7763 }
7764 for (uint32_t i = 0; i < value.size; ++i) {
7765 result = Serialize_BYTE(value.buffer[i], buffer);
7766 if (result) {
7767 return result;
7768 }
7769 }
7770 return result;
7771 }
7772
Parse_TPM2B_CONTEXT_SENSITIVE(std::string * buffer,TPM2B_CONTEXT_SENSITIVE * value,std::string * value_bytes)7773 TPM_RC Parse_TPM2B_CONTEXT_SENSITIVE(std::string* buffer,
7774 TPM2B_CONTEXT_SENSITIVE* value,
7775 std::string* value_bytes) {
7776 TPM_RC result = TPM_RC_SUCCESS;
7777 VLOG(3) << __func__;
7778
7779 result = Parse_UINT16(buffer, &value->size, value_bytes);
7780 if (result) {
7781 return result;
7782 }
7783
7784 if (std::size(value->buffer) < value->size) {
7785 return TPM_RC_INSUFFICIENT;
7786 }
7787 for (uint32_t i = 0; i < value->size; ++i) {
7788 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7789 if (result) {
7790 return result;
7791 }
7792 }
7793 return result;
7794 }
7795
Make_TPM2B_CONTEXT_SENSITIVE(const std::string & bytes)7796 TPM2B_CONTEXT_SENSITIVE Make_TPM2B_CONTEXT_SENSITIVE(const std::string& bytes) {
7797 TPM2B_CONTEXT_SENSITIVE tpm2b;
7798 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7799 memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_SENSITIVE));
7800 tpm2b.size = bytes.size();
7801 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7802 return tpm2b;
7803 }
7804
StringFrom_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE & tpm2b)7805 std::string StringFrom_TPM2B_CONTEXT_SENSITIVE(
7806 const TPM2B_CONTEXT_SENSITIVE& tpm2b) {
7807 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7808 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7809 return std::string(char_buffer, tpm2b.size);
7810 }
7811
Serialize_TPMS_CONTEXT_DATA(const TPMS_CONTEXT_DATA & value,std::string * buffer)7812 TPM_RC Serialize_TPMS_CONTEXT_DATA(const TPMS_CONTEXT_DATA& value,
7813 std::string* buffer) {
7814 TPM_RC result = TPM_RC_SUCCESS;
7815 VLOG(3) << __func__;
7816
7817 result = Serialize_TPM2B_DIGEST(value.integrity, buffer);
7818 if (result) {
7819 return result;
7820 }
7821
7822 result = Serialize_TPM2B_CONTEXT_SENSITIVE(value.encrypted, buffer);
7823 if (result) {
7824 return result;
7825 }
7826 return result;
7827 }
7828
Parse_TPMS_CONTEXT_DATA(std::string * buffer,TPMS_CONTEXT_DATA * value,std::string * value_bytes)7829 TPM_RC Parse_TPMS_CONTEXT_DATA(std::string* buffer,
7830 TPMS_CONTEXT_DATA* value,
7831 std::string* value_bytes) {
7832 TPM_RC result = TPM_RC_SUCCESS;
7833 VLOG(3) << __func__;
7834
7835 result = Parse_TPM2B_DIGEST(buffer, &value->integrity, value_bytes);
7836 if (result) {
7837 return result;
7838 }
7839
7840 result =
7841 Parse_TPM2B_CONTEXT_SENSITIVE(buffer, &value->encrypted, value_bytes);
7842 if (result) {
7843 return result;
7844 }
7845 return result;
7846 }
7847
Serialize_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA & value,std::string * buffer)7848 TPM_RC Serialize_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA& value,
7849 std::string* buffer) {
7850 TPM_RC result = TPM_RC_SUCCESS;
7851 VLOG(3) << __func__;
7852
7853 result = Serialize_UINT16(value.size, buffer);
7854 if (result) {
7855 return result;
7856 }
7857
7858 if (std::size(value.buffer) < value.size) {
7859 return TPM_RC_INSUFFICIENT;
7860 }
7861 for (uint32_t i = 0; i < value.size; ++i) {
7862 result = Serialize_BYTE(value.buffer[i], buffer);
7863 if (result) {
7864 return result;
7865 }
7866 }
7867 return result;
7868 }
7869
Parse_TPM2B_CONTEXT_DATA(std::string * buffer,TPM2B_CONTEXT_DATA * value,std::string * value_bytes)7870 TPM_RC Parse_TPM2B_CONTEXT_DATA(std::string* buffer,
7871 TPM2B_CONTEXT_DATA* value,
7872 std::string* value_bytes) {
7873 TPM_RC result = TPM_RC_SUCCESS;
7874 VLOG(3) << __func__;
7875
7876 result = Parse_UINT16(buffer, &value->size, value_bytes);
7877 if (result) {
7878 return result;
7879 }
7880
7881 if (std::size(value->buffer) < value->size) {
7882 return TPM_RC_INSUFFICIENT;
7883 }
7884 for (uint32_t i = 0; i < value->size; ++i) {
7885 result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7886 if (result) {
7887 return result;
7888 }
7889 }
7890 return result;
7891 }
7892
Make_TPM2B_CONTEXT_DATA(const std::string & bytes)7893 TPM2B_CONTEXT_DATA Make_TPM2B_CONTEXT_DATA(const std::string& bytes) {
7894 TPM2B_CONTEXT_DATA tpm2b;
7895 CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7896 memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_DATA));
7897 tpm2b.size = bytes.size();
7898 memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7899 return tpm2b;
7900 }
7901
StringFrom_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA & tpm2b)7902 std::string StringFrom_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA& tpm2b) {
7903 CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7904 const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7905 return std::string(char_buffer, tpm2b.size);
7906 }
7907
Serialize_TPMS_CONTEXT(const TPMS_CONTEXT & value,std::string * buffer)7908 TPM_RC Serialize_TPMS_CONTEXT(const TPMS_CONTEXT& value, std::string* buffer) {
7909 TPM_RC result = TPM_RC_SUCCESS;
7910 VLOG(3) << __func__;
7911
7912 result = Serialize_UINT64(value.sequence, buffer);
7913 if (result) {
7914 return result;
7915 }
7916
7917 result = Serialize_TPMI_DH_CONTEXT(value.saved_handle, buffer);
7918 if (result) {
7919 return result;
7920 }
7921
7922 result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
7923 if (result) {
7924 return result;
7925 }
7926
7927 result = Serialize_TPM2B_CONTEXT_DATA(value.context_blob, buffer);
7928 if (result) {
7929 return result;
7930 }
7931 return result;
7932 }
7933
Parse_TPMS_CONTEXT(std::string * buffer,TPMS_CONTEXT * value,std::string * value_bytes)7934 TPM_RC Parse_TPMS_CONTEXT(std::string* buffer,
7935 TPMS_CONTEXT* value,
7936 std::string* value_bytes) {
7937 TPM_RC result = TPM_RC_SUCCESS;
7938 VLOG(3) << __func__;
7939
7940 result = Parse_UINT64(buffer, &value->sequence, value_bytes);
7941 if (result) {
7942 return result;
7943 }
7944
7945 result = Parse_TPMI_DH_CONTEXT(buffer, &value->saved_handle, value_bytes);
7946 if (result) {
7947 return result;
7948 }
7949
7950 result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
7951 if (result) {
7952 return result;
7953 }
7954
7955 result = Parse_TPM2B_CONTEXT_DATA(buffer, &value->context_blob, value_bytes);
7956 if (result) {
7957 return result;
7958 }
7959 return result;
7960 }
7961
Serialize_TPMS_CREATION_DATA(const TPMS_CREATION_DATA & value,std::string * buffer)7962 TPM_RC Serialize_TPMS_CREATION_DATA(const TPMS_CREATION_DATA& value,
7963 std::string* buffer) {
7964 TPM_RC result = TPM_RC_SUCCESS;
7965 VLOG(3) << __func__;
7966
7967 result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer);
7968 if (result) {
7969 return result;
7970 }
7971
7972 result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer);
7973 if (result) {
7974 return result;
7975 }
7976
7977 result = Serialize_TPMA_LOCALITY(value.locality, buffer);
7978 if (result) {
7979 return result;
7980 }
7981
7982 result = Serialize_TPM_ALG_ID(value.parent_name_alg, buffer);
7983 if (result) {
7984 return result;
7985 }
7986
7987 result = Serialize_TPM2B_NAME(value.parent_name, buffer);
7988 if (result) {
7989 return result;
7990 }
7991
7992 result = Serialize_TPM2B_NAME(value.parent_qualified_name, buffer);
7993 if (result) {
7994 return result;
7995 }
7996
7997 result = Serialize_TPM2B_DATA(value.outside_info, buffer);
7998 if (result) {
7999 return result;
8000 }
8001 return result;
8002 }
8003
Parse_TPMS_CREATION_DATA(std::string * buffer,TPMS_CREATION_DATA * value,std::string * value_bytes)8004 TPM_RC Parse_TPMS_CREATION_DATA(std::string* buffer,
8005 TPMS_CREATION_DATA* value,
8006 std::string* value_bytes) {
8007 TPM_RC result = TPM_RC_SUCCESS;
8008 VLOG(3) << __func__;
8009
8010 result = Parse_TPML_PCR_SELECTION(buffer, &value->pcr_select, value_bytes);
8011 if (result) {
8012 return result;
8013 }
8014
8015 result = Parse_TPM2B_DIGEST(buffer, &value->pcr_digest, value_bytes);
8016 if (result) {
8017 return result;
8018 }
8019
8020 result = Parse_TPMA_LOCALITY(buffer, &value->locality, value_bytes);
8021 if (result) {
8022 return result;
8023 }
8024
8025 result = Parse_TPM_ALG_ID(buffer, &value->parent_name_alg, value_bytes);
8026 if (result) {
8027 return result;
8028 }
8029
8030 result = Parse_TPM2B_NAME(buffer, &value->parent_name, value_bytes);
8031 if (result) {
8032 return result;
8033 }
8034
8035 result = Parse_TPM2B_NAME(buffer, &value->parent_qualified_name, value_bytes);
8036 if (result) {
8037 return result;
8038 }
8039
8040 result = Parse_TPM2B_DATA(buffer, &value->outside_info, value_bytes);
8041 if (result) {
8042 return result;
8043 }
8044 return result;
8045 }
8046
Serialize_TPM2B_CREATION_DATA(const TPM2B_CREATION_DATA & value,std::string * buffer)8047 TPM_RC Serialize_TPM2B_CREATION_DATA(const TPM2B_CREATION_DATA& value,
8048 std::string* buffer) {
8049 TPM_RC result = TPM_RC_SUCCESS;
8050 VLOG(3) << __func__;
8051
8052 std::string field_bytes;
8053 if (value.size) {
8054 if (value.size != sizeof(TPMS_CREATION_DATA)) {
8055 return TPM_RC_SIZE;
8056 }
8057 result = Serialize_TPMS_CREATION_DATA(value.creation_data, &field_bytes);
8058 if (result) {
8059 return result;
8060 }
8061 }
8062 std::string size_bytes;
8063 result = Serialize_UINT16(field_bytes.size(), &size_bytes);
8064 if (result) {
8065 return result;
8066 }
8067 buffer->append(size_bytes + field_bytes);
8068 return result;
8069 }
8070
Parse_TPM2B_CREATION_DATA(std::string * buffer,TPM2B_CREATION_DATA * value,std::string * value_bytes)8071 TPM_RC Parse_TPM2B_CREATION_DATA(std::string* buffer,
8072 TPM2B_CREATION_DATA* value,
8073 std::string* value_bytes) {
8074 TPM_RC result = TPM_RC_SUCCESS;
8075 VLOG(3) << __func__;
8076
8077 UINT16 parsed_size = 0;
8078 result = Parse_UINT16(buffer, &parsed_size, value_bytes);
8079 if (result) {
8080 return result;
8081 }
8082 if (!parsed_size) {
8083 value->size = 0;
8084 } else {
8085 value->size = sizeof(TPMS_CREATION_DATA);
8086 result =
8087 Parse_TPMS_CREATION_DATA(buffer, &value->creation_data, value_bytes);
8088 if (result) {
8089 return result;
8090 }
8091 }
8092 return result;
8093 }
8094
Make_TPM2B_CREATION_DATA(const TPMS_CREATION_DATA & inner)8095 TPM2B_CREATION_DATA Make_TPM2B_CREATION_DATA(const TPMS_CREATION_DATA& inner) {
8096 TPM2B_CREATION_DATA tpm2b;
8097 tpm2b.size = sizeof(TPMS_CREATION_DATA);
8098 tpm2b.creation_data = inner;
8099 return tpm2b;
8100 }
8101
SerializeCommand_Startup(const TPM_SU & startup_type,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8102 TPM_RC Tpm::SerializeCommand_Startup(
8103 const TPM_SU& startup_type,
8104 std::string* serialized_command,
8105 AuthorizationDelegate* authorization_delegate) {
8106 VLOG(3) << __func__;
8107 TPM_RC rc = TPM_RC_SUCCESS;
8108 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8109 UINT32 command_size = 10; // Header size.
8110 std::string handle_section_bytes;
8111 std::string parameter_section_bytes;
8112 TPM_CC command_code = TPM_CC_Startup;
8113 bool is_command_parameter_encryption_possible = false;
8114 bool is_response_parameter_encryption_possible = false;
8115 std::string command_code_bytes;
8116 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8117 if (rc != TPM_RC_SUCCESS) {
8118 return rc;
8119 }
8120 std::string startup_type_bytes;
8121 rc = Serialize_TPM_SU(startup_type, &startup_type_bytes);
8122 if (rc != TPM_RC_SUCCESS) {
8123 return rc;
8124 }
8125 std::unique_ptr<crypto::SecureHash> hash(
8126 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8127 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8128 hash->Update(startup_type_bytes.data(), startup_type_bytes.size());
8129 parameter_section_bytes += startup_type_bytes;
8130 command_size += startup_type_bytes.size();
8131 std::string command_hash(32, 0);
8132 hash->Finish(std::data(command_hash), command_hash.size());
8133 std::string authorization_section_bytes;
8134 std::string authorization_size_bytes;
8135 if (authorization_delegate) {
8136 if (!authorization_delegate->GetCommandAuthorization(
8137 command_hash, is_command_parameter_encryption_possible,
8138 is_response_parameter_encryption_possible,
8139 &authorization_section_bytes)) {
8140 return TRUNKS_RC_AUTHORIZATION_FAILED;
8141 }
8142 if (!authorization_section_bytes.empty()) {
8143 tag = TPM_ST_SESSIONS;
8144 std::string tmp;
8145 rc = Serialize_UINT32(authorization_section_bytes.size(),
8146 &authorization_size_bytes);
8147 if (rc != TPM_RC_SUCCESS) {
8148 return rc;
8149 }
8150 command_size +=
8151 authorization_size_bytes.size() + authorization_section_bytes.size();
8152 }
8153 }
8154 std::string tag_bytes;
8155 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8156 if (rc != TPM_RC_SUCCESS) {
8157 return rc;
8158 }
8159 std::string command_size_bytes;
8160 rc = Serialize_UINT32(command_size, &command_size_bytes);
8161 if (rc != TPM_RC_SUCCESS) {
8162 return rc;
8163 }
8164 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8165 handle_section_bytes + authorization_size_bytes +
8166 authorization_section_bytes + parameter_section_bytes;
8167 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8168 VLOG(2) << "Command: "
8169 << base::HexEncode(serialized_command->data(),
8170 serialized_command->size());
8171 return TPM_RC_SUCCESS;
8172 }
8173
ParseResponse_Startup(const std::string & response,AuthorizationDelegate * authorization_delegate)8174 TPM_RC Tpm::ParseResponse_Startup(
8175 const std::string& response,
8176 AuthorizationDelegate* authorization_delegate) {
8177 VLOG(3) << __func__;
8178 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8179 TPM_RC rc = TPM_RC_SUCCESS;
8180 std::string buffer(response);
8181 TPM_ST tag;
8182 std::string tag_bytes;
8183 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8184 if (rc != TPM_RC_SUCCESS) {
8185 return rc;
8186 }
8187 UINT32 response_size;
8188 std::string response_size_bytes;
8189 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8190 if (rc != TPM_RC_SUCCESS) {
8191 return rc;
8192 }
8193 TPM_RC response_code;
8194 std::string response_code_bytes;
8195 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8196 if (rc != TPM_RC_SUCCESS) {
8197 return rc;
8198 }
8199 if (response_size != response.size()) {
8200 return TPM_RC_SIZE;
8201 }
8202 if (response_code != TPM_RC_SUCCESS) {
8203 return response_code;
8204 }
8205 TPM_CC command_code = TPM_CC_Startup;
8206 std::string command_code_bytes;
8207 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8208 if (rc != TPM_RC_SUCCESS) {
8209 return rc;
8210 }
8211 std::string authorization_section_bytes;
8212 if (tag == TPM_ST_SESSIONS) {
8213 UINT32 parameter_section_size = buffer.size();
8214 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
8215 if (rc != TPM_RC_SUCCESS) {
8216 return rc;
8217 }
8218 if (parameter_section_size > buffer.size()) {
8219 return TPM_RC_INSUFFICIENT;
8220 }
8221 authorization_section_bytes = buffer.substr(parameter_section_size);
8222 // Keep the parameter section in |buffer|.
8223 buffer.erase(parameter_section_size);
8224 }
8225 std::unique_ptr<crypto::SecureHash> hash(
8226 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8227 hash->Update(response_code_bytes.data(), response_code_bytes.size());
8228 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8229 hash->Update(buffer.data(), buffer.size());
8230 std::string response_hash(32, 0);
8231 hash->Finish(std::data(response_hash), response_hash.size());
8232 if (tag == TPM_ST_SESSIONS) {
8233 if (!authorization_delegate)
8234 return TRUNKS_RC_AUTHORIZATION_FAILED;
8235 if (!authorization_delegate->CheckResponseAuthorization(
8236 response_hash, authorization_section_bytes)) {
8237 return TRUNKS_RC_AUTHORIZATION_FAILED;
8238 }
8239 }
8240 return TPM_RC_SUCCESS;
8241 }
8242
StartupErrorCallback(Tpm::StartupResponse callback,TPM_RC response_code)8243 void StartupErrorCallback(Tpm::StartupResponse callback, TPM_RC response_code) {
8244 VLOG(1) << __func__;
8245 std::move(callback).Run(response_code);
8246 }
8247
StartupResponseParser(Tpm::StartupResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8248 void StartupResponseParser(Tpm::StartupResponse callback,
8249 AuthorizationDelegate* authorization_delegate,
8250 const std::string& response) {
8251 VLOG(1) << __func__;
8252 TPM_RC rc = Tpm::ParseResponse_Startup(response, authorization_delegate);
8253 if (rc != TPM_RC_SUCCESS) {
8254 base::OnceCallback<void(TPM_RC)> error_reporter =
8255 base::BindOnce(StartupErrorCallback, std::move(callback));
8256 std::move(error_reporter).Run(rc);
8257 return;
8258 }
8259 std::move(callback).Run(rc);
8260 }
8261
Startup(const TPM_SU & startup_type,AuthorizationDelegate * authorization_delegate,StartupResponse callback)8262 void Tpm::Startup(const TPM_SU& startup_type,
8263 AuthorizationDelegate* authorization_delegate,
8264 StartupResponse callback) {
8265 VLOG(1) << __func__;
8266 std::string command;
8267 TPM_RC rc =
8268 SerializeCommand_Startup(startup_type, &command, authorization_delegate);
8269 if (rc != TPM_RC_SUCCESS) {
8270 base::OnceCallback<void(TPM_RC)> error_reporter =
8271 base::BindOnce(StartupErrorCallback, std::move(callback));
8272 std::move(error_reporter).Run(rc);
8273 return;
8274 }
8275 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8276 StartupResponseParser, std::move(callback), authorization_delegate);
8277 transceiver_->SendCommand(command, std::move(parser));
8278 }
8279
StartupSync(const TPM_SU & startup_type,AuthorizationDelegate * authorization_delegate)8280 TPM_RC Tpm::StartupSync(const TPM_SU& startup_type,
8281 AuthorizationDelegate* authorization_delegate) {
8282 VLOG(1) << __func__;
8283 std::string command;
8284 TPM_RC rc =
8285 SerializeCommand_Startup(startup_type, &command, authorization_delegate);
8286 if (rc != TPM_RC_SUCCESS) {
8287 return rc;
8288 }
8289 std::string response = transceiver_->SendCommandAndWait(command);
8290 rc = ParseResponse_Startup(response, authorization_delegate);
8291 return rc;
8292 }
8293
SerializeCommand_Shutdown(const TPM_SU & shutdown_type,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8294 TPM_RC Tpm::SerializeCommand_Shutdown(
8295 const TPM_SU& shutdown_type,
8296 std::string* serialized_command,
8297 AuthorizationDelegate* authorization_delegate) {
8298 VLOG(3) << __func__;
8299 TPM_RC rc = TPM_RC_SUCCESS;
8300 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8301 UINT32 command_size = 10; // Header size.
8302 std::string handle_section_bytes;
8303 std::string parameter_section_bytes;
8304 TPM_CC command_code = TPM_CC_Shutdown;
8305 bool is_command_parameter_encryption_possible = false;
8306 bool is_response_parameter_encryption_possible = false;
8307 std::string command_code_bytes;
8308 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8309 if (rc != TPM_RC_SUCCESS) {
8310 return rc;
8311 }
8312 std::string shutdown_type_bytes;
8313 rc = Serialize_TPM_SU(shutdown_type, &shutdown_type_bytes);
8314 if (rc != TPM_RC_SUCCESS) {
8315 return rc;
8316 }
8317 std::unique_ptr<crypto::SecureHash> hash(
8318 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8319 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8320 hash->Update(shutdown_type_bytes.data(), shutdown_type_bytes.size());
8321 parameter_section_bytes += shutdown_type_bytes;
8322 command_size += shutdown_type_bytes.size();
8323 std::string command_hash(32, 0);
8324 hash->Finish(std::data(command_hash), command_hash.size());
8325 std::string authorization_section_bytes;
8326 std::string authorization_size_bytes;
8327 if (authorization_delegate) {
8328 if (!authorization_delegate->GetCommandAuthorization(
8329 command_hash, is_command_parameter_encryption_possible,
8330 is_response_parameter_encryption_possible,
8331 &authorization_section_bytes)) {
8332 return TRUNKS_RC_AUTHORIZATION_FAILED;
8333 }
8334 if (!authorization_section_bytes.empty()) {
8335 tag = TPM_ST_SESSIONS;
8336 std::string tmp;
8337 rc = Serialize_UINT32(authorization_section_bytes.size(),
8338 &authorization_size_bytes);
8339 if (rc != TPM_RC_SUCCESS) {
8340 return rc;
8341 }
8342 command_size +=
8343 authorization_size_bytes.size() + authorization_section_bytes.size();
8344 }
8345 }
8346 std::string tag_bytes;
8347 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8348 if (rc != TPM_RC_SUCCESS) {
8349 return rc;
8350 }
8351 std::string command_size_bytes;
8352 rc = Serialize_UINT32(command_size, &command_size_bytes);
8353 if (rc != TPM_RC_SUCCESS) {
8354 return rc;
8355 }
8356 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8357 handle_section_bytes + authorization_size_bytes +
8358 authorization_section_bytes + parameter_section_bytes;
8359 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8360 VLOG(2) << "Command: "
8361 << base::HexEncode(serialized_command->data(),
8362 serialized_command->size());
8363 return TPM_RC_SUCCESS;
8364 }
8365
ParseResponse_Shutdown(const std::string & response,AuthorizationDelegate * authorization_delegate)8366 TPM_RC Tpm::ParseResponse_Shutdown(
8367 const std::string& response,
8368 AuthorizationDelegate* authorization_delegate) {
8369 VLOG(3) << __func__;
8370 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8371 TPM_RC rc = TPM_RC_SUCCESS;
8372 std::string buffer(response);
8373 TPM_ST tag;
8374 std::string tag_bytes;
8375 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8376 if (rc != TPM_RC_SUCCESS) {
8377 return rc;
8378 }
8379 UINT32 response_size;
8380 std::string response_size_bytes;
8381 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8382 if (rc != TPM_RC_SUCCESS) {
8383 return rc;
8384 }
8385 TPM_RC response_code;
8386 std::string response_code_bytes;
8387 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8388 if (rc != TPM_RC_SUCCESS) {
8389 return rc;
8390 }
8391 if (response_size != response.size()) {
8392 return TPM_RC_SIZE;
8393 }
8394 if (response_code != TPM_RC_SUCCESS) {
8395 return response_code;
8396 }
8397 TPM_CC command_code = TPM_CC_Shutdown;
8398 std::string command_code_bytes;
8399 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8400 if (rc != TPM_RC_SUCCESS) {
8401 return rc;
8402 }
8403 std::string authorization_section_bytes;
8404 if (tag == TPM_ST_SESSIONS) {
8405 UINT32 parameter_section_size = buffer.size();
8406 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
8407 if (rc != TPM_RC_SUCCESS) {
8408 return rc;
8409 }
8410 if (parameter_section_size > buffer.size()) {
8411 return TPM_RC_INSUFFICIENT;
8412 }
8413 authorization_section_bytes = buffer.substr(parameter_section_size);
8414 // Keep the parameter section in |buffer|.
8415 buffer.erase(parameter_section_size);
8416 }
8417 std::unique_ptr<crypto::SecureHash> hash(
8418 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8419 hash->Update(response_code_bytes.data(), response_code_bytes.size());
8420 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8421 hash->Update(buffer.data(), buffer.size());
8422 std::string response_hash(32, 0);
8423 hash->Finish(std::data(response_hash), response_hash.size());
8424 if (tag == TPM_ST_SESSIONS) {
8425 if (!authorization_delegate)
8426 return TRUNKS_RC_AUTHORIZATION_FAILED;
8427 if (!authorization_delegate->CheckResponseAuthorization(
8428 response_hash, authorization_section_bytes)) {
8429 return TRUNKS_RC_AUTHORIZATION_FAILED;
8430 }
8431 }
8432 return TPM_RC_SUCCESS;
8433 }
8434
ShutdownErrorCallback(Tpm::ShutdownResponse callback,TPM_RC response_code)8435 void ShutdownErrorCallback(Tpm::ShutdownResponse callback,
8436 TPM_RC response_code) {
8437 VLOG(1) << __func__;
8438 std::move(callback).Run(response_code);
8439 }
8440
ShutdownResponseParser(Tpm::ShutdownResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8441 void ShutdownResponseParser(Tpm::ShutdownResponse callback,
8442 AuthorizationDelegate* authorization_delegate,
8443 const std::string& response) {
8444 VLOG(1) << __func__;
8445 TPM_RC rc = Tpm::ParseResponse_Shutdown(response, authorization_delegate);
8446 if (rc != TPM_RC_SUCCESS) {
8447 base::OnceCallback<void(TPM_RC)> error_reporter =
8448 base::BindOnce(ShutdownErrorCallback, std::move(callback));
8449 std::move(error_reporter).Run(rc);
8450 return;
8451 }
8452 std::move(callback).Run(rc);
8453 }
8454
Shutdown(const TPM_SU & shutdown_type,AuthorizationDelegate * authorization_delegate,ShutdownResponse callback)8455 void Tpm::Shutdown(const TPM_SU& shutdown_type,
8456 AuthorizationDelegate* authorization_delegate,
8457 ShutdownResponse callback) {
8458 VLOG(1) << __func__;
8459 std::string command;
8460 TPM_RC rc = SerializeCommand_Shutdown(shutdown_type, &command,
8461 authorization_delegate);
8462 if (rc != TPM_RC_SUCCESS) {
8463 base::OnceCallback<void(TPM_RC)> error_reporter =
8464 base::BindOnce(ShutdownErrorCallback, std::move(callback));
8465 std::move(error_reporter).Run(rc);
8466 return;
8467 }
8468 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8469 ShutdownResponseParser, std::move(callback), authorization_delegate);
8470 transceiver_->SendCommand(command, std::move(parser));
8471 }
8472
ShutdownSync(const TPM_SU & shutdown_type,AuthorizationDelegate * authorization_delegate)8473 TPM_RC Tpm::ShutdownSync(const TPM_SU& shutdown_type,
8474 AuthorizationDelegate* authorization_delegate) {
8475 VLOG(1) << __func__;
8476 std::string command;
8477 TPM_RC rc = SerializeCommand_Shutdown(shutdown_type, &command,
8478 authorization_delegate);
8479 if (rc != TPM_RC_SUCCESS) {
8480 return rc;
8481 }
8482 std::string response = transceiver_->SendCommandAndWait(command);
8483 rc = ParseResponse_Shutdown(response, authorization_delegate);
8484 return rc;
8485 }
8486
SerializeCommand_SelfTest(const TPMI_YES_NO & full_test,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8487 TPM_RC Tpm::SerializeCommand_SelfTest(
8488 const TPMI_YES_NO& full_test,
8489 std::string* serialized_command,
8490 AuthorizationDelegate* authorization_delegate) {
8491 VLOG(3) << __func__;
8492 TPM_RC rc = TPM_RC_SUCCESS;
8493 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8494 UINT32 command_size = 10; // Header size.
8495 std::string handle_section_bytes;
8496 std::string parameter_section_bytes;
8497 TPM_CC command_code = TPM_CC_SelfTest;
8498 bool is_command_parameter_encryption_possible = false;
8499 bool is_response_parameter_encryption_possible = false;
8500 std::string command_code_bytes;
8501 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8502 if (rc != TPM_RC_SUCCESS) {
8503 return rc;
8504 }
8505 std::string full_test_bytes;
8506 rc = Serialize_TPMI_YES_NO(full_test, &full_test_bytes);
8507 if (rc != TPM_RC_SUCCESS) {
8508 return rc;
8509 }
8510 std::unique_ptr<crypto::SecureHash> hash(
8511 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8512 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8513 hash->Update(full_test_bytes.data(), full_test_bytes.size());
8514 parameter_section_bytes += full_test_bytes;
8515 command_size += full_test_bytes.size();
8516 std::string command_hash(32, 0);
8517 hash->Finish(std::data(command_hash), command_hash.size());
8518 std::string authorization_section_bytes;
8519 std::string authorization_size_bytes;
8520 if (authorization_delegate) {
8521 if (!authorization_delegate->GetCommandAuthorization(
8522 command_hash, is_command_parameter_encryption_possible,
8523 is_response_parameter_encryption_possible,
8524 &authorization_section_bytes)) {
8525 return TRUNKS_RC_AUTHORIZATION_FAILED;
8526 }
8527 if (!authorization_section_bytes.empty()) {
8528 tag = TPM_ST_SESSIONS;
8529 std::string tmp;
8530 rc = Serialize_UINT32(authorization_section_bytes.size(),
8531 &authorization_size_bytes);
8532 if (rc != TPM_RC_SUCCESS) {
8533 return rc;
8534 }
8535 command_size +=
8536 authorization_size_bytes.size() + authorization_section_bytes.size();
8537 }
8538 }
8539 std::string tag_bytes;
8540 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8541 if (rc != TPM_RC_SUCCESS) {
8542 return rc;
8543 }
8544 std::string command_size_bytes;
8545 rc = Serialize_UINT32(command_size, &command_size_bytes);
8546 if (rc != TPM_RC_SUCCESS) {
8547 return rc;
8548 }
8549 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8550 handle_section_bytes + authorization_size_bytes +
8551 authorization_section_bytes + parameter_section_bytes;
8552 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8553 VLOG(2) << "Command: "
8554 << base::HexEncode(serialized_command->data(),
8555 serialized_command->size());
8556 return TPM_RC_SUCCESS;
8557 }
8558
ParseResponse_SelfTest(const std::string & response,AuthorizationDelegate * authorization_delegate)8559 TPM_RC Tpm::ParseResponse_SelfTest(
8560 const std::string& response,
8561 AuthorizationDelegate* authorization_delegate) {
8562 VLOG(3) << __func__;
8563 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8564 TPM_RC rc = TPM_RC_SUCCESS;
8565 std::string buffer(response);
8566 TPM_ST tag;
8567 std::string tag_bytes;
8568 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8569 if (rc != TPM_RC_SUCCESS) {
8570 return rc;
8571 }
8572 UINT32 response_size;
8573 std::string response_size_bytes;
8574 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8575 if (rc != TPM_RC_SUCCESS) {
8576 return rc;
8577 }
8578 TPM_RC response_code;
8579 std::string response_code_bytes;
8580 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8581 if (rc != TPM_RC_SUCCESS) {
8582 return rc;
8583 }
8584 if (response_size != response.size()) {
8585 return TPM_RC_SIZE;
8586 }
8587 if (response_code != TPM_RC_SUCCESS) {
8588 return response_code;
8589 }
8590 TPM_CC command_code = TPM_CC_SelfTest;
8591 std::string command_code_bytes;
8592 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8593 if (rc != TPM_RC_SUCCESS) {
8594 return rc;
8595 }
8596 std::string authorization_section_bytes;
8597 if (tag == TPM_ST_SESSIONS) {
8598 UINT32 parameter_section_size = buffer.size();
8599 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
8600 if (rc != TPM_RC_SUCCESS) {
8601 return rc;
8602 }
8603 if (parameter_section_size > buffer.size()) {
8604 return TPM_RC_INSUFFICIENT;
8605 }
8606 authorization_section_bytes = buffer.substr(parameter_section_size);
8607 // Keep the parameter section in |buffer|.
8608 buffer.erase(parameter_section_size);
8609 }
8610 std::unique_ptr<crypto::SecureHash> hash(
8611 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8612 hash->Update(response_code_bytes.data(), response_code_bytes.size());
8613 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8614 hash->Update(buffer.data(), buffer.size());
8615 std::string response_hash(32, 0);
8616 hash->Finish(std::data(response_hash), response_hash.size());
8617 if (tag == TPM_ST_SESSIONS) {
8618 if (!authorization_delegate)
8619 return TRUNKS_RC_AUTHORIZATION_FAILED;
8620 if (!authorization_delegate->CheckResponseAuthorization(
8621 response_hash, authorization_section_bytes)) {
8622 return TRUNKS_RC_AUTHORIZATION_FAILED;
8623 }
8624 }
8625 return TPM_RC_SUCCESS;
8626 }
8627
SelfTestErrorCallback(Tpm::SelfTestResponse callback,TPM_RC response_code)8628 void SelfTestErrorCallback(Tpm::SelfTestResponse callback,
8629 TPM_RC response_code) {
8630 VLOG(1) << __func__;
8631 std::move(callback).Run(response_code);
8632 }
8633
SelfTestResponseParser(Tpm::SelfTestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8634 void SelfTestResponseParser(Tpm::SelfTestResponse callback,
8635 AuthorizationDelegate* authorization_delegate,
8636 const std::string& response) {
8637 VLOG(1) << __func__;
8638 TPM_RC rc = Tpm::ParseResponse_SelfTest(response, authorization_delegate);
8639 if (rc != TPM_RC_SUCCESS) {
8640 base::OnceCallback<void(TPM_RC)> error_reporter =
8641 base::BindOnce(SelfTestErrorCallback, std::move(callback));
8642 std::move(error_reporter).Run(rc);
8643 return;
8644 }
8645 std::move(callback).Run(rc);
8646 }
8647
SelfTest(const TPMI_YES_NO & full_test,AuthorizationDelegate * authorization_delegate,SelfTestResponse callback)8648 void Tpm::SelfTest(const TPMI_YES_NO& full_test,
8649 AuthorizationDelegate* authorization_delegate,
8650 SelfTestResponse callback) {
8651 VLOG(1) << __func__;
8652 std::string command;
8653 TPM_RC rc =
8654 SerializeCommand_SelfTest(full_test, &command, authorization_delegate);
8655 if (rc != TPM_RC_SUCCESS) {
8656 base::OnceCallback<void(TPM_RC)> error_reporter =
8657 base::BindOnce(SelfTestErrorCallback, std::move(callback));
8658 std::move(error_reporter).Run(rc);
8659 return;
8660 }
8661 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8662 SelfTestResponseParser, std::move(callback), authorization_delegate);
8663 transceiver_->SendCommand(command, std::move(parser));
8664 }
8665
SelfTestSync(const TPMI_YES_NO & full_test,AuthorizationDelegate * authorization_delegate)8666 TPM_RC Tpm::SelfTestSync(const TPMI_YES_NO& full_test,
8667 AuthorizationDelegate* authorization_delegate) {
8668 VLOG(1) << __func__;
8669 std::string command;
8670 TPM_RC rc =
8671 SerializeCommand_SelfTest(full_test, &command, authorization_delegate);
8672 if (rc != TPM_RC_SUCCESS) {
8673 return rc;
8674 }
8675 std::string response = transceiver_->SendCommandAndWait(command);
8676 rc = ParseResponse_SelfTest(response, authorization_delegate);
8677 return rc;
8678 }
8679
SerializeCommand_IncrementalSelfTest(const TPML_ALG & to_test,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8680 TPM_RC Tpm::SerializeCommand_IncrementalSelfTest(
8681 const TPML_ALG& to_test,
8682 std::string* serialized_command,
8683 AuthorizationDelegate* authorization_delegate) {
8684 VLOG(3) << __func__;
8685 TPM_RC rc = TPM_RC_SUCCESS;
8686 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8687 UINT32 command_size = 10; // Header size.
8688 std::string handle_section_bytes;
8689 std::string parameter_section_bytes;
8690 TPM_CC command_code = TPM_CC_IncrementalSelfTest;
8691 bool is_command_parameter_encryption_possible = false;
8692 bool is_response_parameter_encryption_possible = false;
8693 std::string command_code_bytes;
8694 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8695 if (rc != TPM_RC_SUCCESS) {
8696 return rc;
8697 }
8698 std::string to_test_bytes;
8699 rc = Serialize_TPML_ALG(to_test, &to_test_bytes);
8700 if (rc != TPM_RC_SUCCESS) {
8701 return rc;
8702 }
8703 std::unique_ptr<crypto::SecureHash> hash(
8704 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8705 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8706 hash->Update(to_test_bytes.data(), to_test_bytes.size());
8707 parameter_section_bytes += to_test_bytes;
8708 command_size += to_test_bytes.size();
8709 std::string command_hash(32, 0);
8710 hash->Finish(std::data(command_hash), command_hash.size());
8711 std::string authorization_section_bytes;
8712 std::string authorization_size_bytes;
8713 if (authorization_delegate) {
8714 if (!authorization_delegate->GetCommandAuthorization(
8715 command_hash, is_command_parameter_encryption_possible,
8716 is_response_parameter_encryption_possible,
8717 &authorization_section_bytes)) {
8718 return TRUNKS_RC_AUTHORIZATION_FAILED;
8719 }
8720 if (!authorization_section_bytes.empty()) {
8721 tag = TPM_ST_SESSIONS;
8722 std::string tmp;
8723 rc = Serialize_UINT32(authorization_section_bytes.size(),
8724 &authorization_size_bytes);
8725 if (rc != TPM_RC_SUCCESS) {
8726 return rc;
8727 }
8728 command_size +=
8729 authorization_size_bytes.size() + authorization_section_bytes.size();
8730 }
8731 }
8732 std::string tag_bytes;
8733 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8734 if (rc != TPM_RC_SUCCESS) {
8735 return rc;
8736 }
8737 std::string command_size_bytes;
8738 rc = Serialize_UINT32(command_size, &command_size_bytes);
8739 if (rc != TPM_RC_SUCCESS) {
8740 return rc;
8741 }
8742 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8743 handle_section_bytes + authorization_size_bytes +
8744 authorization_section_bytes + parameter_section_bytes;
8745 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8746 VLOG(2) << "Command: "
8747 << base::HexEncode(serialized_command->data(),
8748 serialized_command->size());
8749 return TPM_RC_SUCCESS;
8750 }
8751
ParseResponse_IncrementalSelfTest(const std::string & response,TPML_ALG * to_do_list,AuthorizationDelegate * authorization_delegate)8752 TPM_RC Tpm::ParseResponse_IncrementalSelfTest(
8753 const std::string& response,
8754 TPML_ALG* to_do_list,
8755 AuthorizationDelegate* authorization_delegate) {
8756 VLOG(3) << __func__;
8757 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8758 TPM_RC rc = TPM_RC_SUCCESS;
8759 std::string buffer(response);
8760 TPM_ST tag;
8761 std::string tag_bytes;
8762 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8763 if (rc != TPM_RC_SUCCESS) {
8764 return rc;
8765 }
8766 UINT32 response_size;
8767 std::string response_size_bytes;
8768 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8769 if (rc != TPM_RC_SUCCESS) {
8770 return rc;
8771 }
8772 TPM_RC response_code;
8773 std::string response_code_bytes;
8774 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8775 if (rc != TPM_RC_SUCCESS) {
8776 return rc;
8777 }
8778 if (response_size != response.size()) {
8779 return TPM_RC_SIZE;
8780 }
8781 if (response_code != TPM_RC_SUCCESS) {
8782 return response_code;
8783 }
8784 TPM_CC command_code = TPM_CC_IncrementalSelfTest;
8785 std::string command_code_bytes;
8786 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8787 if (rc != TPM_RC_SUCCESS) {
8788 return rc;
8789 }
8790 std::string authorization_section_bytes;
8791 if (tag == TPM_ST_SESSIONS) {
8792 UINT32 parameter_section_size = buffer.size();
8793 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
8794 if (rc != TPM_RC_SUCCESS) {
8795 return rc;
8796 }
8797 if (parameter_section_size > buffer.size()) {
8798 return TPM_RC_INSUFFICIENT;
8799 }
8800 authorization_section_bytes = buffer.substr(parameter_section_size);
8801 // Keep the parameter section in |buffer|.
8802 buffer.erase(parameter_section_size);
8803 }
8804 std::unique_ptr<crypto::SecureHash> hash(
8805 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8806 hash->Update(response_code_bytes.data(), response_code_bytes.size());
8807 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8808 hash->Update(buffer.data(), buffer.size());
8809 std::string response_hash(32, 0);
8810 hash->Finish(std::data(response_hash), response_hash.size());
8811 if (tag == TPM_ST_SESSIONS) {
8812 if (!authorization_delegate)
8813 return TRUNKS_RC_AUTHORIZATION_FAILED;
8814 if (!authorization_delegate->CheckResponseAuthorization(
8815 response_hash, authorization_section_bytes)) {
8816 return TRUNKS_RC_AUTHORIZATION_FAILED;
8817 }
8818 }
8819 std::string to_do_list_bytes;
8820 rc = Parse_TPML_ALG(&buffer, to_do_list, &to_do_list_bytes);
8821 if (rc != TPM_RC_SUCCESS) {
8822 return rc;
8823 }
8824 return TPM_RC_SUCCESS;
8825 }
8826
IncrementalSelfTestErrorCallback(Tpm::IncrementalSelfTestResponse callback,TPM_RC response_code)8827 void IncrementalSelfTestErrorCallback(Tpm::IncrementalSelfTestResponse callback,
8828 TPM_RC response_code) {
8829 VLOG(1) << __func__;
8830 std::move(callback).Run(response_code, TPML_ALG());
8831 }
8832
IncrementalSelfTestResponseParser(Tpm::IncrementalSelfTestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8833 void IncrementalSelfTestResponseParser(
8834 Tpm::IncrementalSelfTestResponse callback,
8835 AuthorizationDelegate* authorization_delegate,
8836 const std::string& response) {
8837 VLOG(1) << __func__;
8838 TPML_ALG to_do_list;
8839 TPM_RC rc = Tpm::ParseResponse_IncrementalSelfTest(response, &to_do_list,
8840 authorization_delegate);
8841 if (rc != TPM_RC_SUCCESS) {
8842 base::OnceCallback<void(TPM_RC)> error_reporter =
8843 base::BindOnce(IncrementalSelfTestErrorCallback, std::move(callback));
8844 std::move(error_reporter).Run(rc);
8845 return;
8846 }
8847 std::move(callback).Run(rc, to_do_list);
8848 }
8849
IncrementalSelfTest(const TPML_ALG & to_test,AuthorizationDelegate * authorization_delegate,IncrementalSelfTestResponse callback)8850 void Tpm::IncrementalSelfTest(const TPML_ALG& to_test,
8851 AuthorizationDelegate* authorization_delegate,
8852 IncrementalSelfTestResponse callback) {
8853 VLOG(1) << __func__;
8854 std::string command;
8855 TPM_RC rc = SerializeCommand_IncrementalSelfTest(to_test, &command,
8856 authorization_delegate);
8857 if (rc != TPM_RC_SUCCESS) {
8858 base::OnceCallback<void(TPM_RC)> error_reporter =
8859 base::BindOnce(IncrementalSelfTestErrorCallback, std::move(callback));
8860 std::move(error_reporter).Run(rc);
8861 return;
8862 }
8863 base::OnceCallback<void(const std::string&)> parser =
8864 base::BindOnce(IncrementalSelfTestResponseParser, std::move(callback),
8865 authorization_delegate);
8866 transceiver_->SendCommand(command, std::move(parser));
8867 }
8868
IncrementalSelfTestSync(const TPML_ALG & to_test,TPML_ALG * to_do_list,AuthorizationDelegate * authorization_delegate)8869 TPM_RC Tpm::IncrementalSelfTestSync(
8870 const TPML_ALG& to_test,
8871 TPML_ALG* to_do_list,
8872 AuthorizationDelegate* authorization_delegate) {
8873 VLOG(1) << __func__;
8874 std::string command;
8875 TPM_RC rc = SerializeCommand_IncrementalSelfTest(to_test, &command,
8876 authorization_delegate);
8877 if (rc != TPM_RC_SUCCESS) {
8878 return rc;
8879 }
8880 std::string response = transceiver_->SendCommandAndWait(command);
8881 rc = ParseResponse_IncrementalSelfTest(response, to_do_list,
8882 authorization_delegate);
8883 return rc;
8884 }
8885
SerializeCommand_GetTestResult(std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8886 TPM_RC Tpm::SerializeCommand_GetTestResult(
8887 std::string* serialized_command,
8888 AuthorizationDelegate* authorization_delegate) {
8889 VLOG(3) << __func__;
8890 TPM_RC rc = TPM_RC_SUCCESS;
8891 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8892 UINT32 command_size = 10; // Header size.
8893 std::string handle_section_bytes;
8894 std::string parameter_section_bytes;
8895 TPM_CC command_code = TPM_CC_GetTestResult;
8896 bool is_command_parameter_encryption_possible = false;
8897 bool is_response_parameter_encryption_possible = true;
8898 std::string command_code_bytes;
8899 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8900 if (rc != TPM_RC_SUCCESS) {
8901 return rc;
8902 }
8903 std::unique_ptr<crypto::SecureHash> hash(
8904 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8905 hash->Update(command_code_bytes.data(), command_code_bytes.size());
8906 std::string command_hash(32, 0);
8907 hash->Finish(std::data(command_hash), command_hash.size());
8908 std::string authorization_section_bytes;
8909 std::string authorization_size_bytes;
8910 if (authorization_delegate) {
8911 if (!authorization_delegate->GetCommandAuthorization(
8912 command_hash, is_command_parameter_encryption_possible,
8913 is_response_parameter_encryption_possible,
8914 &authorization_section_bytes)) {
8915 return TRUNKS_RC_AUTHORIZATION_FAILED;
8916 }
8917 if (!authorization_section_bytes.empty()) {
8918 tag = TPM_ST_SESSIONS;
8919 std::string tmp;
8920 rc = Serialize_UINT32(authorization_section_bytes.size(),
8921 &authorization_size_bytes);
8922 if (rc != TPM_RC_SUCCESS) {
8923 return rc;
8924 }
8925 command_size +=
8926 authorization_size_bytes.size() + authorization_section_bytes.size();
8927 }
8928 }
8929 std::string tag_bytes;
8930 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8931 if (rc != TPM_RC_SUCCESS) {
8932 return rc;
8933 }
8934 std::string command_size_bytes;
8935 rc = Serialize_UINT32(command_size, &command_size_bytes);
8936 if (rc != TPM_RC_SUCCESS) {
8937 return rc;
8938 }
8939 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8940 handle_section_bytes + authorization_size_bytes +
8941 authorization_section_bytes + parameter_section_bytes;
8942 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8943 VLOG(2) << "Command: "
8944 << base::HexEncode(serialized_command->data(),
8945 serialized_command->size());
8946 return TPM_RC_SUCCESS;
8947 }
8948
ParseResponse_GetTestResult(const std::string & response,TPM2B_MAX_BUFFER * out_data,TPM_RC * test_result,AuthorizationDelegate * authorization_delegate)8949 TPM_RC Tpm::ParseResponse_GetTestResult(
8950 const std::string& response,
8951 TPM2B_MAX_BUFFER* out_data,
8952 TPM_RC* test_result,
8953 AuthorizationDelegate* authorization_delegate) {
8954 VLOG(3) << __func__;
8955 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8956 TPM_RC rc = TPM_RC_SUCCESS;
8957 std::string buffer(response);
8958 TPM_ST tag;
8959 std::string tag_bytes;
8960 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8961 if (rc != TPM_RC_SUCCESS) {
8962 return rc;
8963 }
8964 UINT32 response_size;
8965 std::string response_size_bytes;
8966 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8967 if (rc != TPM_RC_SUCCESS) {
8968 return rc;
8969 }
8970 TPM_RC response_code;
8971 std::string response_code_bytes;
8972 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8973 if (rc != TPM_RC_SUCCESS) {
8974 return rc;
8975 }
8976 if (response_size != response.size()) {
8977 return TPM_RC_SIZE;
8978 }
8979 if (response_code != TPM_RC_SUCCESS) {
8980 return response_code;
8981 }
8982 TPM_CC command_code = TPM_CC_GetTestResult;
8983 std::string command_code_bytes;
8984 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8985 if (rc != TPM_RC_SUCCESS) {
8986 return rc;
8987 }
8988 std::string authorization_section_bytes;
8989 if (tag == TPM_ST_SESSIONS) {
8990 UINT32 parameter_section_size = buffer.size();
8991 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
8992 if (rc != TPM_RC_SUCCESS) {
8993 return rc;
8994 }
8995 if (parameter_section_size > buffer.size()) {
8996 return TPM_RC_INSUFFICIENT;
8997 }
8998 authorization_section_bytes = buffer.substr(parameter_section_size);
8999 // Keep the parameter section in |buffer|.
9000 buffer.erase(parameter_section_size);
9001 }
9002 std::unique_ptr<crypto::SecureHash> hash(
9003 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9004 hash->Update(response_code_bytes.data(), response_code_bytes.size());
9005 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9006 hash->Update(buffer.data(), buffer.size());
9007 std::string response_hash(32, 0);
9008 hash->Finish(std::data(response_hash), response_hash.size());
9009 if (tag == TPM_ST_SESSIONS) {
9010 if (!authorization_delegate)
9011 return TRUNKS_RC_AUTHORIZATION_FAILED;
9012 if (!authorization_delegate->CheckResponseAuthorization(
9013 response_hash, authorization_section_bytes)) {
9014 return TRUNKS_RC_AUTHORIZATION_FAILED;
9015 }
9016 }
9017 if (tag == TPM_ST_SESSIONS) {
9018 if (!authorization_delegate)
9019 return TRUNKS_RC_AUTHORIZATION_FAILED;
9020
9021 // Parse the encrypted parameter size.
9022 UINT16 size;
9023 std::string size_buffer = buffer.substr(0, 2);
9024 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9025 return result;
9026 }
9027 if (buffer.size() < 2 + size) {
9028 return TPM_RC_INSUFFICIENT;
9029 }
9030
9031 // Decrypt just the parameter data, not the size.
9032 std::string decrypted_data = buffer.substr(2, size);
9033 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9034 return TRUNKS_RC_ENCRYPTION_FAILED;
9035 }
9036 buffer.replace(2, size, decrypted_data);
9037 }
9038 std::string out_data_bytes;
9039 rc = Parse_TPM2B_MAX_BUFFER(&buffer, out_data, &out_data_bytes);
9040 if (rc != TPM_RC_SUCCESS) {
9041 return rc;
9042 }
9043 std::string test_result_bytes;
9044 rc = Parse_TPM_RC(&buffer, test_result, &test_result_bytes);
9045 if (rc != TPM_RC_SUCCESS) {
9046 return rc;
9047 }
9048 return TPM_RC_SUCCESS;
9049 }
9050
GetTestResultErrorCallback(Tpm::GetTestResultResponse callback,TPM_RC response_code)9051 void GetTestResultErrorCallback(Tpm::GetTestResultResponse callback,
9052 TPM_RC response_code) {
9053 VLOG(1) << __func__;
9054 std::move(callback).Run(response_code, TPM2B_MAX_BUFFER(), TPM_RC());
9055 }
9056
GetTestResultResponseParser(Tpm::GetTestResultResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9057 void GetTestResultResponseParser(Tpm::GetTestResultResponse callback,
9058 AuthorizationDelegate* authorization_delegate,
9059 const std::string& response) {
9060 VLOG(1) << __func__;
9061 TPM2B_MAX_BUFFER out_data;
9062 TPM_RC test_result;
9063 TPM_RC rc = Tpm::ParseResponse_GetTestResult(
9064 response, &out_data, &test_result, authorization_delegate);
9065 if (rc != TPM_RC_SUCCESS) {
9066 base::OnceCallback<void(TPM_RC)> error_reporter =
9067 base::BindOnce(GetTestResultErrorCallback, std::move(callback));
9068 std::move(error_reporter).Run(rc);
9069 return;
9070 }
9071 std::move(callback).Run(rc, out_data, test_result);
9072 }
9073
GetTestResult(AuthorizationDelegate * authorization_delegate,GetTestResultResponse callback)9074 void Tpm::GetTestResult(AuthorizationDelegate* authorization_delegate,
9075 GetTestResultResponse callback) {
9076 VLOG(1) << __func__;
9077 std::string command;
9078 TPM_RC rc = SerializeCommand_GetTestResult(&command, authorization_delegate);
9079 if (rc != TPM_RC_SUCCESS) {
9080 base::OnceCallback<void(TPM_RC)> error_reporter =
9081 base::BindOnce(GetTestResultErrorCallback, std::move(callback));
9082 std::move(error_reporter).Run(rc);
9083 return;
9084 }
9085 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9086 GetTestResultResponseParser, std::move(callback), authorization_delegate);
9087 transceiver_->SendCommand(command, std::move(parser));
9088 }
9089
GetTestResultSync(TPM2B_MAX_BUFFER * out_data,TPM_RC * test_result,AuthorizationDelegate * authorization_delegate)9090 TPM_RC Tpm::GetTestResultSync(TPM2B_MAX_BUFFER* out_data,
9091 TPM_RC* test_result,
9092 AuthorizationDelegate* authorization_delegate) {
9093 VLOG(1) << __func__;
9094 std::string command;
9095 TPM_RC rc = SerializeCommand_GetTestResult(&command, authorization_delegate);
9096 if (rc != TPM_RC_SUCCESS) {
9097 return rc;
9098 }
9099 std::string response = transceiver_->SendCommandAndWait(command);
9100 rc = ParseResponse_GetTestResult(response, out_data, test_result,
9101 authorization_delegate);
9102 return rc;
9103 }
9104
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)9105 TPM_RC Tpm::SerializeCommand_StartAuthSession(
9106 const TPMI_DH_OBJECT& tpm_key,
9107 const std::string& tpm_key_name,
9108 const TPMI_DH_ENTITY& bind,
9109 const std::string& bind_name,
9110 const TPM2B_NONCE& nonce_caller,
9111 const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9112 const TPM_SE& session_type,
9113 const TPMT_SYM_DEF& symmetric,
9114 const TPMI_ALG_HASH& auth_hash,
9115 std::string* serialized_command,
9116 AuthorizationDelegate* authorization_delegate) {
9117 VLOG(3) << __func__;
9118 TPM_RC rc = TPM_RC_SUCCESS;
9119 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9120 UINT32 command_size = 10; // Header size.
9121 std::string handle_section_bytes;
9122 std::string parameter_section_bytes;
9123 TPM_CC command_code = TPM_CC_StartAuthSession;
9124 bool is_command_parameter_encryption_possible = true;
9125 bool is_response_parameter_encryption_possible = true;
9126 std::string command_code_bytes;
9127 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9128 if (rc != TPM_RC_SUCCESS) {
9129 return rc;
9130 }
9131 std::string tpm_key_bytes;
9132 rc = Serialize_TPMI_DH_OBJECT(tpm_key, &tpm_key_bytes);
9133 if (rc != TPM_RC_SUCCESS) {
9134 return rc;
9135 }
9136 std::string bind_bytes;
9137 rc = Serialize_TPMI_DH_ENTITY(bind, &bind_bytes);
9138 if (rc != TPM_RC_SUCCESS) {
9139 return rc;
9140 }
9141 std::string nonce_caller_bytes;
9142 rc = Serialize_TPM2B_NONCE(nonce_caller, &nonce_caller_bytes);
9143 if (rc != TPM_RC_SUCCESS) {
9144 return rc;
9145 }
9146 std::string encrypted_salt_bytes;
9147 rc = Serialize_TPM2B_ENCRYPTED_SECRET(encrypted_salt, &encrypted_salt_bytes);
9148 if (rc != TPM_RC_SUCCESS) {
9149 return rc;
9150 }
9151 std::string session_type_bytes;
9152 rc = Serialize_TPM_SE(session_type, &session_type_bytes);
9153 if (rc != TPM_RC_SUCCESS) {
9154 return rc;
9155 }
9156 std::string symmetric_bytes;
9157 rc = Serialize_TPMT_SYM_DEF(symmetric, &symmetric_bytes);
9158 if (rc != TPM_RC_SUCCESS) {
9159 return rc;
9160 }
9161 std::string auth_hash_bytes;
9162 rc = Serialize_TPMI_ALG_HASH(auth_hash, &auth_hash_bytes);
9163 if (rc != TPM_RC_SUCCESS) {
9164 return rc;
9165 }
9166 if (authorization_delegate) {
9167 // Encrypt just the parameter data, not the size.
9168 std::string tmp = nonce_caller_bytes.substr(2);
9169 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9170 return TRUNKS_RC_ENCRYPTION_FAILED;
9171 }
9172 nonce_caller_bytes.replace(2, std::string::npos, tmp);
9173 }
9174 std::unique_ptr<crypto::SecureHash> hash(
9175 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9176 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9177 hash->Update(tpm_key_name.data(), tpm_key_name.size());
9178 handle_section_bytes += tpm_key_bytes;
9179 command_size += tpm_key_bytes.size();
9180 hash->Update(bind_name.data(), bind_name.size());
9181 handle_section_bytes += bind_bytes;
9182 command_size += bind_bytes.size();
9183 hash->Update(nonce_caller_bytes.data(), nonce_caller_bytes.size());
9184 parameter_section_bytes += nonce_caller_bytes;
9185 command_size += nonce_caller_bytes.size();
9186 hash->Update(encrypted_salt_bytes.data(), encrypted_salt_bytes.size());
9187 parameter_section_bytes += encrypted_salt_bytes;
9188 command_size += encrypted_salt_bytes.size();
9189 hash->Update(session_type_bytes.data(), session_type_bytes.size());
9190 parameter_section_bytes += session_type_bytes;
9191 command_size += session_type_bytes.size();
9192 hash->Update(symmetric_bytes.data(), symmetric_bytes.size());
9193 parameter_section_bytes += symmetric_bytes;
9194 command_size += symmetric_bytes.size();
9195 hash->Update(auth_hash_bytes.data(), auth_hash_bytes.size());
9196 parameter_section_bytes += auth_hash_bytes;
9197 command_size += auth_hash_bytes.size();
9198 std::string command_hash(32, 0);
9199 hash->Finish(std::data(command_hash), command_hash.size());
9200 std::string authorization_section_bytes;
9201 std::string authorization_size_bytes;
9202 if (authorization_delegate) {
9203 if (!authorization_delegate->GetCommandAuthorization(
9204 command_hash, is_command_parameter_encryption_possible,
9205 is_response_parameter_encryption_possible,
9206 &authorization_section_bytes)) {
9207 return TRUNKS_RC_AUTHORIZATION_FAILED;
9208 }
9209 if (!authorization_section_bytes.empty()) {
9210 tag = TPM_ST_SESSIONS;
9211 std::string tmp;
9212 rc = Serialize_UINT32(authorization_section_bytes.size(),
9213 &authorization_size_bytes);
9214 if (rc != TPM_RC_SUCCESS) {
9215 return rc;
9216 }
9217 command_size +=
9218 authorization_size_bytes.size() + authorization_section_bytes.size();
9219 }
9220 }
9221 std::string tag_bytes;
9222 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9223 if (rc != TPM_RC_SUCCESS) {
9224 return rc;
9225 }
9226 std::string command_size_bytes;
9227 rc = Serialize_UINT32(command_size, &command_size_bytes);
9228 if (rc != TPM_RC_SUCCESS) {
9229 return rc;
9230 }
9231 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9232 handle_section_bytes + authorization_size_bytes +
9233 authorization_section_bytes + parameter_section_bytes;
9234 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9235 VLOG(2) << "Command: "
9236 << base::HexEncode(serialized_command->data(),
9237 serialized_command->size());
9238 return TPM_RC_SUCCESS;
9239 }
9240
ParseResponse_StartAuthSession(const std::string & response,TPMI_SH_AUTH_SESSION * session_handle,TPM2B_NONCE * nonce_tpm,AuthorizationDelegate * authorization_delegate)9241 TPM_RC Tpm::ParseResponse_StartAuthSession(
9242 const std::string& response,
9243 TPMI_SH_AUTH_SESSION* session_handle,
9244 TPM2B_NONCE* nonce_tpm,
9245 AuthorizationDelegate* authorization_delegate) {
9246 VLOG(3) << __func__;
9247 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9248 TPM_RC rc = TPM_RC_SUCCESS;
9249 std::string buffer(response);
9250 TPM_ST tag;
9251 std::string tag_bytes;
9252 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9253 if (rc != TPM_RC_SUCCESS) {
9254 return rc;
9255 }
9256 UINT32 response_size;
9257 std::string response_size_bytes;
9258 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9259 if (rc != TPM_RC_SUCCESS) {
9260 return rc;
9261 }
9262 TPM_RC response_code;
9263 std::string response_code_bytes;
9264 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9265 if (rc != TPM_RC_SUCCESS) {
9266 return rc;
9267 }
9268 if (response_size != response.size()) {
9269 return TPM_RC_SIZE;
9270 }
9271 if (response_code != TPM_RC_SUCCESS) {
9272 return response_code;
9273 }
9274 std::string session_handle_bytes;
9275 rc = Parse_TPMI_SH_AUTH_SESSION(&buffer, session_handle,
9276 &session_handle_bytes);
9277 if (rc != TPM_RC_SUCCESS) {
9278 return rc;
9279 }
9280 TPM_CC command_code = TPM_CC_StartAuthSession;
9281 std::string command_code_bytes;
9282 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9283 if (rc != TPM_RC_SUCCESS) {
9284 return rc;
9285 }
9286 std::string authorization_section_bytes;
9287 if (tag == TPM_ST_SESSIONS) {
9288 UINT32 parameter_section_size = buffer.size();
9289 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
9290 if (rc != TPM_RC_SUCCESS) {
9291 return rc;
9292 }
9293 if (parameter_section_size > buffer.size()) {
9294 return TPM_RC_INSUFFICIENT;
9295 }
9296 authorization_section_bytes = buffer.substr(parameter_section_size);
9297 // Keep the parameter section in |buffer|.
9298 buffer.erase(parameter_section_size);
9299 }
9300 std::unique_ptr<crypto::SecureHash> hash(
9301 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9302 hash->Update(response_code_bytes.data(), response_code_bytes.size());
9303 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9304 hash->Update(buffer.data(), buffer.size());
9305 std::string response_hash(32, 0);
9306 hash->Finish(std::data(response_hash), response_hash.size());
9307 if (tag == TPM_ST_SESSIONS) {
9308 if (!authorization_delegate)
9309 return TRUNKS_RC_AUTHORIZATION_FAILED;
9310 if (!authorization_delegate->CheckResponseAuthorization(
9311 response_hash, authorization_section_bytes)) {
9312 return TRUNKS_RC_AUTHORIZATION_FAILED;
9313 }
9314 }
9315 if (tag == TPM_ST_SESSIONS) {
9316 if (!authorization_delegate)
9317 return TRUNKS_RC_AUTHORIZATION_FAILED;
9318
9319 // Parse the encrypted parameter size.
9320 UINT16 size;
9321 std::string size_buffer = buffer.substr(0, 2);
9322 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9323 return result;
9324 }
9325 if (buffer.size() < 2 + size) {
9326 return TPM_RC_INSUFFICIENT;
9327 }
9328
9329 // Decrypt just the parameter data, not the size.
9330 std::string decrypted_data = buffer.substr(2, size);
9331 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9332 return TRUNKS_RC_ENCRYPTION_FAILED;
9333 }
9334 buffer.replace(2, size, decrypted_data);
9335 }
9336 std::string nonce_tpm_bytes;
9337 rc = Parse_TPM2B_NONCE(&buffer, nonce_tpm, &nonce_tpm_bytes);
9338 if (rc != TPM_RC_SUCCESS) {
9339 return rc;
9340 }
9341 return TPM_RC_SUCCESS;
9342 }
9343
StartAuthSessionErrorCallback(Tpm::StartAuthSessionResponse callback,TPM_RC response_code)9344 void StartAuthSessionErrorCallback(Tpm::StartAuthSessionResponse callback,
9345 TPM_RC response_code) {
9346 VLOG(1) << __func__;
9347 std::move(callback).Run(response_code, TPMI_SH_AUTH_SESSION(), TPM2B_NONCE());
9348 }
9349
StartAuthSessionResponseParser(Tpm::StartAuthSessionResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9350 void StartAuthSessionResponseParser(
9351 Tpm::StartAuthSessionResponse callback,
9352 AuthorizationDelegate* authorization_delegate,
9353 const std::string& response) {
9354 VLOG(1) << __func__;
9355 TPMI_SH_AUTH_SESSION session_handle;
9356 TPM2B_NONCE nonce_tpm;
9357 TPM_RC rc = Tpm::ParseResponse_StartAuthSession(
9358 response, &session_handle, &nonce_tpm, authorization_delegate);
9359 if (rc != TPM_RC_SUCCESS) {
9360 base::OnceCallback<void(TPM_RC)> error_reporter =
9361 base::BindOnce(StartAuthSessionErrorCallback, std::move(callback));
9362 std::move(error_reporter).Run(rc);
9363 return;
9364 }
9365 std::move(callback).Run(rc, session_handle, nonce_tpm);
9366 }
9367
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)9368 void Tpm::StartAuthSession(const TPMI_DH_OBJECT& tpm_key,
9369 const std::string& tpm_key_name,
9370 const TPMI_DH_ENTITY& bind,
9371 const std::string& bind_name,
9372 const TPM2B_NONCE& nonce_caller,
9373 const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9374 const TPM_SE& session_type,
9375 const TPMT_SYM_DEF& symmetric,
9376 const TPMI_ALG_HASH& auth_hash,
9377 AuthorizationDelegate* authorization_delegate,
9378 StartAuthSessionResponse callback) {
9379 VLOG(1) << __func__;
9380 std::string command;
9381 TPM_RC rc = SerializeCommand_StartAuthSession(
9382 tpm_key, tpm_key_name, bind, bind_name, nonce_caller, encrypted_salt,
9383 session_type, symmetric, auth_hash, &command, authorization_delegate);
9384 if (rc != TPM_RC_SUCCESS) {
9385 base::OnceCallback<void(TPM_RC)> error_reporter =
9386 base::BindOnce(StartAuthSessionErrorCallback, std::move(callback));
9387 std::move(error_reporter).Run(rc);
9388 return;
9389 }
9390 base::OnceCallback<void(const std::string&)> parser =
9391 base::BindOnce(StartAuthSessionResponseParser, std::move(callback),
9392 authorization_delegate);
9393 transceiver_->SendCommand(command, std::move(parser));
9394 }
9395
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)9396 TPM_RC Tpm::StartAuthSessionSync(
9397 const TPMI_DH_OBJECT& tpm_key,
9398 const std::string& tpm_key_name,
9399 const TPMI_DH_ENTITY& bind,
9400 const std::string& bind_name,
9401 const TPM2B_NONCE& nonce_caller,
9402 const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9403 const TPM_SE& session_type,
9404 const TPMT_SYM_DEF& symmetric,
9405 const TPMI_ALG_HASH& auth_hash,
9406 TPMI_SH_AUTH_SESSION* session_handle,
9407 TPM2B_NONCE* nonce_tpm,
9408 AuthorizationDelegate* authorization_delegate) {
9409 VLOG(1) << __func__;
9410 std::string command;
9411 TPM_RC rc = SerializeCommand_StartAuthSession(
9412 tpm_key, tpm_key_name, bind, bind_name, nonce_caller, encrypted_salt,
9413 session_type, symmetric, auth_hash, &command, authorization_delegate);
9414 if (rc != TPM_RC_SUCCESS) {
9415 return rc;
9416 }
9417 std::string response = transceiver_->SendCommandAndWait(command);
9418 rc = ParseResponse_StartAuthSession(response, session_handle, nonce_tpm,
9419 authorization_delegate);
9420 return rc;
9421 }
9422
SerializeCommand_PolicyRestart(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9423 TPM_RC Tpm::SerializeCommand_PolicyRestart(
9424 const TPMI_SH_POLICY& session_handle,
9425 const std::string& session_handle_name,
9426 std::string* serialized_command,
9427 AuthorizationDelegate* authorization_delegate) {
9428 VLOG(3) << __func__;
9429 TPM_RC rc = TPM_RC_SUCCESS;
9430 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9431 UINT32 command_size = 10; // Header size.
9432 std::string handle_section_bytes;
9433 std::string parameter_section_bytes;
9434 TPM_CC command_code = TPM_CC_PolicyRestart;
9435 bool is_command_parameter_encryption_possible = false;
9436 bool is_response_parameter_encryption_possible = false;
9437 std::string command_code_bytes;
9438 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9439 if (rc != TPM_RC_SUCCESS) {
9440 return rc;
9441 }
9442 std::string session_handle_bytes;
9443 rc = Serialize_TPMI_SH_POLICY(session_handle, &session_handle_bytes);
9444 if (rc != TPM_RC_SUCCESS) {
9445 return rc;
9446 }
9447 std::unique_ptr<crypto::SecureHash> hash(
9448 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9449 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9450 hash->Update(session_handle_name.data(), session_handle_name.size());
9451 handle_section_bytes += session_handle_bytes;
9452 command_size += session_handle_bytes.size();
9453 std::string command_hash(32, 0);
9454 hash->Finish(std::data(command_hash), command_hash.size());
9455 std::string authorization_section_bytes;
9456 std::string authorization_size_bytes;
9457 if (authorization_delegate) {
9458 if (!authorization_delegate->GetCommandAuthorization(
9459 command_hash, is_command_parameter_encryption_possible,
9460 is_response_parameter_encryption_possible,
9461 &authorization_section_bytes)) {
9462 return TRUNKS_RC_AUTHORIZATION_FAILED;
9463 }
9464 if (!authorization_section_bytes.empty()) {
9465 tag = TPM_ST_SESSIONS;
9466 std::string tmp;
9467 rc = Serialize_UINT32(authorization_section_bytes.size(),
9468 &authorization_size_bytes);
9469 if (rc != TPM_RC_SUCCESS) {
9470 return rc;
9471 }
9472 command_size +=
9473 authorization_size_bytes.size() + authorization_section_bytes.size();
9474 }
9475 }
9476 std::string tag_bytes;
9477 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9478 if (rc != TPM_RC_SUCCESS) {
9479 return rc;
9480 }
9481 std::string command_size_bytes;
9482 rc = Serialize_UINT32(command_size, &command_size_bytes);
9483 if (rc != TPM_RC_SUCCESS) {
9484 return rc;
9485 }
9486 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9487 handle_section_bytes + authorization_size_bytes +
9488 authorization_section_bytes + parameter_section_bytes;
9489 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9490 VLOG(2) << "Command: "
9491 << base::HexEncode(serialized_command->data(),
9492 serialized_command->size());
9493 return TPM_RC_SUCCESS;
9494 }
9495
ParseResponse_PolicyRestart(const std::string & response,AuthorizationDelegate * authorization_delegate)9496 TPM_RC Tpm::ParseResponse_PolicyRestart(
9497 const std::string& response,
9498 AuthorizationDelegate* authorization_delegate) {
9499 VLOG(3) << __func__;
9500 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9501 TPM_RC rc = TPM_RC_SUCCESS;
9502 std::string buffer(response);
9503 TPM_ST tag;
9504 std::string tag_bytes;
9505 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9506 if (rc != TPM_RC_SUCCESS) {
9507 return rc;
9508 }
9509 UINT32 response_size;
9510 std::string response_size_bytes;
9511 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9512 if (rc != TPM_RC_SUCCESS) {
9513 return rc;
9514 }
9515 TPM_RC response_code;
9516 std::string response_code_bytes;
9517 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9518 if (rc != TPM_RC_SUCCESS) {
9519 return rc;
9520 }
9521 if (response_size != response.size()) {
9522 return TPM_RC_SIZE;
9523 }
9524 if (response_code != TPM_RC_SUCCESS) {
9525 return response_code;
9526 }
9527 TPM_CC command_code = TPM_CC_PolicyRestart;
9528 std::string command_code_bytes;
9529 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9530 if (rc != TPM_RC_SUCCESS) {
9531 return rc;
9532 }
9533 std::string authorization_section_bytes;
9534 if (tag == TPM_ST_SESSIONS) {
9535 UINT32 parameter_section_size = buffer.size();
9536 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
9537 if (rc != TPM_RC_SUCCESS) {
9538 return rc;
9539 }
9540 if (parameter_section_size > buffer.size()) {
9541 return TPM_RC_INSUFFICIENT;
9542 }
9543 authorization_section_bytes = buffer.substr(parameter_section_size);
9544 // Keep the parameter section in |buffer|.
9545 buffer.erase(parameter_section_size);
9546 }
9547 std::unique_ptr<crypto::SecureHash> hash(
9548 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9549 hash->Update(response_code_bytes.data(), response_code_bytes.size());
9550 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9551 hash->Update(buffer.data(), buffer.size());
9552 std::string response_hash(32, 0);
9553 hash->Finish(std::data(response_hash), response_hash.size());
9554 if (tag == TPM_ST_SESSIONS) {
9555 if (!authorization_delegate)
9556 return TRUNKS_RC_AUTHORIZATION_FAILED;
9557 if (!authorization_delegate->CheckResponseAuthorization(
9558 response_hash, authorization_section_bytes)) {
9559 return TRUNKS_RC_AUTHORIZATION_FAILED;
9560 }
9561 }
9562 return TPM_RC_SUCCESS;
9563 }
9564
PolicyRestartErrorCallback(Tpm::PolicyRestartResponse callback,TPM_RC response_code)9565 void PolicyRestartErrorCallback(Tpm::PolicyRestartResponse callback,
9566 TPM_RC response_code) {
9567 VLOG(1) << __func__;
9568 std::move(callback).Run(response_code);
9569 }
9570
PolicyRestartResponseParser(Tpm::PolicyRestartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9571 void PolicyRestartResponseParser(Tpm::PolicyRestartResponse callback,
9572 AuthorizationDelegate* authorization_delegate,
9573 const std::string& response) {
9574 VLOG(1) << __func__;
9575 TPM_RC rc =
9576 Tpm::ParseResponse_PolicyRestart(response, authorization_delegate);
9577 if (rc != TPM_RC_SUCCESS) {
9578 base::OnceCallback<void(TPM_RC)> error_reporter =
9579 base::BindOnce(PolicyRestartErrorCallback, std::move(callback));
9580 std::move(error_reporter).Run(rc);
9581 return;
9582 }
9583 std::move(callback).Run(rc);
9584 }
9585
PolicyRestart(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,AuthorizationDelegate * authorization_delegate,PolicyRestartResponse callback)9586 void Tpm::PolicyRestart(const TPMI_SH_POLICY& session_handle,
9587 const std::string& session_handle_name,
9588 AuthorizationDelegate* authorization_delegate,
9589 PolicyRestartResponse callback) {
9590 VLOG(1) << __func__;
9591 std::string command;
9592 TPM_RC rc = SerializeCommand_PolicyRestart(
9593 session_handle, session_handle_name, &command, authorization_delegate);
9594 if (rc != TPM_RC_SUCCESS) {
9595 base::OnceCallback<void(TPM_RC)> error_reporter =
9596 base::BindOnce(PolicyRestartErrorCallback, std::move(callback));
9597 std::move(error_reporter).Run(rc);
9598 return;
9599 }
9600 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9601 PolicyRestartResponseParser, std::move(callback), authorization_delegate);
9602 transceiver_->SendCommand(command, std::move(parser));
9603 }
9604
PolicyRestartSync(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,AuthorizationDelegate * authorization_delegate)9605 TPM_RC Tpm::PolicyRestartSync(const TPMI_SH_POLICY& session_handle,
9606 const std::string& session_handle_name,
9607 AuthorizationDelegate* authorization_delegate) {
9608 VLOG(1) << __func__;
9609 std::string command;
9610 TPM_RC rc = SerializeCommand_PolicyRestart(
9611 session_handle, session_handle_name, &command, authorization_delegate);
9612 if (rc != TPM_RC_SUCCESS) {
9613 return rc;
9614 }
9615 std::string response = transceiver_->SendCommandAndWait(command);
9616 rc = ParseResponse_PolicyRestart(response, authorization_delegate);
9617 return rc;
9618 }
9619
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)9620 TPM_RC Tpm::SerializeCommand_Create(
9621 const TPMI_DH_OBJECT& parent_handle,
9622 const std::string& parent_handle_name,
9623 const TPM2B_SENSITIVE_CREATE& in_sensitive,
9624 const TPM2B_PUBLIC& in_public,
9625 const TPM2B_DATA& outside_info,
9626 const TPML_PCR_SELECTION& creation_pcr,
9627 std::string* serialized_command,
9628 AuthorizationDelegate* authorization_delegate) {
9629 VLOG(3) << __func__;
9630 TPM_RC rc = TPM_RC_SUCCESS;
9631 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9632 UINT32 command_size = 10; // Header size.
9633 std::string handle_section_bytes;
9634 std::string parameter_section_bytes;
9635 TPM_CC command_code = TPM_CC_Create;
9636 bool is_command_parameter_encryption_possible = true;
9637 bool is_response_parameter_encryption_possible = true;
9638 std::string command_code_bytes;
9639 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9640 if (rc != TPM_RC_SUCCESS) {
9641 return rc;
9642 }
9643 std::string parent_handle_bytes;
9644 rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
9645 if (rc != TPM_RC_SUCCESS) {
9646 return rc;
9647 }
9648 std::string in_sensitive_bytes;
9649 rc = Serialize_TPM2B_SENSITIVE_CREATE(in_sensitive, &in_sensitive_bytes);
9650 if (rc != TPM_RC_SUCCESS) {
9651 return rc;
9652 }
9653 std::string in_public_bytes;
9654 rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
9655 if (rc != TPM_RC_SUCCESS) {
9656 return rc;
9657 }
9658 std::string outside_info_bytes;
9659 rc = Serialize_TPM2B_DATA(outside_info, &outside_info_bytes);
9660 if (rc != TPM_RC_SUCCESS) {
9661 return rc;
9662 }
9663 std::string creation_pcr_bytes;
9664 rc = Serialize_TPML_PCR_SELECTION(creation_pcr, &creation_pcr_bytes);
9665 if (rc != TPM_RC_SUCCESS) {
9666 return rc;
9667 }
9668 if (authorization_delegate) {
9669 // Encrypt just the parameter data, not the size.
9670 std::string tmp = in_sensitive_bytes.substr(2);
9671 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9672 return TRUNKS_RC_ENCRYPTION_FAILED;
9673 }
9674 in_sensitive_bytes.replace(2, std::string::npos, tmp);
9675 }
9676 std::unique_ptr<crypto::SecureHash> hash(
9677 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9678 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9679 hash->Update(parent_handle_name.data(), parent_handle_name.size());
9680 handle_section_bytes += parent_handle_bytes;
9681 command_size += parent_handle_bytes.size();
9682 hash->Update(in_sensitive_bytes.data(), in_sensitive_bytes.size());
9683 parameter_section_bytes += in_sensitive_bytes;
9684 command_size += in_sensitive_bytes.size();
9685 hash->Update(in_public_bytes.data(), in_public_bytes.size());
9686 parameter_section_bytes += in_public_bytes;
9687 command_size += in_public_bytes.size();
9688 hash->Update(outside_info_bytes.data(), outside_info_bytes.size());
9689 parameter_section_bytes += outside_info_bytes;
9690 command_size += outside_info_bytes.size();
9691 hash->Update(creation_pcr_bytes.data(), creation_pcr_bytes.size());
9692 parameter_section_bytes += creation_pcr_bytes;
9693 command_size += creation_pcr_bytes.size();
9694 std::string command_hash(32, 0);
9695 hash->Finish(std::data(command_hash), command_hash.size());
9696 std::string authorization_section_bytes;
9697 std::string authorization_size_bytes;
9698 if (authorization_delegate) {
9699 if (!authorization_delegate->GetCommandAuthorization(
9700 command_hash, is_command_parameter_encryption_possible,
9701 is_response_parameter_encryption_possible,
9702 &authorization_section_bytes)) {
9703 return TRUNKS_RC_AUTHORIZATION_FAILED;
9704 }
9705 if (!authorization_section_bytes.empty()) {
9706 tag = TPM_ST_SESSIONS;
9707 std::string tmp;
9708 rc = Serialize_UINT32(authorization_section_bytes.size(),
9709 &authorization_size_bytes);
9710 if (rc != TPM_RC_SUCCESS) {
9711 return rc;
9712 }
9713 command_size +=
9714 authorization_size_bytes.size() + authorization_section_bytes.size();
9715 }
9716 }
9717 std::string tag_bytes;
9718 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9719 if (rc != TPM_RC_SUCCESS) {
9720 return rc;
9721 }
9722 std::string command_size_bytes;
9723 rc = Serialize_UINT32(command_size, &command_size_bytes);
9724 if (rc != TPM_RC_SUCCESS) {
9725 return rc;
9726 }
9727 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9728 handle_section_bytes + authorization_size_bytes +
9729 authorization_section_bytes + parameter_section_bytes;
9730 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9731 VLOG(2) << "Command: "
9732 << base::HexEncode(serialized_command->data(),
9733 serialized_command->size());
9734 return TPM_RC_SUCCESS;
9735 }
9736
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)9737 TPM_RC Tpm::ParseResponse_Create(
9738 const std::string& response,
9739 TPM2B_PRIVATE* out_private,
9740 TPM2B_PUBLIC* out_public,
9741 TPM2B_CREATION_DATA* creation_data,
9742 TPM2B_DIGEST* creation_hash,
9743 TPMT_TK_CREATION* creation_ticket,
9744 AuthorizationDelegate* authorization_delegate) {
9745 VLOG(3) << __func__;
9746 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9747 TPM_RC rc = TPM_RC_SUCCESS;
9748 std::string buffer(response);
9749 TPM_ST tag;
9750 std::string tag_bytes;
9751 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9752 if (rc != TPM_RC_SUCCESS) {
9753 return rc;
9754 }
9755 UINT32 response_size;
9756 std::string response_size_bytes;
9757 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9758 if (rc != TPM_RC_SUCCESS) {
9759 return rc;
9760 }
9761 TPM_RC response_code;
9762 std::string response_code_bytes;
9763 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9764 if (rc != TPM_RC_SUCCESS) {
9765 return rc;
9766 }
9767 if (response_size != response.size()) {
9768 return TPM_RC_SIZE;
9769 }
9770 if (response_code != TPM_RC_SUCCESS) {
9771 return response_code;
9772 }
9773 TPM_CC command_code = TPM_CC_Create;
9774 std::string command_code_bytes;
9775 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9776 if (rc != TPM_RC_SUCCESS) {
9777 return rc;
9778 }
9779 std::string authorization_section_bytes;
9780 if (tag == TPM_ST_SESSIONS) {
9781 UINT32 parameter_section_size = buffer.size();
9782 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
9783 if (rc != TPM_RC_SUCCESS) {
9784 return rc;
9785 }
9786 if (parameter_section_size > buffer.size()) {
9787 return TPM_RC_INSUFFICIENT;
9788 }
9789 authorization_section_bytes = buffer.substr(parameter_section_size);
9790 // Keep the parameter section in |buffer|.
9791 buffer.erase(parameter_section_size);
9792 }
9793 std::unique_ptr<crypto::SecureHash> hash(
9794 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9795 hash->Update(response_code_bytes.data(), response_code_bytes.size());
9796 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9797 hash->Update(buffer.data(), buffer.size());
9798 std::string response_hash(32, 0);
9799 hash->Finish(std::data(response_hash), response_hash.size());
9800 if (tag == TPM_ST_SESSIONS) {
9801 if (!authorization_delegate)
9802 return TRUNKS_RC_AUTHORIZATION_FAILED;
9803 if (!authorization_delegate->CheckResponseAuthorization(
9804 response_hash, authorization_section_bytes)) {
9805 return TRUNKS_RC_AUTHORIZATION_FAILED;
9806 }
9807 }
9808 if (tag == TPM_ST_SESSIONS) {
9809 if (!authorization_delegate)
9810 return TRUNKS_RC_AUTHORIZATION_FAILED;
9811
9812 // Parse the encrypted parameter size.
9813 UINT16 size;
9814 std::string size_buffer = buffer.substr(0, 2);
9815 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9816 return result;
9817 }
9818 if (buffer.size() < 2 + size) {
9819 return TPM_RC_INSUFFICIENT;
9820 }
9821
9822 // Decrypt just the parameter data, not the size.
9823 std::string decrypted_data = buffer.substr(2, size);
9824 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9825 return TRUNKS_RC_ENCRYPTION_FAILED;
9826 }
9827 buffer.replace(2, size, decrypted_data);
9828 }
9829 std::string out_private_bytes;
9830 rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
9831 if (rc != TPM_RC_SUCCESS) {
9832 return rc;
9833 }
9834 std::string out_public_bytes;
9835 rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
9836 if (rc != TPM_RC_SUCCESS) {
9837 return rc;
9838 }
9839 std::string creation_data_bytes;
9840 rc = Parse_TPM2B_CREATION_DATA(&buffer, creation_data, &creation_data_bytes);
9841 if (rc != TPM_RC_SUCCESS) {
9842 return rc;
9843 }
9844 std::string creation_hash_bytes;
9845 rc = Parse_TPM2B_DIGEST(&buffer, creation_hash, &creation_hash_bytes);
9846 if (rc != TPM_RC_SUCCESS) {
9847 return rc;
9848 }
9849 std::string creation_ticket_bytes;
9850 rc = Parse_TPMT_TK_CREATION(&buffer, creation_ticket, &creation_ticket_bytes);
9851 if (rc != TPM_RC_SUCCESS) {
9852 return rc;
9853 }
9854 return TPM_RC_SUCCESS;
9855 }
9856
CreateErrorCallback(Tpm::CreateResponse callback,TPM_RC response_code)9857 void CreateErrorCallback(Tpm::CreateResponse callback, TPM_RC response_code) {
9858 VLOG(1) << __func__;
9859 std::move(callback).Run(response_code, TPM2B_PRIVATE(), TPM2B_PUBLIC(),
9860 TPM2B_CREATION_DATA(), TPM2B_DIGEST(),
9861 TPMT_TK_CREATION());
9862 }
9863
CreateResponseParser(Tpm::CreateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9864 void CreateResponseParser(Tpm::CreateResponse callback,
9865 AuthorizationDelegate* authorization_delegate,
9866 const std::string& response) {
9867 VLOG(1) << __func__;
9868 TPM2B_PRIVATE out_private;
9869 TPM2B_PUBLIC out_public;
9870 TPM2B_CREATION_DATA creation_data;
9871 TPM2B_DIGEST creation_hash;
9872 TPMT_TK_CREATION creation_ticket;
9873 TPM_RC rc = Tpm::ParseResponse_Create(
9874 response, &out_private, &out_public, &creation_data, &creation_hash,
9875 &creation_ticket, authorization_delegate);
9876 if (rc != TPM_RC_SUCCESS) {
9877 base::OnceCallback<void(TPM_RC)> error_reporter =
9878 base::BindOnce(CreateErrorCallback, std::move(callback));
9879 std::move(error_reporter).Run(rc);
9880 return;
9881 }
9882 std::move(callback).Run(rc, out_private, out_public, creation_data,
9883 creation_hash, creation_ticket);
9884 }
9885
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)9886 void Tpm::Create(const TPMI_DH_OBJECT& parent_handle,
9887 const std::string& parent_handle_name,
9888 const TPM2B_SENSITIVE_CREATE& in_sensitive,
9889 const TPM2B_PUBLIC& in_public,
9890 const TPM2B_DATA& outside_info,
9891 const TPML_PCR_SELECTION& creation_pcr,
9892 AuthorizationDelegate* authorization_delegate,
9893 CreateResponse callback) {
9894 VLOG(1) << __func__;
9895 std::string command;
9896 TPM_RC rc = SerializeCommand_Create(
9897 parent_handle, parent_handle_name, in_sensitive, in_public, outside_info,
9898 creation_pcr, &command, authorization_delegate);
9899 if (rc != TPM_RC_SUCCESS) {
9900 base::OnceCallback<void(TPM_RC)> error_reporter =
9901 base::BindOnce(CreateErrorCallback, std::move(callback));
9902 std::move(error_reporter).Run(rc);
9903 return;
9904 }
9905 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9906 CreateResponseParser, std::move(callback), authorization_delegate);
9907 transceiver_->SendCommand(command, std::move(parser));
9908 }
9909
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)9910 TPM_RC Tpm::CreateSync(const TPMI_DH_OBJECT& parent_handle,
9911 const std::string& parent_handle_name,
9912 const TPM2B_SENSITIVE_CREATE& in_sensitive,
9913 const TPM2B_PUBLIC& in_public,
9914 const TPM2B_DATA& outside_info,
9915 const TPML_PCR_SELECTION& creation_pcr,
9916 TPM2B_PRIVATE* out_private,
9917 TPM2B_PUBLIC* out_public,
9918 TPM2B_CREATION_DATA* creation_data,
9919 TPM2B_DIGEST* creation_hash,
9920 TPMT_TK_CREATION* creation_ticket,
9921 AuthorizationDelegate* authorization_delegate) {
9922 VLOG(1) << __func__;
9923 std::string command;
9924 TPM_RC rc = SerializeCommand_Create(
9925 parent_handle, parent_handle_name, in_sensitive, in_public, outside_info,
9926 creation_pcr, &command, authorization_delegate);
9927 if (rc != TPM_RC_SUCCESS) {
9928 return rc;
9929 }
9930 std::string response = transceiver_->SendCommandAndWait(command);
9931 rc = ParseResponse_Create(response, out_private, out_public, creation_data,
9932 creation_hash, creation_ticket,
9933 authorization_delegate);
9934 return rc;
9935 }
9936
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)9937 TPM_RC Tpm::SerializeCommand_Load(
9938 const TPMI_DH_OBJECT& parent_handle,
9939 const std::string& parent_handle_name,
9940 const TPM2B_PRIVATE& in_private,
9941 const TPM2B_PUBLIC& in_public,
9942 std::string* serialized_command,
9943 AuthorizationDelegate* authorization_delegate) {
9944 VLOG(3) << __func__;
9945 TPM_RC rc = TPM_RC_SUCCESS;
9946 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9947 UINT32 command_size = 10; // Header size.
9948 std::string handle_section_bytes;
9949 std::string parameter_section_bytes;
9950 TPM_CC command_code = TPM_CC_Load;
9951 bool is_command_parameter_encryption_possible = true;
9952 bool is_response_parameter_encryption_possible = true;
9953 std::string command_code_bytes;
9954 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9955 if (rc != TPM_RC_SUCCESS) {
9956 return rc;
9957 }
9958 std::string parent_handle_bytes;
9959 rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
9960 if (rc != TPM_RC_SUCCESS) {
9961 return rc;
9962 }
9963 std::string in_private_bytes;
9964 rc = Serialize_TPM2B_PRIVATE(in_private, &in_private_bytes);
9965 if (rc != TPM_RC_SUCCESS) {
9966 return rc;
9967 }
9968 std::string in_public_bytes;
9969 rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
9970 if (rc != TPM_RC_SUCCESS) {
9971 return rc;
9972 }
9973 if (authorization_delegate) {
9974 // Encrypt just the parameter data, not the size.
9975 std::string tmp = in_private_bytes.substr(2);
9976 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9977 return TRUNKS_RC_ENCRYPTION_FAILED;
9978 }
9979 in_private_bytes.replace(2, std::string::npos, tmp);
9980 }
9981 std::unique_ptr<crypto::SecureHash> hash(
9982 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9983 hash->Update(command_code_bytes.data(), command_code_bytes.size());
9984 hash->Update(parent_handle_name.data(), parent_handle_name.size());
9985 handle_section_bytes += parent_handle_bytes;
9986 command_size += parent_handle_bytes.size();
9987 hash->Update(in_private_bytes.data(), in_private_bytes.size());
9988 parameter_section_bytes += in_private_bytes;
9989 command_size += in_private_bytes.size();
9990 hash->Update(in_public_bytes.data(), in_public_bytes.size());
9991 parameter_section_bytes += in_public_bytes;
9992 command_size += in_public_bytes.size();
9993 std::string command_hash(32, 0);
9994 hash->Finish(std::data(command_hash), command_hash.size());
9995 std::string authorization_section_bytes;
9996 std::string authorization_size_bytes;
9997 if (authorization_delegate) {
9998 if (!authorization_delegate->GetCommandAuthorization(
9999 command_hash, is_command_parameter_encryption_possible,
10000 is_response_parameter_encryption_possible,
10001 &authorization_section_bytes)) {
10002 return TRUNKS_RC_AUTHORIZATION_FAILED;
10003 }
10004 if (!authorization_section_bytes.empty()) {
10005 tag = TPM_ST_SESSIONS;
10006 std::string tmp;
10007 rc = Serialize_UINT32(authorization_section_bytes.size(),
10008 &authorization_size_bytes);
10009 if (rc != TPM_RC_SUCCESS) {
10010 return rc;
10011 }
10012 command_size +=
10013 authorization_size_bytes.size() + authorization_section_bytes.size();
10014 }
10015 }
10016 std::string tag_bytes;
10017 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10018 if (rc != TPM_RC_SUCCESS) {
10019 return rc;
10020 }
10021 std::string command_size_bytes;
10022 rc = Serialize_UINT32(command_size, &command_size_bytes);
10023 if (rc != TPM_RC_SUCCESS) {
10024 return rc;
10025 }
10026 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10027 handle_section_bytes + authorization_size_bytes +
10028 authorization_section_bytes + parameter_section_bytes;
10029 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10030 VLOG(2) << "Command: "
10031 << base::HexEncode(serialized_command->data(),
10032 serialized_command->size());
10033 return TPM_RC_SUCCESS;
10034 }
10035
ParseResponse_Load(const std::string & response,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10036 TPM_RC Tpm::ParseResponse_Load(const std::string& response,
10037 TPM_HANDLE* object_handle,
10038 TPM2B_NAME* name,
10039 AuthorizationDelegate* authorization_delegate) {
10040 VLOG(3) << __func__;
10041 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10042 TPM_RC rc = TPM_RC_SUCCESS;
10043 std::string buffer(response);
10044 TPM_ST tag;
10045 std::string tag_bytes;
10046 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10047 if (rc != TPM_RC_SUCCESS) {
10048 return rc;
10049 }
10050 UINT32 response_size;
10051 std::string response_size_bytes;
10052 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10053 if (rc != TPM_RC_SUCCESS) {
10054 return rc;
10055 }
10056 TPM_RC response_code;
10057 std::string response_code_bytes;
10058 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10059 if (rc != TPM_RC_SUCCESS) {
10060 return rc;
10061 }
10062 if (response_size != response.size()) {
10063 return TPM_RC_SIZE;
10064 }
10065 if (response_code != TPM_RC_SUCCESS) {
10066 return response_code;
10067 }
10068 std::string object_handle_bytes;
10069 rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
10070 if (rc != TPM_RC_SUCCESS) {
10071 return rc;
10072 }
10073 TPM_CC command_code = TPM_CC_Load;
10074 std::string command_code_bytes;
10075 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10076 if (rc != TPM_RC_SUCCESS) {
10077 return rc;
10078 }
10079 std::string authorization_section_bytes;
10080 if (tag == TPM_ST_SESSIONS) {
10081 UINT32 parameter_section_size = buffer.size();
10082 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
10083 if (rc != TPM_RC_SUCCESS) {
10084 return rc;
10085 }
10086 if (parameter_section_size > buffer.size()) {
10087 return TPM_RC_INSUFFICIENT;
10088 }
10089 authorization_section_bytes = buffer.substr(parameter_section_size);
10090 // Keep the parameter section in |buffer|.
10091 buffer.erase(parameter_section_size);
10092 }
10093 std::unique_ptr<crypto::SecureHash> hash(
10094 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10095 hash->Update(response_code_bytes.data(), response_code_bytes.size());
10096 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10097 hash->Update(buffer.data(), buffer.size());
10098 std::string response_hash(32, 0);
10099 hash->Finish(std::data(response_hash), response_hash.size());
10100 if (tag == TPM_ST_SESSIONS) {
10101 if (!authorization_delegate)
10102 return TRUNKS_RC_AUTHORIZATION_FAILED;
10103 if (!authorization_delegate->CheckResponseAuthorization(
10104 response_hash, authorization_section_bytes)) {
10105 return TRUNKS_RC_AUTHORIZATION_FAILED;
10106 }
10107 }
10108 if (tag == TPM_ST_SESSIONS) {
10109 if (!authorization_delegate)
10110 return TRUNKS_RC_AUTHORIZATION_FAILED;
10111
10112 // Parse the encrypted parameter size.
10113 UINT16 size;
10114 std::string size_buffer = buffer.substr(0, 2);
10115 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10116 return result;
10117 }
10118 if (buffer.size() < 2 + size) {
10119 return TPM_RC_INSUFFICIENT;
10120 }
10121
10122 // Decrypt just the parameter data, not the size.
10123 std::string decrypted_data = buffer.substr(2, size);
10124 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10125 return TRUNKS_RC_ENCRYPTION_FAILED;
10126 }
10127 buffer.replace(2, size, decrypted_data);
10128 }
10129 std::string name_bytes;
10130 rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10131 if (rc != TPM_RC_SUCCESS) {
10132 return rc;
10133 }
10134 return TPM_RC_SUCCESS;
10135 }
10136
LoadErrorCallback(Tpm::LoadResponse callback,TPM_RC response_code)10137 void LoadErrorCallback(Tpm::LoadResponse callback, TPM_RC response_code) {
10138 VLOG(1) << __func__;
10139 std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_NAME());
10140 }
10141
LoadResponseParser(Tpm::LoadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10142 void LoadResponseParser(Tpm::LoadResponse callback,
10143 AuthorizationDelegate* authorization_delegate,
10144 const std::string& response) {
10145 VLOG(1) << __func__;
10146 TPM_HANDLE object_handle;
10147 TPM2B_NAME name;
10148 TPM_RC rc = Tpm::ParseResponse_Load(response, &object_handle, &name,
10149 authorization_delegate);
10150 if (rc != TPM_RC_SUCCESS) {
10151 base::OnceCallback<void(TPM_RC)> error_reporter =
10152 base::BindOnce(LoadErrorCallback, std::move(callback));
10153 std::move(error_reporter).Run(rc);
10154 return;
10155 }
10156 std::move(callback).Run(rc, object_handle, name);
10157 }
10158
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)10159 void Tpm::Load(const TPMI_DH_OBJECT& parent_handle,
10160 const std::string& parent_handle_name,
10161 const TPM2B_PRIVATE& in_private,
10162 const TPM2B_PUBLIC& in_public,
10163 AuthorizationDelegate* authorization_delegate,
10164 LoadResponse callback) {
10165 VLOG(1) << __func__;
10166 std::string command;
10167 TPM_RC rc =
10168 SerializeCommand_Load(parent_handle, parent_handle_name, in_private,
10169 in_public, &command, authorization_delegate);
10170 if (rc != TPM_RC_SUCCESS) {
10171 base::OnceCallback<void(TPM_RC)> error_reporter =
10172 base::BindOnce(LoadErrorCallback, std::move(callback));
10173 std::move(error_reporter).Run(rc);
10174 return;
10175 }
10176 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10177 LoadResponseParser, std::move(callback), authorization_delegate);
10178 transceiver_->SendCommand(command, std::move(parser));
10179 }
10180
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)10181 TPM_RC Tpm::LoadSync(const TPMI_DH_OBJECT& parent_handle,
10182 const std::string& parent_handle_name,
10183 const TPM2B_PRIVATE& in_private,
10184 const TPM2B_PUBLIC& in_public,
10185 TPM_HANDLE* object_handle,
10186 TPM2B_NAME* name,
10187 AuthorizationDelegate* authorization_delegate) {
10188 VLOG(1) << __func__;
10189 std::string command;
10190 TPM_RC rc =
10191 SerializeCommand_Load(parent_handle, parent_handle_name, in_private,
10192 in_public, &command, authorization_delegate);
10193 if (rc != TPM_RC_SUCCESS) {
10194 return rc;
10195 }
10196 std::string response = transceiver_->SendCommandAndWait(command);
10197 rc =
10198 ParseResponse_Load(response, object_handle, name, authorization_delegate);
10199 return rc;
10200 }
10201
SerializeCommand_LoadExternal(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10202 TPM_RC Tpm::SerializeCommand_LoadExternal(
10203 const TPM2B_SENSITIVE& in_private,
10204 const TPM2B_PUBLIC& in_public,
10205 const TPMI_RH_HIERARCHY& hierarchy,
10206 std::string* serialized_command,
10207 AuthorizationDelegate* authorization_delegate) {
10208 VLOG(3) << __func__;
10209 TPM_RC rc = TPM_RC_SUCCESS;
10210 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10211 UINT32 command_size = 10; // Header size.
10212 std::string handle_section_bytes;
10213 std::string parameter_section_bytes;
10214 TPM_CC command_code = TPM_CC_LoadExternal;
10215 bool is_command_parameter_encryption_possible = true;
10216 bool is_response_parameter_encryption_possible = true;
10217 std::string command_code_bytes;
10218 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10219 if (rc != TPM_RC_SUCCESS) {
10220 return rc;
10221 }
10222 std::string in_private_bytes;
10223 rc = Serialize_TPM2B_SENSITIVE(in_private, &in_private_bytes);
10224 if (rc != TPM_RC_SUCCESS) {
10225 return rc;
10226 }
10227 std::string in_public_bytes;
10228 rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
10229 if (rc != TPM_RC_SUCCESS) {
10230 return rc;
10231 }
10232 std::string hierarchy_bytes;
10233 rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
10234 if (rc != TPM_RC_SUCCESS) {
10235 return rc;
10236 }
10237 if (authorization_delegate) {
10238 // Encrypt just the parameter data, not the size.
10239 std::string tmp = in_private_bytes.substr(2);
10240 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10241 return TRUNKS_RC_ENCRYPTION_FAILED;
10242 }
10243 in_private_bytes.replace(2, std::string::npos, tmp);
10244 }
10245 std::unique_ptr<crypto::SecureHash> hash(
10246 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10247 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10248 hash->Update(in_private_bytes.data(), in_private_bytes.size());
10249 parameter_section_bytes += in_private_bytes;
10250 command_size += in_private_bytes.size();
10251 hash->Update(in_public_bytes.data(), in_public_bytes.size());
10252 parameter_section_bytes += in_public_bytes;
10253 command_size += in_public_bytes.size();
10254 hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
10255 parameter_section_bytes += hierarchy_bytes;
10256 command_size += hierarchy_bytes.size();
10257 std::string command_hash(32, 0);
10258 hash->Finish(std::data(command_hash), command_hash.size());
10259 std::string authorization_section_bytes;
10260 std::string authorization_size_bytes;
10261 if (authorization_delegate) {
10262 if (!authorization_delegate->GetCommandAuthorization(
10263 command_hash, is_command_parameter_encryption_possible,
10264 is_response_parameter_encryption_possible,
10265 &authorization_section_bytes)) {
10266 return TRUNKS_RC_AUTHORIZATION_FAILED;
10267 }
10268 if (!authorization_section_bytes.empty()) {
10269 tag = TPM_ST_SESSIONS;
10270 std::string tmp;
10271 rc = Serialize_UINT32(authorization_section_bytes.size(),
10272 &authorization_size_bytes);
10273 if (rc != TPM_RC_SUCCESS) {
10274 return rc;
10275 }
10276 command_size +=
10277 authorization_size_bytes.size() + authorization_section_bytes.size();
10278 }
10279 }
10280 std::string tag_bytes;
10281 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10282 if (rc != TPM_RC_SUCCESS) {
10283 return rc;
10284 }
10285 std::string command_size_bytes;
10286 rc = Serialize_UINT32(command_size, &command_size_bytes);
10287 if (rc != TPM_RC_SUCCESS) {
10288 return rc;
10289 }
10290 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10291 handle_section_bytes + authorization_size_bytes +
10292 authorization_section_bytes + parameter_section_bytes;
10293 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10294 VLOG(2) << "Command: "
10295 << base::HexEncode(serialized_command->data(),
10296 serialized_command->size());
10297 return TPM_RC_SUCCESS;
10298 }
10299
ParseResponse_LoadExternal(const std::string & response,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10300 TPM_RC Tpm::ParseResponse_LoadExternal(
10301 const std::string& response,
10302 TPM_HANDLE* object_handle,
10303 TPM2B_NAME* name,
10304 AuthorizationDelegate* authorization_delegate) {
10305 VLOG(3) << __func__;
10306 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10307 TPM_RC rc = TPM_RC_SUCCESS;
10308 std::string buffer(response);
10309 TPM_ST tag;
10310 std::string tag_bytes;
10311 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10312 if (rc != TPM_RC_SUCCESS) {
10313 return rc;
10314 }
10315 UINT32 response_size;
10316 std::string response_size_bytes;
10317 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10318 if (rc != TPM_RC_SUCCESS) {
10319 return rc;
10320 }
10321 TPM_RC response_code;
10322 std::string response_code_bytes;
10323 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10324 if (rc != TPM_RC_SUCCESS) {
10325 return rc;
10326 }
10327 if (response_size != response.size()) {
10328 return TPM_RC_SIZE;
10329 }
10330 if (response_code != TPM_RC_SUCCESS) {
10331 return response_code;
10332 }
10333 std::string object_handle_bytes;
10334 rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
10335 if (rc != TPM_RC_SUCCESS) {
10336 return rc;
10337 }
10338 TPM_CC command_code = TPM_CC_LoadExternal;
10339 std::string command_code_bytes;
10340 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10341 if (rc != TPM_RC_SUCCESS) {
10342 return rc;
10343 }
10344 std::string authorization_section_bytes;
10345 if (tag == TPM_ST_SESSIONS) {
10346 UINT32 parameter_section_size = buffer.size();
10347 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
10348 if (rc != TPM_RC_SUCCESS) {
10349 return rc;
10350 }
10351 if (parameter_section_size > buffer.size()) {
10352 return TPM_RC_INSUFFICIENT;
10353 }
10354 authorization_section_bytes = buffer.substr(parameter_section_size);
10355 // Keep the parameter section in |buffer|.
10356 buffer.erase(parameter_section_size);
10357 }
10358 std::unique_ptr<crypto::SecureHash> hash(
10359 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10360 hash->Update(response_code_bytes.data(), response_code_bytes.size());
10361 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10362 hash->Update(buffer.data(), buffer.size());
10363 std::string response_hash(32, 0);
10364 hash->Finish(std::data(response_hash), response_hash.size());
10365 if (tag == TPM_ST_SESSIONS) {
10366 if (!authorization_delegate)
10367 return TRUNKS_RC_AUTHORIZATION_FAILED;
10368 if (!authorization_delegate->CheckResponseAuthorization(
10369 response_hash, authorization_section_bytes)) {
10370 return TRUNKS_RC_AUTHORIZATION_FAILED;
10371 }
10372 }
10373 if (tag == TPM_ST_SESSIONS) {
10374 if (!authorization_delegate)
10375 return TRUNKS_RC_AUTHORIZATION_FAILED;
10376
10377 // Parse the encrypted parameter size.
10378 UINT16 size;
10379 std::string size_buffer = buffer.substr(0, 2);
10380 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10381 return result;
10382 }
10383 if (buffer.size() < 2 + size) {
10384 return TPM_RC_INSUFFICIENT;
10385 }
10386
10387 // Decrypt just the parameter data, not the size.
10388 std::string decrypted_data = buffer.substr(2, size);
10389 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10390 return TRUNKS_RC_ENCRYPTION_FAILED;
10391 }
10392 buffer.replace(2, size, decrypted_data);
10393 }
10394 std::string name_bytes;
10395 rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10396 if (rc != TPM_RC_SUCCESS) {
10397 return rc;
10398 }
10399 return TPM_RC_SUCCESS;
10400 }
10401
LoadExternalErrorCallback(Tpm::LoadExternalResponse callback,TPM_RC response_code)10402 void LoadExternalErrorCallback(Tpm::LoadExternalResponse callback,
10403 TPM_RC response_code) {
10404 VLOG(1) << __func__;
10405 std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_NAME());
10406 }
10407
LoadExternalResponseParser(Tpm::LoadExternalResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10408 void LoadExternalResponseParser(Tpm::LoadExternalResponse callback,
10409 AuthorizationDelegate* authorization_delegate,
10410 const std::string& response) {
10411 VLOG(1) << __func__;
10412 TPM_HANDLE object_handle;
10413 TPM2B_NAME name;
10414 TPM_RC rc = Tpm::ParseResponse_LoadExternal(response, &object_handle, &name,
10415 authorization_delegate);
10416 if (rc != TPM_RC_SUCCESS) {
10417 base::OnceCallback<void(TPM_RC)> error_reporter =
10418 base::BindOnce(LoadExternalErrorCallback, std::move(callback));
10419 std::move(error_reporter).Run(rc);
10420 return;
10421 }
10422 std::move(callback).Run(rc, object_handle, name);
10423 }
10424
LoadExternal(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,LoadExternalResponse callback)10425 void Tpm::LoadExternal(const TPM2B_SENSITIVE& in_private,
10426 const TPM2B_PUBLIC& in_public,
10427 const TPMI_RH_HIERARCHY& hierarchy,
10428 AuthorizationDelegate* authorization_delegate,
10429 LoadExternalResponse callback) {
10430 VLOG(1) << __func__;
10431 std::string command;
10432 TPM_RC rc = SerializeCommand_LoadExternal(in_private, in_public, hierarchy,
10433 &command, authorization_delegate);
10434 if (rc != TPM_RC_SUCCESS) {
10435 base::OnceCallback<void(TPM_RC)> error_reporter =
10436 base::BindOnce(LoadExternalErrorCallback, std::move(callback));
10437 std::move(error_reporter).Run(rc);
10438 return;
10439 }
10440 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10441 LoadExternalResponseParser, std::move(callback), authorization_delegate);
10442 transceiver_->SendCommand(command, std::move(parser));
10443 }
10444
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)10445 TPM_RC Tpm::LoadExternalSync(const TPM2B_SENSITIVE& in_private,
10446 const TPM2B_PUBLIC& in_public,
10447 const TPMI_RH_HIERARCHY& hierarchy,
10448 TPM_HANDLE* object_handle,
10449 TPM2B_NAME* name,
10450 AuthorizationDelegate* authorization_delegate) {
10451 VLOG(1) << __func__;
10452 std::string command;
10453 TPM_RC rc = SerializeCommand_LoadExternal(in_private, in_public, hierarchy,
10454 &command, authorization_delegate);
10455 if (rc != TPM_RC_SUCCESS) {
10456 return rc;
10457 }
10458 std::string response = transceiver_->SendCommandAndWait(command);
10459 rc = ParseResponse_LoadExternal(response, object_handle, name,
10460 authorization_delegate);
10461 return rc;
10462 }
10463
SerializeCommand_ReadPublic(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10464 TPM_RC Tpm::SerializeCommand_ReadPublic(
10465 const TPMI_DH_OBJECT& object_handle,
10466 const std::string& object_handle_name,
10467 std::string* serialized_command,
10468 AuthorizationDelegate* authorization_delegate) {
10469 VLOG(3) << __func__;
10470 TPM_RC rc = TPM_RC_SUCCESS;
10471 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10472 UINT32 command_size = 10; // Header size.
10473 std::string handle_section_bytes;
10474 std::string parameter_section_bytes;
10475 TPM_CC command_code = TPM_CC_ReadPublic;
10476 bool is_command_parameter_encryption_possible = false;
10477 bool is_response_parameter_encryption_possible = true;
10478 std::string command_code_bytes;
10479 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10480 if (rc != TPM_RC_SUCCESS) {
10481 return rc;
10482 }
10483 std::string object_handle_bytes;
10484 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
10485 if (rc != TPM_RC_SUCCESS) {
10486 return rc;
10487 }
10488 std::unique_ptr<crypto::SecureHash> hash(
10489 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10490 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10491 hash->Update(object_handle_name.data(), object_handle_name.size());
10492 handle_section_bytes += object_handle_bytes;
10493 command_size += object_handle_bytes.size();
10494 std::string command_hash(32, 0);
10495 hash->Finish(std::data(command_hash), command_hash.size());
10496 std::string authorization_section_bytes;
10497 std::string authorization_size_bytes;
10498 if (authorization_delegate) {
10499 if (!authorization_delegate->GetCommandAuthorization(
10500 command_hash, is_command_parameter_encryption_possible,
10501 is_response_parameter_encryption_possible,
10502 &authorization_section_bytes)) {
10503 return TRUNKS_RC_AUTHORIZATION_FAILED;
10504 }
10505 if (!authorization_section_bytes.empty()) {
10506 tag = TPM_ST_SESSIONS;
10507 std::string tmp;
10508 rc = Serialize_UINT32(authorization_section_bytes.size(),
10509 &authorization_size_bytes);
10510 if (rc != TPM_RC_SUCCESS) {
10511 return rc;
10512 }
10513 command_size +=
10514 authorization_size_bytes.size() + authorization_section_bytes.size();
10515 }
10516 }
10517 std::string tag_bytes;
10518 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10519 if (rc != TPM_RC_SUCCESS) {
10520 return rc;
10521 }
10522 std::string command_size_bytes;
10523 rc = Serialize_UINT32(command_size, &command_size_bytes);
10524 if (rc != TPM_RC_SUCCESS) {
10525 return rc;
10526 }
10527 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10528 handle_section_bytes + authorization_size_bytes +
10529 authorization_section_bytes + parameter_section_bytes;
10530 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10531 VLOG(2) << "Command: "
10532 << base::HexEncode(serialized_command->data(),
10533 serialized_command->size());
10534 return TPM_RC_SUCCESS;
10535 }
10536
ParseResponse_ReadPublic(const std::string & response,TPM2B_PUBLIC * out_public,TPM2B_NAME * name,TPM2B_NAME * qualified_name,AuthorizationDelegate * authorization_delegate)10537 TPM_RC Tpm::ParseResponse_ReadPublic(
10538 const std::string& response,
10539 TPM2B_PUBLIC* out_public,
10540 TPM2B_NAME* name,
10541 TPM2B_NAME* qualified_name,
10542 AuthorizationDelegate* authorization_delegate) {
10543 VLOG(3) << __func__;
10544 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10545 TPM_RC rc = TPM_RC_SUCCESS;
10546 std::string buffer(response);
10547 TPM_ST tag;
10548 std::string tag_bytes;
10549 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10550 if (rc != TPM_RC_SUCCESS) {
10551 return rc;
10552 }
10553 UINT32 response_size;
10554 std::string response_size_bytes;
10555 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10556 if (rc != TPM_RC_SUCCESS) {
10557 return rc;
10558 }
10559 TPM_RC response_code;
10560 std::string response_code_bytes;
10561 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10562 if (rc != TPM_RC_SUCCESS) {
10563 return rc;
10564 }
10565 if (response_size != response.size()) {
10566 return TPM_RC_SIZE;
10567 }
10568 if (response_code != TPM_RC_SUCCESS) {
10569 return response_code;
10570 }
10571 TPM_CC command_code = TPM_CC_ReadPublic;
10572 std::string command_code_bytes;
10573 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10574 if (rc != TPM_RC_SUCCESS) {
10575 return rc;
10576 }
10577 std::string authorization_section_bytes;
10578 if (tag == TPM_ST_SESSIONS) {
10579 UINT32 parameter_section_size = buffer.size();
10580 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
10581 if (rc != TPM_RC_SUCCESS) {
10582 return rc;
10583 }
10584 if (parameter_section_size > buffer.size()) {
10585 return TPM_RC_INSUFFICIENT;
10586 }
10587 authorization_section_bytes = buffer.substr(parameter_section_size);
10588 // Keep the parameter section in |buffer|.
10589 buffer.erase(parameter_section_size);
10590 }
10591 std::unique_ptr<crypto::SecureHash> hash(
10592 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10593 hash->Update(response_code_bytes.data(), response_code_bytes.size());
10594 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10595 hash->Update(buffer.data(), buffer.size());
10596 std::string response_hash(32, 0);
10597 hash->Finish(std::data(response_hash), response_hash.size());
10598 if (tag == TPM_ST_SESSIONS) {
10599 if (!authorization_delegate)
10600 return TRUNKS_RC_AUTHORIZATION_FAILED;
10601 if (!authorization_delegate->CheckResponseAuthorization(
10602 response_hash, authorization_section_bytes)) {
10603 return TRUNKS_RC_AUTHORIZATION_FAILED;
10604 }
10605 }
10606 if (tag == TPM_ST_SESSIONS) {
10607 if (!authorization_delegate)
10608 return TRUNKS_RC_AUTHORIZATION_FAILED;
10609
10610 // Parse the encrypted parameter size.
10611 UINT16 size;
10612 std::string size_buffer = buffer.substr(0, 2);
10613 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10614 return result;
10615 }
10616 if (buffer.size() < 2 + size) {
10617 return TPM_RC_INSUFFICIENT;
10618 }
10619
10620 // Decrypt just the parameter data, not the size.
10621 std::string decrypted_data = buffer.substr(2, size);
10622 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10623 return TRUNKS_RC_ENCRYPTION_FAILED;
10624 }
10625 buffer.replace(2, size, decrypted_data);
10626 }
10627 std::string out_public_bytes;
10628 rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
10629 if (rc != TPM_RC_SUCCESS) {
10630 return rc;
10631 }
10632 std::string name_bytes;
10633 rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10634 if (rc != TPM_RC_SUCCESS) {
10635 return rc;
10636 }
10637 std::string qualified_name_bytes;
10638 rc = Parse_TPM2B_NAME(&buffer, qualified_name, &qualified_name_bytes);
10639 if (rc != TPM_RC_SUCCESS) {
10640 return rc;
10641 }
10642 return TPM_RC_SUCCESS;
10643 }
10644
ReadPublicErrorCallback(Tpm::ReadPublicResponse callback,TPM_RC response_code)10645 void ReadPublicErrorCallback(Tpm::ReadPublicResponse callback,
10646 TPM_RC response_code) {
10647 VLOG(1) << __func__;
10648 std::move(callback).Run(response_code, TPM2B_PUBLIC(), TPM2B_NAME(),
10649 TPM2B_NAME());
10650 }
10651
ReadPublicResponseParser(Tpm::ReadPublicResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10652 void ReadPublicResponseParser(Tpm::ReadPublicResponse callback,
10653 AuthorizationDelegate* authorization_delegate,
10654 const std::string& response) {
10655 VLOG(1) << __func__;
10656 TPM2B_PUBLIC out_public;
10657 TPM2B_NAME name;
10658 TPM2B_NAME qualified_name;
10659 TPM_RC rc = Tpm::ParseResponse_ReadPublic(
10660 response, &out_public, &name, &qualified_name, authorization_delegate);
10661 if (rc != TPM_RC_SUCCESS) {
10662 base::OnceCallback<void(TPM_RC)> error_reporter =
10663 base::BindOnce(ReadPublicErrorCallback, std::move(callback));
10664 std::move(error_reporter).Run(rc);
10665 return;
10666 }
10667 std::move(callback).Run(rc, out_public, name, qualified_name);
10668 }
10669
ReadPublic(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,AuthorizationDelegate * authorization_delegate,ReadPublicResponse callback)10670 void Tpm::ReadPublic(const TPMI_DH_OBJECT& object_handle,
10671 const std::string& object_handle_name,
10672 AuthorizationDelegate* authorization_delegate,
10673 ReadPublicResponse callback) {
10674 VLOG(1) << __func__;
10675 std::string command;
10676 TPM_RC rc = SerializeCommand_ReadPublic(object_handle, object_handle_name,
10677 &command, authorization_delegate);
10678 if (rc != TPM_RC_SUCCESS) {
10679 base::OnceCallback<void(TPM_RC)> error_reporter =
10680 base::BindOnce(ReadPublicErrorCallback, std::move(callback));
10681 std::move(error_reporter).Run(rc);
10682 return;
10683 }
10684 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10685 ReadPublicResponseParser, std::move(callback), authorization_delegate);
10686 transceiver_->SendCommand(command, std::move(parser));
10687 }
10688
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)10689 TPM_RC Tpm::ReadPublicSync(const TPMI_DH_OBJECT& object_handle,
10690 const std::string& object_handle_name,
10691 TPM2B_PUBLIC* out_public,
10692 TPM2B_NAME* name,
10693 TPM2B_NAME* qualified_name,
10694 AuthorizationDelegate* authorization_delegate) {
10695 VLOG(1) << __func__;
10696 std::string command;
10697 TPM_RC rc = SerializeCommand_ReadPublic(object_handle, object_handle_name,
10698 &command, authorization_delegate);
10699 if (rc != TPM_RC_SUCCESS) {
10700 return rc;
10701 }
10702 std::string response = transceiver_->SendCommandAndWait(command);
10703 rc = ParseResponse_ReadPublic(response, out_public, name, qualified_name,
10704 authorization_delegate);
10705 return rc;
10706 }
10707
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)10708 TPM_RC Tpm::SerializeCommand_ActivateCredential(
10709 const TPMI_DH_OBJECT& activate_handle,
10710 const std::string& activate_handle_name,
10711 const TPMI_DH_OBJECT& key_handle,
10712 const std::string& key_handle_name,
10713 const TPM2B_ID_OBJECT& credential_blob,
10714 const TPM2B_ENCRYPTED_SECRET& secret,
10715 std::string* serialized_command,
10716 AuthorizationDelegate* authorization_delegate) {
10717 VLOG(3) << __func__;
10718 TPM_RC rc = TPM_RC_SUCCESS;
10719 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10720 UINT32 command_size = 10; // Header size.
10721 std::string handle_section_bytes;
10722 std::string parameter_section_bytes;
10723 TPM_CC command_code = TPM_CC_ActivateCredential;
10724 bool is_command_parameter_encryption_possible = true;
10725 bool is_response_parameter_encryption_possible = true;
10726 std::string command_code_bytes;
10727 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10728 if (rc != TPM_RC_SUCCESS) {
10729 return rc;
10730 }
10731 std::string activate_handle_bytes;
10732 rc = Serialize_TPMI_DH_OBJECT(activate_handle, &activate_handle_bytes);
10733 if (rc != TPM_RC_SUCCESS) {
10734 return rc;
10735 }
10736 std::string key_handle_bytes;
10737 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
10738 if (rc != TPM_RC_SUCCESS) {
10739 return rc;
10740 }
10741 std::string credential_blob_bytes;
10742 rc = Serialize_TPM2B_ID_OBJECT(credential_blob, &credential_blob_bytes);
10743 if (rc != TPM_RC_SUCCESS) {
10744 return rc;
10745 }
10746 std::string secret_bytes;
10747 rc = Serialize_TPM2B_ENCRYPTED_SECRET(secret, &secret_bytes);
10748 if (rc != TPM_RC_SUCCESS) {
10749 return rc;
10750 }
10751 if (authorization_delegate) {
10752 // Encrypt just the parameter data, not the size.
10753 std::string tmp = credential_blob_bytes.substr(2);
10754 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10755 return TRUNKS_RC_ENCRYPTION_FAILED;
10756 }
10757 credential_blob_bytes.replace(2, std::string::npos, tmp);
10758 }
10759 std::unique_ptr<crypto::SecureHash> hash(
10760 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10761 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10762 hash->Update(activate_handle_name.data(), activate_handle_name.size());
10763 handle_section_bytes += activate_handle_bytes;
10764 command_size += activate_handle_bytes.size();
10765 hash->Update(key_handle_name.data(), key_handle_name.size());
10766 handle_section_bytes += key_handle_bytes;
10767 command_size += key_handle_bytes.size();
10768 hash->Update(credential_blob_bytes.data(), credential_blob_bytes.size());
10769 parameter_section_bytes += credential_blob_bytes;
10770 command_size += credential_blob_bytes.size();
10771 hash->Update(secret_bytes.data(), secret_bytes.size());
10772 parameter_section_bytes += secret_bytes;
10773 command_size += secret_bytes.size();
10774 std::string command_hash(32, 0);
10775 hash->Finish(std::data(command_hash), command_hash.size());
10776 std::string authorization_section_bytes;
10777 std::string authorization_size_bytes;
10778 if (authorization_delegate) {
10779 if (!authorization_delegate->GetCommandAuthorization(
10780 command_hash, is_command_parameter_encryption_possible,
10781 is_response_parameter_encryption_possible,
10782 &authorization_section_bytes)) {
10783 return TRUNKS_RC_AUTHORIZATION_FAILED;
10784 }
10785 if (!authorization_section_bytes.empty()) {
10786 tag = TPM_ST_SESSIONS;
10787 std::string tmp;
10788 rc = Serialize_UINT32(authorization_section_bytes.size(),
10789 &authorization_size_bytes);
10790 if (rc != TPM_RC_SUCCESS) {
10791 return rc;
10792 }
10793 command_size +=
10794 authorization_size_bytes.size() + authorization_section_bytes.size();
10795 }
10796 }
10797 std::string tag_bytes;
10798 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10799 if (rc != TPM_RC_SUCCESS) {
10800 return rc;
10801 }
10802 std::string command_size_bytes;
10803 rc = Serialize_UINT32(command_size, &command_size_bytes);
10804 if (rc != TPM_RC_SUCCESS) {
10805 return rc;
10806 }
10807 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10808 handle_section_bytes + authorization_size_bytes +
10809 authorization_section_bytes + parameter_section_bytes;
10810 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10811 VLOG(2) << "Command: "
10812 << base::HexEncode(serialized_command->data(),
10813 serialized_command->size());
10814 return TPM_RC_SUCCESS;
10815 }
10816
ParseResponse_ActivateCredential(const std::string & response,TPM2B_DIGEST * cert_info,AuthorizationDelegate * authorization_delegate)10817 TPM_RC Tpm::ParseResponse_ActivateCredential(
10818 const std::string& response,
10819 TPM2B_DIGEST* cert_info,
10820 AuthorizationDelegate* authorization_delegate) {
10821 VLOG(3) << __func__;
10822 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10823 TPM_RC rc = TPM_RC_SUCCESS;
10824 std::string buffer(response);
10825 TPM_ST tag;
10826 std::string tag_bytes;
10827 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10828 if (rc != TPM_RC_SUCCESS) {
10829 return rc;
10830 }
10831 UINT32 response_size;
10832 std::string response_size_bytes;
10833 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10834 if (rc != TPM_RC_SUCCESS) {
10835 return rc;
10836 }
10837 TPM_RC response_code;
10838 std::string response_code_bytes;
10839 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10840 if (rc != TPM_RC_SUCCESS) {
10841 return rc;
10842 }
10843 if (response_size != response.size()) {
10844 return TPM_RC_SIZE;
10845 }
10846 if (response_code != TPM_RC_SUCCESS) {
10847 return response_code;
10848 }
10849 TPM_CC command_code = TPM_CC_ActivateCredential;
10850 std::string command_code_bytes;
10851 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10852 if (rc != TPM_RC_SUCCESS) {
10853 return rc;
10854 }
10855 std::string authorization_section_bytes;
10856 if (tag == TPM_ST_SESSIONS) {
10857 UINT32 parameter_section_size = buffer.size();
10858 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
10859 if (rc != TPM_RC_SUCCESS) {
10860 return rc;
10861 }
10862 if (parameter_section_size > buffer.size()) {
10863 return TPM_RC_INSUFFICIENT;
10864 }
10865 authorization_section_bytes = buffer.substr(parameter_section_size);
10866 // Keep the parameter section in |buffer|.
10867 buffer.erase(parameter_section_size);
10868 }
10869 std::unique_ptr<crypto::SecureHash> hash(
10870 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10871 hash->Update(response_code_bytes.data(), response_code_bytes.size());
10872 hash->Update(command_code_bytes.data(), command_code_bytes.size());
10873 hash->Update(buffer.data(), buffer.size());
10874 std::string response_hash(32, 0);
10875 hash->Finish(std::data(response_hash), response_hash.size());
10876 if (tag == TPM_ST_SESSIONS) {
10877 if (!authorization_delegate)
10878 return TRUNKS_RC_AUTHORIZATION_FAILED;
10879 if (!authorization_delegate->CheckResponseAuthorization(
10880 response_hash, authorization_section_bytes)) {
10881 return TRUNKS_RC_AUTHORIZATION_FAILED;
10882 }
10883 }
10884 if (tag == TPM_ST_SESSIONS) {
10885 if (!authorization_delegate)
10886 return TRUNKS_RC_AUTHORIZATION_FAILED;
10887
10888 // Parse the encrypted parameter size.
10889 UINT16 size;
10890 std::string size_buffer = buffer.substr(0, 2);
10891 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10892 return result;
10893 }
10894 if (buffer.size() < 2 + size) {
10895 return TPM_RC_INSUFFICIENT;
10896 }
10897
10898 // Decrypt just the parameter data, not the size.
10899 std::string decrypted_data = buffer.substr(2, size);
10900 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10901 return TRUNKS_RC_ENCRYPTION_FAILED;
10902 }
10903 buffer.replace(2, size, decrypted_data);
10904 }
10905 std::string cert_info_bytes;
10906 rc = Parse_TPM2B_DIGEST(&buffer, cert_info, &cert_info_bytes);
10907 if (rc != TPM_RC_SUCCESS) {
10908 return rc;
10909 }
10910 return TPM_RC_SUCCESS;
10911 }
10912
ActivateCredentialErrorCallback(Tpm::ActivateCredentialResponse callback,TPM_RC response_code)10913 void ActivateCredentialErrorCallback(Tpm::ActivateCredentialResponse callback,
10914 TPM_RC response_code) {
10915 VLOG(1) << __func__;
10916 std::move(callback).Run(response_code, TPM2B_DIGEST());
10917 }
10918
ActivateCredentialResponseParser(Tpm::ActivateCredentialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10919 void ActivateCredentialResponseParser(
10920 Tpm::ActivateCredentialResponse callback,
10921 AuthorizationDelegate* authorization_delegate,
10922 const std::string& response) {
10923 VLOG(1) << __func__;
10924 TPM2B_DIGEST cert_info;
10925 TPM_RC rc = Tpm::ParseResponse_ActivateCredential(response, &cert_info,
10926 authorization_delegate);
10927 if (rc != TPM_RC_SUCCESS) {
10928 base::OnceCallback<void(TPM_RC)> error_reporter =
10929 base::BindOnce(ActivateCredentialErrorCallback, std::move(callback));
10930 std::move(error_reporter).Run(rc);
10931 return;
10932 }
10933 std::move(callback).Run(rc, cert_info);
10934 }
10935
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)10936 void Tpm::ActivateCredential(const TPMI_DH_OBJECT& activate_handle,
10937 const std::string& activate_handle_name,
10938 const TPMI_DH_OBJECT& key_handle,
10939 const std::string& key_handle_name,
10940 const TPM2B_ID_OBJECT& credential_blob,
10941 const TPM2B_ENCRYPTED_SECRET& secret,
10942 AuthorizationDelegate* authorization_delegate,
10943 ActivateCredentialResponse callback) {
10944 VLOG(1) << __func__;
10945 std::string command;
10946 TPM_RC rc = SerializeCommand_ActivateCredential(
10947 activate_handle, activate_handle_name, key_handle, key_handle_name,
10948 credential_blob, secret, &command, authorization_delegate);
10949 if (rc != TPM_RC_SUCCESS) {
10950 base::OnceCallback<void(TPM_RC)> error_reporter =
10951 base::BindOnce(ActivateCredentialErrorCallback, std::move(callback));
10952 std::move(error_reporter).Run(rc);
10953 return;
10954 }
10955 base::OnceCallback<void(const std::string&)> parser =
10956 base::BindOnce(ActivateCredentialResponseParser, std::move(callback),
10957 authorization_delegate);
10958 transceiver_->SendCommand(command, std::move(parser));
10959 }
10960
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)10961 TPM_RC Tpm::ActivateCredentialSync(
10962 const TPMI_DH_OBJECT& activate_handle,
10963 const std::string& activate_handle_name,
10964 const TPMI_DH_OBJECT& key_handle,
10965 const std::string& key_handle_name,
10966 const TPM2B_ID_OBJECT& credential_blob,
10967 const TPM2B_ENCRYPTED_SECRET& secret,
10968 TPM2B_DIGEST* cert_info,
10969 AuthorizationDelegate* authorization_delegate) {
10970 VLOG(1) << __func__;
10971 std::string command;
10972 TPM_RC rc = SerializeCommand_ActivateCredential(
10973 activate_handle, activate_handle_name, key_handle, key_handle_name,
10974 credential_blob, secret, &command, authorization_delegate);
10975 if (rc != TPM_RC_SUCCESS) {
10976 return rc;
10977 }
10978 std::string response = transceiver_->SendCommandAndWait(command);
10979 rc = ParseResponse_ActivateCredential(response, cert_info,
10980 authorization_delegate);
10981 return rc;
10982 }
10983
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)10984 TPM_RC Tpm::SerializeCommand_MakeCredential(
10985 const TPMI_DH_OBJECT& handle,
10986 const std::string& handle_name,
10987 const TPM2B_DIGEST& credential,
10988 const TPM2B_NAME& object_name,
10989 std::string* serialized_command,
10990 AuthorizationDelegate* authorization_delegate) {
10991 VLOG(3) << __func__;
10992 TPM_RC rc = TPM_RC_SUCCESS;
10993 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10994 UINT32 command_size = 10; // Header size.
10995 std::string handle_section_bytes;
10996 std::string parameter_section_bytes;
10997 TPM_CC command_code = TPM_CC_MakeCredential;
10998 bool is_command_parameter_encryption_possible = true;
10999 bool is_response_parameter_encryption_possible = true;
11000 std::string command_code_bytes;
11001 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11002 if (rc != TPM_RC_SUCCESS) {
11003 return rc;
11004 }
11005 std::string handle_bytes;
11006 rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
11007 if (rc != TPM_RC_SUCCESS) {
11008 return rc;
11009 }
11010 std::string credential_bytes;
11011 rc = Serialize_TPM2B_DIGEST(credential, &credential_bytes);
11012 if (rc != TPM_RC_SUCCESS) {
11013 return rc;
11014 }
11015 std::string object_name_bytes;
11016 rc = Serialize_TPM2B_NAME(object_name, &object_name_bytes);
11017 if (rc != TPM_RC_SUCCESS) {
11018 return rc;
11019 }
11020 if (authorization_delegate) {
11021 // Encrypt just the parameter data, not the size.
11022 std::string tmp = credential_bytes.substr(2);
11023 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11024 return TRUNKS_RC_ENCRYPTION_FAILED;
11025 }
11026 credential_bytes.replace(2, std::string::npos, tmp);
11027 }
11028 std::unique_ptr<crypto::SecureHash> hash(
11029 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11030 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11031 hash->Update(handle_name.data(), handle_name.size());
11032 handle_section_bytes += handle_bytes;
11033 command_size += handle_bytes.size();
11034 hash->Update(credential_bytes.data(), credential_bytes.size());
11035 parameter_section_bytes += credential_bytes;
11036 command_size += credential_bytes.size();
11037 hash->Update(object_name_bytes.data(), object_name_bytes.size());
11038 parameter_section_bytes += object_name_bytes;
11039 command_size += object_name_bytes.size();
11040 std::string command_hash(32, 0);
11041 hash->Finish(std::data(command_hash), command_hash.size());
11042 std::string authorization_section_bytes;
11043 std::string authorization_size_bytes;
11044 if (authorization_delegate) {
11045 if (!authorization_delegate->GetCommandAuthorization(
11046 command_hash, is_command_parameter_encryption_possible,
11047 is_response_parameter_encryption_possible,
11048 &authorization_section_bytes)) {
11049 return TRUNKS_RC_AUTHORIZATION_FAILED;
11050 }
11051 if (!authorization_section_bytes.empty()) {
11052 tag = TPM_ST_SESSIONS;
11053 std::string tmp;
11054 rc = Serialize_UINT32(authorization_section_bytes.size(),
11055 &authorization_size_bytes);
11056 if (rc != TPM_RC_SUCCESS) {
11057 return rc;
11058 }
11059 command_size +=
11060 authorization_size_bytes.size() + authorization_section_bytes.size();
11061 }
11062 }
11063 std::string tag_bytes;
11064 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11065 if (rc != TPM_RC_SUCCESS) {
11066 return rc;
11067 }
11068 std::string command_size_bytes;
11069 rc = Serialize_UINT32(command_size, &command_size_bytes);
11070 if (rc != TPM_RC_SUCCESS) {
11071 return rc;
11072 }
11073 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11074 handle_section_bytes + authorization_size_bytes +
11075 authorization_section_bytes + parameter_section_bytes;
11076 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11077 VLOG(2) << "Command: "
11078 << base::HexEncode(serialized_command->data(),
11079 serialized_command->size());
11080 return TPM_RC_SUCCESS;
11081 }
11082
ParseResponse_MakeCredential(const std::string & response,TPM2B_ID_OBJECT * credential_blob,TPM2B_ENCRYPTED_SECRET * secret,AuthorizationDelegate * authorization_delegate)11083 TPM_RC Tpm::ParseResponse_MakeCredential(
11084 const std::string& response,
11085 TPM2B_ID_OBJECT* credential_blob,
11086 TPM2B_ENCRYPTED_SECRET* secret,
11087 AuthorizationDelegate* authorization_delegate) {
11088 VLOG(3) << __func__;
11089 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11090 TPM_RC rc = TPM_RC_SUCCESS;
11091 std::string buffer(response);
11092 TPM_ST tag;
11093 std::string tag_bytes;
11094 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11095 if (rc != TPM_RC_SUCCESS) {
11096 return rc;
11097 }
11098 UINT32 response_size;
11099 std::string response_size_bytes;
11100 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11101 if (rc != TPM_RC_SUCCESS) {
11102 return rc;
11103 }
11104 TPM_RC response_code;
11105 std::string response_code_bytes;
11106 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11107 if (rc != TPM_RC_SUCCESS) {
11108 return rc;
11109 }
11110 if (response_size != response.size()) {
11111 return TPM_RC_SIZE;
11112 }
11113 if (response_code != TPM_RC_SUCCESS) {
11114 return response_code;
11115 }
11116 TPM_CC command_code = TPM_CC_MakeCredential;
11117 std::string command_code_bytes;
11118 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11119 if (rc != TPM_RC_SUCCESS) {
11120 return rc;
11121 }
11122 std::string authorization_section_bytes;
11123 if (tag == TPM_ST_SESSIONS) {
11124 UINT32 parameter_section_size = buffer.size();
11125 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
11126 if (rc != TPM_RC_SUCCESS) {
11127 return rc;
11128 }
11129 if (parameter_section_size > buffer.size()) {
11130 return TPM_RC_INSUFFICIENT;
11131 }
11132 authorization_section_bytes = buffer.substr(parameter_section_size);
11133 // Keep the parameter section in |buffer|.
11134 buffer.erase(parameter_section_size);
11135 }
11136 std::unique_ptr<crypto::SecureHash> hash(
11137 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11138 hash->Update(response_code_bytes.data(), response_code_bytes.size());
11139 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11140 hash->Update(buffer.data(), buffer.size());
11141 std::string response_hash(32, 0);
11142 hash->Finish(std::data(response_hash), response_hash.size());
11143 if (tag == TPM_ST_SESSIONS) {
11144 if (!authorization_delegate)
11145 return TRUNKS_RC_AUTHORIZATION_FAILED;
11146 if (!authorization_delegate->CheckResponseAuthorization(
11147 response_hash, authorization_section_bytes)) {
11148 return TRUNKS_RC_AUTHORIZATION_FAILED;
11149 }
11150 }
11151 if (tag == TPM_ST_SESSIONS) {
11152 if (!authorization_delegate)
11153 return TRUNKS_RC_AUTHORIZATION_FAILED;
11154
11155 // Parse the encrypted parameter size.
11156 UINT16 size;
11157 std::string size_buffer = buffer.substr(0, 2);
11158 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11159 return result;
11160 }
11161 if (buffer.size() < 2 + size) {
11162 return TPM_RC_INSUFFICIENT;
11163 }
11164
11165 // Decrypt just the parameter data, not the size.
11166 std::string decrypted_data = buffer.substr(2, size);
11167 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11168 return TRUNKS_RC_ENCRYPTION_FAILED;
11169 }
11170 buffer.replace(2, size, decrypted_data);
11171 }
11172 std::string credential_blob_bytes;
11173 rc = Parse_TPM2B_ID_OBJECT(&buffer, credential_blob, &credential_blob_bytes);
11174 if (rc != TPM_RC_SUCCESS) {
11175 return rc;
11176 }
11177 std::string secret_bytes;
11178 rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, secret, &secret_bytes);
11179 if (rc != TPM_RC_SUCCESS) {
11180 return rc;
11181 }
11182 return TPM_RC_SUCCESS;
11183 }
11184
MakeCredentialErrorCallback(Tpm::MakeCredentialResponse callback,TPM_RC response_code)11185 void MakeCredentialErrorCallback(Tpm::MakeCredentialResponse callback,
11186 TPM_RC response_code) {
11187 VLOG(1) << __func__;
11188 std::move(callback).Run(response_code, TPM2B_ID_OBJECT(),
11189 TPM2B_ENCRYPTED_SECRET());
11190 }
11191
MakeCredentialResponseParser(Tpm::MakeCredentialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11192 void MakeCredentialResponseParser(Tpm::MakeCredentialResponse callback,
11193 AuthorizationDelegate* authorization_delegate,
11194 const std::string& response) {
11195 VLOG(1) << __func__;
11196 TPM2B_ID_OBJECT credential_blob;
11197 TPM2B_ENCRYPTED_SECRET secret;
11198 TPM_RC rc = Tpm::ParseResponse_MakeCredential(
11199 response, &credential_blob, &secret, authorization_delegate);
11200 if (rc != TPM_RC_SUCCESS) {
11201 base::OnceCallback<void(TPM_RC)> error_reporter =
11202 base::BindOnce(MakeCredentialErrorCallback, std::move(callback));
11203 std::move(error_reporter).Run(rc);
11204 return;
11205 }
11206 std::move(callback).Run(rc, credential_blob, secret);
11207 }
11208
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)11209 void Tpm::MakeCredential(const TPMI_DH_OBJECT& handle,
11210 const std::string& handle_name,
11211 const TPM2B_DIGEST& credential,
11212 const TPM2B_NAME& object_name,
11213 AuthorizationDelegate* authorization_delegate,
11214 MakeCredentialResponse callback) {
11215 VLOG(1) << __func__;
11216 std::string command;
11217 TPM_RC rc = SerializeCommand_MakeCredential(handle, handle_name, credential,
11218 object_name, &command,
11219 authorization_delegate);
11220 if (rc != TPM_RC_SUCCESS) {
11221 base::OnceCallback<void(TPM_RC)> error_reporter =
11222 base::BindOnce(MakeCredentialErrorCallback, std::move(callback));
11223 std::move(error_reporter).Run(rc);
11224 return;
11225 }
11226 base::OnceCallback<void(const std::string&)> parser =
11227 base::BindOnce(MakeCredentialResponseParser, std::move(callback),
11228 authorization_delegate);
11229 transceiver_->SendCommand(command, std::move(parser));
11230 }
11231
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)11232 TPM_RC Tpm::MakeCredentialSync(const TPMI_DH_OBJECT& handle,
11233 const std::string& handle_name,
11234 const TPM2B_DIGEST& credential,
11235 const TPM2B_NAME& object_name,
11236 TPM2B_ID_OBJECT* credential_blob,
11237 TPM2B_ENCRYPTED_SECRET* secret,
11238 AuthorizationDelegate* authorization_delegate) {
11239 VLOG(1) << __func__;
11240 std::string command;
11241 TPM_RC rc = SerializeCommand_MakeCredential(handle, handle_name, credential,
11242 object_name, &command,
11243 authorization_delegate);
11244 if (rc != TPM_RC_SUCCESS) {
11245 return rc;
11246 }
11247 std::string response = transceiver_->SendCommandAndWait(command);
11248 rc = ParseResponse_MakeCredential(response, credential_blob, secret,
11249 authorization_delegate);
11250 return rc;
11251 }
11252
SerializeCommand_Unseal(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)11253 TPM_RC Tpm::SerializeCommand_Unseal(
11254 const TPMI_DH_OBJECT& item_handle,
11255 const std::string& item_handle_name,
11256 std::string* serialized_command,
11257 AuthorizationDelegate* authorization_delegate) {
11258 VLOG(3) << __func__;
11259 TPM_RC rc = TPM_RC_SUCCESS;
11260 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11261 UINT32 command_size = 10; // Header size.
11262 std::string handle_section_bytes;
11263 std::string parameter_section_bytes;
11264 TPM_CC command_code = TPM_CC_Unseal;
11265 bool is_command_parameter_encryption_possible = false;
11266 bool is_response_parameter_encryption_possible = true;
11267 std::string command_code_bytes;
11268 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11269 if (rc != TPM_RC_SUCCESS) {
11270 return rc;
11271 }
11272 std::string item_handle_bytes;
11273 rc = Serialize_TPMI_DH_OBJECT(item_handle, &item_handle_bytes);
11274 if (rc != TPM_RC_SUCCESS) {
11275 return rc;
11276 }
11277 std::unique_ptr<crypto::SecureHash> hash(
11278 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11279 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11280 hash->Update(item_handle_name.data(), item_handle_name.size());
11281 handle_section_bytes += item_handle_bytes;
11282 command_size += item_handle_bytes.size();
11283 std::string command_hash(32, 0);
11284 hash->Finish(std::data(command_hash), command_hash.size());
11285 std::string authorization_section_bytes;
11286 std::string authorization_size_bytes;
11287 if (authorization_delegate) {
11288 if (!authorization_delegate->GetCommandAuthorization(
11289 command_hash, is_command_parameter_encryption_possible,
11290 is_response_parameter_encryption_possible,
11291 &authorization_section_bytes)) {
11292 return TRUNKS_RC_AUTHORIZATION_FAILED;
11293 }
11294 if (!authorization_section_bytes.empty()) {
11295 tag = TPM_ST_SESSIONS;
11296 std::string tmp;
11297 rc = Serialize_UINT32(authorization_section_bytes.size(),
11298 &authorization_size_bytes);
11299 if (rc != TPM_RC_SUCCESS) {
11300 return rc;
11301 }
11302 command_size +=
11303 authorization_size_bytes.size() + authorization_section_bytes.size();
11304 }
11305 }
11306 std::string tag_bytes;
11307 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11308 if (rc != TPM_RC_SUCCESS) {
11309 return rc;
11310 }
11311 std::string command_size_bytes;
11312 rc = Serialize_UINT32(command_size, &command_size_bytes);
11313 if (rc != TPM_RC_SUCCESS) {
11314 return rc;
11315 }
11316 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11317 handle_section_bytes + authorization_size_bytes +
11318 authorization_section_bytes + parameter_section_bytes;
11319 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11320 VLOG(2) << "Command: "
11321 << base::HexEncode(serialized_command->data(),
11322 serialized_command->size());
11323 return TPM_RC_SUCCESS;
11324 }
11325
ParseResponse_Unseal(const std::string & response,TPM2B_SENSITIVE_DATA * out_data,AuthorizationDelegate * authorization_delegate)11326 TPM_RC Tpm::ParseResponse_Unseal(
11327 const std::string& response,
11328 TPM2B_SENSITIVE_DATA* out_data,
11329 AuthorizationDelegate* authorization_delegate) {
11330 VLOG(3) << __func__;
11331 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11332 TPM_RC rc = TPM_RC_SUCCESS;
11333 std::string buffer(response);
11334 TPM_ST tag;
11335 std::string tag_bytes;
11336 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11337 if (rc != TPM_RC_SUCCESS) {
11338 return rc;
11339 }
11340 UINT32 response_size;
11341 std::string response_size_bytes;
11342 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11343 if (rc != TPM_RC_SUCCESS) {
11344 return rc;
11345 }
11346 TPM_RC response_code;
11347 std::string response_code_bytes;
11348 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11349 if (rc != TPM_RC_SUCCESS) {
11350 return rc;
11351 }
11352 if (response_size != response.size()) {
11353 return TPM_RC_SIZE;
11354 }
11355 if (response_code != TPM_RC_SUCCESS) {
11356 return response_code;
11357 }
11358 TPM_CC command_code = TPM_CC_Unseal;
11359 std::string command_code_bytes;
11360 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11361 if (rc != TPM_RC_SUCCESS) {
11362 return rc;
11363 }
11364 std::string authorization_section_bytes;
11365 if (tag == TPM_ST_SESSIONS) {
11366 UINT32 parameter_section_size = buffer.size();
11367 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
11368 if (rc != TPM_RC_SUCCESS) {
11369 return rc;
11370 }
11371 if (parameter_section_size > buffer.size()) {
11372 return TPM_RC_INSUFFICIENT;
11373 }
11374 authorization_section_bytes = buffer.substr(parameter_section_size);
11375 // Keep the parameter section in |buffer|.
11376 buffer.erase(parameter_section_size);
11377 }
11378 std::unique_ptr<crypto::SecureHash> hash(
11379 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11380 hash->Update(response_code_bytes.data(), response_code_bytes.size());
11381 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11382 hash->Update(buffer.data(), buffer.size());
11383 std::string response_hash(32, 0);
11384 hash->Finish(std::data(response_hash), response_hash.size());
11385 if (tag == TPM_ST_SESSIONS) {
11386 if (!authorization_delegate)
11387 return TRUNKS_RC_AUTHORIZATION_FAILED;
11388 if (!authorization_delegate->CheckResponseAuthorization(
11389 response_hash, authorization_section_bytes)) {
11390 return TRUNKS_RC_AUTHORIZATION_FAILED;
11391 }
11392 }
11393 if (tag == TPM_ST_SESSIONS) {
11394 if (!authorization_delegate)
11395 return TRUNKS_RC_AUTHORIZATION_FAILED;
11396
11397 // Parse the encrypted parameter size.
11398 UINT16 size;
11399 std::string size_buffer = buffer.substr(0, 2);
11400 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11401 return result;
11402 }
11403 if (buffer.size() < 2 + size) {
11404 return TPM_RC_INSUFFICIENT;
11405 }
11406
11407 // Decrypt just the parameter data, not the size.
11408 std::string decrypted_data = buffer.substr(2, size);
11409 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11410 return TRUNKS_RC_ENCRYPTION_FAILED;
11411 }
11412 buffer.replace(2, size, decrypted_data);
11413 }
11414 std::string out_data_bytes;
11415 rc = Parse_TPM2B_SENSITIVE_DATA(&buffer, out_data, &out_data_bytes);
11416 if (rc != TPM_RC_SUCCESS) {
11417 return rc;
11418 }
11419 return TPM_RC_SUCCESS;
11420 }
11421
UnsealErrorCallback(Tpm::UnsealResponse callback,TPM_RC response_code)11422 void UnsealErrorCallback(Tpm::UnsealResponse callback, TPM_RC response_code) {
11423 VLOG(1) << __func__;
11424 std::move(callback).Run(response_code, TPM2B_SENSITIVE_DATA());
11425 }
11426
UnsealResponseParser(Tpm::UnsealResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11427 void UnsealResponseParser(Tpm::UnsealResponse callback,
11428 AuthorizationDelegate* authorization_delegate,
11429 const std::string& response) {
11430 VLOG(1) << __func__;
11431 TPM2B_SENSITIVE_DATA out_data;
11432 TPM_RC rc =
11433 Tpm::ParseResponse_Unseal(response, &out_data, authorization_delegate);
11434 if (rc != TPM_RC_SUCCESS) {
11435 base::OnceCallback<void(TPM_RC)> error_reporter =
11436 base::BindOnce(UnsealErrorCallback, std::move(callback));
11437 std::move(error_reporter).Run(rc);
11438 return;
11439 }
11440 std::move(callback).Run(rc, out_data);
11441 }
11442
Unseal(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,AuthorizationDelegate * authorization_delegate,UnsealResponse callback)11443 void Tpm::Unseal(const TPMI_DH_OBJECT& item_handle,
11444 const std::string& item_handle_name,
11445 AuthorizationDelegate* authorization_delegate,
11446 UnsealResponse callback) {
11447 VLOG(1) << __func__;
11448 std::string command;
11449 TPM_RC rc = SerializeCommand_Unseal(item_handle, item_handle_name, &command,
11450 authorization_delegate);
11451 if (rc != TPM_RC_SUCCESS) {
11452 base::OnceCallback<void(TPM_RC)> error_reporter =
11453 base::BindOnce(UnsealErrorCallback, std::move(callback));
11454 std::move(error_reporter).Run(rc);
11455 return;
11456 }
11457 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
11458 UnsealResponseParser, std::move(callback), authorization_delegate);
11459 transceiver_->SendCommand(command, std::move(parser));
11460 }
11461
UnsealSync(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,TPM2B_SENSITIVE_DATA * out_data,AuthorizationDelegate * authorization_delegate)11462 TPM_RC Tpm::UnsealSync(const TPMI_DH_OBJECT& item_handle,
11463 const std::string& item_handle_name,
11464 TPM2B_SENSITIVE_DATA* out_data,
11465 AuthorizationDelegate* authorization_delegate) {
11466 VLOG(1) << __func__;
11467 std::string command;
11468 TPM_RC rc = SerializeCommand_Unseal(item_handle, item_handle_name, &command,
11469 authorization_delegate);
11470 if (rc != TPM_RC_SUCCESS) {
11471 return rc;
11472 }
11473 std::string response = transceiver_->SendCommandAndWait(command);
11474 rc = ParseResponse_Unseal(response, out_data, authorization_delegate);
11475 return rc;
11476 }
11477
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)11478 TPM_RC Tpm::SerializeCommand_ObjectChangeAuth(
11479 const TPMI_DH_OBJECT& object_handle,
11480 const std::string& object_handle_name,
11481 const TPMI_DH_OBJECT& parent_handle,
11482 const std::string& parent_handle_name,
11483 const TPM2B_AUTH& new_auth,
11484 std::string* serialized_command,
11485 AuthorizationDelegate* authorization_delegate) {
11486 VLOG(3) << __func__;
11487 TPM_RC rc = TPM_RC_SUCCESS;
11488 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11489 UINT32 command_size = 10; // Header size.
11490 std::string handle_section_bytes;
11491 std::string parameter_section_bytes;
11492 TPM_CC command_code = TPM_CC_ObjectChangeAuth;
11493 bool is_command_parameter_encryption_possible = true;
11494 bool is_response_parameter_encryption_possible = true;
11495 std::string command_code_bytes;
11496 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11497 if (rc != TPM_RC_SUCCESS) {
11498 return rc;
11499 }
11500 std::string object_handle_bytes;
11501 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
11502 if (rc != TPM_RC_SUCCESS) {
11503 return rc;
11504 }
11505 std::string parent_handle_bytes;
11506 rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
11507 if (rc != TPM_RC_SUCCESS) {
11508 return rc;
11509 }
11510 std::string new_auth_bytes;
11511 rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
11512 if (rc != TPM_RC_SUCCESS) {
11513 return rc;
11514 }
11515 if (authorization_delegate) {
11516 // Encrypt just the parameter data, not the size.
11517 std::string tmp = new_auth_bytes.substr(2);
11518 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11519 return TRUNKS_RC_ENCRYPTION_FAILED;
11520 }
11521 new_auth_bytes.replace(2, std::string::npos, tmp);
11522 }
11523 std::unique_ptr<crypto::SecureHash> hash(
11524 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11525 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11526 hash->Update(object_handle_name.data(), object_handle_name.size());
11527 handle_section_bytes += object_handle_bytes;
11528 command_size += object_handle_bytes.size();
11529 hash->Update(parent_handle_name.data(), parent_handle_name.size());
11530 handle_section_bytes += parent_handle_bytes;
11531 command_size += parent_handle_bytes.size();
11532 hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
11533 parameter_section_bytes += new_auth_bytes;
11534 command_size += new_auth_bytes.size();
11535 std::string command_hash(32, 0);
11536 hash->Finish(std::data(command_hash), command_hash.size());
11537 std::string authorization_section_bytes;
11538 std::string authorization_size_bytes;
11539 if (authorization_delegate) {
11540 if (!authorization_delegate->GetCommandAuthorization(
11541 command_hash, is_command_parameter_encryption_possible,
11542 is_response_parameter_encryption_possible,
11543 &authorization_section_bytes)) {
11544 return TRUNKS_RC_AUTHORIZATION_FAILED;
11545 }
11546 if (!authorization_section_bytes.empty()) {
11547 tag = TPM_ST_SESSIONS;
11548 std::string tmp;
11549 rc = Serialize_UINT32(authorization_section_bytes.size(),
11550 &authorization_size_bytes);
11551 if (rc != TPM_RC_SUCCESS) {
11552 return rc;
11553 }
11554 command_size +=
11555 authorization_size_bytes.size() + authorization_section_bytes.size();
11556 }
11557 }
11558 std::string tag_bytes;
11559 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11560 if (rc != TPM_RC_SUCCESS) {
11561 return rc;
11562 }
11563 std::string command_size_bytes;
11564 rc = Serialize_UINT32(command_size, &command_size_bytes);
11565 if (rc != TPM_RC_SUCCESS) {
11566 return rc;
11567 }
11568 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11569 handle_section_bytes + authorization_size_bytes +
11570 authorization_section_bytes + parameter_section_bytes;
11571 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11572 VLOG(2) << "Command: "
11573 << base::HexEncode(serialized_command->data(),
11574 serialized_command->size());
11575 return TPM_RC_SUCCESS;
11576 }
11577
ParseResponse_ObjectChangeAuth(const std::string & response,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)11578 TPM_RC Tpm::ParseResponse_ObjectChangeAuth(
11579 const std::string& response,
11580 TPM2B_PRIVATE* out_private,
11581 AuthorizationDelegate* authorization_delegate) {
11582 VLOG(3) << __func__;
11583 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11584 TPM_RC rc = TPM_RC_SUCCESS;
11585 std::string buffer(response);
11586 TPM_ST tag;
11587 std::string tag_bytes;
11588 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11589 if (rc != TPM_RC_SUCCESS) {
11590 return rc;
11591 }
11592 UINT32 response_size;
11593 std::string response_size_bytes;
11594 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11595 if (rc != TPM_RC_SUCCESS) {
11596 return rc;
11597 }
11598 TPM_RC response_code;
11599 std::string response_code_bytes;
11600 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11601 if (rc != TPM_RC_SUCCESS) {
11602 return rc;
11603 }
11604 if (response_size != response.size()) {
11605 return TPM_RC_SIZE;
11606 }
11607 if (response_code != TPM_RC_SUCCESS) {
11608 return response_code;
11609 }
11610 TPM_CC command_code = TPM_CC_ObjectChangeAuth;
11611 std::string command_code_bytes;
11612 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11613 if (rc != TPM_RC_SUCCESS) {
11614 return rc;
11615 }
11616 std::string authorization_section_bytes;
11617 if (tag == TPM_ST_SESSIONS) {
11618 UINT32 parameter_section_size = buffer.size();
11619 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
11620 if (rc != TPM_RC_SUCCESS) {
11621 return rc;
11622 }
11623 if (parameter_section_size > buffer.size()) {
11624 return TPM_RC_INSUFFICIENT;
11625 }
11626 authorization_section_bytes = buffer.substr(parameter_section_size);
11627 // Keep the parameter section in |buffer|.
11628 buffer.erase(parameter_section_size);
11629 }
11630 std::unique_ptr<crypto::SecureHash> hash(
11631 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11632 hash->Update(response_code_bytes.data(), response_code_bytes.size());
11633 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11634 hash->Update(buffer.data(), buffer.size());
11635 std::string response_hash(32, 0);
11636 hash->Finish(std::data(response_hash), response_hash.size());
11637 if (tag == TPM_ST_SESSIONS) {
11638 if (!authorization_delegate)
11639 return TRUNKS_RC_AUTHORIZATION_FAILED;
11640 if (!authorization_delegate->CheckResponseAuthorization(
11641 response_hash, authorization_section_bytes)) {
11642 return TRUNKS_RC_AUTHORIZATION_FAILED;
11643 }
11644 }
11645 if (tag == TPM_ST_SESSIONS) {
11646 if (!authorization_delegate)
11647 return TRUNKS_RC_AUTHORIZATION_FAILED;
11648
11649 // Parse the encrypted parameter size.
11650 UINT16 size;
11651 std::string size_buffer = buffer.substr(0, 2);
11652 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11653 return result;
11654 }
11655 if (buffer.size() < 2 + size) {
11656 return TPM_RC_INSUFFICIENT;
11657 }
11658
11659 // Decrypt just the parameter data, not the size.
11660 std::string decrypted_data = buffer.substr(2, size);
11661 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11662 return TRUNKS_RC_ENCRYPTION_FAILED;
11663 }
11664 buffer.replace(2, size, decrypted_data);
11665 }
11666 std::string out_private_bytes;
11667 rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
11668 if (rc != TPM_RC_SUCCESS) {
11669 return rc;
11670 }
11671 return TPM_RC_SUCCESS;
11672 }
11673
ObjectChangeAuthErrorCallback(Tpm::ObjectChangeAuthResponse callback,TPM_RC response_code)11674 void ObjectChangeAuthErrorCallback(Tpm::ObjectChangeAuthResponse callback,
11675 TPM_RC response_code) {
11676 VLOG(1) << __func__;
11677 std::move(callback).Run(response_code, TPM2B_PRIVATE());
11678 }
11679
ObjectChangeAuthResponseParser(Tpm::ObjectChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11680 void ObjectChangeAuthResponseParser(
11681 Tpm::ObjectChangeAuthResponse callback,
11682 AuthorizationDelegate* authorization_delegate,
11683 const std::string& response) {
11684 VLOG(1) << __func__;
11685 TPM2B_PRIVATE out_private;
11686 TPM_RC rc = Tpm::ParseResponse_ObjectChangeAuth(response, &out_private,
11687 authorization_delegate);
11688 if (rc != TPM_RC_SUCCESS) {
11689 base::OnceCallback<void(TPM_RC)> error_reporter =
11690 base::BindOnce(ObjectChangeAuthErrorCallback, std::move(callback));
11691 std::move(error_reporter).Run(rc);
11692 return;
11693 }
11694 std::move(callback).Run(rc, out_private);
11695 }
11696
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)11697 void Tpm::ObjectChangeAuth(const TPMI_DH_OBJECT& object_handle,
11698 const std::string& object_handle_name,
11699 const TPMI_DH_OBJECT& parent_handle,
11700 const std::string& parent_handle_name,
11701 const TPM2B_AUTH& new_auth,
11702 AuthorizationDelegate* authorization_delegate,
11703 ObjectChangeAuthResponse callback) {
11704 VLOG(1) << __func__;
11705 std::string command;
11706 TPM_RC rc = SerializeCommand_ObjectChangeAuth(
11707 object_handle, object_handle_name, parent_handle, parent_handle_name,
11708 new_auth, &command, authorization_delegate);
11709 if (rc != TPM_RC_SUCCESS) {
11710 base::OnceCallback<void(TPM_RC)> error_reporter =
11711 base::BindOnce(ObjectChangeAuthErrorCallback, std::move(callback));
11712 std::move(error_reporter).Run(rc);
11713 return;
11714 }
11715 base::OnceCallback<void(const std::string&)> parser =
11716 base::BindOnce(ObjectChangeAuthResponseParser, std::move(callback),
11717 authorization_delegate);
11718 transceiver_->SendCommand(command, std::move(parser));
11719 }
11720
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)11721 TPM_RC Tpm::ObjectChangeAuthSync(
11722 const TPMI_DH_OBJECT& object_handle,
11723 const std::string& object_handle_name,
11724 const TPMI_DH_OBJECT& parent_handle,
11725 const std::string& parent_handle_name,
11726 const TPM2B_AUTH& new_auth,
11727 TPM2B_PRIVATE* out_private,
11728 AuthorizationDelegate* authorization_delegate) {
11729 VLOG(1) << __func__;
11730 std::string command;
11731 TPM_RC rc = SerializeCommand_ObjectChangeAuth(
11732 object_handle, object_handle_name, parent_handle, parent_handle_name,
11733 new_auth, &command, authorization_delegate);
11734 if (rc != TPM_RC_SUCCESS) {
11735 return rc;
11736 }
11737 std::string response = transceiver_->SendCommandAndWait(command);
11738 rc = ParseResponse_ObjectChangeAuth(response, out_private,
11739 authorization_delegate);
11740 return rc;
11741 }
11742
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)11743 TPM_RC Tpm::SerializeCommand_Duplicate(
11744 const TPMI_DH_OBJECT& object_handle,
11745 const std::string& object_handle_name,
11746 const TPMI_DH_OBJECT& new_parent_handle,
11747 const std::string& new_parent_handle_name,
11748 const TPM2B_DATA& encryption_key_in,
11749 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11750 std::string* serialized_command,
11751 AuthorizationDelegate* authorization_delegate) {
11752 VLOG(3) << __func__;
11753 TPM_RC rc = TPM_RC_SUCCESS;
11754 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11755 UINT32 command_size = 10; // Header size.
11756 std::string handle_section_bytes;
11757 std::string parameter_section_bytes;
11758 TPM_CC command_code = TPM_CC_Duplicate;
11759 bool is_command_parameter_encryption_possible = true;
11760 bool is_response_parameter_encryption_possible = true;
11761 std::string command_code_bytes;
11762 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11763 if (rc != TPM_RC_SUCCESS) {
11764 return rc;
11765 }
11766 std::string object_handle_bytes;
11767 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
11768 if (rc != TPM_RC_SUCCESS) {
11769 return rc;
11770 }
11771 std::string new_parent_handle_bytes;
11772 rc = Serialize_TPMI_DH_OBJECT(new_parent_handle, &new_parent_handle_bytes);
11773 if (rc != TPM_RC_SUCCESS) {
11774 return rc;
11775 }
11776 std::string encryption_key_in_bytes;
11777 rc = Serialize_TPM2B_DATA(encryption_key_in, &encryption_key_in_bytes);
11778 if (rc != TPM_RC_SUCCESS) {
11779 return rc;
11780 }
11781 std::string symmetric_alg_bytes;
11782 rc = Serialize_TPMT_SYM_DEF_OBJECT(symmetric_alg, &symmetric_alg_bytes);
11783 if (rc != TPM_RC_SUCCESS) {
11784 return rc;
11785 }
11786 if (authorization_delegate) {
11787 // Encrypt just the parameter data, not the size.
11788 std::string tmp = encryption_key_in_bytes.substr(2);
11789 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11790 return TRUNKS_RC_ENCRYPTION_FAILED;
11791 }
11792 encryption_key_in_bytes.replace(2, std::string::npos, tmp);
11793 }
11794 std::unique_ptr<crypto::SecureHash> hash(
11795 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11796 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11797 hash->Update(object_handle_name.data(), object_handle_name.size());
11798 handle_section_bytes += object_handle_bytes;
11799 command_size += object_handle_bytes.size();
11800 hash->Update(new_parent_handle_name.data(), new_parent_handle_name.size());
11801 handle_section_bytes += new_parent_handle_bytes;
11802 command_size += new_parent_handle_bytes.size();
11803 hash->Update(encryption_key_in_bytes.data(), encryption_key_in_bytes.size());
11804 parameter_section_bytes += encryption_key_in_bytes;
11805 command_size += encryption_key_in_bytes.size();
11806 hash->Update(symmetric_alg_bytes.data(), symmetric_alg_bytes.size());
11807 parameter_section_bytes += symmetric_alg_bytes;
11808 command_size += symmetric_alg_bytes.size();
11809 std::string command_hash(32, 0);
11810 hash->Finish(std::data(command_hash), command_hash.size());
11811 std::string authorization_section_bytes;
11812 std::string authorization_size_bytes;
11813 if (authorization_delegate) {
11814 if (!authorization_delegate->GetCommandAuthorization(
11815 command_hash, is_command_parameter_encryption_possible,
11816 is_response_parameter_encryption_possible,
11817 &authorization_section_bytes)) {
11818 return TRUNKS_RC_AUTHORIZATION_FAILED;
11819 }
11820 if (!authorization_section_bytes.empty()) {
11821 tag = TPM_ST_SESSIONS;
11822 std::string tmp;
11823 rc = Serialize_UINT32(authorization_section_bytes.size(),
11824 &authorization_size_bytes);
11825 if (rc != TPM_RC_SUCCESS) {
11826 return rc;
11827 }
11828 command_size +=
11829 authorization_size_bytes.size() + authorization_section_bytes.size();
11830 }
11831 }
11832 std::string tag_bytes;
11833 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11834 if (rc != TPM_RC_SUCCESS) {
11835 return rc;
11836 }
11837 std::string command_size_bytes;
11838 rc = Serialize_UINT32(command_size, &command_size_bytes);
11839 if (rc != TPM_RC_SUCCESS) {
11840 return rc;
11841 }
11842 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11843 handle_section_bytes + authorization_size_bytes +
11844 authorization_section_bytes + parameter_section_bytes;
11845 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11846 VLOG(2) << "Command: "
11847 << base::HexEncode(serialized_command->data(),
11848 serialized_command->size());
11849 return TPM_RC_SUCCESS;
11850 }
11851
ParseResponse_Duplicate(const std::string & response,TPM2B_DATA * encryption_key_out,TPM2B_PRIVATE * duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)11852 TPM_RC Tpm::ParseResponse_Duplicate(
11853 const std::string& response,
11854 TPM2B_DATA* encryption_key_out,
11855 TPM2B_PRIVATE* duplicate,
11856 TPM2B_ENCRYPTED_SECRET* out_sym_seed,
11857 AuthorizationDelegate* authorization_delegate) {
11858 VLOG(3) << __func__;
11859 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11860 TPM_RC rc = TPM_RC_SUCCESS;
11861 std::string buffer(response);
11862 TPM_ST tag;
11863 std::string tag_bytes;
11864 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11865 if (rc != TPM_RC_SUCCESS) {
11866 return rc;
11867 }
11868 UINT32 response_size;
11869 std::string response_size_bytes;
11870 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11871 if (rc != TPM_RC_SUCCESS) {
11872 return rc;
11873 }
11874 TPM_RC response_code;
11875 std::string response_code_bytes;
11876 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11877 if (rc != TPM_RC_SUCCESS) {
11878 return rc;
11879 }
11880 if (response_size != response.size()) {
11881 return TPM_RC_SIZE;
11882 }
11883 if (response_code != TPM_RC_SUCCESS) {
11884 return response_code;
11885 }
11886 TPM_CC command_code = TPM_CC_Duplicate;
11887 std::string command_code_bytes;
11888 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11889 if (rc != TPM_RC_SUCCESS) {
11890 return rc;
11891 }
11892 std::string authorization_section_bytes;
11893 if (tag == TPM_ST_SESSIONS) {
11894 UINT32 parameter_section_size = buffer.size();
11895 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
11896 if (rc != TPM_RC_SUCCESS) {
11897 return rc;
11898 }
11899 if (parameter_section_size > buffer.size()) {
11900 return TPM_RC_INSUFFICIENT;
11901 }
11902 authorization_section_bytes = buffer.substr(parameter_section_size);
11903 // Keep the parameter section in |buffer|.
11904 buffer.erase(parameter_section_size);
11905 }
11906 std::unique_ptr<crypto::SecureHash> hash(
11907 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11908 hash->Update(response_code_bytes.data(), response_code_bytes.size());
11909 hash->Update(command_code_bytes.data(), command_code_bytes.size());
11910 hash->Update(buffer.data(), buffer.size());
11911 std::string response_hash(32, 0);
11912 hash->Finish(std::data(response_hash), response_hash.size());
11913 if (tag == TPM_ST_SESSIONS) {
11914 if (!authorization_delegate)
11915 return TRUNKS_RC_AUTHORIZATION_FAILED;
11916 if (!authorization_delegate->CheckResponseAuthorization(
11917 response_hash, authorization_section_bytes)) {
11918 return TRUNKS_RC_AUTHORIZATION_FAILED;
11919 }
11920 }
11921 if (tag == TPM_ST_SESSIONS) {
11922 if (!authorization_delegate)
11923 return TRUNKS_RC_AUTHORIZATION_FAILED;
11924
11925 // Parse the encrypted parameter size.
11926 UINT16 size;
11927 std::string size_buffer = buffer.substr(0, 2);
11928 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11929 return result;
11930 }
11931 if (buffer.size() < 2 + size) {
11932 return TPM_RC_INSUFFICIENT;
11933 }
11934
11935 // Decrypt just the parameter data, not the size.
11936 std::string decrypted_data = buffer.substr(2, size);
11937 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11938 return TRUNKS_RC_ENCRYPTION_FAILED;
11939 }
11940 buffer.replace(2, size, decrypted_data);
11941 }
11942 std::string encryption_key_out_bytes;
11943 rc = Parse_TPM2B_DATA(&buffer, encryption_key_out, &encryption_key_out_bytes);
11944 if (rc != TPM_RC_SUCCESS) {
11945 return rc;
11946 }
11947 std::string duplicate_bytes;
11948 rc = Parse_TPM2B_PRIVATE(&buffer, duplicate, &duplicate_bytes);
11949 if (rc != TPM_RC_SUCCESS) {
11950 return rc;
11951 }
11952 std::string out_sym_seed_bytes;
11953 rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, out_sym_seed, &out_sym_seed_bytes);
11954 if (rc != TPM_RC_SUCCESS) {
11955 return rc;
11956 }
11957 return TPM_RC_SUCCESS;
11958 }
11959
DuplicateErrorCallback(Tpm::DuplicateResponse callback,TPM_RC response_code)11960 void DuplicateErrorCallback(Tpm::DuplicateResponse callback,
11961 TPM_RC response_code) {
11962 VLOG(1) << __func__;
11963 std::move(callback).Run(response_code, TPM2B_DATA(), TPM2B_PRIVATE(),
11964 TPM2B_ENCRYPTED_SECRET());
11965 }
11966
DuplicateResponseParser(Tpm::DuplicateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11967 void DuplicateResponseParser(Tpm::DuplicateResponse callback,
11968 AuthorizationDelegate* authorization_delegate,
11969 const std::string& response) {
11970 VLOG(1) << __func__;
11971 TPM2B_DATA encryption_key_out;
11972 TPM2B_PRIVATE duplicate;
11973 TPM2B_ENCRYPTED_SECRET out_sym_seed;
11974 TPM_RC rc =
11975 Tpm::ParseResponse_Duplicate(response, &encryption_key_out, &duplicate,
11976 &out_sym_seed, authorization_delegate);
11977 if (rc != TPM_RC_SUCCESS) {
11978 base::OnceCallback<void(TPM_RC)> error_reporter =
11979 base::BindOnce(DuplicateErrorCallback, std::move(callback));
11980 std::move(error_reporter).Run(rc);
11981 return;
11982 }
11983 std::move(callback).Run(rc, encryption_key_out, duplicate, out_sym_seed);
11984 }
11985
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)11986 void Tpm::Duplicate(const TPMI_DH_OBJECT& object_handle,
11987 const std::string& object_handle_name,
11988 const TPMI_DH_OBJECT& new_parent_handle,
11989 const std::string& new_parent_handle_name,
11990 const TPM2B_DATA& encryption_key_in,
11991 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11992 AuthorizationDelegate* authorization_delegate,
11993 DuplicateResponse callback) {
11994 VLOG(1) << __func__;
11995 std::string command;
11996 TPM_RC rc = SerializeCommand_Duplicate(
11997 object_handle, object_handle_name, new_parent_handle,
11998 new_parent_handle_name, encryption_key_in, symmetric_alg, &command,
11999 authorization_delegate);
12000 if (rc != TPM_RC_SUCCESS) {
12001 base::OnceCallback<void(TPM_RC)> error_reporter =
12002 base::BindOnce(DuplicateErrorCallback, std::move(callback));
12003 std::move(error_reporter).Run(rc);
12004 return;
12005 }
12006 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12007 DuplicateResponseParser, std::move(callback), authorization_delegate);
12008 transceiver_->SendCommand(command, std::move(parser));
12009 }
12010
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)12011 TPM_RC Tpm::DuplicateSync(const TPMI_DH_OBJECT& object_handle,
12012 const std::string& object_handle_name,
12013 const TPMI_DH_OBJECT& new_parent_handle,
12014 const std::string& new_parent_handle_name,
12015 const TPM2B_DATA& encryption_key_in,
12016 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12017 TPM2B_DATA* encryption_key_out,
12018 TPM2B_PRIVATE* duplicate,
12019 TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12020 AuthorizationDelegate* authorization_delegate) {
12021 VLOG(1) << __func__;
12022 std::string command;
12023 TPM_RC rc = SerializeCommand_Duplicate(
12024 object_handle, object_handle_name, new_parent_handle,
12025 new_parent_handle_name, encryption_key_in, symmetric_alg, &command,
12026 authorization_delegate);
12027 if (rc != TPM_RC_SUCCESS) {
12028 return rc;
12029 }
12030 std::string response = transceiver_->SendCommandAndWait(command);
12031 rc = ParseResponse_Duplicate(response, encryption_key_out, duplicate,
12032 out_sym_seed, authorization_delegate);
12033 return rc;
12034 }
12035
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)12036 TPM_RC Tpm::SerializeCommand_Rewrap(
12037 const TPMI_DH_OBJECT& old_parent,
12038 const std::string& old_parent_name,
12039 const TPMI_DH_OBJECT& new_parent,
12040 const std::string& new_parent_name,
12041 const TPM2B_PRIVATE& in_duplicate,
12042 const TPM2B_NAME& name,
12043 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12044 std::string* serialized_command,
12045 AuthorizationDelegate* authorization_delegate) {
12046 VLOG(3) << __func__;
12047 TPM_RC rc = TPM_RC_SUCCESS;
12048 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12049 UINT32 command_size = 10; // Header size.
12050 std::string handle_section_bytes;
12051 std::string parameter_section_bytes;
12052 TPM_CC command_code = TPM_CC_Rewrap;
12053 bool is_command_parameter_encryption_possible = true;
12054 bool is_response_parameter_encryption_possible = true;
12055 std::string command_code_bytes;
12056 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12057 if (rc != TPM_RC_SUCCESS) {
12058 return rc;
12059 }
12060 std::string old_parent_bytes;
12061 rc = Serialize_TPMI_DH_OBJECT(old_parent, &old_parent_bytes);
12062 if (rc != TPM_RC_SUCCESS) {
12063 return rc;
12064 }
12065 std::string new_parent_bytes;
12066 rc = Serialize_TPMI_DH_OBJECT(new_parent, &new_parent_bytes);
12067 if (rc != TPM_RC_SUCCESS) {
12068 return rc;
12069 }
12070 std::string in_duplicate_bytes;
12071 rc = Serialize_TPM2B_PRIVATE(in_duplicate, &in_duplicate_bytes);
12072 if (rc != TPM_RC_SUCCESS) {
12073 return rc;
12074 }
12075 std::string name_bytes;
12076 rc = Serialize_TPM2B_NAME(name, &name_bytes);
12077 if (rc != TPM_RC_SUCCESS) {
12078 return rc;
12079 }
12080 std::string in_sym_seed_bytes;
12081 rc = Serialize_TPM2B_ENCRYPTED_SECRET(in_sym_seed, &in_sym_seed_bytes);
12082 if (rc != TPM_RC_SUCCESS) {
12083 return rc;
12084 }
12085 if (authorization_delegate) {
12086 // Encrypt just the parameter data, not the size.
12087 std::string tmp = in_duplicate_bytes.substr(2);
12088 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12089 return TRUNKS_RC_ENCRYPTION_FAILED;
12090 }
12091 in_duplicate_bytes.replace(2, std::string::npos, tmp);
12092 }
12093 std::unique_ptr<crypto::SecureHash> hash(
12094 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12095 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12096 hash->Update(old_parent_name.data(), old_parent_name.size());
12097 handle_section_bytes += old_parent_bytes;
12098 command_size += old_parent_bytes.size();
12099 hash->Update(new_parent_name.data(), new_parent_name.size());
12100 handle_section_bytes += new_parent_bytes;
12101 command_size += new_parent_bytes.size();
12102 hash->Update(in_duplicate_bytes.data(), in_duplicate_bytes.size());
12103 parameter_section_bytes += in_duplicate_bytes;
12104 command_size += in_duplicate_bytes.size();
12105 hash->Update(name_bytes.data(), name_bytes.size());
12106 parameter_section_bytes += name_bytes;
12107 command_size += name_bytes.size();
12108 hash->Update(in_sym_seed_bytes.data(), in_sym_seed_bytes.size());
12109 parameter_section_bytes += in_sym_seed_bytes;
12110 command_size += in_sym_seed_bytes.size();
12111 std::string command_hash(32, 0);
12112 hash->Finish(std::data(command_hash), command_hash.size());
12113 std::string authorization_section_bytes;
12114 std::string authorization_size_bytes;
12115 if (authorization_delegate) {
12116 if (!authorization_delegate->GetCommandAuthorization(
12117 command_hash, is_command_parameter_encryption_possible,
12118 is_response_parameter_encryption_possible,
12119 &authorization_section_bytes)) {
12120 return TRUNKS_RC_AUTHORIZATION_FAILED;
12121 }
12122 if (!authorization_section_bytes.empty()) {
12123 tag = TPM_ST_SESSIONS;
12124 std::string tmp;
12125 rc = Serialize_UINT32(authorization_section_bytes.size(),
12126 &authorization_size_bytes);
12127 if (rc != TPM_RC_SUCCESS) {
12128 return rc;
12129 }
12130 command_size +=
12131 authorization_size_bytes.size() + authorization_section_bytes.size();
12132 }
12133 }
12134 std::string tag_bytes;
12135 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12136 if (rc != TPM_RC_SUCCESS) {
12137 return rc;
12138 }
12139 std::string command_size_bytes;
12140 rc = Serialize_UINT32(command_size, &command_size_bytes);
12141 if (rc != TPM_RC_SUCCESS) {
12142 return rc;
12143 }
12144 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12145 handle_section_bytes + authorization_size_bytes +
12146 authorization_section_bytes + parameter_section_bytes;
12147 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12148 VLOG(2) << "Command: "
12149 << base::HexEncode(serialized_command->data(),
12150 serialized_command->size());
12151 return TPM_RC_SUCCESS;
12152 }
12153
ParseResponse_Rewrap(const std::string & response,TPM2B_PRIVATE * out_duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)12154 TPM_RC Tpm::ParseResponse_Rewrap(
12155 const std::string& response,
12156 TPM2B_PRIVATE* out_duplicate,
12157 TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12158 AuthorizationDelegate* authorization_delegate) {
12159 VLOG(3) << __func__;
12160 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12161 TPM_RC rc = TPM_RC_SUCCESS;
12162 std::string buffer(response);
12163 TPM_ST tag;
12164 std::string tag_bytes;
12165 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12166 if (rc != TPM_RC_SUCCESS) {
12167 return rc;
12168 }
12169 UINT32 response_size;
12170 std::string response_size_bytes;
12171 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12172 if (rc != TPM_RC_SUCCESS) {
12173 return rc;
12174 }
12175 TPM_RC response_code;
12176 std::string response_code_bytes;
12177 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12178 if (rc != TPM_RC_SUCCESS) {
12179 return rc;
12180 }
12181 if (response_size != response.size()) {
12182 return TPM_RC_SIZE;
12183 }
12184 if (response_code != TPM_RC_SUCCESS) {
12185 return response_code;
12186 }
12187 TPM_CC command_code = TPM_CC_Rewrap;
12188 std::string command_code_bytes;
12189 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12190 if (rc != TPM_RC_SUCCESS) {
12191 return rc;
12192 }
12193 std::string authorization_section_bytes;
12194 if (tag == TPM_ST_SESSIONS) {
12195 UINT32 parameter_section_size = buffer.size();
12196 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
12197 if (rc != TPM_RC_SUCCESS) {
12198 return rc;
12199 }
12200 if (parameter_section_size > buffer.size()) {
12201 return TPM_RC_INSUFFICIENT;
12202 }
12203 authorization_section_bytes = buffer.substr(parameter_section_size);
12204 // Keep the parameter section in |buffer|.
12205 buffer.erase(parameter_section_size);
12206 }
12207 std::unique_ptr<crypto::SecureHash> hash(
12208 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12209 hash->Update(response_code_bytes.data(), response_code_bytes.size());
12210 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12211 hash->Update(buffer.data(), buffer.size());
12212 std::string response_hash(32, 0);
12213 hash->Finish(std::data(response_hash), response_hash.size());
12214 if (tag == TPM_ST_SESSIONS) {
12215 if (!authorization_delegate)
12216 return TRUNKS_RC_AUTHORIZATION_FAILED;
12217 if (!authorization_delegate->CheckResponseAuthorization(
12218 response_hash, authorization_section_bytes)) {
12219 return TRUNKS_RC_AUTHORIZATION_FAILED;
12220 }
12221 }
12222 if (tag == TPM_ST_SESSIONS) {
12223 if (!authorization_delegate)
12224 return TRUNKS_RC_AUTHORIZATION_FAILED;
12225
12226 // Parse the encrypted parameter size.
12227 UINT16 size;
12228 std::string size_buffer = buffer.substr(0, 2);
12229 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12230 return result;
12231 }
12232 if (buffer.size() < 2 + size) {
12233 return TPM_RC_INSUFFICIENT;
12234 }
12235
12236 // Decrypt just the parameter data, not the size.
12237 std::string decrypted_data = buffer.substr(2, size);
12238 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12239 return TRUNKS_RC_ENCRYPTION_FAILED;
12240 }
12241 buffer.replace(2, size, decrypted_data);
12242 }
12243 std::string out_duplicate_bytes;
12244 rc = Parse_TPM2B_PRIVATE(&buffer, out_duplicate, &out_duplicate_bytes);
12245 if (rc != TPM_RC_SUCCESS) {
12246 return rc;
12247 }
12248 std::string out_sym_seed_bytes;
12249 rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, out_sym_seed, &out_sym_seed_bytes);
12250 if (rc != TPM_RC_SUCCESS) {
12251 return rc;
12252 }
12253 return TPM_RC_SUCCESS;
12254 }
12255
RewrapErrorCallback(Tpm::RewrapResponse callback,TPM_RC response_code)12256 void RewrapErrorCallback(Tpm::RewrapResponse callback, TPM_RC response_code) {
12257 VLOG(1) << __func__;
12258 std::move(callback).Run(response_code, TPM2B_PRIVATE(),
12259 TPM2B_ENCRYPTED_SECRET());
12260 }
12261
RewrapResponseParser(Tpm::RewrapResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12262 void RewrapResponseParser(Tpm::RewrapResponse callback,
12263 AuthorizationDelegate* authorization_delegate,
12264 const std::string& response) {
12265 VLOG(1) << __func__;
12266 TPM2B_PRIVATE out_duplicate;
12267 TPM2B_ENCRYPTED_SECRET out_sym_seed;
12268 TPM_RC rc = Tpm::ParseResponse_Rewrap(response, &out_duplicate, &out_sym_seed,
12269 authorization_delegate);
12270 if (rc != TPM_RC_SUCCESS) {
12271 base::OnceCallback<void(TPM_RC)> error_reporter =
12272 base::BindOnce(RewrapErrorCallback, std::move(callback));
12273 std::move(error_reporter).Run(rc);
12274 return;
12275 }
12276 std::move(callback).Run(rc, out_duplicate, out_sym_seed);
12277 }
12278
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)12279 void Tpm::Rewrap(const TPMI_DH_OBJECT& old_parent,
12280 const std::string& old_parent_name,
12281 const TPMI_DH_OBJECT& new_parent,
12282 const std::string& new_parent_name,
12283 const TPM2B_PRIVATE& in_duplicate,
12284 const TPM2B_NAME& name,
12285 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12286 AuthorizationDelegate* authorization_delegate,
12287 RewrapResponse callback) {
12288 VLOG(1) << __func__;
12289 std::string command;
12290 TPM_RC rc = SerializeCommand_Rewrap(
12291 old_parent, old_parent_name, new_parent, new_parent_name, in_duplicate,
12292 name, in_sym_seed, &command, authorization_delegate);
12293 if (rc != TPM_RC_SUCCESS) {
12294 base::OnceCallback<void(TPM_RC)> error_reporter =
12295 base::BindOnce(RewrapErrorCallback, std::move(callback));
12296 std::move(error_reporter).Run(rc);
12297 return;
12298 }
12299 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12300 RewrapResponseParser, std::move(callback), authorization_delegate);
12301 transceiver_->SendCommand(command, std::move(parser));
12302 }
12303
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)12304 TPM_RC Tpm::RewrapSync(const TPMI_DH_OBJECT& old_parent,
12305 const std::string& old_parent_name,
12306 const TPMI_DH_OBJECT& new_parent,
12307 const std::string& new_parent_name,
12308 const TPM2B_PRIVATE& in_duplicate,
12309 const TPM2B_NAME& name,
12310 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12311 TPM2B_PRIVATE* out_duplicate,
12312 TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12313 AuthorizationDelegate* authorization_delegate) {
12314 VLOG(1) << __func__;
12315 std::string command;
12316 TPM_RC rc = SerializeCommand_Rewrap(
12317 old_parent, old_parent_name, new_parent, new_parent_name, in_duplicate,
12318 name, in_sym_seed, &command, authorization_delegate);
12319 if (rc != TPM_RC_SUCCESS) {
12320 return rc;
12321 }
12322 std::string response = transceiver_->SendCommandAndWait(command);
12323 rc = ParseResponse_Rewrap(response, out_duplicate, out_sym_seed,
12324 authorization_delegate);
12325 return rc;
12326 }
12327
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)12328 TPM_RC Tpm::SerializeCommand_Import(
12329 const TPMI_DH_OBJECT& parent_handle,
12330 const std::string& parent_handle_name,
12331 const TPM2B_DATA& encryption_key,
12332 const TPM2B_PUBLIC& object_public,
12333 const TPM2B_PRIVATE& duplicate,
12334 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12335 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12336 std::string* serialized_command,
12337 AuthorizationDelegate* authorization_delegate) {
12338 VLOG(3) << __func__;
12339 TPM_RC rc = TPM_RC_SUCCESS;
12340 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12341 UINT32 command_size = 10; // Header size.
12342 std::string handle_section_bytes;
12343 std::string parameter_section_bytes;
12344 TPM_CC command_code = TPM_CC_Import;
12345 bool is_command_parameter_encryption_possible = true;
12346 bool is_response_parameter_encryption_possible = true;
12347 std::string command_code_bytes;
12348 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12349 if (rc != TPM_RC_SUCCESS) {
12350 return rc;
12351 }
12352 std::string parent_handle_bytes;
12353 rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
12354 if (rc != TPM_RC_SUCCESS) {
12355 return rc;
12356 }
12357 std::string encryption_key_bytes;
12358 rc = Serialize_TPM2B_DATA(encryption_key, &encryption_key_bytes);
12359 if (rc != TPM_RC_SUCCESS) {
12360 return rc;
12361 }
12362 std::string object_public_bytes;
12363 rc = Serialize_TPM2B_PUBLIC(object_public, &object_public_bytes);
12364 if (rc != TPM_RC_SUCCESS) {
12365 return rc;
12366 }
12367 std::string duplicate_bytes;
12368 rc = Serialize_TPM2B_PRIVATE(duplicate, &duplicate_bytes);
12369 if (rc != TPM_RC_SUCCESS) {
12370 return rc;
12371 }
12372 std::string in_sym_seed_bytes;
12373 rc = Serialize_TPM2B_ENCRYPTED_SECRET(in_sym_seed, &in_sym_seed_bytes);
12374 if (rc != TPM_RC_SUCCESS) {
12375 return rc;
12376 }
12377 std::string symmetric_alg_bytes;
12378 rc = Serialize_TPMT_SYM_DEF_OBJECT(symmetric_alg, &symmetric_alg_bytes);
12379 if (rc != TPM_RC_SUCCESS) {
12380 return rc;
12381 }
12382 if (authorization_delegate) {
12383 // Encrypt just the parameter data, not the size.
12384 std::string tmp = encryption_key_bytes.substr(2);
12385 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12386 return TRUNKS_RC_ENCRYPTION_FAILED;
12387 }
12388 encryption_key_bytes.replace(2, std::string::npos, tmp);
12389 }
12390 std::unique_ptr<crypto::SecureHash> hash(
12391 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12392 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12393 hash->Update(parent_handle_name.data(), parent_handle_name.size());
12394 handle_section_bytes += parent_handle_bytes;
12395 command_size += parent_handle_bytes.size();
12396 hash->Update(encryption_key_bytes.data(), encryption_key_bytes.size());
12397 parameter_section_bytes += encryption_key_bytes;
12398 command_size += encryption_key_bytes.size();
12399 hash->Update(object_public_bytes.data(), object_public_bytes.size());
12400 parameter_section_bytes += object_public_bytes;
12401 command_size += object_public_bytes.size();
12402 hash->Update(duplicate_bytes.data(), duplicate_bytes.size());
12403 parameter_section_bytes += duplicate_bytes;
12404 command_size += duplicate_bytes.size();
12405 hash->Update(in_sym_seed_bytes.data(), in_sym_seed_bytes.size());
12406 parameter_section_bytes += in_sym_seed_bytes;
12407 command_size += in_sym_seed_bytes.size();
12408 hash->Update(symmetric_alg_bytes.data(), symmetric_alg_bytes.size());
12409 parameter_section_bytes += symmetric_alg_bytes;
12410 command_size += symmetric_alg_bytes.size();
12411 std::string command_hash(32, 0);
12412 hash->Finish(std::data(command_hash), command_hash.size());
12413 std::string authorization_section_bytes;
12414 std::string authorization_size_bytes;
12415 if (authorization_delegate) {
12416 if (!authorization_delegate->GetCommandAuthorization(
12417 command_hash, is_command_parameter_encryption_possible,
12418 is_response_parameter_encryption_possible,
12419 &authorization_section_bytes)) {
12420 return TRUNKS_RC_AUTHORIZATION_FAILED;
12421 }
12422 if (!authorization_section_bytes.empty()) {
12423 tag = TPM_ST_SESSIONS;
12424 std::string tmp;
12425 rc = Serialize_UINT32(authorization_section_bytes.size(),
12426 &authorization_size_bytes);
12427 if (rc != TPM_RC_SUCCESS) {
12428 return rc;
12429 }
12430 command_size +=
12431 authorization_size_bytes.size() + authorization_section_bytes.size();
12432 }
12433 }
12434 std::string tag_bytes;
12435 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12436 if (rc != TPM_RC_SUCCESS) {
12437 return rc;
12438 }
12439 std::string command_size_bytes;
12440 rc = Serialize_UINT32(command_size, &command_size_bytes);
12441 if (rc != TPM_RC_SUCCESS) {
12442 return rc;
12443 }
12444 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12445 handle_section_bytes + authorization_size_bytes +
12446 authorization_section_bytes + parameter_section_bytes;
12447 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12448 VLOG(2) << "Command: "
12449 << base::HexEncode(serialized_command->data(),
12450 serialized_command->size());
12451 return TPM_RC_SUCCESS;
12452 }
12453
ParseResponse_Import(const std::string & response,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)12454 TPM_RC Tpm::ParseResponse_Import(
12455 const std::string& response,
12456 TPM2B_PRIVATE* out_private,
12457 AuthorizationDelegate* authorization_delegate) {
12458 VLOG(3) << __func__;
12459 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12460 TPM_RC rc = TPM_RC_SUCCESS;
12461 std::string buffer(response);
12462 TPM_ST tag;
12463 std::string tag_bytes;
12464 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12465 if (rc != TPM_RC_SUCCESS) {
12466 return rc;
12467 }
12468 UINT32 response_size;
12469 std::string response_size_bytes;
12470 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12471 if (rc != TPM_RC_SUCCESS) {
12472 return rc;
12473 }
12474 TPM_RC response_code;
12475 std::string response_code_bytes;
12476 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12477 if (rc != TPM_RC_SUCCESS) {
12478 return rc;
12479 }
12480 if (response_size != response.size()) {
12481 return TPM_RC_SIZE;
12482 }
12483 if (response_code != TPM_RC_SUCCESS) {
12484 return response_code;
12485 }
12486 TPM_CC command_code = TPM_CC_Import;
12487 std::string command_code_bytes;
12488 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12489 if (rc != TPM_RC_SUCCESS) {
12490 return rc;
12491 }
12492 std::string authorization_section_bytes;
12493 if (tag == TPM_ST_SESSIONS) {
12494 UINT32 parameter_section_size = buffer.size();
12495 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
12496 if (rc != TPM_RC_SUCCESS) {
12497 return rc;
12498 }
12499 if (parameter_section_size > buffer.size()) {
12500 return TPM_RC_INSUFFICIENT;
12501 }
12502 authorization_section_bytes = buffer.substr(parameter_section_size);
12503 // Keep the parameter section in |buffer|.
12504 buffer.erase(parameter_section_size);
12505 }
12506 std::unique_ptr<crypto::SecureHash> hash(
12507 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12508 hash->Update(response_code_bytes.data(), response_code_bytes.size());
12509 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12510 hash->Update(buffer.data(), buffer.size());
12511 std::string response_hash(32, 0);
12512 hash->Finish(std::data(response_hash), response_hash.size());
12513 if (tag == TPM_ST_SESSIONS) {
12514 if (!authorization_delegate)
12515 return TRUNKS_RC_AUTHORIZATION_FAILED;
12516 if (!authorization_delegate->CheckResponseAuthorization(
12517 response_hash, authorization_section_bytes)) {
12518 return TRUNKS_RC_AUTHORIZATION_FAILED;
12519 }
12520 }
12521 if (tag == TPM_ST_SESSIONS) {
12522 if (!authorization_delegate)
12523 return TRUNKS_RC_AUTHORIZATION_FAILED;
12524
12525 // Parse the encrypted parameter size.
12526 UINT16 size;
12527 std::string size_buffer = buffer.substr(0, 2);
12528 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12529 return result;
12530 }
12531 if (buffer.size() < 2 + size) {
12532 return TPM_RC_INSUFFICIENT;
12533 }
12534
12535 // Decrypt just the parameter data, not the size.
12536 std::string decrypted_data = buffer.substr(2, size);
12537 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12538 return TRUNKS_RC_ENCRYPTION_FAILED;
12539 }
12540 buffer.replace(2, size, decrypted_data);
12541 }
12542 std::string out_private_bytes;
12543 rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
12544 if (rc != TPM_RC_SUCCESS) {
12545 return rc;
12546 }
12547 return TPM_RC_SUCCESS;
12548 }
12549
ImportErrorCallback(Tpm::ImportResponse callback,TPM_RC response_code)12550 void ImportErrorCallback(Tpm::ImportResponse callback, TPM_RC response_code) {
12551 VLOG(1) << __func__;
12552 std::move(callback).Run(response_code, TPM2B_PRIVATE());
12553 }
12554
ImportResponseParser(Tpm::ImportResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12555 void ImportResponseParser(Tpm::ImportResponse callback,
12556 AuthorizationDelegate* authorization_delegate,
12557 const std::string& response) {
12558 VLOG(1) << __func__;
12559 TPM2B_PRIVATE out_private;
12560 TPM_RC rc =
12561 Tpm::ParseResponse_Import(response, &out_private, authorization_delegate);
12562 if (rc != TPM_RC_SUCCESS) {
12563 base::OnceCallback<void(TPM_RC)> error_reporter =
12564 base::BindOnce(ImportErrorCallback, std::move(callback));
12565 std::move(error_reporter).Run(rc);
12566 return;
12567 }
12568 std::move(callback).Run(rc, out_private);
12569 }
12570
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)12571 void Tpm::Import(const TPMI_DH_OBJECT& parent_handle,
12572 const std::string& parent_handle_name,
12573 const TPM2B_DATA& encryption_key,
12574 const TPM2B_PUBLIC& object_public,
12575 const TPM2B_PRIVATE& duplicate,
12576 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12577 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12578 AuthorizationDelegate* authorization_delegate,
12579 ImportResponse callback) {
12580 VLOG(1) << __func__;
12581 std::string command;
12582 TPM_RC rc = SerializeCommand_Import(
12583 parent_handle, parent_handle_name, encryption_key, object_public,
12584 duplicate, in_sym_seed, symmetric_alg, &command, authorization_delegate);
12585 if (rc != TPM_RC_SUCCESS) {
12586 base::OnceCallback<void(TPM_RC)> error_reporter =
12587 base::BindOnce(ImportErrorCallback, std::move(callback));
12588 std::move(error_reporter).Run(rc);
12589 return;
12590 }
12591 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12592 ImportResponseParser, std::move(callback), authorization_delegate);
12593 transceiver_->SendCommand(command, std::move(parser));
12594 }
12595
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)12596 TPM_RC Tpm::ImportSync(const TPMI_DH_OBJECT& parent_handle,
12597 const std::string& parent_handle_name,
12598 const TPM2B_DATA& encryption_key,
12599 const TPM2B_PUBLIC& object_public,
12600 const TPM2B_PRIVATE& duplicate,
12601 const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12602 const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12603 TPM2B_PRIVATE* out_private,
12604 AuthorizationDelegate* authorization_delegate) {
12605 VLOG(1) << __func__;
12606 std::string command;
12607 TPM_RC rc = SerializeCommand_Import(
12608 parent_handle, parent_handle_name, encryption_key, object_public,
12609 duplicate, in_sym_seed, symmetric_alg, &command, authorization_delegate);
12610 if (rc != TPM_RC_SUCCESS) {
12611 return rc;
12612 }
12613 std::string response = transceiver_->SendCommandAndWait(command);
12614 rc = ParseResponse_Import(response, out_private, authorization_delegate);
12615 return rc;
12616 }
12617
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)12618 TPM_RC Tpm::SerializeCommand_RSA_Encrypt(
12619 const TPMI_DH_OBJECT& key_handle,
12620 const std::string& key_handle_name,
12621 const TPM2B_PUBLIC_KEY_RSA& message,
12622 const TPMT_RSA_DECRYPT& in_scheme,
12623 const TPM2B_DATA& label,
12624 std::string* serialized_command,
12625 AuthorizationDelegate* authorization_delegate) {
12626 VLOG(3) << __func__;
12627 TPM_RC rc = TPM_RC_SUCCESS;
12628 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12629 UINT32 command_size = 10; // Header size.
12630 std::string handle_section_bytes;
12631 std::string parameter_section_bytes;
12632 TPM_CC command_code = TPM_CC_RSA_Encrypt;
12633 bool is_command_parameter_encryption_possible = true;
12634 bool is_response_parameter_encryption_possible = true;
12635 std::string command_code_bytes;
12636 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12637 if (rc != TPM_RC_SUCCESS) {
12638 return rc;
12639 }
12640 std::string key_handle_bytes;
12641 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
12642 if (rc != TPM_RC_SUCCESS) {
12643 return rc;
12644 }
12645 std::string message_bytes;
12646 rc = Serialize_TPM2B_PUBLIC_KEY_RSA(message, &message_bytes);
12647 if (rc != TPM_RC_SUCCESS) {
12648 return rc;
12649 }
12650 std::string in_scheme_bytes;
12651 rc = Serialize_TPMT_RSA_DECRYPT(in_scheme, &in_scheme_bytes);
12652 if (rc != TPM_RC_SUCCESS) {
12653 return rc;
12654 }
12655 std::string label_bytes;
12656 rc = Serialize_TPM2B_DATA(label, &label_bytes);
12657 if (rc != TPM_RC_SUCCESS) {
12658 return rc;
12659 }
12660 if (authorization_delegate) {
12661 // Encrypt just the parameter data, not the size.
12662 std::string tmp = message_bytes.substr(2);
12663 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12664 return TRUNKS_RC_ENCRYPTION_FAILED;
12665 }
12666 message_bytes.replace(2, std::string::npos, tmp);
12667 }
12668 std::unique_ptr<crypto::SecureHash> hash(
12669 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12670 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12671 hash->Update(key_handle_name.data(), key_handle_name.size());
12672 handle_section_bytes += key_handle_bytes;
12673 command_size += key_handle_bytes.size();
12674 hash->Update(message_bytes.data(), message_bytes.size());
12675 parameter_section_bytes += message_bytes;
12676 command_size += message_bytes.size();
12677 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
12678 parameter_section_bytes += in_scheme_bytes;
12679 command_size += in_scheme_bytes.size();
12680 hash->Update(label_bytes.data(), label_bytes.size());
12681 parameter_section_bytes += label_bytes;
12682 command_size += label_bytes.size();
12683 std::string command_hash(32, 0);
12684 hash->Finish(std::data(command_hash), command_hash.size());
12685 std::string authorization_section_bytes;
12686 std::string authorization_size_bytes;
12687 if (authorization_delegate) {
12688 if (!authorization_delegate->GetCommandAuthorization(
12689 command_hash, is_command_parameter_encryption_possible,
12690 is_response_parameter_encryption_possible,
12691 &authorization_section_bytes)) {
12692 return TRUNKS_RC_AUTHORIZATION_FAILED;
12693 }
12694 if (!authorization_section_bytes.empty()) {
12695 tag = TPM_ST_SESSIONS;
12696 std::string tmp;
12697 rc = Serialize_UINT32(authorization_section_bytes.size(),
12698 &authorization_size_bytes);
12699 if (rc != TPM_RC_SUCCESS) {
12700 return rc;
12701 }
12702 command_size +=
12703 authorization_size_bytes.size() + authorization_section_bytes.size();
12704 }
12705 }
12706 std::string tag_bytes;
12707 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12708 if (rc != TPM_RC_SUCCESS) {
12709 return rc;
12710 }
12711 std::string command_size_bytes;
12712 rc = Serialize_UINT32(command_size, &command_size_bytes);
12713 if (rc != TPM_RC_SUCCESS) {
12714 return rc;
12715 }
12716 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12717 handle_section_bytes + authorization_size_bytes +
12718 authorization_section_bytes + parameter_section_bytes;
12719 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12720 VLOG(2) << "Command: "
12721 << base::HexEncode(serialized_command->data(),
12722 serialized_command->size());
12723 return TPM_RC_SUCCESS;
12724 }
12725
ParseResponse_RSA_Encrypt(const std::string & response,TPM2B_PUBLIC_KEY_RSA * out_data,AuthorizationDelegate * authorization_delegate)12726 TPM_RC Tpm::ParseResponse_RSA_Encrypt(
12727 const std::string& response,
12728 TPM2B_PUBLIC_KEY_RSA* out_data,
12729 AuthorizationDelegate* authorization_delegate) {
12730 VLOG(3) << __func__;
12731 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12732 TPM_RC rc = TPM_RC_SUCCESS;
12733 std::string buffer(response);
12734 TPM_ST tag;
12735 std::string tag_bytes;
12736 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12737 if (rc != TPM_RC_SUCCESS) {
12738 return rc;
12739 }
12740 UINT32 response_size;
12741 std::string response_size_bytes;
12742 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12743 if (rc != TPM_RC_SUCCESS) {
12744 return rc;
12745 }
12746 TPM_RC response_code;
12747 std::string response_code_bytes;
12748 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12749 if (rc != TPM_RC_SUCCESS) {
12750 return rc;
12751 }
12752 if (response_size != response.size()) {
12753 return TPM_RC_SIZE;
12754 }
12755 if (response_code != TPM_RC_SUCCESS) {
12756 return response_code;
12757 }
12758 TPM_CC command_code = TPM_CC_RSA_Encrypt;
12759 std::string command_code_bytes;
12760 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12761 if (rc != TPM_RC_SUCCESS) {
12762 return rc;
12763 }
12764 std::string authorization_section_bytes;
12765 if (tag == TPM_ST_SESSIONS) {
12766 UINT32 parameter_section_size = buffer.size();
12767 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
12768 if (rc != TPM_RC_SUCCESS) {
12769 return rc;
12770 }
12771 if (parameter_section_size > buffer.size()) {
12772 return TPM_RC_INSUFFICIENT;
12773 }
12774 authorization_section_bytes = buffer.substr(parameter_section_size);
12775 // Keep the parameter section in |buffer|.
12776 buffer.erase(parameter_section_size);
12777 }
12778 std::unique_ptr<crypto::SecureHash> hash(
12779 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12780 hash->Update(response_code_bytes.data(), response_code_bytes.size());
12781 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12782 hash->Update(buffer.data(), buffer.size());
12783 std::string response_hash(32, 0);
12784 hash->Finish(std::data(response_hash), response_hash.size());
12785 if (tag == TPM_ST_SESSIONS) {
12786 if (!authorization_delegate)
12787 return TRUNKS_RC_AUTHORIZATION_FAILED;
12788 if (!authorization_delegate->CheckResponseAuthorization(
12789 response_hash, authorization_section_bytes)) {
12790 return TRUNKS_RC_AUTHORIZATION_FAILED;
12791 }
12792 }
12793 if (tag == TPM_ST_SESSIONS) {
12794 if (!authorization_delegate)
12795 return TRUNKS_RC_AUTHORIZATION_FAILED;
12796
12797 // Parse the encrypted parameter size.
12798 UINT16 size;
12799 std::string size_buffer = buffer.substr(0, 2);
12800 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12801 return result;
12802 }
12803 if (buffer.size() < 2 + size) {
12804 return TPM_RC_INSUFFICIENT;
12805 }
12806
12807 // Decrypt just the parameter data, not the size.
12808 std::string decrypted_data = buffer.substr(2, size);
12809 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12810 return TRUNKS_RC_ENCRYPTION_FAILED;
12811 }
12812 buffer.replace(2, size, decrypted_data);
12813 }
12814 std::string out_data_bytes;
12815 rc = Parse_TPM2B_PUBLIC_KEY_RSA(&buffer, out_data, &out_data_bytes);
12816 if (rc != TPM_RC_SUCCESS) {
12817 return rc;
12818 }
12819 return TPM_RC_SUCCESS;
12820 }
12821
RSA_EncryptErrorCallback(Tpm::RSA_EncryptResponse callback,TPM_RC response_code)12822 void RSA_EncryptErrorCallback(Tpm::RSA_EncryptResponse callback,
12823 TPM_RC response_code) {
12824 VLOG(1) << __func__;
12825 std::move(callback).Run(response_code, TPM2B_PUBLIC_KEY_RSA());
12826 }
12827
RSA_EncryptResponseParser(Tpm::RSA_EncryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12828 void RSA_EncryptResponseParser(Tpm::RSA_EncryptResponse callback,
12829 AuthorizationDelegate* authorization_delegate,
12830 const std::string& response) {
12831 VLOG(1) << __func__;
12832 TPM2B_PUBLIC_KEY_RSA out_data;
12833 TPM_RC rc = Tpm::ParseResponse_RSA_Encrypt(response, &out_data,
12834 authorization_delegate);
12835 if (rc != TPM_RC_SUCCESS) {
12836 base::OnceCallback<void(TPM_RC)> error_reporter =
12837 base::BindOnce(RSA_EncryptErrorCallback, std::move(callback));
12838 std::move(error_reporter).Run(rc);
12839 return;
12840 }
12841 std::move(callback).Run(rc, out_data);
12842 }
12843
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)12844 void Tpm::RSA_Encrypt(const TPMI_DH_OBJECT& key_handle,
12845 const std::string& key_handle_name,
12846 const TPM2B_PUBLIC_KEY_RSA& message,
12847 const TPMT_RSA_DECRYPT& in_scheme,
12848 const TPM2B_DATA& label,
12849 AuthorizationDelegate* authorization_delegate,
12850 RSA_EncryptResponse callback) {
12851 VLOG(1) << __func__;
12852 std::string command;
12853 TPM_RC rc = SerializeCommand_RSA_Encrypt(key_handle, key_handle_name, message,
12854 in_scheme, label, &command,
12855 authorization_delegate);
12856 if (rc != TPM_RC_SUCCESS) {
12857 base::OnceCallback<void(TPM_RC)> error_reporter =
12858 base::BindOnce(RSA_EncryptErrorCallback, std::move(callback));
12859 std::move(error_reporter).Run(rc);
12860 return;
12861 }
12862 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12863 RSA_EncryptResponseParser, std::move(callback), authorization_delegate);
12864 transceiver_->SendCommand(command, std::move(parser));
12865 }
12866
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)12867 TPM_RC Tpm::RSA_EncryptSync(const TPMI_DH_OBJECT& key_handle,
12868 const std::string& key_handle_name,
12869 const TPM2B_PUBLIC_KEY_RSA& message,
12870 const TPMT_RSA_DECRYPT& in_scheme,
12871 const TPM2B_DATA& label,
12872 TPM2B_PUBLIC_KEY_RSA* out_data,
12873 AuthorizationDelegate* authorization_delegate) {
12874 VLOG(1) << __func__;
12875 std::string command;
12876 TPM_RC rc = SerializeCommand_RSA_Encrypt(key_handle, key_handle_name, message,
12877 in_scheme, label, &command,
12878 authorization_delegate);
12879 if (rc != TPM_RC_SUCCESS) {
12880 return rc;
12881 }
12882 std::string response = transceiver_->SendCommandAndWait(command);
12883 rc = ParseResponse_RSA_Encrypt(response, out_data, authorization_delegate);
12884 return rc;
12885 }
12886
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)12887 TPM_RC Tpm::SerializeCommand_RSA_Decrypt(
12888 const TPMI_DH_OBJECT& key_handle,
12889 const std::string& key_handle_name,
12890 const TPM2B_PUBLIC_KEY_RSA& cipher_text,
12891 const TPMT_RSA_DECRYPT& in_scheme,
12892 const TPM2B_DATA& label,
12893 std::string* serialized_command,
12894 AuthorizationDelegate* authorization_delegate) {
12895 VLOG(3) << __func__;
12896 TPM_RC rc = TPM_RC_SUCCESS;
12897 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12898 UINT32 command_size = 10; // Header size.
12899 std::string handle_section_bytes;
12900 std::string parameter_section_bytes;
12901 TPM_CC command_code = TPM_CC_RSA_Decrypt;
12902 bool is_command_parameter_encryption_possible = true;
12903 bool is_response_parameter_encryption_possible = true;
12904 std::string command_code_bytes;
12905 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12906 if (rc != TPM_RC_SUCCESS) {
12907 return rc;
12908 }
12909 std::string key_handle_bytes;
12910 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
12911 if (rc != TPM_RC_SUCCESS) {
12912 return rc;
12913 }
12914 std::string cipher_text_bytes;
12915 rc = Serialize_TPM2B_PUBLIC_KEY_RSA(cipher_text, &cipher_text_bytes);
12916 if (rc != TPM_RC_SUCCESS) {
12917 return rc;
12918 }
12919 std::string in_scheme_bytes;
12920 rc = Serialize_TPMT_RSA_DECRYPT(in_scheme, &in_scheme_bytes);
12921 if (rc != TPM_RC_SUCCESS) {
12922 return rc;
12923 }
12924 std::string label_bytes;
12925 rc = Serialize_TPM2B_DATA(label, &label_bytes);
12926 if (rc != TPM_RC_SUCCESS) {
12927 return rc;
12928 }
12929 if (authorization_delegate) {
12930 // Encrypt just the parameter data, not the size.
12931 std::string tmp = cipher_text_bytes.substr(2);
12932 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12933 return TRUNKS_RC_ENCRYPTION_FAILED;
12934 }
12935 cipher_text_bytes.replace(2, std::string::npos, tmp);
12936 }
12937 std::unique_ptr<crypto::SecureHash> hash(
12938 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12939 hash->Update(command_code_bytes.data(), command_code_bytes.size());
12940 hash->Update(key_handle_name.data(), key_handle_name.size());
12941 handle_section_bytes += key_handle_bytes;
12942 command_size += key_handle_bytes.size();
12943 hash->Update(cipher_text_bytes.data(), cipher_text_bytes.size());
12944 parameter_section_bytes += cipher_text_bytes;
12945 command_size += cipher_text_bytes.size();
12946 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
12947 parameter_section_bytes += in_scheme_bytes;
12948 command_size += in_scheme_bytes.size();
12949 hash->Update(label_bytes.data(), label_bytes.size());
12950 parameter_section_bytes += label_bytes;
12951 command_size += label_bytes.size();
12952 std::string command_hash(32, 0);
12953 hash->Finish(std::data(command_hash), command_hash.size());
12954 std::string authorization_section_bytes;
12955 std::string authorization_size_bytes;
12956 if (authorization_delegate) {
12957 if (!authorization_delegate->GetCommandAuthorization(
12958 command_hash, is_command_parameter_encryption_possible,
12959 is_response_parameter_encryption_possible,
12960 &authorization_section_bytes)) {
12961 return TRUNKS_RC_AUTHORIZATION_FAILED;
12962 }
12963 if (!authorization_section_bytes.empty()) {
12964 tag = TPM_ST_SESSIONS;
12965 std::string tmp;
12966 rc = Serialize_UINT32(authorization_section_bytes.size(),
12967 &authorization_size_bytes);
12968 if (rc != TPM_RC_SUCCESS) {
12969 return rc;
12970 }
12971 command_size +=
12972 authorization_size_bytes.size() + authorization_section_bytes.size();
12973 }
12974 }
12975 std::string tag_bytes;
12976 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12977 if (rc != TPM_RC_SUCCESS) {
12978 return rc;
12979 }
12980 std::string command_size_bytes;
12981 rc = Serialize_UINT32(command_size, &command_size_bytes);
12982 if (rc != TPM_RC_SUCCESS) {
12983 return rc;
12984 }
12985 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12986 handle_section_bytes + authorization_size_bytes +
12987 authorization_section_bytes + parameter_section_bytes;
12988 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12989 VLOG(2) << "Command: "
12990 << base::HexEncode(serialized_command->data(),
12991 serialized_command->size());
12992 return TPM_RC_SUCCESS;
12993 }
12994
ParseResponse_RSA_Decrypt(const std::string & response,TPM2B_PUBLIC_KEY_RSA * message,AuthorizationDelegate * authorization_delegate)12995 TPM_RC Tpm::ParseResponse_RSA_Decrypt(
12996 const std::string& response,
12997 TPM2B_PUBLIC_KEY_RSA* message,
12998 AuthorizationDelegate* authorization_delegate) {
12999 VLOG(3) << __func__;
13000 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13001 TPM_RC rc = TPM_RC_SUCCESS;
13002 std::string buffer(response);
13003 TPM_ST tag;
13004 std::string tag_bytes;
13005 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13006 if (rc != TPM_RC_SUCCESS) {
13007 return rc;
13008 }
13009 UINT32 response_size;
13010 std::string response_size_bytes;
13011 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13012 if (rc != TPM_RC_SUCCESS) {
13013 return rc;
13014 }
13015 TPM_RC response_code;
13016 std::string response_code_bytes;
13017 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13018 if (rc != TPM_RC_SUCCESS) {
13019 return rc;
13020 }
13021 if (response_size != response.size()) {
13022 return TPM_RC_SIZE;
13023 }
13024 if (response_code != TPM_RC_SUCCESS) {
13025 return response_code;
13026 }
13027 TPM_CC command_code = TPM_CC_RSA_Decrypt;
13028 std::string command_code_bytes;
13029 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13030 if (rc != TPM_RC_SUCCESS) {
13031 return rc;
13032 }
13033 std::string authorization_section_bytes;
13034 if (tag == TPM_ST_SESSIONS) {
13035 UINT32 parameter_section_size = buffer.size();
13036 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
13037 if (rc != TPM_RC_SUCCESS) {
13038 return rc;
13039 }
13040 if (parameter_section_size > buffer.size()) {
13041 return TPM_RC_INSUFFICIENT;
13042 }
13043 authorization_section_bytes = buffer.substr(parameter_section_size);
13044 // Keep the parameter section in |buffer|.
13045 buffer.erase(parameter_section_size);
13046 }
13047 std::unique_ptr<crypto::SecureHash> hash(
13048 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13049 hash->Update(response_code_bytes.data(), response_code_bytes.size());
13050 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13051 hash->Update(buffer.data(), buffer.size());
13052 std::string response_hash(32, 0);
13053 hash->Finish(std::data(response_hash), response_hash.size());
13054 if (tag == TPM_ST_SESSIONS) {
13055 if (!authorization_delegate)
13056 return TRUNKS_RC_AUTHORIZATION_FAILED;
13057 if (!authorization_delegate->CheckResponseAuthorization(
13058 response_hash, authorization_section_bytes)) {
13059 return TRUNKS_RC_AUTHORIZATION_FAILED;
13060 }
13061 }
13062 if (tag == TPM_ST_SESSIONS) {
13063 if (!authorization_delegate)
13064 return TRUNKS_RC_AUTHORIZATION_FAILED;
13065
13066 // Parse the encrypted parameter size.
13067 UINT16 size;
13068 std::string size_buffer = buffer.substr(0, 2);
13069 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13070 return result;
13071 }
13072 if (buffer.size() < 2 + size) {
13073 return TPM_RC_INSUFFICIENT;
13074 }
13075
13076 // Decrypt just the parameter data, not the size.
13077 std::string decrypted_data = buffer.substr(2, size);
13078 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13079 return TRUNKS_RC_ENCRYPTION_FAILED;
13080 }
13081 buffer.replace(2, size, decrypted_data);
13082 }
13083 std::string message_bytes;
13084 rc = Parse_TPM2B_PUBLIC_KEY_RSA(&buffer, message, &message_bytes);
13085 if (rc != TPM_RC_SUCCESS) {
13086 return rc;
13087 }
13088 return TPM_RC_SUCCESS;
13089 }
13090
RSA_DecryptErrorCallback(Tpm::RSA_DecryptResponse callback,TPM_RC response_code)13091 void RSA_DecryptErrorCallback(Tpm::RSA_DecryptResponse callback,
13092 TPM_RC response_code) {
13093 VLOG(1) << __func__;
13094 std::move(callback).Run(response_code, TPM2B_PUBLIC_KEY_RSA());
13095 }
13096
RSA_DecryptResponseParser(Tpm::RSA_DecryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13097 void RSA_DecryptResponseParser(Tpm::RSA_DecryptResponse callback,
13098 AuthorizationDelegate* authorization_delegate,
13099 const std::string& response) {
13100 VLOG(1) << __func__;
13101 TPM2B_PUBLIC_KEY_RSA message;
13102 TPM_RC rc = Tpm::ParseResponse_RSA_Decrypt(response, &message,
13103 authorization_delegate);
13104 if (rc != TPM_RC_SUCCESS) {
13105 base::OnceCallback<void(TPM_RC)> error_reporter =
13106 base::BindOnce(RSA_DecryptErrorCallback, std::move(callback));
13107 std::move(error_reporter).Run(rc);
13108 return;
13109 }
13110 std::move(callback).Run(rc, message);
13111 }
13112
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)13113 void Tpm::RSA_Decrypt(const TPMI_DH_OBJECT& key_handle,
13114 const std::string& key_handle_name,
13115 const TPM2B_PUBLIC_KEY_RSA& cipher_text,
13116 const TPMT_RSA_DECRYPT& in_scheme,
13117 const TPM2B_DATA& label,
13118 AuthorizationDelegate* authorization_delegate,
13119 RSA_DecryptResponse callback) {
13120 VLOG(1) << __func__;
13121 std::string command;
13122 TPM_RC rc = SerializeCommand_RSA_Decrypt(key_handle, key_handle_name,
13123 cipher_text, in_scheme, label,
13124 &command, authorization_delegate);
13125 if (rc != TPM_RC_SUCCESS) {
13126 base::OnceCallback<void(TPM_RC)> error_reporter =
13127 base::BindOnce(RSA_DecryptErrorCallback, std::move(callback));
13128 std::move(error_reporter).Run(rc);
13129 return;
13130 }
13131 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13132 RSA_DecryptResponseParser, std::move(callback), authorization_delegate);
13133 transceiver_->SendCommand(command, std::move(parser));
13134 }
13135
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)13136 TPM_RC Tpm::RSA_DecryptSync(const TPMI_DH_OBJECT& key_handle,
13137 const std::string& key_handle_name,
13138 const TPM2B_PUBLIC_KEY_RSA& cipher_text,
13139 const TPMT_RSA_DECRYPT& in_scheme,
13140 const TPM2B_DATA& label,
13141 TPM2B_PUBLIC_KEY_RSA* message,
13142 AuthorizationDelegate* authorization_delegate) {
13143 VLOG(1) << __func__;
13144 std::string command;
13145 TPM_RC rc = SerializeCommand_RSA_Decrypt(key_handle, key_handle_name,
13146 cipher_text, in_scheme, label,
13147 &command, authorization_delegate);
13148 if (rc != TPM_RC_SUCCESS) {
13149 return rc;
13150 }
13151 std::string response = transceiver_->SendCommandAndWait(command);
13152 rc = ParseResponse_RSA_Decrypt(response, message, authorization_delegate);
13153 return rc;
13154 }
13155
SerializeCommand_ECDH_KeyGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13156 TPM_RC Tpm::SerializeCommand_ECDH_KeyGen(
13157 const TPMI_DH_OBJECT& key_handle,
13158 const std::string& key_handle_name,
13159 std::string* serialized_command,
13160 AuthorizationDelegate* authorization_delegate) {
13161 VLOG(3) << __func__;
13162 TPM_RC rc = TPM_RC_SUCCESS;
13163 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13164 UINT32 command_size = 10; // Header size.
13165 std::string handle_section_bytes;
13166 std::string parameter_section_bytes;
13167 TPM_CC command_code = TPM_CC_ECDH_KeyGen;
13168 bool is_command_parameter_encryption_possible = false;
13169 bool is_response_parameter_encryption_possible = true;
13170 std::string command_code_bytes;
13171 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13172 if (rc != TPM_RC_SUCCESS) {
13173 return rc;
13174 }
13175 std::string key_handle_bytes;
13176 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13177 if (rc != TPM_RC_SUCCESS) {
13178 return rc;
13179 }
13180 std::unique_ptr<crypto::SecureHash> hash(
13181 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13182 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13183 hash->Update(key_handle_name.data(), key_handle_name.size());
13184 handle_section_bytes += key_handle_bytes;
13185 command_size += key_handle_bytes.size();
13186 std::string command_hash(32, 0);
13187 hash->Finish(std::data(command_hash), command_hash.size());
13188 std::string authorization_section_bytes;
13189 std::string authorization_size_bytes;
13190 if (authorization_delegate) {
13191 if (!authorization_delegate->GetCommandAuthorization(
13192 command_hash, is_command_parameter_encryption_possible,
13193 is_response_parameter_encryption_possible,
13194 &authorization_section_bytes)) {
13195 return TRUNKS_RC_AUTHORIZATION_FAILED;
13196 }
13197 if (!authorization_section_bytes.empty()) {
13198 tag = TPM_ST_SESSIONS;
13199 std::string tmp;
13200 rc = Serialize_UINT32(authorization_section_bytes.size(),
13201 &authorization_size_bytes);
13202 if (rc != TPM_RC_SUCCESS) {
13203 return rc;
13204 }
13205 command_size +=
13206 authorization_size_bytes.size() + authorization_section_bytes.size();
13207 }
13208 }
13209 std::string tag_bytes;
13210 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13211 if (rc != TPM_RC_SUCCESS) {
13212 return rc;
13213 }
13214 std::string command_size_bytes;
13215 rc = Serialize_UINT32(command_size, &command_size_bytes);
13216 if (rc != TPM_RC_SUCCESS) {
13217 return rc;
13218 }
13219 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13220 handle_section_bytes + authorization_size_bytes +
13221 authorization_section_bytes + parameter_section_bytes;
13222 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13223 VLOG(2) << "Command: "
13224 << base::HexEncode(serialized_command->data(),
13225 serialized_command->size());
13226 return TPM_RC_SUCCESS;
13227 }
13228
ParseResponse_ECDH_KeyGen(const std::string & response,TPM2B_ECC_POINT * z_point,TPM2B_ECC_POINT * pub_point,AuthorizationDelegate * authorization_delegate)13229 TPM_RC Tpm::ParseResponse_ECDH_KeyGen(
13230 const std::string& response,
13231 TPM2B_ECC_POINT* z_point,
13232 TPM2B_ECC_POINT* pub_point,
13233 AuthorizationDelegate* authorization_delegate) {
13234 VLOG(3) << __func__;
13235 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13236 TPM_RC rc = TPM_RC_SUCCESS;
13237 std::string buffer(response);
13238 TPM_ST tag;
13239 std::string tag_bytes;
13240 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13241 if (rc != TPM_RC_SUCCESS) {
13242 return rc;
13243 }
13244 UINT32 response_size;
13245 std::string response_size_bytes;
13246 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13247 if (rc != TPM_RC_SUCCESS) {
13248 return rc;
13249 }
13250 TPM_RC response_code;
13251 std::string response_code_bytes;
13252 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13253 if (rc != TPM_RC_SUCCESS) {
13254 return rc;
13255 }
13256 if (response_size != response.size()) {
13257 return TPM_RC_SIZE;
13258 }
13259 if (response_code != TPM_RC_SUCCESS) {
13260 return response_code;
13261 }
13262 TPM_CC command_code = TPM_CC_ECDH_KeyGen;
13263 std::string command_code_bytes;
13264 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13265 if (rc != TPM_RC_SUCCESS) {
13266 return rc;
13267 }
13268 std::string authorization_section_bytes;
13269 if (tag == TPM_ST_SESSIONS) {
13270 UINT32 parameter_section_size = buffer.size();
13271 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
13272 if (rc != TPM_RC_SUCCESS) {
13273 return rc;
13274 }
13275 if (parameter_section_size > buffer.size()) {
13276 return TPM_RC_INSUFFICIENT;
13277 }
13278 authorization_section_bytes = buffer.substr(parameter_section_size);
13279 // Keep the parameter section in |buffer|.
13280 buffer.erase(parameter_section_size);
13281 }
13282 std::unique_ptr<crypto::SecureHash> hash(
13283 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13284 hash->Update(response_code_bytes.data(), response_code_bytes.size());
13285 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13286 hash->Update(buffer.data(), buffer.size());
13287 std::string response_hash(32, 0);
13288 hash->Finish(std::data(response_hash), response_hash.size());
13289 if (tag == TPM_ST_SESSIONS) {
13290 if (!authorization_delegate)
13291 return TRUNKS_RC_AUTHORIZATION_FAILED;
13292 if (!authorization_delegate->CheckResponseAuthorization(
13293 response_hash, authorization_section_bytes)) {
13294 return TRUNKS_RC_AUTHORIZATION_FAILED;
13295 }
13296 }
13297 if (tag == TPM_ST_SESSIONS) {
13298 if (!authorization_delegate)
13299 return TRUNKS_RC_AUTHORIZATION_FAILED;
13300
13301 // Parse the encrypted parameter size.
13302 UINT16 size;
13303 std::string size_buffer = buffer.substr(0, 2);
13304 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13305 return result;
13306 }
13307 if (buffer.size() < 2 + size) {
13308 return TPM_RC_INSUFFICIENT;
13309 }
13310
13311 // Decrypt just the parameter data, not the size.
13312 std::string decrypted_data = buffer.substr(2, size);
13313 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13314 return TRUNKS_RC_ENCRYPTION_FAILED;
13315 }
13316 buffer.replace(2, size, decrypted_data);
13317 }
13318 std::string z_point_bytes;
13319 rc = Parse_TPM2B_ECC_POINT(&buffer, z_point, &z_point_bytes);
13320 if (rc != TPM_RC_SUCCESS) {
13321 return rc;
13322 }
13323 std::string pub_point_bytes;
13324 rc = Parse_TPM2B_ECC_POINT(&buffer, pub_point, &pub_point_bytes);
13325 if (rc != TPM_RC_SUCCESS) {
13326 return rc;
13327 }
13328 return TPM_RC_SUCCESS;
13329 }
13330
ECDH_KeyGenErrorCallback(Tpm::ECDH_KeyGenResponse callback,TPM_RC response_code)13331 void ECDH_KeyGenErrorCallback(Tpm::ECDH_KeyGenResponse callback,
13332 TPM_RC response_code) {
13333 VLOG(1) << __func__;
13334 std::move(callback).Run(response_code, TPM2B_ECC_POINT(), TPM2B_ECC_POINT());
13335 }
13336
ECDH_KeyGenResponseParser(Tpm::ECDH_KeyGenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13337 void ECDH_KeyGenResponseParser(Tpm::ECDH_KeyGenResponse callback,
13338 AuthorizationDelegate* authorization_delegate,
13339 const std::string& response) {
13340 VLOG(1) << __func__;
13341 TPM2B_ECC_POINT z_point;
13342 TPM2B_ECC_POINT pub_point;
13343 TPM_RC rc = Tpm::ParseResponse_ECDH_KeyGen(response, &z_point, &pub_point,
13344 authorization_delegate);
13345 if (rc != TPM_RC_SUCCESS) {
13346 base::OnceCallback<void(TPM_RC)> error_reporter =
13347 base::BindOnce(ECDH_KeyGenErrorCallback, std::move(callback));
13348 std::move(error_reporter).Run(rc);
13349 return;
13350 }
13351 std::move(callback).Run(rc, z_point, pub_point);
13352 }
13353
ECDH_KeyGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,AuthorizationDelegate * authorization_delegate,ECDH_KeyGenResponse callback)13354 void Tpm::ECDH_KeyGen(const TPMI_DH_OBJECT& key_handle,
13355 const std::string& key_handle_name,
13356 AuthorizationDelegate* authorization_delegate,
13357 ECDH_KeyGenResponse callback) {
13358 VLOG(1) << __func__;
13359 std::string command;
13360 TPM_RC rc = SerializeCommand_ECDH_KeyGen(key_handle, key_handle_name,
13361 &command, authorization_delegate);
13362 if (rc != TPM_RC_SUCCESS) {
13363 base::OnceCallback<void(TPM_RC)> error_reporter =
13364 base::BindOnce(ECDH_KeyGenErrorCallback, std::move(callback));
13365 std::move(error_reporter).Run(rc);
13366 return;
13367 }
13368 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13369 ECDH_KeyGenResponseParser, std::move(callback), authorization_delegate);
13370 transceiver_->SendCommand(command, std::move(parser));
13371 }
13372
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)13373 TPM_RC Tpm::ECDH_KeyGenSync(const TPMI_DH_OBJECT& key_handle,
13374 const std::string& key_handle_name,
13375 TPM2B_ECC_POINT* z_point,
13376 TPM2B_ECC_POINT* pub_point,
13377 AuthorizationDelegate* authorization_delegate) {
13378 VLOG(1) << __func__;
13379 std::string command;
13380 TPM_RC rc = SerializeCommand_ECDH_KeyGen(key_handle, key_handle_name,
13381 &command, authorization_delegate);
13382 if (rc != TPM_RC_SUCCESS) {
13383 return rc;
13384 }
13385 std::string response = transceiver_->SendCommandAndWait(command);
13386 rc = ParseResponse_ECDH_KeyGen(response, z_point, pub_point,
13387 authorization_delegate);
13388 return rc;
13389 }
13390
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)13391 TPM_RC Tpm::SerializeCommand_ECDH_ZGen(
13392 const TPMI_DH_OBJECT& key_handle,
13393 const std::string& key_handle_name,
13394 const TPM2B_ECC_POINT& in_point,
13395 std::string* serialized_command,
13396 AuthorizationDelegate* authorization_delegate) {
13397 VLOG(3) << __func__;
13398 TPM_RC rc = TPM_RC_SUCCESS;
13399 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13400 UINT32 command_size = 10; // Header size.
13401 std::string handle_section_bytes;
13402 std::string parameter_section_bytes;
13403 TPM_CC command_code = TPM_CC_ECDH_ZGen;
13404 bool is_command_parameter_encryption_possible = true;
13405 bool is_response_parameter_encryption_possible = true;
13406 std::string command_code_bytes;
13407 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13408 if (rc != TPM_RC_SUCCESS) {
13409 return rc;
13410 }
13411 std::string key_handle_bytes;
13412 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13413 if (rc != TPM_RC_SUCCESS) {
13414 return rc;
13415 }
13416 std::string in_point_bytes;
13417 rc = Serialize_TPM2B_ECC_POINT(in_point, &in_point_bytes);
13418 if (rc != TPM_RC_SUCCESS) {
13419 return rc;
13420 }
13421 if (authorization_delegate) {
13422 // Encrypt just the parameter data, not the size.
13423 std::string tmp = in_point_bytes.substr(2);
13424 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
13425 return TRUNKS_RC_ENCRYPTION_FAILED;
13426 }
13427 in_point_bytes.replace(2, std::string::npos, tmp);
13428 }
13429 std::unique_ptr<crypto::SecureHash> hash(
13430 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13431 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13432 hash->Update(key_handle_name.data(), key_handle_name.size());
13433 handle_section_bytes += key_handle_bytes;
13434 command_size += key_handle_bytes.size();
13435 hash->Update(in_point_bytes.data(), in_point_bytes.size());
13436 parameter_section_bytes += in_point_bytes;
13437 command_size += in_point_bytes.size();
13438 std::string command_hash(32, 0);
13439 hash->Finish(std::data(command_hash), command_hash.size());
13440 std::string authorization_section_bytes;
13441 std::string authorization_size_bytes;
13442 if (authorization_delegate) {
13443 if (!authorization_delegate->GetCommandAuthorization(
13444 command_hash, is_command_parameter_encryption_possible,
13445 is_response_parameter_encryption_possible,
13446 &authorization_section_bytes)) {
13447 return TRUNKS_RC_AUTHORIZATION_FAILED;
13448 }
13449 if (!authorization_section_bytes.empty()) {
13450 tag = TPM_ST_SESSIONS;
13451 std::string tmp;
13452 rc = Serialize_UINT32(authorization_section_bytes.size(),
13453 &authorization_size_bytes);
13454 if (rc != TPM_RC_SUCCESS) {
13455 return rc;
13456 }
13457 command_size +=
13458 authorization_size_bytes.size() + authorization_section_bytes.size();
13459 }
13460 }
13461 std::string tag_bytes;
13462 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13463 if (rc != TPM_RC_SUCCESS) {
13464 return rc;
13465 }
13466 std::string command_size_bytes;
13467 rc = Serialize_UINT32(command_size, &command_size_bytes);
13468 if (rc != TPM_RC_SUCCESS) {
13469 return rc;
13470 }
13471 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13472 handle_section_bytes + authorization_size_bytes +
13473 authorization_section_bytes + parameter_section_bytes;
13474 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13475 VLOG(2) << "Command: "
13476 << base::HexEncode(serialized_command->data(),
13477 serialized_command->size());
13478 return TPM_RC_SUCCESS;
13479 }
13480
ParseResponse_ECDH_ZGen(const std::string & response,TPM2B_ECC_POINT * out_point,AuthorizationDelegate * authorization_delegate)13481 TPM_RC Tpm::ParseResponse_ECDH_ZGen(
13482 const std::string& response,
13483 TPM2B_ECC_POINT* out_point,
13484 AuthorizationDelegate* authorization_delegate) {
13485 VLOG(3) << __func__;
13486 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13487 TPM_RC rc = TPM_RC_SUCCESS;
13488 std::string buffer(response);
13489 TPM_ST tag;
13490 std::string tag_bytes;
13491 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13492 if (rc != TPM_RC_SUCCESS) {
13493 return rc;
13494 }
13495 UINT32 response_size;
13496 std::string response_size_bytes;
13497 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13498 if (rc != TPM_RC_SUCCESS) {
13499 return rc;
13500 }
13501 TPM_RC response_code;
13502 std::string response_code_bytes;
13503 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13504 if (rc != TPM_RC_SUCCESS) {
13505 return rc;
13506 }
13507 if (response_size != response.size()) {
13508 return TPM_RC_SIZE;
13509 }
13510 if (response_code != TPM_RC_SUCCESS) {
13511 return response_code;
13512 }
13513 TPM_CC command_code = TPM_CC_ECDH_ZGen;
13514 std::string command_code_bytes;
13515 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13516 if (rc != TPM_RC_SUCCESS) {
13517 return rc;
13518 }
13519 std::string authorization_section_bytes;
13520 if (tag == TPM_ST_SESSIONS) {
13521 UINT32 parameter_section_size = buffer.size();
13522 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
13523 if (rc != TPM_RC_SUCCESS) {
13524 return rc;
13525 }
13526 if (parameter_section_size > buffer.size()) {
13527 return TPM_RC_INSUFFICIENT;
13528 }
13529 authorization_section_bytes = buffer.substr(parameter_section_size);
13530 // Keep the parameter section in |buffer|.
13531 buffer.erase(parameter_section_size);
13532 }
13533 std::unique_ptr<crypto::SecureHash> hash(
13534 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13535 hash->Update(response_code_bytes.data(), response_code_bytes.size());
13536 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13537 hash->Update(buffer.data(), buffer.size());
13538 std::string response_hash(32, 0);
13539 hash->Finish(std::data(response_hash), response_hash.size());
13540 if (tag == TPM_ST_SESSIONS) {
13541 if (!authorization_delegate)
13542 return TRUNKS_RC_AUTHORIZATION_FAILED;
13543 if (!authorization_delegate->CheckResponseAuthorization(
13544 response_hash, authorization_section_bytes)) {
13545 return TRUNKS_RC_AUTHORIZATION_FAILED;
13546 }
13547 }
13548 if (tag == TPM_ST_SESSIONS) {
13549 if (!authorization_delegate)
13550 return TRUNKS_RC_AUTHORIZATION_FAILED;
13551
13552 // Parse the encrypted parameter size.
13553 UINT16 size;
13554 std::string size_buffer = buffer.substr(0, 2);
13555 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13556 return result;
13557 }
13558 if (buffer.size() < 2 + size) {
13559 return TPM_RC_INSUFFICIENT;
13560 }
13561
13562 // Decrypt just the parameter data, not the size.
13563 std::string decrypted_data = buffer.substr(2, size);
13564 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13565 return TRUNKS_RC_ENCRYPTION_FAILED;
13566 }
13567 buffer.replace(2, size, decrypted_data);
13568 }
13569 std::string out_point_bytes;
13570 rc = Parse_TPM2B_ECC_POINT(&buffer, out_point, &out_point_bytes);
13571 if (rc != TPM_RC_SUCCESS) {
13572 return rc;
13573 }
13574 return TPM_RC_SUCCESS;
13575 }
13576
ECDH_ZGenErrorCallback(Tpm::ECDH_ZGenResponse callback,TPM_RC response_code)13577 void ECDH_ZGenErrorCallback(Tpm::ECDH_ZGenResponse callback,
13578 TPM_RC response_code) {
13579 VLOG(1) << __func__;
13580 std::move(callback).Run(response_code, TPM2B_ECC_POINT());
13581 }
13582
ECDH_ZGenResponseParser(Tpm::ECDH_ZGenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13583 void ECDH_ZGenResponseParser(Tpm::ECDH_ZGenResponse callback,
13584 AuthorizationDelegate* authorization_delegate,
13585 const std::string& response) {
13586 VLOG(1) << __func__;
13587 TPM2B_ECC_POINT out_point;
13588 TPM_RC rc = Tpm::ParseResponse_ECDH_ZGen(response, &out_point,
13589 authorization_delegate);
13590 if (rc != TPM_RC_SUCCESS) {
13591 base::OnceCallback<void(TPM_RC)> error_reporter =
13592 base::BindOnce(ECDH_ZGenErrorCallback, std::move(callback));
13593 std::move(error_reporter).Run(rc);
13594 return;
13595 }
13596 std::move(callback).Run(rc, out_point);
13597 }
13598
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)13599 void Tpm::ECDH_ZGen(const TPMI_DH_OBJECT& key_handle,
13600 const std::string& key_handle_name,
13601 const TPM2B_ECC_POINT& in_point,
13602 AuthorizationDelegate* authorization_delegate,
13603 ECDH_ZGenResponse callback) {
13604 VLOG(1) << __func__;
13605 std::string command;
13606 TPM_RC rc = SerializeCommand_ECDH_ZGen(key_handle, key_handle_name, in_point,
13607 &command, authorization_delegate);
13608 if (rc != TPM_RC_SUCCESS) {
13609 base::OnceCallback<void(TPM_RC)> error_reporter =
13610 base::BindOnce(ECDH_ZGenErrorCallback, std::move(callback));
13611 std::move(error_reporter).Run(rc);
13612 return;
13613 }
13614 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13615 ECDH_ZGenResponseParser, std::move(callback), authorization_delegate);
13616 transceiver_->SendCommand(command, std::move(parser));
13617 }
13618
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)13619 TPM_RC Tpm::ECDH_ZGenSync(const TPMI_DH_OBJECT& key_handle,
13620 const std::string& key_handle_name,
13621 const TPM2B_ECC_POINT& in_point,
13622 TPM2B_ECC_POINT* out_point,
13623 AuthorizationDelegate* authorization_delegate) {
13624 VLOG(1) << __func__;
13625 std::string command;
13626 TPM_RC rc = SerializeCommand_ECDH_ZGen(key_handle, key_handle_name, in_point,
13627 &command, authorization_delegate);
13628 if (rc != TPM_RC_SUCCESS) {
13629 return rc;
13630 }
13631 std::string response = transceiver_->SendCommandAndWait(command);
13632 rc = ParseResponse_ECDH_ZGen(response, out_point, authorization_delegate);
13633 return rc;
13634 }
13635
SerializeCommand_ECC_Parameters(const TPMI_ECC_CURVE & curve_id,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13636 TPM_RC Tpm::SerializeCommand_ECC_Parameters(
13637 const TPMI_ECC_CURVE& curve_id,
13638 std::string* serialized_command,
13639 AuthorizationDelegate* authorization_delegate) {
13640 VLOG(3) << __func__;
13641 TPM_RC rc = TPM_RC_SUCCESS;
13642 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13643 UINT32 command_size = 10; // Header size.
13644 std::string handle_section_bytes;
13645 std::string parameter_section_bytes;
13646 TPM_CC command_code = TPM_CC_ECC_Parameters;
13647 bool is_command_parameter_encryption_possible = false;
13648 bool is_response_parameter_encryption_possible = false;
13649 std::string command_code_bytes;
13650 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13651 if (rc != TPM_RC_SUCCESS) {
13652 return rc;
13653 }
13654 std::string curve_id_bytes;
13655 rc = Serialize_TPMI_ECC_CURVE(curve_id, &curve_id_bytes);
13656 if (rc != TPM_RC_SUCCESS) {
13657 return rc;
13658 }
13659 std::unique_ptr<crypto::SecureHash> hash(
13660 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13661 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13662 hash->Update(curve_id_bytes.data(), curve_id_bytes.size());
13663 parameter_section_bytes += curve_id_bytes;
13664 command_size += curve_id_bytes.size();
13665 std::string command_hash(32, 0);
13666 hash->Finish(std::data(command_hash), command_hash.size());
13667 std::string authorization_section_bytes;
13668 std::string authorization_size_bytes;
13669 if (authorization_delegate) {
13670 if (!authorization_delegate->GetCommandAuthorization(
13671 command_hash, is_command_parameter_encryption_possible,
13672 is_response_parameter_encryption_possible,
13673 &authorization_section_bytes)) {
13674 return TRUNKS_RC_AUTHORIZATION_FAILED;
13675 }
13676 if (!authorization_section_bytes.empty()) {
13677 tag = TPM_ST_SESSIONS;
13678 std::string tmp;
13679 rc = Serialize_UINT32(authorization_section_bytes.size(),
13680 &authorization_size_bytes);
13681 if (rc != TPM_RC_SUCCESS) {
13682 return rc;
13683 }
13684 command_size +=
13685 authorization_size_bytes.size() + authorization_section_bytes.size();
13686 }
13687 }
13688 std::string tag_bytes;
13689 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13690 if (rc != TPM_RC_SUCCESS) {
13691 return rc;
13692 }
13693 std::string command_size_bytes;
13694 rc = Serialize_UINT32(command_size, &command_size_bytes);
13695 if (rc != TPM_RC_SUCCESS) {
13696 return rc;
13697 }
13698 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13699 handle_section_bytes + authorization_size_bytes +
13700 authorization_section_bytes + parameter_section_bytes;
13701 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13702 VLOG(2) << "Command: "
13703 << base::HexEncode(serialized_command->data(),
13704 serialized_command->size());
13705 return TPM_RC_SUCCESS;
13706 }
13707
ParseResponse_ECC_Parameters(const std::string & response,TPMS_ALGORITHM_DETAIL_ECC * parameters,AuthorizationDelegate * authorization_delegate)13708 TPM_RC Tpm::ParseResponse_ECC_Parameters(
13709 const std::string& response,
13710 TPMS_ALGORITHM_DETAIL_ECC* parameters,
13711 AuthorizationDelegate* authorization_delegate) {
13712 VLOG(3) << __func__;
13713 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13714 TPM_RC rc = TPM_RC_SUCCESS;
13715 std::string buffer(response);
13716 TPM_ST tag;
13717 std::string tag_bytes;
13718 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13719 if (rc != TPM_RC_SUCCESS) {
13720 return rc;
13721 }
13722 UINT32 response_size;
13723 std::string response_size_bytes;
13724 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13725 if (rc != TPM_RC_SUCCESS) {
13726 return rc;
13727 }
13728 TPM_RC response_code;
13729 std::string response_code_bytes;
13730 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13731 if (rc != TPM_RC_SUCCESS) {
13732 return rc;
13733 }
13734 if (response_size != response.size()) {
13735 return TPM_RC_SIZE;
13736 }
13737 if (response_code != TPM_RC_SUCCESS) {
13738 return response_code;
13739 }
13740 TPM_CC command_code = TPM_CC_ECC_Parameters;
13741 std::string command_code_bytes;
13742 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13743 if (rc != TPM_RC_SUCCESS) {
13744 return rc;
13745 }
13746 std::string authorization_section_bytes;
13747 if (tag == TPM_ST_SESSIONS) {
13748 UINT32 parameter_section_size = buffer.size();
13749 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
13750 if (rc != TPM_RC_SUCCESS) {
13751 return rc;
13752 }
13753 if (parameter_section_size > buffer.size()) {
13754 return TPM_RC_INSUFFICIENT;
13755 }
13756 authorization_section_bytes = buffer.substr(parameter_section_size);
13757 // Keep the parameter section in |buffer|.
13758 buffer.erase(parameter_section_size);
13759 }
13760 std::unique_ptr<crypto::SecureHash> hash(
13761 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13762 hash->Update(response_code_bytes.data(), response_code_bytes.size());
13763 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13764 hash->Update(buffer.data(), buffer.size());
13765 std::string response_hash(32, 0);
13766 hash->Finish(std::data(response_hash), response_hash.size());
13767 if (tag == TPM_ST_SESSIONS) {
13768 if (!authorization_delegate)
13769 return TRUNKS_RC_AUTHORIZATION_FAILED;
13770 if (!authorization_delegate->CheckResponseAuthorization(
13771 response_hash, authorization_section_bytes)) {
13772 return TRUNKS_RC_AUTHORIZATION_FAILED;
13773 }
13774 }
13775 std::string parameters_bytes;
13776 rc = Parse_TPMS_ALGORITHM_DETAIL_ECC(&buffer, parameters, ¶meters_bytes);
13777 if (rc != TPM_RC_SUCCESS) {
13778 return rc;
13779 }
13780 return TPM_RC_SUCCESS;
13781 }
13782
ECC_ParametersErrorCallback(Tpm::ECC_ParametersResponse callback,TPM_RC response_code)13783 void ECC_ParametersErrorCallback(Tpm::ECC_ParametersResponse callback,
13784 TPM_RC response_code) {
13785 VLOG(1) << __func__;
13786 std::move(callback).Run(response_code, TPMS_ALGORITHM_DETAIL_ECC());
13787 }
13788
ECC_ParametersResponseParser(Tpm::ECC_ParametersResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13789 void ECC_ParametersResponseParser(Tpm::ECC_ParametersResponse callback,
13790 AuthorizationDelegate* authorization_delegate,
13791 const std::string& response) {
13792 VLOG(1) << __func__;
13793 TPMS_ALGORITHM_DETAIL_ECC parameters;
13794 TPM_RC rc = Tpm::ParseResponse_ECC_Parameters(response, ¶meters,
13795 authorization_delegate);
13796 if (rc != TPM_RC_SUCCESS) {
13797 base::OnceCallback<void(TPM_RC)> error_reporter =
13798 base::BindOnce(ECC_ParametersErrorCallback, std::move(callback));
13799 std::move(error_reporter).Run(rc);
13800 return;
13801 }
13802 std::move(callback).Run(rc, parameters);
13803 }
13804
ECC_Parameters(const TPMI_ECC_CURVE & curve_id,AuthorizationDelegate * authorization_delegate,ECC_ParametersResponse callback)13805 void Tpm::ECC_Parameters(const TPMI_ECC_CURVE& curve_id,
13806 AuthorizationDelegate* authorization_delegate,
13807 ECC_ParametersResponse callback) {
13808 VLOG(1) << __func__;
13809 std::string command;
13810 TPM_RC rc = SerializeCommand_ECC_Parameters(curve_id, &command,
13811 authorization_delegate);
13812 if (rc != TPM_RC_SUCCESS) {
13813 base::OnceCallback<void(TPM_RC)> error_reporter =
13814 base::BindOnce(ECC_ParametersErrorCallback, std::move(callback));
13815 std::move(error_reporter).Run(rc);
13816 return;
13817 }
13818 base::OnceCallback<void(const std::string&)> parser =
13819 base::BindOnce(ECC_ParametersResponseParser, std::move(callback),
13820 authorization_delegate);
13821 transceiver_->SendCommand(command, std::move(parser));
13822 }
13823
ECC_ParametersSync(const TPMI_ECC_CURVE & curve_id,TPMS_ALGORITHM_DETAIL_ECC * parameters,AuthorizationDelegate * authorization_delegate)13824 TPM_RC Tpm::ECC_ParametersSync(const TPMI_ECC_CURVE& curve_id,
13825 TPMS_ALGORITHM_DETAIL_ECC* parameters,
13826 AuthorizationDelegate* authorization_delegate) {
13827 VLOG(1) << __func__;
13828 std::string command;
13829 TPM_RC rc = SerializeCommand_ECC_Parameters(curve_id, &command,
13830 authorization_delegate);
13831 if (rc != TPM_RC_SUCCESS) {
13832 return rc;
13833 }
13834 std::string response = transceiver_->SendCommandAndWait(command);
13835 rc = ParseResponse_ECC_Parameters(response, parameters,
13836 authorization_delegate);
13837 return rc;
13838 }
13839
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)13840 TPM_RC Tpm::SerializeCommand_ZGen_2Phase(
13841 const TPMI_DH_OBJECT& key_a,
13842 const std::string& key_a_name,
13843 const TPM2B_ECC_POINT& in_qs_b,
13844 const TPM2B_ECC_POINT& in_qe_b,
13845 const TPMI_ECC_KEY_EXCHANGE& in_scheme,
13846 const UINT16& counter,
13847 std::string* serialized_command,
13848 AuthorizationDelegate* authorization_delegate) {
13849 VLOG(3) << __func__;
13850 TPM_RC rc = TPM_RC_SUCCESS;
13851 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13852 UINT32 command_size = 10; // Header size.
13853 std::string handle_section_bytes;
13854 std::string parameter_section_bytes;
13855 TPM_CC command_code = TPM_CC_ZGen_2Phase;
13856 bool is_command_parameter_encryption_possible = true;
13857 bool is_response_parameter_encryption_possible = true;
13858 std::string command_code_bytes;
13859 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13860 if (rc != TPM_RC_SUCCESS) {
13861 return rc;
13862 }
13863 std::string key_a_bytes;
13864 rc = Serialize_TPMI_DH_OBJECT(key_a, &key_a_bytes);
13865 if (rc != TPM_RC_SUCCESS) {
13866 return rc;
13867 }
13868 std::string in_qs_b_bytes;
13869 rc = Serialize_TPM2B_ECC_POINT(in_qs_b, &in_qs_b_bytes);
13870 if (rc != TPM_RC_SUCCESS) {
13871 return rc;
13872 }
13873 std::string in_qe_b_bytes;
13874 rc = Serialize_TPM2B_ECC_POINT(in_qe_b, &in_qe_b_bytes);
13875 if (rc != TPM_RC_SUCCESS) {
13876 return rc;
13877 }
13878 std::string in_scheme_bytes;
13879 rc = Serialize_TPMI_ECC_KEY_EXCHANGE(in_scheme, &in_scheme_bytes);
13880 if (rc != TPM_RC_SUCCESS) {
13881 return rc;
13882 }
13883 std::string counter_bytes;
13884 rc = Serialize_UINT16(counter, &counter_bytes);
13885 if (rc != TPM_RC_SUCCESS) {
13886 return rc;
13887 }
13888 if (authorization_delegate) {
13889 // Encrypt just the parameter data, not the size.
13890 std::string tmp = in_qs_b_bytes.substr(2);
13891 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
13892 return TRUNKS_RC_ENCRYPTION_FAILED;
13893 }
13894 in_qs_b_bytes.replace(2, std::string::npos, tmp);
13895 }
13896 std::unique_ptr<crypto::SecureHash> hash(
13897 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13898 hash->Update(command_code_bytes.data(), command_code_bytes.size());
13899 hash->Update(key_a_name.data(), key_a_name.size());
13900 handle_section_bytes += key_a_bytes;
13901 command_size += key_a_bytes.size();
13902 hash->Update(in_qs_b_bytes.data(), in_qs_b_bytes.size());
13903 parameter_section_bytes += in_qs_b_bytes;
13904 command_size += in_qs_b_bytes.size();
13905 hash->Update(in_qe_b_bytes.data(), in_qe_b_bytes.size());
13906 parameter_section_bytes += in_qe_b_bytes;
13907 command_size += in_qe_b_bytes.size();
13908 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
13909 parameter_section_bytes += in_scheme_bytes;
13910 command_size += in_scheme_bytes.size();
13911 hash->Update(counter_bytes.data(), counter_bytes.size());
13912 parameter_section_bytes += counter_bytes;
13913 command_size += counter_bytes.size();
13914 std::string command_hash(32, 0);
13915 hash->Finish(std::data(command_hash), command_hash.size());
13916 std::string authorization_section_bytes;
13917 std::string authorization_size_bytes;
13918 if (authorization_delegate) {
13919 if (!authorization_delegate->GetCommandAuthorization(
13920 command_hash, is_command_parameter_encryption_possible,
13921 is_response_parameter_encryption_possible,
13922 &authorization_section_bytes)) {
13923 return TRUNKS_RC_AUTHORIZATION_FAILED;
13924 }
13925 if (!authorization_section_bytes.empty()) {
13926 tag = TPM_ST_SESSIONS;
13927 std::string tmp;
13928 rc = Serialize_UINT32(authorization_section_bytes.size(),
13929 &authorization_size_bytes);
13930 if (rc != TPM_RC_SUCCESS) {
13931 return rc;
13932 }
13933 command_size +=
13934 authorization_size_bytes.size() + authorization_section_bytes.size();
13935 }
13936 }
13937 std::string tag_bytes;
13938 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13939 if (rc != TPM_RC_SUCCESS) {
13940 return rc;
13941 }
13942 std::string command_size_bytes;
13943 rc = Serialize_UINT32(command_size, &command_size_bytes);
13944 if (rc != TPM_RC_SUCCESS) {
13945 return rc;
13946 }
13947 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13948 handle_section_bytes + authorization_size_bytes +
13949 authorization_section_bytes + parameter_section_bytes;
13950 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13951 VLOG(2) << "Command: "
13952 << base::HexEncode(serialized_command->data(),
13953 serialized_command->size());
13954 return TPM_RC_SUCCESS;
13955 }
13956
ParseResponse_ZGen_2Phase(const std::string & response,TPM2B_ECC_POINT * out_z1,TPM2B_ECC_POINT * out_z2,AuthorizationDelegate * authorization_delegate)13957 TPM_RC Tpm::ParseResponse_ZGen_2Phase(
13958 const std::string& response,
13959 TPM2B_ECC_POINT* out_z1,
13960 TPM2B_ECC_POINT* out_z2,
13961 AuthorizationDelegate* authorization_delegate) {
13962 VLOG(3) << __func__;
13963 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13964 TPM_RC rc = TPM_RC_SUCCESS;
13965 std::string buffer(response);
13966 TPM_ST tag;
13967 std::string tag_bytes;
13968 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13969 if (rc != TPM_RC_SUCCESS) {
13970 return rc;
13971 }
13972 UINT32 response_size;
13973 std::string response_size_bytes;
13974 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13975 if (rc != TPM_RC_SUCCESS) {
13976 return rc;
13977 }
13978 TPM_RC response_code;
13979 std::string response_code_bytes;
13980 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13981 if (rc != TPM_RC_SUCCESS) {
13982 return rc;
13983 }
13984 if (response_size != response.size()) {
13985 return TPM_RC_SIZE;
13986 }
13987 if (response_code != TPM_RC_SUCCESS) {
13988 return response_code;
13989 }
13990 TPM_CC command_code = TPM_CC_ZGen_2Phase;
13991 std::string command_code_bytes;
13992 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13993 if (rc != TPM_RC_SUCCESS) {
13994 return rc;
13995 }
13996 std::string authorization_section_bytes;
13997 if (tag == TPM_ST_SESSIONS) {
13998 UINT32 parameter_section_size = buffer.size();
13999 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
14000 if (rc != TPM_RC_SUCCESS) {
14001 return rc;
14002 }
14003 if (parameter_section_size > buffer.size()) {
14004 return TPM_RC_INSUFFICIENT;
14005 }
14006 authorization_section_bytes = buffer.substr(parameter_section_size);
14007 // Keep the parameter section in |buffer|.
14008 buffer.erase(parameter_section_size);
14009 }
14010 std::unique_ptr<crypto::SecureHash> hash(
14011 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14012 hash->Update(response_code_bytes.data(), response_code_bytes.size());
14013 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14014 hash->Update(buffer.data(), buffer.size());
14015 std::string response_hash(32, 0);
14016 hash->Finish(std::data(response_hash), response_hash.size());
14017 if (tag == TPM_ST_SESSIONS) {
14018 if (!authorization_delegate)
14019 return TRUNKS_RC_AUTHORIZATION_FAILED;
14020 if (!authorization_delegate->CheckResponseAuthorization(
14021 response_hash, authorization_section_bytes)) {
14022 return TRUNKS_RC_AUTHORIZATION_FAILED;
14023 }
14024 }
14025 if (tag == TPM_ST_SESSIONS) {
14026 if (!authorization_delegate)
14027 return TRUNKS_RC_AUTHORIZATION_FAILED;
14028
14029 // Parse the encrypted parameter size.
14030 UINT16 size;
14031 std::string size_buffer = buffer.substr(0, 2);
14032 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14033 return result;
14034 }
14035 if (buffer.size() < 2 + size) {
14036 return TPM_RC_INSUFFICIENT;
14037 }
14038
14039 // Decrypt just the parameter data, not the size.
14040 std::string decrypted_data = buffer.substr(2, size);
14041 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14042 return TRUNKS_RC_ENCRYPTION_FAILED;
14043 }
14044 buffer.replace(2, size, decrypted_data);
14045 }
14046 std::string out_z1_bytes;
14047 rc = Parse_TPM2B_ECC_POINT(&buffer, out_z1, &out_z1_bytes);
14048 if (rc != TPM_RC_SUCCESS) {
14049 return rc;
14050 }
14051 std::string out_z2_bytes;
14052 rc = Parse_TPM2B_ECC_POINT(&buffer, out_z2, &out_z2_bytes);
14053 if (rc != TPM_RC_SUCCESS) {
14054 return rc;
14055 }
14056 return TPM_RC_SUCCESS;
14057 }
14058
ZGen_2PhaseErrorCallback(Tpm::ZGen_2PhaseResponse callback,TPM_RC response_code)14059 void ZGen_2PhaseErrorCallback(Tpm::ZGen_2PhaseResponse callback,
14060 TPM_RC response_code) {
14061 VLOG(1) << __func__;
14062 std::move(callback).Run(response_code, TPM2B_ECC_POINT(), TPM2B_ECC_POINT());
14063 }
14064
ZGen_2PhaseResponseParser(Tpm::ZGen_2PhaseResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14065 void ZGen_2PhaseResponseParser(Tpm::ZGen_2PhaseResponse callback,
14066 AuthorizationDelegate* authorization_delegate,
14067 const std::string& response) {
14068 VLOG(1) << __func__;
14069 TPM2B_ECC_POINT out_z1;
14070 TPM2B_ECC_POINT out_z2;
14071 TPM_RC rc = Tpm::ParseResponse_ZGen_2Phase(response, &out_z1, &out_z2,
14072 authorization_delegate);
14073 if (rc != TPM_RC_SUCCESS) {
14074 base::OnceCallback<void(TPM_RC)> error_reporter =
14075 base::BindOnce(ZGen_2PhaseErrorCallback, std::move(callback));
14076 std::move(error_reporter).Run(rc);
14077 return;
14078 }
14079 std::move(callback).Run(rc, out_z1, out_z2);
14080 }
14081
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)14082 void Tpm::ZGen_2Phase(const TPMI_DH_OBJECT& key_a,
14083 const std::string& key_a_name,
14084 const TPM2B_ECC_POINT& in_qs_b,
14085 const TPM2B_ECC_POINT& in_qe_b,
14086 const TPMI_ECC_KEY_EXCHANGE& in_scheme,
14087 const UINT16& counter,
14088 AuthorizationDelegate* authorization_delegate,
14089 ZGen_2PhaseResponse callback) {
14090 VLOG(1) << __func__;
14091 std::string command;
14092 TPM_RC rc = SerializeCommand_ZGen_2Phase(key_a, key_a_name, in_qs_b, in_qe_b,
14093 in_scheme, counter, &command,
14094 authorization_delegate);
14095 if (rc != TPM_RC_SUCCESS) {
14096 base::OnceCallback<void(TPM_RC)> error_reporter =
14097 base::BindOnce(ZGen_2PhaseErrorCallback, std::move(callback));
14098 std::move(error_reporter).Run(rc);
14099 return;
14100 }
14101 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14102 ZGen_2PhaseResponseParser, std::move(callback), authorization_delegate);
14103 transceiver_->SendCommand(command, std::move(parser));
14104 }
14105
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)14106 TPM_RC Tpm::ZGen_2PhaseSync(const TPMI_DH_OBJECT& key_a,
14107 const std::string& key_a_name,
14108 const TPM2B_ECC_POINT& in_qs_b,
14109 const TPM2B_ECC_POINT& in_qe_b,
14110 const TPMI_ECC_KEY_EXCHANGE& in_scheme,
14111 const UINT16& counter,
14112 TPM2B_ECC_POINT* out_z1,
14113 TPM2B_ECC_POINT* out_z2,
14114 AuthorizationDelegate* authorization_delegate) {
14115 VLOG(1) << __func__;
14116 std::string command;
14117 TPM_RC rc = SerializeCommand_ZGen_2Phase(key_a, key_a_name, in_qs_b, in_qe_b,
14118 in_scheme, counter, &command,
14119 authorization_delegate);
14120 if (rc != TPM_RC_SUCCESS) {
14121 return rc;
14122 }
14123 std::string response = transceiver_->SendCommandAndWait(command);
14124 rc = ParseResponse_ZGen_2Phase(response, out_z1, out_z2,
14125 authorization_delegate);
14126 return rc;
14127 }
14128
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)14129 TPM_RC Tpm::SerializeCommand_EncryptDecrypt(
14130 const TPMI_DH_OBJECT& key_handle,
14131 const std::string& key_handle_name,
14132 const TPMI_YES_NO& decrypt,
14133 const TPMI_ALG_SYM_MODE& mode,
14134 const TPM2B_IV& iv_in,
14135 const TPM2B_MAX_BUFFER& in_data,
14136 std::string* serialized_command,
14137 AuthorizationDelegate* authorization_delegate) {
14138 VLOG(3) << __func__;
14139 TPM_RC rc = TPM_RC_SUCCESS;
14140 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14141 UINT32 command_size = 10; // Header size.
14142 std::string handle_section_bytes;
14143 std::string parameter_section_bytes;
14144 TPM_CC command_code = TPM_CC_EncryptDecrypt;
14145 bool is_command_parameter_encryption_possible = false;
14146 bool is_response_parameter_encryption_possible = true;
14147 std::string command_code_bytes;
14148 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14149 if (rc != TPM_RC_SUCCESS) {
14150 return rc;
14151 }
14152 std::string key_handle_bytes;
14153 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
14154 if (rc != TPM_RC_SUCCESS) {
14155 return rc;
14156 }
14157 std::string decrypt_bytes;
14158 rc = Serialize_TPMI_YES_NO(decrypt, &decrypt_bytes);
14159 if (rc != TPM_RC_SUCCESS) {
14160 return rc;
14161 }
14162 std::string mode_bytes;
14163 rc = Serialize_TPMI_ALG_SYM_MODE(mode, &mode_bytes);
14164 if (rc != TPM_RC_SUCCESS) {
14165 return rc;
14166 }
14167 std::string iv_in_bytes;
14168 rc = Serialize_TPM2B_IV(iv_in, &iv_in_bytes);
14169 if (rc != TPM_RC_SUCCESS) {
14170 return rc;
14171 }
14172 std::string in_data_bytes;
14173 rc = Serialize_TPM2B_MAX_BUFFER(in_data, &in_data_bytes);
14174 if (rc != TPM_RC_SUCCESS) {
14175 return rc;
14176 }
14177 std::unique_ptr<crypto::SecureHash> hash(
14178 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14179 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14180 hash->Update(key_handle_name.data(), key_handle_name.size());
14181 handle_section_bytes += key_handle_bytes;
14182 command_size += key_handle_bytes.size();
14183 hash->Update(decrypt_bytes.data(), decrypt_bytes.size());
14184 parameter_section_bytes += decrypt_bytes;
14185 command_size += decrypt_bytes.size();
14186 hash->Update(mode_bytes.data(), mode_bytes.size());
14187 parameter_section_bytes += mode_bytes;
14188 command_size += mode_bytes.size();
14189 hash->Update(iv_in_bytes.data(), iv_in_bytes.size());
14190 parameter_section_bytes += iv_in_bytes;
14191 command_size += iv_in_bytes.size();
14192 hash->Update(in_data_bytes.data(), in_data_bytes.size());
14193 parameter_section_bytes += in_data_bytes;
14194 command_size += in_data_bytes.size();
14195 std::string command_hash(32, 0);
14196 hash->Finish(std::data(command_hash), command_hash.size());
14197 std::string authorization_section_bytes;
14198 std::string authorization_size_bytes;
14199 if (authorization_delegate) {
14200 if (!authorization_delegate->GetCommandAuthorization(
14201 command_hash, is_command_parameter_encryption_possible,
14202 is_response_parameter_encryption_possible,
14203 &authorization_section_bytes)) {
14204 return TRUNKS_RC_AUTHORIZATION_FAILED;
14205 }
14206 if (!authorization_section_bytes.empty()) {
14207 tag = TPM_ST_SESSIONS;
14208 std::string tmp;
14209 rc = Serialize_UINT32(authorization_section_bytes.size(),
14210 &authorization_size_bytes);
14211 if (rc != TPM_RC_SUCCESS) {
14212 return rc;
14213 }
14214 command_size +=
14215 authorization_size_bytes.size() + authorization_section_bytes.size();
14216 }
14217 }
14218 std::string tag_bytes;
14219 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14220 if (rc != TPM_RC_SUCCESS) {
14221 return rc;
14222 }
14223 std::string command_size_bytes;
14224 rc = Serialize_UINT32(command_size, &command_size_bytes);
14225 if (rc != TPM_RC_SUCCESS) {
14226 return rc;
14227 }
14228 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14229 handle_section_bytes + authorization_size_bytes +
14230 authorization_section_bytes + parameter_section_bytes;
14231 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14232 VLOG(2) << "Command: "
14233 << base::HexEncode(serialized_command->data(),
14234 serialized_command->size());
14235 return TPM_RC_SUCCESS;
14236 }
14237
ParseResponse_EncryptDecrypt(const std::string & response,TPM2B_MAX_BUFFER * out_data,TPM2B_IV * iv_out,AuthorizationDelegate * authorization_delegate)14238 TPM_RC Tpm::ParseResponse_EncryptDecrypt(
14239 const std::string& response,
14240 TPM2B_MAX_BUFFER* out_data,
14241 TPM2B_IV* iv_out,
14242 AuthorizationDelegate* authorization_delegate) {
14243 VLOG(3) << __func__;
14244 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14245 TPM_RC rc = TPM_RC_SUCCESS;
14246 std::string buffer(response);
14247 TPM_ST tag;
14248 std::string tag_bytes;
14249 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14250 if (rc != TPM_RC_SUCCESS) {
14251 return rc;
14252 }
14253 UINT32 response_size;
14254 std::string response_size_bytes;
14255 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14256 if (rc != TPM_RC_SUCCESS) {
14257 return rc;
14258 }
14259 TPM_RC response_code;
14260 std::string response_code_bytes;
14261 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14262 if (rc != TPM_RC_SUCCESS) {
14263 return rc;
14264 }
14265 if (response_size != response.size()) {
14266 return TPM_RC_SIZE;
14267 }
14268 if (response_code != TPM_RC_SUCCESS) {
14269 return response_code;
14270 }
14271 TPM_CC command_code = TPM_CC_EncryptDecrypt;
14272 std::string command_code_bytes;
14273 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14274 if (rc != TPM_RC_SUCCESS) {
14275 return rc;
14276 }
14277 std::string authorization_section_bytes;
14278 if (tag == TPM_ST_SESSIONS) {
14279 UINT32 parameter_section_size = buffer.size();
14280 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
14281 if (rc != TPM_RC_SUCCESS) {
14282 return rc;
14283 }
14284 if (parameter_section_size > buffer.size()) {
14285 return TPM_RC_INSUFFICIENT;
14286 }
14287 authorization_section_bytes = buffer.substr(parameter_section_size);
14288 // Keep the parameter section in |buffer|.
14289 buffer.erase(parameter_section_size);
14290 }
14291 std::unique_ptr<crypto::SecureHash> hash(
14292 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14293 hash->Update(response_code_bytes.data(), response_code_bytes.size());
14294 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14295 hash->Update(buffer.data(), buffer.size());
14296 std::string response_hash(32, 0);
14297 hash->Finish(std::data(response_hash), response_hash.size());
14298 if (tag == TPM_ST_SESSIONS) {
14299 if (!authorization_delegate)
14300 return TRUNKS_RC_AUTHORIZATION_FAILED;
14301 if (!authorization_delegate->CheckResponseAuthorization(
14302 response_hash, authorization_section_bytes)) {
14303 return TRUNKS_RC_AUTHORIZATION_FAILED;
14304 }
14305 }
14306 if (tag == TPM_ST_SESSIONS) {
14307 if (!authorization_delegate)
14308 return TRUNKS_RC_AUTHORIZATION_FAILED;
14309
14310 // Parse the encrypted parameter size.
14311 UINT16 size;
14312 std::string size_buffer = buffer.substr(0, 2);
14313 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14314 return result;
14315 }
14316 if (buffer.size() < 2 + size) {
14317 return TPM_RC_INSUFFICIENT;
14318 }
14319
14320 // Decrypt just the parameter data, not the size.
14321 std::string decrypted_data = buffer.substr(2, size);
14322 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14323 return TRUNKS_RC_ENCRYPTION_FAILED;
14324 }
14325 buffer.replace(2, size, decrypted_data);
14326 }
14327 std::string out_data_bytes;
14328 rc = Parse_TPM2B_MAX_BUFFER(&buffer, out_data, &out_data_bytes);
14329 if (rc != TPM_RC_SUCCESS) {
14330 return rc;
14331 }
14332 std::string iv_out_bytes;
14333 rc = Parse_TPM2B_IV(&buffer, iv_out, &iv_out_bytes);
14334 if (rc != TPM_RC_SUCCESS) {
14335 return rc;
14336 }
14337 return TPM_RC_SUCCESS;
14338 }
14339
EncryptDecryptErrorCallback(Tpm::EncryptDecryptResponse callback,TPM_RC response_code)14340 void EncryptDecryptErrorCallback(Tpm::EncryptDecryptResponse callback,
14341 TPM_RC response_code) {
14342 VLOG(1) << __func__;
14343 std::move(callback).Run(response_code, TPM2B_MAX_BUFFER(), TPM2B_IV());
14344 }
14345
EncryptDecryptResponseParser(Tpm::EncryptDecryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14346 void EncryptDecryptResponseParser(Tpm::EncryptDecryptResponse callback,
14347 AuthorizationDelegate* authorization_delegate,
14348 const std::string& response) {
14349 VLOG(1) << __func__;
14350 TPM2B_MAX_BUFFER out_data;
14351 TPM2B_IV iv_out;
14352 TPM_RC rc = Tpm::ParseResponse_EncryptDecrypt(response, &out_data, &iv_out,
14353 authorization_delegate);
14354 if (rc != TPM_RC_SUCCESS) {
14355 base::OnceCallback<void(TPM_RC)> error_reporter =
14356 base::BindOnce(EncryptDecryptErrorCallback, std::move(callback));
14357 std::move(error_reporter).Run(rc);
14358 return;
14359 }
14360 std::move(callback).Run(rc, out_data, iv_out);
14361 }
14362
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)14363 void Tpm::EncryptDecrypt(const TPMI_DH_OBJECT& key_handle,
14364 const std::string& key_handle_name,
14365 const TPMI_YES_NO& decrypt,
14366 const TPMI_ALG_SYM_MODE& mode,
14367 const TPM2B_IV& iv_in,
14368 const TPM2B_MAX_BUFFER& in_data,
14369 AuthorizationDelegate* authorization_delegate,
14370 EncryptDecryptResponse callback) {
14371 VLOG(1) << __func__;
14372 std::string command;
14373 TPM_RC rc = SerializeCommand_EncryptDecrypt(key_handle, key_handle_name,
14374 decrypt, mode, iv_in, in_data,
14375 &command, authorization_delegate);
14376 if (rc != TPM_RC_SUCCESS) {
14377 base::OnceCallback<void(TPM_RC)> error_reporter =
14378 base::BindOnce(EncryptDecryptErrorCallback, std::move(callback));
14379 std::move(error_reporter).Run(rc);
14380 return;
14381 }
14382 base::OnceCallback<void(const std::string&)> parser =
14383 base::BindOnce(EncryptDecryptResponseParser, std::move(callback),
14384 authorization_delegate);
14385 transceiver_->SendCommand(command, std::move(parser));
14386 }
14387
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)14388 TPM_RC Tpm::EncryptDecryptSync(const TPMI_DH_OBJECT& key_handle,
14389 const std::string& key_handle_name,
14390 const TPMI_YES_NO& decrypt,
14391 const TPMI_ALG_SYM_MODE& mode,
14392 const TPM2B_IV& iv_in,
14393 const TPM2B_MAX_BUFFER& in_data,
14394 TPM2B_MAX_BUFFER* out_data,
14395 TPM2B_IV* iv_out,
14396 AuthorizationDelegate* authorization_delegate) {
14397 VLOG(1) << __func__;
14398 std::string command;
14399 TPM_RC rc = SerializeCommand_EncryptDecrypt(key_handle, key_handle_name,
14400 decrypt, mode, iv_in, in_data,
14401 &command, authorization_delegate);
14402 if (rc != TPM_RC_SUCCESS) {
14403 return rc;
14404 }
14405 std::string response = transceiver_->SendCommandAndWait(command);
14406 rc = ParseResponse_EncryptDecrypt(response, out_data, iv_out,
14407 authorization_delegate);
14408 return rc;
14409 }
14410
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)14411 TPM_RC Tpm::SerializeCommand_Hash(
14412 const TPM2B_MAX_BUFFER& data,
14413 const TPMI_ALG_HASH& hash_alg,
14414 const TPMI_RH_HIERARCHY& hierarchy,
14415 std::string* serialized_command,
14416 AuthorizationDelegate* authorization_delegate) {
14417 VLOG(3) << __func__;
14418 TPM_RC rc = TPM_RC_SUCCESS;
14419 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14420 UINT32 command_size = 10; // Header size.
14421 std::string handle_section_bytes;
14422 std::string parameter_section_bytes;
14423 TPM_CC command_code = TPM_CC_Hash;
14424 bool is_command_parameter_encryption_possible = true;
14425 bool is_response_parameter_encryption_possible = true;
14426 std::string command_code_bytes;
14427 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14428 if (rc != TPM_RC_SUCCESS) {
14429 return rc;
14430 }
14431 std::string data_bytes;
14432 rc = Serialize_TPM2B_MAX_BUFFER(data, &data_bytes);
14433 if (rc != TPM_RC_SUCCESS) {
14434 return rc;
14435 }
14436 std::string hash_alg_bytes;
14437 rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
14438 if (rc != TPM_RC_SUCCESS) {
14439 return rc;
14440 }
14441 std::string hierarchy_bytes;
14442 rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
14443 if (rc != TPM_RC_SUCCESS) {
14444 return rc;
14445 }
14446 if (authorization_delegate) {
14447 // Encrypt just the parameter data, not the size.
14448 std::string tmp = data_bytes.substr(2);
14449 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14450 return TRUNKS_RC_ENCRYPTION_FAILED;
14451 }
14452 data_bytes.replace(2, std::string::npos, tmp);
14453 }
14454 std::unique_ptr<crypto::SecureHash> hash(
14455 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14456 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14457 hash->Update(data_bytes.data(), data_bytes.size());
14458 parameter_section_bytes += data_bytes;
14459 command_size += data_bytes.size();
14460 hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
14461 parameter_section_bytes += hash_alg_bytes;
14462 command_size += hash_alg_bytes.size();
14463 hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
14464 parameter_section_bytes += hierarchy_bytes;
14465 command_size += hierarchy_bytes.size();
14466 std::string command_hash(32, 0);
14467 hash->Finish(std::data(command_hash), command_hash.size());
14468 std::string authorization_section_bytes;
14469 std::string authorization_size_bytes;
14470 if (authorization_delegate) {
14471 if (!authorization_delegate->GetCommandAuthorization(
14472 command_hash, is_command_parameter_encryption_possible,
14473 is_response_parameter_encryption_possible,
14474 &authorization_section_bytes)) {
14475 return TRUNKS_RC_AUTHORIZATION_FAILED;
14476 }
14477 if (!authorization_section_bytes.empty()) {
14478 tag = TPM_ST_SESSIONS;
14479 std::string tmp;
14480 rc = Serialize_UINT32(authorization_section_bytes.size(),
14481 &authorization_size_bytes);
14482 if (rc != TPM_RC_SUCCESS) {
14483 return rc;
14484 }
14485 command_size +=
14486 authorization_size_bytes.size() + authorization_section_bytes.size();
14487 }
14488 }
14489 std::string tag_bytes;
14490 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14491 if (rc != TPM_RC_SUCCESS) {
14492 return rc;
14493 }
14494 std::string command_size_bytes;
14495 rc = Serialize_UINT32(command_size, &command_size_bytes);
14496 if (rc != TPM_RC_SUCCESS) {
14497 return rc;
14498 }
14499 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14500 handle_section_bytes + authorization_size_bytes +
14501 authorization_section_bytes + parameter_section_bytes;
14502 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14503 VLOG(2) << "Command: "
14504 << base::HexEncode(serialized_command->data(),
14505 serialized_command->size());
14506 return TPM_RC_SUCCESS;
14507 }
14508
ParseResponse_Hash(const std::string & response,TPM2B_DIGEST * out_hash,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)14509 TPM_RC Tpm::ParseResponse_Hash(const std::string& response,
14510 TPM2B_DIGEST* out_hash,
14511 TPMT_TK_HASHCHECK* validation,
14512 AuthorizationDelegate* authorization_delegate) {
14513 VLOG(3) << __func__;
14514 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14515 TPM_RC rc = TPM_RC_SUCCESS;
14516 std::string buffer(response);
14517 TPM_ST tag;
14518 std::string tag_bytes;
14519 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14520 if (rc != TPM_RC_SUCCESS) {
14521 return rc;
14522 }
14523 UINT32 response_size;
14524 std::string response_size_bytes;
14525 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14526 if (rc != TPM_RC_SUCCESS) {
14527 return rc;
14528 }
14529 TPM_RC response_code;
14530 std::string response_code_bytes;
14531 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14532 if (rc != TPM_RC_SUCCESS) {
14533 return rc;
14534 }
14535 if (response_size != response.size()) {
14536 return TPM_RC_SIZE;
14537 }
14538 if (response_code != TPM_RC_SUCCESS) {
14539 return response_code;
14540 }
14541 TPM_CC command_code = TPM_CC_Hash;
14542 std::string command_code_bytes;
14543 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14544 if (rc != TPM_RC_SUCCESS) {
14545 return rc;
14546 }
14547 std::string authorization_section_bytes;
14548 if (tag == TPM_ST_SESSIONS) {
14549 UINT32 parameter_section_size = buffer.size();
14550 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
14551 if (rc != TPM_RC_SUCCESS) {
14552 return rc;
14553 }
14554 if (parameter_section_size > buffer.size()) {
14555 return TPM_RC_INSUFFICIENT;
14556 }
14557 authorization_section_bytes = buffer.substr(parameter_section_size);
14558 // Keep the parameter section in |buffer|.
14559 buffer.erase(parameter_section_size);
14560 }
14561 std::unique_ptr<crypto::SecureHash> hash(
14562 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14563 hash->Update(response_code_bytes.data(), response_code_bytes.size());
14564 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14565 hash->Update(buffer.data(), buffer.size());
14566 std::string response_hash(32, 0);
14567 hash->Finish(std::data(response_hash), response_hash.size());
14568 if (tag == TPM_ST_SESSIONS) {
14569 if (!authorization_delegate)
14570 return TRUNKS_RC_AUTHORIZATION_FAILED;
14571 if (!authorization_delegate->CheckResponseAuthorization(
14572 response_hash, authorization_section_bytes)) {
14573 return TRUNKS_RC_AUTHORIZATION_FAILED;
14574 }
14575 }
14576 if (tag == TPM_ST_SESSIONS) {
14577 if (!authorization_delegate)
14578 return TRUNKS_RC_AUTHORIZATION_FAILED;
14579
14580 // Parse the encrypted parameter size.
14581 UINT16 size;
14582 std::string size_buffer = buffer.substr(0, 2);
14583 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14584 return result;
14585 }
14586 if (buffer.size() < 2 + size) {
14587 return TPM_RC_INSUFFICIENT;
14588 }
14589
14590 // Decrypt just the parameter data, not the size.
14591 std::string decrypted_data = buffer.substr(2, size);
14592 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14593 return TRUNKS_RC_ENCRYPTION_FAILED;
14594 }
14595 buffer.replace(2, size, decrypted_data);
14596 }
14597 std::string out_hash_bytes;
14598 rc = Parse_TPM2B_DIGEST(&buffer, out_hash, &out_hash_bytes);
14599 if (rc != TPM_RC_SUCCESS) {
14600 return rc;
14601 }
14602 std::string validation_bytes;
14603 rc = Parse_TPMT_TK_HASHCHECK(&buffer, validation, &validation_bytes);
14604 if (rc != TPM_RC_SUCCESS) {
14605 return rc;
14606 }
14607 return TPM_RC_SUCCESS;
14608 }
14609
HashErrorCallback(Tpm::HashResponse callback,TPM_RC response_code)14610 void HashErrorCallback(Tpm::HashResponse callback, TPM_RC response_code) {
14611 VLOG(1) << __func__;
14612 std::move(callback).Run(response_code, TPM2B_DIGEST(), TPMT_TK_HASHCHECK());
14613 }
14614
HashResponseParser(Tpm::HashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14615 void HashResponseParser(Tpm::HashResponse callback,
14616 AuthorizationDelegate* authorization_delegate,
14617 const std::string& response) {
14618 VLOG(1) << __func__;
14619 TPM2B_DIGEST out_hash;
14620 TPMT_TK_HASHCHECK validation;
14621 TPM_RC rc = Tpm::ParseResponse_Hash(response, &out_hash, &validation,
14622 authorization_delegate);
14623 if (rc != TPM_RC_SUCCESS) {
14624 base::OnceCallback<void(TPM_RC)> error_reporter =
14625 base::BindOnce(HashErrorCallback, std::move(callback));
14626 std::move(error_reporter).Run(rc);
14627 return;
14628 }
14629 std::move(callback).Run(rc, out_hash, validation);
14630 }
14631
Hash(const TPM2B_MAX_BUFFER & data,const TPMI_ALG_HASH & hash_alg,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,HashResponse callback)14632 void Tpm::Hash(const TPM2B_MAX_BUFFER& data,
14633 const TPMI_ALG_HASH& hash_alg,
14634 const TPMI_RH_HIERARCHY& hierarchy,
14635 AuthorizationDelegate* authorization_delegate,
14636 HashResponse callback) {
14637 VLOG(1) << __func__;
14638 std::string command;
14639 TPM_RC rc = SerializeCommand_Hash(data, hash_alg, hierarchy, &command,
14640 authorization_delegate);
14641 if (rc != TPM_RC_SUCCESS) {
14642 base::OnceCallback<void(TPM_RC)> error_reporter =
14643 base::BindOnce(HashErrorCallback, std::move(callback));
14644 std::move(error_reporter).Run(rc);
14645 return;
14646 }
14647 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14648 HashResponseParser, std::move(callback), authorization_delegate);
14649 transceiver_->SendCommand(command, std::move(parser));
14650 }
14651
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)14652 TPM_RC Tpm::HashSync(const TPM2B_MAX_BUFFER& data,
14653 const TPMI_ALG_HASH& hash_alg,
14654 const TPMI_RH_HIERARCHY& hierarchy,
14655 TPM2B_DIGEST* out_hash,
14656 TPMT_TK_HASHCHECK* validation,
14657 AuthorizationDelegate* authorization_delegate) {
14658 VLOG(1) << __func__;
14659 std::string command;
14660 TPM_RC rc = SerializeCommand_Hash(data, hash_alg, hierarchy, &command,
14661 authorization_delegate);
14662 if (rc != TPM_RC_SUCCESS) {
14663 return rc;
14664 }
14665 std::string response = transceiver_->SendCommandAndWait(command);
14666 rc = ParseResponse_Hash(response, out_hash, validation,
14667 authorization_delegate);
14668 return rc;
14669 }
14670
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)14671 TPM_RC Tpm::SerializeCommand_HMAC(
14672 const TPMI_DH_OBJECT& handle,
14673 const std::string& handle_name,
14674 const TPM2B_MAX_BUFFER& buffer,
14675 const TPMI_ALG_HASH& hash_alg,
14676 std::string* serialized_command,
14677 AuthorizationDelegate* authorization_delegate) {
14678 VLOG(3) << __func__;
14679 TPM_RC rc = TPM_RC_SUCCESS;
14680 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14681 UINT32 command_size = 10; // Header size.
14682 std::string handle_section_bytes;
14683 std::string parameter_section_bytes;
14684 TPM_CC command_code = TPM_CC_HMAC;
14685 bool is_command_parameter_encryption_possible = true;
14686 bool is_response_parameter_encryption_possible = true;
14687 std::string command_code_bytes;
14688 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14689 if (rc != TPM_RC_SUCCESS) {
14690 return rc;
14691 }
14692 std::string handle_bytes;
14693 rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
14694 if (rc != TPM_RC_SUCCESS) {
14695 return rc;
14696 }
14697 std::string buffer_bytes;
14698 rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
14699 if (rc != TPM_RC_SUCCESS) {
14700 return rc;
14701 }
14702 std::string hash_alg_bytes;
14703 rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
14704 if (rc != TPM_RC_SUCCESS) {
14705 return rc;
14706 }
14707 if (authorization_delegate) {
14708 // Encrypt just the parameter data, not the size.
14709 std::string tmp = buffer_bytes.substr(2);
14710 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14711 return TRUNKS_RC_ENCRYPTION_FAILED;
14712 }
14713 buffer_bytes.replace(2, std::string::npos, tmp);
14714 }
14715 std::unique_ptr<crypto::SecureHash> hash(
14716 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14717 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14718 hash->Update(handle_name.data(), handle_name.size());
14719 handle_section_bytes += handle_bytes;
14720 command_size += handle_bytes.size();
14721 hash->Update(buffer_bytes.data(), buffer_bytes.size());
14722 parameter_section_bytes += buffer_bytes;
14723 command_size += buffer_bytes.size();
14724 hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
14725 parameter_section_bytes += hash_alg_bytes;
14726 command_size += hash_alg_bytes.size();
14727 std::string command_hash(32, 0);
14728 hash->Finish(std::data(command_hash), command_hash.size());
14729 std::string authorization_section_bytes;
14730 std::string authorization_size_bytes;
14731 if (authorization_delegate) {
14732 if (!authorization_delegate->GetCommandAuthorization(
14733 command_hash, is_command_parameter_encryption_possible,
14734 is_response_parameter_encryption_possible,
14735 &authorization_section_bytes)) {
14736 return TRUNKS_RC_AUTHORIZATION_FAILED;
14737 }
14738 if (!authorization_section_bytes.empty()) {
14739 tag = TPM_ST_SESSIONS;
14740 std::string tmp;
14741 rc = Serialize_UINT32(authorization_section_bytes.size(),
14742 &authorization_size_bytes);
14743 if (rc != TPM_RC_SUCCESS) {
14744 return rc;
14745 }
14746 command_size +=
14747 authorization_size_bytes.size() + authorization_section_bytes.size();
14748 }
14749 }
14750 std::string tag_bytes;
14751 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14752 if (rc != TPM_RC_SUCCESS) {
14753 return rc;
14754 }
14755 std::string command_size_bytes;
14756 rc = Serialize_UINT32(command_size, &command_size_bytes);
14757 if (rc != TPM_RC_SUCCESS) {
14758 return rc;
14759 }
14760 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14761 handle_section_bytes + authorization_size_bytes +
14762 authorization_section_bytes + parameter_section_bytes;
14763 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14764 VLOG(2) << "Command: "
14765 << base::HexEncode(serialized_command->data(),
14766 serialized_command->size());
14767 return TPM_RC_SUCCESS;
14768 }
14769
ParseResponse_HMAC(const std::string & response,TPM2B_DIGEST * out_hmac,AuthorizationDelegate * authorization_delegate)14770 TPM_RC Tpm::ParseResponse_HMAC(const std::string& response,
14771 TPM2B_DIGEST* out_hmac,
14772 AuthorizationDelegate* authorization_delegate) {
14773 VLOG(3) << __func__;
14774 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14775 TPM_RC rc = TPM_RC_SUCCESS;
14776 std::string buffer(response);
14777 TPM_ST tag;
14778 std::string tag_bytes;
14779 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14780 if (rc != TPM_RC_SUCCESS) {
14781 return rc;
14782 }
14783 UINT32 response_size;
14784 std::string response_size_bytes;
14785 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14786 if (rc != TPM_RC_SUCCESS) {
14787 return rc;
14788 }
14789 TPM_RC response_code;
14790 std::string response_code_bytes;
14791 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14792 if (rc != TPM_RC_SUCCESS) {
14793 return rc;
14794 }
14795 if (response_size != response.size()) {
14796 return TPM_RC_SIZE;
14797 }
14798 if (response_code != TPM_RC_SUCCESS) {
14799 return response_code;
14800 }
14801 TPM_CC command_code = TPM_CC_HMAC;
14802 std::string command_code_bytes;
14803 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14804 if (rc != TPM_RC_SUCCESS) {
14805 return rc;
14806 }
14807 std::string authorization_section_bytes;
14808 if (tag == TPM_ST_SESSIONS) {
14809 UINT32 parameter_section_size = buffer.size();
14810 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
14811 if (rc != TPM_RC_SUCCESS) {
14812 return rc;
14813 }
14814 if (parameter_section_size > buffer.size()) {
14815 return TPM_RC_INSUFFICIENT;
14816 }
14817 authorization_section_bytes = buffer.substr(parameter_section_size);
14818 // Keep the parameter section in |buffer|.
14819 buffer.erase(parameter_section_size);
14820 }
14821 std::unique_ptr<crypto::SecureHash> hash(
14822 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14823 hash->Update(response_code_bytes.data(), response_code_bytes.size());
14824 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14825 hash->Update(buffer.data(), buffer.size());
14826 std::string response_hash(32, 0);
14827 hash->Finish(std::data(response_hash), response_hash.size());
14828 if (tag == TPM_ST_SESSIONS) {
14829 if (!authorization_delegate)
14830 return TRUNKS_RC_AUTHORIZATION_FAILED;
14831 if (!authorization_delegate->CheckResponseAuthorization(
14832 response_hash, authorization_section_bytes)) {
14833 return TRUNKS_RC_AUTHORIZATION_FAILED;
14834 }
14835 }
14836 if (tag == TPM_ST_SESSIONS) {
14837 if (!authorization_delegate)
14838 return TRUNKS_RC_AUTHORIZATION_FAILED;
14839
14840 // Parse the encrypted parameter size.
14841 UINT16 size;
14842 std::string size_buffer = buffer.substr(0, 2);
14843 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14844 return result;
14845 }
14846 if (buffer.size() < 2 + size) {
14847 return TPM_RC_INSUFFICIENT;
14848 }
14849
14850 // Decrypt just the parameter data, not the size.
14851 std::string decrypted_data = buffer.substr(2, size);
14852 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14853 return TRUNKS_RC_ENCRYPTION_FAILED;
14854 }
14855 buffer.replace(2, size, decrypted_data);
14856 }
14857 std::string out_hmac_bytes;
14858 rc = Parse_TPM2B_DIGEST(&buffer, out_hmac, &out_hmac_bytes);
14859 if (rc != TPM_RC_SUCCESS) {
14860 return rc;
14861 }
14862 return TPM_RC_SUCCESS;
14863 }
14864
HMACErrorCallback(Tpm::HMACResponse callback,TPM_RC response_code)14865 void HMACErrorCallback(Tpm::HMACResponse callback, TPM_RC response_code) {
14866 VLOG(1) << __func__;
14867 std::move(callback).Run(response_code, TPM2B_DIGEST());
14868 }
14869
HMACResponseParser(Tpm::HMACResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14870 void HMACResponseParser(Tpm::HMACResponse callback,
14871 AuthorizationDelegate* authorization_delegate,
14872 const std::string& response) {
14873 VLOG(1) << __func__;
14874 TPM2B_DIGEST out_hmac;
14875 TPM_RC rc =
14876 Tpm::ParseResponse_HMAC(response, &out_hmac, authorization_delegate);
14877 if (rc != TPM_RC_SUCCESS) {
14878 base::OnceCallback<void(TPM_RC)> error_reporter =
14879 base::BindOnce(HMACErrorCallback, std::move(callback));
14880 std::move(error_reporter).Run(rc);
14881 return;
14882 }
14883 std::move(callback).Run(rc, out_hmac);
14884 }
14885
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)14886 void Tpm::HMAC(const TPMI_DH_OBJECT& handle,
14887 const std::string& handle_name,
14888 const TPM2B_MAX_BUFFER& buffer,
14889 const TPMI_ALG_HASH& hash_alg,
14890 AuthorizationDelegate* authorization_delegate,
14891 HMACResponse callback) {
14892 VLOG(1) << __func__;
14893 std::string command;
14894 TPM_RC rc = SerializeCommand_HMAC(handle, handle_name, buffer, hash_alg,
14895 &command, authorization_delegate);
14896 if (rc != TPM_RC_SUCCESS) {
14897 base::OnceCallback<void(TPM_RC)> error_reporter =
14898 base::BindOnce(HMACErrorCallback, std::move(callback));
14899 std::move(error_reporter).Run(rc);
14900 return;
14901 }
14902 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14903 HMACResponseParser, std::move(callback), authorization_delegate);
14904 transceiver_->SendCommand(command, std::move(parser));
14905 }
14906
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)14907 TPM_RC Tpm::HMACSync(const TPMI_DH_OBJECT& handle,
14908 const std::string& handle_name,
14909 const TPM2B_MAX_BUFFER& buffer,
14910 const TPMI_ALG_HASH& hash_alg,
14911 TPM2B_DIGEST* out_hmac,
14912 AuthorizationDelegate* authorization_delegate) {
14913 VLOG(1) << __func__;
14914 std::string command;
14915 TPM_RC rc = SerializeCommand_HMAC(handle, handle_name, buffer, hash_alg,
14916 &command, authorization_delegate);
14917 if (rc != TPM_RC_SUCCESS) {
14918 return rc;
14919 }
14920 std::string response = transceiver_->SendCommandAndWait(command);
14921 rc = ParseResponse_HMAC(response, out_hmac, authorization_delegate);
14922 return rc;
14923 }
14924
SerializeCommand_GetRandom(const UINT16 & bytes_requested,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14925 TPM_RC Tpm::SerializeCommand_GetRandom(
14926 const UINT16& bytes_requested,
14927 std::string* serialized_command,
14928 AuthorizationDelegate* authorization_delegate) {
14929 VLOG(3) << __func__;
14930 TPM_RC rc = TPM_RC_SUCCESS;
14931 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14932 UINT32 command_size = 10; // Header size.
14933 std::string handle_section_bytes;
14934 std::string parameter_section_bytes;
14935 TPM_CC command_code = TPM_CC_GetRandom;
14936 bool is_command_parameter_encryption_possible = false;
14937 bool is_response_parameter_encryption_possible = true;
14938 std::string command_code_bytes;
14939 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14940 if (rc != TPM_RC_SUCCESS) {
14941 return rc;
14942 }
14943 std::string bytes_requested_bytes;
14944 rc = Serialize_UINT16(bytes_requested, &bytes_requested_bytes);
14945 if (rc != TPM_RC_SUCCESS) {
14946 return rc;
14947 }
14948 std::unique_ptr<crypto::SecureHash> hash(
14949 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14950 hash->Update(command_code_bytes.data(), command_code_bytes.size());
14951 hash->Update(bytes_requested_bytes.data(), bytes_requested_bytes.size());
14952 parameter_section_bytes += bytes_requested_bytes;
14953 command_size += bytes_requested_bytes.size();
14954 std::string command_hash(32, 0);
14955 hash->Finish(std::data(command_hash), command_hash.size());
14956 std::string authorization_section_bytes;
14957 std::string authorization_size_bytes;
14958 if (authorization_delegate) {
14959 if (!authorization_delegate->GetCommandAuthorization(
14960 command_hash, is_command_parameter_encryption_possible,
14961 is_response_parameter_encryption_possible,
14962 &authorization_section_bytes)) {
14963 return TRUNKS_RC_AUTHORIZATION_FAILED;
14964 }
14965 if (!authorization_section_bytes.empty()) {
14966 tag = TPM_ST_SESSIONS;
14967 std::string tmp;
14968 rc = Serialize_UINT32(authorization_section_bytes.size(),
14969 &authorization_size_bytes);
14970 if (rc != TPM_RC_SUCCESS) {
14971 return rc;
14972 }
14973 command_size +=
14974 authorization_size_bytes.size() + authorization_section_bytes.size();
14975 }
14976 }
14977 std::string tag_bytes;
14978 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14979 if (rc != TPM_RC_SUCCESS) {
14980 return rc;
14981 }
14982 std::string command_size_bytes;
14983 rc = Serialize_UINT32(command_size, &command_size_bytes);
14984 if (rc != TPM_RC_SUCCESS) {
14985 return rc;
14986 }
14987 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14988 handle_section_bytes + authorization_size_bytes +
14989 authorization_section_bytes + parameter_section_bytes;
14990 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14991 VLOG(2) << "Command: "
14992 << base::HexEncode(serialized_command->data(),
14993 serialized_command->size());
14994 return TPM_RC_SUCCESS;
14995 }
14996
ParseResponse_GetRandom(const std::string & response,TPM2B_DIGEST * random_bytes,AuthorizationDelegate * authorization_delegate)14997 TPM_RC Tpm::ParseResponse_GetRandom(
14998 const std::string& response,
14999 TPM2B_DIGEST* random_bytes,
15000 AuthorizationDelegate* authorization_delegate) {
15001 VLOG(3) << __func__;
15002 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15003 TPM_RC rc = TPM_RC_SUCCESS;
15004 std::string buffer(response);
15005 TPM_ST tag;
15006 std::string tag_bytes;
15007 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15008 if (rc != TPM_RC_SUCCESS) {
15009 return rc;
15010 }
15011 UINT32 response_size;
15012 std::string response_size_bytes;
15013 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15014 if (rc != TPM_RC_SUCCESS) {
15015 return rc;
15016 }
15017 TPM_RC response_code;
15018 std::string response_code_bytes;
15019 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15020 if (rc != TPM_RC_SUCCESS) {
15021 return rc;
15022 }
15023 if (response_size != response.size()) {
15024 return TPM_RC_SIZE;
15025 }
15026 if (response_code != TPM_RC_SUCCESS) {
15027 return response_code;
15028 }
15029 TPM_CC command_code = TPM_CC_GetRandom;
15030 std::string command_code_bytes;
15031 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15032 if (rc != TPM_RC_SUCCESS) {
15033 return rc;
15034 }
15035 std::string authorization_section_bytes;
15036 if (tag == TPM_ST_SESSIONS) {
15037 UINT32 parameter_section_size = buffer.size();
15038 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
15039 if (rc != TPM_RC_SUCCESS) {
15040 return rc;
15041 }
15042 if (parameter_section_size > buffer.size()) {
15043 return TPM_RC_INSUFFICIENT;
15044 }
15045 authorization_section_bytes = buffer.substr(parameter_section_size);
15046 // Keep the parameter section in |buffer|.
15047 buffer.erase(parameter_section_size);
15048 }
15049 std::unique_ptr<crypto::SecureHash> hash(
15050 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15051 hash->Update(response_code_bytes.data(), response_code_bytes.size());
15052 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15053 hash->Update(buffer.data(), buffer.size());
15054 std::string response_hash(32, 0);
15055 hash->Finish(std::data(response_hash), response_hash.size());
15056 if (tag == TPM_ST_SESSIONS) {
15057 if (!authorization_delegate)
15058 return TRUNKS_RC_AUTHORIZATION_FAILED;
15059 if (!authorization_delegate->CheckResponseAuthorization(
15060 response_hash, authorization_section_bytes)) {
15061 return TRUNKS_RC_AUTHORIZATION_FAILED;
15062 }
15063 }
15064 if (tag == TPM_ST_SESSIONS) {
15065 if (!authorization_delegate)
15066 return TRUNKS_RC_AUTHORIZATION_FAILED;
15067
15068 // Parse the encrypted parameter size.
15069 UINT16 size;
15070 std::string size_buffer = buffer.substr(0, 2);
15071 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
15072 return result;
15073 }
15074 if (buffer.size() < 2 + size) {
15075 return TPM_RC_INSUFFICIENT;
15076 }
15077
15078 // Decrypt just the parameter data, not the size.
15079 std::string decrypted_data = buffer.substr(2, size);
15080 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
15081 return TRUNKS_RC_ENCRYPTION_FAILED;
15082 }
15083 buffer.replace(2, size, decrypted_data);
15084 }
15085 std::string random_bytes_bytes;
15086 rc = Parse_TPM2B_DIGEST(&buffer, random_bytes, &random_bytes_bytes);
15087 if (rc != TPM_RC_SUCCESS) {
15088 return rc;
15089 }
15090 return TPM_RC_SUCCESS;
15091 }
15092
GetRandomErrorCallback(Tpm::GetRandomResponse callback,TPM_RC response_code)15093 void GetRandomErrorCallback(Tpm::GetRandomResponse callback,
15094 TPM_RC response_code) {
15095 VLOG(1) << __func__;
15096 std::move(callback).Run(response_code, TPM2B_DIGEST());
15097 }
15098
GetRandomResponseParser(Tpm::GetRandomResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15099 void GetRandomResponseParser(Tpm::GetRandomResponse callback,
15100 AuthorizationDelegate* authorization_delegate,
15101 const std::string& response) {
15102 VLOG(1) << __func__;
15103 TPM2B_DIGEST random_bytes;
15104 TPM_RC rc = Tpm::ParseResponse_GetRandom(response, &random_bytes,
15105 authorization_delegate);
15106 if (rc != TPM_RC_SUCCESS) {
15107 base::OnceCallback<void(TPM_RC)> error_reporter =
15108 base::BindOnce(GetRandomErrorCallback, std::move(callback));
15109 std::move(error_reporter).Run(rc);
15110 return;
15111 }
15112 std::move(callback).Run(rc, random_bytes);
15113 }
15114
GetRandom(const UINT16 & bytes_requested,AuthorizationDelegate * authorization_delegate,GetRandomResponse callback)15115 void Tpm::GetRandom(const UINT16& bytes_requested,
15116 AuthorizationDelegate* authorization_delegate,
15117 GetRandomResponse callback) {
15118 VLOG(1) << __func__;
15119 std::string command;
15120 TPM_RC rc = SerializeCommand_GetRandom(bytes_requested, &command,
15121 authorization_delegate);
15122 if (rc != TPM_RC_SUCCESS) {
15123 base::OnceCallback<void(TPM_RC)> error_reporter =
15124 base::BindOnce(GetRandomErrorCallback, std::move(callback));
15125 std::move(error_reporter).Run(rc);
15126 return;
15127 }
15128 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15129 GetRandomResponseParser, std::move(callback), authorization_delegate);
15130 transceiver_->SendCommand(command, std::move(parser));
15131 }
15132
GetRandomSync(const UINT16 & bytes_requested,TPM2B_DIGEST * random_bytes,AuthorizationDelegate * authorization_delegate)15133 TPM_RC Tpm::GetRandomSync(const UINT16& bytes_requested,
15134 TPM2B_DIGEST* random_bytes,
15135 AuthorizationDelegate* authorization_delegate) {
15136 VLOG(1) << __func__;
15137 std::string command;
15138 TPM_RC rc = SerializeCommand_GetRandom(bytes_requested, &command,
15139 authorization_delegate);
15140 if (rc != TPM_RC_SUCCESS) {
15141 return rc;
15142 }
15143 std::string response = transceiver_->SendCommandAndWait(command);
15144 rc = ParseResponse_GetRandom(response, random_bytes, authorization_delegate);
15145 return rc;
15146 }
15147
SerializeCommand_StirRandom(const TPM2B_SENSITIVE_DATA & in_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15148 TPM_RC Tpm::SerializeCommand_StirRandom(
15149 const TPM2B_SENSITIVE_DATA& in_data,
15150 std::string* serialized_command,
15151 AuthorizationDelegate* authorization_delegate) {
15152 VLOG(3) << __func__;
15153 TPM_RC rc = TPM_RC_SUCCESS;
15154 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15155 UINT32 command_size = 10; // Header size.
15156 std::string handle_section_bytes;
15157 std::string parameter_section_bytes;
15158 TPM_CC command_code = TPM_CC_StirRandom;
15159 bool is_command_parameter_encryption_possible = true;
15160 bool is_response_parameter_encryption_possible = false;
15161 std::string command_code_bytes;
15162 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15163 if (rc != TPM_RC_SUCCESS) {
15164 return rc;
15165 }
15166 std::string in_data_bytes;
15167 rc = Serialize_TPM2B_SENSITIVE_DATA(in_data, &in_data_bytes);
15168 if (rc != TPM_RC_SUCCESS) {
15169 return rc;
15170 }
15171 if (authorization_delegate) {
15172 // Encrypt just the parameter data, not the size.
15173 std::string tmp = in_data_bytes.substr(2);
15174 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15175 return TRUNKS_RC_ENCRYPTION_FAILED;
15176 }
15177 in_data_bytes.replace(2, std::string::npos, tmp);
15178 }
15179 std::unique_ptr<crypto::SecureHash> hash(
15180 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15181 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15182 hash->Update(in_data_bytes.data(), in_data_bytes.size());
15183 parameter_section_bytes += in_data_bytes;
15184 command_size += in_data_bytes.size();
15185 std::string command_hash(32, 0);
15186 hash->Finish(std::data(command_hash), command_hash.size());
15187 std::string authorization_section_bytes;
15188 std::string authorization_size_bytes;
15189 if (authorization_delegate) {
15190 if (!authorization_delegate->GetCommandAuthorization(
15191 command_hash, is_command_parameter_encryption_possible,
15192 is_response_parameter_encryption_possible,
15193 &authorization_section_bytes)) {
15194 return TRUNKS_RC_AUTHORIZATION_FAILED;
15195 }
15196 if (!authorization_section_bytes.empty()) {
15197 tag = TPM_ST_SESSIONS;
15198 std::string tmp;
15199 rc = Serialize_UINT32(authorization_section_bytes.size(),
15200 &authorization_size_bytes);
15201 if (rc != TPM_RC_SUCCESS) {
15202 return rc;
15203 }
15204 command_size +=
15205 authorization_size_bytes.size() + authorization_section_bytes.size();
15206 }
15207 }
15208 std::string tag_bytes;
15209 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15210 if (rc != TPM_RC_SUCCESS) {
15211 return rc;
15212 }
15213 std::string command_size_bytes;
15214 rc = Serialize_UINT32(command_size, &command_size_bytes);
15215 if (rc != TPM_RC_SUCCESS) {
15216 return rc;
15217 }
15218 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15219 handle_section_bytes + authorization_size_bytes +
15220 authorization_section_bytes + parameter_section_bytes;
15221 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15222 VLOG(2) << "Command: "
15223 << base::HexEncode(serialized_command->data(),
15224 serialized_command->size());
15225 return TPM_RC_SUCCESS;
15226 }
15227
ParseResponse_StirRandom(const std::string & response,AuthorizationDelegate * authorization_delegate)15228 TPM_RC Tpm::ParseResponse_StirRandom(
15229 const std::string& response,
15230 AuthorizationDelegate* authorization_delegate) {
15231 VLOG(3) << __func__;
15232 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15233 TPM_RC rc = TPM_RC_SUCCESS;
15234 std::string buffer(response);
15235 TPM_ST tag;
15236 std::string tag_bytes;
15237 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15238 if (rc != TPM_RC_SUCCESS) {
15239 return rc;
15240 }
15241 UINT32 response_size;
15242 std::string response_size_bytes;
15243 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15244 if (rc != TPM_RC_SUCCESS) {
15245 return rc;
15246 }
15247 TPM_RC response_code;
15248 std::string response_code_bytes;
15249 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15250 if (rc != TPM_RC_SUCCESS) {
15251 return rc;
15252 }
15253 if (response_size != response.size()) {
15254 return TPM_RC_SIZE;
15255 }
15256 if (response_code != TPM_RC_SUCCESS) {
15257 return response_code;
15258 }
15259 TPM_CC command_code = TPM_CC_StirRandom;
15260 std::string command_code_bytes;
15261 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15262 if (rc != TPM_RC_SUCCESS) {
15263 return rc;
15264 }
15265 std::string authorization_section_bytes;
15266 if (tag == TPM_ST_SESSIONS) {
15267 UINT32 parameter_section_size = buffer.size();
15268 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
15269 if (rc != TPM_RC_SUCCESS) {
15270 return rc;
15271 }
15272 if (parameter_section_size > buffer.size()) {
15273 return TPM_RC_INSUFFICIENT;
15274 }
15275 authorization_section_bytes = buffer.substr(parameter_section_size);
15276 // Keep the parameter section in |buffer|.
15277 buffer.erase(parameter_section_size);
15278 }
15279 std::unique_ptr<crypto::SecureHash> hash(
15280 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15281 hash->Update(response_code_bytes.data(), response_code_bytes.size());
15282 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15283 hash->Update(buffer.data(), buffer.size());
15284 std::string response_hash(32, 0);
15285 hash->Finish(std::data(response_hash), response_hash.size());
15286 if (tag == TPM_ST_SESSIONS) {
15287 if (!authorization_delegate)
15288 return TRUNKS_RC_AUTHORIZATION_FAILED;
15289 if (!authorization_delegate->CheckResponseAuthorization(
15290 response_hash, authorization_section_bytes)) {
15291 return TRUNKS_RC_AUTHORIZATION_FAILED;
15292 }
15293 }
15294 return TPM_RC_SUCCESS;
15295 }
15296
StirRandomErrorCallback(Tpm::StirRandomResponse callback,TPM_RC response_code)15297 void StirRandomErrorCallback(Tpm::StirRandomResponse callback,
15298 TPM_RC response_code) {
15299 VLOG(1) << __func__;
15300 std::move(callback).Run(response_code);
15301 }
15302
StirRandomResponseParser(Tpm::StirRandomResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15303 void StirRandomResponseParser(Tpm::StirRandomResponse callback,
15304 AuthorizationDelegate* authorization_delegate,
15305 const std::string& response) {
15306 VLOG(1) << __func__;
15307 TPM_RC rc = Tpm::ParseResponse_StirRandom(response, authorization_delegate);
15308 if (rc != TPM_RC_SUCCESS) {
15309 base::OnceCallback<void(TPM_RC)> error_reporter =
15310 base::BindOnce(StirRandomErrorCallback, std::move(callback));
15311 std::move(error_reporter).Run(rc);
15312 return;
15313 }
15314 std::move(callback).Run(rc);
15315 }
15316
StirRandom(const TPM2B_SENSITIVE_DATA & in_data,AuthorizationDelegate * authorization_delegate,StirRandomResponse callback)15317 void Tpm::StirRandom(const TPM2B_SENSITIVE_DATA& in_data,
15318 AuthorizationDelegate* authorization_delegate,
15319 StirRandomResponse callback) {
15320 VLOG(1) << __func__;
15321 std::string command;
15322 TPM_RC rc =
15323 SerializeCommand_StirRandom(in_data, &command, authorization_delegate);
15324 if (rc != TPM_RC_SUCCESS) {
15325 base::OnceCallback<void(TPM_RC)> error_reporter =
15326 base::BindOnce(StirRandomErrorCallback, std::move(callback));
15327 std::move(error_reporter).Run(rc);
15328 return;
15329 }
15330 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15331 StirRandomResponseParser, std::move(callback), authorization_delegate);
15332 transceiver_->SendCommand(command, std::move(parser));
15333 }
15334
StirRandomSync(const TPM2B_SENSITIVE_DATA & in_data,AuthorizationDelegate * authorization_delegate)15335 TPM_RC Tpm::StirRandomSync(const TPM2B_SENSITIVE_DATA& in_data,
15336 AuthorizationDelegate* authorization_delegate) {
15337 VLOG(1) << __func__;
15338 std::string command;
15339 TPM_RC rc =
15340 SerializeCommand_StirRandom(in_data, &command, authorization_delegate);
15341 if (rc != TPM_RC_SUCCESS) {
15342 return rc;
15343 }
15344 std::string response = transceiver_->SendCommandAndWait(command);
15345 rc = ParseResponse_StirRandom(response, authorization_delegate);
15346 return rc;
15347 }
15348
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)15349 TPM_RC Tpm::SerializeCommand_HMAC_Start(
15350 const TPMI_DH_OBJECT& handle,
15351 const std::string& handle_name,
15352 const TPM2B_AUTH& auth,
15353 const TPMI_ALG_HASH& hash_alg,
15354 std::string* serialized_command,
15355 AuthorizationDelegate* authorization_delegate) {
15356 VLOG(3) << __func__;
15357 TPM_RC rc = TPM_RC_SUCCESS;
15358 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15359 UINT32 command_size = 10; // Header size.
15360 std::string handle_section_bytes;
15361 std::string parameter_section_bytes;
15362 TPM_CC command_code = TPM_CC_HMAC_Start;
15363 bool is_command_parameter_encryption_possible = true;
15364 bool is_response_parameter_encryption_possible = false;
15365 std::string command_code_bytes;
15366 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15367 if (rc != TPM_RC_SUCCESS) {
15368 return rc;
15369 }
15370 std::string handle_bytes;
15371 rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
15372 if (rc != TPM_RC_SUCCESS) {
15373 return rc;
15374 }
15375 std::string auth_bytes;
15376 rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
15377 if (rc != TPM_RC_SUCCESS) {
15378 return rc;
15379 }
15380 std::string hash_alg_bytes;
15381 rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
15382 if (rc != TPM_RC_SUCCESS) {
15383 return rc;
15384 }
15385 if (authorization_delegate) {
15386 // Encrypt just the parameter data, not the size.
15387 std::string tmp = auth_bytes.substr(2);
15388 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15389 return TRUNKS_RC_ENCRYPTION_FAILED;
15390 }
15391 auth_bytes.replace(2, std::string::npos, tmp);
15392 }
15393 std::unique_ptr<crypto::SecureHash> hash(
15394 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15395 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15396 hash->Update(handle_name.data(), handle_name.size());
15397 handle_section_bytes += handle_bytes;
15398 command_size += handle_bytes.size();
15399 hash->Update(auth_bytes.data(), auth_bytes.size());
15400 parameter_section_bytes += auth_bytes;
15401 command_size += auth_bytes.size();
15402 hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
15403 parameter_section_bytes += hash_alg_bytes;
15404 command_size += hash_alg_bytes.size();
15405 std::string command_hash(32, 0);
15406 hash->Finish(std::data(command_hash), command_hash.size());
15407 std::string authorization_section_bytes;
15408 std::string authorization_size_bytes;
15409 if (authorization_delegate) {
15410 if (!authorization_delegate->GetCommandAuthorization(
15411 command_hash, is_command_parameter_encryption_possible,
15412 is_response_parameter_encryption_possible,
15413 &authorization_section_bytes)) {
15414 return TRUNKS_RC_AUTHORIZATION_FAILED;
15415 }
15416 if (!authorization_section_bytes.empty()) {
15417 tag = TPM_ST_SESSIONS;
15418 std::string tmp;
15419 rc = Serialize_UINT32(authorization_section_bytes.size(),
15420 &authorization_size_bytes);
15421 if (rc != TPM_RC_SUCCESS) {
15422 return rc;
15423 }
15424 command_size +=
15425 authorization_size_bytes.size() + authorization_section_bytes.size();
15426 }
15427 }
15428 std::string tag_bytes;
15429 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15430 if (rc != TPM_RC_SUCCESS) {
15431 return rc;
15432 }
15433 std::string command_size_bytes;
15434 rc = Serialize_UINT32(command_size, &command_size_bytes);
15435 if (rc != TPM_RC_SUCCESS) {
15436 return rc;
15437 }
15438 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15439 handle_section_bytes + authorization_size_bytes +
15440 authorization_section_bytes + parameter_section_bytes;
15441 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15442 VLOG(2) << "Command: "
15443 << base::HexEncode(serialized_command->data(),
15444 serialized_command->size());
15445 return TPM_RC_SUCCESS;
15446 }
15447
ParseResponse_HMAC_Start(const std::string & response,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15448 TPM_RC Tpm::ParseResponse_HMAC_Start(
15449 const std::string& response,
15450 TPMI_DH_OBJECT* sequence_handle,
15451 AuthorizationDelegate* authorization_delegate) {
15452 VLOG(3) << __func__;
15453 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15454 TPM_RC rc = TPM_RC_SUCCESS;
15455 std::string buffer(response);
15456 TPM_ST tag;
15457 std::string tag_bytes;
15458 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15459 if (rc != TPM_RC_SUCCESS) {
15460 return rc;
15461 }
15462 UINT32 response_size;
15463 std::string response_size_bytes;
15464 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15465 if (rc != TPM_RC_SUCCESS) {
15466 return rc;
15467 }
15468 TPM_RC response_code;
15469 std::string response_code_bytes;
15470 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15471 if (rc != TPM_RC_SUCCESS) {
15472 return rc;
15473 }
15474 if (response_size != response.size()) {
15475 return TPM_RC_SIZE;
15476 }
15477 if (response_code != TPM_RC_SUCCESS) {
15478 return response_code;
15479 }
15480 std::string sequence_handle_bytes;
15481 rc = Parse_TPMI_DH_OBJECT(&buffer, sequence_handle, &sequence_handle_bytes);
15482 if (rc != TPM_RC_SUCCESS) {
15483 return rc;
15484 }
15485 TPM_CC command_code = TPM_CC_HMAC_Start;
15486 std::string command_code_bytes;
15487 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15488 if (rc != TPM_RC_SUCCESS) {
15489 return rc;
15490 }
15491 std::string authorization_section_bytes;
15492 if (tag == TPM_ST_SESSIONS) {
15493 UINT32 parameter_section_size = buffer.size();
15494 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
15495 if (rc != TPM_RC_SUCCESS) {
15496 return rc;
15497 }
15498 if (parameter_section_size > buffer.size()) {
15499 return TPM_RC_INSUFFICIENT;
15500 }
15501 authorization_section_bytes = buffer.substr(parameter_section_size);
15502 // Keep the parameter section in |buffer|.
15503 buffer.erase(parameter_section_size);
15504 }
15505 std::unique_ptr<crypto::SecureHash> hash(
15506 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15507 hash->Update(response_code_bytes.data(), response_code_bytes.size());
15508 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15509 hash->Update(buffer.data(), buffer.size());
15510 std::string response_hash(32, 0);
15511 hash->Finish(std::data(response_hash), response_hash.size());
15512 if (tag == TPM_ST_SESSIONS) {
15513 if (!authorization_delegate)
15514 return TRUNKS_RC_AUTHORIZATION_FAILED;
15515 if (!authorization_delegate->CheckResponseAuthorization(
15516 response_hash, authorization_section_bytes)) {
15517 return TRUNKS_RC_AUTHORIZATION_FAILED;
15518 }
15519 }
15520 return TPM_RC_SUCCESS;
15521 }
15522
HMAC_StartErrorCallback(Tpm::HMAC_StartResponse callback,TPM_RC response_code)15523 void HMAC_StartErrorCallback(Tpm::HMAC_StartResponse callback,
15524 TPM_RC response_code) {
15525 VLOG(1) << __func__;
15526 std::move(callback).Run(response_code, TPMI_DH_OBJECT());
15527 }
15528
HMAC_StartResponseParser(Tpm::HMAC_StartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15529 void HMAC_StartResponseParser(Tpm::HMAC_StartResponse callback,
15530 AuthorizationDelegate* authorization_delegate,
15531 const std::string& response) {
15532 VLOG(1) << __func__;
15533 TPMI_DH_OBJECT sequence_handle;
15534 TPM_RC rc = Tpm::ParseResponse_HMAC_Start(response, &sequence_handle,
15535 authorization_delegate);
15536 if (rc != TPM_RC_SUCCESS) {
15537 base::OnceCallback<void(TPM_RC)> error_reporter =
15538 base::BindOnce(HMAC_StartErrorCallback, std::move(callback));
15539 std::move(error_reporter).Run(rc);
15540 return;
15541 }
15542 std::move(callback).Run(rc, sequence_handle);
15543 }
15544
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)15545 void Tpm::HMAC_Start(const TPMI_DH_OBJECT& handle,
15546 const std::string& handle_name,
15547 const TPM2B_AUTH& auth,
15548 const TPMI_ALG_HASH& hash_alg,
15549 AuthorizationDelegate* authorization_delegate,
15550 HMAC_StartResponse callback) {
15551 VLOG(1) << __func__;
15552 std::string command;
15553 TPM_RC rc = SerializeCommand_HMAC_Start(handle, handle_name, auth, hash_alg,
15554 &command, authorization_delegate);
15555 if (rc != TPM_RC_SUCCESS) {
15556 base::OnceCallback<void(TPM_RC)> error_reporter =
15557 base::BindOnce(HMAC_StartErrorCallback, std::move(callback));
15558 std::move(error_reporter).Run(rc);
15559 return;
15560 }
15561 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15562 HMAC_StartResponseParser, std::move(callback), authorization_delegate);
15563 transceiver_->SendCommand(command, std::move(parser));
15564 }
15565
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)15566 TPM_RC Tpm::HMAC_StartSync(const TPMI_DH_OBJECT& handle,
15567 const std::string& handle_name,
15568 const TPM2B_AUTH& auth,
15569 const TPMI_ALG_HASH& hash_alg,
15570 TPMI_DH_OBJECT* sequence_handle,
15571 AuthorizationDelegate* authorization_delegate) {
15572 VLOG(1) << __func__;
15573 std::string command;
15574 TPM_RC rc = SerializeCommand_HMAC_Start(handle, handle_name, auth, hash_alg,
15575 &command, authorization_delegate);
15576 if (rc != TPM_RC_SUCCESS) {
15577 return rc;
15578 }
15579 std::string response = transceiver_->SendCommandAndWait(command);
15580 rc = ParseResponse_HMAC_Start(response, sequence_handle,
15581 authorization_delegate);
15582 return rc;
15583 }
15584
SerializeCommand_HashSequenceStart(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15585 TPM_RC Tpm::SerializeCommand_HashSequenceStart(
15586 const TPM2B_AUTH& auth,
15587 const TPMI_ALG_HASH& hash_alg,
15588 std::string* serialized_command,
15589 AuthorizationDelegate* authorization_delegate) {
15590 VLOG(3) << __func__;
15591 TPM_RC rc = TPM_RC_SUCCESS;
15592 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15593 UINT32 command_size = 10; // Header size.
15594 std::string handle_section_bytes;
15595 std::string parameter_section_bytes;
15596 TPM_CC command_code = TPM_CC_HashSequenceStart;
15597 bool is_command_parameter_encryption_possible = true;
15598 bool is_response_parameter_encryption_possible = false;
15599 std::string command_code_bytes;
15600 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15601 if (rc != TPM_RC_SUCCESS) {
15602 return rc;
15603 }
15604 std::string auth_bytes;
15605 rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
15606 if (rc != TPM_RC_SUCCESS) {
15607 return rc;
15608 }
15609 std::string hash_alg_bytes;
15610 rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
15611 if (rc != TPM_RC_SUCCESS) {
15612 return rc;
15613 }
15614 if (authorization_delegate) {
15615 // Encrypt just the parameter data, not the size.
15616 std::string tmp = auth_bytes.substr(2);
15617 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15618 return TRUNKS_RC_ENCRYPTION_FAILED;
15619 }
15620 auth_bytes.replace(2, std::string::npos, tmp);
15621 }
15622 std::unique_ptr<crypto::SecureHash> hash(
15623 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15624 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15625 hash->Update(auth_bytes.data(), auth_bytes.size());
15626 parameter_section_bytes += auth_bytes;
15627 command_size += auth_bytes.size();
15628 hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
15629 parameter_section_bytes += hash_alg_bytes;
15630 command_size += hash_alg_bytes.size();
15631 std::string command_hash(32, 0);
15632 hash->Finish(std::data(command_hash), command_hash.size());
15633 std::string authorization_section_bytes;
15634 std::string authorization_size_bytes;
15635 if (authorization_delegate) {
15636 if (!authorization_delegate->GetCommandAuthorization(
15637 command_hash, is_command_parameter_encryption_possible,
15638 is_response_parameter_encryption_possible,
15639 &authorization_section_bytes)) {
15640 return TRUNKS_RC_AUTHORIZATION_FAILED;
15641 }
15642 if (!authorization_section_bytes.empty()) {
15643 tag = TPM_ST_SESSIONS;
15644 std::string tmp;
15645 rc = Serialize_UINT32(authorization_section_bytes.size(),
15646 &authorization_size_bytes);
15647 if (rc != TPM_RC_SUCCESS) {
15648 return rc;
15649 }
15650 command_size +=
15651 authorization_size_bytes.size() + authorization_section_bytes.size();
15652 }
15653 }
15654 std::string tag_bytes;
15655 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15656 if (rc != TPM_RC_SUCCESS) {
15657 return rc;
15658 }
15659 std::string command_size_bytes;
15660 rc = Serialize_UINT32(command_size, &command_size_bytes);
15661 if (rc != TPM_RC_SUCCESS) {
15662 return rc;
15663 }
15664 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15665 handle_section_bytes + authorization_size_bytes +
15666 authorization_section_bytes + parameter_section_bytes;
15667 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15668 VLOG(2) << "Command: "
15669 << base::HexEncode(serialized_command->data(),
15670 serialized_command->size());
15671 return TPM_RC_SUCCESS;
15672 }
15673
ParseResponse_HashSequenceStart(const std::string & response,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15674 TPM_RC Tpm::ParseResponse_HashSequenceStart(
15675 const std::string& response,
15676 TPMI_DH_OBJECT* sequence_handle,
15677 AuthorizationDelegate* authorization_delegate) {
15678 VLOG(3) << __func__;
15679 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15680 TPM_RC rc = TPM_RC_SUCCESS;
15681 std::string buffer(response);
15682 TPM_ST tag;
15683 std::string tag_bytes;
15684 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15685 if (rc != TPM_RC_SUCCESS) {
15686 return rc;
15687 }
15688 UINT32 response_size;
15689 std::string response_size_bytes;
15690 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15691 if (rc != TPM_RC_SUCCESS) {
15692 return rc;
15693 }
15694 TPM_RC response_code;
15695 std::string response_code_bytes;
15696 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15697 if (rc != TPM_RC_SUCCESS) {
15698 return rc;
15699 }
15700 if (response_size != response.size()) {
15701 return TPM_RC_SIZE;
15702 }
15703 if (response_code != TPM_RC_SUCCESS) {
15704 return response_code;
15705 }
15706 std::string sequence_handle_bytes;
15707 rc = Parse_TPMI_DH_OBJECT(&buffer, sequence_handle, &sequence_handle_bytes);
15708 if (rc != TPM_RC_SUCCESS) {
15709 return rc;
15710 }
15711 TPM_CC command_code = TPM_CC_HashSequenceStart;
15712 std::string command_code_bytes;
15713 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15714 if (rc != TPM_RC_SUCCESS) {
15715 return rc;
15716 }
15717 std::string authorization_section_bytes;
15718 if (tag == TPM_ST_SESSIONS) {
15719 UINT32 parameter_section_size = buffer.size();
15720 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
15721 if (rc != TPM_RC_SUCCESS) {
15722 return rc;
15723 }
15724 if (parameter_section_size > buffer.size()) {
15725 return TPM_RC_INSUFFICIENT;
15726 }
15727 authorization_section_bytes = buffer.substr(parameter_section_size);
15728 // Keep the parameter section in |buffer|.
15729 buffer.erase(parameter_section_size);
15730 }
15731 std::unique_ptr<crypto::SecureHash> hash(
15732 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15733 hash->Update(response_code_bytes.data(), response_code_bytes.size());
15734 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15735 hash->Update(buffer.data(), buffer.size());
15736 std::string response_hash(32, 0);
15737 hash->Finish(std::data(response_hash), response_hash.size());
15738 if (tag == TPM_ST_SESSIONS) {
15739 if (!authorization_delegate)
15740 return TRUNKS_RC_AUTHORIZATION_FAILED;
15741 if (!authorization_delegate->CheckResponseAuthorization(
15742 response_hash, authorization_section_bytes)) {
15743 return TRUNKS_RC_AUTHORIZATION_FAILED;
15744 }
15745 }
15746 return TPM_RC_SUCCESS;
15747 }
15748
HashSequenceStartErrorCallback(Tpm::HashSequenceStartResponse callback,TPM_RC response_code)15749 void HashSequenceStartErrorCallback(Tpm::HashSequenceStartResponse callback,
15750 TPM_RC response_code) {
15751 VLOG(1) << __func__;
15752 std::move(callback).Run(response_code, TPMI_DH_OBJECT());
15753 }
15754
HashSequenceStartResponseParser(Tpm::HashSequenceStartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15755 void HashSequenceStartResponseParser(
15756 Tpm::HashSequenceStartResponse callback,
15757 AuthorizationDelegate* authorization_delegate,
15758 const std::string& response) {
15759 VLOG(1) << __func__;
15760 TPMI_DH_OBJECT sequence_handle;
15761 TPM_RC rc = Tpm::ParseResponse_HashSequenceStart(response, &sequence_handle,
15762 authorization_delegate);
15763 if (rc != TPM_RC_SUCCESS) {
15764 base::OnceCallback<void(TPM_RC)> error_reporter =
15765 base::BindOnce(HashSequenceStartErrorCallback, std::move(callback));
15766 std::move(error_reporter).Run(rc);
15767 return;
15768 }
15769 std::move(callback).Run(rc, sequence_handle);
15770 }
15771
HashSequenceStart(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,HashSequenceStartResponse callback)15772 void Tpm::HashSequenceStart(const TPM2B_AUTH& auth,
15773 const TPMI_ALG_HASH& hash_alg,
15774 AuthorizationDelegate* authorization_delegate,
15775 HashSequenceStartResponse callback) {
15776 VLOG(1) << __func__;
15777 std::string command;
15778 TPM_RC rc = SerializeCommand_HashSequenceStart(auth, hash_alg, &command,
15779 authorization_delegate);
15780 if (rc != TPM_RC_SUCCESS) {
15781 base::OnceCallback<void(TPM_RC)> error_reporter =
15782 base::BindOnce(HashSequenceStartErrorCallback, std::move(callback));
15783 std::move(error_reporter).Run(rc);
15784 return;
15785 }
15786 base::OnceCallback<void(const std::string&)> parser =
15787 base::BindOnce(HashSequenceStartResponseParser, std::move(callback),
15788 authorization_delegate);
15789 transceiver_->SendCommand(command, std::move(parser));
15790 }
15791
HashSequenceStartSync(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15792 TPM_RC Tpm::HashSequenceStartSync(
15793 const TPM2B_AUTH& auth,
15794 const TPMI_ALG_HASH& hash_alg,
15795 TPMI_DH_OBJECT* sequence_handle,
15796 AuthorizationDelegate* authorization_delegate) {
15797 VLOG(1) << __func__;
15798 std::string command;
15799 TPM_RC rc = SerializeCommand_HashSequenceStart(auth, hash_alg, &command,
15800 authorization_delegate);
15801 if (rc != TPM_RC_SUCCESS) {
15802 return rc;
15803 }
15804 std::string response = transceiver_->SendCommandAndWait(command);
15805 rc = ParseResponse_HashSequenceStart(response, sequence_handle,
15806 authorization_delegate);
15807 return rc;
15808 }
15809
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)15810 TPM_RC Tpm::SerializeCommand_SequenceUpdate(
15811 const TPMI_DH_OBJECT& sequence_handle,
15812 const std::string& sequence_handle_name,
15813 const TPM2B_MAX_BUFFER& buffer,
15814 std::string* serialized_command,
15815 AuthorizationDelegate* authorization_delegate) {
15816 VLOG(3) << __func__;
15817 TPM_RC rc = TPM_RC_SUCCESS;
15818 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15819 UINT32 command_size = 10; // Header size.
15820 std::string handle_section_bytes;
15821 std::string parameter_section_bytes;
15822 TPM_CC command_code = TPM_CC_SequenceUpdate;
15823 bool is_command_parameter_encryption_possible = true;
15824 bool is_response_parameter_encryption_possible = false;
15825 std::string command_code_bytes;
15826 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15827 if (rc != TPM_RC_SUCCESS) {
15828 return rc;
15829 }
15830 std::string sequence_handle_bytes;
15831 rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
15832 if (rc != TPM_RC_SUCCESS) {
15833 return rc;
15834 }
15835 std::string buffer_bytes;
15836 rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
15837 if (rc != TPM_RC_SUCCESS) {
15838 return rc;
15839 }
15840 if (authorization_delegate) {
15841 // Encrypt just the parameter data, not the size.
15842 std::string tmp = buffer_bytes.substr(2);
15843 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15844 return TRUNKS_RC_ENCRYPTION_FAILED;
15845 }
15846 buffer_bytes.replace(2, std::string::npos, tmp);
15847 }
15848 std::unique_ptr<crypto::SecureHash> hash(
15849 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15850 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15851 hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
15852 handle_section_bytes += sequence_handle_bytes;
15853 command_size += sequence_handle_bytes.size();
15854 hash->Update(buffer_bytes.data(), buffer_bytes.size());
15855 parameter_section_bytes += buffer_bytes;
15856 command_size += buffer_bytes.size();
15857 std::string command_hash(32, 0);
15858 hash->Finish(std::data(command_hash), command_hash.size());
15859 std::string authorization_section_bytes;
15860 std::string authorization_size_bytes;
15861 if (authorization_delegate) {
15862 if (!authorization_delegate->GetCommandAuthorization(
15863 command_hash, is_command_parameter_encryption_possible,
15864 is_response_parameter_encryption_possible,
15865 &authorization_section_bytes)) {
15866 return TRUNKS_RC_AUTHORIZATION_FAILED;
15867 }
15868 if (!authorization_section_bytes.empty()) {
15869 tag = TPM_ST_SESSIONS;
15870 std::string tmp;
15871 rc = Serialize_UINT32(authorization_section_bytes.size(),
15872 &authorization_size_bytes);
15873 if (rc != TPM_RC_SUCCESS) {
15874 return rc;
15875 }
15876 command_size +=
15877 authorization_size_bytes.size() + authorization_section_bytes.size();
15878 }
15879 }
15880 std::string tag_bytes;
15881 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15882 if (rc != TPM_RC_SUCCESS) {
15883 return rc;
15884 }
15885 std::string command_size_bytes;
15886 rc = Serialize_UINT32(command_size, &command_size_bytes);
15887 if (rc != TPM_RC_SUCCESS) {
15888 return rc;
15889 }
15890 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15891 handle_section_bytes + authorization_size_bytes +
15892 authorization_section_bytes + parameter_section_bytes;
15893 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15894 VLOG(2) << "Command: "
15895 << base::HexEncode(serialized_command->data(),
15896 serialized_command->size());
15897 return TPM_RC_SUCCESS;
15898 }
15899
ParseResponse_SequenceUpdate(const std::string & response,AuthorizationDelegate * authorization_delegate)15900 TPM_RC Tpm::ParseResponse_SequenceUpdate(
15901 const std::string& response,
15902 AuthorizationDelegate* authorization_delegate) {
15903 VLOG(3) << __func__;
15904 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15905 TPM_RC rc = TPM_RC_SUCCESS;
15906 std::string buffer(response);
15907 TPM_ST tag;
15908 std::string tag_bytes;
15909 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15910 if (rc != TPM_RC_SUCCESS) {
15911 return rc;
15912 }
15913 UINT32 response_size;
15914 std::string response_size_bytes;
15915 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15916 if (rc != TPM_RC_SUCCESS) {
15917 return rc;
15918 }
15919 TPM_RC response_code;
15920 std::string response_code_bytes;
15921 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15922 if (rc != TPM_RC_SUCCESS) {
15923 return rc;
15924 }
15925 if (response_size != response.size()) {
15926 return TPM_RC_SIZE;
15927 }
15928 if (response_code != TPM_RC_SUCCESS) {
15929 return response_code;
15930 }
15931 TPM_CC command_code = TPM_CC_SequenceUpdate;
15932 std::string command_code_bytes;
15933 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15934 if (rc != TPM_RC_SUCCESS) {
15935 return rc;
15936 }
15937 std::string authorization_section_bytes;
15938 if (tag == TPM_ST_SESSIONS) {
15939 UINT32 parameter_section_size = buffer.size();
15940 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
15941 if (rc != TPM_RC_SUCCESS) {
15942 return rc;
15943 }
15944 if (parameter_section_size > buffer.size()) {
15945 return TPM_RC_INSUFFICIENT;
15946 }
15947 authorization_section_bytes = buffer.substr(parameter_section_size);
15948 // Keep the parameter section in |buffer|.
15949 buffer.erase(parameter_section_size);
15950 }
15951 std::unique_ptr<crypto::SecureHash> hash(
15952 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15953 hash->Update(response_code_bytes.data(), response_code_bytes.size());
15954 hash->Update(command_code_bytes.data(), command_code_bytes.size());
15955 hash->Update(buffer.data(), buffer.size());
15956 std::string response_hash(32, 0);
15957 hash->Finish(std::data(response_hash), response_hash.size());
15958 if (tag == TPM_ST_SESSIONS) {
15959 if (!authorization_delegate)
15960 return TRUNKS_RC_AUTHORIZATION_FAILED;
15961 if (!authorization_delegate->CheckResponseAuthorization(
15962 response_hash, authorization_section_bytes)) {
15963 return TRUNKS_RC_AUTHORIZATION_FAILED;
15964 }
15965 }
15966 return TPM_RC_SUCCESS;
15967 }
15968
SequenceUpdateErrorCallback(Tpm::SequenceUpdateResponse callback,TPM_RC response_code)15969 void SequenceUpdateErrorCallback(Tpm::SequenceUpdateResponse callback,
15970 TPM_RC response_code) {
15971 VLOG(1) << __func__;
15972 std::move(callback).Run(response_code);
15973 }
15974
SequenceUpdateResponseParser(Tpm::SequenceUpdateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15975 void SequenceUpdateResponseParser(Tpm::SequenceUpdateResponse callback,
15976 AuthorizationDelegate* authorization_delegate,
15977 const std::string& response) {
15978 VLOG(1) << __func__;
15979 TPM_RC rc =
15980 Tpm::ParseResponse_SequenceUpdate(response, authorization_delegate);
15981 if (rc != TPM_RC_SUCCESS) {
15982 base::OnceCallback<void(TPM_RC)> error_reporter =
15983 base::BindOnce(SequenceUpdateErrorCallback, std::move(callback));
15984 std::move(error_reporter).Run(rc);
15985 return;
15986 }
15987 std::move(callback).Run(rc);
15988 }
15989
SequenceUpdate(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate,SequenceUpdateResponse callback)15990 void Tpm::SequenceUpdate(const TPMI_DH_OBJECT& sequence_handle,
15991 const std::string& sequence_handle_name,
15992 const TPM2B_MAX_BUFFER& buffer,
15993 AuthorizationDelegate* authorization_delegate,
15994 SequenceUpdateResponse callback) {
15995 VLOG(1) << __func__;
15996 std::string command;
15997 TPM_RC rc =
15998 SerializeCommand_SequenceUpdate(sequence_handle, sequence_handle_name,
15999 buffer, &command, authorization_delegate);
16000 if (rc != TPM_RC_SUCCESS) {
16001 base::OnceCallback<void(TPM_RC)> error_reporter =
16002 base::BindOnce(SequenceUpdateErrorCallback, std::move(callback));
16003 std::move(error_reporter).Run(rc);
16004 return;
16005 }
16006 base::OnceCallback<void(const std::string&)> parser =
16007 base::BindOnce(SequenceUpdateResponseParser, std::move(callback),
16008 authorization_delegate);
16009 transceiver_->SendCommand(command, std::move(parser));
16010 }
16011
SequenceUpdateSync(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate)16012 TPM_RC Tpm::SequenceUpdateSync(const TPMI_DH_OBJECT& sequence_handle,
16013 const std::string& sequence_handle_name,
16014 const TPM2B_MAX_BUFFER& buffer,
16015 AuthorizationDelegate* authorization_delegate) {
16016 VLOG(1) << __func__;
16017 std::string command;
16018 TPM_RC rc =
16019 SerializeCommand_SequenceUpdate(sequence_handle, sequence_handle_name,
16020 buffer, &command, authorization_delegate);
16021 if (rc != TPM_RC_SUCCESS) {
16022 return rc;
16023 }
16024 std::string response = transceiver_->SendCommandAndWait(command);
16025 rc = ParseResponse_SequenceUpdate(response, authorization_delegate);
16026 return rc;
16027 }
16028
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)16029 TPM_RC Tpm::SerializeCommand_SequenceComplete(
16030 const TPMI_DH_OBJECT& sequence_handle,
16031 const std::string& sequence_handle_name,
16032 const TPM2B_MAX_BUFFER& buffer,
16033 const TPMI_RH_HIERARCHY& hierarchy,
16034 std::string* serialized_command,
16035 AuthorizationDelegate* authorization_delegate) {
16036 VLOG(3) << __func__;
16037 TPM_RC rc = TPM_RC_SUCCESS;
16038 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16039 UINT32 command_size = 10; // Header size.
16040 std::string handle_section_bytes;
16041 std::string parameter_section_bytes;
16042 TPM_CC command_code = TPM_CC_SequenceComplete;
16043 bool is_command_parameter_encryption_possible = true;
16044 bool is_response_parameter_encryption_possible = true;
16045 std::string command_code_bytes;
16046 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16047 if (rc != TPM_RC_SUCCESS) {
16048 return rc;
16049 }
16050 std::string sequence_handle_bytes;
16051 rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
16052 if (rc != TPM_RC_SUCCESS) {
16053 return rc;
16054 }
16055 std::string buffer_bytes;
16056 rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
16057 if (rc != TPM_RC_SUCCESS) {
16058 return rc;
16059 }
16060 std::string hierarchy_bytes;
16061 rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
16062 if (rc != TPM_RC_SUCCESS) {
16063 return rc;
16064 }
16065 if (authorization_delegate) {
16066 // Encrypt just the parameter data, not the size.
16067 std::string tmp = buffer_bytes.substr(2);
16068 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16069 return TRUNKS_RC_ENCRYPTION_FAILED;
16070 }
16071 buffer_bytes.replace(2, std::string::npos, tmp);
16072 }
16073 std::unique_ptr<crypto::SecureHash> hash(
16074 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16075 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16076 hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
16077 handle_section_bytes += sequence_handle_bytes;
16078 command_size += sequence_handle_bytes.size();
16079 hash->Update(buffer_bytes.data(), buffer_bytes.size());
16080 parameter_section_bytes += buffer_bytes;
16081 command_size += buffer_bytes.size();
16082 hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
16083 parameter_section_bytes += hierarchy_bytes;
16084 command_size += hierarchy_bytes.size();
16085 std::string command_hash(32, 0);
16086 hash->Finish(std::data(command_hash), command_hash.size());
16087 std::string authorization_section_bytes;
16088 std::string authorization_size_bytes;
16089 if (authorization_delegate) {
16090 if (!authorization_delegate->GetCommandAuthorization(
16091 command_hash, is_command_parameter_encryption_possible,
16092 is_response_parameter_encryption_possible,
16093 &authorization_section_bytes)) {
16094 return TRUNKS_RC_AUTHORIZATION_FAILED;
16095 }
16096 if (!authorization_section_bytes.empty()) {
16097 tag = TPM_ST_SESSIONS;
16098 std::string tmp;
16099 rc = Serialize_UINT32(authorization_section_bytes.size(),
16100 &authorization_size_bytes);
16101 if (rc != TPM_RC_SUCCESS) {
16102 return rc;
16103 }
16104 command_size +=
16105 authorization_size_bytes.size() + authorization_section_bytes.size();
16106 }
16107 }
16108 std::string tag_bytes;
16109 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16110 if (rc != TPM_RC_SUCCESS) {
16111 return rc;
16112 }
16113 std::string command_size_bytes;
16114 rc = Serialize_UINT32(command_size, &command_size_bytes);
16115 if (rc != TPM_RC_SUCCESS) {
16116 return rc;
16117 }
16118 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16119 handle_section_bytes + authorization_size_bytes +
16120 authorization_section_bytes + parameter_section_bytes;
16121 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16122 VLOG(2) << "Command: "
16123 << base::HexEncode(serialized_command->data(),
16124 serialized_command->size());
16125 return TPM_RC_SUCCESS;
16126 }
16127
ParseResponse_SequenceComplete(const std::string & response,TPM2B_DIGEST * result,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)16128 TPM_RC Tpm::ParseResponse_SequenceComplete(
16129 const std::string& response,
16130 TPM2B_DIGEST* result,
16131 TPMT_TK_HASHCHECK* validation,
16132 AuthorizationDelegate* authorization_delegate) {
16133 VLOG(3) << __func__;
16134 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16135 TPM_RC rc = TPM_RC_SUCCESS;
16136 std::string buffer(response);
16137 TPM_ST tag;
16138 std::string tag_bytes;
16139 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16140 if (rc != TPM_RC_SUCCESS) {
16141 return rc;
16142 }
16143 UINT32 response_size;
16144 std::string response_size_bytes;
16145 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16146 if (rc != TPM_RC_SUCCESS) {
16147 return rc;
16148 }
16149 TPM_RC response_code;
16150 std::string response_code_bytes;
16151 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16152 if (rc != TPM_RC_SUCCESS) {
16153 return rc;
16154 }
16155 if (response_size != response.size()) {
16156 return TPM_RC_SIZE;
16157 }
16158 if (response_code != TPM_RC_SUCCESS) {
16159 return response_code;
16160 }
16161 TPM_CC command_code = TPM_CC_SequenceComplete;
16162 std::string command_code_bytes;
16163 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16164 if (rc != TPM_RC_SUCCESS) {
16165 return rc;
16166 }
16167 std::string authorization_section_bytes;
16168 if (tag == TPM_ST_SESSIONS) {
16169 UINT32 parameter_section_size = buffer.size();
16170 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
16171 if (rc != TPM_RC_SUCCESS) {
16172 return rc;
16173 }
16174 if (parameter_section_size > buffer.size()) {
16175 return TPM_RC_INSUFFICIENT;
16176 }
16177 authorization_section_bytes = buffer.substr(parameter_section_size);
16178 // Keep the parameter section in |buffer|.
16179 buffer.erase(parameter_section_size);
16180 }
16181 std::unique_ptr<crypto::SecureHash> hash(
16182 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16183 hash->Update(response_code_bytes.data(), response_code_bytes.size());
16184 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16185 hash->Update(buffer.data(), buffer.size());
16186 std::string response_hash(32, 0);
16187 hash->Finish(std::data(response_hash), response_hash.size());
16188 if (tag == TPM_ST_SESSIONS) {
16189 if (!authorization_delegate)
16190 return TRUNKS_RC_AUTHORIZATION_FAILED;
16191 if (!authorization_delegate->CheckResponseAuthorization(
16192 response_hash, authorization_section_bytes)) {
16193 return TRUNKS_RC_AUTHORIZATION_FAILED;
16194 }
16195 }
16196 if (tag == TPM_ST_SESSIONS) {
16197 if (!authorization_delegate)
16198 return TRUNKS_RC_AUTHORIZATION_FAILED;
16199
16200 // Parse the encrypted parameter size.
16201 UINT16 size;
16202 std::string size_buffer = buffer.substr(0, 2);
16203 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
16204 return result;
16205 }
16206 if (buffer.size() < 2 + size) {
16207 return TPM_RC_INSUFFICIENT;
16208 }
16209
16210 // Decrypt just the parameter data, not the size.
16211 std::string decrypted_data = buffer.substr(2, size);
16212 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
16213 return TRUNKS_RC_ENCRYPTION_FAILED;
16214 }
16215 buffer.replace(2, size, decrypted_data);
16216 }
16217 std::string result_bytes;
16218 rc = Parse_TPM2B_DIGEST(&buffer, result, &result_bytes);
16219 if (rc != TPM_RC_SUCCESS) {
16220 return rc;
16221 }
16222 std::string validation_bytes;
16223 rc = Parse_TPMT_TK_HASHCHECK(&buffer, validation, &validation_bytes);
16224 if (rc != TPM_RC_SUCCESS) {
16225 return rc;
16226 }
16227 return TPM_RC_SUCCESS;
16228 }
16229
SequenceCompleteErrorCallback(Tpm::SequenceCompleteResponse callback,TPM_RC response_code)16230 void SequenceCompleteErrorCallback(Tpm::SequenceCompleteResponse callback,
16231 TPM_RC response_code) {
16232 VLOG(1) << __func__;
16233 std::move(callback).Run(response_code, TPM2B_DIGEST(), TPMT_TK_HASHCHECK());
16234 }
16235
SequenceCompleteResponseParser(Tpm::SequenceCompleteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16236 void SequenceCompleteResponseParser(
16237 Tpm::SequenceCompleteResponse callback,
16238 AuthorizationDelegate* authorization_delegate,
16239 const std::string& response) {
16240 VLOG(1) << __func__;
16241 TPM2B_DIGEST result;
16242 TPMT_TK_HASHCHECK validation;
16243 TPM_RC rc = Tpm::ParseResponse_SequenceComplete(
16244 response, &result, &validation, authorization_delegate);
16245 if (rc != TPM_RC_SUCCESS) {
16246 base::OnceCallback<void(TPM_RC)> error_reporter =
16247 base::BindOnce(SequenceCompleteErrorCallback, std::move(callback));
16248 std::move(error_reporter).Run(rc);
16249 return;
16250 }
16251 std::move(callback).Run(rc, result, validation);
16252 }
16253
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)16254 void Tpm::SequenceComplete(const TPMI_DH_OBJECT& sequence_handle,
16255 const std::string& sequence_handle_name,
16256 const TPM2B_MAX_BUFFER& buffer,
16257 const TPMI_RH_HIERARCHY& hierarchy,
16258 AuthorizationDelegate* authorization_delegate,
16259 SequenceCompleteResponse callback) {
16260 VLOG(1) << __func__;
16261 std::string command;
16262 TPM_RC rc = SerializeCommand_SequenceComplete(
16263 sequence_handle, sequence_handle_name, buffer, hierarchy, &command,
16264 authorization_delegate);
16265 if (rc != TPM_RC_SUCCESS) {
16266 base::OnceCallback<void(TPM_RC)> error_reporter =
16267 base::BindOnce(SequenceCompleteErrorCallback, std::move(callback));
16268 std::move(error_reporter).Run(rc);
16269 return;
16270 }
16271 base::OnceCallback<void(const std::string&)> parser =
16272 base::BindOnce(SequenceCompleteResponseParser, std::move(callback),
16273 authorization_delegate);
16274 transceiver_->SendCommand(command, std::move(parser));
16275 }
16276
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)16277 TPM_RC Tpm::SequenceCompleteSync(
16278 const TPMI_DH_OBJECT& sequence_handle,
16279 const std::string& sequence_handle_name,
16280 const TPM2B_MAX_BUFFER& buffer,
16281 const TPMI_RH_HIERARCHY& hierarchy,
16282 TPM2B_DIGEST* result,
16283 TPMT_TK_HASHCHECK* validation,
16284 AuthorizationDelegate* authorization_delegate) {
16285 VLOG(1) << __func__;
16286 std::string command;
16287 TPM_RC rc = SerializeCommand_SequenceComplete(
16288 sequence_handle, sequence_handle_name, buffer, hierarchy, &command,
16289 authorization_delegate);
16290 if (rc != TPM_RC_SUCCESS) {
16291 return rc;
16292 }
16293 std::string response = transceiver_->SendCommandAndWait(command);
16294 rc = ParseResponse_SequenceComplete(response, result, validation,
16295 authorization_delegate);
16296 return rc;
16297 }
16298
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)16299 TPM_RC Tpm::SerializeCommand_EventSequenceComplete(
16300 const TPMI_DH_PCR& pcr_handle,
16301 const std::string& pcr_handle_name,
16302 const TPMI_DH_OBJECT& sequence_handle,
16303 const std::string& sequence_handle_name,
16304 const TPM2B_MAX_BUFFER& buffer,
16305 std::string* serialized_command,
16306 AuthorizationDelegate* authorization_delegate) {
16307 VLOG(3) << __func__;
16308 TPM_RC rc = TPM_RC_SUCCESS;
16309 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16310 UINT32 command_size = 10; // Header size.
16311 std::string handle_section_bytes;
16312 std::string parameter_section_bytes;
16313 TPM_CC command_code = TPM_CC_EventSequenceComplete;
16314 bool is_command_parameter_encryption_possible = true;
16315 bool is_response_parameter_encryption_possible = false;
16316 std::string command_code_bytes;
16317 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16318 if (rc != TPM_RC_SUCCESS) {
16319 return rc;
16320 }
16321 std::string pcr_handle_bytes;
16322 rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
16323 if (rc != TPM_RC_SUCCESS) {
16324 return rc;
16325 }
16326 std::string sequence_handle_bytes;
16327 rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
16328 if (rc != TPM_RC_SUCCESS) {
16329 return rc;
16330 }
16331 std::string buffer_bytes;
16332 rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
16333 if (rc != TPM_RC_SUCCESS) {
16334 return rc;
16335 }
16336 if (authorization_delegate) {
16337 // Encrypt just the parameter data, not the size.
16338 std::string tmp = buffer_bytes.substr(2);
16339 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16340 return TRUNKS_RC_ENCRYPTION_FAILED;
16341 }
16342 buffer_bytes.replace(2, std::string::npos, tmp);
16343 }
16344 std::unique_ptr<crypto::SecureHash> hash(
16345 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16346 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16347 hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
16348 handle_section_bytes += pcr_handle_bytes;
16349 command_size += pcr_handle_bytes.size();
16350 hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
16351 handle_section_bytes += sequence_handle_bytes;
16352 command_size += sequence_handle_bytes.size();
16353 hash->Update(buffer_bytes.data(), buffer_bytes.size());
16354 parameter_section_bytes += buffer_bytes;
16355 command_size += buffer_bytes.size();
16356 std::string command_hash(32, 0);
16357 hash->Finish(std::data(command_hash), command_hash.size());
16358 std::string authorization_section_bytes;
16359 std::string authorization_size_bytes;
16360 if (authorization_delegate) {
16361 if (!authorization_delegate->GetCommandAuthorization(
16362 command_hash, is_command_parameter_encryption_possible,
16363 is_response_parameter_encryption_possible,
16364 &authorization_section_bytes)) {
16365 return TRUNKS_RC_AUTHORIZATION_FAILED;
16366 }
16367 if (!authorization_section_bytes.empty()) {
16368 tag = TPM_ST_SESSIONS;
16369 std::string tmp;
16370 rc = Serialize_UINT32(authorization_section_bytes.size(),
16371 &authorization_size_bytes);
16372 if (rc != TPM_RC_SUCCESS) {
16373 return rc;
16374 }
16375 command_size +=
16376 authorization_size_bytes.size() + authorization_section_bytes.size();
16377 }
16378 }
16379 std::string tag_bytes;
16380 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16381 if (rc != TPM_RC_SUCCESS) {
16382 return rc;
16383 }
16384 std::string command_size_bytes;
16385 rc = Serialize_UINT32(command_size, &command_size_bytes);
16386 if (rc != TPM_RC_SUCCESS) {
16387 return rc;
16388 }
16389 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16390 handle_section_bytes + authorization_size_bytes +
16391 authorization_section_bytes + parameter_section_bytes;
16392 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16393 VLOG(2) << "Command: "
16394 << base::HexEncode(serialized_command->data(),
16395 serialized_command->size());
16396 return TPM_RC_SUCCESS;
16397 }
16398
ParseResponse_EventSequenceComplete(const std::string & response,TPML_DIGEST_VALUES * results,AuthorizationDelegate * authorization_delegate)16399 TPM_RC Tpm::ParseResponse_EventSequenceComplete(
16400 const std::string& response,
16401 TPML_DIGEST_VALUES* results,
16402 AuthorizationDelegate* authorization_delegate) {
16403 VLOG(3) << __func__;
16404 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16405 TPM_RC rc = TPM_RC_SUCCESS;
16406 std::string buffer(response);
16407 TPM_ST tag;
16408 std::string tag_bytes;
16409 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16410 if (rc != TPM_RC_SUCCESS) {
16411 return rc;
16412 }
16413 UINT32 response_size;
16414 std::string response_size_bytes;
16415 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16416 if (rc != TPM_RC_SUCCESS) {
16417 return rc;
16418 }
16419 TPM_RC response_code;
16420 std::string response_code_bytes;
16421 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16422 if (rc != TPM_RC_SUCCESS) {
16423 return rc;
16424 }
16425 if (response_size != response.size()) {
16426 return TPM_RC_SIZE;
16427 }
16428 if (response_code != TPM_RC_SUCCESS) {
16429 return response_code;
16430 }
16431 TPM_CC command_code = TPM_CC_EventSequenceComplete;
16432 std::string command_code_bytes;
16433 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16434 if (rc != TPM_RC_SUCCESS) {
16435 return rc;
16436 }
16437 std::string authorization_section_bytes;
16438 if (tag == TPM_ST_SESSIONS) {
16439 UINT32 parameter_section_size = buffer.size();
16440 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
16441 if (rc != TPM_RC_SUCCESS) {
16442 return rc;
16443 }
16444 if (parameter_section_size > buffer.size()) {
16445 return TPM_RC_INSUFFICIENT;
16446 }
16447 authorization_section_bytes = buffer.substr(parameter_section_size);
16448 // Keep the parameter section in |buffer|.
16449 buffer.erase(parameter_section_size);
16450 }
16451 std::unique_ptr<crypto::SecureHash> hash(
16452 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16453 hash->Update(response_code_bytes.data(), response_code_bytes.size());
16454 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16455 hash->Update(buffer.data(), buffer.size());
16456 std::string response_hash(32, 0);
16457 hash->Finish(std::data(response_hash), response_hash.size());
16458 if (tag == TPM_ST_SESSIONS) {
16459 if (!authorization_delegate)
16460 return TRUNKS_RC_AUTHORIZATION_FAILED;
16461 if (!authorization_delegate->CheckResponseAuthorization(
16462 response_hash, authorization_section_bytes)) {
16463 return TRUNKS_RC_AUTHORIZATION_FAILED;
16464 }
16465 }
16466 std::string results_bytes;
16467 rc = Parse_TPML_DIGEST_VALUES(&buffer, results, &results_bytes);
16468 if (rc != TPM_RC_SUCCESS) {
16469 return rc;
16470 }
16471 return TPM_RC_SUCCESS;
16472 }
16473
EventSequenceCompleteErrorCallback(Tpm::EventSequenceCompleteResponse callback,TPM_RC response_code)16474 void EventSequenceCompleteErrorCallback(
16475 Tpm::EventSequenceCompleteResponse callback, TPM_RC response_code) {
16476 VLOG(1) << __func__;
16477 std::move(callback).Run(response_code, TPML_DIGEST_VALUES());
16478 }
16479
EventSequenceCompleteResponseParser(Tpm::EventSequenceCompleteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16480 void EventSequenceCompleteResponseParser(
16481 Tpm::EventSequenceCompleteResponse callback,
16482 AuthorizationDelegate* authorization_delegate,
16483 const std::string& response) {
16484 VLOG(1) << __func__;
16485 TPML_DIGEST_VALUES results;
16486 TPM_RC rc = Tpm::ParseResponse_EventSequenceComplete(response, &results,
16487 authorization_delegate);
16488 if (rc != TPM_RC_SUCCESS) {
16489 base::OnceCallback<void(TPM_RC)> error_reporter =
16490 base::BindOnce(EventSequenceCompleteErrorCallback, std::move(callback));
16491 std::move(error_reporter).Run(rc);
16492 return;
16493 }
16494 std::move(callback).Run(rc, results);
16495 }
16496
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)16497 void Tpm::EventSequenceComplete(const TPMI_DH_PCR& pcr_handle,
16498 const std::string& pcr_handle_name,
16499 const TPMI_DH_OBJECT& sequence_handle,
16500 const std::string& sequence_handle_name,
16501 const TPM2B_MAX_BUFFER& buffer,
16502 AuthorizationDelegate* authorization_delegate,
16503 EventSequenceCompleteResponse callback) {
16504 VLOG(1) << __func__;
16505 std::string command;
16506 TPM_RC rc = SerializeCommand_EventSequenceComplete(
16507 pcr_handle, pcr_handle_name, sequence_handle, sequence_handle_name,
16508 buffer, &command, authorization_delegate);
16509 if (rc != TPM_RC_SUCCESS) {
16510 base::OnceCallback<void(TPM_RC)> error_reporter =
16511 base::BindOnce(EventSequenceCompleteErrorCallback, std::move(callback));
16512 std::move(error_reporter).Run(rc);
16513 return;
16514 }
16515 base::OnceCallback<void(const std::string&)> parser =
16516 base::BindOnce(EventSequenceCompleteResponseParser, std::move(callback),
16517 authorization_delegate);
16518 transceiver_->SendCommand(command, std::move(parser));
16519 }
16520
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)16521 TPM_RC Tpm::EventSequenceCompleteSync(
16522 const TPMI_DH_PCR& pcr_handle,
16523 const std::string& pcr_handle_name,
16524 const TPMI_DH_OBJECT& sequence_handle,
16525 const std::string& sequence_handle_name,
16526 const TPM2B_MAX_BUFFER& buffer,
16527 TPML_DIGEST_VALUES* results,
16528 AuthorizationDelegate* authorization_delegate) {
16529 VLOG(1) << __func__;
16530 std::string command;
16531 TPM_RC rc = SerializeCommand_EventSequenceComplete(
16532 pcr_handle, pcr_handle_name, sequence_handle, sequence_handle_name,
16533 buffer, &command, authorization_delegate);
16534 if (rc != TPM_RC_SUCCESS) {
16535 return rc;
16536 }
16537 std::string response = transceiver_->SendCommandAndWait(command);
16538 rc = ParseResponse_EventSequenceComplete(response, results,
16539 authorization_delegate);
16540 return rc;
16541 }
16542
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)16543 TPM_RC Tpm::SerializeCommand_Certify(
16544 const TPMI_DH_OBJECT& object_handle,
16545 const std::string& object_handle_name,
16546 const TPMI_DH_OBJECT& sign_handle,
16547 const std::string& sign_handle_name,
16548 const TPM2B_DATA& qualifying_data,
16549 const TPMT_SIG_SCHEME& in_scheme,
16550 std::string* serialized_command,
16551 AuthorizationDelegate* authorization_delegate) {
16552 VLOG(3) << __func__;
16553 TPM_RC rc = TPM_RC_SUCCESS;
16554 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16555 UINT32 command_size = 10; // Header size.
16556 std::string handle_section_bytes;
16557 std::string parameter_section_bytes;
16558 TPM_CC command_code = TPM_CC_Certify;
16559 bool is_command_parameter_encryption_possible = true;
16560 bool is_response_parameter_encryption_possible = true;
16561 std::string command_code_bytes;
16562 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16563 if (rc != TPM_RC_SUCCESS) {
16564 return rc;
16565 }
16566 std::string object_handle_bytes;
16567 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
16568 if (rc != TPM_RC_SUCCESS) {
16569 return rc;
16570 }
16571 std::string sign_handle_bytes;
16572 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16573 if (rc != TPM_RC_SUCCESS) {
16574 return rc;
16575 }
16576 std::string qualifying_data_bytes;
16577 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16578 if (rc != TPM_RC_SUCCESS) {
16579 return rc;
16580 }
16581 std::string in_scheme_bytes;
16582 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16583 if (rc != TPM_RC_SUCCESS) {
16584 return rc;
16585 }
16586 if (authorization_delegate) {
16587 // Encrypt just the parameter data, not the size.
16588 std::string tmp = qualifying_data_bytes.substr(2);
16589 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16590 return TRUNKS_RC_ENCRYPTION_FAILED;
16591 }
16592 qualifying_data_bytes.replace(2, std::string::npos, tmp);
16593 }
16594 std::unique_ptr<crypto::SecureHash> hash(
16595 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16596 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16597 hash->Update(object_handle_name.data(), object_handle_name.size());
16598 handle_section_bytes += object_handle_bytes;
16599 command_size += object_handle_bytes.size();
16600 hash->Update(sign_handle_name.data(), sign_handle_name.size());
16601 handle_section_bytes += sign_handle_bytes;
16602 command_size += sign_handle_bytes.size();
16603 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16604 parameter_section_bytes += qualifying_data_bytes;
16605 command_size += qualifying_data_bytes.size();
16606 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16607 parameter_section_bytes += in_scheme_bytes;
16608 command_size += in_scheme_bytes.size();
16609 std::string command_hash(32, 0);
16610 hash->Finish(std::data(command_hash), command_hash.size());
16611 std::string authorization_section_bytes;
16612 std::string authorization_size_bytes;
16613 if (authorization_delegate) {
16614 if (!authorization_delegate->GetCommandAuthorization(
16615 command_hash, is_command_parameter_encryption_possible,
16616 is_response_parameter_encryption_possible,
16617 &authorization_section_bytes)) {
16618 return TRUNKS_RC_AUTHORIZATION_FAILED;
16619 }
16620 if (!authorization_section_bytes.empty()) {
16621 tag = TPM_ST_SESSIONS;
16622 std::string tmp;
16623 rc = Serialize_UINT32(authorization_section_bytes.size(),
16624 &authorization_size_bytes);
16625 if (rc != TPM_RC_SUCCESS) {
16626 return rc;
16627 }
16628 command_size +=
16629 authorization_size_bytes.size() + authorization_section_bytes.size();
16630 }
16631 }
16632 std::string tag_bytes;
16633 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16634 if (rc != TPM_RC_SUCCESS) {
16635 return rc;
16636 }
16637 std::string command_size_bytes;
16638 rc = Serialize_UINT32(command_size, &command_size_bytes);
16639 if (rc != TPM_RC_SUCCESS) {
16640 return rc;
16641 }
16642 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16643 handle_section_bytes + authorization_size_bytes +
16644 authorization_section_bytes + parameter_section_bytes;
16645 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16646 VLOG(2) << "Command: "
16647 << base::HexEncode(serialized_command->data(),
16648 serialized_command->size());
16649 return TPM_RC_SUCCESS;
16650 }
16651
ParseResponse_Certify(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16652 TPM_RC Tpm::ParseResponse_Certify(
16653 const std::string& response,
16654 TPM2B_ATTEST* certify_info,
16655 TPMT_SIGNATURE* signature,
16656 AuthorizationDelegate* authorization_delegate) {
16657 VLOG(3) << __func__;
16658 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16659 TPM_RC rc = TPM_RC_SUCCESS;
16660 std::string buffer(response);
16661 TPM_ST tag;
16662 std::string tag_bytes;
16663 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16664 if (rc != TPM_RC_SUCCESS) {
16665 return rc;
16666 }
16667 UINT32 response_size;
16668 std::string response_size_bytes;
16669 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16670 if (rc != TPM_RC_SUCCESS) {
16671 return rc;
16672 }
16673 TPM_RC response_code;
16674 std::string response_code_bytes;
16675 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16676 if (rc != TPM_RC_SUCCESS) {
16677 return rc;
16678 }
16679 if (response_size != response.size()) {
16680 return TPM_RC_SIZE;
16681 }
16682 if (response_code != TPM_RC_SUCCESS) {
16683 return response_code;
16684 }
16685 TPM_CC command_code = TPM_CC_Certify;
16686 std::string command_code_bytes;
16687 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16688 if (rc != TPM_RC_SUCCESS) {
16689 return rc;
16690 }
16691 std::string authorization_section_bytes;
16692 if (tag == TPM_ST_SESSIONS) {
16693 UINT32 parameter_section_size = buffer.size();
16694 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
16695 if (rc != TPM_RC_SUCCESS) {
16696 return rc;
16697 }
16698 if (parameter_section_size > buffer.size()) {
16699 return TPM_RC_INSUFFICIENT;
16700 }
16701 authorization_section_bytes = buffer.substr(parameter_section_size);
16702 // Keep the parameter section in |buffer|.
16703 buffer.erase(parameter_section_size);
16704 }
16705 std::unique_ptr<crypto::SecureHash> hash(
16706 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16707 hash->Update(response_code_bytes.data(), response_code_bytes.size());
16708 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16709 hash->Update(buffer.data(), buffer.size());
16710 std::string response_hash(32, 0);
16711 hash->Finish(std::data(response_hash), response_hash.size());
16712 if (tag == TPM_ST_SESSIONS) {
16713 if (!authorization_delegate)
16714 return TRUNKS_RC_AUTHORIZATION_FAILED;
16715 if (!authorization_delegate->CheckResponseAuthorization(
16716 response_hash, authorization_section_bytes)) {
16717 return TRUNKS_RC_AUTHORIZATION_FAILED;
16718 }
16719 }
16720 if (tag == TPM_ST_SESSIONS) {
16721 if (!authorization_delegate)
16722 return TRUNKS_RC_AUTHORIZATION_FAILED;
16723
16724 // Parse the encrypted parameter size.
16725 UINT16 size;
16726 std::string size_buffer = buffer.substr(0, 2);
16727 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
16728 return result;
16729 }
16730 if (buffer.size() < 2 + size) {
16731 return TPM_RC_INSUFFICIENT;
16732 }
16733
16734 // Decrypt just the parameter data, not the size.
16735 std::string decrypted_data = buffer.substr(2, size);
16736 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
16737 return TRUNKS_RC_ENCRYPTION_FAILED;
16738 }
16739 buffer.replace(2, size, decrypted_data);
16740 }
16741 std::string certify_info_bytes;
16742 rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
16743 if (rc != TPM_RC_SUCCESS) {
16744 return rc;
16745 }
16746 std::string signature_bytes;
16747 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
16748 if (rc != TPM_RC_SUCCESS) {
16749 return rc;
16750 }
16751 return TPM_RC_SUCCESS;
16752 }
16753
CertifyErrorCallback(Tpm::CertifyResponse callback,TPM_RC response_code)16754 void CertifyErrorCallback(Tpm::CertifyResponse callback, TPM_RC response_code) {
16755 VLOG(1) << __func__;
16756 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
16757 }
16758
CertifyResponseParser(Tpm::CertifyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16759 void CertifyResponseParser(Tpm::CertifyResponse callback,
16760 AuthorizationDelegate* authorization_delegate,
16761 const std::string& response) {
16762 VLOG(1) << __func__;
16763 TPM2B_ATTEST certify_info;
16764 TPMT_SIGNATURE signature;
16765 TPM_RC rc = Tpm::ParseResponse_Certify(response, &certify_info, &signature,
16766 authorization_delegate);
16767 if (rc != TPM_RC_SUCCESS) {
16768 base::OnceCallback<void(TPM_RC)> error_reporter =
16769 base::BindOnce(CertifyErrorCallback, std::move(callback));
16770 std::move(error_reporter).Run(rc);
16771 return;
16772 }
16773 std::move(callback).Run(rc, certify_info, signature);
16774 }
16775
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)16776 void Tpm::Certify(const TPMI_DH_OBJECT& object_handle,
16777 const std::string& object_handle_name,
16778 const TPMI_DH_OBJECT& sign_handle,
16779 const std::string& sign_handle_name,
16780 const TPM2B_DATA& qualifying_data,
16781 const TPMT_SIG_SCHEME& in_scheme,
16782 AuthorizationDelegate* authorization_delegate,
16783 CertifyResponse callback) {
16784 VLOG(1) << __func__;
16785 std::string command;
16786 TPM_RC rc = SerializeCommand_Certify(
16787 object_handle, object_handle_name, sign_handle, sign_handle_name,
16788 qualifying_data, in_scheme, &command, authorization_delegate);
16789 if (rc != TPM_RC_SUCCESS) {
16790 base::OnceCallback<void(TPM_RC)> error_reporter =
16791 base::BindOnce(CertifyErrorCallback, std::move(callback));
16792 std::move(error_reporter).Run(rc);
16793 return;
16794 }
16795 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
16796 CertifyResponseParser, std::move(callback), authorization_delegate);
16797 transceiver_->SendCommand(command, std::move(parser));
16798 }
16799
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)16800 TPM_RC Tpm::CertifySync(const TPMI_DH_OBJECT& object_handle,
16801 const std::string& object_handle_name,
16802 const TPMI_DH_OBJECT& sign_handle,
16803 const std::string& sign_handle_name,
16804 const TPM2B_DATA& qualifying_data,
16805 const TPMT_SIG_SCHEME& in_scheme,
16806 TPM2B_ATTEST* certify_info,
16807 TPMT_SIGNATURE* signature,
16808 AuthorizationDelegate* authorization_delegate) {
16809 VLOG(1) << __func__;
16810 std::string command;
16811 TPM_RC rc = SerializeCommand_Certify(
16812 object_handle, object_handle_name, sign_handle, sign_handle_name,
16813 qualifying_data, in_scheme, &command, authorization_delegate);
16814 if (rc != TPM_RC_SUCCESS) {
16815 return rc;
16816 }
16817 std::string response = transceiver_->SendCommandAndWait(command);
16818 rc = ParseResponse_Certify(response, certify_info, signature,
16819 authorization_delegate);
16820 return rc;
16821 }
16822
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)16823 TPM_RC Tpm::SerializeCommand_CertifyCreation(
16824 const TPMI_DH_OBJECT& sign_handle,
16825 const std::string& sign_handle_name,
16826 const TPMI_DH_OBJECT& object_handle,
16827 const std::string& object_handle_name,
16828 const TPM2B_DATA& qualifying_data,
16829 const TPM2B_DIGEST& creation_hash,
16830 const TPMT_SIG_SCHEME& in_scheme,
16831 const TPMT_TK_CREATION& creation_ticket,
16832 std::string* serialized_command,
16833 AuthorizationDelegate* authorization_delegate) {
16834 VLOG(3) << __func__;
16835 TPM_RC rc = TPM_RC_SUCCESS;
16836 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16837 UINT32 command_size = 10; // Header size.
16838 std::string handle_section_bytes;
16839 std::string parameter_section_bytes;
16840 TPM_CC command_code = TPM_CC_CertifyCreation;
16841 bool is_command_parameter_encryption_possible = true;
16842 bool is_response_parameter_encryption_possible = true;
16843 std::string command_code_bytes;
16844 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16845 if (rc != TPM_RC_SUCCESS) {
16846 return rc;
16847 }
16848 std::string sign_handle_bytes;
16849 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16850 if (rc != TPM_RC_SUCCESS) {
16851 return rc;
16852 }
16853 std::string object_handle_bytes;
16854 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
16855 if (rc != TPM_RC_SUCCESS) {
16856 return rc;
16857 }
16858 std::string qualifying_data_bytes;
16859 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16860 if (rc != TPM_RC_SUCCESS) {
16861 return rc;
16862 }
16863 std::string creation_hash_bytes;
16864 rc = Serialize_TPM2B_DIGEST(creation_hash, &creation_hash_bytes);
16865 if (rc != TPM_RC_SUCCESS) {
16866 return rc;
16867 }
16868 std::string in_scheme_bytes;
16869 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16870 if (rc != TPM_RC_SUCCESS) {
16871 return rc;
16872 }
16873 std::string creation_ticket_bytes;
16874 rc = Serialize_TPMT_TK_CREATION(creation_ticket, &creation_ticket_bytes);
16875 if (rc != TPM_RC_SUCCESS) {
16876 return rc;
16877 }
16878 if (authorization_delegate) {
16879 // Encrypt just the parameter data, not the size.
16880 std::string tmp = qualifying_data_bytes.substr(2);
16881 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16882 return TRUNKS_RC_ENCRYPTION_FAILED;
16883 }
16884 qualifying_data_bytes.replace(2, std::string::npos, tmp);
16885 }
16886 std::unique_ptr<crypto::SecureHash> hash(
16887 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16888 hash->Update(command_code_bytes.data(), command_code_bytes.size());
16889 hash->Update(sign_handle_name.data(), sign_handle_name.size());
16890 handle_section_bytes += sign_handle_bytes;
16891 command_size += sign_handle_bytes.size();
16892 hash->Update(object_handle_name.data(), object_handle_name.size());
16893 handle_section_bytes += object_handle_bytes;
16894 command_size += object_handle_bytes.size();
16895 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16896 parameter_section_bytes += qualifying_data_bytes;
16897 command_size += qualifying_data_bytes.size();
16898 hash->Update(creation_hash_bytes.data(), creation_hash_bytes.size());
16899 parameter_section_bytes += creation_hash_bytes;
16900 command_size += creation_hash_bytes.size();
16901 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16902 parameter_section_bytes += in_scheme_bytes;
16903 command_size += in_scheme_bytes.size();
16904 hash->Update(creation_ticket_bytes.data(), creation_ticket_bytes.size());
16905 parameter_section_bytes += creation_ticket_bytes;
16906 command_size += creation_ticket_bytes.size();
16907 std::string command_hash(32, 0);
16908 hash->Finish(std::data(command_hash), command_hash.size());
16909 std::string authorization_section_bytes;
16910 std::string authorization_size_bytes;
16911 if (authorization_delegate) {
16912 if (!authorization_delegate->GetCommandAuthorization(
16913 command_hash, is_command_parameter_encryption_possible,
16914 is_response_parameter_encryption_possible,
16915 &authorization_section_bytes)) {
16916 return TRUNKS_RC_AUTHORIZATION_FAILED;
16917 }
16918 if (!authorization_section_bytes.empty()) {
16919 tag = TPM_ST_SESSIONS;
16920 std::string tmp;
16921 rc = Serialize_UINT32(authorization_section_bytes.size(),
16922 &authorization_size_bytes);
16923 if (rc != TPM_RC_SUCCESS) {
16924 return rc;
16925 }
16926 command_size +=
16927 authorization_size_bytes.size() + authorization_section_bytes.size();
16928 }
16929 }
16930 std::string tag_bytes;
16931 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16932 if (rc != TPM_RC_SUCCESS) {
16933 return rc;
16934 }
16935 std::string command_size_bytes;
16936 rc = Serialize_UINT32(command_size, &command_size_bytes);
16937 if (rc != TPM_RC_SUCCESS) {
16938 return rc;
16939 }
16940 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16941 handle_section_bytes + authorization_size_bytes +
16942 authorization_section_bytes + parameter_section_bytes;
16943 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16944 VLOG(2) << "Command: "
16945 << base::HexEncode(serialized_command->data(),
16946 serialized_command->size());
16947 return TPM_RC_SUCCESS;
16948 }
16949
ParseResponse_CertifyCreation(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16950 TPM_RC Tpm::ParseResponse_CertifyCreation(
16951 const std::string& response,
16952 TPM2B_ATTEST* certify_info,
16953 TPMT_SIGNATURE* signature,
16954 AuthorizationDelegate* authorization_delegate) {
16955 VLOG(3) << __func__;
16956 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16957 TPM_RC rc = TPM_RC_SUCCESS;
16958 std::string buffer(response);
16959 TPM_ST tag;
16960 std::string tag_bytes;
16961 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16962 if (rc != TPM_RC_SUCCESS) {
16963 return rc;
16964 }
16965 UINT32 response_size;
16966 std::string response_size_bytes;
16967 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16968 if (rc != TPM_RC_SUCCESS) {
16969 return rc;
16970 }
16971 TPM_RC response_code;
16972 std::string response_code_bytes;
16973 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16974 if (rc != TPM_RC_SUCCESS) {
16975 return rc;
16976 }
16977 if (response_size != response.size()) {
16978 return TPM_RC_SIZE;
16979 }
16980 if (response_code != TPM_RC_SUCCESS) {
16981 return response_code;
16982 }
16983 TPM_CC command_code = TPM_CC_CertifyCreation;
16984 std::string command_code_bytes;
16985 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16986 if (rc != TPM_RC_SUCCESS) {
16987 return rc;
16988 }
16989 std::string authorization_section_bytes;
16990 if (tag == TPM_ST_SESSIONS) {
16991 UINT32 parameter_section_size = buffer.size();
16992 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
16993 if (rc != TPM_RC_SUCCESS) {
16994 return rc;
16995 }
16996 if (parameter_section_size > buffer.size()) {
16997 return TPM_RC_INSUFFICIENT;
16998 }
16999 authorization_section_bytes = buffer.substr(parameter_section_size);
17000 // Keep the parameter section in |buffer|.
17001 buffer.erase(parameter_section_size);
17002 }
17003 std::unique_ptr<crypto::SecureHash> hash(
17004 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17005 hash->Update(response_code_bytes.data(), response_code_bytes.size());
17006 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17007 hash->Update(buffer.data(), buffer.size());
17008 std::string response_hash(32, 0);
17009 hash->Finish(std::data(response_hash), response_hash.size());
17010 if (tag == TPM_ST_SESSIONS) {
17011 if (!authorization_delegate)
17012 return TRUNKS_RC_AUTHORIZATION_FAILED;
17013 if (!authorization_delegate->CheckResponseAuthorization(
17014 response_hash, authorization_section_bytes)) {
17015 return TRUNKS_RC_AUTHORIZATION_FAILED;
17016 }
17017 }
17018 if (tag == TPM_ST_SESSIONS) {
17019 if (!authorization_delegate)
17020 return TRUNKS_RC_AUTHORIZATION_FAILED;
17021
17022 // Parse the encrypted parameter size.
17023 UINT16 size;
17024 std::string size_buffer = buffer.substr(0, 2);
17025 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17026 return result;
17027 }
17028 if (buffer.size() < 2 + size) {
17029 return TPM_RC_INSUFFICIENT;
17030 }
17031
17032 // Decrypt just the parameter data, not the size.
17033 std::string decrypted_data = buffer.substr(2, size);
17034 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17035 return TRUNKS_RC_ENCRYPTION_FAILED;
17036 }
17037 buffer.replace(2, size, decrypted_data);
17038 }
17039 std::string certify_info_bytes;
17040 rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
17041 if (rc != TPM_RC_SUCCESS) {
17042 return rc;
17043 }
17044 std::string signature_bytes;
17045 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17046 if (rc != TPM_RC_SUCCESS) {
17047 return rc;
17048 }
17049 return TPM_RC_SUCCESS;
17050 }
17051
CertifyCreationErrorCallback(Tpm::CertifyCreationResponse callback,TPM_RC response_code)17052 void CertifyCreationErrorCallback(Tpm::CertifyCreationResponse callback,
17053 TPM_RC response_code) {
17054 VLOG(1) << __func__;
17055 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17056 }
17057
CertifyCreationResponseParser(Tpm::CertifyCreationResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17058 void CertifyCreationResponseParser(
17059 Tpm::CertifyCreationResponse callback,
17060 AuthorizationDelegate* authorization_delegate,
17061 const std::string& response) {
17062 VLOG(1) << __func__;
17063 TPM2B_ATTEST certify_info;
17064 TPMT_SIGNATURE signature;
17065 TPM_RC rc = Tpm::ParseResponse_CertifyCreation(
17066 response, &certify_info, &signature, authorization_delegate);
17067 if (rc != TPM_RC_SUCCESS) {
17068 base::OnceCallback<void(TPM_RC)> error_reporter =
17069 base::BindOnce(CertifyCreationErrorCallback, std::move(callback));
17070 std::move(error_reporter).Run(rc);
17071 return;
17072 }
17073 std::move(callback).Run(rc, certify_info, signature);
17074 }
17075
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)17076 void Tpm::CertifyCreation(const TPMI_DH_OBJECT& sign_handle,
17077 const std::string& sign_handle_name,
17078 const TPMI_DH_OBJECT& object_handle,
17079 const std::string& object_handle_name,
17080 const TPM2B_DATA& qualifying_data,
17081 const TPM2B_DIGEST& creation_hash,
17082 const TPMT_SIG_SCHEME& in_scheme,
17083 const TPMT_TK_CREATION& creation_ticket,
17084 AuthorizationDelegate* authorization_delegate,
17085 CertifyCreationResponse callback) {
17086 VLOG(1) << __func__;
17087 std::string command;
17088 TPM_RC rc = SerializeCommand_CertifyCreation(
17089 sign_handle, sign_handle_name, object_handle, object_handle_name,
17090 qualifying_data, creation_hash, in_scheme, creation_ticket, &command,
17091 authorization_delegate);
17092 if (rc != TPM_RC_SUCCESS) {
17093 base::OnceCallback<void(TPM_RC)> error_reporter =
17094 base::BindOnce(CertifyCreationErrorCallback, std::move(callback));
17095 std::move(error_reporter).Run(rc);
17096 return;
17097 }
17098 base::OnceCallback<void(const std::string&)> parser =
17099 base::BindOnce(CertifyCreationResponseParser, std::move(callback),
17100 authorization_delegate);
17101 transceiver_->SendCommand(command, std::move(parser));
17102 }
17103
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)17104 TPM_RC Tpm::CertifyCreationSync(const TPMI_DH_OBJECT& sign_handle,
17105 const std::string& sign_handle_name,
17106 const TPMI_DH_OBJECT& object_handle,
17107 const std::string& object_handle_name,
17108 const TPM2B_DATA& qualifying_data,
17109 const TPM2B_DIGEST& creation_hash,
17110 const TPMT_SIG_SCHEME& in_scheme,
17111 const TPMT_TK_CREATION& creation_ticket,
17112 TPM2B_ATTEST* certify_info,
17113 TPMT_SIGNATURE* signature,
17114 AuthorizationDelegate* authorization_delegate) {
17115 VLOG(1) << __func__;
17116 std::string command;
17117 TPM_RC rc = SerializeCommand_CertifyCreation(
17118 sign_handle, sign_handle_name, object_handle, object_handle_name,
17119 qualifying_data, creation_hash, in_scheme, creation_ticket, &command,
17120 authorization_delegate);
17121 if (rc != TPM_RC_SUCCESS) {
17122 return rc;
17123 }
17124 std::string response = transceiver_->SendCommandAndWait(command);
17125 rc = ParseResponse_CertifyCreation(response, certify_info, signature,
17126 authorization_delegate);
17127 return rc;
17128 }
17129
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)17130 TPM_RC Tpm::SerializeCommand_Quote(
17131 const TPMI_DH_OBJECT& sign_handle,
17132 const std::string& sign_handle_name,
17133 const TPM2B_DATA& qualifying_data,
17134 const TPMT_SIG_SCHEME& in_scheme,
17135 const TPML_PCR_SELECTION& pcrselect,
17136 std::string* serialized_command,
17137 AuthorizationDelegate* authorization_delegate) {
17138 VLOG(3) << __func__;
17139 TPM_RC rc = TPM_RC_SUCCESS;
17140 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17141 UINT32 command_size = 10; // Header size.
17142 std::string handle_section_bytes;
17143 std::string parameter_section_bytes;
17144 TPM_CC command_code = TPM_CC_Quote;
17145 bool is_command_parameter_encryption_possible = true;
17146 bool is_response_parameter_encryption_possible = true;
17147 std::string command_code_bytes;
17148 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17149 if (rc != TPM_RC_SUCCESS) {
17150 return rc;
17151 }
17152 std::string sign_handle_bytes;
17153 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17154 if (rc != TPM_RC_SUCCESS) {
17155 return rc;
17156 }
17157 std::string qualifying_data_bytes;
17158 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17159 if (rc != TPM_RC_SUCCESS) {
17160 return rc;
17161 }
17162 std::string in_scheme_bytes;
17163 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17164 if (rc != TPM_RC_SUCCESS) {
17165 return rc;
17166 }
17167 std::string pcrselect_bytes;
17168 rc = Serialize_TPML_PCR_SELECTION(pcrselect, &pcrselect_bytes);
17169 if (rc != TPM_RC_SUCCESS) {
17170 return rc;
17171 }
17172 if (authorization_delegate) {
17173 // Encrypt just the parameter data, not the size.
17174 std::string tmp = qualifying_data_bytes.substr(2);
17175 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17176 return TRUNKS_RC_ENCRYPTION_FAILED;
17177 }
17178 qualifying_data_bytes.replace(2, std::string::npos, tmp);
17179 }
17180 std::unique_ptr<crypto::SecureHash> hash(
17181 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17182 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17183 hash->Update(sign_handle_name.data(), sign_handle_name.size());
17184 handle_section_bytes += sign_handle_bytes;
17185 command_size += sign_handle_bytes.size();
17186 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17187 parameter_section_bytes += qualifying_data_bytes;
17188 command_size += qualifying_data_bytes.size();
17189 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17190 parameter_section_bytes += in_scheme_bytes;
17191 command_size += in_scheme_bytes.size();
17192 hash->Update(pcrselect_bytes.data(), pcrselect_bytes.size());
17193 parameter_section_bytes += pcrselect_bytes;
17194 command_size += pcrselect_bytes.size();
17195 std::string command_hash(32, 0);
17196 hash->Finish(std::data(command_hash), command_hash.size());
17197 std::string authorization_section_bytes;
17198 std::string authorization_size_bytes;
17199 if (authorization_delegate) {
17200 if (!authorization_delegate->GetCommandAuthorization(
17201 command_hash, is_command_parameter_encryption_possible,
17202 is_response_parameter_encryption_possible,
17203 &authorization_section_bytes)) {
17204 return TRUNKS_RC_AUTHORIZATION_FAILED;
17205 }
17206 if (!authorization_section_bytes.empty()) {
17207 tag = TPM_ST_SESSIONS;
17208 std::string tmp;
17209 rc = Serialize_UINT32(authorization_section_bytes.size(),
17210 &authorization_size_bytes);
17211 if (rc != TPM_RC_SUCCESS) {
17212 return rc;
17213 }
17214 command_size +=
17215 authorization_size_bytes.size() + authorization_section_bytes.size();
17216 }
17217 }
17218 std::string tag_bytes;
17219 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17220 if (rc != TPM_RC_SUCCESS) {
17221 return rc;
17222 }
17223 std::string command_size_bytes;
17224 rc = Serialize_UINT32(command_size, &command_size_bytes);
17225 if (rc != TPM_RC_SUCCESS) {
17226 return rc;
17227 }
17228 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17229 handle_section_bytes + authorization_size_bytes +
17230 authorization_section_bytes + parameter_section_bytes;
17231 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17232 VLOG(2) << "Command: "
17233 << base::HexEncode(serialized_command->data(),
17234 serialized_command->size());
17235 return TPM_RC_SUCCESS;
17236 }
17237
ParseResponse_Quote(const std::string & response,TPM2B_ATTEST * quoted,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17238 TPM_RC Tpm::ParseResponse_Quote(const std::string& response,
17239 TPM2B_ATTEST* quoted,
17240 TPMT_SIGNATURE* signature,
17241 AuthorizationDelegate* authorization_delegate) {
17242 VLOG(3) << __func__;
17243 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17244 TPM_RC rc = TPM_RC_SUCCESS;
17245 std::string buffer(response);
17246 TPM_ST tag;
17247 std::string tag_bytes;
17248 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17249 if (rc != TPM_RC_SUCCESS) {
17250 return rc;
17251 }
17252 UINT32 response_size;
17253 std::string response_size_bytes;
17254 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17255 if (rc != TPM_RC_SUCCESS) {
17256 return rc;
17257 }
17258 TPM_RC response_code;
17259 std::string response_code_bytes;
17260 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17261 if (rc != TPM_RC_SUCCESS) {
17262 return rc;
17263 }
17264 if (response_size != response.size()) {
17265 return TPM_RC_SIZE;
17266 }
17267 if (response_code != TPM_RC_SUCCESS) {
17268 return response_code;
17269 }
17270 TPM_CC command_code = TPM_CC_Quote;
17271 std::string command_code_bytes;
17272 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17273 if (rc != TPM_RC_SUCCESS) {
17274 return rc;
17275 }
17276 std::string authorization_section_bytes;
17277 if (tag == TPM_ST_SESSIONS) {
17278 UINT32 parameter_section_size = buffer.size();
17279 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
17280 if (rc != TPM_RC_SUCCESS) {
17281 return rc;
17282 }
17283 if (parameter_section_size > buffer.size()) {
17284 return TPM_RC_INSUFFICIENT;
17285 }
17286 authorization_section_bytes = buffer.substr(parameter_section_size);
17287 // Keep the parameter section in |buffer|.
17288 buffer.erase(parameter_section_size);
17289 }
17290 std::unique_ptr<crypto::SecureHash> hash(
17291 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17292 hash->Update(response_code_bytes.data(), response_code_bytes.size());
17293 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17294 hash->Update(buffer.data(), buffer.size());
17295 std::string response_hash(32, 0);
17296 hash->Finish(std::data(response_hash), response_hash.size());
17297 if (tag == TPM_ST_SESSIONS) {
17298 if (!authorization_delegate)
17299 return TRUNKS_RC_AUTHORIZATION_FAILED;
17300 if (!authorization_delegate->CheckResponseAuthorization(
17301 response_hash, authorization_section_bytes)) {
17302 return TRUNKS_RC_AUTHORIZATION_FAILED;
17303 }
17304 }
17305 if (tag == TPM_ST_SESSIONS) {
17306 if (!authorization_delegate)
17307 return TRUNKS_RC_AUTHORIZATION_FAILED;
17308
17309 // Parse the encrypted parameter size.
17310 UINT16 size;
17311 std::string size_buffer = buffer.substr(0, 2);
17312 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17313 return result;
17314 }
17315 if (buffer.size() < 2 + size) {
17316 return TPM_RC_INSUFFICIENT;
17317 }
17318
17319 // Decrypt just the parameter data, not the size.
17320 std::string decrypted_data = buffer.substr(2, size);
17321 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17322 return TRUNKS_RC_ENCRYPTION_FAILED;
17323 }
17324 buffer.replace(2, size, decrypted_data);
17325 }
17326 std::string quoted_bytes;
17327 rc = Parse_TPM2B_ATTEST(&buffer, quoted, "ed_bytes);
17328 if (rc != TPM_RC_SUCCESS) {
17329 return rc;
17330 }
17331 std::string signature_bytes;
17332 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17333 if (rc != TPM_RC_SUCCESS) {
17334 return rc;
17335 }
17336 return TPM_RC_SUCCESS;
17337 }
17338
QuoteErrorCallback(Tpm::QuoteResponse callback,TPM_RC response_code)17339 void QuoteErrorCallback(Tpm::QuoteResponse callback, TPM_RC response_code) {
17340 VLOG(1) << __func__;
17341 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17342 }
17343
QuoteResponseParser(Tpm::QuoteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17344 void QuoteResponseParser(Tpm::QuoteResponse callback,
17345 AuthorizationDelegate* authorization_delegate,
17346 const std::string& response) {
17347 VLOG(1) << __func__;
17348 TPM2B_ATTEST quoted;
17349 TPMT_SIGNATURE signature;
17350 TPM_RC rc = Tpm::ParseResponse_Quote(response, "ed, &signature,
17351 authorization_delegate);
17352 if (rc != TPM_RC_SUCCESS) {
17353 base::OnceCallback<void(TPM_RC)> error_reporter =
17354 base::BindOnce(QuoteErrorCallback, std::move(callback));
17355 std::move(error_reporter).Run(rc);
17356 return;
17357 }
17358 std::move(callback).Run(rc, quoted, signature);
17359 }
17360
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)17361 void Tpm::Quote(const TPMI_DH_OBJECT& sign_handle,
17362 const std::string& sign_handle_name,
17363 const TPM2B_DATA& qualifying_data,
17364 const TPMT_SIG_SCHEME& in_scheme,
17365 const TPML_PCR_SELECTION& pcrselect,
17366 AuthorizationDelegate* authorization_delegate,
17367 QuoteResponse callback) {
17368 VLOG(1) << __func__;
17369 std::string command;
17370 TPM_RC rc = SerializeCommand_Quote(sign_handle, sign_handle_name,
17371 qualifying_data, in_scheme, pcrselect,
17372 &command, authorization_delegate);
17373 if (rc != TPM_RC_SUCCESS) {
17374 base::OnceCallback<void(TPM_RC)> error_reporter =
17375 base::BindOnce(QuoteErrorCallback, std::move(callback));
17376 std::move(error_reporter).Run(rc);
17377 return;
17378 }
17379 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
17380 QuoteResponseParser, std::move(callback), authorization_delegate);
17381 transceiver_->SendCommand(command, std::move(parser));
17382 }
17383
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)17384 TPM_RC Tpm::QuoteSync(const TPMI_DH_OBJECT& sign_handle,
17385 const std::string& sign_handle_name,
17386 const TPM2B_DATA& qualifying_data,
17387 const TPMT_SIG_SCHEME& in_scheme,
17388 const TPML_PCR_SELECTION& pcrselect,
17389 TPM2B_ATTEST* quoted,
17390 TPMT_SIGNATURE* signature,
17391 AuthorizationDelegate* authorization_delegate) {
17392 VLOG(1) << __func__;
17393 std::string command;
17394 TPM_RC rc = SerializeCommand_Quote(sign_handle, sign_handle_name,
17395 qualifying_data, in_scheme, pcrselect,
17396 &command, authorization_delegate);
17397 if (rc != TPM_RC_SUCCESS) {
17398 return rc;
17399 }
17400 std::string response = transceiver_->SendCommandAndWait(command);
17401 rc = ParseResponse_Quote(response, quoted, signature, authorization_delegate);
17402 return rc;
17403 }
17404
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)17405 TPM_RC Tpm::SerializeCommand_GetSessionAuditDigest(
17406 const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17407 const std::string& privacy_admin_handle_name,
17408 const TPMI_DH_OBJECT& sign_handle,
17409 const std::string& sign_handle_name,
17410 const TPMI_SH_HMAC& session_handle,
17411 const std::string& session_handle_name,
17412 const TPM2B_DATA& qualifying_data,
17413 const TPMT_SIG_SCHEME& in_scheme,
17414 std::string* serialized_command,
17415 AuthorizationDelegate* authorization_delegate) {
17416 VLOG(3) << __func__;
17417 TPM_RC rc = TPM_RC_SUCCESS;
17418 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17419 UINT32 command_size = 10; // Header size.
17420 std::string handle_section_bytes;
17421 std::string parameter_section_bytes;
17422 TPM_CC command_code = TPM_CC_GetSessionAuditDigest;
17423 bool is_command_parameter_encryption_possible = true;
17424 bool is_response_parameter_encryption_possible = true;
17425 std::string command_code_bytes;
17426 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17427 if (rc != TPM_RC_SUCCESS) {
17428 return rc;
17429 }
17430 std::string privacy_admin_handle_bytes;
17431 rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_admin_handle,
17432 &privacy_admin_handle_bytes);
17433 if (rc != TPM_RC_SUCCESS) {
17434 return rc;
17435 }
17436 std::string sign_handle_bytes;
17437 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17438 if (rc != TPM_RC_SUCCESS) {
17439 return rc;
17440 }
17441 std::string session_handle_bytes;
17442 rc = Serialize_TPMI_SH_HMAC(session_handle, &session_handle_bytes);
17443 if (rc != TPM_RC_SUCCESS) {
17444 return rc;
17445 }
17446 std::string qualifying_data_bytes;
17447 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17448 if (rc != TPM_RC_SUCCESS) {
17449 return rc;
17450 }
17451 std::string in_scheme_bytes;
17452 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17453 if (rc != TPM_RC_SUCCESS) {
17454 return rc;
17455 }
17456 if (authorization_delegate) {
17457 // Encrypt just the parameter data, not the size.
17458 std::string tmp = qualifying_data_bytes.substr(2);
17459 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17460 return TRUNKS_RC_ENCRYPTION_FAILED;
17461 }
17462 qualifying_data_bytes.replace(2, std::string::npos, tmp);
17463 }
17464 std::unique_ptr<crypto::SecureHash> hash(
17465 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17466 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17467 hash->Update(privacy_admin_handle_name.data(),
17468 privacy_admin_handle_name.size());
17469 handle_section_bytes += privacy_admin_handle_bytes;
17470 command_size += privacy_admin_handle_bytes.size();
17471 hash->Update(sign_handle_name.data(), sign_handle_name.size());
17472 handle_section_bytes += sign_handle_bytes;
17473 command_size += sign_handle_bytes.size();
17474 hash->Update(session_handle_name.data(), session_handle_name.size());
17475 handle_section_bytes += session_handle_bytes;
17476 command_size += session_handle_bytes.size();
17477 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17478 parameter_section_bytes += qualifying_data_bytes;
17479 command_size += qualifying_data_bytes.size();
17480 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17481 parameter_section_bytes += in_scheme_bytes;
17482 command_size += in_scheme_bytes.size();
17483 std::string command_hash(32, 0);
17484 hash->Finish(std::data(command_hash), command_hash.size());
17485 std::string authorization_section_bytes;
17486 std::string authorization_size_bytes;
17487 if (authorization_delegate) {
17488 if (!authorization_delegate->GetCommandAuthorization(
17489 command_hash, is_command_parameter_encryption_possible,
17490 is_response_parameter_encryption_possible,
17491 &authorization_section_bytes)) {
17492 return TRUNKS_RC_AUTHORIZATION_FAILED;
17493 }
17494 if (!authorization_section_bytes.empty()) {
17495 tag = TPM_ST_SESSIONS;
17496 std::string tmp;
17497 rc = Serialize_UINT32(authorization_section_bytes.size(),
17498 &authorization_size_bytes);
17499 if (rc != TPM_RC_SUCCESS) {
17500 return rc;
17501 }
17502 command_size +=
17503 authorization_size_bytes.size() + authorization_section_bytes.size();
17504 }
17505 }
17506 std::string tag_bytes;
17507 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17508 if (rc != TPM_RC_SUCCESS) {
17509 return rc;
17510 }
17511 std::string command_size_bytes;
17512 rc = Serialize_UINT32(command_size, &command_size_bytes);
17513 if (rc != TPM_RC_SUCCESS) {
17514 return rc;
17515 }
17516 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17517 handle_section_bytes + authorization_size_bytes +
17518 authorization_section_bytes + parameter_section_bytes;
17519 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17520 VLOG(2) << "Command: "
17521 << base::HexEncode(serialized_command->data(),
17522 serialized_command->size());
17523 return TPM_RC_SUCCESS;
17524 }
17525
ParseResponse_GetSessionAuditDigest(const std::string & response,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17526 TPM_RC Tpm::ParseResponse_GetSessionAuditDigest(
17527 const std::string& response,
17528 TPM2B_ATTEST* audit_info,
17529 TPMT_SIGNATURE* signature,
17530 AuthorizationDelegate* authorization_delegate) {
17531 VLOG(3) << __func__;
17532 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17533 TPM_RC rc = TPM_RC_SUCCESS;
17534 std::string buffer(response);
17535 TPM_ST tag;
17536 std::string tag_bytes;
17537 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17538 if (rc != TPM_RC_SUCCESS) {
17539 return rc;
17540 }
17541 UINT32 response_size;
17542 std::string response_size_bytes;
17543 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17544 if (rc != TPM_RC_SUCCESS) {
17545 return rc;
17546 }
17547 TPM_RC response_code;
17548 std::string response_code_bytes;
17549 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17550 if (rc != TPM_RC_SUCCESS) {
17551 return rc;
17552 }
17553 if (response_size != response.size()) {
17554 return TPM_RC_SIZE;
17555 }
17556 if (response_code != TPM_RC_SUCCESS) {
17557 return response_code;
17558 }
17559 TPM_CC command_code = TPM_CC_GetSessionAuditDigest;
17560 std::string command_code_bytes;
17561 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17562 if (rc != TPM_RC_SUCCESS) {
17563 return rc;
17564 }
17565 std::string authorization_section_bytes;
17566 if (tag == TPM_ST_SESSIONS) {
17567 UINT32 parameter_section_size = buffer.size();
17568 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
17569 if (rc != TPM_RC_SUCCESS) {
17570 return rc;
17571 }
17572 if (parameter_section_size > buffer.size()) {
17573 return TPM_RC_INSUFFICIENT;
17574 }
17575 authorization_section_bytes = buffer.substr(parameter_section_size);
17576 // Keep the parameter section in |buffer|.
17577 buffer.erase(parameter_section_size);
17578 }
17579 std::unique_ptr<crypto::SecureHash> hash(
17580 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17581 hash->Update(response_code_bytes.data(), response_code_bytes.size());
17582 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17583 hash->Update(buffer.data(), buffer.size());
17584 std::string response_hash(32, 0);
17585 hash->Finish(std::data(response_hash), response_hash.size());
17586 if (tag == TPM_ST_SESSIONS) {
17587 if (!authorization_delegate)
17588 return TRUNKS_RC_AUTHORIZATION_FAILED;
17589 if (!authorization_delegate->CheckResponseAuthorization(
17590 response_hash, authorization_section_bytes)) {
17591 return TRUNKS_RC_AUTHORIZATION_FAILED;
17592 }
17593 }
17594 if (tag == TPM_ST_SESSIONS) {
17595 if (!authorization_delegate)
17596 return TRUNKS_RC_AUTHORIZATION_FAILED;
17597
17598 // Parse the encrypted parameter size.
17599 UINT16 size;
17600 std::string size_buffer = buffer.substr(0, 2);
17601 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17602 return result;
17603 }
17604 if (buffer.size() < 2 + size) {
17605 return TPM_RC_INSUFFICIENT;
17606 }
17607
17608 // Decrypt just the parameter data, not the size.
17609 std::string decrypted_data = buffer.substr(2, size);
17610 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17611 return TRUNKS_RC_ENCRYPTION_FAILED;
17612 }
17613 buffer.replace(2, size, decrypted_data);
17614 }
17615 std::string audit_info_bytes;
17616 rc = Parse_TPM2B_ATTEST(&buffer, audit_info, &audit_info_bytes);
17617 if (rc != TPM_RC_SUCCESS) {
17618 return rc;
17619 }
17620 std::string signature_bytes;
17621 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17622 if (rc != TPM_RC_SUCCESS) {
17623 return rc;
17624 }
17625 return TPM_RC_SUCCESS;
17626 }
17627
GetSessionAuditDigestErrorCallback(Tpm::GetSessionAuditDigestResponse callback,TPM_RC response_code)17628 void GetSessionAuditDigestErrorCallback(
17629 Tpm::GetSessionAuditDigestResponse callback, TPM_RC response_code) {
17630 VLOG(1) << __func__;
17631 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17632 }
17633
GetSessionAuditDigestResponseParser(Tpm::GetSessionAuditDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17634 void GetSessionAuditDigestResponseParser(
17635 Tpm::GetSessionAuditDigestResponse callback,
17636 AuthorizationDelegate* authorization_delegate,
17637 const std::string& response) {
17638 VLOG(1) << __func__;
17639 TPM2B_ATTEST audit_info;
17640 TPMT_SIGNATURE signature;
17641 TPM_RC rc = Tpm::ParseResponse_GetSessionAuditDigest(
17642 response, &audit_info, &signature, authorization_delegate);
17643 if (rc != TPM_RC_SUCCESS) {
17644 base::OnceCallback<void(TPM_RC)> error_reporter =
17645 base::BindOnce(GetSessionAuditDigestErrorCallback, std::move(callback));
17646 std::move(error_reporter).Run(rc);
17647 return;
17648 }
17649 std::move(callback).Run(rc, audit_info, signature);
17650 }
17651
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)17652 void Tpm::GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17653 const std::string& privacy_admin_handle_name,
17654 const TPMI_DH_OBJECT& sign_handle,
17655 const std::string& sign_handle_name,
17656 const TPMI_SH_HMAC& session_handle,
17657 const std::string& session_handle_name,
17658 const TPM2B_DATA& qualifying_data,
17659 const TPMT_SIG_SCHEME& in_scheme,
17660 AuthorizationDelegate* authorization_delegate,
17661 GetSessionAuditDigestResponse callback) {
17662 VLOG(1) << __func__;
17663 std::string command;
17664 TPM_RC rc = SerializeCommand_GetSessionAuditDigest(
17665 privacy_admin_handle, privacy_admin_handle_name, sign_handle,
17666 sign_handle_name, session_handle, session_handle_name, qualifying_data,
17667 in_scheme, &command, authorization_delegate);
17668 if (rc != TPM_RC_SUCCESS) {
17669 base::OnceCallback<void(TPM_RC)> error_reporter =
17670 base::BindOnce(GetSessionAuditDigestErrorCallback, std::move(callback));
17671 std::move(error_reporter).Run(rc);
17672 return;
17673 }
17674 base::OnceCallback<void(const std::string&)> parser =
17675 base::BindOnce(GetSessionAuditDigestResponseParser, std::move(callback),
17676 authorization_delegate);
17677 transceiver_->SendCommand(command, std::move(parser));
17678 }
17679
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)17680 TPM_RC Tpm::GetSessionAuditDigestSync(
17681 const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17682 const std::string& privacy_admin_handle_name,
17683 const TPMI_DH_OBJECT& sign_handle,
17684 const std::string& sign_handle_name,
17685 const TPMI_SH_HMAC& session_handle,
17686 const std::string& session_handle_name,
17687 const TPM2B_DATA& qualifying_data,
17688 const TPMT_SIG_SCHEME& in_scheme,
17689 TPM2B_ATTEST* audit_info,
17690 TPMT_SIGNATURE* signature,
17691 AuthorizationDelegate* authorization_delegate) {
17692 VLOG(1) << __func__;
17693 std::string command;
17694 TPM_RC rc = SerializeCommand_GetSessionAuditDigest(
17695 privacy_admin_handle, privacy_admin_handle_name, sign_handle,
17696 sign_handle_name, session_handle, session_handle_name, qualifying_data,
17697 in_scheme, &command, authorization_delegate);
17698 if (rc != TPM_RC_SUCCESS) {
17699 return rc;
17700 }
17701 std::string response = transceiver_->SendCommandAndWait(command);
17702 rc = ParseResponse_GetSessionAuditDigest(response, audit_info, signature,
17703 authorization_delegate);
17704 return rc;
17705 }
17706
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)17707 TPM_RC Tpm::SerializeCommand_GetCommandAuditDigest(
17708 const TPMI_RH_ENDORSEMENT& privacy_handle,
17709 const std::string& privacy_handle_name,
17710 const TPMI_DH_OBJECT& sign_handle,
17711 const std::string& sign_handle_name,
17712 const TPM2B_DATA& qualifying_data,
17713 const TPMT_SIG_SCHEME& in_scheme,
17714 std::string* serialized_command,
17715 AuthorizationDelegate* authorization_delegate) {
17716 VLOG(3) << __func__;
17717 TPM_RC rc = TPM_RC_SUCCESS;
17718 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17719 UINT32 command_size = 10; // Header size.
17720 std::string handle_section_bytes;
17721 std::string parameter_section_bytes;
17722 TPM_CC command_code = TPM_CC_GetCommandAuditDigest;
17723 bool is_command_parameter_encryption_possible = true;
17724 bool is_response_parameter_encryption_possible = true;
17725 std::string command_code_bytes;
17726 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17727 if (rc != TPM_RC_SUCCESS) {
17728 return rc;
17729 }
17730 std::string privacy_handle_bytes;
17731 rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_handle, &privacy_handle_bytes);
17732 if (rc != TPM_RC_SUCCESS) {
17733 return rc;
17734 }
17735 std::string sign_handle_bytes;
17736 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17737 if (rc != TPM_RC_SUCCESS) {
17738 return rc;
17739 }
17740 std::string qualifying_data_bytes;
17741 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17742 if (rc != TPM_RC_SUCCESS) {
17743 return rc;
17744 }
17745 std::string in_scheme_bytes;
17746 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17747 if (rc != TPM_RC_SUCCESS) {
17748 return rc;
17749 }
17750 if (authorization_delegate) {
17751 // Encrypt just the parameter data, not the size.
17752 std::string tmp = qualifying_data_bytes.substr(2);
17753 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17754 return TRUNKS_RC_ENCRYPTION_FAILED;
17755 }
17756 qualifying_data_bytes.replace(2, std::string::npos, tmp);
17757 }
17758 std::unique_ptr<crypto::SecureHash> hash(
17759 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17760 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17761 hash->Update(privacy_handle_name.data(), privacy_handle_name.size());
17762 handle_section_bytes += privacy_handle_bytes;
17763 command_size += privacy_handle_bytes.size();
17764 hash->Update(sign_handle_name.data(), sign_handle_name.size());
17765 handle_section_bytes += sign_handle_bytes;
17766 command_size += sign_handle_bytes.size();
17767 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17768 parameter_section_bytes += qualifying_data_bytes;
17769 command_size += qualifying_data_bytes.size();
17770 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17771 parameter_section_bytes += in_scheme_bytes;
17772 command_size += in_scheme_bytes.size();
17773 std::string command_hash(32, 0);
17774 hash->Finish(std::data(command_hash), command_hash.size());
17775 std::string authorization_section_bytes;
17776 std::string authorization_size_bytes;
17777 if (authorization_delegate) {
17778 if (!authorization_delegate->GetCommandAuthorization(
17779 command_hash, is_command_parameter_encryption_possible,
17780 is_response_parameter_encryption_possible,
17781 &authorization_section_bytes)) {
17782 return TRUNKS_RC_AUTHORIZATION_FAILED;
17783 }
17784 if (!authorization_section_bytes.empty()) {
17785 tag = TPM_ST_SESSIONS;
17786 std::string tmp;
17787 rc = Serialize_UINT32(authorization_section_bytes.size(),
17788 &authorization_size_bytes);
17789 if (rc != TPM_RC_SUCCESS) {
17790 return rc;
17791 }
17792 command_size +=
17793 authorization_size_bytes.size() + authorization_section_bytes.size();
17794 }
17795 }
17796 std::string tag_bytes;
17797 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17798 if (rc != TPM_RC_SUCCESS) {
17799 return rc;
17800 }
17801 std::string command_size_bytes;
17802 rc = Serialize_UINT32(command_size, &command_size_bytes);
17803 if (rc != TPM_RC_SUCCESS) {
17804 return rc;
17805 }
17806 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17807 handle_section_bytes + authorization_size_bytes +
17808 authorization_section_bytes + parameter_section_bytes;
17809 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17810 VLOG(2) << "Command: "
17811 << base::HexEncode(serialized_command->data(),
17812 serialized_command->size());
17813 return TPM_RC_SUCCESS;
17814 }
17815
ParseResponse_GetCommandAuditDigest(const std::string & response,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17816 TPM_RC Tpm::ParseResponse_GetCommandAuditDigest(
17817 const std::string& response,
17818 TPM2B_ATTEST* audit_info,
17819 TPMT_SIGNATURE* signature,
17820 AuthorizationDelegate* authorization_delegate) {
17821 VLOG(3) << __func__;
17822 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17823 TPM_RC rc = TPM_RC_SUCCESS;
17824 std::string buffer(response);
17825 TPM_ST tag;
17826 std::string tag_bytes;
17827 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17828 if (rc != TPM_RC_SUCCESS) {
17829 return rc;
17830 }
17831 UINT32 response_size;
17832 std::string response_size_bytes;
17833 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17834 if (rc != TPM_RC_SUCCESS) {
17835 return rc;
17836 }
17837 TPM_RC response_code;
17838 std::string response_code_bytes;
17839 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17840 if (rc != TPM_RC_SUCCESS) {
17841 return rc;
17842 }
17843 if (response_size != response.size()) {
17844 return TPM_RC_SIZE;
17845 }
17846 if (response_code != TPM_RC_SUCCESS) {
17847 return response_code;
17848 }
17849 TPM_CC command_code = TPM_CC_GetCommandAuditDigest;
17850 std::string command_code_bytes;
17851 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17852 if (rc != TPM_RC_SUCCESS) {
17853 return rc;
17854 }
17855 std::string authorization_section_bytes;
17856 if (tag == TPM_ST_SESSIONS) {
17857 UINT32 parameter_section_size = buffer.size();
17858 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
17859 if (rc != TPM_RC_SUCCESS) {
17860 return rc;
17861 }
17862 if (parameter_section_size > buffer.size()) {
17863 return TPM_RC_INSUFFICIENT;
17864 }
17865 authorization_section_bytes = buffer.substr(parameter_section_size);
17866 // Keep the parameter section in |buffer|.
17867 buffer.erase(parameter_section_size);
17868 }
17869 std::unique_ptr<crypto::SecureHash> hash(
17870 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17871 hash->Update(response_code_bytes.data(), response_code_bytes.size());
17872 hash->Update(command_code_bytes.data(), command_code_bytes.size());
17873 hash->Update(buffer.data(), buffer.size());
17874 std::string response_hash(32, 0);
17875 hash->Finish(std::data(response_hash), response_hash.size());
17876 if (tag == TPM_ST_SESSIONS) {
17877 if (!authorization_delegate)
17878 return TRUNKS_RC_AUTHORIZATION_FAILED;
17879 if (!authorization_delegate->CheckResponseAuthorization(
17880 response_hash, authorization_section_bytes)) {
17881 return TRUNKS_RC_AUTHORIZATION_FAILED;
17882 }
17883 }
17884 if (tag == TPM_ST_SESSIONS) {
17885 if (!authorization_delegate)
17886 return TRUNKS_RC_AUTHORIZATION_FAILED;
17887
17888 // Parse the encrypted parameter size.
17889 UINT16 size;
17890 std::string size_buffer = buffer.substr(0, 2);
17891 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17892 return result;
17893 }
17894 if (buffer.size() < 2 + size) {
17895 return TPM_RC_INSUFFICIENT;
17896 }
17897
17898 // Decrypt just the parameter data, not the size.
17899 std::string decrypted_data = buffer.substr(2, size);
17900 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17901 return TRUNKS_RC_ENCRYPTION_FAILED;
17902 }
17903 buffer.replace(2, size, decrypted_data);
17904 }
17905 std::string audit_info_bytes;
17906 rc = Parse_TPM2B_ATTEST(&buffer, audit_info, &audit_info_bytes);
17907 if (rc != TPM_RC_SUCCESS) {
17908 return rc;
17909 }
17910 std::string signature_bytes;
17911 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17912 if (rc != TPM_RC_SUCCESS) {
17913 return rc;
17914 }
17915 return TPM_RC_SUCCESS;
17916 }
17917
GetCommandAuditDigestErrorCallback(Tpm::GetCommandAuditDigestResponse callback,TPM_RC response_code)17918 void GetCommandAuditDigestErrorCallback(
17919 Tpm::GetCommandAuditDigestResponse callback, TPM_RC response_code) {
17920 VLOG(1) << __func__;
17921 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17922 }
17923
GetCommandAuditDigestResponseParser(Tpm::GetCommandAuditDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17924 void GetCommandAuditDigestResponseParser(
17925 Tpm::GetCommandAuditDigestResponse callback,
17926 AuthorizationDelegate* authorization_delegate,
17927 const std::string& response) {
17928 VLOG(1) << __func__;
17929 TPM2B_ATTEST audit_info;
17930 TPMT_SIGNATURE signature;
17931 TPM_RC rc = Tpm::ParseResponse_GetCommandAuditDigest(
17932 response, &audit_info, &signature, authorization_delegate);
17933 if (rc != TPM_RC_SUCCESS) {
17934 base::OnceCallback<void(TPM_RC)> error_reporter =
17935 base::BindOnce(GetCommandAuditDigestErrorCallback, std::move(callback));
17936 std::move(error_reporter).Run(rc);
17937 return;
17938 }
17939 std::move(callback).Run(rc, audit_info, signature);
17940 }
17941
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)17942 void Tpm::GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT& privacy_handle,
17943 const std::string& privacy_handle_name,
17944 const TPMI_DH_OBJECT& sign_handle,
17945 const std::string& sign_handle_name,
17946 const TPM2B_DATA& qualifying_data,
17947 const TPMT_SIG_SCHEME& in_scheme,
17948 AuthorizationDelegate* authorization_delegate,
17949 GetCommandAuditDigestResponse callback) {
17950 VLOG(1) << __func__;
17951 std::string command;
17952 TPM_RC rc = SerializeCommand_GetCommandAuditDigest(
17953 privacy_handle, privacy_handle_name, sign_handle, sign_handle_name,
17954 qualifying_data, in_scheme, &command, authorization_delegate);
17955 if (rc != TPM_RC_SUCCESS) {
17956 base::OnceCallback<void(TPM_RC)> error_reporter =
17957 base::BindOnce(GetCommandAuditDigestErrorCallback, std::move(callback));
17958 std::move(error_reporter).Run(rc);
17959 return;
17960 }
17961 base::OnceCallback<void(const std::string&)> parser =
17962 base::BindOnce(GetCommandAuditDigestResponseParser, std::move(callback),
17963 authorization_delegate);
17964 transceiver_->SendCommand(command, std::move(parser));
17965 }
17966
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)17967 TPM_RC Tpm::GetCommandAuditDigestSync(
17968 const TPMI_RH_ENDORSEMENT& privacy_handle,
17969 const std::string& privacy_handle_name,
17970 const TPMI_DH_OBJECT& sign_handle,
17971 const std::string& sign_handle_name,
17972 const TPM2B_DATA& qualifying_data,
17973 const TPMT_SIG_SCHEME& in_scheme,
17974 TPM2B_ATTEST* audit_info,
17975 TPMT_SIGNATURE* signature,
17976 AuthorizationDelegate* authorization_delegate) {
17977 VLOG(1) << __func__;
17978 std::string command;
17979 TPM_RC rc = SerializeCommand_GetCommandAuditDigest(
17980 privacy_handle, privacy_handle_name, sign_handle, sign_handle_name,
17981 qualifying_data, in_scheme, &command, authorization_delegate);
17982 if (rc != TPM_RC_SUCCESS) {
17983 return rc;
17984 }
17985 std::string response = transceiver_->SendCommandAndWait(command);
17986 rc = ParseResponse_GetCommandAuditDigest(response, audit_info, signature,
17987 authorization_delegate);
17988 return rc;
17989 }
17990
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)17991 TPM_RC Tpm::SerializeCommand_GetTime(
17992 const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17993 const std::string& privacy_admin_handle_name,
17994 const TPMI_DH_OBJECT& sign_handle,
17995 const std::string& sign_handle_name,
17996 const TPM2B_DATA& qualifying_data,
17997 const TPMT_SIG_SCHEME& in_scheme,
17998 std::string* serialized_command,
17999 AuthorizationDelegate* authorization_delegate) {
18000 VLOG(3) << __func__;
18001 TPM_RC rc = TPM_RC_SUCCESS;
18002 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18003 UINT32 command_size = 10; // Header size.
18004 std::string handle_section_bytes;
18005 std::string parameter_section_bytes;
18006 TPM_CC command_code = TPM_CC_GetTime;
18007 bool is_command_parameter_encryption_possible = true;
18008 bool is_response_parameter_encryption_possible = true;
18009 std::string command_code_bytes;
18010 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18011 if (rc != TPM_RC_SUCCESS) {
18012 return rc;
18013 }
18014 std::string privacy_admin_handle_bytes;
18015 rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_admin_handle,
18016 &privacy_admin_handle_bytes);
18017 if (rc != TPM_RC_SUCCESS) {
18018 return rc;
18019 }
18020 std::string sign_handle_bytes;
18021 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
18022 if (rc != TPM_RC_SUCCESS) {
18023 return rc;
18024 }
18025 std::string qualifying_data_bytes;
18026 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
18027 if (rc != TPM_RC_SUCCESS) {
18028 return rc;
18029 }
18030 std::string in_scheme_bytes;
18031 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
18032 if (rc != TPM_RC_SUCCESS) {
18033 return rc;
18034 }
18035 if (authorization_delegate) {
18036 // Encrypt just the parameter data, not the size.
18037 std::string tmp = qualifying_data_bytes.substr(2);
18038 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
18039 return TRUNKS_RC_ENCRYPTION_FAILED;
18040 }
18041 qualifying_data_bytes.replace(2, std::string::npos, tmp);
18042 }
18043 std::unique_ptr<crypto::SecureHash> hash(
18044 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18045 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18046 hash->Update(privacy_admin_handle_name.data(),
18047 privacy_admin_handle_name.size());
18048 handle_section_bytes += privacy_admin_handle_bytes;
18049 command_size += privacy_admin_handle_bytes.size();
18050 hash->Update(sign_handle_name.data(), sign_handle_name.size());
18051 handle_section_bytes += sign_handle_bytes;
18052 command_size += sign_handle_bytes.size();
18053 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
18054 parameter_section_bytes += qualifying_data_bytes;
18055 command_size += qualifying_data_bytes.size();
18056 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
18057 parameter_section_bytes += in_scheme_bytes;
18058 command_size += in_scheme_bytes.size();
18059 std::string command_hash(32, 0);
18060 hash->Finish(std::data(command_hash), command_hash.size());
18061 std::string authorization_section_bytes;
18062 std::string authorization_size_bytes;
18063 if (authorization_delegate) {
18064 if (!authorization_delegate->GetCommandAuthorization(
18065 command_hash, is_command_parameter_encryption_possible,
18066 is_response_parameter_encryption_possible,
18067 &authorization_section_bytes)) {
18068 return TRUNKS_RC_AUTHORIZATION_FAILED;
18069 }
18070 if (!authorization_section_bytes.empty()) {
18071 tag = TPM_ST_SESSIONS;
18072 std::string tmp;
18073 rc = Serialize_UINT32(authorization_section_bytes.size(),
18074 &authorization_size_bytes);
18075 if (rc != TPM_RC_SUCCESS) {
18076 return rc;
18077 }
18078 command_size +=
18079 authorization_size_bytes.size() + authorization_section_bytes.size();
18080 }
18081 }
18082 std::string tag_bytes;
18083 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18084 if (rc != TPM_RC_SUCCESS) {
18085 return rc;
18086 }
18087 std::string command_size_bytes;
18088 rc = Serialize_UINT32(command_size, &command_size_bytes);
18089 if (rc != TPM_RC_SUCCESS) {
18090 return rc;
18091 }
18092 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18093 handle_section_bytes + authorization_size_bytes +
18094 authorization_section_bytes + parameter_section_bytes;
18095 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18096 VLOG(2) << "Command: "
18097 << base::HexEncode(serialized_command->data(),
18098 serialized_command->size());
18099 return TPM_RC_SUCCESS;
18100 }
18101
ParseResponse_GetTime(const std::string & response,TPM2B_ATTEST * time_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)18102 TPM_RC Tpm::ParseResponse_GetTime(
18103 const std::string& response,
18104 TPM2B_ATTEST* time_info,
18105 TPMT_SIGNATURE* signature,
18106 AuthorizationDelegate* authorization_delegate) {
18107 VLOG(3) << __func__;
18108 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18109 TPM_RC rc = TPM_RC_SUCCESS;
18110 std::string buffer(response);
18111 TPM_ST tag;
18112 std::string tag_bytes;
18113 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18114 if (rc != TPM_RC_SUCCESS) {
18115 return rc;
18116 }
18117 UINT32 response_size;
18118 std::string response_size_bytes;
18119 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18120 if (rc != TPM_RC_SUCCESS) {
18121 return rc;
18122 }
18123 TPM_RC response_code;
18124 std::string response_code_bytes;
18125 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18126 if (rc != TPM_RC_SUCCESS) {
18127 return rc;
18128 }
18129 if (response_size != response.size()) {
18130 return TPM_RC_SIZE;
18131 }
18132 if (response_code != TPM_RC_SUCCESS) {
18133 return response_code;
18134 }
18135 TPM_CC command_code = TPM_CC_GetTime;
18136 std::string command_code_bytes;
18137 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18138 if (rc != TPM_RC_SUCCESS) {
18139 return rc;
18140 }
18141 std::string authorization_section_bytes;
18142 if (tag == TPM_ST_SESSIONS) {
18143 UINT32 parameter_section_size = buffer.size();
18144 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
18145 if (rc != TPM_RC_SUCCESS) {
18146 return rc;
18147 }
18148 if (parameter_section_size > buffer.size()) {
18149 return TPM_RC_INSUFFICIENT;
18150 }
18151 authorization_section_bytes = buffer.substr(parameter_section_size);
18152 // Keep the parameter section in |buffer|.
18153 buffer.erase(parameter_section_size);
18154 }
18155 std::unique_ptr<crypto::SecureHash> hash(
18156 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18157 hash->Update(response_code_bytes.data(), response_code_bytes.size());
18158 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18159 hash->Update(buffer.data(), buffer.size());
18160 std::string response_hash(32, 0);
18161 hash->Finish(std::data(response_hash), response_hash.size());
18162 if (tag == TPM_ST_SESSIONS) {
18163 if (!authorization_delegate)
18164 return TRUNKS_RC_AUTHORIZATION_FAILED;
18165 if (!authorization_delegate->CheckResponseAuthorization(
18166 response_hash, authorization_section_bytes)) {
18167 return TRUNKS_RC_AUTHORIZATION_FAILED;
18168 }
18169 }
18170 if (tag == TPM_ST_SESSIONS) {
18171 if (!authorization_delegate)
18172 return TRUNKS_RC_AUTHORIZATION_FAILED;
18173
18174 // Parse the encrypted parameter size.
18175 UINT16 size;
18176 std::string size_buffer = buffer.substr(0, 2);
18177 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
18178 return result;
18179 }
18180 if (buffer.size() < 2 + size) {
18181 return TPM_RC_INSUFFICIENT;
18182 }
18183
18184 // Decrypt just the parameter data, not the size.
18185 std::string decrypted_data = buffer.substr(2, size);
18186 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
18187 return TRUNKS_RC_ENCRYPTION_FAILED;
18188 }
18189 buffer.replace(2, size, decrypted_data);
18190 }
18191 std::string time_info_bytes;
18192 rc = Parse_TPM2B_ATTEST(&buffer, time_info, &time_info_bytes);
18193 if (rc != TPM_RC_SUCCESS) {
18194 return rc;
18195 }
18196 std::string signature_bytes;
18197 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
18198 if (rc != TPM_RC_SUCCESS) {
18199 return rc;
18200 }
18201 return TPM_RC_SUCCESS;
18202 }
18203
GetTimeErrorCallback(Tpm::GetTimeResponse callback,TPM_RC response_code)18204 void GetTimeErrorCallback(Tpm::GetTimeResponse callback, TPM_RC response_code) {
18205 VLOG(1) << __func__;
18206 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
18207 }
18208
GetTimeResponseParser(Tpm::GetTimeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18209 void GetTimeResponseParser(Tpm::GetTimeResponse callback,
18210 AuthorizationDelegate* authorization_delegate,
18211 const std::string& response) {
18212 VLOG(1) << __func__;
18213 TPM2B_ATTEST time_info;
18214 TPMT_SIGNATURE signature;
18215 TPM_RC rc = Tpm::ParseResponse_GetTime(response, &time_info, &signature,
18216 authorization_delegate);
18217 if (rc != TPM_RC_SUCCESS) {
18218 base::OnceCallback<void(TPM_RC)> error_reporter =
18219 base::BindOnce(GetTimeErrorCallback, std::move(callback));
18220 std::move(error_reporter).Run(rc);
18221 return;
18222 }
18223 std::move(callback).Run(rc, time_info, signature);
18224 }
18225
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)18226 void Tpm::GetTime(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
18227 const std::string& privacy_admin_handle_name,
18228 const TPMI_DH_OBJECT& sign_handle,
18229 const std::string& sign_handle_name,
18230 const TPM2B_DATA& qualifying_data,
18231 const TPMT_SIG_SCHEME& in_scheme,
18232 AuthorizationDelegate* authorization_delegate,
18233 GetTimeResponse callback) {
18234 VLOG(1) << __func__;
18235 std::string command;
18236 TPM_RC rc =
18237 SerializeCommand_GetTime(privacy_admin_handle, privacy_admin_handle_name,
18238 sign_handle, sign_handle_name, qualifying_data,
18239 in_scheme, &command, authorization_delegate);
18240 if (rc != TPM_RC_SUCCESS) {
18241 base::OnceCallback<void(TPM_RC)> error_reporter =
18242 base::BindOnce(GetTimeErrorCallback, std::move(callback));
18243 std::move(error_reporter).Run(rc);
18244 return;
18245 }
18246 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18247 GetTimeResponseParser, std::move(callback), authorization_delegate);
18248 transceiver_->SendCommand(command, std::move(parser));
18249 }
18250
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)18251 TPM_RC Tpm::GetTimeSync(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
18252 const std::string& privacy_admin_handle_name,
18253 const TPMI_DH_OBJECT& sign_handle,
18254 const std::string& sign_handle_name,
18255 const TPM2B_DATA& qualifying_data,
18256 const TPMT_SIG_SCHEME& in_scheme,
18257 TPM2B_ATTEST* time_info,
18258 TPMT_SIGNATURE* signature,
18259 AuthorizationDelegate* authorization_delegate) {
18260 VLOG(1) << __func__;
18261 std::string command;
18262 TPM_RC rc =
18263 SerializeCommand_GetTime(privacy_admin_handle, privacy_admin_handle_name,
18264 sign_handle, sign_handle_name, qualifying_data,
18265 in_scheme, &command, authorization_delegate);
18266 if (rc != TPM_RC_SUCCESS) {
18267 return rc;
18268 }
18269 std::string response = transceiver_->SendCommandAndWait(command);
18270 rc = ParseResponse_GetTime(response, time_info, signature,
18271 authorization_delegate);
18272 return rc;
18273 }
18274
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)18275 TPM_RC Tpm::SerializeCommand_Commit(
18276 const TPMI_DH_OBJECT& sign_handle,
18277 const std::string& sign_handle_name,
18278 const UINT32& param_size,
18279 const TPM2B_ECC_POINT& p1,
18280 const TPM2B_SENSITIVE_DATA& s2,
18281 const TPM2B_ECC_PARAMETER& y2,
18282 std::string* serialized_command,
18283 AuthorizationDelegate* authorization_delegate) {
18284 VLOG(3) << __func__;
18285 TPM_RC rc = TPM_RC_SUCCESS;
18286 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18287 UINT32 command_size = 10; // Header size.
18288 std::string handle_section_bytes;
18289 std::string parameter_section_bytes;
18290 TPM_CC command_code = TPM_CC_Commit;
18291 bool is_command_parameter_encryption_possible = false;
18292 bool is_response_parameter_encryption_possible = false;
18293 std::string command_code_bytes;
18294 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18295 if (rc != TPM_RC_SUCCESS) {
18296 return rc;
18297 }
18298 std::string param_size_bytes;
18299 rc = Serialize_UINT32(param_size, ¶m_size_bytes);
18300 if (rc != TPM_RC_SUCCESS) {
18301 return rc;
18302 }
18303 std::string sign_handle_bytes;
18304 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
18305 if (rc != TPM_RC_SUCCESS) {
18306 return rc;
18307 }
18308 std::string p1_bytes;
18309 rc = Serialize_TPM2B_ECC_POINT(p1, &p1_bytes);
18310 if (rc != TPM_RC_SUCCESS) {
18311 return rc;
18312 }
18313 std::string s2_bytes;
18314 rc = Serialize_TPM2B_SENSITIVE_DATA(s2, &s2_bytes);
18315 if (rc != TPM_RC_SUCCESS) {
18316 return rc;
18317 }
18318 std::string y2_bytes;
18319 rc = Serialize_TPM2B_ECC_PARAMETER(y2, &y2_bytes);
18320 if (rc != TPM_RC_SUCCESS) {
18321 return rc;
18322 }
18323 std::unique_ptr<crypto::SecureHash> hash(
18324 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18325 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18326 hash->Update(sign_handle_name.data(), sign_handle_name.size());
18327 handle_section_bytes += sign_handle_bytes;
18328 command_size += sign_handle_bytes.size();
18329 hash->Update(param_size_bytes.data(), param_size_bytes.size());
18330 parameter_section_bytes += param_size_bytes;
18331 command_size += param_size_bytes.size();
18332 hash->Update(p1_bytes.data(), p1_bytes.size());
18333 parameter_section_bytes += p1_bytes;
18334 command_size += p1_bytes.size();
18335 hash->Update(s2_bytes.data(), s2_bytes.size());
18336 parameter_section_bytes += s2_bytes;
18337 command_size += s2_bytes.size();
18338 hash->Update(y2_bytes.data(), y2_bytes.size());
18339 parameter_section_bytes += y2_bytes;
18340 command_size += y2_bytes.size();
18341 std::string command_hash(32, 0);
18342 hash->Finish(std::data(command_hash), command_hash.size());
18343 std::string authorization_section_bytes;
18344 std::string authorization_size_bytes;
18345 if (authorization_delegate) {
18346 if (!authorization_delegate->GetCommandAuthorization(
18347 command_hash, is_command_parameter_encryption_possible,
18348 is_response_parameter_encryption_possible,
18349 &authorization_section_bytes)) {
18350 return TRUNKS_RC_AUTHORIZATION_FAILED;
18351 }
18352 if (!authorization_section_bytes.empty()) {
18353 tag = TPM_ST_SESSIONS;
18354 std::string tmp;
18355 rc = Serialize_UINT32(authorization_section_bytes.size(),
18356 &authorization_size_bytes);
18357 if (rc != TPM_RC_SUCCESS) {
18358 return rc;
18359 }
18360 command_size +=
18361 authorization_size_bytes.size() + authorization_section_bytes.size();
18362 }
18363 }
18364 std::string tag_bytes;
18365 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18366 if (rc != TPM_RC_SUCCESS) {
18367 return rc;
18368 }
18369 std::string command_size_bytes;
18370 rc = Serialize_UINT32(command_size, &command_size_bytes);
18371 if (rc != TPM_RC_SUCCESS) {
18372 return rc;
18373 }
18374 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18375 handle_section_bytes + authorization_size_bytes +
18376 authorization_section_bytes + parameter_section_bytes;
18377 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18378 VLOG(2) << "Command: "
18379 << base::HexEncode(serialized_command->data(),
18380 serialized_command->size());
18381 return TPM_RC_SUCCESS;
18382 }
18383
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)18384 TPM_RC Tpm::ParseResponse_Commit(
18385 const std::string& response,
18386 UINT32* param_size_out,
18387 TPM2B_ECC_POINT* k,
18388 TPM2B_ECC_POINT* l,
18389 TPM2B_ECC_POINT* e,
18390 UINT16* counter,
18391 AuthorizationDelegate* authorization_delegate) {
18392 VLOG(3) << __func__;
18393 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18394 TPM_RC rc = TPM_RC_SUCCESS;
18395 std::string buffer(response);
18396 TPM_ST tag;
18397 std::string tag_bytes;
18398 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18399 if (rc != TPM_RC_SUCCESS) {
18400 return rc;
18401 }
18402 UINT32 response_size;
18403 std::string response_size_bytes;
18404 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18405 if (rc != TPM_RC_SUCCESS) {
18406 return rc;
18407 }
18408 TPM_RC response_code;
18409 std::string response_code_bytes;
18410 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18411 if (rc != TPM_RC_SUCCESS) {
18412 return rc;
18413 }
18414 if (response_size != response.size()) {
18415 return TPM_RC_SIZE;
18416 }
18417 if (response_code != TPM_RC_SUCCESS) {
18418 return response_code;
18419 }
18420 TPM_CC command_code = TPM_CC_Commit;
18421 std::string command_code_bytes;
18422 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18423 if (rc != TPM_RC_SUCCESS) {
18424 return rc;
18425 }
18426 std::string authorization_section_bytes;
18427 if (tag == TPM_ST_SESSIONS) {
18428 UINT32 parameter_section_size = buffer.size();
18429 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
18430 if (rc != TPM_RC_SUCCESS) {
18431 return rc;
18432 }
18433 if (parameter_section_size > buffer.size()) {
18434 return TPM_RC_INSUFFICIENT;
18435 }
18436 authorization_section_bytes = buffer.substr(parameter_section_size);
18437 // Keep the parameter section in |buffer|.
18438 buffer.erase(parameter_section_size);
18439 }
18440 std::unique_ptr<crypto::SecureHash> hash(
18441 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18442 hash->Update(response_code_bytes.data(), response_code_bytes.size());
18443 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18444 hash->Update(buffer.data(), buffer.size());
18445 std::string response_hash(32, 0);
18446 hash->Finish(std::data(response_hash), response_hash.size());
18447 if (tag == TPM_ST_SESSIONS) {
18448 if (!authorization_delegate)
18449 return TRUNKS_RC_AUTHORIZATION_FAILED;
18450 if (!authorization_delegate->CheckResponseAuthorization(
18451 response_hash, authorization_section_bytes)) {
18452 return TRUNKS_RC_AUTHORIZATION_FAILED;
18453 }
18454 }
18455 std::string param_size_out_bytes;
18456 rc = Parse_UINT32(&buffer, param_size_out, ¶m_size_out_bytes);
18457 if (rc != TPM_RC_SUCCESS) {
18458 return rc;
18459 }
18460 std::string k_bytes;
18461 rc = Parse_TPM2B_ECC_POINT(&buffer, k, &k_bytes);
18462 if (rc != TPM_RC_SUCCESS) {
18463 return rc;
18464 }
18465 std::string l_bytes;
18466 rc = Parse_TPM2B_ECC_POINT(&buffer, l, &l_bytes);
18467 if (rc != TPM_RC_SUCCESS) {
18468 return rc;
18469 }
18470 std::string e_bytes;
18471 rc = Parse_TPM2B_ECC_POINT(&buffer, e, &e_bytes);
18472 if (rc != TPM_RC_SUCCESS) {
18473 return rc;
18474 }
18475 std::string counter_bytes;
18476 rc = Parse_UINT16(&buffer, counter, &counter_bytes);
18477 if (rc != TPM_RC_SUCCESS) {
18478 return rc;
18479 }
18480 return TPM_RC_SUCCESS;
18481 }
18482
CommitErrorCallback(Tpm::CommitResponse callback,TPM_RC response_code)18483 void CommitErrorCallback(Tpm::CommitResponse callback, TPM_RC response_code) {
18484 VLOG(1) << __func__;
18485 std::move(callback).Run(response_code, UINT32(), TPM2B_ECC_POINT(),
18486 TPM2B_ECC_POINT(), TPM2B_ECC_POINT(), UINT16());
18487 }
18488
CommitResponseParser(Tpm::CommitResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18489 void CommitResponseParser(Tpm::CommitResponse callback,
18490 AuthorizationDelegate* authorization_delegate,
18491 const std::string& response) {
18492 VLOG(1) << __func__;
18493 UINT32 param_size_out;
18494 TPM2B_ECC_POINT k;
18495 TPM2B_ECC_POINT l;
18496 TPM2B_ECC_POINT e;
18497 UINT16 counter;
18498 TPM_RC rc = Tpm::ParseResponse_Commit(response, ¶m_size_out, &k, &l, &e,
18499 &counter, authorization_delegate);
18500 if (rc != TPM_RC_SUCCESS) {
18501 base::OnceCallback<void(TPM_RC)> error_reporter =
18502 base::BindOnce(CommitErrorCallback, std::move(callback));
18503 std::move(error_reporter).Run(rc);
18504 return;
18505 }
18506 std::move(callback).Run(rc, param_size_out, k, l, e, counter);
18507 }
18508
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)18509 void Tpm::Commit(const TPMI_DH_OBJECT& sign_handle,
18510 const std::string& sign_handle_name,
18511 const UINT32& param_size,
18512 const TPM2B_ECC_POINT& p1,
18513 const TPM2B_SENSITIVE_DATA& s2,
18514 const TPM2B_ECC_PARAMETER& y2,
18515 AuthorizationDelegate* authorization_delegate,
18516 CommitResponse callback) {
18517 VLOG(1) << __func__;
18518 std::string command;
18519 TPM_RC rc =
18520 SerializeCommand_Commit(sign_handle, sign_handle_name, param_size, p1, s2,
18521 y2, &command, authorization_delegate);
18522 if (rc != TPM_RC_SUCCESS) {
18523 base::OnceCallback<void(TPM_RC)> error_reporter =
18524 base::BindOnce(CommitErrorCallback, std::move(callback));
18525 std::move(error_reporter).Run(rc);
18526 return;
18527 }
18528 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18529 CommitResponseParser, std::move(callback), authorization_delegate);
18530 transceiver_->SendCommand(command, std::move(parser));
18531 }
18532
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)18533 TPM_RC Tpm::CommitSync(const TPMI_DH_OBJECT& sign_handle,
18534 const std::string& sign_handle_name,
18535 const UINT32& param_size,
18536 const TPM2B_ECC_POINT& p1,
18537 const TPM2B_SENSITIVE_DATA& s2,
18538 const TPM2B_ECC_PARAMETER& y2,
18539 UINT32* param_size_out,
18540 TPM2B_ECC_POINT* k,
18541 TPM2B_ECC_POINT* l,
18542 TPM2B_ECC_POINT* e,
18543 UINT16* counter,
18544 AuthorizationDelegate* authorization_delegate) {
18545 VLOG(1) << __func__;
18546 std::string command;
18547 TPM_RC rc =
18548 SerializeCommand_Commit(sign_handle, sign_handle_name, param_size, p1, s2,
18549 y2, &command, authorization_delegate);
18550 if (rc != TPM_RC_SUCCESS) {
18551 return rc;
18552 }
18553 std::string response = transceiver_->SendCommandAndWait(command);
18554 rc = ParseResponse_Commit(response, param_size_out, k, l, e, counter,
18555 authorization_delegate);
18556 return rc;
18557 }
18558
SerializeCommand_EC_Ephemeral(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)18559 TPM_RC Tpm::SerializeCommand_EC_Ephemeral(
18560 const UINT32& param_size,
18561 const TPMI_ECC_CURVE& curve_id,
18562 std::string* serialized_command,
18563 AuthorizationDelegate* authorization_delegate) {
18564 VLOG(3) << __func__;
18565 TPM_RC rc = TPM_RC_SUCCESS;
18566 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18567 UINT32 command_size = 10; // Header size.
18568 std::string handle_section_bytes;
18569 std::string parameter_section_bytes;
18570 TPM_CC command_code = TPM_CC_EC_Ephemeral;
18571 bool is_command_parameter_encryption_possible = false;
18572 bool is_response_parameter_encryption_possible = false;
18573 std::string command_code_bytes;
18574 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18575 if (rc != TPM_RC_SUCCESS) {
18576 return rc;
18577 }
18578 std::string param_size_bytes;
18579 rc = Serialize_UINT32(param_size, ¶m_size_bytes);
18580 if (rc != TPM_RC_SUCCESS) {
18581 return rc;
18582 }
18583 std::string curve_id_bytes;
18584 rc = Serialize_TPMI_ECC_CURVE(curve_id, &curve_id_bytes);
18585 if (rc != TPM_RC_SUCCESS) {
18586 return rc;
18587 }
18588 std::unique_ptr<crypto::SecureHash> hash(
18589 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18590 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18591 hash->Update(param_size_bytes.data(), param_size_bytes.size());
18592 parameter_section_bytes += param_size_bytes;
18593 command_size += param_size_bytes.size();
18594 hash->Update(curve_id_bytes.data(), curve_id_bytes.size());
18595 parameter_section_bytes += curve_id_bytes;
18596 command_size += curve_id_bytes.size();
18597 std::string command_hash(32, 0);
18598 hash->Finish(std::data(command_hash), command_hash.size());
18599 std::string authorization_section_bytes;
18600 std::string authorization_size_bytes;
18601 if (authorization_delegate) {
18602 if (!authorization_delegate->GetCommandAuthorization(
18603 command_hash, is_command_parameter_encryption_possible,
18604 is_response_parameter_encryption_possible,
18605 &authorization_section_bytes)) {
18606 return TRUNKS_RC_AUTHORIZATION_FAILED;
18607 }
18608 if (!authorization_section_bytes.empty()) {
18609 tag = TPM_ST_SESSIONS;
18610 std::string tmp;
18611 rc = Serialize_UINT32(authorization_section_bytes.size(),
18612 &authorization_size_bytes);
18613 if (rc != TPM_RC_SUCCESS) {
18614 return rc;
18615 }
18616 command_size +=
18617 authorization_size_bytes.size() + authorization_section_bytes.size();
18618 }
18619 }
18620 std::string tag_bytes;
18621 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18622 if (rc != TPM_RC_SUCCESS) {
18623 return rc;
18624 }
18625 std::string command_size_bytes;
18626 rc = Serialize_UINT32(command_size, &command_size_bytes);
18627 if (rc != TPM_RC_SUCCESS) {
18628 return rc;
18629 }
18630 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18631 handle_section_bytes + authorization_size_bytes +
18632 authorization_section_bytes + parameter_section_bytes;
18633 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18634 VLOG(2) << "Command: "
18635 << base::HexEncode(serialized_command->data(),
18636 serialized_command->size());
18637 return TPM_RC_SUCCESS;
18638 }
18639
ParseResponse_EC_Ephemeral(const std::string & response,UINT32 * param_size_out,TPM2B_ECC_POINT * q,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18640 TPM_RC Tpm::ParseResponse_EC_Ephemeral(
18641 const std::string& response,
18642 UINT32* param_size_out,
18643 TPM2B_ECC_POINT* q,
18644 UINT16* counter,
18645 AuthorizationDelegate* authorization_delegate) {
18646 VLOG(3) << __func__;
18647 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18648 TPM_RC rc = TPM_RC_SUCCESS;
18649 std::string buffer(response);
18650 TPM_ST tag;
18651 std::string tag_bytes;
18652 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18653 if (rc != TPM_RC_SUCCESS) {
18654 return rc;
18655 }
18656 UINT32 response_size;
18657 std::string response_size_bytes;
18658 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18659 if (rc != TPM_RC_SUCCESS) {
18660 return rc;
18661 }
18662 TPM_RC response_code;
18663 std::string response_code_bytes;
18664 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18665 if (rc != TPM_RC_SUCCESS) {
18666 return rc;
18667 }
18668 if (response_size != response.size()) {
18669 return TPM_RC_SIZE;
18670 }
18671 if (response_code != TPM_RC_SUCCESS) {
18672 return response_code;
18673 }
18674 TPM_CC command_code = TPM_CC_EC_Ephemeral;
18675 std::string command_code_bytes;
18676 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18677 if (rc != TPM_RC_SUCCESS) {
18678 return rc;
18679 }
18680 std::string authorization_section_bytes;
18681 if (tag == TPM_ST_SESSIONS) {
18682 UINT32 parameter_section_size = buffer.size();
18683 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
18684 if (rc != TPM_RC_SUCCESS) {
18685 return rc;
18686 }
18687 if (parameter_section_size > buffer.size()) {
18688 return TPM_RC_INSUFFICIENT;
18689 }
18690 authorization_section_bytes = buffer.substr(parameter_section_size);
18691 // Keep the parameter section in |buffer|.
18692 buffer.erase(parameter_section_size);
18693 }
18694 std::unique_ptr<crypto::SecureHash> hash(
18695 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18696 hash->Update(response_code_bytes.data(), response_code_bytes.size());
18697 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18698 hash->Update(buffer.data(), buffer.size());
18699 std::string response_hash(32, 0);
18700 hash->Finish(std::data(response_hash), response_hash.size());
18701 if (tag == TPM_ST_SESSIONS) {
18702 if (!authorization_delegate)
18703 return TRUNKS_RC_AUTHORIZATION_FAILED;
18704 if (!authorization_delegate->CheckResponseAuthorization(
18705 response_hash, authorization_section_bytes)) {
18706 return TRUNKS_RC_AUTHORIZATION_FAILED;
18707 }
18708 }
18709 std::string param_size_out_bytes;
18710 rc = Parse_UINT32(&buffer, param_size_out, ¶m_size_out_bytes);
18711 if (rc != TPM_RC_SUCCESS) {
18712 return rc;
18713 }
18714 std::string q_bytes;
18715 rc = Parse_TPM2B_ECC_POINT(&buffer, q, &q_bytes);
18716 if (rc != TPM_RC_SUCCESS) {
18717 return rc;
18718 }
18719 std::string counter_bytes;
18720 rc = Parse_UINT16(&buffer, counter, &counter_bytes);
18721 if (rc != TPM_RC_SUCCESS) {
18722 return rc;
18723 }
18724 return TPM_RC_SUCCESS;
18725 }
18726
EC_EphemeralErrorCallback(Tpm::EC_EphemeralResponse callback,TPM_RC response_code)18727 void EC_EphemeralErrorCallback(Tpm::EC_EphemeralResponse callback,
18728 TPM_RC response_code) {
18729 VLOG(1) << __func__;
18730 std::move(callback).Run(response_code, UINT32(), TPM2B_ECC_POINT(), UINT16());
18731 }
18732
EC_EphemeralResponseParser(Tpm::EC_EphemeralResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18733 void EC_EphemeralResponseParser(Tpm::EC_EphemeralResponse callback,
18734 AuthorizationDelegate* authorization_delegate,
18735 const std::string& response) {
18736 VLOG(1) << __func__;
18737 UINT32 param_size_out;
18738 TPM2B_ECC_POINT q;
18739 UINT16 counter;
18740 TPM_RC rc = Tpm::ParseResponse_EC_Ephemeral(response, ¶m_size_out, &q,
18741 &counter, authorization_delegate);
18742 if (rc != TPM_RC_SUCCESS) {
18743 base::OnceCallback<void(TPM_RC)> error_reporter =
18744 base::BindOnce(EC_EphemeralErrorCallback, std::move(callback));
18745 std::move(error_reporter).Run(rc);
18746 return;
18747 }
18748 std::move(callback).Run(rc, param_size_out, q, counter);
18749 }
18750
EC_Ephemeral(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,AuthorizationDelegate * authorization_delegate,EC_EphemeralResponse callback)18751 void Tpm::EC_Ephemeral(const UINT32& param_size,
18752 const TPMI_ECC_CURVE& curve_id,
18753 AuthorizationDelegate* authorization_delegate,
18754 EC_EphemeralResponse callback) {
18755 VLOG(1) << __func__;
18756 std::string command;
18757 TPM_RC rc = SerializeCommand_EC_Ephemeral(param_size, curve_id, &command,
18758 authorization_delegate);
18759 if (rc != TPM_RC_SUCCESS) {
18760 base::OnceCallback<void(TPM_RC)> error_reporter =
18761 base::BindOnce(EC_EphemeralErrorCallback, std::move(callback));
18762 std::move(error_reporter).Run(rc);
18763 return;
18764 }
18765 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18766 EC_EphemeralResponseParser, std::move(callback), authorization_delegate);
18767 transceiver_->SendCommand(command, std::move(parser));
18768 }
18769
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)18770 TPM_RC Tpm::EC_EphemeralSync(const UINT32& param_size,
18771 const TPMI_ECC_CURVE& curve_id,
18772 UINT32* param_size_out,
18773 TPM2B_ECC_POINT* q,
18774 UINT16* counter,
18775 AuthorizationDelegate* authorization_delegate) {
18776 VLOG(1) << __func__;
18777 std::string command;
18778 TPM_RC rc = SerializeCommand_EC_Ephemeral(param_size, curve_id, &command,
18779 authorization_delegate);
18780 if (rc != TPM_RC_SUCCESS) {
18781 return rc;
18782 }
18783 std::string response = transceiver_->SendCommandAndWait(command);
18784 rc = ParseResponse_EC_Ephemeral(response, param_size_out, q, counter,
18785 authorization_delegate);
18786 return rc;
18787 }
18788
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)18789 TPM_RC Tpm::SerializeCommand_VerifySignature(
18790 const TPMI_DH_OBJECT& key_handle,
18791 const std::string& key_handle_name,
18792 const TPM2B_DIGEST& digest,
18793 const TPMT_SIGNATURE& signature,
18794 std::string* serialized_command,
18795 AuthorizationDelegate* authorization_delegate) {
18796 VLOG(3) << __func__;
18797 TPM_RC rc = TPM_RC_SUCCESS;
18798 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18799 UINT32 command_size = 10; // Header size.
18800 std::string handle_section_bytes;
18801 std::string parameter_section_bytes;
18802 TPM_CC command_code = TPM_CC_VerifySignature;
18803 bool is_command_parameter_encryption_possible = true;
18804 bool is_response_parameter_encryption_possible = false;
18805 std::string command_code_bytes;
18806 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18807 if (rc != TPM_RC_SUCCESS) {
18808 return rc;
18809 }
18810 std::string key_handle_bytes;
18811 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
18812 if (rc != TPM_RC_SUCCESS) {
18813 return rc;
18814 }
18815 std::string digest_bytes;
18816 rc = Serialize_TPM2B_DIGEST(digest, &digest_bytes);
18817 if (rc != TPM_RC_SUCCESS) {
18818 return rc;
18819 }
18820 std::string signature_bytes;
18821 rc = Serialize_TPMT_SIGNATURE(signature, &signature_bytes);
18822 if (rc != TPM_RC_SUCCESS) {
18823 return rc;
18824 }
18825 if (authorization_delegate) {
18826 // Encrypt just the parameter data, not the size.
18827 std::string tmp = digest_bytes.substr(2);
18828 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
18829 return TRUNKS_RC_ENCRYPTION_FAILED;
18830 }
18831 digest_bytes.replace(2, std::string::npos, tmp);
18832 }
18833 std::unique_ptr<crypto::SecureHash> hash(
18834 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18835 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18836 hash->Update(key_handle_name.data(), key_handle_name.size());
18837 handle_section_bytes += key_handle_bytes;
18838 command_size += key_handle_bytes.size();
18839 hash->Update(digest_bytes.data(), digest_bytes.size());
18840 parameter_section_bytes += digest_bytes;
18841 command_size += digest_bytes.size();
18842 hash->Update(signature_bytes.data(), signature_bytes.size());
18843 parameter_section_bytes += signature_bytes;
18844 command_size += signature_bytes.size();
18845 std::string command_hash(32, 0);
18846 hash->Finish(std::data(command_hash), command_hash.size());
18847 std::string authorization_section_bytes;
18848 std::string authorization_size_bytes;
18849 if (authorization_delegate) {
18850 if (!authorization_delegate->GetCommandAuthorization(
18851 command_hash, is_command_parameter_encryption_possible,
18852 is_response_parameter_encryption_possible,
18853 &authorization_section_bytes)) {
18854 return TRUNKS_RC_AUTHORIZATION_FAILED;
18855 }
18856 if (!authorization_section_bytes.empty()) {
18857 tag = TPM_ST_SESSIONS;
18858 std::string tmp;
18859 rc = Serialize_UINT32(authorization_section_bytes.size(),
18860 &authorization_size_bytes);
18861 if (rc != TPM_RC_SUCCESS) {
18862 return rc;
18863 }
18864 command_size +=
18865 authorization_size_bytes.size() + authorization_section_bytes.size();
18866 }
18867 }
18868 std::string tag_bytes;
18869 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18870 if (rc != TPM_RC_SUCCESS) {
18871 return rc;
18872 }
18873 std::string command_size_bytes;
18874 rc = Serialize_UINT32(command_size, &command_size_bytes);
18875 if (rc != TPM_RC_SUCCESS) {
18876 return rc;
18877 }
18878 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18879 handle_section_bytes + authorization_size_bytes +
18880 authorization_section_bytes + parameter_section_bytes;
18881 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18882 VLOG(2) << "Command: "
18883 << base::HexEncode(serialized_command->data(),
18884 serialized_command->size());
18885 return TPM_RC_SUCCESS;
18886 }
18887
ParseResponse_VerifySignature(const std::string & response,TPMT_TK_VERIFIED * validation,AuthorizationDelegate * authorization_delegate)18888 TPM_RC Tpm::ParseResponse_VerifySignature(
18889 const std::string& response,
18890 TPMT_TK_VERIFIED* validation,
18891 AuthorizationDelegate* authorization_delegate) {
18892 VLOG(3) << __func__;
18893 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18894 TPM_RC rc = TPM_RC_SUCCESS;
18895 std::string buffer(response);
18896 TPM_ST tag;
18897 std::string tag_bytes;
18898 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18899 if (rc != TPM_RC_SUCCESS) {
18900 return rc;
18901 }
18902 UINT32 response_size;
18903 std::string response_size_bytes;
18904 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18905 if (rc != TPM_RC_SUCCESS) {
18906 return rc;
18907 }
18908 TPM_RC response_code;
18909 std::string response_code_bytes;
18910 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18911 if (rc != TPM_RC_SUCCESS) {
18912 return rc;
18913 }
18914 if (response_size != response.size()) {
18915 return TPM_RC_SIZE;
18916 }
18917 if (response_code != TPM_RC_SUCCESS) {
18918 return response_code;
18919 }
18920 TPM_CC command_code = TPM_CC_VerifySignature;
18921 std::string command_code_bytes;
18922 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18923 if (rc != TPM_RC_SUCCESS) {
18924 return rc;
18925 }
18926 std::string authorization_section_bytes;
18927 if (tag == TPM_ST_SESSIONS) {
18928 UINT32 parameter_section_size = buffer.size();
18929 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
18930 if (rc != TPM_RC_SUCCESS) {
18931 return rc;
18932 }
18933 if (parameter_section_size > buffer.size()) {
18934 return TPM_RC_INSUFFICIENT;
18935 }
18936 authorization_section_bytes = buffer.substr(parameter_section_size);
18937 // Keep the parameter section in |buffer|.
18938 buffer.erase(parameter_section_size);
18939 }
18940 std::unique_ptr<crypto::SecureHash> hash(
18941 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18942 hash->Update(response_code_bytes.data(), response_code_bytes.size());
18943 hash->Update(command_code_bytes.data(), command_code_bytes.size());
18944 hash->Update(buffer.data(), buffer.size());
18945 std::string response_hash(32, 0);
18946 hash->Finish(std::data(response_hash), response_hash.size());
18947 if (tag == TPM_ST_SESSIONS) {
18948 if (!authorization_delegate)
18949 return TRUNKS_RC_AUTHORIZATION_FAILED;
18950 if (!authorization_delegate->CheckResponseAuthorization(
18951 response_hash, authorization_section_bytes)) {
18952 return TRUNKS_RC_AUTHORIZATION_FAILED;
18953 }
18954 }
18955 std::string validation_bytes;
18956 rc = Parse_TPMT_TK_VERIFIED(&buffer, validation, &validation_bytes);
18957 if (rc != TPM_RC_SUCCESS) {
18958 return rc;
18959 }
18960 return TPM_RC_SUCCESS;
18961 }
18962
VerifySignatureErrorCallback(Tpm::VerifySignatureResponse callback,TPM_RC response_code)18963 void VerifySignatureErrorCallback(Tpm::VerifySignatureResponse callback,
18964 TPM_RC response_code) {
18965 VLOG(1) << __func__;
18966 std::move(callback).Run(response_code, TPMT_TK_VERIFIED());
18967 }
18968
VerifySignatureResponseParser(Tpm::VerifySignatureResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18969 void VerifySignatureResponseParser(
18970 Tpm::VerifySignatureResponse callback,
18971 AuthorizationDelegate* authorization_delegate,
18972 const std::string& response) {
18973 VLOG(1) << __func__;
18974 TPMT_TK_VERIFIED validation;
18975 TPM_RC rc = Tpm::ParseResponse_VerifySignature(response, &validation,
18976 authorization_delegate);
18977 if (rc != TPM_RC_SUCCESS) {
18978 base::OnceCallback<void(TPM_RC)> error_reporter =
18979 base::BindOnce(VerifySignatureErrorCallback, std::move(callback));
18980 std::move(error_reporter).Run(rc);
18981 return;
18982 }
18983 std::move(callback).Run(rc, validation);
18984 }
18985
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)18986 void Tpm::VerifySignature(const TPMI_DH_OBJECT& key_handle,
18987 const std::string& key_handle_name,
18988 const TPM2B_DIGEST& digest,
18989 const TPMT_SIGNATURE& signature,
18990 AuthorizationDelegate* authorization_delegate,
18991 VerifySignatureResponse callback) {
18992 VLOG(1) << __func__;
18993 std::string command;
18994 TPM_RC rc = SerializeCommand_VerifySignature(key_handle, key_handle_name,
18995 digest, signature, &command,
18996 authorization_delegate);
18997 if (rc != TPM_RC_SUCCESS) {
18998 base::OnceCallback<void(TPM_RC)> error_reporter =
18999 base::BindOnce(VerifySignatureErrorCallback, std::move(callback));
19000 std::move(error_reporter).Run(rc);
19001 return;
19002 }
19003 base::OnceCallback<void(const std::string&)> parser =
19004 base::BindOnce(VerifySignatureResponseParser, std::move(callback),
19005 authorization_delegate);
19006 transceiver_->SendCommand(command, std::move(parser));
19007 }
19008
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)19009 TPM_RC Tpm::VerifySignatureSync(const TPMI_DH_OBJECT& key_handle,
19010 const std::string& key_handle_name,
19011 const TPM2B_DIGEST& digest,
19012 const TPMT_SIGNATURE& signature,
19013 TPMT_TK_VERIFIED* validation,
19014 AuthorizationDelegate* authorization_delegate) {
19015 VLOG(1) << __func__;
19016 std::string command;
19017 TPM_RC rc = SerializeCommand_VerifySignature(key_handle, key_handle_name,
19018 digest, signature, &command,
19019 authorization_delegate);
19020 if (rc != TPM_RC_SUCCESS) {
19021 return rc;
19022 }
19023 std::string response = transceiver_->SendCommandAndWait(command);
19024 rc = ParseResponse_VerifySignature(response, validation,
19025 authorization_delegate);
19026 return rc;
19027 }
19028
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)19029 TPM_RC Tpm::SerializeCommand_Sign(
19030 const TPMI_DH_OBJECT& key_handle,
19031 const std::string& key_handle_name,
19032 const TPM2B_DIGEST& digest,
19033 const TPMT_SIG_SCHEME& in_scheme,
19034 const TPMT_TK_HASHCHECK& validation,
19035 std::string* serialized_command,
19036 AuthorizationDelegate* authorization_delegate) {
19037 VLOG(3) << __func__;
19038 TPM_RC rc = TPM_RC_SUCCESS;
19039 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19040 UINT32 command_size = 10; // Header size.
19041 std::string handle_section_bytes;
19042 std::string parameter_section_bytes;
19043 TPM_CC command_code = TPM_CC_Sign;
19044 bool is_command_parameter_encryption_possible = true;
19045 bool is_response_parameter_encryption_possible = false;
19046 std::string command_code_bytes;
19047 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19048 if (rc != TPM_RC_SUCCESS) {
19049 return rc;
19050 }
19051 std::string key_handle_bytes;
19052 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
19053 if (rc != TPM_RC_SUCCESS) {
19054 return rc;
19055 }
19056 std::string digest_bytes;
19057 rc = Serialize_TPM2B_DIGEST(digest, &digest_bytes);
19058 if (rc != TPM_RC_SUCCESS) {
19059 return rc;
19060 }
19061 std::string in_scheme_bytes;
19062 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
19063 if (rc != TPM_RC_SUCCESS) {
19064 return rc;
19065 }
19066 std::string validation_bytes;
19067 rc = Serialize_TPMT_TK_HASHCHECK(validation, &validation_bytes);
19068 if (rc != TPM_RC_SUCCESS) {
19069 return rc;
19070 }
19071 if (authorization_delegate) {
19072 // Encrypt just the parameter data, not the size.
19073 std::string tmp = digest_bytes.substr(2);
19074 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
19075 return TRUNKS_RC_ENCRYPTION_FAILED;
19076 }
19077 digest_bytes.replace(2, std::string::npos, tmp);
19078 }
19079 std::unique_ptr<crypto::SecureHash> hash(
19080 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19081 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19082 hash->Update(key_handle_name.data(), key_handle_name.size());
19083 handle_section_bytes += key_handle_bytes;
19084 command_size += key_handle_bytes.size();
19085 hash->Update(digest_bytes.data(), digest_bytes.size());
19086 parameter_section_bytes += digest_bytes;
19087 command_size += digest_bytes.size();
19088 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
19089 parameter_section_bytes += in_scheme_bytes;
19090 command_size += in_scheme_bytes.size();
19091 hash->Update(validation_bytes.data(), validation_bytes.size());
19092 parameter_section_bytes += validation_bytes;
19093 command_size += validation_bytes.size();
19094 std::string command_hash(32, 0);
19095 hash->Finish(std::data(command_hash), command_hash.size());
19096 std::string authorization_section_bytes;
19097 std::string authorization_size_bytes;
19098 if (authorization_delegate) {
19099 if (!authorization_delegate->GetCommandAuthorization(
19100 command_hash, is_command_parameter_encryption_possible,
19101 is_response_parameter_encryption_possible,
19102 &authorization_section_bytes)) {
19103 return TRUNKS_RC_AUTHORIZATION_FAILED;
19104 }
19105 if (!authorization_section_bytes.empty()) {
19106 tag = TPM_ST_SESSIONS;
19107 std::string tmp;
19108 rc = Serialize_UINT32(authorization_section_bytes.size(),
19109 &authorization_size_bytes);
19110 if (rc != TPM_RC_SUCCESS) {
19111 return rc;
19112 }
19113 command_size +=
19114 authorization_size_bytes.size() + authorization_section_bytes.size();
19115 }
19116 }
19117 std::string tag_bytes;
19118 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19119 if (rc != TPM_RC_SUCCESS) {
19120 return rc;
19121 }
19122 std::string command_size_bytes;
19123 rc = Serialize_UINT32(command_size, &command_size_bytes);
19124 if (rc != TPM_RC_SUCCESS) {
19125 return rc;
19126 }
19127 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19128 handle_section_bytes + authorization_size_bytes +
19129 authorization_section_bytes + parameter_section_bytes;
19130 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19131 VLOG(2) << "Command: "
19132 << base::HexEncode(serialized_command->data(),
19133 serialized_command->size());
19134 return TPM_RC_SUCCESS;
19135 }
19136
ParseResponse_Sign(const std::string & response,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)19137 TPM_RC Tpm::ParseResponse_Sign(const std::string& response,
19138 TPMT_SIGNATURE* signature,
19139 AuthorizationDelegate* authorization_delegate) {
19140 VLOG(3) << __func__;
19141 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19142 TPM_RC rc = TPM_RC_SUCCESS;
19143 std::string buffer(response);
19144 TPM_ST tag;
19145 std::string tag_bytes;
19146 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19147 if (rc != TPM_RC_SUCCESS) {
19148 return rc;
19149 }
19150 UINT32 response_size;
19151 std::string response_size_bytes;
19152 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19153 if (rc != TPM_RC_SUCCESS) {
19154 return rc;
19155 }
19156 TPM_RC response_code;
19157 std::string response_code_bytes;
19158 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19159 if (rc != TPM_RC_SUCCESS) {
19160 return rc;
19161 }
19162 if (response_size != response.size()) {
19163 return TPM_RC_SIZE;
19164 }
19165 if (response_code != TPM_RC_SUCCESS) {
19166 return response_code;
19167 }
19168 TPM_CC command_code = TPM_CC_Sign;
19169 std::string command_code_bytes;
19170 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19171 if (rc != TPM_RC_SUCCESS) {
19172 return rc;
19173 }
19174 std::string authorization_section_bytes;
19175 if (tag == TPM_ST_SESSIONS) {
19176 UINT32 parameter_section_size = buffer.size();
19177 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
19178 if (rc != TPM_RC_SUCCESS) {
19179 return rc;
19180 }
19181 if (parameter_section_size > buffer.size()) {
19182 return TPM_RC_INSUFFICIENT;
19183 }
19184 authorization_section_bytes = buffer.substr(parameter_section_size);
19185 // Keep the parameter section in |buffer|.
19186 buffer.erase(parameter_section_size);
19187 }
19188 std::unique_ptr<crypto::SecureHash> hash(
19189 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19190 hash->Update(response_code_bytes.data(), response_code_bytes.size());
19191 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19192 hash->Update(buffer.data(), buffer.size());
19193 std::string response_hash(32, 0);
19194 hash->Finish(std::data(response_hash), response_hash.size());
19195 if (tag == TPM_ST_SESSIONS) {
19196 if (!authorization_delegate)
19197 return TRUNKS_RC_AUTHORIZATION_FAILED;
19198 if (!authorization_delegate->CheckResponseAuthorization(
19199 response_hash, authorization_section_bytes)) {
19200 return TRUNKS_RC_AUTHORIZATION_FAILED;
19201 }
19202 }
19203 std::string signature_bytes;
19204 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
19205 if (rc != TPM_RC_SUCCESS) {
19206 return rc;
19207 }
19208 return TPM_RC_SUCCESS;
19209 }
19210
SignErrorCallback(Tpm::SignResponse callback,TPM_RC response_code)19211 void SignErrorCallback(Tpm::SignResponse callback, TPM_RC response_code) {
19212 VLOG(1) << __func__;
19213 std::move(callback).Run(response_code, TPMT_SIGNATURE());
19214 }
19215
SignResponseParser(Tpm::SignResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19216 void SignResponseParser(Tpm::SignResponse callback,
19217 AuthorizationDelegate* authorization_delegate,
19218 const std::string& response) {
19219 VLOG(1) << __func__;
19220 TPMT_SIGNATURE signature;
19221 TPM_RC rc =
19222 Tpm::ParseResponse_Sign(response, &signature, authorization_delegate);
19223 if (rc != TPM_RC_SUCCESS) {
19224 base::OnceCallback<void(TPM_RC)> error_reporter =
19225 base::BindOnce(SignErrorCallback, std::move(callback));
19226 std::move(error_reporter).Run(rc);
19227 return;
19228 }
19229 std::move(callback).Run(rc, signature);
19230 }
19231
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)19232 void Tpm::Sign(const TPMI_DH_OBJECT& key_handle,
19233 const std::string& key_handle_name,
19234 const TPM2B_DIGEST& digest,
19235 const TPMT_SIG_SCHEME& in_scheme,
19236 const TPMT_TK_HASHCHECK& validation,
19237 AuthorizationDelegate* authorization_delegate,
19238 SignResponse callback) {
19239 VLOG(1) << __func__;
19240 std::string command;
19241 TPM_RC rc =
19242 SerializeCommand_Sign(key_handle, key_handle_name, digest, in_scheme,
19243 validation, &command, authorization_delegate);
19244 if (rc != TPM_RC_SUCCESS) {
19245 base::OnceCallback<void(TPM_RC)> error_reporter =
19246 base::BindOnce(SignErrorCallback, std::move(callback));
19247 std::move(error_reporter).Run(rc);
19248 return;
19249 }
19250 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19251 SignResponseParser, std::move(callback), authorization_delegate);
19252 transceiver_->SendCommand(command, std::move(parser));
19253 }
19254
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)19255 TPM_RC Tpm::SignSync(const TPMI_DH_OBJECT& key_handle,
19256 const std::string& key_handle_name,
19257 const TPM2B_DIGEST& digest,
19258 const TPMT_SIG_SCHEME& in_scheme,
19259 const TPMT_TK_HASHCHECK& validation,
19260 TPMT_SIGNATURE* signature,
19261 AuthorizationDelegate* authorization_delegate) {
19262 VLOG(1) << __func__;
19263 std::string command;
19264 TPM_RC rc =
19265 SerializeCommand_Sign(key_handle, key_handle_name, digest, in_scheme,
19266 validation, &command, authorization_delegate);
19267 if (rc != TPM_RC_SUCCESS) {
19268 return rc;
19269 }
19270 std::string response = transceiver_->SendCommandAndWait(command);
19271 rc = ParseResponse_Sign(response, signature, authorization_delegate);
19272 return rc;
19273 }
19274
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)19275 TPM_RC Tpm::SerializeCommand_SetCommandCodeAuditStatus(
19276 const TPMI_RH_PROVISION& auth,
19277 const std::string& auth_name,
19278 const TPMI_ALG_HASH& audit_alg,
19279 const TPML_CC& set_list,
19280 const TPML_CC& clear_list,
19281 std::string* serialized_command,
19282 AuthorizationDelegate* authorization_delegate) {
19283 VLOG(3) << __func__;
19284 TPM_RC rc = TPM_RC_SUCCESS;
19285 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19286 UINT32 command_size = 10; // Header size.
19287 std::string handle_section_bytes;
19288 std::string parameter_section_bytes;
19289 TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus;
19290 bool is_command_parameter_encryption_possible = false;
19291 bool is_response_parameter_encryption_possible = false;
19292 std::string command_code_bytes;
19293 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19294 if (rc != TPM_RC_SUCCESS) {
19295 return rc;
19296 }
19297 std::string auth_bytes;
19298 rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
19299 if (rc != TPM_RC_SUCCESS) {
19300 return rc;
19301 }
19302 std::string audit_alg_bytes;
19303 rc = Serialize_TPMI_ALG_HASH(audit_alg, &audit_alg_bytes);
19304 if (rc != TPM_RC_SUCCESS) {
19305 return rc;
19306 }
19307 std::string set_list_bytes;
19308 rc = Serialize_TPML_CC(set_list, &set_list_bytes);
19309 if (rc != TPM_RC_SUCCESS) {
19310 return rc;
19311 }
19312 std::string clear_list_bytes;
19313 rc = Serialize_TPML_CC(clear_list, &clear_list_bytes);
19314 if (rc != TPM_RC_SUCCESS) {
19315 return rc;
19316 }
19317 std::unique_ptr<crypto::SecureHash> hash(
19318 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19319 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19320 hash->Update(auth_name.data(), auth_name.size());
19321 handle_section_bytes += auth_bytes;
19322 command_size += auth_bytes.size();
19323 hash->Update(audit_alg_bytes.data(), audit_alg_bytes.size());
19324 parameter_section_bytes += audit_alg_bytes;
19325 command_size += audit_alg_bytes.size();
19326 hash->Update(set_list_bytes.data(), set_list_bytes.size());
19327 parameter_section_bytes += set_list_bytes;
19328 command_size += set_list_bytes.size();
19329 hash->Update(clear_list_bytes.data(), clear_list_bytes.size());
19330 parameter_section_bytes += clear_list_bytes;
19331 command_size += clear_list_bytes.size();
19332 std::string command_hash(32, 0);
19333 hash->Finish(std::data(command_hash), command_hash.size());
19334 std::string authorization_section_bytes;
19335 std::string authorization_size_bytes;
19336 if (authorization_delegate) {
19337 if (!authorization_delegate->GetCommandAuthorization(
19338 command_hash, is_command_parameter_encryption_possible,
19339 is_response_parameter_encryption_possible,
19340 &authorization_section_bytes)) {
19341 return TRUNKS_RC_AUTHORIZATION_FAILED;
19342 }
19343 if (!authorization_section_bytes.empty()) {
19344 tag = TPM_ST_SESSIONS;
19345 std::string tmp;
19346 rc = Serialize_UINT32(authorization_section_bytes.size(),
19347 &authorization_size_bytes);
19348 if (rc != TPM_RC_SUCCESS) {
19349 return rc;
19350 }
19351 command_size +=
19352 authorization_size_bytes.size() + authorization_section_bytes.size();
19353 }
19354 }
19355 std::string tag_bytes;
19356 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19357 if (rc != TPM_RC_SUCCESS) {
19358 return rc;
19359 }
19360 std::string command_size_bytes;
19361 rc = Serialize_UINT32(command_size, &command_size_bytes);
19362 if (rc != TPM_RC_SUCCESS) {
19363 return rc;
19364 }
19365 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19366 handle_section_bytes + authorization_size_bytes +
19367 authorization_section_bytes + parameter_section_bytes;
19368 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19369 VLOG(2) << "Command: "
19370 << base::HexEncode(serialized_command->data(),
19371 serialized_command->size());
19372 return TPM_RC_SUCCESS;
19373 }
19374
ParseResponse_SetCommandCodeAuditStatus(const std::string & response,AuthorizationDelegate * authorization_delegate)19375 TPM_RC Tpm::ParseResponse_SetCommandCodeAuditStatus(
19376 const std::string& response,
19377 AuthorizationDelegate* authorization_delegate) {
19378 VLOG(3) << __func__;
19379 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19380 TPM_RC rc = TPM_RC_SUCCESS;
19381 std::string buffer(response);
19382 TPM_ST tag;
19383 std::string tag_bytes;
19384 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19385 if (rc != TPM_RC_SUCCESS) {
19386 return rc;
19387 }
19388 UINT32 response_size;
19389 std::string response_size_bytes;
19390 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19391 if (rc != TPM_RC_SUCCESS) {
19392 return rc;
19393 }
19394 TPM_RC response_code;
19395 std::string response_code_bytes;
19396 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19397 if (rc != TPM_RC_SUCCESS) {
19398 return rc;
19399 }
19400 if (response_size != response.size()) {
19401 return TPM_RC_SIZE;
19402 }
19403 if (response_code != TPM_RC_SUCCESS) {
19404 return response_code;
19405 }
19406 TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus;
19407 std::string command_code_bytes;
19408 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19409 if (rc != TPM_RC_SUCCESS) {
19410 return rc;
19411 }
19412 std::string authorization_section_bytes;
19413 if (tag == TPM_ST_SESSIONS) {
19414 UINT32 parameter_section_size = buffer.size();
19415 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
19416 if (rc != TPM_RC_SUCCESS) {
19417 return rc;
19418 }
19419 if (parameter_section_size > buffer.size()) {
19420 return TPM_RC_INSUFFICIENT;
19421 }
19422 authorization_section_bytes = buffer.substr(parameter_section_size);
19423 // Keep the parameter section in |buffer|.
19424 buffer.erase(parameter_section_size);
19425 }
19426 std::unique_ptr<crypto::SecureHash> hash(
19427 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19428 hash->Update(response_code_bytes.data(), response_code_bytes.size());
19429 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19430 hash->Update(buffer.data(), buffer.size());
19431 std::string response_hash(32, 0);
19432 hash->Finish(std::data(response_hash), response_hash.size());
19433 if (tag == TPM_ST_SESSIONS) {
19434 if (!authorization_delegate)
19435 return TRUNKS_RC_AUTHORIZATION_FAILED;
19436 if (!authorization_delegate->CheckResponseAuthorization(
19437 response_hash, authorization_section_bytes)) {
19438 return TRUNKS_RC_AUTHORIZATION_FAILED;
19439 }
19440 }
19441 return TPM_RC_SUCCESS;
19442 }
19443
SetCommandCodeAuditStatusErrorCallback(Tpm::SetCommandCodeAuditStatusResponse callback,TPM_RC response_code)19444 void SetCommandCodeAuditStatusErrorCallback(
19445 Tpm::SetCommandCodeAuditStatusResponse callback, TPM_RC response_code) {
19446 VLOG(1) << __func__;
19447 std::move(callback).Run(response_code);
19448 }
19449
SetCommandCodeAuditStatusResponseParser(Tpm::SetCommandCodeAuditStatusResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19450 void SetCommandCodeAuditStatusResponseParser(
19451 Tpm::SetCommandCodeAuditStatusResponse callback,
19452 AuthorizationDelegate* authorization_delegate,
19453 const std::string& response) {
19454 VLOG(1) << __func__;
19455 TPM_RC rc = Tpm::ParseResponse_SetCommandCodeAuditStatus(
19456 response, authorization_delegate);
19457 if (rc != TPM_RC_SUCCESS) {
19458 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
19459 SetCommandCodeAuditStatusErrorCallback, std::move(callback));
19460 std::move(error_reporter).Run(rc);
19461 return;
19462 }
19463 std::move(callback).Run(rc);
19464 }
19465
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)19466 void Tpm::SetCommandCodeAuditStatus(
19467 const TPMI_RH_PROVISION& auth,
19468 const std::string& auth_name,
19469 const TPMI_ALG_HASH& audit_alg,
19470 const TPML_CC& set_list,
19471 const TPML_CC& clear_list,
19472 AuthorizationDelegate* authorization_delegate,
19473 SetCommandCodeAuditStatusResponse callback) {
19474 VLOG(1) << __func__;
19475 std::string command;
19476 TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus(
19477 auth, auth_name, audit_alg, set_list, clear_list, &command,
19478 authorization_delegate);
19479 if (rc != TPM_RC_SUCCESS) {
19480 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
19481 SetCommandCodeAuditStatusErrorCallback, std::move(callback));
19482 std::move(error_reporter).Run(rc);
19483 return;
19484 }
19485 base::OnceCallback<void(const std::string&)> parser =
19486 base::BindOnce(SetCommandCodeAuditStatusResponseParser,
19487 std::move(callback), authorization_delegate);
19488 transceiver_->SendCommand(command, std::move(parser));
19489 }
19490
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)19491 TPM_RC Tpm::SetCommandCodeAuditStatusSync(
19492 const TPMI_RH_PROVISION& auth,
19493 const std::string& auth_name,
19494 const TPMI_ALG_HASH& audit_alg,
19495 const TPML_CC& set_list,
19496 const TPML_CC& clear_list,
19497 AuthorizationDelegate* authorization_delegate) {
19498 VLOG(1) << __func__;
19499 std::string command;
19500 TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus(
19501 auth, auth_name, audit_alg, set_list, clear_list, &command,
19502 authorization_delegate);
19503 if (rc != TPM_RC_SUCCESS) {
19504 return rc;
19505 }
19506 std::string response = transceiver_->SendCommandAndWait(command);
19507 rc =
19508 ParseResponse_SetCommandCodeAuditStatus(response, authorization_delegate);
19509 return rc;
19510 }
19511
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)19512 TPM_RC Tpm::SerializeCommand_PCR_Extend(
19513 const TPMI_DH_PCR& pcr_handle,
19514 const std::string& pcr_handle_name,
19515 const TPML_DIGEST_VALUES& digests,
19516 std::string* serialized_command,
19517 AuthorizationDelegate* authorization_delegate) {
19518 VLOG(3) << __func__;
19519 TPM_RC rc = TPM_RC_SUCCESS;
19520 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19521 UINT32 command_size = 10; // Header size.
19522 std::string handle_section_bytes;
19523 std::string parameter_section_bytes;
19524 TPM_CC command_code = TPM_CC_PCR_Extend;
19525 bool is_command_parameter_encryption_possible = false;
19526 bool is_response_parameter_encryption_possible = false;
19527 std::string command_code_bytes;
19528 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19529 if (rc != TPM_RC_SUCCESS) {
19530 return rc;
19531 }
19532 std::string pcr_handle_bytes;
19533 rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
19534 if (rc != TPM_RC_SUCCESS) {
19535 return rc;
19536 }
19537 std::string digests_bytes;
19538 rc = Serialize_TPML_DIGEST_VALUES(digests, &digests_bytes);
19539 if (rc != TPM_RC_SUCCESS) {
19540 return rc;
19541 }
19542 std::unique_ptr<crypto::SecureHash> hash(
19543 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19544 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19545 hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
19546 handle_section_bytes += pcr_handle_bytes;
19547 command_size += pcr_handle_bytes.size();
19548 hash->Update(digests_bytes.data(), digests_bytes.size());
19549 parameter_section_bytes += digests_bytes;
19550 command_size += digests_bytes.size();
19551 std::string command_hash(32, 0);
19552 hash->Finish(std::data(command_hash), command_hash.size());
19553 std::string authorization_section_bytes;
19554 std::string authorization_size_bytes;
19555 if (authorization_delegate) {
19556 if (!authorization_delegate->GetCommandAuthorization(
19557 command_hash, is_command_parameter_encryption_possible,
19558 is_response_parameter_encryption_possible,
19559 &authorization_section_bytes)) {
19560 return TRUNKS_RC_AUTHORIZATION_FAILED;
19561 }
19562 if (!authorization_section_bytes.empty()) {
19563 tag = TPM_ST_SESSIONS;
19564 std::string tmp;
19565 rc = Serialize_UINT32(authorization_section_bytes.size(),
19566 &authorization_size_bytes);
19567 if (rc != TPM_RC_SUCCESS) {
19568 return rc;
19569 }
19570 command_size +=
19571 authorization_size_bytes.size() + authorization_section_bytes.size();
19572 }
19573 }
19574 std::string tag_bytes;
19575 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19576 if (rc != TPM_RC_SUCCESS) {
19577 return rc;
19578 }
19579 std::string command_size_bytes;
19580 rc = Serialize_UINT32(command_size, &command_size_bytes);
19581 if (rc != TPM_RC_SUCCESS) {
19582 return rc;
19583 }
19584 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19585 handle_section_bytes + authorization_size_bytes +
19586 authorization_section_bytes + parameter_section_bytes;
19587 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19588 VLOG(2) << "Command: "
19589 << base::HexEncode(serialized_command->data(),
19590 serialized_command->size());
19591 return TPM_RC_SUCCESS;
19592 }
19593
ParseResponse_PCR_Extend(const std::string & response,AuthorizationDelegate * authorization_delegate)19594 TPM_RC Tpm::ParseResponse_PCR_Extend(
19595 const std::string& response,
19596 AuthorizationDelegate* authorization_delegate) {
19597 VLOG(3) << __func__;
19598 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19599 TPM_RC rc = TPM_RC_SUCCESS;
19600 std::string buffer(response);
19601 TPM_ST tag;
19602 std::string tag_bytes;
19603 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19604 if (rc != TPM_RC_SUCCESS) {
19605 return rc;
19606 }
19607 UINT32 response_size;
19608 std::string response_size_bytes;
19609 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19610 if (rc != TPM_RC_SUCCESS) {
19611 return rc;
19612 }
19613 TPM_RC response_code;
19614 std::string response_code_bytes;
19615 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19616 if (rc != TPM_RC_SUCCESS) {
19617 return rc;
19618 }
19619 if (response_size != response.size()) {
19620 return TPM_RC_SIZE;
19621 }
19622 if (response_code != TPM_RC_SUCCESS) {
19623 return response_code;
19624 }
19625 TPM_CC command_code = TPM_CC_PCR_Extend;
19626 std::string command_code_bytes;
19627 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19628 if (rc != TPM_RC_SUCCESS) {
19629 return rc;
19630 }
19631 std::string authorization_section_bytes;
19632 if (tag == TPM_ST_SESSIONS) {
19633 UINT32 parameter_section_size = buffer.size();
19634 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
19635 if (rc != TPM_RC_SUCCESS) {
19636 return rc;
19637 }
19638 if (parameter_section_size > buffer.size()) {
19639 return TPM_RC_INSUFFICIENT;
19640 }
19641 authorization_section_bytes = buffer.substr(parameter_section_size);
19642 // Keep the parameter section in |buffer|.
19643 buffer.erase(parameter_section_size);
19644 }
19645 std::unique_ptr<crypto::SecureHash> hash(
19646 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19647 hash->Update(response_code_bytes.data(), response_code_bytes.size());
19648 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19649 hash->Update(buffer.data(), buffer.size());
19650 std::string response_hash(32, 0);
19651 hash->Finish(std::data(response_hash), response_hash.size());
19652 if (tag == TPM_ST_SESSIONS) {
19653 if (!authorization_delegate)
19654 return TRUNKS_RC_AUTHORIZATION_FAILED;
19655 if (!authorization_delegate->CheckResponseAuthorization(
19656 response_hash, authorization_section_bytes)) {
19657 return TRUNKS_RC_AUTHORIZATION_FAILED;
19658 }
19659 }
19660 return TPM_RC_SUCCESS;
19661 }
19662
PCR_ExtendErrorCallback(Tpm::PCR_ExtendResponse callback,TPM_RC response_code)19663 void PCR_ExtendErrorCallback(Tpm::PCR_ExtendResponse callback,
19664 TPM_RC response_code) {
19665 VLOG(1) << __func__;
19666 std::move(callback).Run(response_code);
19667 }
19668
PCR_ExtendResponseParser(Tpm::PCR_ExtendResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19669 void PCR_ExtendResponseParser(Tpm::PCR_ExtendResponse callback,
19670 AuthorizationDelegate* authorization_delegate,
19671 const std::string& response) {
19672 VLOG(1) << __func__;
19673 TPM_RC rc = Tpm::ParseResponse_PCR_Extend(response, authorization_delegate);
19674 if (rc != TPM_RC_SUCCESS) {
19675 base::OnceCallback<void(TPM_RC)> error_reporter =
19676 base::BindOnce(PCR_ExtendErrorCallback, std::move(callback));
19677 std::move(error_reporter).Run(rc);
19678 return;
19679 }
19680 std::move(callback).Run(rc);
19681 }
19682
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)19683 void Tpm::PCR_Extend(const TPMI_DH_PCR& pcr_handle,
19684 const std::string& pcr_handle_name,
19685 const TPML_DIGEST_VALUES& digests,
19686 AuthorizationDelegate* authorization_delegate,
19687 PCR_ExtendResponse callback) {
19688 VLOG(1) << __func__;
19689 std::string command;
19690 TPM_RC rc = SerializeCommand_PCR_Extend(pcr_handle, pcr_handle_name, digests,
19691 &command, authorization_delegate);
19692 if (rc != TPM_RC_SUCCESS) {
19693 base::OnceCallback<void(TPM_RC)> error_reporter =
19694 base::BindOnce(PCR_ExtendErrorCallback, std::move(callback));
19695 std::move(error_reporter).Run(rc);
19696 return;
19697 }
19698 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19699 PCR_ExtendResponseParser, std::move(callback), authorization_delegate);
19700 transceiver_->SendCommand(command, std::move(parser));
19701 }
19702
PCR_ExtendSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPML_DIGEST_VALUES & digests,AuthorizationDelegate * authorization_delegate)19703 TPM_RC Tpm::PCR_ExtendSync(const TPMI_DH_PCR& pcr_handle,
19704 const std::string& pcr_handle_name,
19705 const TPML_DIGEST_VALUES& digests,
19706 AuthorizationDelegate* authorization_delegate) {
19707 VLOG(1) << __func__;
19708 std::string command;
19709 TPM_RC rc = SerializeCommand_PCR_Extend(pcr_handle, pcr_handle_name, digests,
19710 &command, authorization_delegate);
19711 if (rc != TPM_RC_SUCCESS) {
19712 return rc;
19713 }
19714 std::string response = transceiver_->SendCommandAndWait(command);
19715 rc = ParseResponse_PCR_Extend(response, authorization_delegate);
19716 return rc;
19717 }
19718
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)19719 TPM_RC Tpm::SerializeCommand_PCR_Event(
19720 const TPMI_DH_PCR& pcr_handle,
19721 const std::string& pcr_handle_name,
19722 const TPM2B_EVENT& event_data,
19723 std::string* serialized_command,
19724 AuthorizationDelegate* authorization_delegate) {
19725 VLOG(3) << __func__;
19726 TPM_RC rc = TPM_RC_SUCCESS;
19727 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19728 UINT32 command_size = 10; // Header size.
19729 std::string handle_section_bytes;
19730 std::string parameter_section_bytes;
19731 TPM_CC command_code = TPM_CC_PCR_Event;
19732 bool is_command_parameter_encryption_possible = true;
19733 bool is_response_parameter_encryption_possible = false;
19734 std::string command_code_bytes;
19735 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19736 if (rc != TPM_RC_SUCCESS) {
19737 return rc;
19738 }
19739 std::string pcr_handle_bytes;
19740 rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
19741 if (rc != TPM_RC_SUCCESS) {
19742 return rc;
19743 }
19744 std::string event_data_bytes;
19745 rc = Serialize_TPM2B_EVENT(event_data, &event_data_bytes);
19746 if (rc != TPM_RC_SUCCESS) {
19747 return rc;
19748 }
19749 if (authorization_delegate) {
19750 // Encrypt just the parameter data, not the size.
19751 std::string tmp = event_data_bytes.substr(2);
19752 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
19753 return TRUNKS_RC_ENCRYPTION_FAILED;
19754 }
19755 event_data_bytes.replace(2, std::string::npos, tmp);
19756 }
19757 std::unique_ptr<crypto::SecureHash> hash(
19758 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19759 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19760 hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
19761 handle_section_bytes += pcr_handle_bytes;
19762 command_size += pcr_handle_bytes.size();
19763 hash->Update(event_data_bytes.data(), event_data_bytes.size());
19764 parameter_section_bytes += event_data_bytes;
19765 command_size += event_data_bytes.size();
19766 std::string command_hash(32, 0);
19767 hash->Finish(std::data(command_hash), command_hash.size());
19768 std::string authorization_section_bytes;
19769 std::string authorization_size_bytes;
19770 if (authorization_delegate) {
19771 if (!authorization_delegate->GetCommandAuthorization(
19772 command_hash, is_command_parameter_encryption_possible,
19773 is_response_parameter_encryption_possible,
19774 &authorization_section_bytes)) {
19775 return TRUNKS_RC_AUTHORIZATION_FAILED;
19776 }
19777 if (!authorization_section_bytes.empty()) {
19778 tag = TPM_ST_SESSIONS;
19779 std::string tmp;
19780 rc = Serialize_UINT32(authorization_section_bytes.size(),
19781 &authorization_size_bytes);
19782 if (rc != TPM_RC_SUCCESS) {
19783 return rc;
19784 }
19785 command_size +=
19786 authorization_size_bytes.size() + authorization_section_bytes.size();
19787 }
19788 }
19789 std::string tag_bytes;
19790 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19791 if (rc != TPM_RC_SUCCESS) {
19792 return rc;
19793 }
19794 std::string command_size_bytes;
19795 rc = Serialize_UINT32(command_size, &command_size_bytes);
19796 if (rc != TPM_RC_SUCCESS) {
19797 return rc;
19798 }
19799 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19800 handle_section_bytes + authorization_size_bytes +
19801 authorization_section_bytes + parameter_section_bytes;
19802 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19803 VLOG(2) << "Command: "
19804 << base::HexEncode(serialized_command->data(),
19805 serialized_command->size());
19806 return TPM_RC_SUCCESS;
19807 }
19808
ParseResponse_PCR_Event(const std::string & response,TPML_DIGEST_VALUES * digests,AuthorizationDelegate * authorization_delegate)19809 TPM_RC Tpm::ParseResponse_PCR_Event(
19810 const std::string& response,
19811 TPML_DIGEST_VALUES* digests,
19812 AuthorizationDelegate* authorization_delegate) {
19813 VLOG(3) << __func__;
19814 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19815 TPM_RC rc = TPM_RC_SUCCESS;
19816 std::string buffer(response);
19817 TPM_ST tag;
19818 std::string tag_bytes;
19819 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19820 if (rc != TPM_RC_SUCCESS) {
19821 return rc;
19822 }
19823 UINT32 response_size;
19824 std::string response_size_bytes;
19825 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19826 if (rc != TPM_RC_SUCCESS) {
19827 return rc;
19828 }
19829 TPM_RC response_code;
19830 std::string response_code_bytes;
19831 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19832 if (rc != TPM_RC_SUCCESS) {
19833 return rc;
19834 }
19835 if (response_size != response.size()) {
19836 return TPM_RC_SIZE;
19837 }
19838 if (response_code != TPM_RC_SUCCESS) {
19839 return response_code;
19840 }
19841 TPM_CC command_code = TPM_CC_PCR_Event;
19842 std::string command_code_bytes;
19843 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19844 if (rc != TPM_RC_SUCCESS) {
19845 return rc;
19846 }
19847 std::string authorization_section_bytes;
19848 if (tag == TPM_ST_SESSIONS) {
19849 UINT32 parameter_section_size = buffer.size();
19850 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
19851 if (rc != TPM_RC_SUCCESS) {
19852 return rc;
19853 }
19854 if (parameter_section_size > buffer.size()) {
19855 return TPM_RC_INSUFFICIENT;
19856 }
19857 authorization_section_bytes = buffer.substr(parameter_section_size);
19858 // Keep the parameter section in |buffer|.
19859 buffer.erase(parameter_section_size);
19860 }
19861 std::unique_ptr<crypto::SecureHash> hash(
19862 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19863 hash->Update(response_code_bytes.data(), response_code_bytes.size());
19864 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19865 hash->Update(buffer.data(), buffer.size());
19866 std::string response_hash(32, 0);
19867 hash->Finish(std::data(response_hash), response_hash.size());
19868 if (tag == TPM_ST_SESSIONS) {
19869 if (!authorization_delegate)
19870 return TRUNKS_RC_AUTHORIZATION_FAILED;
19871 if (!authorization_delegate->CheckResponseAuthorization(
19872 response_hash, authorization_section_bytes)) {
19873 return TRUNKS_RC_AUTHORIZATION_FAILED;
19874 }
19875 }
19876 std::string digests_bytes;
19877 rc = Parse_TPML_DIGEST_VALUES(&buffer, digests, &digests_bytes);
19878 if (rc != TPM_RC_SUCCESS) {
19879 return rc;
19880 }
19881 return TPM_RC_SUCCESS;
19882 }
19883
PCR_EventErrorCallback(Tpm::PCR_EventResponse callback,TPM_RC response_code)19884 void PCR_EventErrorCallback(Tpm::PCR_EventResponse callback,
19885 TPM_RC response_code) {
19886 VLOG(1) << __func__;
19887 std::move(callback).Run(response_code, TPML_DIGEST_VALUES());
19888 }
19889
PCR_EventResponseParser(Tpm::PCR_EventResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19890 void PCR_EventResponseParser(Tpm::PCR_EventResponse callback,
19891 AuthorizationDelegate* authorization_delegate,
19892 const std::string& response) {
19893 VLOG(1) << __func__;
19894 TPML_DIGEST_VALUES digests;
19895 TPM_RC rc =
19896 Tpm::ParseResponse_PCR_Event(response, &digests, authorization_delegate);
19897 if (rc != TPM_RC_SUCCESS) {
19898 base::OnceCallback<void(TPM_RC)> error_reporter =
19899 base::BindOnce(PCR_EventErrorCallback, std::move(callback));
19900 std::move(error_reporter).Run(rc);
19901 return;
19902 }
19903 std::move(callback).Run(rc, digests);
19904 }
19905
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)19906 void Tpm::PCR_Event(const TPMI_DH_PCR& pcr_handle,
19907 const std::string& pcr_handle_name,
19908 const TPM2B_EVENT& event_data,
19909 AuthorizationDelegate* authorization_delegate,
19910 PCR_EventResponse callback) {
19911 VLOG(1) << __func__;
19912 std::string command;
19913 TPM_RC rc =
19914 SerializeCommand_PCR_Event(pcr_handle, pcr_handle_name, event_data,
19915 &command, authorization_delegate);
19916 if (rc != TPM_RC_SUCCESS) {
19917 base::OnceCallback<void(TPM_RC)> error_reporter =
19918 base::BindOnce(PCR_EventErrorCallback, std::move(callback));
19919 std::move(error_reporter).Run(rc);
19920 return;
19921 }
19922 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19923 PCR_EventResponseParser, std::move(callback), authorization_delegate);
19924 transceiver_->SendCommand(command, std::move(parser));
19925 }
19926
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)19927 TPM_RC Tpm::PCR_EventSync(const TPMI_DH_PCR& pcr_handle,
19928 const std::string& pcr_handle_name,
19929 const TPM2B_EVENT& event_data,
19930 TPML_DIGEST_VALUES* digests,
19931 AuthorizationDelegate* authorization_delegate) {
19932 VLOG(1) << __func__;
19933 std::string command;
19934 TPM_RC rc =
19935 SerializeCommand_PCR_Event(pcr_handle, pcr_handle_name, event_data,
19936 &command, authorization_delegate);
19937 if (rc != TPM_RC_SUCCESS) {
19938 return rc;
19939 }
19940 std::string response = transceiver_->SendCommandAndWait(command);
19941 rc = ParseResponse_PCR_Event(response, digests, authorization_delegate);
19942 return rc;
19943 }
19944
SerializeCommand_PCR_Read(const TPML_PCR_SELECTION & pcr_selection_in,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19945 TPM_RC Tpm::SerializeCommand_PCR_Read(
19946 const TPML_PCR_SELECTION& pcr_selection_in,
19947 std::string* serialized_command,
19948 AuthorizationDelegate* authorization_delegate) {
19949 VLOG(3) << __func__;
19950 TPM_RC rc = TPM_RC_SUCCESS;
19951 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19952 UINT32 command_size = 10; // Header size.
19953 std::string handle_section_bytes;
19954 std::string parameter_section_bytes;
19955 TPM_CC command_code = TPM_CC_PCR_Read;
19956 bool is_command_parameter_encryption_possible = false;
19957 bool is_response_parameter_encryption_possible = false;
19958 std::string command_code_bytes;
19959 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19960 if (rc != TPM_RC_SUCCESS) {
19961 return rc;
19962 }
19963 std::string pcr_selection_in_bytes;
19964 rc = Serialize_TPML_PCR_SELECTION(pcr_selection_in, &pcr_selection_in_bytes);
19965 if (rc != TPM_RC_SUCCESS) {
19966 return rc;
19967 }
19968 std::unique_ptr<crypto::SecureHash> hash(
19969 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19970 hash->Update(command_code_bytes.data(), command_code_bytes.size());
19971 hash->Update(pcr_selection_in_bytes.data(), pcr_selection_in_bytes.size());
19972 parameter_section_bytes += pcr_selection_in_bytes;
19973 command_size += pcr_selection_in_bytes.size();
19974 std::string command_hash(32, 0);
19975 hash->Finish(std::data(command_hash), command_hash.size());
19976 std::string authorization_section_bytes;
19977 std::string authorization_size_bytes;
19978 if (authorization_delegate) {
19979 if (!authorization_delegate->GetCommandAuthorization(
19980 command_hash, is_command_parameter_encryption_possible,
19981 is_response_parameter_encryption_possible,
19982 &authorization_section_bytes)) {
19983 return TRUNKS_RC_AUTHORIZATION_FAILED;
19984 }
19985 if (!authorization_section_bytes.empty()) {
19986 tag = TPM_ST_SESSIONS;
19987 std::string tmp;
19988 rc = Serialize_UINT32(authorization_section_bytes.size(),
19989 &authorization_size_bytes);
19990 if (rc != TPM_RC_SUCCESS) {
19991 return rc;
19992 }
19993 command_size +=
19994 authorization_size_bytes.size() + authorization_section_bytes.size();
19995 }
19996 }
19997 std::string tag_bytes;
19998 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19999 if (rc != TPM_RC_SUCCESS) {
20000 return rc;
20001 }
20002 std::string command_size_bytes;
20003 rc = Serialize_UINT32(command_size, &command_size_bytes);
20004 if (rc != TPM_RC_SUCCESS) {
20005 return rc;
20006 }
20007 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20008 handle_section_bytes + authorization_size_bytes +
20009 authorization_section_bytes + parameter_section_bytes;
20010 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20011 VLOG(2) << "Command: "
20012 << base::HexEncode(serialized_command->data(),
20013 serialized_command->size());
20014 return TPM_RC_SUCCESS;
20015 }
20016
ParseResponse_PCR_Read(const std::string & response,UINT32 * pcr_update_counter,TPML_PCR_SELECTION * pcr_selection_out,TPML_DIGEST * pcr_values,AuthorizationDelegate * authorization_delegate)20017 TPM_RC Tpm::ParseResponse_PCR_Read(
20018 const std::string& response,
20019 UINT32* pcr_update_counter,
20020 TPML_PCR_SELECTION* pcr_selection_out,
20021 TPML_DIGEST* pcr_values,
20022 AuthorizationDelegate* authorization_delegate) {
20023 VLOG(3) << __func__;
20024 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20025 TPM_RC rc = TPM_RC_SUCCESS;
20026 std::string buffer(response);
20027 TPM_ST tag;
20028 std::string tag_bytes;
20029 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20030 if (rc != TPM_RC_SUCCESS) {
20031 return rc;
20032 }
20033 UINT32 response_size;
20034 std::string response_size_bytes;
20035 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20036 if (rc != TPM_RC_SUCCESS) {
20037 return rc;
20038 }
20039 TPM_RC response_code;
20040 std::string response_code_bytes;
20041 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20042 if (rc != TPM_RC_SUCCESS) {
20043 return rc;
20044 }
20045 if (response_size != response.size()) {
20046 return TPM_RC_SIZE;
20047 }
20048 if (response_code != TPM_RC_SUCCESS) {
20049 return response_code;
20050 }
20051 TPM_CC command_code = TPM_CC_PCR_Read;
20052 std::string command_code_bytes;
20053 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20054 if (rc != TPM_RC_SUCCESS) {
20055 return rc;
20056 }
20057 std::string authorization_section_bytes;
20058 if (tag == TPM_ST_SESSIONS) {
20059 UINT32 parameter_section_size = buffer.size();
20060 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
20061 if (rc != TPM_RC_SUCCESS) {
20062 return rc;
20063 }
20064 if (parameter_section_size > buffer.size()) {
20065 return TPM_RC_INSUFFICIENT;
20066 }
20067 authorization_section_bytes = buffer.substr(parameter_section_size);
20068 // Keep the parameter section in |buffer|.
20069 buffer.erase(parameter_section_size);
20070 }
20071 std::unique_ptr<crypto::SecureHash> hash(
20072 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20073 hash->Update(response_code_bytes.data(), response_code_bytes.size());
20074 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20075 hash->Update(buffer.data(), buffer.size());
20076 std::string response_hash(32, 0);
20077 hash->Finish(std::data(response_hash), response_hash.size());
20078 if (tag == TPM_ST_SESSIONS) {
20079 if (!authorization_delegate)
20080 return TRUNKS_RC_AUTHORIZATION_FAILED;
20081 if (!authorization_delegate->CheckResponseAuthorization(
20082 response_hash, authorization_section_bytes)) {
20083 return TRUNKS_RC_AUTHORIZATION_FAILED;
20084 }
20085 }
20086 std::string pcr_update_counter_bytes;
20087 rc = Parse_UINT32(&buffer, pcr_update_counter, &pcr_update_counter_bytes);
20088 if (rc != TPM_RC_SUCCESS) {
20089 return rc;
20090 }
20091 std::string pcr_selection_out_bytes;
20092 rc = Parse_TPML_PCR_SELECTION(&buffer, pcr_selection_out,
20093 &pcr_selection_out_bytes);
20094 if (rc != TPM_RC_SUCCESS) {
20095 return rc;
20096 }
20097 std::string pcr_values_bytes;
20098 rc = Parse_TPML_DIGEST(&buffer, pcr_values, &pcr_values_bytes);
20099 if (rc != TPM_RC_SUCCESS) {
20100 return rc;
20101 }
20102 return TPM_RC_SUCCESS;
20103 }
20104
PCR_ReadErrorCallback(Tpm::PCR_ReadResponse callback,TPM_RC response_code)20105 void PCR_ReadErrorCallback(Tpm::PCR_ReadResponse callback,
20106 TPM_RC response_code) {
20107 VLOG(1) << __func__;
20108 std::move(callback).Run(response_code, UINT32(), TPML_PCR_SELECTION(),
20109 TPML_DIGEST());
20110 }
20111
PCR_ReadResponseParser(Tpm::PCR_ReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20112 void PCR_ReadResponseParser(Tpm::PCR_ReadResponse callback,
20113 AuthorizationDelegate* authorization_delegate,
20114 const std::string& response) {
20115 VLOG(1) << __func__;
20116 UINT32 pcr_update_counter;
20117 TPML_PCR_SELECTION pcr_selection_out;
20118 TPML_DIGEST pcr_values;
20119 TPM_RC rc = Tpm::ParseResponse_PCR_Read(response, &pcr_update_counter,
20120 &pcr_selection_out, &pcr_values,
20121 authorization_delegate);
20122 if (rc != TPM_RC_SUCCESS) {
20123 base::OnceCallback<void(TPM_RC)> error_reporter =
20124 base::BindOnce(PCR_ReadErrorCallback, std::move(callback));
20125 std::move(error_reporter).Run(rc);
20126 return;
20127 }
20128 std::move(callback).Run(rc, pcr_update_counter, pcr_selection_out,
20129 pcr_values);
20130 }
20131
PCR_Read(const TPML_PCR_SELECTION & pcr_selection_in,AuthorizationDelegate * authorization_delegate,PCR_ReadResponse callback)20132 void Tpm::PCR_Read(const TPML_PCR_SELECTION& pcr_selection_in,
20133 AuthorizationDelegate* authorization_delegate,
20134 PCR_ReadResponse callback) {
20135 VLOG(1) << __func__;
20136 std::string command;
20137 TPM_RC rc = SerializeCommand_PCR_Read(pcr_selection_in, &command,
20138 authorization_delegate);
20139 if (rc != TPM_RC_SUCCESS) {
20140 base::OnceCallback<void(TPM_RC)> error_reporter =
20141 base::BindOnce(PCR_ReadErrorCallback, std::move(callback));
20142 std::move(error_reporter).Run(rc);
20143 return;
20144 }
20145 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
20146 PCR_ReadResponseParser, std::move(callback), authorization_delegate);
20147 transceiver_->SendCommand(command, std::move(parser));
20148 }
20149
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)20150 TPM_RC Tpm::PCR_ReadSync(const TPML_PCR_SELECTION& pcr_selection_in,
20151 UINT32* pcr_update_counter,
20152 TPML_PCR_SELECTION* pcr_selection_out,
20153 TPML_DIGEST* pcr_values,
20154 AuthorizationDelegate* authorization_delegate) {
20155 VLOG(1) << __func__;
20156 std::string command;
20157 TPM_RC rc = SerializeCommand_PCR_Read(pcr_selection_in, &command,
20158 authorization_delegate);
20159 if (rc != TPM_RC_SUCCESS) {
20160 return rc;
20161 }
20162 std::string response = transceiver_->SendCommandAndWait(command);
20163 rc = ParseResponse_PCR_Read(response, pcr_update_counter, pcr_selection_out,
20164 pcr_values, authorization_delegate);
20165 return rc;
20166 }
20167
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)20168 TPM_RC Tpm::SerializeCommand_PCR_Allocate(
20169 const TPMI_RH_PLATFORM& auth_handle,
20170 const std::string& auth_handle_name,
20171 const TPML_PCR_SELECTION& pcr_allocation,
20172 std::string* serialized_command,
20173 AuthorizationDelegate* authorization_delegate) {
20174 VLOG(3) << __func__;
20175 TPM_RC rc = TPM_RC_SUCCESS;
20176 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20177 UINT32 command_size = 10; // Header size.
20178 std::string handle_section_bytes;
20179 std::string parameter_section_bytes;
20180 TPM_CC command_code = TPM_CC_PCR_Allocate;
20181 bool is_command_parameter_encryption_possible = false;
20182 bool is_response_parameter_encryption_possible = false;
20183 std::string command_code_bytes;
20184 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20185 if (rc != TPM_RC_SUCCESS) {
20186 return rc;
20187 }
20188 std::string auth_handle_bytes;
20189 rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
20190 if (rc != TPM_RC_SUCCESS) {
20191 return rc;
20192 }
20193 std::string pcr_allocation_bytes;
20194 rc = Serialize_TPML_PCR_SELECTION(pcr_allocation, &pcr_allocation_bytes);
20195 if (rc != TPM_RC_SUCCESS) {
20196 return rc;
20197 }
20198 std::unique_ptr<crypto::SecureHash> hash(
20199 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20200 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20201 hash->Update(auth_handle_name.data(), auth_handle_name.size());
20202 handle_section_bytes += auth_handle_bytes;
20203 command_size += auth_handle_bytes.size();
20204 hash->Update(pcr_allocation_bytes.data(), pcr_allocation_bytes.size());
20205 parameter_section_bytes += pcr_allocation_bytes;
20206 command_size += pcr_allocation_bytes.size();
20207 std::string command_hash(32, 0);
20208 hash->Finish(std::data(command_hash), command_hash.size());
20209 std::string authorization_section_bytes;
20210 std::string authorization_size_bytes;
20211 if (authorization_delegate) {
20212 if (!authorization_delegate->GetCommandAuthorization(
20213 command_hash, is_command_parameter_encryption_possible,
20214 is_response_parameter_encryption_possible,
20215 &authorization_section_bytes)) {
20216 return TRUNKS_RC_AUTHORIZATION_FAILED;
20217 }
20218 if (!authorization_section_bytes.empty()) {
20219 tag = TPM_ST_SESSIONS;
20220 std::string tmp;
20221 rc = Serialize_UINT32(authorization_section_bytes.size(),
20222 &authorization_size_bytes);
20223 if (rc != TPM_RC_SUCCESS) {
20224 return rc;
20225 }
20226 command_size +=
20227 authorization_size_bytes.size() + authorization_section_bytes.size();
20228 }
20229 }
20230 std::string tag_bytes;
20231 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20232 if (rc != TPM_RC_SUCCESS) {
20233 return rc;
20234 }
20235 std::string command_size_bytes;
20236 rc = Serialize_UINT32(command_size, &command_size_bytes);
20237 if (rc != TPM_RC_SUCCESS) {
20238 return rc;
20239 }
20240 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20241 handle_section_bytes + authorization_size_bytes +
20242 authorization_section_bytes + parameter_section_bytes;
20243 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20244 VLOG(2) << "Command: "
20245 << base::HexEncode(serialized_command->data(),
20246 serialized_command->size());
20247 return TPM_RC_SUCCESS;
20248 }
20249
ParseResponse_PCR_Allocate(const std::string & response,TPMI_YES_NO * allocation_success,UINT32 * max_pcr,UINT32 * size_needed,UINT32 * size_available,AuthorizationDelegate * authorization_delegate)20250 TPM_RC Tpm::ParseResponse_PCR_Allocate(
20251 const std::string& response,
20252 TPMI_YES_NO* allocation_success,
20253 UINT32* max_pcr,
20254 UINT32* size_needed,
20255 UINT32* size_available,
20256 AuthorizationDelegate* authorization_delegate) {
20257 VLOG(3) << __func__;
20258 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20259 TPM_RC rc = TPM_RC_SUCCESS;
20260 std::string buffer(response);
20261 TPM_ST tag;
20262 std::string tag_bytes;
20263 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20264 if (rc != TPM_RC_SUCCESS) {
20265 return rc;
20266 }
20267 UINT32 response_size;
20268 std::string response_size_bytes;
20269 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20270 if (rc != TPM_RC_SUCCESS) {
20271 return rc;
20272 }
20273 TPM_RC response_code;
20274 std::string response_code_bytes;
20275 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20276 if (rc != TPM_RC_SUCCESS) {
20277 return rc;
20278 }
20279 if (response_size != response.size()) {
20280 return TPM_RC_SIZE;
20281 }
20282 if (response_code != TPM_RC_SUCCESS) {
20283 return response_code;
20284 }
20285 TPM_CC command_code = TPM_CC_PCR_Allocate;
20286 std::string command_code_bytes;
20287 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20288 if (rc != TPM_RC_SUCCESS) {
20289 return rc;
20290 }
20291 std::string authorization_section_bytes;
20292 if (tag == TPM_ST_SESSIONS) {
20293 UINT32 parameter_section_size = buffer.size();
20294 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
20295 if (rc != TPM_RC_SUCCESS) {
20296 return rc;
20297 }
20298 if (parameter_section_size > buffer.size()) {
20299 return TPM_RC_INSUFFICIENT;
20300 }
20301 authorization_section_bytes = buffer.substr(parameter_section_size);
20302 // Keep the parameter section in |buffer|.
20303 buffer.erase(parameter_section_size);
20304 }
20305 std::unique_ptr<crypto::SecureHash> hash(
20306 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20307 hash->Update(response_code_bytes.data(), response_code_bytes.size());
20308 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20309 hash->Update(buffer.data(), buffer.size());
20310 std::string response_hash(32, 0);
20311 hash->Finish(std::data(response_hash), response_hash.size());
20312 if (tag == TPM_ST_SESSIONS) {
20313 if (!authorization_delegate)
20314 return TRUNKS_RC_AUTHORIZATION_FAILED;
20315 if (!authorization_delegate->CheckResponseAuthorization(
20316 response_hash, authorization_section_bytes)) {
20317 return TRUNKS_RC_AUTHORIZATION_FAILED;
20318 }
20319 }
20320 std::string allocation_success_bytes;
20321 rc =
20322 Parse_TPMI_YES_NO(&buffer, allocation_success, &allocation_success_bytes);
20323 if (rc != TPM_RC_SUCCESS) {
20324 return rc;
20325 }
20326 std::string max_pcr_bytes;
20327 rc = Parse_UINT32(&buffer, max_pcr, &max_pcr_bytes);
20328 if (rc != TPM_RC_SUCCESS) {
20329 return rc;
20330 }
20331 std::string size_needed_bytes;
20332 rc = Parse_UINT32(&buffer, size_needed, &size_needed_bytes);
20333 if (rc != TPM_RC_SUCCESS) {
20334 return rc;
20335 }
20336 std::string size_available_bytes;
20337 rc = Parse_UINT32(&buffer, size_available, &size_available_bytes);
20338 if (rc != TPM_RC_SUCCESS) {
20339 return rc;
20340 }
20341 return TPM_RC_SUCCESS;
20342 }
20343
PCR_AllocateErrorCallback(Tpm::PCR_AllocateResponse callback,TPM_RC response_code)20344 void PCR_AllocateErrorCallback(Tpm::PCR_AllocateResponse callback,
20345 TPM_RC response_code) {
20346 VLOG(1) << __func__;
20347 std::move(callback).Run(response_code, TPMI_YES_NO(), UINT32(), UINT32(),
20348 UINT32());
20349 }
20350
PCR_AllocateResponseParser(Tpm::PCR_AllocateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20351 void PCR_AllocateResponseParser(Tpm::PCR_AllocateResponse callback,
20352 AuthorizationDelegate* authorization_delegate,
20353 const std::string& response) {
20354 VLOG(1) << __func__;
20355 TPMI_YES_NO allocation_success;
20356 UINT32 max_pcr;
20357 UINT32 size_needed;
20358 UINT32 size_available;
20359 TPM_RC rc = Tpm::ParseResponse_PCR_Allocate(
20360 response, &allocation_success, &max_pcr, &size_needed, &size_available,
20361 authorization_delegate);
20362 if (rc != TPM_RC_SUCCESS) {
20363 base::OnceCallback<void(TPM_RC)> error_reporter =
20364 base::BindOnce(PCR_AllocateErrorCallback, std::move(callback));
20365 std::move(error_reporter).Run(rc);
20366 return;
20367 }
20368 std::move(callback).Run(rc, allocation_success, max_pcr, size_needed,
20369 size_available);
20370 }
20371
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)20372 void Tpm::PCR_Allocate(const TPMI_RH_PLATFORM& auth_handle,
20373 const std::string& auth_handle_name,
20374 const TPML_PCR_SELECTION& pcr_allocation,
20375 AuthorizationDelegate* authorization_delegate,
20376 PCR_AllocateResponse callback) {
20377 VLOG(1) << __func__;
20378 std::string command;
20379 TPM_RC rc = SerializeCommand_PCR_Allocate(auth_handle, auth_handle_name,
20380 pcr_allocation, &command,
20381 authorization_delegate);
20382 if (rc != TPM_RC_SUCCESS) {
20383 base::OnceCallback<void(TPM_RC)> error_reporter =
20384 base::BindOnce(PCR_AllocateErrorCallback, std::move(callback));
20385 std::move(error_reporter).Run(rc);
20386 return;
20387 }
20388 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
20389 PCR_AllocateResponseParser, std::move(callback), authorization_delegate);
20390 transceiver_->SendCommand(command, std::move(parser));
20391 }
20392
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)20393 TPM_RC Tpm::PCR_AllocateSync(const TPMI_RH_PLATFORM& auth_handle,
20394 const std::string& auth_handle_name,
20395 const TPML_PCR_SELECTION& pcr_allocation,
20396 TPMI_YES_NO* allocation_success,
20397 UINT32* max_pcr,
20398 UINT32* size_needed,
20399 UINT32* size_available,
20400 AuthorizationDelegate* authorization_delegate) {
20401 VLOG(1) << __func__;
20402 std::string command;
20403 TPM_RC rc = SerializeCommand_PCR_Allocate(auth_handle, auth_handle_name,
20404 pcr_allocation, &command,
20405 authorization_delegate);
20406 if (rc != TPM_RC_SUCCESS) {
20407 return rc;
20408 }
20409 std::string response = transceiver_->SendCommandAndWait(command);
20410 rc = ParseResponse_PCR_Allocate(response, allocation_success, max_pcr,
20411 size_needed, size_available,
20412 authorization_delegate);
20413 return rc;
20414 }
20415
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)20416 TPM_RC Tpm::SerializeCommand_PCR_SetAuthPolicy(
20417 const TPMI_RH_PLATFORM& auth_handle,
20418 const std::string& auth_handle_name,
20419 const TPMI_DH_PCR& pcr_num,
20420 const std::string& pcr_num_name,
20421 const TPM2B_DIGEST& auth_policy,
20422 const TPMI_ALG_HASH& policy_digest,
20423 std::string* serialized_command,
20424 AuthorizationDelegate* authorization_delegate) {
20425 VLOG(3) << __func__;
20426 TPM_RC rc = TPM_RC_SUCCESS;
20427 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20428 UINT32 command_size = 10; // Header size.
20429 std::string handle_section_bytes;
20430 std::string parameter_section_bytes;
20431 TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy;
20432 bool is_command_parameter_encryption_possible = true;
20433 bool is_response_parameter_encryption_possible = false;
20434 std::string command_code_bytes;
20435 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20436 if (rc != TPM_RC_SUCCESS) {
20437 return rc;
20438 }
20439 std::string auth_handle_bytes;
20440 rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
20441 if (rc != TPM_RC_SUCCESS) {
20442 return rc;
20443 }
20444 std::string auth_policy_bytes;
20445 rc = Serialize_TPM2B_DIGEST(auth_policy, &auth_policy_bytes);
20446 if (rc != TPM_RC_SUCCESS) {
20447 return rc;
20448 }
20449 std::string policy_digest_bytes;
20450 rc = Serialize_TPMI_ALG_HASH(policy_digest, &policy_digest_bytes);
20451 if (rc != TPM_RC_SUCCESS) {
20452 return rc;
20453 }
20454 std::string pcr_num_bytes;
20455 rc = Serialize_TPMI_DH_PCR(pcr_num, &pcr_num_bytes);
20456 if (rc != TPM_RC_SUCCESS) {
20457 return rc;
20458 }
20459 if (authorization_delegate) {
20460 // Encrypt just the parameter data, not the size.
20461 std::string tmp = auth_policy_bytes.substr(2);
20462 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20463 return TRUNKS_RC_ENCRYPTION_FAILED;
20464 }
20465 auth_policy_bytes.replace(2, std::string::npos, tmp);
20466 }
20467 std::unique_ptr<crypto::SecureHash> hash(
20468 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20469 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20470 hash->Update(auth_handle_name.data(), auth_handle_name.size());
20471 handle_section_bytes += auth_handle_bytes;
20472 command_size += auth_handle_bytes.size();
20473 hash->Update(pcr_num_name.data(), pcr_num_name.size());
20474 handle_section_bytes += pcr_num_bytes;
20475 command_size += pcr_num_bytes.size();
20476 hash->Update(auth_policy_bytes.data(), auth_policy_bytes.size());
20477 parameter_section_bytes += auth_policy_bytes;
20478 command_size += auth_policy_bytes.size();
20479 hash->Update(policy_digest_bytes.data(), policy_digest_bytes.size());
20480 parameter_section_bytes += policy_digest_bytes;
20481 command_size += policy_digest_bytes.size();
20482 std::string command_hash(32, 0);
20483 hash->Finish(std::data(command_hash), command_hash.size());
20484 std::string authorization_section_bytes;
20485 std::string authorization_size_bytes;
20486 if (authorization_delegate) {
20487 if (!authorization_delegate->GetCommandAuthorization(
20488 command_hash, is_command_parameter_encryption_possible,
20489 is_response_parameter_encryption_possible,
20490 &authorization_section_bytes)) {
20491 return TRUNKS_RC_AUTHORIZATION_FAILED;
20492 }
20493 if (!authorization_section_bytes.empty()) {
20494 tag = TPM_ST_SESSIONS;
20495 std::string tmp;
20496 rc = Serialize_UINT32(authorization_section_bytes.size(),
20497 &authorization_size_bytes);
20498 if (rc != TPM_RC_SUCCESS) {
20499 return rc;
20500 }
20501 command_size +=
20502 authorization_size_bytes.size() + authorization_section_bytes.size();
20503 }
20504 }
20505 std::string tag_bytes;
20506 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20507 if (rc != TPM_RC_SUCCESS) {
20508 return rc;
20509 }
20510 std::string command_size_bytes;
20511 rc = Serialize_UINT32(command_size, &command_size_bytes);
20512 if (rc != TPM_RC_SUCCESS) {
20513 return rc;
20514 }
20515 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20516 handle_section_bytes + authorization_size_bytes +
20517 authorization_section_bytes + parameter_section_bytes;
20518 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20519 VLOG(2) << "Command: "
20520 << base::HexEncode(serialized_command->data(),
20521 serialized_command->size());
20522 return TPM_RC_SUCCESS;
20523 }
20524
ParseResponse_PCR_SetAuthPolicy(const std::string & response,AuthorizationDelegate * authorization_delegate)20525 TPM_RC Tpm::ParseResponse_PCR_SetAuthPolicy(
20526 const std::string& response,
20527 AuthorizationDelegate* authorization_delegate) {
20528 VLOG(3) << __func__;
20529 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20530 TPM_RC rc = TPM_RC_SUCCESS;
20531 std::string buffer(response);
20532 TPM_ST tag;
20533 std::string tag_bytes;
20534 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20535 if (rc != TPM_RC_SUCCESS) {
20536 return rc;
20537 }
20538 UINT32 response_size;
20539 std::string response_size_bytes;
20540 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20541 if (rc != TPM_RC_SUCCESS) {
20542 return rc;
20543 }
20544 TPM_RC response_code;
20545 std::string response_code_bytes;
20546 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20547 if (rc != TPM_RC_SUCCESS) {
20548 return rc;
20549 }
20550 if (response_size != response.size()) {
20551 return TPM_RC_SIZE;
20552 }
20553 if (response_code != TPM_RC_SUCCESS) {
20554 return response_code;
20555 }
20556 TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy;
20557 std::string command_code_bytes;
20558 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20559 if (rc != TPM_RC_SUCCESS) {
20560 return rc;
20561 }
20562 std::string authorization_section_bytes;
20563 if (tag == TPM_ST_SESSIONS) {
20564 UINT32 parameter_section_size = buffer.size();
20565 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
20566 if (rc != TPM_RC_SUCCESS) {
20567 return rc;
20568 }
20569 if (parameter_section_size > buffer.size()) {
20570 return TPM_RC_INSUFFICIENT;
20571 }
20572 authorization_section_bytes = buffer.substr(parameter_section_size);
20573 // Keep the parameter section in |buffer|.
20574 buffer.erase(parameter_section_size);
20575 }
20576 std::unique_ptr<crypto::SecureHash> hash(
20577 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20578 hash->Update(response_code_bytes.data(), response_code_bytes.size());
20579 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20580 hash->Update(buffer.data(), buffer.size());
20581 std::string response_hash(32, 0);
20582 hash->Finish(std::data(response_hash), response_hash.size());
20583 if (tag == TPM_ST_SESSIONS) {
20584 if (!authorization_delegate)
20585 return TRUNKS_RC_AUTHORIZATION_FAILED;
20586 if (!authorization_delegate->CheckResponseAuthorization(
20587 response_hash, authorization_section_bytes)) {
20588 return TRUNKS_RC_AUTHORIZATION_FAILED;
20589 }
20590 }
20591 return TPM_RC_SUCCESS;
20592 }
20593
PCR_SetAuthPolicyErrorCallback(Tpm::PCR_SetAuthPolicyResponse callback,TPM_RC response_code)20594 void PCR_SetAuthPolicyErrorCallback(Tpm::PCR_SetAuthPolicyResponse callback,
20595 TPM_RC response_code) {
20596 VLOG(1) << __func__;
20597 std::move(callback).Run(response_code);
20598 }
20599
PCR_SetAuthPolicyResponseParser(Tpm::PCR_SetAuthPolicyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20600 void PCR_SetAuthPolicyResponseParser(
20601 Tpm::PCR_SetAuthPolicyResponse callback,
20602 AuthorizationDelegate* authorization_delegate,
20603 const std::string& response) {
20604 VLOG(1) << __func__;
20605 TPM_RC rc =
20606 Tpm::ParseResponse_PCR_SetAuthPolicy(response, authorization_delegate);
20607 if (rc != TPM_RC_SUCCESS) {
20608 base::OnceCallback<void(TPM_RC)> error_reporter =
20609 base::BindOnce(PCR_SetAuthPolicyErrorCallback, std::move(callback));
20610 std::move(error_reporter).Run(rc);
20611 return;
20612 }
20613 std::move(callback).Run(rc);
20614 }
20615
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)20616 void Tpm::PCR_SetAuthPolicy(const TPMI_RH_PLATFORM& auth_handle,
20617 const std::string& auth_handle_name,
20618 const TPMI_DH_PCR& pcr_num,
20619 const std::string& pcr_num_name,
20620 const TPM2B_DIGEST& auth_policy,
20621 const TPMI_ALG_HASH& policy_digest,
20622 AuthorizationDelegate* authorization_delegate,
20623 PCR_SetAuthPolicyResponse callback) {
20624 VLOG(1) << __func__;
20625 std::string command;
20626 TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy(
20627 auth_handle, auth_handle_name, pcr_num, pcr_num_name, auth_policy,
20628 policy_digest, &command, authorization_delegate);
20629 if (rc != TPM_RC_SUCCESS) {
20630 base::OnceCallback<void(TPM_RC)> error_reporter =
20631 base::BindOnce(PCR_SetAuthPolicyErrorCallback, std::move(callback));
20632 std::move(error_reporter).Run(rc);
20633 return;
20634 }
20635 base::OnceCallback<void(const std::string&)> parser =
20636 base::BindOnce(PCR_SetAuthPolicyResponseParser, std::move(callback),
20637 authorization_delegate);
20638 transceiver_->SendCommand(command, std::move(parser));
20639 }
20640
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)20641 TPM_RC Tpm::PCR_SetAuthPolicySync(
20642 const TPMI_RH_PLATFORM& auth_handle,
20643 const std::string& auth_handle_name,
20644 const TPMI_DH_PCR& pcr_num,
20645 const std::string& pcr_num_name,
20646 const TPM2B_DIGEST& auth_policy,
20647 const TPMI_ALG_HASH& policy_digest,
20648 AuthorizationDelegate* authorization_delegate) {
20649 VLOG(1) << __func__;
20650 std::string command;
20651 TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy(
20652 auth_handle, auth_handle_name, pcr_num, pcr_num_name, auth_policy,
20653 policy_digest, &command, authorization_delegate);
20654 if (rc != TPM_RC_SUCCESS) {
20655 return rc;
20656 }
20657 std::string response = transceiver_->SendCommandAndWait(command);
20658 rc = ParseResponse_PCR_SetAuthPolicy(response, authorization_delegate);
20659 return rc;
20660 }
20661
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)20662 TPM_RC Tpm::SerializeCommand_PCR_SetAuthValue(
20663 const TPMI_DH_PCR& pcr_handle,
20664 const std::string& pcr_handle_name,
20665 const TPM2B_DIGEST& auth,
20666 std::string* serialized_command,
20667 AuthorizationDelegate* authorization_delegate) {
20668 VLOG(3) << __func__;
20669 TPM_RC rc = TPM_RC_SUCCESS;
20670 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20671 UINT32 command_size = 10; // Header size.
20672 std::string handle_section_bytes;
20673 std::string parameter_section_bytes;
20674 TPM_CC command_code = TPM_CC_PCR_SetAuthValue;
20675 bool is_command_parameter_encryption_possible = true;
20676 bool is_response_parameter_encryption_possible = false;
20677 std::string command_code_bytes;
20678 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20679 if (rc != TPM_RC_SUCCESS) {
20680 return rc;
20681 }
20682 std::string pcr_handle_bytes;
20683 rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
20684 if (rc != TPM_RC_SUCCESS) {
20685 return rc;
20686 }
20687 std::string auth_bytes;
20688 rc = Serialize_TPM2B_DIGEST(auth, &auth_bytes);
20689 if (rc != TPM_RC_SUCCESS) {
20690 return rc;
20691 }
20692 if (authorization_delegate) {
20693 // Encrypt just the parameter data, not the size.
20694 std::string tmp = auth_bytes.substr(2);
20695 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20696 return TRUNKS_RC_ENCRYPTION_FAILED;
20697 }
20698 auth_bytes.replace(2, std::string::npos, tmp);
20699 }
20700 std::unique_ptr<crypto::SecureHash> hash(
20701 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20702 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20703 hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
20704 handle_section_bytes += pcr_handle_bytes;
20705 command_size += pcr_handle_bytes.size();
20706 hash->Update(auth_bytes.data(), auth_bytes.size());
20707 parameter_section_bytes += auth_bytes;
20708 command_size += auth_bytes.size();
20709 std::string command_hash(32, 0);
20710 hash->Finish(std::data(command_hash), command_hash.size());
20711 std::string authorization_section_bytes;
20712 std::string authorization_size_bytes;
20713 if (authorization_delegate) {
20714 if (!authorization_delegate->GetCommandAuthorization(
20715 command_hash, is_command_parameter_encryption_possible,
20716 is_response_parameter_encryption_possible,
20717 &authorization_section_bytes)) {
20718 return TRUNKS_RC_AUTHORIZATION_FAILED;
20719 }
20720 if (!authorization_section_bytes.empty()) {
20721 tag = TPM_ST_SESSIONS;
20722 std::string tmp;
20723 rc = Serialize_UINT32(authorization_section_bytes.size(),
20724 &authorization_size_bytes);
20725 if (rc != TPM_RC_SUCCESS) {
20726 return rc;
20727 }
20728 command_size +=
20729 authorization_size_bytes.size() + authorization_section_bytes.size();
20730 }
20731 }
20732 std::string tag_bytes;
20733 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20734 if (rc != TPM_RC_SUCCESS) {
20735 return rc;
20736 }
20737 std::string command_size_bytes;
20738 rc = Serialize_UINT32(command_size, &command_size_bytes);
20739 if (rc != TPM_RC_SUCCESS) {
20740 return rc;
20741 }
20742 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20743 handle_section_bytes + authorization_size_bytes +
20744 authorization_section_bytes + parameter_section_bytes;
20745 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20746 VLOG(2) << "Command: "
20747 << base::HexEncode(serialized_command->data(),
20748 serialized_command->size());
20749 return TPM_RC_SUCCESS;
20750 }
20751
ParseResponse_PCR_SetAuthValue(const std::string & response,AuthorizationDelegate * authorization_delegate)20752 TPM_RC Tpm::ParseResponse_PCR_SetAuthValue(
20753 const std::string& response,
20754 AuthorizationDelegate* authorization_delegate) {
20755 VLOG(3) << __func__;
20756 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20757 TPM_RC rc = TPM_RC_SUCCESS;
20758 std::string buffer(response);
20759 TPM_ST tag;
20760 std::string tag_bytes;
20761 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20762 if (rc != TPM_RC_SUCCESS) {
20763 return rc;
20764 }
20765 UINT32 response_size;
20766 std::string response_size_bytes;
20767 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20768 if (rc != TPM_RC_SUCCESS) {
20769 return rc;
20770 }
20771 TPM_RC response_code;
20772 std::string response_code_bytes;
20773 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20774 if (rc != TPM_RC_SUCCESS) {
20775 return rc;
20776 }
20777 if (response_size != response.size()) {
20778 return TPM_RC_SIZE;
20779 }
20780 if (response_code != TPM_RC_SUCCESS) {
20781 return response_code;
20782 }
20783 TPM_CC command_code = TPM_CC_PCR_SetAuthValue;
20784 std::string command_code_bytes;
20785 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20786 if (rc != TPM_RC_SUCCESS) {
20787 return rc;
20788 }
20789 std::string authorization_section_bytes;
20790 if (tag == TPM_ST_SESSIONS) {
20791 UINT32 parameter_section_size = buffer.size();
20792 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
20793 if (rc != TPM_RC_SUCCESS) {
20794 return rc;
20795 }
20796 if (parameter_section_size > buffer.size()) {
20797 return TPM_RC_INSUFFICIENT;
20798 }
20799 authorization_section_bytes = buffer.substr(parameter_section_size);
20800 // Keep the parameter section in |buffer|.
20801 buffer.erase(parameter_section_size);
20802 }
20803 std::unique_ptr<crypto::SecureHash> hash(
20804 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20805 hash->Update(response_code_bytes.data(), response_code_bytes.size());
20806 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20807 hash->Update(buffer.data(), buffer.size());
20808 std::string response_hash(32, 0);
20809 hash->Finish(std::data(response_hash), response_hash.size());
20810 if (tag == TPM_ST_SESSIONS) {
20811 if (!authorization_delegate)
20812 return TRUNKS_RC_AUTHORIZATION_FAILED;
20813 if (!authorization_delegate->CheckResponseAuthorization(
20814 response_hash, authorization_section_bytes)) {
20815 return TRUNKS_RC_AUTHORIZATION_FAILED;
20816 }
20817 }
20818 return TPM_RC_SUCCESS;
20819 }
20820
PCR_SetAuthValueErrorCallback(Tpm::PCR_SetAuthValueResponse callback,TPM_RC response_code)20821 void PCR_SetAuthValueErrorCallback(Tpm::PCR_SetAuthValueResponse callback,
20822 TPM_RC response_code) {
20823 VLOG(1) << __func__;
20824 std::move(callback).Run(response_code);
20825 }
20826
PCR_SetAuthValueResponseParser(Tpm::PCR_SetAuthValueResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20827 void PCR_SetAuthValueResponseParser(
20828 Tpm::PCR_SetAuthValueResponse callback,
20829 AuthorizationDelegate* authorization_delegate,
20830 const std::string& response) {
20831 VLOG(1) << __func__;
20832 TPM_RC rc =
20833 Tpm::ParseResponse_PCR_SetAuthValue(response, authorization_delegate);
20834 if (rc != TPM_RC_SUCCESS) {
20835 base::OnceCallback<void(TPM_RC)> error_reporter =
20836 base::BindOnce(PCR_SetAuthValueErrorCallback, std::move(callback));
20837 std::move(error_reporter).Run(rc);
20838 return;
20839 }
20840 std::move(callback).Run(rc);
20841 }
20842
PCR_SetAuthValue(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,AuthorizationDelegate * authorization_delegate,PCR_SetAuthValueResponse callback)20843 void Tpm::PCR_SetAuthValue(const TPMI_DH_PCR& pcr_handle,
20844 const std::string& pcr_handle_name,
20845 const TPM2B_DIGEST& auth,
20846 AuthorizationDelegate* authorization_delegate,
20847 PCR_SetAuthValueResponse callback) {
20848 VLOG(1) << __func__;
20849 std::string command;
20850 TPM_RC rc = SerializeCommand_PCR_SetAuthValue(
20851 pcr_handle, pcr_handle_name, auth, &command, authorization_delegate);
20852 if (rc != TPM_RC_SUCCESS) {
20853 base::OnceCallback<void(TPM_RC)> error_reporter =
20854 base::BindOnce(PCR_SetAuthValueErrorCallback, std::move(callback));
20855 std::move(error_reporter).Run(rc);
20856 return;
20857 }
20858 base::OnceCallback<void(const std::string&)> parser =
20859 base::BindOnce(PCR_SetAuthValueResponseParser, std::move(callback),
20860 authorization_delegate);
20861 transceiver_->SendCommand(command, std::move(parser));
20862 }
20863
PCR_SetAuthValueSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,AuthorizationDelegate * authorization_delegate)20864 TPM_RC Tpm::PCR_SetAuthValueSync(
20865 const TPMI_DH_PCR& pcr_handle,
20866 const std::string& pcr_handle_name,
20867 const TPM2B_DIGEST& auth,
20868 AuthorizationDelegate* authorization_delegate) {
20869 VLOG(1) << __func__;
20870 std::string command;
20871 TPM_RC rc = SerializeCommand_PCR_SetAuthValue(
20872 pcr_handle, pcr_handle_name, auth, &command, authorization_delegate);
20873 if (rc != TPM_RC_SUCCESS) {
20874 return rc;
20875 }
20876 std::string response = transceiver_->SendCommandAndWait(command);
20877 rc = ParseResponse_PCR_SetAuthValue(response, authorization_delegate);
20878 return rc;
20879 }
20880
SerializeCommand_PCR_Reset(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20881 TPM_RC Tpm::SerializeCommand_PCR_Reset(
20882 const TPMI_DH_PCR& pcr_handle,
20883 const std::string& pcr_handle_name,
20884 std::string* serialized_command,
20885 AuthorizationDelegate* authorization_delegate) {
20886 VLOG(3) << __func__;
20887 TPM_RC rc = TPM_RC_SUCCESS;
20888 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20889 UINT32 command_size = 10; // Header size.
20890 std::string handle_section_bytes;
20891 std::string parameter_section_bytes;
20892 TPM_CC command_code = TPM_CC_PCR_Reset;
20893 bool is_command_parameter_encryption_possible = false;
20894 bool is_response_parameter_encryption_possible = false;
20895 std::string command_code_bytes;
20896 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20897 if (rc != TPM_RC_SUCCESS) {
20898 return rc;
20899 }
20900 std::string pcr_handle_bytes;
20901 rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
20902 if (rc != TPM_RC_SUCCESS) {
20903 return rc;
20904 }
20905 std::unique_ptr<crypto::SecureHash> hash(
20906 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20907 hash->Update(command_code_bytes.data(), command_code_bytes.size());
20908 hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
20909 handle_section_bytes += pcr_handle_bytes;
20910 command_size += pcr_handle_bytes.size();
20911 std::string command_hash(32, 0);
20912 hash->Finish(std::data(command_hash), command_hash.size());
20913 std::string authorization_section_bytes;
20914 std::string authorization_size_bytes;
20915 if (authorization_delegate) {
20916 if (!authorization_delegate->GetCommandAuthorization(
20917 command_hash, is_command_parameter_encryption_possible,
20918 is_response_parameter_encryption_possible,
20919 &authorization_section_bytes)) {
20920 return TRUNKS_RC_AUTHORIZATION_FAILED;
20921 }
20922 if (!authorization_section_bytes.empty()) {
20923 tag = TPM_ST_SESSIONS;
20924 std::string tmp;
20925 rc = Serialize_UINT32(authorization_section_bytes.size(),
20926 &authorization_size_bytes);
20927 if (rc != TPM_RC_SUCCESS) {
20928 return rc;
20929 }
20930 command_size +=
20931 authorization_size_bytes.size() + authorization_section_bytes.size();
20932 }
20933 }
20934 std::string tag_bytes;
20935 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20936 if (rc != TPM_RC_SUCCESS) {
20937 return rc;
20938 }
20939 std::string command_size_bytes;
20940 rc = Serialize_UINT32(command_size, &command_size_bytes);
20941 if (rc != TPM_RC_SUCCESS) {
20942 return rc;
20943 }
20944 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20945 handle_section_bytes + authorization_size_bytes +
20946 authorization_section_bytes + parameter_section_bytes;
20947 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20948 VLOG(2) << "Command: "
20949 << base::HexEncode(serialized_command->data(),
20950 serialized_command->size());
20951 return TPM_RC_SUCCESS;
20952 }
20953
ParseResponse_PCR_Reset(const std::string & response,AuthorizationDelegate * authorization_delegate)20954 TPM_RC Tpm::ParseResponse_PCR_Reset(
20955 const std::string& response,
20956 AuthorizationDelegate* authorization_delegate) {
20957 VLOG(3) << __func__;
20958 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20959 TPM_RC rc = TPM_RC_SUCCESS;
20960 std::string buffer(response);
20961 TPM_ST tag;
20962 std::string tag_bytes;
20963 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20964 if (rc != TPM_RC_SUCCESS) {
20965 return rc;
20966 }
20967 UINT32 response_size;
20968 std::string response_size_bytes;
20969 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20970 if (rc != TPM_RC_SUCCESS) {
20971 return rc;
20972 }
20973 TPM_RC response_code;
20974 std::string response_code_bytes;
20975 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20976 if (rc != TPM_RC_SUCCESS) {
20977 return rc;
20978 }
20979 if (response_size != response.size()) {
20980 return TPM_RC_SIZE;
20981 }
20982 if (response_code != TPM_RC_SUCCESS) {
20983 return response_code;
20984 }
20985 TPM_CC command_code = TPM_CC_PCR_Reset;
20986 std::string command_code_bytes;
20987 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20988 if (rc != TPM_RC_SUCCESS) {
20989 return rc;
20990 }
20991 std::string authorization_section_bytes;
20992 if (tag == TPM_ST_SESSIONS) {
20993 UINT32 parameter_section_size = buffer.size();
20994 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
20995 if (rc != TPM_RC_SUCCESS) {
20996 return rc;
20997 }
20998 if (parameter_section_size > buffer.size()) {
20999 return TPM_RC_INSUFFICIENT;
21000 }
21001 authorization_section_bytes = buffer.substr(parameter_section_size);
21002 // Keep the parameter section in |buffer|.
21003 buffer.erase(parameter_section_size);
21004 }
21005 std::unique_ptr<crypto::SecureHash> hash(
21006 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21007 hash->Update(response_code_bytes.data(), response_code_bytes.size());
21008 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21009 hash->Update(buffer.data(), buffer.size());
21010 std::string response_hash(32, 0);
21011 hash->Finish(std::data(response_hash), response_hash.size());
21012 if (tag == TPM_ST_SESSIONS) {
21013 if (!authorization_delegate)
21014 return TRUNKS_RC_AUTHORIZATION_FAILED;
21015 if (!authorization_delegate->CheckResponseAuthorization(
21016 response_hash, authorization_section_bytes)) {
21017 return TRUNKS_RC_AUTHORIZATION_FAILED;
21018 }
21019 }
21020 return TPM_RC_SUCCESS;
21021 }
21022
PCR_ResetErrorCallback(Tpm::PCR_ResetResponse callback,TPM_RC response_code)21023 void PCR_ResetErrorCallback(Tpm::PCR_ResetResponse callback,
21024 TPM_RC response_code) {
21025 VLOG(1) << __func__;
21026 std::move(callback).Run(response_code);
21027 }
21028
PCR_ResetResponseParser(Tpm::PCR_ResetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21029 void PCR_ResetResponseParser(Tpm::PCR_ResetResponse callback,
21030 AuthorizationDelegate* authorization_delegate,
21031 const std::string& response) {
21032 VLOG(1) << __func__;
21033 TPM_RC rc = Tpm::ParseResponse_PCR_Reset(response, authorization_delegate);
21034 if (rc != TPM_RC_SUCCESS) {
21035 base::OnceCallback<void(TPM_RC)> error_reporter =
21036 base::BindOnce(PCR_ResetErrorCallback, std::move(callback));
21037 std::move(error_reporter).Run(rc);
21038 return;
21039 }
21040 std::move(callback).Run(rc);
21041 }
21042
PCR_Reset(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,AuthorizationDelegate * authorization_delegate,PCR_ResetResponse callback)21043 void Tpm::PCR_Reset(const TPMI_DH_PCR& pcr_handle,
21044 const std::string& pcr_handle_name,
21045 AuthorizationDelegate* authorization_delegate,
21046 PCR_ResetResponse callback) {
21047 VLOG(1) << __func__;
21048 std::string command;
21049 TPM_RC rc = SerializeCommand_PCR_Reset(pcr_handle, pcr_handle_name, &command,
21050 authorization_delegate);
21051 if (rc != TPM_RC_SUCCESS) {
21052 base::OnceCallback<void(TPM_RC)> error_reporter =
21053 base::BindOnce(PCR_ResetErrorCallback, std::move(callback));
21054 std::move(error_reporter).Run(rc);
21055 return;
21056 }
21057 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21058 PCR_ResetResponseParser, std::move(callback), authorization_delegate);
21059 transceiver_->SendCommand(command, std::move(parser));
21060 }
21061
PCR_ResetSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,AuthorizationDelegate * authorization_delegate)21062 TPM_RC Tpm::PCR_ResetSync(const TPMI_DH_PCR& pcr_handle,
21063 const std::string& pcr_handle_name,
21064 AuthorizationDelegate* authorization_delegate) {
21065 VLOG(1) << __func__;
21066 std::string command;
21067 TPM_RC rc = SerializeCommand_PCR_Reset(pcr_handle, pcr_handle_name, &command,
21068 authorization_delegate);
21069 if (rc != TPM_RC_SUCCESS) {
21070 return rc;
21071 }
21072 std::string response = transceiver_->SendCommandAndWait(command);
21073 rc = ParseResponse_PCR_Reset(response, authorization_delegate);
21074 return rc;
21075 }
21076
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)21077 TPM_RC Tpm::SerializeCommand_PolicySigned(
21078 const TPMI_DH_OBJECT& auth_object,
21079 const std::string& auth_object_name,
21080 const TPMI_SH_POLICY& policy_session,
21081 const std::string& policy_session_name,
21082 const TPM2B_NONCE& nonce_tpm,
21083 const TPM2B_DIGEST& cp_hash_a,
21084 const TPM2B_NONCE& policy_ref,
21085 const INT32& expiration,
21086 const TPMT_SIGNATURE& auth,
21087 std::string* serialized_command,
21088 AuthorizationDelegate* authorization_delegate) {
21089 VLOG(3) << __func__;
21090 TPM_RC rc = TPM_RC_SUCCESS;
21091 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21092 UINT32 command_size = 10; // Header size.
21093 std::string handle_section_bytes;
21094 std::string parameter_section_bytes;
21095 TPM_CC command_code = TPM_CC_PolicySigned;
21096 bool is_command_parameter_encryption_possible = true;
21097 bool is_response_parameter_encryption_possible = true;
21098 std::string command_code_bytes;
21099 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21100 if (rc != TPM_RC_SUCCESS) {
21101 return rc;
21102 }
21103 std::string auth_object_bytes;
21104 rc = Serialize_TPMI_DH_OBJECT(auth_object, &auth_object_bytes);
21105 if (rc != TPM_RC_SUCCESS) {
21106 return rc;
21107 }
21108 std::string policy_session_bytes;
21109 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21110 if (rc != TPM_RC_SUCCESS) {
21111 return rc;
21112 }
21113 std::string nonce_tpm_bytes;
21114 rc = Serialize_TPM2B_NONCE(nonce_tpm, &nonce_tpm_bytes);
21115 if (rc != TPM_RC_SUCCESS) {
21116 return rc;
21117 }
21118 std::string cp_hash_a_bytes;
21119 rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21120 if (rc != TPM_RC_SUCCESS) {
21121 return rc;
21122 }
21123 std::string policy_ref_bytes;
21124 rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21125 if (rc != TPM_RC_SUCCESS) {
21126 return rc;
21127 }
21128 std::string expiration_bytes;
21129 rc = Serialize_INT32(expiration, &expiration_bytes);
21130 if (rc != TPM_RC_SUCCESS) {
21131 return rc;
21132 }
21133 std::string auth_bytes;
21134 rc = Serialize_TPMT_SIGNATURE(auth, &auth_bytes);
21135 if (rc != TPM_RC_SUCCESS) {
21136 return rc;
21137 }
21138 if (authorization_delegate) {
21139 // Encrypt just the parameter data, not the size.
21140 std::string tmp = nonce_tpm_bytes.substr(2);
21141 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21142 return TRUNKS_RC_ENCRYPTION_FAILED;
21143 }
21144 nonce_tpm_bytes.replace(2, std::string::npos, tmp);
21145 }
21146 std::unique_ptr<crypto::SecureHash> hash(
21147 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21148 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21149 hash->Update(auth_object_name.data(), auth_object_name.size());
21150 handle_section_bytes += auth_object_bytes;
21151 command_size += auth_object_bytes.size();
21152 hash->Update(policy_session_name.data(), policy_session_name.size());
21153 handle_section_bytes += policy_session_bytes;
21154 command_size += policy_session_bytes.size();
21155 hash->Update(nonce_tpm_bytes.data(), nonce_tpm_bytes.size());
21156 parameter_section_bytes += nonce_tpm_bytes;
21157 command_size += nonce_tpm_bytes.size();
21158 hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21159 parameter_section_bytes += cp_hash_a_bytes;
21160 command_size += cp_hash_a_bytes.size();
21161 hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21162 parameter_section_bytes += policy_ref_bytes;
21163 command_size += policy_ref_bytes.size();
21164 hash->Update(expiration_bytes.data(), expiration_bytes.size());
21165 parameter_section_bytes += expiration_bytes;
21166 command_size += expiration_bytes.size();
21167 hash->Update(auth_bytes.data(), auth_bytes.size());
21168 parameter_section_bytes += auth_bytes;
21169 command_size += auth_bytes.size();
21170 std::string command_hash(32, 0);
21171 hash->Finish(std::data(command_hash), command_hash.size());
21172 std::string authorization_section_bytes;
21173 std::string authorization_size_bytes;
21174 if (authorization_delegate) {
21175 if (!authorization_delegate->GetCommandAuthorization(
21176 command_hash, is_command_parameter_encryption_possible,
21177 is_response_parameter_encryption_possible,
21178 &authorization_section_bytes)) {
21179 return TRUNKS_RC_AUTHORIZATION_FAILED;
21180 }
21181 if (!authorization_section_bytes.empty()) {
21182 tag = TPM_ST_SESSIONS;
21183 std::string tmp;
21184 rc = Serialize_UINT32(authorization_section_bytes.size(),
21185 &authorization_size_bytes);
21186 if (rc != TPM_RC_SUCCESS) {
21187 return rc;
21188 }
21189 command_size +=
21190 authorization_size_bytes.size() + authorization_section_bytes.size();
21191 }
21192 }
21193 std::string tag_bytes;
21194 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21195 if (rc != TPM_RC_SUCCESS) {
21196 return rc;
21197 }
21198 std::string command_size_bytes;
21199 rc = Serialize_UINT32(command_size, &command_size_bytes);
21200 if (rc != TPM_RC_SUCCESS) {
21201 return rc;
21202 }
21203 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21204 handle_section_bytes + authorization_size_bytes +
21205 authorization_section_bytes + parameter_section_bytes;
21206 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21207 VLOG(2) << "Command: "
21208 << base::HexEncode(serialized_command->data(),
21209 serialized_command->size());
21210 return TPM_RC_SUCCESS;
21211 }
21212
ParseResponse_PolicySigned(const std::string & response,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21213 TPM_RC Tpm::ParseResponse_PolicySigned(
21214 const std::string& response,
21215 TPM2B_TIMEOUT* timeout,
21216 TPMT_TK_AUTH* policy_ticket,
21217 AuthorizationDelegate* authorization_delegate) {
21218 VLOG(3) << __func__;
21219 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21220 TPM_RC rc = TPM_RC_SUCCESS;
21221 std::string buffer(response);
21222 TPM_ST tag;
21223 std::string tag_bytes;
21224 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21225 if (rc != TPM_RC_SUCCESS) {
21226 return rc;
21227 }
21228 UINT32 response_size;
21229 std::string response_size_bytes;
21230 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21231 if (rc != TPM_RC_SUCCESS) {
21232 return rc;
21233 }
21234 TPM_RC response_code;
21235 std::string response_code_bytes;
21236 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21237 if (rc != TPM_RC_SUCCESS) {
21238 return rc;
21239 }
21240 if (response_size != response.size()) {
21241 return TPM_RC_SIZE;
21242 }
21243 if (response_code != TPM_RC_SUCCESS) {
21244 return response_code;
21245 }
21246 TPM_CC command_code = TPM_CC_PolicySigned;
21247 std::string command_code_bytes;
21248 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21249 if (rc != TPM_RC_SUCCESS) {
21250 return rc;
21251 }
21252 std::string authorization_section_bytes;
21253 if (tag == TPM_ST_SESSIONS) {
21254 UINT32 parameter_section_size = buffer.size();
21255 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
21256 if (rc != TPM_RC_SUCCESS) {
21257 return rc;
21258 }
21259 if (parameter_section_size > buffer.size()) {
21260 return TPM_RC_INSUFFICIENT;
21261 }
21262 authorization_section_bytes = buffer.substr(parameter_section_size);
21263 // Keep the parameter section in |buffer|.
21264 buffer.erase(parameter_section_size);
21265 }
21266 std::unique_ptr<crypto::SecureHash> hash(
21267 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21268 hash->Update(response_code_bytes.data(), response_code_bytes.size());
21269 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21270 hash->Update(buffer.data(), buffer.size());
21271 std::string response_hash(32, 0);
21272 hash->Finish(std::data(response_hash), response_hash.size());
21273 if (tag == TPM_ST_SESSIONS) {
21274 if (!authorization_delegate)
21275 return TRUNKS_RC_AUTHORIZATION_FAILED;
21276 if (!authorization_delegate->CheckResponseAuthorization(
21277 response_hash, authorization_section_bytes)) {
21278 return TRUNKS_RC_AUTHORIZATION_FAILED;
21279 }
21280 }
21281 if (tag == TPM_ST_SESSIONS) {
21282 if (!authorization_delegate)
21283 return TRUNKS_RC_AUTHORIZATION_FAILED;
21284
21285 // Parse the encrypted parameter size.
21286 UINT16 size;
21287 std::string size_buffer = buffer.substr(0, 2);
21288 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
21289 return result;
21290 }
21291 if (buffer.size() < 2 + size) {
21292 return TPM_RC_INSUFFICIENT;
21293 }
21294
21295 // Decrypt just the parameter data, not the size.
21296 std::string decrypted_data = buffer.substr(2, size);
21297 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
21298 return TRUNKS_RC_ENCRYPTION_FAILED;
21299 }
21300 buffer.replace(2, size, decrypted_data);
21301 }
21302 std::string timeout_bytes;
21303 rc = Parse_TPM2B_TIMEOUT(&buffer, timeout, &timeout_bytes);
21304 if (rc != TPM_RC_SUCCESS) {
21305 return rc;
21306 }
21307 std::string policy_ticket_bytes;
21308 rc = Parse_TPMT_TK_AUTH(&buffer, policy_ticket, &policy_ticket_bytes);
21309 if (rc != TPM_RC_SUCCESS) {
21310 return rc;
21311 }
21312 return TPM_RC_SUCCESS;
21313 }
21314
PolicySignedErrorCallback(Tpm::PolicySignedResponse callback,TPM_RC response_code)21315 void PolicySignedErrorCallback(Tpm::PolicySignedResponse callback,
21316 TPM_RC response_code) {
21317 VLOG(1) << __func__;
21318 std::move(callback).Run(response_code, TPM2B_TIMEOUT(), TPMT_TK_AUTH());
21319 }
21320
PolicySignedResponseParser(Tpm::PolicySignedResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21321 void PolicySignedResponseParser(Tpm::PolicySignedResponse callback,
21322 AuthorizationDelegate* authorization_delegate,
21323 const std::string& response) {
21324 VLOG(1) << __func__;
21325 TPM2B_TIMEOUT timeout;
21326 TPMT_TK_AUTH policy_ticket;
21327 TPM_RC rc = Tpm::ParseResponse_PolicySigned(
21328 response, &timeout, &policy_ticket, authorization_delegate);
21329 if (rc != TPM_RC_SUCCESS) {
21330 base::OnceCallback<void(TPM_RC)> error_reporter =
21331 base::BindOnce(PolicySignedErrorCallback, std::move(callback));
21332 std::move(error_reporter).Run(rc);
21333 return;
21334 }
21335 std::move(callback).Run(rc, timeout, policy_ticket);
21336 }
21337
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)21338 void Tpm::PolicySigned(const TPMI_DH_OBJECT& auth_object,
21339 const std::string& auth_object_name,
21340 const TPMI_SH_POLICY& policy_session,
21341 const std::string& policy_session_name,
21342 const TPM2B_NONCE& nonce_tpm,
21343 const TPM2B_DIGEST& cp_hash_a,
21344 const TPM2B_NONCE& policy_ref,
21345 const INT32& expiration,
21346 const TPMT_SIGNATURE& auth,
21347 AuthorizationDelegate* authorization_delegate,
21348 PolicySignedResponse callback) {
21349 VLOG(1) << __func__;
21350 std::string command;
21351 TPM_RC rc = SerializeCommand_PolicySigned(
21352 auth_object, auth_object_name, policy_session, policy_session_name,
21353 nonce_tpm, cp_hash_a, policy_ref, expiration, auth, &command,
21354 authorization_delegate);
21355 if (rc != TPM_RC_SUCCESS) {
21356 base::OnceCallback<void(TPM_RC)> error_reporter =
21357 base::BindOnce(PolicySignedErrorCallback, std::move(callback));
21358 std::move(error_reporter).Run(rc);
21359 return;
21360 }
21361 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21362 PolicySignedResponseParser, std::move(callback), authorization_delegate);
21363 transceiver_->SendCommand(command, std::move(parser));
21364 }
21365
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)21366 TPM_RC Tpm::PolicySignedSync(const TPMI_DH_OBJECT& auth_object,
21367 const std::string& auth_object_name,
21368 const TPMI_SH_POLICY& policy_session,
21369 const std::string& policy_session_name,
21370 const TPM2B_NONCE& nonce_tpm,
21371 const TPM2B_DIGEST& cp_hash_a,
21372 const TPM2B_NONCE& policy_ref,
21373 const INT32& expiration,
21374 const TPMT_SIGNATURE& auth,
21375 TPM2B_TIMEOUT* timeout,
21376 TPMT_TK_AUTH* policy_ticket,
21377 AuthorizationDelegate* authorization_delegate) {
21378 VLOG(1) << __func__;
21379 std::string command;
21380 TPM_RC rc = SerializeCommand_PolicySigned(
21381 auth_object, auth_object_name, policy_session, policy_session_name,
21382 nonce_tpm, cp_hash_a, policy_ref, expiration, auth, &command,
21383 authorization_delegate);
21384 if (rc != TPM_RC_SUCCESS) {
21385 return rc;
21386 }
21387 std::string response = transceiver_->SendCommandAndWait(command);
21388 rc = ParseResponse_PolicySigned(response, timeout, policy_ticket,
21389 authorization_delegate);
21390 return rc;
21391 }
21392
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)21393 TPM_RC Tpm::SerializeCommand_PolicySecret(
21394 const TPMI_DH_ENTITY& auth_handle,
21395 const std::string& auth_handle_name,
21396 const TPMI_SH_POLICY& policy_session,
21397 const std::string& policy_session_name,
21398 const TPM2B_NONCE& nonce_tpm,
21399 const TPM2B_DIGEST& cp_hash_a,
21400 const TPM2B_NONCE& policy_ref,
21401 const INT32& expiration,
21402 std::string* serialized_command,
21403 AuthorizationDelegate* authorization_delegate) {
21404 VLOG(3) << __func__;
21405 TPM_RC rc = TPM_RC_SUCCESS;
21406 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21407 UINT32 command_size = 10; // Header size.
21408 std::string handle_section_bytes;
21409 std::string parameter_section_bytes;
21410 TPM_CC command_code = TPM_CC_PolicySecret;
21411 bool is_command_parameter_encryption_possible = true;
21412 bool is_response_parameter_encryption_possible = true;
21413 std::string command_code_bytes;
21414 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21415 if (rc != TPM_RC_SUCCESS) {
21416 return rc;
21417 }
21418 std::string auth_handle_bytes;
21419 rc = Serialize_TPMI_DH_ENTITY(auth_handle, &auth_handle_bytes);
21420 if (rc != TPM_RC_SUCCESS) {
21421 return rc;
21422 }
21423 std::string policy_session_bytes;
21424 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21425 if (rc != TPM_RC_SUCCESS) {
21426 return rc;
21427 }
21428 std::string nonce_tpm_bytes;
21429 rc = Serialize_TPM2B_NONCE(nonce_tpm, &nonce_tpm_bytes);
21430 if (rc != TPM_RC_SUCCESS) {
21431 return rc;
21432 }
21433 std::string cp_hash_a_bytes;
21434 rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21435 if (rc != TPM_RC_SUCCESS) {
21436 return rc;
21437 }
21438 std::string policy_ref_bytes;
21439 rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21440 if (rc != TPM_RC_SUCCESS) {
21441 return rc;
21442 }
21443 std::string expiration_bytes;
21444 rc = Serialize_INT32(expiration, &expiration_bytes);
21445 if (rc != TPM_RC_SUCCESS) {
21446 return rc;
21447 }
21448 if (authorization_delegate) {
21449 // Encrypt just the parameter data, not the size.
21450 std::string tmp = nonce_tpm_bytes.substr(2);
21451 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21452 return TRUNKS_RC_ENCRYPTION_FAILED;
21453 }
21454 nonce_tpm_bytes.replace(2, std::string::npos, tmp);
21455 }
21456 std::unique_ptr<crypto::SecureHash> hash(
21457 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21458 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21459 hash->Update(auth_handle_name.data(), auth_handle_name.size());
21460 handle_section_bytes += auth_handle_bytes;
21461 command_size += auth_handle_bytes.size();
21462 hash->Update(policy_session_name.data(), policy_session_name.size());
21463 handle_section_bytes += policy_session_bytes;
21464 command_size += policy_session_bytes.size();
21465 hash->Update(nonce_tpm_bytes.data(), nonce_tpm_bytes.size());
21466 parameter_section_bytes += nonce_tpm_bytes;
21467 command_size += nonce_tpm_bytes.size();
21468 hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21469 parameter_section_bytes += cp_hash_a_bytes;
21470 command_size += cp_hash_a_bytes.size();
21471 hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21472 parameter_section_bytes += policy_ref_bytes;
21473 command_size += policy_ref_bytes.size();
21474 hash->Update(expiration_bytes.data(), expiration_bytes.size());
21475 parameter_section_bytes += expiration_bytes;
21476 command_size += expiration_bytes.size();
21477 std::string command_hash(32, 0);
21478 hash->Finish(std::data(command_hash), command_hash.size());
21479 std::string authorization_section_bytes;
21480 std::string authorization_size_bytes;
21481 if (authorization_delegate) {
21482 if (!authorization_delegate->GetCommandAuthorization(
21483 command_hash, is_command_parameter_encryption_possible,
21484 is_response_parameter_encryption_possible,
21485 &authorization_section_bytes)) {
21486 return TRUNKS_RC_AUTHORIZATION_FAILED;
21487 }
21488 if (!authorization_section_bytes.empty()) {
21489 tag = TPM_ST_SESSIONS;
21490 std::string tmp;
21491 rc = Serialize_UINT32(authorization_section_bytes.size(),
21492 &authorization_size_bytes);
21493 if (rc != TPM_RC_SUCCESS) {
21494 return rc;
21495 }
21496 command_size +=
21497 authorization_size_bytes.size() + authorization_section_bytes.size();
21498 }
21499 }
21500 std::string tag_bytes;
21501 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21502 if (rc != TPM_RC_SUCCESS) {
21503 return rc;
21504 }
21505 std::string command_size_bytes;
21506 rc = Serialize_UINT32(command_size, &command_size_bytes);
21507 if (rc != TPM_RC_SUCCESS) {
21508 return rc;
21509 }
21510 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21511 handle_section_bytes + authorization_size_bytes +
21512 authorization_section_bytes + parameter_section_bytes;
21513 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21514 VLOG(2) << "Command: "
21515 << base::HexEncode(serialized_command->data(),
21516 serialized_command->size());
21517 return TPM_RC_SUCCESS;
21518 }
21519
ParseResponse_PolicySecret(const std::string & response,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21520 TPM_RC Tpm::ParseResponse_PolicySecret(
21521 const std::string& response,
21522 TPM2B_TIMEOUT* timeout,
21523 TPMT_TK_AUTH* policy_ticket,
21524 AuthorizationDelegate* authorization_delegate) {
21525 VLOG(3) << __func__;
21526 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21527 TPM_RC rc = TPM_RC_SUCCESS;
21528 std::string buffer(response);
21529 TPM_ST tag;
21530 std::string tag_bytes;
21531 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21532 if (rc != TPM_RC_SUCCESS) {
21533 return rc;
21534 }
21535 UINT32 response_size;
21536 std::string response_size_bytes;
21537 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21538 if (rc != TPM_RC_SUCCESS) {
21539 return rc;
21540 }
21541 TPM_RC response_code;
21542 std::string response_code_bytes;
21543 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21544 if (rc != TPM_RC_SUCCESS) {
21545 return rc;
21546 }
21547 if (response_size != response.size()) {
21548 return TPM_RC_SIZE;
21549 }
21550 if (response_code != TPM_RC_SUCCESS) {
21551 return response_code;
21552 }
21553 TPM_CC command_code = TPM_CC_PolicySecret;
21554 std::string command_code_bytes;
21555 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21556 if (rc != TPM_RC_SUCCESS) {
21557 return rc;
21558 }
21559 std::string authorization_section_bytes;
21560 if (tag == TPM_ST_SESSIONS) {
21561 UINT32 parameter_section_size = buffer.size();
21562 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
21563 if (rc != TPM_RC_SUCCESS) {
21564 return rc;
21565 }
21566 if (parameter_section_size > buffer.size()) {
21567 return TPM_RC_INSUFFICIENT;
21568 }
21569 authorization_section_bytes = buffer.substr(parameter_section_size);
21570 // Keep the parameter section in |buffer|.
21571 buffer.erase(parameter_section_size);
21572 }
21573 std::unique_ptr<crypto::SecureHash> hash(
21574 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21575 hash->Update(response_code_bytes.data(), response_code_bytes.size());
21576 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21577 hash->Update(buffer.data(), buffer.size());
21578 std::string response_hash(32, 0);
21579 hash->Finish(std::data(response_hash), response_hash.size());
21580 if (tag == TPM_ST_SESSIONS) {
21581 if (!authorization_delegate)
21582 return TRUNKS_RC_AUTHORIZATION_FAILED;
21583 if (!authorization_delegate->CheckResponseAuthorization(
21584 response_hash, authorization_section_bytes)) {
21585 return TRUNKS_RC_AUTHORIZATION_FAILED;
21586 }
21587 }
21588 if (tag == TPM_ST_SESSIONS) {
21589 if (!authorization_delegate)
21590 return TRUNKS_RC_AUTHORIZATION_FAILED;
21591
21592 // Parse the encrypted parameter size.
21593 UINT16 size;
21594 std::string size_buffer = buffer.substr(0, 2);
21595 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
21596 return result;
21597 }
21598 if (buffer.size() < 2 + size) {
21599 return TPM_RC_INSUFFICIENT;
21600 }
21601
21602 // Decrypt just the parameter data, not the size.
21603 std::string decrypted_data = buffer.substr(2, size);
21604 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
21605 return TRUNKS_RC_ENCRYPTION_FAILED;
21606 }
21607 buffer.replace(2, size, decrypted_data);
21608 }
21609 std::string timeout_bytes;
21610 rc = Parse_TPM2B_TIMEOUT(&buffer, timeout, &timeout_bytes);
21611 if (rc != TPM_RC_SUCCESS) {
21612 return rc;
21613 }
21614 std::string policy_ticket_bytes;
21615 rc = Parse_TPMT_TK_AUTH(&buffer, policy_ticket, &policy_ticket_bytes);
21616 if (rc != TPM_RC_SUCCESS) {
21617 return rc;
21618 }
21619 return TPM_RC_SUCCESS;
21620 }
21621
PolicySecretErrorCallback(Tpm::PolicySecretResponse callback,TPM_RC response_code)21622 void PolicySecretErrorCallback(Tpm::PolicySecretResponse callback,
21623 TPM_RC response_code) {
21624 VLOG(1) << __func__;
21625 std::move(callback).Run(response_code, TPM2B_TIMEOUT(), TPMT_TK_AUTH());
21626 }
21627
PolicySecretResponseParser(Tpm::PolicySecretResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21628 void PolicySecretResponseParser(Tpm::PolicySecretResponse callback,
21629 AuthorizationDelegate* authorization_delegate,
21630 const std::string& response) {
21631 VLOG(1) << __func__;
21632 TPM2B_TIMEOUT timeout;
21633 TPMT_TK_AUTH policy_ticket;
21634 TPM_RC rc = Tpm::ParseResponse_PolicySecret(
21635 response, &timeout, &policy_ticket, authorization_delegate);
21636 if (rc != TPM_RC_SUCCESS) {
21637 base::OnceCallback<void(TPM_RC)> error_reporter =
21638 base::BindOnce(PolicySecretErrorCallback, std::move(callback));
21639 std::move(error_reporter).Run(rc);
21640 return;
21641 }
21642 std::move(callback).Run(rc, timeout, policy_ticket);
21643 }
21644
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)21645 void Tpm::PolicySecret(const TPMI_DH_ENTITY& auth_handle,
21646 const std::string& auth_handle_name,
21647 const TPMI_SH_POLICY& policy_session,
21648 const std::string& policy_session_name,
21649 const TPM2B_NONCE& nonce_tpm,
21650 const TPM2B_DIGEST& cp_hash_a,
21651 const TPM2B_NONCE& policy_ref,
21652 const INT32& expiration,
21653 AuthorizationDelegate* authorization_delegate,
21654 PolicySecretResponse callback) {
21655 VLOG(1) << __func__;
21656 std::string command;
21657 TPM_RC rc = SerializeCommand_PolicySecret(
21658 auth_handle, auth_handle_name, policy_session, policy_session_name,
21659 nonce_tpm, cp_hash_a, policy_ref, expiration, &command,
21660 authorization_delegate);
21661 if (rc != TPM_RC_SUCCESS) {
21662 base::OnceCallback<void(TPM_RC)> error_reporter =
21663 base::BindOnce(PolicySecretErrorCallback, std::move(callback));
21664 std::move(error_reporter).Run(rc);
21665 return;
21666 }
21667 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21668 PolicySecretResponseParser, std::move(callback), authorization_delegate);
21669 transceiver_->SendCommand(command, std::move(parser));
21670 }
21671
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)21672 TPM_RC Tpm::PolicySecretSync(const TPMI_DH_ENTITY& auth_handle,
21673 const std::string& auth_handle_name,
21674 const TPMI_SH_POLICY& policy_session,
21675 const std::string& policy_session_name,
21676 const TPM2B_NONCE& nonce_tpm,
21677 const TPM2B_DIGEST& cp_hash_a,
21678 const TPM2B_NONCE& policy_ref,
21679 const INT32& expiration,
21680 TPM2B_TIMEOUT* timeout,
21681 TPMT_TK_AUTH* policy_ticket,
21682 AuthorizationDelegate* authorization_delegate) {
21683 VLOG(1) << __func__;
21684 std::string command;
21685 TPM_RC rc = SerializeCommand_PolicySecret(
21686 auth_handle, auth_handle_name, policy_session, policy_session_name,
21687 nonce_tpm, cp_hash_a, policy_ref, expiration, &command,
21688 authorization_delegate);
21689 if (rc != TPM_RC_SUCCESS) {
21690 return rc;
21691 }
21692 std::string response = transceiver_->SendCommandAndWait(command);
21693 rc = ParseResponse_PolicySecret(response, timeout, policy_ticket,
21694 authorization_delegate);
21695 return rc;
21696 }
21697
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)21698 TPM_RC Tpm::SerializeCommand_PolicyTicket(
21699 const TPMI_SH_POLICY& policy_session,
21700 const std::string& policy_session_name,
21701 const TPM2B_TIMEOUT& timeout,
21702 const TPM2B_DIGEST& cp_hash_a,
21703 const TPM2B_NONCE& policy_ref,
21704 const TPM2B_NAME& auth_name,
21705 const TPMT_TK_AUTH& ticket,
21706 std::string* serialized_command,
21707 AuthorizationDelegate* authorization_delegate) {
21708 VLOG(3) << __func__;
21709 TPM_RC rc = TPM_RC_SUCCESS;
21710 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21711 UINT32 command_size = 10; // Header size.
21712 std::string handle_section_bytes;
21713 std::string parameter_section_bytes;
21714 TPM_CC command_code = TPM_CC_PolicyTicket;
21715 bool is_command_parameter_encryption_possible = true;
21716 bool is_response_parameter_encryption_possible = false;
21717 std::string command_code_bytes;
21718 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21719 if (rc != TPM_RC_SUCCESS) {
21720 return rc;
21721 }
21722 std::string policy_session_bytes;
21723 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21724 if (rc != TPM_RC_SUCCESS) {
21725 return rc;
21726 }
21727 std::string timeout_bytes;
21728 rc = Serialize_TPM2B_TIMEOUT(timeout, &timeout_bytes);
21729 if (rc != TPM_RC_SUCCESS) {
21730 return rc;
21731 }
21732 std::string cp_hash_a_bytes;
21733 rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21734 if (rc != TPM_RC_SUCCESS) {
21735 return rc;
21736 }
21737 std::string policy_ref_bytes;
21738 rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21739 if (rc != TPM_RC_SUCCESS) {
21740 return rc;
21741 }
21742 std::string auth_name_bytes;
21743 rc = Serialize_TPM2B_NAME(auth_name, &auth_name_bytes);
21744 if (rc != TPM_RC_SUCCESS) {
21745 return rc;
21746 }
21747 std::string ticket_bytes;
21748 rc = Serialize_TPMT_TK_AUTH(ticket, &ticket_bytes);
21749 if (rc != TPM_RC_SUCCESS) {
21750 return rc;
21751 }
21752 if (authorization_delegate) {
21753 // Encrypt just the parameter data, not the size.
21754 std::string tmp = timeout_bytes.substr(2);
21755 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21756 return TRUNKS_RC_ENCRYPTION_FAILED;
21757 }
21758 timeout_bytes.replace(2, std::string::npos, tmp);
21759 }
21760 std::unique_ptr<crypto::SecureHash> hash(
21761 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21762 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21763 hash->Update(policy_session_name.data(), policy_session_name.size());
21764 handle_section_bytes += policy_session_bytes;
21765 command_size += policy_session_bytes.size();
21766 hash->Update(timeout_bytes.data(), timeout_bytes.size());
21767 parameter_section_bytes += timeout_bytes;
21768 command_size += timeout_bytes.size();
21769 hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21770 parameter_section_bytes += cp_hash_a_bytes;
21771 command_size += cp_hash_a_bytes.size();
21772 hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21773 parameter_section_bytes += policy_ref_bytes;
21774 command_size += policy_ref_bytes.size();
21775 hash->Update(auth_name_bytes.data(), auth_name_bytes.size());
21776 parameter_section_bytes += auth_name_bytes;
21777 command_size += auth_name_bytes.size();
21778 hash->Update(ticket_bytes.data(), ticket_bytes.size());
21779 parameter_section_bytes += ticket_bytes;
21780 command_size += ticket_bytes.size();
21781 std::string command_hash(32, 0);
21782 hash->Finish(std::data(command_hash), command_hash.size());
21783 std::string authorization_section_bytes;
21784 std::string authorization_size_bytes;
21785 if (authorization_delegate) {
21786 if (!authorization_delegate->GetCommandAuthorization(
21787 command_hash, is_command_parameter_encryption_possible,
21788 is_response_parameter_encryption_possible,
21789 &authorization_section_bytes)) {
21790 return TRUNKS_RC_AUTHORIZATION_FAILED;
21791 }
21792 if (!authorization_section_bytes.empty()) {
21793 tag = TPM_ST_SESSIONS;
21794 std::string tmp;
21795 rc = Serialize_UINT32(authorization_section_bytes.size(),
21796 &authorization_size_bytes);
21797 if (rc != TPM_RC_SUCCESS) {
21798 return rc;
21799 }
21800 command_size +=
21801 authorization_size_bytes.size() + authorization_section_bytes.size();
21802 }
21803 }
21804 std::string tag_bytes;
21805 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21806 if (rc != TPM_RC_SUCCESS) {
21807 return rc;
21808 }
21809 std::string command_size_bytes;
21810 rc = Serialize_UINT32(command_size, &command_size_bytes);
21811 if (rc != TPM_RC_SUCCESS) {
21812 return rc;
21813 }
21814 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21815 handle_section_bytes + authorization_size_bytes +
21816 authorization_section_bytes + parameter_section_bytes;
21817 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21818 VLOG(2) << "Command: "
21819 << base::HexEncode(serialized_command->data(),
21820 serialized_command->size());
21821 return TPM_RC_SUCCESS;
21822 }
21823
ParseResponse_PolicyTicket(const std::string & response,AuthorizationDelegate * authorization_delegate)21824 TPM_RC Tpm::ParseResponse_PolicyTicket(
21825 const std::string& response,
21826 AuthorizationDelegate* authorization_delegate) {
21827 VLOG(3) << __func__;
21828 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21829 TPM_RC rc = TPM_RC_SUCCESS;
21830 std::string buffer(response);
21831 TPM_ST tag;
21832 std::string tag_bytes;
21833 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21834 if (rc != TPM_RC_SUCCESS) {
21835 return rc;
21836 }
21837 UINT32 response_size;
21838 std::string response_size_bytes;
21839 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21840 if (rc != TPM_RC_SUCCESS) {
21841 return rc;
21842 }
21843 TPM_RC response_code;
21844 std::string response_code_bytes;
21845 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21846 if (rc != TPM_RC_SUCCESS) {
21847 return rc;
21848 }
21849 if (response_size != response.size()) {
21850 return TPM_RC_SIZE;
21851 }
21852 if (response_code != TPM_RC_SUCCESS) {
21853 return response_code;
21854 }
21855 TPM_CC command_code = TPM_CC_PolicyTicket;
21856 std::string command_code_bytes;
21857 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21858 if (rc != TPM_RC_SUCCESS) {
21859 return rc;
21860 }
21861 std::string authorization_section_bytes;
21862 if (tag == TPM_ST_SESSIONS) {
21863 UINT32 parameter_section_size = buffer.size();
21864 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
21865 if (rc != TPM_RC_SUCCESS) {
21866 return rc;
21867 }
21868 if (parameter_section_size > buffer.size()) {
21869 return TPM_RC_INSUFFICIENT;
21870 }
21871 authorization_section_bytes = buffer.substr(parameter_section_size);
21872 // Keep the parameter section in |buffer|.
21873 buffer.erase(parameter_section_size);
21874 }
21875 std::unique_ptr<crypto::SecureHash> hash(
21876 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21877 hash->Update(response_code_bytes.data(), response_code_bytes.size());
21878 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21879 hash->Update(buffer.data(), buffer.size());
21880 std::string response_hash(32, 0);
21881 hash->Finish(std::data(response_hash), response_hash.size());
21882 if (tag == TPM_ST_SESSIONS) {
21883 if (!authorization_delegate)
21884 return TRUNKS_RC_AUTHORIZATION_FAILED;
21885 if (!authorization_delegate->CheckResponseAuthorization(
21886 response_hash, authorization_section_bytes)) {
21887 return TRUNKS_RC_AUTHORIZATION_FAILED;
21888 }
21889 }
21890 return TPM_RC_SUCCESS;
21891 }
21892
PolicyTicketErrorCallback(Tpm::PolicyTicketResponse callback,TPM_RC response_code)21893 void PolicyTicketErrorCallback(Tpm::PolicyTicketResponse callback,
21894 TPM_RC response_code) {
21895 VLOG(1) << __func__;
21896 std::move(callback).Run(response_code);
21897 }
21898
PolicyTicketResponseParser(Tpm::PolicyTicketResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21899 void PolicyTicketResponseParser(Tpm::PolicyTicketResponse callback,
21900 AuthorizationDelegate* authorization_delegate,
21901 const std::string& response) {
21902 VLOG(1) << __func__;
21903 TPM_RC rc = Tpm::ParseResponse_PolicyTicket(response, authorization_delegate);
21904 if (rc != TPM_RC_SUCCESS) {
21905 base::OnceCallback<void(TPM_RC)> error_reporter =
21906 base::BindOnce(PolicyTicketErrorCallback, std::move(callback));
21907 std::move(error_reporter).Run(rc);
21908 return;
21909 }
21910 std::move(callback).Run(rc);
21911 }
21912
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)21913 void Tpm::PolicyTicket(const TPMI_SH_POLICY& policy_session,
21914 const std::string& policy_session_name,
21915 const TPM2B_TIMEOUT& timeout,
21916 const TPM2B_DIGEST& cp_hash_a,
21917 const TPM2B_NONCE& policy_ref,
21918 const TPM2B_NAME& auth_name,
21919 const TPMT_TK_AUTH& ticket,
21920 AuthorizationDelegate* authorization_delegate,
21921 PolicyTicketResponse callback) {
21922 VLOG(1) << __func__;
21923 std::string command;
21924 TPM_RC rc = SerializeCommand_PolicyTicket(
21925 policy_session, policy_session_name, timeout, cp_hash_a, policy_ref,
21926 auth_name, ticket, &command, authorization_delegate);
21927 if (rc != TPM_RC_SUCCESS) {
21928 base::OnceCallback<void(TPM_RC)> error_reporter =
21929 base::BindOnce(PolicyTicketErrorCallback, std::move(callback));
21930 std::move(error_reporter).Run(rc);
21931 return;
21932 }
21933 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21934 PolicyTicketResponseParser, std::move(callback), authorization_delegate);
21935 transceiver_->SendCommand(command, std::move(parser));
21936 }
21937
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)21938 TPM_RC Tpm::PolicyTicketSync(const TPMI_SH_POLICY& policy_session,
21939 const std::string& policy_session_name,
21940 const TPM2B_TIMEOUT& timeout,
21941 const TPM2B_DIGEST& cp_hash_a,
21942 const TPM2B_NONCE& policy_ref,
21943 const TPM2B_NAME& auth_name,
21944 const TPMT_TK_AUTH& ticket,
21945 AuthorizationDelegate* authorization_delegate) {
21946 VLOG(1) << __func__;
21947 std::string command;
21948 TPM_RC rc = SerializeCommand_PolicyTicket(
21949 policy_session, policy_session_name, timeout, cp_hash_a, policy_ref,
21950 auth_name, ticket, &command, authorization_delegate);
21951 if (rc != TPM_RC_SUCCESS) {
21952 return rc;
21953 }
21954 std::string response = transceiver_->SendCommandAndWait(command);
21955 rc = ParseResponse_PolicyTicket(response, authorization_delegate);
21956 return rc;
21957 }
21958
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)21959 TPM_RC Tpm::SerializeCommand_PolicyOR(
21960 const TPMI_SH_POLICY& policy_session,
21961 const std::string& policy_session_name,
21962 const TPML_DIGEST& p_hash_list,
21963 std::string* serialized_command,
21964 AuthorizationDelegate* authorization_delegate) {
21965 VLOG(3) << __func__;
21966 TPM_RC rc = TPM_RC_SUCCESS;
21967 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21968 UINT32 command_size = 10; // Header size.
21969 std::string handle_section_bytes;
21970 std::string parameter_section_bytes;
21971 TPM_CC command_code = TPM_CC_PolicyOR;
21972 bool is_command_parameter_encryption_possible = false;
21973 bool is_response_parameter_encryption_possible = false;
21974 std::string command_code_bytes;
21975 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21976 if (rc != TPM_RC_SUCCESS) {
21977 return rc;
21978 }
21979 std::string policy_session_bytes;
21980 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21981 if (rc != TPM_RC_SUCCESS) {
21982 return rc;
21983 }
21984 std::string p_hash_list_bytes;
21985 rc = Serialize_TPML_DIGEST(p_hash_list, &p_hash_list_bytes);
21986 if (rc != TPM_RC_SUCCESS) {
21987 return rc;
21988 }
21989 std::unique_ptr<crypto::SecureHash> hash(
21990 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21991 hash->Update(command_code_bytes.data(), command_code_bytes.size());
21992 hash->Update(policy_session_name.data(), policy_session_name.size());
21993 handle_section_bytes += policy_session_bytes;
21994 command_size += policy_session_bytes.size();
21995 hash->Update(p_hash_list_bytes.data(), p_hash_list_bytes.size());
21996 parameter_section_bytes += p_hash_list_bytes;
21997 command_size += p_hash_list_bytes.size();
21998 std::string command_hash(32, 0);
21999 hash->Finish(std::data(command_hash), command_hash.size());
22000 std::string authorization_section_bytes;
22001 std::string authorization_size_bytes;
22002 if (authorization_delegate) {
22003 if (!authorization_delegate->GetCommandAuthorization(
22004 command_hash, is_command_parameter_encryption_possible,
22005 is_response_parameter_encryption_possible,
22006 &authorization_section_bytes)) {
22007 return TRUNKS_RC_AUTHORIZATION_FAILED;
22008 }
22009 if (!authorization_section_bytes.empty()) {
22010 tag = TPM_ST_SESSIONS;
22011 std::string tmp;
22012 rc = Serialize_UINT32(authorization_section_bytes.size(),
22013 &authorization_size_bytes);
22014 if (rc != TPM_RC_SUCCESS) {
22015 return rc;
22016 }
22017 command_size +=
22018 authorization_size_bytes.size() + authorization_section_bytes.size();
22019 }
22020 }
22021 std::string tag_bytes;
22022 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22023 if (rc != TPM_RC_SUCCESS) {
22024 return rc;
22025 }
22026 std::string command_size_bytes;
22027 rc = Serialize_UINT32(command_size, &command_size_bytes);
22028 if (rc != TPM_RC_SUCCESS) {
22029 return rc;
22030 }
22031 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22032 handle_section_bytes + authorization_size_bytes +
22033 authorization_section_bytes + parameter_section_bytes;
22034 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22035 VLOG(2) << "Command: "
22036 << base::HexEncode(serialized_command->data(),
22037 serialized_command->size());
22038 return TPM_RC_SUCCESS;
22039 }
22040
ParseResponse_PolicyOR(const std::string & response,AuthorizationDelegate * authorization_delegate)22041 TPM_RC Tpm::ParseResponse_PolicyOR(
22042 const std::string& response,
22043 AuthorizationDelegate* authorization_delegate) {
22044 VLOG(3) << __func__;
22045 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22046 TPM_RC rc = TPM_RC_SUCCESS;
22047 std::string buffer(response);
22048 TPM_ST tag;
22049 std::string tag_bytes;
22050 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22051 if (rc != TPM_RC_SUCCESS) {
22052 return rc;
22053 }
22054 UINT32 response_size;
22055 std::string response_size_bytes;
22056 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22057 if (rc != TPM_RC_SUCCESS) {
22058 return rc;
22059 }
22060 TPM_RC response_code;
22061 std::string response_code_bytes;
22062 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22063 if (rc != TPM_RC_SUCCESS) {
22064 return rc;
22065 }
22066 if (response_size != response.size()) {
22067 return TPM_RC_SIZE;
22068 }
22069 if (response_code != TPM_RC_SUCCESS) {
22070 return response_code;
22071 }
22072 TPM_CC command_code = TPM_CC_PolicyOR;
22073 std::string command_code_bytes;
22074 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22075 if (rc != TPM_RC_SUCCESS) {
22076 return rc;
22077 }
22078 std::string authorization_section_bytes;
22079 if (tag == TPM_ST_SESSIONS) {
22080 UINT32 parameter_section_size = buffer.size();
22081 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
22082 if (rc != TPM_RC_SUCCESS) {
22083 return rc;
22084 }
22085 if (parameter_section_size > buffer.size()) {
22086 return TPM_RC_INSUFFICIENT;
22087 }
22088 authorization_section_bytes = buffer.substr(parameter_section_size);
22089 // Keep the parameter section in |buffer|.
22090 buffer.erase(parameter_section_size);
22091 }
22092 std::unique_ptr<crypto::SecureHash> hash(
22093 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22094 hash->Update(response_code_bytes.data(), response_code_bytes.size());
22095 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22096 hash->Update(buffer.data(), buffer.size());
22097 std::string response_hash(32, 0);
22098 hash->Finish(std::data(response_hash), response_hash.size());
22099 if (tag == TPM_ST_SESSIONS) {
22100 if (!authorization_delegate)
22101 return TRUNKS_RC_AUTHORIZATION_FAILED;
22102 if (!authorization_delegate->CheckResponseAuthorization(
22103 response_hash, authorization_section_bytes)) {
22104 return TRUNKS_RC_AUTHORIZATION_FAILED;
22105 }
22106 }
22107 return TPM_RC_SUCCESS;
22108 }
22109
PolicyORErrorCallback(Tpm::PolicyORResponse callback,TPM_RC response_code)22110 void PolicyORErrorCallback(Tpm::PolicyORResponse callback,
22111 TPM_RC response_code) {
22112 VLOG(1) << __func__;
22113 std::move(callback).Run(response_code);
22114 }
22115
PolicyORResponseParser(Tpm::PolicyORResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22116 void PolicyORResponseParser(Tpm::PolicyORResponse callback,
22117 AuthorizationDelegate* authorization_delegate,
22118 const std::string& response) {
22119 VLOG(1) << __func__;
22120 TPM_RC rc = Tpm::ParseResponse_PolicyOR(response, authorization_delegate);
22121 if (rc != TPM_RC_SUCCESS) {
22122 base::OnceCallback<void(TPM_RC)> error_reporter =
22123 base::BindOnce(PolicyORErrorCallback, std::move(callback));
22124 std::move(error_reporter).Run(rc);
22125 return;
22126 }
22127 std::move(callback).Run(rc);
22128 }
22129
PolicyOR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,AuthorizationDelegate * authorization_delegate,PolicyORResponse callback)22130 void Tpm::PolicyOR(const TPMI_SH_POLICY& policy_session,
22131 const std::string& policy_session_name,
22132 const TPML_DIGEST& p_hash_list,
22133 AuthorizationDelegate* authorization_delegate,
22134 PolicyORResponse callback) {
22135 VLOG(1) << __func__;
22136 std::string command;
22137 TPM_RC rc =
22138 SerializeCommand_PolicyOR(policy_session, policy_session_name,
22139 p_hash_list, &command, authorization_delegate);
22140 if (rc != TPM_RC_SUCCESS) {
22141 base::OnceCallback<void(TPM_RC)> error_reporter =
22142 base::BindOnce(PolicyORErrorCallback, std::move(callback));
22143 std::move(error_reporter).Run(rc);
22144 return;
22145 }
22146 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22147 PolicyORResponseParser, std::move(callback), authorization_delegate);
22148 transceiver_->SendCommand(command, std::move(parser));
22149 }
22150
PolicyORSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,AuthorizationDelegate * authorization_delegate)22151 TPM_RC Tpm::PolicyORSync(const TPMI_SH_POLICY& policy_session,
22152 const std::string& policy_session_name,
22153 const TPML_DIGEST& p_hash_list,
22154 AuthorizationDelegate* authorization_delegate) {
22155 VLOG(1) << __func__;
22156 std::string command;
22157 TPM_RC rc =
22158 SerializeCommand_PolicyOR(policy_session, policy_session_name,
22159 p_hash_list, &command, authorization_delegate);
22160 if (rc != TPM_RC_SUCCESS) {
22161 return rc;
22162 }
22163 std::string response = transceiver_->SendCommandAndWait(command);
22164 rc = ParseResponse_PolicyOR(response, authorization_delegate);
22165 return rc;
22166 }
22167
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)22168 TPM_RC Tpm::SerializeCommand_PolicyPCR(
22169 const TPMI_SH_POLICY& policy_session,
22170 const std::string& policy_session_name,
22171 const TPM2B_DIGEST& pcr_digest,
22172 const TPML_PCR_SELECTION& pcrs,
22173 std::string* serialized_command,
22174 AuthorizationDelegate* authorization_delegate) {
22175 VLOG(3) << __func__;
22176 TPM_RC rc = TPM_RC_SUCCESS;
22177 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22178 UINT32 command_size = 10; // Header size.
22179 std::string handle_section_bytes;
22180 std::string parameter_section_bytes;
22181 TPM_CC command_code = TPM_CC_PolicyPCR;
22182 bool is_command_parameter_encryption_possible = true;
22183 bool is_response_parameter_encryption_possible = false;
22184 std::string command_code_bytes;
22185 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22186 if (rc != TPM_RC_SUCCESS) {
22187 return rc;
22188 }
22189 std::string policy_session_bytes;
22190 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22191 if (rc != TPM_RC_SUCCESS) {
22192 return rc;
22193 }
22194 std::string pcr_digest_bytes;
22195 rc = Serialize_TPM2B_DIGEST(pcr_digest, &pcr_digest_bytes);
22196 if (rc != TPM_RC_SUCCESS) {
22197 return rc;
22198 }
22199 std::string pcrs_bytes;
22200 rc = Serialize_TPML_PCR_SELECTION(pcrs, &pcrs_bytes);
22201 if (rc != TPM_RC_SUCCESS) {
22202 return rc;
22203 }
22204 if (authorization_delegate) {
22205 // Encrypt just the parameter data, not the size.
22206 std::string tmp = pcr_digest_bytes.substr(2);
22207 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22208 return TRUNKS_RC_ENCRYPTION_FAILED;
22209 }
22210 pcr_digest_bytes.replace(2, std::string::npos, tmp);
22211 }
22212 std::unique_ptr<crypto::SecureHash> hash(
22213 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22214 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22215 hash->Update(policy_session_name.data(), policy_session_name.size());
22216 handle_section_bytes += policy_session_bytes;
22217 command_size += policy_session_bytes.size();
22218 hash->Update(pcr_digest_bytes.data(), pcr_digest_bytes.size());
22219 parameter_section_bytes += pcr_digest_bytes;
22220 command_size += pcr_digest_bytes.size();
22221 hash->Update(pcrs_bytes.data(), pcrs_bytes.size());
22222 parameter_section_bytes += pcrs_bytes;
22223 command_size += pcrs_bytes.size();
22224 std::string command_hash(32, 0);
22225 hash->Finish(std::data(command_hash), command_hash.size());
22226 std::string authorization_section_bytes;
22227 std::string authorization_size_bytes;
22228 if (authorization_delegate) {
22229 if (!authorization_delegate->GetCommandAuthorization(
22230 command_hash, is_command_parameter_encryption_possible,
22231 is_response_parameter_encryption_possible,
22232 &authorization_section_bytes)) {
22233 return TRUNKS_RC_AUTHORIZATION_FAILED;
22234 }
22235 if (!authorization_section_bytes.empty()) {
22236 tag = TPM_ST_SESSIONS;
22237 std::string tmp;
22238 rc = Serialize_UINT32(authorization_section_bytes.size(),
22239 &authorization_size_bytes);
22240 if (rc != TPM_RC_SUCCESS) {
22241 return rc;
22242 }
22243 command_size +=
22244 authorization_size_bytes.size() + authorization_section_bytes.size();
22245 }
22246 }
22247 std::string tag_bytes;
22248 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22249 if (rc != TPM_RC_SUCCESS) {
22250 return rc;
22251 }
22252 std::string command_size_bytes;
22253 rc = Serialize_UINT32(command_size, &command_size_bytes);
22254 if (rc != TPM_RC_SUCCESS) {
22255 return rc;
22256 }
22257 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22258 handle_section_bytes + authorization_size_bytes +
22259 authorization_section_bytes + parameter_section_bytes;
22260 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22261 VLOG(2) << "Command: "
22262 << base::HexEncode(serialized_command->data(),
22263 serialized_command->size());
22264 return TPM_RC_SUCCESS;
22265 }
22266
ParseResponse_PolicyPCR(const std::string & response,AuthorizationDelegate * authorization_delegate)22267 TPM_RC Tpm::ParseResponse_PolicyPCR(
22268 const std::string& response,
22269 AuthorizationDelegate* authorization_delegate) {
22270 VLOG(3) << __func__;
22271 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22272 TPM_RC rc = TPM_RC_SUCCESS;
22273 std::string buffer(response);
22274 TPM_ST tag;
22275 std::string tag_bytes;
22276 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22277 if (rc != TPM_RC_SUCCESS) {
22278 return rc;
22279 }
22280 UINT32 response_size;
22281 std::string response_size_bytes;
22282 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22283 if (rc != TPM_RC_SUCCESS) {
22284 return rc;
22285 }
22286 TPM_RC response_code;
22287 std::string response_code_bytes;
22288 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22289 if (rc != TPM_RC_SUCCESS) {
22290 return rc;
22291 }
22292 if (response_size != response.size()) {
22293 return TPM_RC_SIZE;
22294 }
22295 if (response_code != TPM_RC_SUCCESS) {
22296 return response_code;
22297 }
22298 TPM_CC command_code = TPM_CC_PolicyPCR;
22299 std::string command_code_bytes;
22300 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22301 if (rc != TPM_RC_SUCCESS) {
22302 return rc;
22303 }
22304 std::string authorization_section_bytes;
22305 if (tag == TPM_ST_SESSIONS) {
22306 UINT32 parameter_section_size = buffer.size();
22307 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
22308 if (rc != TPM_RC_SUCCESS) {
22309 return rc;
22310 }
22311 if (parameter_section_size > buffer.size()) {
22312 return TPM_RC_INSUFFICIENT;
22313 }
22314 authorization_section_bytes = buffer.substr(parameter_section_size);
22315 // Keep the parameter section in |buffer|.
22316 buffer.erase(parameter_section_size);
22317 }
22318 std::unique_ptr<crypto::SecureHash> hash(
22319 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22320 hash->Update(response_code_bytes.data(), response_code_bytes.size());
22321 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22322 hash->Update(buffer.data(), buffer.size());
22323 std::string response_hash(32, 0);
22324 hash->Finish(std::data(response_hash), response_hash.size());
22325 if (tag == TPM_ST_SESSIONS) {
22326 if (!authorization_delegate)
22327 return TRUNKS_RC_AUTHORIZATION_FAILED;
22328 if (!authorization_delegate->CheckResponseAuthorization(
22329 response_hash, authorization_section_bytes)) {
22330 return TRUNKS_RC_AUTHORIZATION_FAILED;
22331 }
22332 }
22333 return TPM_RC_SUCCESS;
22334 }
22335
PolicyPCRErrorCallback(Tpm::PolicyPCRResponse callback,TPM_RC response_code)22336 void PolicyPCRErrorCallback(Tpm::PolicyPCRResponse callback,
22337 TPM_RC response_code) {
22338 VLOG(1) << __func__;
22339 std::move(callback).Run(response_code);
22340 }
22341
PolicyPCRResponseParser(Tpm::PolicyPCRResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22342 void PolicyPCRResponseParser(Tpm::PolicyPCRResponse callback,
22343 AuthorizationDelegate* authorization_delegate,
22344 const std::string& response) {
22345 VLOG(1) << __func__;
22346 TPM_RC rc = Tpm::ParseResponse_PolicyPCR(response, authorization_delegate);
22347 if (rc != TPM_RC_SUCCESS) {
22348 base::OnceCallback<void(TPM_RC)> error_reporter =
22349 base::BindOnce(PolicyPCRErrorCallback, std::move(callback));
22350 std::move(error_reporter).Run(rc);
22351 return;
22352 }
22353 std::move(callback).Run(rc);
22354 }
22355
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)22356 void Tpm::PolicyPCR(const TPMI_SH_POLICY& policy_session,
22357 const std::string& policy_session_name,
22358 const TPM2B_DIGEST& pcr_digest,
22359 const TPML_PCR_SELECTION& pcrs,
22360 AuthorizationDelegate* authorization_delegate,
22361 PolicyPCRResponse callback) {
22362 VLOG(1) << __func__;
22363 std::string command;
22364 TPM_RC rc = SerializeCommand_PolicyPCR(policy_session, policy_session_name,
22365 pcr_digest, pcrs, &command,
22366 authorization_delegate);
22367 if (rc != TPM_RC_SUCCESS) {
22368 base::OnceCallback<void(TPM_RC)> error_reporter =
22369 base::BindOnce(PolicyPCRErrorCallback, std::move(callback));
22370 std::move(error_reporter).Run(rc);
22371 return;
22372 }
22373 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22374 PolicyPCRResponseParser, std::move(callback), authorization_delegate);
22375 transceiver_->SendCommand(command, std::move(parser));
22376 }
22377
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)22378 TPM_RC Tpm::PolicyPCRSync(const TPMI_SH_POLICY& policy_session,
22379 const std::string& policy_session_name,
22380 const TPM2B_DIGEST& pcr_digest,
22381 const TPML_PCR_SELECTION& pcrs,
22382 AuthorizationDelegate* authorization_delegate) {
22383 VLOG(1) << __func__;
22384 std::string command;
22385 TPM_RC rc = SerializeCommand_PolicyPCR(policy_session, policy_session_name,
22386 pcr_digest, pcrs, &command,
22387 authorization_delegate);
22388 if (rc != TPM_RC_SUCCESS) {
22389 return rc;
22390 }
22391 std::string response = transceiver_->SendCommandAndWait(command);
22392 rc = ParseResponse_PolicyPCR(response, authorization_delegate);
22393 return rc;
22394 }
22395
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)22396 TPM_RC Tpm::SerializeCommand_PolicyLocality(
22397 const TPMI_SH_POLICY& policy_session,
22398 const std::string& policy_session_name,
22399 const TPMA_LOCALITY& locality,
22400 std::string* serialized_command,
22401 AuthorizationDelegate* authorization_delegate) {
22402 VLOG(3) << __func__;
22403 TPM_RC rc = TPM_RC_SUCCESS;
22404 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22405 UINT32 command_size = 10; // Header size.
22406 std::string handle_section_bytes;
22407 std::string parameter_section_bytes;
22408 TPM_CC command_code = TPM_CC_PolicyLocality;
22409 bool is_command_parameter_encryption_possible = false;
22410 bool is_response_parameter_encryption_possible = false;
22411 std::string command_code_bytes;
22412 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22413 if (rc != TPM_RC_SUCCESS) {
22414 return rc;
22415 }
22416 std::string policy_session_bytes;
22417 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22418 if (rc != TPM_RC_SUCCESS) {
22419 return rc;
22420 }
22421 std::string locality_bytes;
22422 rc = Serialize_TPMA_LOCALITY(locality, &locality_bytes);
22423 if (rc != TPM_RC_SUCCESS) {
22424 return rc;
22425 }
22426 std::unique_ptr<crypto::SecureHash> hash(
22427 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22428 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22429 hash->Update(policy_session_name.data(), policy_session_name.size());
22430 handle_section_bytes += policy_session_bytes;
22431 command_size += policy_session_bytes.size();
22432 hash->Update(locality_bytes.data(), locality_bytes.size());
22433 parameter_section_bytes += locality_bytes;
22434 command_size += locality_bytes.size();
22435 std::string command_hash(32, 0);
22436 hash->Finish(std::data(command_hash), command_hash.size());
22437 std::string authorization_section_bytes;
22438 std::string authorization_size_bytes;
22439 if (authorization_delegate) {
22440 if (!authorization_delegate->GetCommandAuthorization(
22441 command_hash, is_command_parameter_encryption_possible,
22442 is_response_parameter_encryption_possible,
22443 &authorization_section_bytes)) {
22444 return TRUNKS_RC_AUTHORIZATION_FAILED;
22445 }
22446 if (!authorization_section_bytes.empty()) {
22447 tag = TPM_ST_SESSIONS;
22448 std::string tmp;
22449 rc = Serialize_UINT32(authorization_section_bytes.size(),
22450 &authorization_size_bytes);
22451 if (rc != TPM_RC_SUCCESS) {
22452 return rc;
22453 }
22454 command_size +=
22455 authorization_size_bytes.size() + authorization_section_bytes.size();
22456 }
22457 }
22458 std::string tag_bytes;
22459 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22460 if (rc != TPM_RC_SUCCESS) {
22461 return rc;
22462 }
22463 std::string command_size_bytes;
22464 rc = Serialize_UINT32(command_size, &command_size_bytes);
22465 if (rc != TPM_RC_SUCCESS) {
22466 return rc;
22467 }
22468 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22469 handle_section_bytes + authorization_size_bytes +
22470 authorization_section_bytes + parameter_section_bytes;
22471 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22472 VLOG(2) << "Command: "
22473 << base::HexEncode(serialized_command->data(),
22474 serialized_command->size());
22475 return TPM_RC_SUCCESS;
22476 }
22477
ParseResponse_PolicyLocality(const std::string & response,AuthorizationDelegate * authorization_delegate)22478 TPM_RC Tpm::ParseResponse_PolicyLocality(
22479 const std::string& response,
22480 AuthorizationDelegate* authorization_delegate) {
22481 VLOG(3) << __func__;
22482 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22483 TPM_RC rc = TPM_RC_SUCCESS;
22484 std::string buffer(response);
22485 TPM_ST tag;
22486 std::string tag_bytes;
22487 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22488 if (rc != TPM_RC_SUCCESS) {
22489 return rc;
22490 }
22491 UINT32 response_size;
22492 std::string response_size_bytes;
22493 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22494 if (rc != TPM_RC_SUCCESS) {
22495 return rc;
22496 }
22497 TPM_RC response_code;
22498 std::string response_code_bytes;
22499 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22500 if (rc != TPM_RC_SUCCESS) {
22501 return rc;
22502 }
22503 if (response_size != response.size()) {
22504 return TPM_RC_SIZE;
22505 }
22506 if (response_code != TPM_RC_SUCCESS) {
22507 return response_code;
22508 }
22509 TPM_CC command_code = TPM_CC_PolicyLocality;
22510 std::string command_code_bytes;
22511 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22512 if (rc != TPM_RC_SUCCESS) {
22513 return rc;
22514 }
22515 std::string authorization_section_bytes;
22516 if (tag == TPM_ST_SESSIONS) {
22517 UINT32 parameter_section_size = buffer.size();
22518 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
22519 if (rc != TPM_RC_SUCCESS) {
22520 return rc;
22521 }
22522 if (parameter_section_size > buffer.size()) {
22523 return TPM_RC_INSUFFICIENT;
22524 }
22525 authorization_section_bytes = buffer.substr(parameter_section_size);
22526 // Keep the parameter section in |buffer|.
22527 buffer.erase(parameter_section_size);
22528 }
22529 std::unique_ptr<crypto::SecureHash> hash(
22530 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22531 hash->Update(response_code_bytes.data(), response_code_bytes.size());
22532 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22533 hash->Update(buffer.data(), buffer.size());
22534 std::string response_hash(32, 0);
22535 hash->Finish(std::data(response_hash), response_hash.size());
22536 if (tag == TPM_ST_SESSIONS) {
22537 if (!authorization_delegate)
22538 return TRUNKS_RC_AUTHORIZATION_FAILED;
22539 if (!authorization_delegate->CheckResponseAuthorization(
22540 response_hash, authorization_section_bytes)) {
22541 return TRUNKS_RC_AUTHORIZATION_FAILED;
22542 }
22543 }
22544 return TPM_RC_SUCCESS;
22545 }
22546
PolicyLocalityErrorCallback(Tpm::PolicyLocalityResponse callback,TPM_RC response_code)22547 void PolicyLocalityErrorCallback(Tpm::PolicyLocalityResponse callback,
22548 TPM_RC response_code) {
22549 VLOG(1) << __func__;
22550 std::move(callback).Run(response_code);
22551 }
22552
PolicyLocalityResponseParser(Tpm::PolicyLocalityResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22553 void PolicyLocalityResponseParser(Tpm::PolicyLocalityResponse callback,
22554 AuthorizationDelegate* authorization_delegate,
22555 const std::string& response) {
22556 VLOG(1) << __func__;
22557 TPM_RC rc =
22558 Tpm::ParseResponse_PolicyLocality(response, authorization_delegate);
22559 if (rc != TPM_RC_SUCCESS) {
22560 base::OnceCallback<void(TPM_RC)> error_reporter =
22561 base::BindOnce(PolicyLocalityErrorCallback, std::move(callback));
22562 std::move(error_reporter).Run(rc);
22563 return;
22564 }
22565 std::move(callback).Run(rc);
22566 }
22567
PolicyLocality(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,AuthorizationDelegate * authorization_delegate,PolicyLocalityResponse callback)22568 void Tpm::PolicyLocality(const TPMI_SH_POLICY& policy_session,
22569 const std::string& policy_session_name,
22570 const TPMA_LOCALITY& locality,
22571 AuthorizationDelegate* authorization_delegate,
22572 PolicyLocalityResponse callback) {
22573 VLOG(1) << __func__;
22574 std::string command;
22575 TPM_RC rc = SerializeCommand_PolicyLocality(policy_session,
22576 policy_session_name, locality,
22577 &command, authorization_delegate);
22578 if (rc != TPM_RC_SUCCESS) {
22579 base::OnceCallback<void(TPM_RC)> error_reporter =
22580 base::BindOnce(PolicyLocalityErrorCallback, std::move(callback));
22581 std::move(error_reporter).Run(rc);
22582 return;
22583 }
22584 base::OnceCallback<void(const std::string&)> parser =
22585 base::BindOnce(PolicyLocalityResponseParser, std::move(callback),
22586 authorization_delegate);
22587 transceiver_->SendCommand(command, std::move(parser));
22588 }
22589
PolicyLocalitySync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,AuthorizationDelegate * authorization_delegate)22590 TPM_RC Tpm::PolicyLocalitySync(const TPMI_SH_POLICY& policy_session,
22591 const std::string& policy_session_name,
22592 const TPMA_LOCALITY& locality,
22593 AuthorizationDelegate* authorization_delegate) {
22594 VLOG(1) << __func__;
22595 std::string command;
22596 TPM_RC rc = SerializeCommand_PolicyLocality(policy_session,
22597 policy_session_name, locality,
22598 &command, authorization_delegate);
22599 if (rc != TPM_RC_SUCCESS) {
22600 return rc;
22601 }
22602 std::string response = transceiver_->SendCommandAndWait(command);
22603 rc = ParseResponse_PolicyLocality(response, authorization_delegate);
22604 return rc;
22605 }
22606
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)22607 TPM_RC Tpm::SerializeCommand_PolicyNV(
22608 const TPMI_RH_NV_AUTH& auth_handle,
22609 const std::string& auth_handle_name,
22610 const TPMI_RH_NV_INDEX& nv_index,
22611 const std::string& nv_index_name,
22612 const TPMI_SH_POLICY& policy_session,
22613 const std::string& policy_session_name,
22614 const TPM2B_OPERAND& operand_b,
22615 const UINT16& offset,
22616 const TPM_EO& operation,
22617 std::string* serialized_command,
22618 AuthorizationDelegate* authorization_delegate) {
22619 VLOG(3) << __func__;
22620 TPM_RC rc = TPM_RC_SUCCESS;
22621 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22622 UINT32 command_size = 10; // Header size.
22623 std::string handle_section_bytes;
22624 std::string parameter_section_bytes;
22625 TPM_CC command_code = TPM_CC_PolicyNV;
22626 bool is_command_parameter_encryption_possible = true;
22627 bool is_response_parameter_encryption_possible = false;
22628 std::string command_code_bytes;
22629 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22630 if (rc != TPM_RC_SUCCESS) {
22631 return rc;
22632 }
22633 std::string auth_handle_bytes;
22634 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
22635 if (rc != TPM_RC_SUCCESS) {
22636 return rc;
22637 }
22638 std::string nv_index_bytes;
22639 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
22640 if (rc != TPM_RC_SUCCESS) {
22641 return rc;
22642 }
22643 std::string policy_session_bytes;
22644 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22645 if (rc != TPM_RC_SUCCESS) {
22646 return rc;
22647 }
22648 std::string operand_b_bytes;
22649 rc = Serialize_TPM2B_OPERAND(operand_b, &operand_b_bytes);
22650 if (rc != TPM_RC_SUCCESS) {
22651 return rc;
22652 }
22653 std::string offset_bytes;
22654 rc = Serialize_UINT16(offset, &offset_bytes);
22655 if (rc != TPM_RC_SUCCESS) {
22656 return rc;
22657 }
22658 std::string operation_bytes;
22659 rc = Serialize_TPM_EO(operation, &operation_bytes);
22660 if (rc != TPM_RC_SUCCESS) {
22661 return rc;
22662 }
22663 if (authorization_delegate) {
22664 // Encrypt just the parameter data, not the size.
22665 std::string tmp = operand_b_bytes.substr(2);
22666 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22667 return TRUNKS_RC_ENCRYPTION_FAILED;
22668 }
22669 operand_b_bytes.replace(2, std::string::npos, tmp);
22670 }
22671 std::unique_ptr<crypto::SecureHash> hash(
22672 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22673 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22674 hash->Update(auth_handle_name.data(), auth_handle_name.size());
22675 handle_section_bytes += auth_handle_bytes;
22676 command_size += auth_handle_bytes.size();
22677 hash->Update(nv_index_name.data(), nv_index_name.size());
22678 handle_section_bytes += nv_index_bytes;
22679 command_size += nv_index_bytes.size();
22680 hash->Update(policy_session_name.data(), policy_session_name.size());
22681 handle_section_bytes += policy_session_bytes;
22682 command_size += policy_session_bytes.size();
22683 hash->Update(operand_b_bytes.data(), operand_b_bytes.size());
22684 parameter_section_bytes += operand_b_bytes;
22685 command_size += operand_b_bytes.size();
22686 hash->Update(offset_bytes.data(), offset_bytes.size());
22687 parameter_section_bytes += offset_bytes;
22688 command_size += offset_bytes.size();
22689 hash->Update(operation_bytes.data(), operation_bytes.size());
22690 parameter_section_bytes += operation_bytes;
22691 command_size += operation_bytes.size();
22692 std::string command_hash(32, 0);
22693 hash->Finish(std::data(command_hash), command_hash.size());
22694 std::string authorization_section_bytes;
22695 std::string authorization_size_bytes;
22696 if (authorization_delegate) {
22697 if (!authorization_delegate->GetCommandAuthorization(
22698 command_hash, is_command_parameter_encryption_possible,
22699 is_response_parameter_encryption_possible,
22700 &authorization_section_bytes)) {
22701 return TRUNKS_RC_AUTHORIZATION_FAILED;
22702 }
22703 if (!authorization_section_bytes.empty()) {
22704 tag = TPM_ST_SESSIONS;
22705 std::string tmp;
22706 rc = Serialize_UINT32(authorization_section_bytes.size(),
22707 &authorization_size_bytes);
22708 if (rc != TPM_RC_SUCCESS) {
22709 return rc;
22710 }
22711 command_size +=
22712 authorization_size_bytes.size() + authorization_section_bytes.size();
22713 }
22714 }
22715 std::string tag_bytes;
22716 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22717 if (rc != TPM_RC_SUCCESS) {
22718 return rc;
22719 }
22720 std::string command_size_bytes;
22721 rc = Serialize_UINT32(command_size, &command_size_bytes);
22722 if (rc != TPM_RC_SUCCESS) {
22723 return rc;
22724 }
22725 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22726 handle_section_bytes + authorization_size_bytes +
22727 authorization_section_bytes + parameter_section_bytes;
22728 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22729 VLOG(2) << "Command: "
22730 << base::HexEncode(serialized_command->data(),
22731 serialized_command->size());
22732 return TPM_RC_SUCCESS;
22733 }
22734
ParseResponse_PolicyNV(const std::string & response,AuthorizationDelegate * authorization_delegate)22735 TPM_RC Tpm::ParseResponse_PolicyNV(
22736 const std::string& response,
22737 AuthorizationDelegate* authorization_delegate) {
22738 VLOG(3) << __func__;
22739 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22740 TPM_RC rc = TPM_RC_SUCCESS;
22741 std::string buffer(response);
22742 TPM_ST tag;
22743 std::string tag_bytes;
22744 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22745 if (rc != TPM_RC_SUCCESS) {
22746 return rc;
22747 }
22748 UINT32 response_size;
22749 std::string response_size_bytes;
22750 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22751 if (rc != TPM_RC_SUCCESS) {
22752 return rc;
22753 }
22754 TPM_RC response_code;
22755 std::string response_code_bytes;
22756 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22757 if (rc != TPM_RC_SUCCESS) {
22758 return rc;
22759 }
22760 if (response_size != response.size()) {
22761 return TPM_RC_SIZE;
22762 }
22763 if (response_code != TPM_RC_SUCCESS) {
22764 return response_code;
22765 }
22766 TPM_CC command_code = TPM_CC_PolicyNV;
22767 std::string command_code_bytes;
22768 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22769 if (rc != TPM_RC_SUCCESS) {
22770 return rc;
22771 }
22772 std::string authorization_section_bytes;
22773 if (tag == TPM_ST_SESSIONS) {
22774 UINT32 parameter_section_size = buffer.size();
22775 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
22776 if (rc != TPM_RC_SUCCESS) {
22777 return rc;
22778 }
22779 if (parameter_section_size > buffer.size()) {
22780 return TPM_RC_INSUFFICIENT;
22781 }
22782 authorization_section_bytes = buffer.substr(parameter_section_size);
22783 // Keep the parameter section in |buffer|.
22784 buffer.erase(parameter_section_size);
22785 }
22786 std::unique_ptr<crypto::SecureHash> hash(
22787 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22788 hash->Update(response_code_bytes.data(), response_code_bytes.size());
22789 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22790 hash->Update(buffer.data(), buffer.size());
22791 std::string response_hash(32, 0);
22792 hash->Finish(std::data(response_hash), response_hash.size());
22793 if (tag == TPM_ST_SESSIONS) {
22794 if (!authorization_delegate)
22795 return TRUNKS_RC_AUTHORIZATION_FAILED;
22796 if (!authorization_delegate->CheckResponseAuthorization(
22797 response_hash, authorization_section_bytes)) {
22798 return TRUNKS_RC_AUTHORIZATION_FAILED;
22799 }
22800 }
22801 return TPM_RC_SUCCESS;
22802 }
22803
PolicyNVErrorCallback(Tpm::PolicyNVResponse callback,TPM_RC response_code)22804 void PolicyNVErrorCallback(Tpm::PolicyNVResponse callback,
22805 TPM_RC response_code) {
22806 VLOG(1) << __func__;
22807 std::move(callback).Run(response_code);
22808 }
22809
PolicyNVResponseParser(Tpm::PolicyNVResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22810 void PolicyNVResponseParser(Tpm::PolicyNVResponse callback,
22811 AuthorizationDelegate* authorization_delegate,
22812 const std::string& response) {
22813 VLOG(1) << __func__;
22814 TPM_RC rc = Tpm::ParseResponse_PolicyNV(response, authorization_delegate);
22815 if (rc != TPM_RC_SUCCESS) {
22816 base::OnceCallback<void(TPM_RC)> error_reporter =
22817 base::BindOnce(PolicyNVErrorCallback, std::move(callback));
22818 std::move(error_reporter).Run(rc);
22819 return;
22820 }
22821 std::move(callback).Run(rc);
22822 }
22823
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)22824 void Tpm::PolicyNV(const TPMI_RH_NV_AUTH& auth_handle,
22825 const std::string& auth_handle_name,
22826 const TPMI_RH_NV_INDEX& nv_index,
22827 const std::string& nv_index_name,
22828 const TPMI_SH_POLICY& policy_session,
22829 const std::string& policy_session_name,
22830 const TPM2B_OPERAND& operand_b,
22831 const UINT16& offset,
22832 const TPM_EO& operation,
22833 AuthorizationDelegate* authorization_delegate,
22834 PolicyNVResponse callback) {
22835 VLOG(1) << __func__;
22836 std::string command;
22837 TPM_RC rc = SerializeCommand_PolicyNV(
22838 auth_handle, auth_handle_name, nv_index, nv_index_name, policy_session,
22839 policy_session_name, operand_b, offset, operation, &command,
22840 authorization_delegate);
22841 if (rc != TPM_RC_SUCCESS) {
22842 base::OnceCallback<void(TPM_RC)> error_reporter =
22843 base::BindOnce(PolicyNVErrorCallback, std::move(callback));
22844 std::move(error_reporter).Run(rc);
22845 return;
22846 }
22847 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22848 PolicyNVResponseParser, std::move(callback), authorization_delegate);
22849 transceiver_->SendCommand(command, std::move(parser));
22850 }
22851
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)22852 TPM_RC Tpm::PolicyNVSync(const TPMI_RH_NV_AUTH& auth_handle,
22853 const std::string& auth_handle_name,
22854 const TPMI_RH_NV_INDEX& nv_index,
22855 const std::string& nv_index_name,
22856 const TPMI_SH_POLICY& policy_session,
22857 const std::string& policy_session_name,
22858 const TPM2B_OPERAND& operand_b,
22859 const UINT16& offset,
22860 const TPM_EO& operation,
22861 AuthorizationDelegate* authorization_delegate) {
22862 VLOG(1) << __func__;
22863 std::string command;
22864 TPM_RC rc = SerializeCommand_PolicyNV(
22865 auth_handle, auth_handle_name, nv_index, nv_index_name, policy_session,
22866 policy_session_name, operand_b, offset, operation, &command,
22867 authorization_delegate);
22868 if (rc != TPM_RC_SUCCESS) {
22869 return rc;
22870 }
22871 std::string response = transceiver_->SendCommandAndWait(command);
22872 rc = ParseResponse_PolicyNV(response, authorization_delegate);
22873 return rc;
22874 }
22875
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)22876 TPM_RC Tpm::SerializeCommand_PolicyCounterTimer(
22877 const TPMI_SH_POLICY& policy_session,
22878 const std::string& policy_session_name,
22879 const TPM2B_OPERAND& operand_b,
22880 const UINT16& offset,
22881 const TPM_EO& operation,
22882 std::string* serialized_command,
22883 AuthorizationDelegate* authorization_delegate) {
22884 VLOG(3) << __func__;
22885 TPM_RC rc = TPM_RC_SUCCESS;
22886 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22887 UINT32 command_size = 10; // Header size.
22888 std::string handle_section_bytes;
22889 std::string parameter_section_bytes;
22890 TPM_CC command_code = TPM_CC_PolicyCounterTimer;
22891 bool is_command_parameter_encryption_possible = true;
22892 bool is_response_parameter_encryption_possible = false;
22893 std::string command_code_bytes;
22894 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22895 if (rc != TPM_RC_SUCCESS) {
22896 return rc;
22897 }
22898 std::string policy_session_bytes;
22899 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22900 if (rc != TPM_RC_SUCCESS) {
22901 return rc;
22902 }
22903 std::string operand_b_bytes;
22904 rc = Serialize_TPM2B_OPERAND(operand_b, &operand_b_bytes);
22905 if (rc != TPM_RC_SUCCESS) {
22906 return rc;
22907 }
22908 std::string offset_bytes;
22909 rc = Serialize_UINT16(offset, &offset_bytes);
22910 if (rc != TPM_RC_SUCCESS) {
22911 return rc;
22912 }
22913 std::string operation_bytes;
22914 rc = Serialize_TPM_EO(operation, &operation_bytes);
22915 if (rc != TPM_RC_SUCCESS) {
22916 return rc;
22917 }
22918 if (authorization_delegate) {
22919 // Encrypt just the parameter data, not the size.
22920 std::string tmp = operand_b_bytes.substr(2);
22921 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22922 return TRUNKS_RC_ENCRYPTION_FAILED;
22923 }
22924 operand_b_bytes.replace(2, std::string::npos, tmp);
22925 }
22926 std::unique_ptr<crypto::SecureHash> hash(
22927 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22928 hash->Update(command_code_bytes.data(), command_code_bytes.size());
22929 hash->Update(policy_session_name.data(), policy_session_name.size());
22930 handle_section_bytes += policy_session_bytes;
22931 command_size += policy_session_bytes.size();
22932 hash->Update(operand_b_bytes.data(), operand_b_bytes.size());
22933 parameter_section_bytes += operand_b_bytes;
22934 command_size += operand_b_bytes.size();
22935 hash->Update(offset_bytes.data(), offset_bytes.size());
22936 parameter_section_bytes += offset_bytes;
22937 command_size += offset_bytes.size();
22938 hash->Update(operation_bytes.data(), operation_bytes.size());
22939 parameter_section_bytes += operation_bytes;
22940 command_size += operation_bytes.size();
22941 std::string command_hash(32, 0);
22942 hash->Finish(std::data(command_hash), command_hash.size());
22943 std::string authorization_section_bytes;
22944 std::string authorization_size_bytes;
22945 if (authorization_delegate) {
22946 if (!authorization_delegate->GetCommandAuthorization(
22947 command_hash, is_command_parameter_encryption_possible,
22948 is_response_parameter_encryption_possible,
22949 &authorization_section_bytes)) {
22950 return TRUNKS_RC_AUTHORIZATION_FAILED;
22951 }
22952 if (!authorization_section_bytes.empty()) {
22953 tag = TPM_ST_SESSIONS;
22954 std::string tmp;
22955 rc = Serialize_UINT32(authorization_section_bytes.size(),
22956 &authorization_size_bytes);
22957 if (rc != TPM_RC_SUCCESS) {
22958 return rc;
22959 }
22960 command_size +=
22961 authorization_size_bytes.size() + authorization_section_bytes.size();
22962 }
22963 }
22964 std::string tag_bytes;
22965 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22966 if (rc != TPM_RC_SUCCESS) {
22967 return rc;
22968 }
22969 std::string command_size_bytes;
22970 rc = Serialize_UINT32(command_size, &command_size_bytes);
22971 if (rc != TPM_RC_SUCCESS) {
22972 return rc;
22973 }
22974 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22975 handle_section_bytes + authorization_size_bytes +
22976 authorization_section_bytes + parameter_section_bytes;
22977 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22978 VLOG(2) << "Command: "
22979 << base::HexEncode(serialized_command->data(),
22980 serialized_command->size());
22981 return TPM_RC_SUCCESS;
22982 }
22983
ParseResponse_PolicyCounterTimer(const std::string & response,AuthorizationDelegate * authorization_delegate)22984 TPM_RC Tpm::ParseResponse_PolicyCounterTimer(
22985 const std::string& response,
22986 AuthorizationDelegate* authorization_delegate) {
22987 VLOG(3) << __func__;
22988 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22989 TPM_RC rc = TPM_RC_SUCCESS;
22990 std::string buffer(response);
22991 TPM_ST tag;
22992 std::string tag_bytes;
22993 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22994 if (rc != TPM_RC_SUCCESS) {
22995 return rc;
22996 }
22997 UINT32 response_size;
22998 std::string response_size_bytes;
22999 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23000 if (rc != TPM_RC_SUCCESS) {
23001 return rc;
23002 }
23003 TPM_RC response_code;
23004 std::string response_code_bytes;
23005 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23006 if (rc != TPM_RC_SUCCESS) {
23007 return rc;
23008 }
23009 if (response_size != response.size()) {
23010 return TPM_RC_SIZE;
23011 }
23012 if (response_code != TPM_RC_SUCCESS) {
23013 return response_code;
23014 }
23015 TPM_CC command_code = TPM_CC_PolicyCounterTimer;
23016 std::string command_code_bytes;
23017 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23018 if (rc != TPM_RC_SUCCESS) {
23019 return rc;
23020 }
23021 std::string authorization_section_bytes;
23022 if (tag == TPM_ST_SESSIONS) {
23023 UINT32 parameter_section_size = buffer.size();
23024 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
23025 if (rc != TPM_RC_SUCCESS) {
23026 return rc;
23027 }
23028 if (parameter_section_size > buffer.size()) {
23029 return TPM_RC_INSUFFICIENT;
23030 }
23031 authorization_section_bytes = buffer.substr(parameter_section_size);
23032 // Keep the parameter section in |buffer|.
23033 buffer.erase(parameter_section_size);
23034 }
23035 std::unique_ptr<crypto::SecureHash> hash(
23036 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23037 hash->Update(response_code_bytes.data(), response_code_bytes.size());
23038 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23039 hash->Update(buffer.data(), buffer.size());
23040 std::string response_hash(32, 0);
23041 hash->Finish(std::data(response_hash), response_hash.size());
23042 if (tag == TPM_ST_SESSIONS) {
23043 if (!authorization_delegate)
23044 return TRUNKS_RC_AUTHORIZATION_FAILED;
23045 if (!authorization_delegate->CheckResponseAuthorization(
23046 response_hash, authorization_section_bytes)) {
23047 return TRUNKS_RC_AUTHORIZATION_FAILED;
23048 }
23049 }
23050 return TPM_RC_SUCCESS;
23051 }
23052
PolicyCounterTimerErrorCallback(Tpm::PolicyCounterTimerResponse callback,TPM_RC response_code)23053 void PolicyCounterTimerErrorCallback(Tpm::PolicyCounterTimerResponse callback,
23054 TPM_RC response_code) {
23055 VLOG(1) << __func__;
23056 std::move(callback).Run(response_code);
23057 }
23058
PolicyCounterTimerResponseParser(Tpm::PolicyCounterTimerResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23059 void PolicyCounterTimerResponseParser(
23060 Tpm::PolicyCounterTimerResponse callback,
23061 AuthorizationDelegate* authorization_delegate,
23062 const std::string& response) {
23063 VLOG(1) << __func__;
23064 TPM_RC rc =
23065 Tpm::ParseResponse_PolicyCounterTimer(response, authorization_delegate);
23066 if (rc != TPM_RC_SUCCESS) {
23067 base::OnceCallback<void(TPM_RC)> error_reporter =
23068 base::BindOnce(PolicyCounterTimerErrorCallback, std::move(callback));
23069 std::move(error_reporter).Run(rc);
23070 return;
23071 }
23072 std::move(callback).Run(rc);
23073 }
23074
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)23075 void Tpm::PolicyCounterTimer(const TPMI_SH_POLICY& policy_session,
23076 const std::string& policy_session_name,
23077 const TPM2B_OPERAND& operand_b,
23078 const UINT16& offset,
23079 const TPM_EO& operation,
23080 AuthorizationDelegate* authorization_delegate,
23081 PolicyCounterTimerResponse callback) {
23082 VLOG(1) << __func__;
23083 std::string command;
23084 TPM_RC rc = SerializeCommand_PolicyCounterTimer(
23085 policy_session, policy_session_name, operand_b, offset, operation,
23086 &command, authorization_delegate);
23087 if (rc != TPM_RC_SUCCESS) {
23088 base::OnceCallback<void(TPM_RC)> error_reporter =
23089 base::BindOnce(PolicyCounterTimerErrorCallback, std::move(callback));
23090 std::move(error_reporter).Run(rc);
23091 return;
23092 }
23093 base::OnceCallback<void(const std::string&)> parser =
23094 base::BindOnce(PolicyCounterTimerResponseParser, std::move(callback),
23095 authorization_delegate);
23096 transceiver_->SendCommand(command, std::move(parser));
23097 }
23098
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)23099 TPM_RC Tpm::PolicyCounterTimerSync(
23100 const TPMI_SH_POLICY& policy_session,
23101 const std::string& policy_session_name,
23102 const TPM2B_OPERAND& operand_b,
23103 const UINT16& offset,
23104 const TPM_EO& operation,
23105 AuthorizationDelegate* authorization_delegate) {
23106 VLOG(1) << __func__;
23107 std::string command;
23108 TPM_RC rc = SerializeCommand_PolicyCounterTimer(
23109 policy_session, policy_session_name, operand_b, offset, operation,
23110 &command, authorization_delegate);
23111 if (rc != TPM_RC_SUCCESS) {
23112 return rc;
23113 }
23114 std::string response = transceiver_->SendCommandAndWait(command);
23115 rc = ParseResponse_PolicyCounterTimer(response, authorization_delegate);
23116 return rc;
23117 }
23118
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)23119 TPM_RC Tpm::SerializeCommand_PolicyCommandCode(
23120 const TPMI_SH_POLICY& policy_session,
23121 const std::string& policy_session_name,
23122 const TPM_CC& code,
23123 std::string* serialized_command,
23124 AuthorizationDelegate* authorization_delegate) {
23125 VLOG(3) << __func__;
23126 TPM_RC rc = TPM_RC_SUCCESS;
23127 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23128 UINT32 command_size = 10; // Header size.
23129 std::string handle_section_bytes;
23130 std::string parameter_section_bytes;
23131 TPM_CC command_code = TPM_CC_PolicyCommandCode;
23132 bool is_command_parameter_encryption_possible = false;
23133 bool is_response_parameter_encryption_possible = false;
23134 std::string command_code_bytes;
23135 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23136 if (rc != TPM_RC_SUCCESS) {
23137 return rc;
23138 }
23139 std::string policy_session_bytes;
23140 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23141 if (rc != TPM_RC_SUCCESS) {
23142 return rc;
23143 }
23144 std::string code_bytes;
23145 rc = Serialize_TPM_CC(code, &code_bytes);
23146 if (rc != TPM_RC_SUCCESS) {
23147 return rc;
23148 }
23149 std::unique_ptr<crypto::SecureHash> hash(
23150 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23151 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23152 hash->Update(policy_session_name.data(), policy_session_name.size());
23153 handle_section_bytes += policy_session_bytes;
23154 command_size += policy_session_bytes.size();
23155 hash->Update(code_bytes.data(), code_bytes.size());
23156 parameter_section_bytes += code_bytes;
23157 command_size += code_bytes.size();
23158 std::string command_hash(32, 0);
23159 hash->Finish(std::data(command_hash), command_hash.size());
23160 std::string authorization_section_bytes;
23161 std::string authorization_size_bytes;
23162 if (authorization_delegate) {
23163 if (!authorization_delegate->GetCommandAuthorization(
23164 command_hash, is_command_parameter_encryption_possible,
23165 is_response_parameter_encryption_possible,
23166 &authorization_section_bytes)) {
23167 return TRUNKS_RC_AUTHORIZATION_FAILED;
23168 }
23169 if (!authorization_section_bytes.empty()) {
23170 tag = TPM_ST_SESSIONS;
23171 std::string tmp;
23172 rc = Serialize_UINT32(authorization_section_bytes.size(),
23173 &authorization_size_bytes);
23174 if (rc != TPM_RC_SUCCESS) {
23175 return rc;
23176 }
23177 command_size +=
23178 authorization_size_bytes.size() + authorization_section_bytes.size();
23179 }
23180 }
23181 std::string tag_bytes;
23182 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23183 if (rc != TPM_RC_SUCCESS) {
23184 return rc;
23185 }
23186 std::string command_size_bytes;
23187 rc = Serialize_UINT32(command_size, &command_size_bytes);
23188 if (rc != TPM_RC_SUCCESS) {
23189 return rc;
23190 }
23191 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23192 handle_section_bytes + authorization_size_bytes +
23193 authorization_section_bytes + parameter_section_bytes;
23194 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23195 VLOG(2) << "Command: "
23196 << base::HexEncode(serialized_command->data(),
23197 serialized_command->size());
23198 return TPM_RC_SUCCESS;
23199 }
23200
ParseResponse_PolicyCommandCode(const std::string & response,AuthorizationDelegate * authorization_delegate)23201 TPM_RC Tpm::ParseResponse_PolicyCommandCode(
23202 const std::string& response,
23203 AuthorizationDelegate* authorization_delegate) {
23204 VLOG(3) << __func__;
23205 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23206 TPM_RC rc = TPM_RC_SUCCESS;
23207 std::string buffer(response);
23208 TPM_ST tag;
23209 std::string tag_bytes;
23210 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23211 if (rc != TPM_RC_SUCCESS) {
23212 return rc;
23213 }
23214 UINT32 response_size;
23215 std::string response_size_bytes;
23216 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23217 if (rc != TPM_RC_SUCCESS) {
23218 return rc;
23219 }
23220 TPM_RC response_code;
23221 std::string response_code_bytes;
23222 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23223 if (rc != TPM_RC_SUCCESS) {
23224 return rc;
23225 }
23226 if (response_size != response.size()) {
23227 return TPM_RC_SIZE;
23228 }
23229 if (response_code != TPM_RC_SUCCESS) {
23230 return response_code;
23231 }
23232 TPM_CC command_code = TPM_CC_PolicyCommandCode;
23233 std::string command_code_bytes;
23234 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23235 if (rc != TPM_RC_SUCCESS) {
23236 return rc;
23237 }
23238 std::string authorization_section_bytes;
23239 if (tag == TPM_ST_SESSIONS) {
23240 UINT32 parameter_section_size = buffer.size();
23241 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
23242 if (rc != TPM_RC_SUCCESS) {
23243 return rc;
23244 }
23245 if (parameter_section_size > buffer.size()) {
23246 return TPM_RC_INSUFFICIENT;
23247 }
23248 authorization_section_bytes = buffer.substr(parameter_section_size);
23249 // Keep the parameter section in |buffer|.
23250 buffer.erase(parameter_section_size);
23251 }
23252 std::unique_ptr<crypto::SecureHash> hash(
23253 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23254 hash->Update(response_code_bytes.data(), response_code_bytes.size());
23255 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23256 hash->Update(buffer.data(), buffer.size());
23257 std::string response_hash(32, 0);
23258 hash->Finish(std::data(response_hash), response_hash.size());
23259 if (tag == TPM_ST_SESSIONS) {
23260 if (!authorization_delegate)
23261 return TRUNKS_RC_AUTHORIZATION_FAILED;
23262 if (!authorization_delegate->CheckResponseAuthorization(
23263 response_hash, authorization_section_bytes)) {
23264 return TRUNKS_RC_AUTHORIZATION_FAILED;
23265 }
23266 }
23267 return TPM_RC_SUCCESS;
23268 }
23269
PolicyCommandCodeErrorCallback(Tpm::PolicyCommandCodeResponse callback,TPM_RC response_code)23270 void PolicyCommandCodeErrorCallback(Tpm::PolicyCommandCodeResponse callback,
23271 TPM_RC response_code) {
23272 VLOG(1) << __func__;
23273 std::move(callback).Run(response_code);
23274 }
23275
PolicyCommandCodeResponseParser(Tpm::PolicyCommandCodeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23276 void PolicyCommandCodeResponseParser(
23277 Tpm::PolicyCommandCodeResponse callback,
23278 AuthorizationDelegate* authorization_delegate,
23279 const std::string& response) {
23280 VLOG(1) << __func__;
23281 TPM_RC rc =
23282 Tpm::ParseResponse_PolicyCommandCode(response, authorization_delegate);
23283 if (rc != TPM_RC_SUCCESS) {
23284 base::OnceCallback<void(TPM_RC)> error_reporter =
23285 base::BindOnce(PolicyCommandCodeErrorCallback, std::move(callback));
23286 std::move(error_reporter).Run(rc);
23287 return;
23288 }
23289 std::move(callback).Run(rc);
23290 }
23291
PolicyCommandCode(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,AuthorizationDelegate * authorization_delegate,PolicyCommandCodeResponse callback)23292 void Tpm::PolicyCommandCode(const TPMI_SH_POLICY& policy_session,
23293 const std::string& policy_session_name,
23294 const TPM_CC& code,
23295 AuthorizationDelegate* authorization_delegate,
23296 PolicyCommandCodeResponse callback) {
23297 VLOG(1) << __func__;
23298 std::string command;
23299 TPM_RC rc = SerializeCommand_PolicyCommandCode(
23300 policy_session, policy_session_name, code, &command,
23301 authorization_delegate);
23302 if (rc != TPM_RC_SUCCESS) {
23303 base::OnceCallback<void(TPM_RC)> error_reporter =
23304 base::BindOnce(PolicyCommandCodeErrorCallback, std::move(callback));
23305 std::move(error_reporter).Run(rc);
23306 return;
23307 }
23308 base::OnceCallback<void(const std::string&)> parser =
23309 base::BindOnce(PolicyCommandCodeResponseParser, std::move(callback),
23310 authorization_delegate);
23311 transceiver_->SendCommand(command, std::move(parser));
23312 }
23313
PolicyCommandCodeSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,AuthorizationDelegate * authorization_delegate)23314 TPM_RC Tpm::PolicyCommandCodeSync(
23315 const TPMI_SH_POLICY& policy_session,
23316 const std::string& policy_session_name,
23317 const TPM_CC& code,
23318 AuthorizationDelegate* authorization_delegate) {
23319 VLOG(1) << __func__;
23320 std::string command;
23321 TPM_RC rc = SerializeCommand_PolicyCommandCode(
23322 policy_session, policy_session_name, code, &command,
23323 authorization_delegate);
23324 if (rc != TPM_RC_SUCCESS) {
23325 return rc;
23326 }
23327 std::string response = transceiver_->SendCommandAndWait(command);
23328 rc = ParseResponse_PolicyCommandCode(response, authorization_delegate);
23329 return rc;
23330 }
23331
SerializeCommand_PolicyPhysicalPresence(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23332 TPM_RC Tpm::SerializeCommand_PolicyPhysicalPresence(
23333 const TPMI_SH_POLICY& policy_session,
23334 const std::string& policy_session_name,
23335 std::string* serialized_command,
23336 AuthorizationDelegate* authorization_delegate) {
23337 VLOG(3) << __func__;
23338 TPM_RC rc = TPM_RC_SUCCESS;
23339 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23340 UINT32 command_size = 10; // Header size.
23341 std::string handle_section_bytes;
23342 std::string parameter_section_bytes;
23343 TPM_CC command_code = TPM_CC_PolicyPhysicalPresence;
23344 bool is_command_parameter_encryption_possible = false;
23345 bool is_response_parameter_encryption_possible = false;
23346 std::string command_code_bytes;
23347 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23348 if (rc != TPM_RC_SUCCESS) {
23349 return rc;
23350 }
23351 std::string policy_session_bytes;
23352 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23353 if (rc != TPM_RC_SUCCESS) {
23354 return rc;
23355 }
23356 std::unique_ptr<crypto::SecureHash> hash(
23357 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23358 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23359 hash->Update(policy_session_name.data(), policy_session_name.size());
23360 handle_section_bytes += policy_session_bytes;
23361 command_size += policy_session_bytes.size();
23362 std::string command_hash(32, 0);
23363 hash->Finish(std::data(command_hash), command_hash.size());
23364 std::string authorization_section_bytes;
23365 std::string authorization_size_bytes;
23366 if (authorization_delegate) {
23367 if (!authorization_delegate->GetCommandAuthorization(
23368 command_hash, is_command_parameter_encryption_possible,
23369 is_response_parameter_encryption_possible,
23370 &authorization_section_bytes)) {
23371 return TRUNKS_RC_AUTHORIZATION_FAILED;
23372 }
23373 if (!authorization_section_bytes.empty()) {
23374 tag = TPM_ST_SESSIONS;
23375 std::string tmp;
23376 rc = Serialize_UINT32(authorization_section_bytes.size(),
23377 &authorization_size_bytes);
23378 if (rc != TPM_RC_SUCCESS) {
23379 return rc;
23380 }
23381 command_size +=
23382 authorization_size_bytes.size() + authorization_section_bytes.size();
23383 }
23384 }
23385 std::string tag_bytes;
23386 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23387 if (rc != TPM_RC_SUCCESS) {
23388 return rc;
23389 }
23390 std::string command_size_bytes;
23391 rc = Serialize_UINT32(command_size, &command_size_bytes);
23392 if (rc != TPM_RC_SUCCESS) {
23393 return rc;
23394 }
23395 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23396 handle_section_bytes + authorization_size_bytes +
23397 authorization_section_bytes + parameter_section_bytes;
23398 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23399 VLOG(2) << "Command: "
23400 << base::HexEncode(serialized_command->data(),
23401 serialized_command->size());
23402 return TPM_RC_SUCCESS;
23403 }
23404
ParseResponse_PolicyPhysicalPresence(const std::string & response,AuthorizationDelegate * authorization_delegate)23405 TPM_RC Tpm::ParseResponse_PolicyPhysicalPresence(
23406 const std::string& response,
23407 AuthorizationDelegate* authorization_delegate) {
23408 VLOG(3) << __func__;
23409 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23410 TPM_RC rc = TPM_RC_SUCCESS;
23411 std::string buffer(response);
23412 TPM_ST tag;
23413 std::string tag_bytes;
23414 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23415 if (rc != TPM_RC_SUCCESS) {
23416 return rc;
23417 }
23418 UINT32 response_size;
23419 std::string response_size_bytes;
23420 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23421 if (rc != TPM_RC_SUCCESS) {
23422 return rc;
23423 }
23424 TPM_RC response_code;
23425 std::string response_code_bytes;
23426 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23427 if (rc != TPM_RC_SUCCESS) {
23428 return rc;
23429 }
23430 if (response_size != response.size()) {
23431 return TPM_RC_SIZE;
23432 }
23433 if (response_code != TPM_RC_SUCCESS) {
23434 return response_code;
23435 }
23436 TPM_CC command_code = TPM_CC_PolicyPhysicalPresence;
23437 std::string command_code_bytes;
23438 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23439 if (rc != TPM_RC_SUCCESS) {
23440 return rc;
23441 }
23442 std::string authorization_section_bytes;
23443 if (tag == TPM_ST_SESSIONS) {
23444 UINT32 parameter_section_size = buffer.size();
23445 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
23446 if (rc != TPM_RC_SUCCESS) {
23447 return rc;
23448 }
23449 if (parameter_section_size > buffer.size()) {
23450 return TPM_RC_INSUFFICIENT;
23451 }
23452 authorization_section_bytes = buffer.substr(parameter_section_size);
23453 // Keep the parameter section in |buffer|.
23454 buffer.erase(parameter_section_size);
23455 }
23456 std::unique_ptr<crypto::SecureHash> hash(
23457 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23458 hash->Update(response_code_bytes.data(), response_code_bytes.size());
23459 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23460 hash->Update(buffer.data(), buffer.size());
23461 std::string response_hash(32, 0);
23462 hash->Finish(std::data(response_hash), response_hash.size());
23463 if (tag == TPM_ST_SESSIONS) {
23464 if (!authorization_delegate)
23465 return TRUNKS_RC_AUTHORIZATION_FAILED;
23466 if (!authorization_delegate->CheckResponseAuthorization(
23467 response_hash, authorization_section_bytes)) {
23468 return TRUNKS_RC_AUTHORIZATION_FAILED;
23469 }
23470 }
23471 return TPM_RC_SUCCESS;
23472 }
23473
PolicyPhysicalPresenceErrorCallback(Tpm::PolicyPhysicalPresenceResponse callback,TPM_RC response_code)23474 void PolicyPhysicalPresenceErrorCallback(
23475 Tpm::PolicyPhysicalPresenceResponse callback, TPM_RC response_code) {
23476 VLOG(1) << __func__;
23477 std::move(callback).Run(response_code);
23478 }
23479
PolicyPhysicalPresenceResponseParser(Tpm::PolicyPhysicalPresenceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23480 void PolicyPhysicalPresenceResponseParser(
23481 Tpm::PolicyPhysicalPresenceResponse callback,
23482 AuthorizationDelegate* authorization_delegate,
23483 const std::string& response) {
23484 VLOG(1) << __func__;
23485 TPM_RC rc = Tpm::ParseResponse_PolicyPhysicalPresence(response,
23486 authorization_delegate);
23487 if (rc != TPM_RC_SUCCESS) {
23488 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
23489 PolicyPhysicalPresenceErrorCallback, std::move(callback));
23490 std::move(error_reporter).Run(rc);
23491 return;
23492 }
23493 std::move(callback).Run(rc);
23494 }
23495
PolicyPhysicalPresence(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyPhysicalPresenceResponse callback)23496 void Tpm::PolicyPhysicalPresence(const TPMI_SH_POLICY& policy_session,
23497 const std::string& policy_session_name,
23498 AuthorizationDelegate* authorization_delegate,
23499 PolicyPhysicalPresenceResponse callback) {
23500 VLOG(1) << __func__;
23501 std::string command;
23502 TPM_RC rc = SerializeCommand_PolicyPhysicalPresence(
23503 policy_session, policy_session_name, &command, authorization_delegate);
23504 if (rc != TPM_RC_SUCCESS) {
23505 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
23506 PolicyPhysicalPresenceErrorCallback, std::move(callback));
23507 std::move(error_reporter).Run(rc);
23508 return;
23509 }
23510 base::OnceCallback<void(const std::string&)> parser =
23511 base::BindOnce(PolicyPhysicalPresenceResponseParser, std::move(callback),
23512 authorization_delegate);
23513 transceiver_->SendCommand(command, std::move(parser));
23514 }
23515
PolicyPhysicalPresenceSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)23516 TPM_RC Tpm::PolicyPhysicalPresenceSync(
23517 const TPMI_SH_POLICY& policy_session,
23518 const std::string& policy_session_name,
23519 AuthorizationDelegate* authorization_delegate) {
23520 VLOG(1) << __func__;
23521 std::string command;
23522 TPM_RC rc = SerializeCommand_PolicyPhysicalPresence(
23523 policy_session, policy_session_name, &command, authorization_delegate);
23524 if (rc != TPM_RC_SUCCESS) {
23525 return rc;
23526 }
23527 std::string response = transceiver_->SendCommandAndWait(command);
23528 rc = ParseResponse_PolicyPhysicalPresence(response, authorization_delegate);
23529 return rc;
23530 }
23531
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)23532 TPM_RC Tpm::SerializeCommand_PolicyCpHash(
23533 const TPMI_SH_POLICY& policy_session,
23534 const std::string& policy_session_name,
23535 const TPM2B_DIGEST& cp_hash_a,
23536 std::string* serialized_command,
23537 AuthorizationDelegate* authorization_delegate) {
23538 VLOG(3) << __func__;
23539 TPM_RC rc = TPM_RC_SUCCESS;
23540 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23541 UINT32 command_size = 10; // Header size.
23542 std::string handle_section_bytes;
23543 std::string parameter_section_bytes;
23544 TPM_CC command_code = TPM_CC_PolicyCpHash;
23545 bool is_command_parameter_encryption_possible = true;
23546 bool is_response_parameter_encryption_possible = false;
23547 std::string command_code_bytes;
23548 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23549 if (rc != TPM_RC_SUCCESS) {
23550 return rc;
23551 }
23552 std::string policy_session_bytes;
23553 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23554 if (rc != TPM_RC_SUCCESS) {
23555 return rc;
23556 }
23557 std::string cp_hash_a_bytes;
23558 rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
23559 if (rc != TPM_RC_SUCCESS) {
23560 return rc;
23561 }
23562 if (authorization_delegate) {
23563 // Encrypt just the parameter data, not the size.
23564 std::string tmp = cp_hash_a_bytes.substr(2);
23565 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23566 return TRUNKS_RC_ENCRYPTION_FAILED;
23567 }
23568 cp_hash_a_bytes.replace(2, std::string::npos, tmp);
23569 }
23570 std::unique_ptr<crypto::SecureHash> hash(
23571 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23572 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23573 hash->Update(policy_session_name.data(), policy_session_name.size());
23574 handle_section_bytes += policy_session_bytes;
23575 command_size += policy_session_bytes.size();
23576 hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
23577 parameter_section_bytes += cp_hash_a_bytes;
23578 command_size += cp_hash_a_bytes.size();
23579 std::string command_hash(32, 0);
23580 hash->Finish(std::data(command_hash), command_hash.size());
23581 std::string authorization_section_bytes;
23582 std::string authorization_size_bytes;
23583 if (authorization_delegate) {
23584 if (!authorization_delegate->GetCommandAuthorization(
23585 command_hash, is_command_parameter_encryption_possible,
23586 is_response_parameter_encryption_possible,
23587 &authorization_section_bytes)) {
23588 return TRUNKS_RC_AUTHORIZATION_FAILED;
23589 }
23590 if (!authorization_section_bytes.empty()) {
23591 tag = TPM_ST_SESSIONS;
23592 std::string tmp;
23593 rc = Serialize_UINT32(authorization_section_bytes.size(),
23594 &authorization_size_bytes);
23595 if (rc != TPM_RC_SUCCESS) {
23596 return rc;
23597 }
23598 command_size +=
23599 authorization_size_bytes.size() + authorization_section_bytes.size();
23600 }
23601 }
23602 std::string tag_bytes;
23603 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23604 if (rc != TPM_RC_SUCCESS) {
23605 return rc;
23606 }
23607 std::string command_size_bytes;
23608 rc = Serialize_UINT32(command_size, &command_size_bytes);
23609 if (rc != TPM_RC_SUCCESS) {
23610 return rc;
23611 }
23612 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23613 handle_section_bytes + authorization_size_bytes +
23614 authorization_section_bytes + parameter_section_bytes;
23615 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23616 VLOG(2) << "Command: "
23617 << base::HexEncode(serialized_command->data(),
23618 serialized_command->size());
23619 return TPM_RC_SUCCESS;
23620 }
23621
ParseResponse_PolicyCpHash(const std::string & response,AuthorizationDelegate * authorization_delegate)23622 TPM_RC Tpm::ParseResponse_PolicyCpHash(
23623 const std::string& response,
23624 AuthorizationDelegate* authorization_delegate) {
23625 VLOG(3) << __func__;
23626 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23627 TPM_RC rc = TPM_RC_SUCCESS;
23628 std::string buffer(response);
23629 TPM_ST tag;
23630 std::string tag_bytes;
23631 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23632 if (rc != TPM_RC_SUCCESS) {
23633 return rc;
23634 }
23635 UINT32 response_size;
23636 std::string response_size_bytes;
23637 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23638 if (rc != TPM_RC_SUCCESS) {
23639 return rc;
23640 }
23641 TPM_RC response_code;
23642 std::string response_code_bytes;
23643 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23644 if (rc != TPM_RC_SUCCESS) {
23645 return rc;
23646 }
23647 if (response_size != response.size()) {
23648 return TPM_RC_SIZE;
23649 }
23650 if (response_code != TPM_RC_SUCCESS) {
23651 return response_code;
23652 }
23653 TPM_CC command_code = TPM_CC_PolicyCpHash;
23654 std::string command_code_bytes;
23655 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23656 if (rc != TPM_RC_SUCCESS) {
23657 return rc;
23658 }
23659 std::string authorization_section_bytes;
23660 if (tag == TPM_ST_SESSIONS) {
23661 UINT32 parameter_section_size = buffer.size();
23662 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
23663 if (rc != TPM_RC_SUCCESS) {
23664 return rc;
23665 }
23666 if (parameter_section_size > buffer.size()) {
23667 return TPM_RC_INSUFFICIENT;
23668 }
23669 authorization_section_bytes = buffer.substr(parameter_section_size);
23670 // Keep the parameter section in |buffer|.
23671 buffer.erase(parameter_section_size);
23672 }
23673 std::unique_ptr<crypto::SecureHash> hash(
23674 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23675 hash->Update(response_code_bytes.data(), response_code_bytes.size());
23676 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23677 hash->Update(buffer.data(), buffer.size());
23678 std::string response_hash(32, 0);
23679 hash->Finish(std::data(response_hash), response_hash.size());
23680 if (tag == TPM_ST_SESSIONS) {
23681 if (!authorization_delegate)
23682 return TRUNKS_RC_AUTHORIZATION_FAILED;
23683 if (!authorization_delegate->CheckResponseAuthorization(
23684 response_hash, authorization_section_bytes)) {
23685 return TRUNKS_RC_AUTHORIZATION_FAILED;
23686 }
23687 }
23688 return TPM_RC_SUCCESS;
23689 }
23690
PolicyCpHashErrorCallback(Tpm::PolicyCpHashResponse callback,TPM_RC response_code)23691 void PolicyCpHashErrorCallback(Tpm::PolicyCpHashResponse callback,
23692 TPM_RC response_code) {
23693 VLOG(1) << __func__;
23694 std::move(callback).Run(response_code);
23695 }
23696
PolicyCpHashResponseParser(Tpm::PolicyCpHashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23697 void PolicyCpHashResponseParser(Tpm::PolicyCpHashResponse callback,
23698 AuthorizationDelegate* authorization_delegate,
23699 const std::string& response) {
23700 VLOG(1) << __func__;
23701 TPM_RC rc = Tpm::ParseResponse_PolicyCpHash(response, authorization_delegate);
23702 if (rc != TPM_RC_SUCCESS) {
23703 base::OnceCallback<void(TPM_RC)> error_reporter =
23704 base::BindOnce(PolicyCpHashErrorCallback, std::move(callback));
23705 std::move(error_reporter).Run(rc);
23706 return;
23707 }
23708 std::move(callback).Run(rc);
23709 }
23710
PolicyCpHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,AuthorizationDelegate * authorization_delegate,PolicyCpHashResponse callback)23711 void Tpm::PolicyCpHash(const TPMI_SH_POLICY& policy_session,
23712 const std::string& policy_session_name,
23713 const TPM2B_DIGEST& cp_hash_a,
23714 AuthorizationDelegate* authorization_delegate,
23715 PolicyCpHashResponse callback) {
23716 VLOG(1) << __func__;
23717 std::string command;
23718 TPM_RC rc = SerializeCommand_PolicyCpHash(policy_session, policy_session_name,
23719 cp_hash_a, &command,
23720 authorization_delegate);
23721 if (rc != TPM_RC_SUCCESS) {
23722 base::OnceCallback<void(TPM_RC)> error_reporter =
23723 base::BindOnce(PolicyCpHashErrorCallback, std::move(callback));
23724 std::move(error_reporter).Run(rc);
23725 return;
23726 }
23727 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
23728 PolicyCpHashResponseParser, std::move(callback), authorization_delegate);
23729 transceiver_->SendCommand(command, std::move(parser));
23730 }
23731
PolicyCpHashSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,AuthorizationDelegate * authorization_delegate)23732 TPM_RC Tpm::PolicyCpHashSync(const TPMI_SH_POLICY& policy_session,
23733 const std::string& policy_session_name,
23734 const TPM2B_DIGEST& cp_hash_a,
23735 AuthorizationDelegate* authorization_delegate) {
23736 VLOG(1) << __func__;
23737 std::string command;
23738 TPM_RC rc = SerializeCommand_PolicyCpHash(policy_session, policy_session_name,
23739 cp_hash_a, &command,
23740 authorization_delegate);
23741 if (rc != TPM_RC_SUCCESS) {
23742 return rc;
23743 }
23744 std::string response = transceiver_->SendCommandAndWait(command);
23745 rc = ParseResponse_PolicyCpHash(response, authorization_delegate);
23746 return rc;
23747 }
23748
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)23749 TPM_RC Tpm::SerializeCommand_PolicyNameHash(
23750 const TPMI_SH_POLICY& policy_session,
23751 const std::string& policy_session_name,
23752 const TPM2B_DIGEST& name_hash,
23753 std::string* serialized_command,
23754 AuthorizationDelegate* authorization_delegate) {
23755 VLOG(3) << __func__;
23756 TPM_RC rc = TPM_RC_SUCCESS;
23757 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23758 UINT32 command_size = 10; // Header size.
23759 std::string handle_section_bytes;
23760 std::string parameter_section_bytes;
23761 TPM_CC command_code = TPM_CC_PolicyNameHash;
23762 bool is_command_parameter_encryption_possible = true;
23763 bool is_response_parameter_encryption_possible = false;
23764 std::string command_code_bytes;
23765 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23766 if (rc != TPM_RC_SUCCESS) {
23767 return rc;
23768 }
23769 std::string policy_session_bytes;
23770 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23771 if (rc != TPM_RC_SUCCESS) {
23772 return rc;
23773 }
23774 std::string name_hash_bytes;
23775 rc = Serialize_TPM2B_DIGEST(name_hash, &name_hash_bytes);
23776 if (rc != TPM_RC_SUCCESS) {
23777 return rc;
23778 }
23779 if (authorization_delegate) {
23780 // Encrypt just the parameter data, not the size.
23781 std::string tmp = name_hash_bytes.substr(2);
23782 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23783 return TRUNKS_RC_ENCRYPTION_FAILED;
23784 }
23785 name_hash_bytes.replace(2, std::string::npos, tmp);
23786 }
23787 std::unique_ptr<crypto::SecureHash> hash(
23788 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23789 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23790 hash->Update(policy_session_name.data(), policy_session_name.size());
23791 handle_section_bytes += policy_session_bytes;
23792 command_size += policy_session_bytes.size();
23793 hash->Update(name_hash_bytes.data(), name_hash_bytes.size());
23794 parameter_section_bytes += name_hash_bytes;
23795 command_size += name_hash_bytes.size();
23796 std::string command_hash(32, 0);
23797 hash->Finish(std::data(command_hash), command_hash.size());
23798 std::string authorization_section_bytes;
23799 std::string authorization_size_bytes;
23800 if (authorization_delegate) {
23801 if (!authorization_delegate->GetCommandAuthorization(
23802 command_hash, is_command_parameter_encryption_possible,
23803 is_response_parameter_encryption_possible,
23804 &authorization_section_bytes)) {
23805 return TRUNKS_RC_AUTHORIZATION_FAILED;
23806 }
23807 if (!authorization_section_bytes.empty()) {
23808 tag = TPM_ST_SESSIONS;
23809 std::string tmp;
23810 rc = Serialize_UINT32(authorization_section_bytes.size(),
23811 &authorization_size_bytes);
23812 if (rc != TPM_RC_SUCCESS) {
23813 return rc;
23814 }
23815 command_size +=
23816 authorization_size_bytes.size() + authorization_section_bytes.size();
23817 }
23818 }
23819 std::string tag_bytes;
23820 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23821 if (rc != TPM_RC_SUCCESS) {
23822 return rc;
23823 }
23824 std::string command_size_bytes;
23825 rc = Serialize_UINT32(command_size, &command_size_bytes);
23826 if (rc != TPM_RC_SUCCESS) {
23827 return rc;
23828 }
23829 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23830 handle_section_bytes + authorization_size_bytes +
23831 authorization_section_bytes + parameter_section_bytes;
23832 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23833 VLOG(2) << "Command: "
23834 << base::HexEncode(serialized_command->data(),
23835 serialized_command->size());
23836 return TPM_RC_SUCCESS;
23837 }
23838
ParseResponse_PolicyNameHash(const std::string & response,AuthorizationDelegate * authorization_delegate)23839 TPM_RC Tpm::ParseResponse_PolicyNameHash(
23840 const std::string& response,
23841 AuthorizationDelegate* authorization_delegate) {
23842 VLOG(3) << __func__;
23843 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23844 TPM_RC rc = TPM_RC_SUCCESS;
23845 std::string buffer(response);
23846 TPM_ST tag;
23847 std::string tag_bytes;
23848 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23849 if (rc != TPM_RC_SUCCESS) {
23850 return rc;
23851 }
23852 UINT32 response_size;
23853 std::string response_size_bytes;
23854 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23855 if (rc != TPM_RC_SUCCESS) {
23856 return rc;
23857 }
23858 TPM_RC response_code;
23859 std::string response_code_bytes;
23860 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23861 if (rc != TPM_RC_SUCCESS) {
23862 return rc;
23863 }
23864 if (response_size != response.size()) {
23865 return TPM_RC_SIZE;
23866 }
23867 if (response_code != TPM_RC_SUCCESS) {
23868 return response_code;
23869 }
23870 TPM_CC command_code = TPM_CC_PolicyNameHash;
23871 std::string command_code_bytes;
23872 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23873 if (rc != TPM_RC_SUCCESS) {
23874 return rc;
23875 }
23876 std::string authorization_section_bytes;
23877 if (tag == TPM_ST_SESSIONS) {
23878 UINT32 parameter_section_size = buffer.size();
23879 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
23880 if (rc != TPM_RC_SUCCESS) {
23881 return rc;
23882 }
23883 if (parameter_section_size > buffer.size()) {
23884 return TPM_RC_INSUFFICIENT;
23885 }
23886 authorization_section_bytes = buffer.substr(parameter_section_size);
23887 // Keep the parameter section in |buffer|.
23888 buffer.erase(parameter_section_size);
23889 }
23890 std::unique_ptr<crypto::SecureHash> hash(
23891 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23892 hash->Update(response_code_bytes.data(), response_code_bytes.size());
23893 hash->Update(command_code_bytes.data(), command_code_bytes.size());
23894 hash->Update(buffer.data(), buffer.size());
23895 std::string response_hash(32, 0);
23896 hash->Finish(std::data(response_hash), response_hash.size());
23897 if (tag == TPM_ST_SESSIONS) {
23898 if (!authorization_delegate)
23899 return TRUNKS_RC_AUTHORIZATION_FAILED;
23900 if (!authorization_delegate->CheckResponseAuthorization(
23901 response_hash, authorization_section_bytes)) {
23902 return TRUNKS_RC_AUTHORIZATION_FAILED;
23903 }
23904 }
23905 return TPM_RC_SUCCESS;
23906 }
23907
PolicyNameHashErrorCallback(Tpm::PolicyNameHashResponse callback,TPM_RC response_code)23908 void PolicyNameHashErrorCallback(Tpm::PolicyNameHashResponse callback,
23909 TPM_RC response_code) {
23910 VLOG(1) << __func__;
23911 std::move(callback).Run(response_code);
23912 }
23913
PolicyNameHashResponseParser(Tpm::PolicyNameHashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23914 void PolicyNameHashResponseParser(Tpm::PolicyNameHashResponse callback,
23915 AuthorizationDelegate* authorization_delegate,
23916 const std::string& response) {
23917 VLOG(1) << __func__;
23918 TPM_RC rc =
23919 Tpm::ParseResponse_PolicyNameHash(response, authorization_delegate);
23920 if (rc != TPM_RC_SUCCESS) {
23921 base::OnceCallback<void(TPM_RC)> error_reporter =
23922 base::BindOnce(PolicyNameHashErrorCallback, std::move(callback));
23923 std::move(error_reporter).Run(rc);
23924 return;
23925 }
23926 std::move(callback).Run(rc);
23927 }
23928
PolicyNameHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,AuthorizationDelegate * authorization_delegate,PolicyNameHashResponse callback)23929 void Tpm::PolicyNameHash(const TPMI_SH_POLICY& policy_session,
23930 const std::string& policy_session_name,
23931 const TPM2B_DIGEST& name_hash,
23932 AuthorizationDelegate* authorization_delegate,
23933 PolicyNameHashResponse callback) {
23934 VLOG(1) << __func__;
23935 std::string command;
23936 TPM_RC rc = SerializeCommand_PolicyNameHash(policy_session,
23937 policy_session_name, name_hash,
23938 &command, authorization_delegate);
23939 if (rc != TPM_RC_SUCCESS) {
23940 base::OnceCallback<void(TPM_RC)> error_reporter =
23941 base::BindOnce(PolicyNameHashErrorCallback, std::move(callback));
23942 std::move(error_reporter).Run(rc);
23943 return;
23944 }
23945 base::OnceCallback<void(const std::string&)> parser =
23946 base::BindOnce(PolicyNameHashResponseParser, std::move(callback),
23947 authorization_delegate);
23948 transceiver_->SendCommand(command, std::move(parser));
23949 }
23950
PolicyNameHashSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,AuthorizationDelegate * authorization_delegate)23951 TPM_RC Tpm::PolicyNameHashSync(const TPMI_SH_POLICY& policy_session,
23952 const std::string& policy_session_name,
23953 const TPM2B_DIGEST& name_hash,
23954 AuthorizationDelegate* authorization_delegate) {
23955 VLOG(1) << __func__;
23956 std::string command;
23957 TPM_RC rc = SerializeCommand_PolicyNameHash(policy_session,
23958 policy_session_name, name_hash,
23959 &command, authorization_delegate);
23960 if (rc != TPM_RC_SUCCESS) {
23961 return rc;
23962 }
23963 std::string response = transceiver_->SendCommandAndWait(command);
23964 rc = ParseResponse_PolicyNameHash(response, authorization_delegate);
23965 return rc;
23966 }
23967
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)23968 TPM_RC Tpm::SerializeCommand_PolicyDuplicationSelect(
23969 const TPMI_SH_POLICY& policy_session,
23970 const std::string& policy_session_name,
23971 const TPM2B_NAME& object_name,
23972 const TPM2B_NAME& new_parent_name,
23973 const TPMI_YES_NO& include_object,
23974 std::string* serialized_command,
23975 AuthorizationDelegate* authorization_delegate) {
23976 VLOG(3) << __func__;
23977 TPM_RC rc = TPM_RC_SUCCESS;
23978 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23979 UINT32 command_size = 10; // Header size.
23980 std::string handle_section_bytes;
23981 std::string parameter_section_bytes;
23982 TPM_CC command_code = TPM_CC_PolicyDuplicationSelect;
23983 bool is_command_parameter_encryption_possible = true;
23984 bool is_response_parameter_encryption_possible = false;
23985 std::string command_code_bytes;
23986 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23987 if (rc != TPM_RC_SUCCESS) {
23988 return rc;
23989 }
23990 std::string policy_session_bytes;
23991 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23992 if (rc != TPM_RC_SUCCESS) {
23993 return rc;
23994 }
23995 std::string object_name_bytes;
23996 rc = Serialize_TPM2B_NAME(object_name, &object_name_bytes);
23997 if (rc != TPM_RC_SUCCESS) {
23998 return rc;
23999 }
24000 std::string new_parent_name_bytes;
24001 rc = Serialize_TPM2B_NAME(new_parent_name, &new_parent_name_bytes);
24002 if (rc != TPM_RC_SUCCESS) {
24003 return rc;
24004 }
24005 std::string include_object_bytes;
24006 rc = Serialize_TPMI_YES_NO(include_object, &include_object_bytes);
24007 if (rc != TPM_RC_SUCCESS) {
24008 return rc;
24009 }
24010 if (authorization_delegate) {
24011 // Encrypt just the parameter data, not the size.
24012 std::string tmp = object_name_bytes.substr(2);
24013 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
24014 return TRUNKS_RC_ENCRYPTION_FAILED;
24015 }
24016 object_name_bytes.replace(2, std::string::npos, tmp);
24017 }
24018 std::unique_ptr<crypto::SecureHash> hash(
24019 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24020 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24021 hash->Update(policy_session_name.data(), policy_session_name.size());
24022 handle_section_bytes += policy_session_bytes;
24023 command_size += policy_session_bytes.size();
24024 hash->Update(object_name_bytes.data(), object_name_bytes.size());
24025 parameter_section_bytes += object_name_bytes;
24026 command_size += object_name_bytes.size();
24027 hash->Update(new_parent_name_bytes.data(), new_parent_name_bytes.size());
24028 parameter_section_bytes += new_parent_name_bytes;
24029 command_size += new_parent_name_bytes.size();
24030 hash->Update(include_object_bytes.data(), include_object_bytes.size());
24031 parameter_section_bytes += include_object_bytes;
24032 command_size += include_object_bytes.size();
24033 std::string command_hash(32, 0);
24034 hash->Finish(std::data(command_hash), command_hash.size());
24035 std::string authorization_section_bytes;
24036 std::string authorization_size_bytes;
24037 if (authorization_delegate) {
24038 if (!authorization_delegate->GetCommandAuthorization(
24039 command_hash, is_command_parameter_encryption_possible,
24040 is_response_parameter_encryption_possible,
24041 &authorization_section_bytes)) {
24042 return TRUNKS_RC_AUTHORIZATION_FAILED;
24043 }
24044 if (!authorization_section_bytes.empty()) {
24045 tag = TPM_ST_SESSIONS;
24046 std::string tmp;
24047 rc = Serialize_UINT32(authorization_section_bytes.size(),
24048 &authorization_size_bytes);
24049 if (rc != TPM_RC_SUCCESS) {
24050 return rc;
24051 }
24052 command_size +=
24053 authorization_size_bytes.size() + authorization_section_bytes.size();
24054 }
24055 }
24056 std::string tag_bytes;
24057 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24058 if (rc != TPM_RC_SUCCESS) {
24059 return rc;
24060 }
24061 std::string command_size_bytes;
24062 rc = Serialize_UINT32(command_size, &command_size_bytes);
24063 if (rc != TPM_RC_SUCCESS) {
24064 return rc;
24065 }
24066 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24067 handle_section_bytes + authorization_size_bytes +
24068 authorization_section_bytes + parameter_section_bytes;
24069 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24070 VLOG(2) << "Command: "
24071 << base::HexEncode(serialized_command->data(),
24072 serialized_command->size());
24073 return TPM_RC_SUCCESS;
24074 }
24075
ParseResponse_PolicyDuplicationSelect(const std::string & response,AuthorizationDelegate * authorization_delegate)24076 TPM_RC Tpm::ParseResponse_PolicyDuplicationSelect(
24077 const std::string& response,
24078 AuthorizationDelegate* authorization_delegate) {
24079 VLOG(3) << __func__;
24080 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24081 TPM_RC rc = TPM_RC_SUCCESS;
24082 std::string buffer(response);
24083 TPM_ST tag;
24084 std::string tag_bytes;
24085 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24086 if (rc != TPM_RC_SUCCESS) {
24087 return rc;
24088 }
24089 UINT32 response_size;
24090 std::string response_size_bytes;
24091 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24092 if (rc != TPM_RC_SUCCESS) {
24093 return rc;
24094 }
24095 TPM_RC response_code;
24096 std::string response_code_bytes;
24097 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24098 if (rc != TPM_RC_SUCCESS) {
24099 return rc;
24100 }
24101 if (response_size != response.size()) {
24102 return TPM_RC_SIZE;
24103 }
24104 if (response_code != TPM_RC_SUCCESS) {
24105 return response_code;
24106 }
24107 TPM_CC command_code = TPM_CC_PolicyDuplicationSelect;
24108 std::string command_code_bytes;
24109 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24110 if (rc != TPM_RC_SUCCESS) {
24111 return rc;
24112 }
24113 std::string authorization_section_bytes;
24114 if (tag == TPM_ST_SESSIONS) {
24115 UINT32 parameter_section_size = buffer.size();
24116 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
24117 if (rc != TPM_RC_SUCCESS) {
24118 return rc;
24119 }
24120 if (parameter_section_size > buffer.size()) {
24121 return TPM_RC_INSUFFICIENT;
24122 }
24123 authorization_section_bytes = buffer.substr(parameter_section_size);
24124 // Keep the parameter section in |buffer|.
24125 buffer.erase(parameter_section_size);
24126 }
24127 std::unique_ptr<crypto::SecureHash> hash(
24128 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24129 hash->Update(response_code_bytes.data(), response_code_bytes.size());
24130 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24131 hash->Update(buffer.data(), buffer.size());
24132 std::string response_hash(32, 0);
24133 hash->Finish(std::data(response_hash), response_hash.size());
24134 if (tag == TPM_ST_SESSIONS) {
24135 if (!authorization_delegate)
24136 return TRUNKS_RC_AUTHORIZATION_FAILED;
24137 if (!authorization_delegate->CheckResponseAuthorization(
24138 response_hash, authorization_section_bytes)) {
24139 return TRUNKS_RC_AUTHORIZATION_FAILED;
24140 }
24141 }
24142 return TPM_RC_SUCCESS;
24143 }
24144
PolicyDuplicationSelectErrorCallback(Tpm::PolicyDuplicationSelectResponse callback,TPM_RC response_code)24145 void PolicyDuplicationSelectErrorCallback(
24146 Tpm::PolicyDuplicationSelectResponse callback, TPM_RC response_code) {
24147 VLOG(1) << __func__;
24148 std::move(callback).Run(response_code);
24149 }
24150
PolicyDuplicationSelectResponseParser(Tpm::PolicyDuplicationSelectResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24151 void PolicyDuplicationSelectResponseParser(
24152 Tpm::PolicyDuplicationSelectResponse callback,
24153 AuthorizationDelegate* authorization_delegate,
24154 const std::string& response) {
24155 VLOG(1) << __func__;
24156 TPM_RC rc = Tpm::ParseResponse_PolicyDuplicationSelect(
24157 response, authorization_delegate);
24158 if (rc != TPM_RC_SUCCESS) {
24159 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
24160 PolicyDuplicationSelectErrorCallback, std::move(callback));
24161 std::move(error_reporter).Run(rc);
24162 return;
24163 }
24164 std::move(callback).Run(rc);
24165 }
24166
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)24167 void Tpm::PolicyDuplicationSelect(const TPMI_SH_POLICY& policy_session,
24168 const std::string& policy_session_name,
24169 const TPM2B_NAME& object_name,
24170 const TPM2B_NAME& new_parent_name,
24171 const TPMI_YES_NO& include_object,
24172 AuthorizationDelegate* authorization_delegate,
24173 PolicyDuplicationSelectResponse callback) {
24174 VLOG(1) << __func__;
24175 std::string command;
24176 TPM_RC rc = SerializeCommand_PolicyDuplicationSelect(
24177 policy_session, policy_session_name, object_name, new_parent_name,
24178 include_object, &command, authorization_delegate);
24179 if (rc != TPM_RC_SUCCESS) {
24180 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
24181 PolicyDuplicationSelectErrorCallback, std::move(callback));
24182 std::move(error_reporter).Run(rc);
24183 return;
24184 }
24185 base::OnceCallback<void(const std::string&)> parser =
24186 base::BindOnce(PolicyDuplicationSelectResponseParser, std::move(callback),
24187 authorization_delegate);
24188 transceiver_->SendCommand(command, std::move(parser));
24189 }
24190
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)24191 TPM_RC Tpm::PolicyDuplicationSelectSync(
24192 const TPMI_SH_POLICY& policy_session,
24193 const std::string& policy_session_name,
24194 const TPM2B_NAME& object_name,
24195 const TPM2B_NAME& new_parent_name,
24196 const TPMI_YES_NO& include_object,
24197 AuthorizationDelegate* authorization_delegate) {
24198 VLOG(1) << __func__;
24199 std::string command;
24200 TPM_RC rc = SerializeCommand_PolicyDuplicationSelect(
24201 policy_session, policy_session_name, object_name, new_parent_name,
24202 include_object, &command, authorization_delegate);
24203 if (rc != TPM_RC_SUCCESS) {
24204 return rc;
24205 }
24206 std::string response = transceiver_->SendCommandAndWait(command);
24207 rc = ParseResponse_PolicyDuplicationSelect(response, authorization_delegate);
24208 return rc;
24209 }
24210
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)24211 TPM_RC Tpm::SerializeCommand_PolicyAuthorize(
24212 const TPMI_SH_POLICY& policy_session,
24213 const std::string& policy_session_name,
24214 const TPM2B_DIGEST& approved_policy,
24215 const TPM2B_NONCE& policy_ref,
24216 const TPM2B_NAME& key_sign,
24217 const TPMT_TK_VERIFIED& check_ticket,
24218 std::string* serialized_command,
24219 AuthorizationDelegate* authorization_delegate) {
24220 VLOG(3) << __func__;
24221 TPM_RC rc = TPM_RC_SUCCESS;
24222 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24223 UINT32 command_size = 10; // Header size.
24224 std::string handle_section_bytes;
24225 std::string parameter_section_bytes;
24226 TPM_CC command_code = TPM_CC_PolicyAuthorize;
24227 bool is_command_parameter_encryption_possible = true;
24228 bool is_response_parameter_encryption_possible = false;
24229 std::string command_code_bytes;
24230 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24231 if (rc != TPM_RC_SUCCESS) {
24232 return rc;
24233 }
24234 std::string policy_session_bytes;
24235 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24236 if (rc != TPM_RC_SUCCESS) {
24237 return rc;
24238 }
24239 std::string approved_policy_bytes;
24240 rc = Serialize_TPM2B_DIGEST(approved_policy, &approved_policy_bytes);
24241 if (rc != TPM_RC_SUCCESS) {
24242 return rc;
24243 }
24244 std::string policy_ref_bytes;
24245 rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
24246 if (rc != TPM_RC_SUCCESS) {
24247 return rc;
24248 }
24249 std::string key_sign_bytes;
24250 rc = Serialize_TPM2B_NAME(key_sign, &key_sign_bytes);
24251 if (rc != TPM_RC_SUCCESS) {
24252 return rc;
24253 }
24254 std::string check_ticket_bytes;
24255 rc = Serialize_TPMT_TK_VERIFIED(check_ticket, &check_ticket_bytes);
24256 if (rc != TPM_RC_SUCCESS) {
24257 return rc;
24258 }
24259 if (authorization_delegate) {
24260 // Encrypt just the parameter data, not the size.
24261 std::string tmp = approved_policy_bytes.substr(2);
24262 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
24263 return TRUNKS_RC_ENCRYPTION_FAILED;
24264 }
24265 approved_policy_bytes.replace(2, std::string::npos, tmp);
24266 }
24267 std::unique_ptr<crypto::SecureHash> hash(
24268 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24269 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24270 hash->Update(policy_session_name.data(), policy_session_name.size());
24271 handle_section_bytes += policy_session_bytes;
24272 command_size += policy_session_bytes.size();
24273 hash->Update(approved_policy_bytes.data(), approved_policy_bytes.size());
24274 parameter_section_bytes += approved_policy_bytes;
24275 command_size += approved_policy_bytes.size();
24276 hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
24277 parameter_section_bytes += policy_ref_bytes;
24278 command_size += policy_ref_bytes.size();
24279 hash->Update(key_sign_bytes.data(), key_sign_bytes.size());
24280 parameter_section_bytes += key_sign_bytes;
24281 command_size += key_sign_bytes.size();
24282 hash->Update(check_ticket_bytes.data(), check_ticket_bytes.size());
24283 parameter_section_bytes += check_ticket_bytes;
24284 command_size += check_ticket_bytes.size();
24285 std::string command_hash(32, 0);
24286 hash->Finish(std::data(command_hash), command_hash.size());
24287 std::string authorization_section_bytes;
24288 std::string authorization_size_bytes;
24289 if (authorization_delegate) {
24290 if (!authorization_delegate->GetCommandAuthorization(
24291 command_hash, is_command_parameter_encryption_possible,
24292 is_response_parameter_encryption_possible,
24293 &authorization_section_bytes)) {
24294 return TRUNKS_RC_AUTHORIZATION_FAILED;
24295 }
24296 if (!authorization_section_bytes.empty()) {
24297 tag = TPM_ST_SESSIONS;
24298 std::string tmp;
24299 rc = Serialize_UINT32(authorization_section_bytes.size(),
24300 &authorization_size_bytes);
24301 if (rc != TPM_RC_SUCCESS) {
24302 return rc;
24303 }
24304 command_size +=
24305 authorization_size_bytes.size() + authorization_section_bytes.size();
24306 }
24307 }
24308 std::string tag_bytes;
24309 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24310 if (rc != TPM_RC_SUCCESS) {
24311 return rc;
24312 }
24313 std::string command_size_bytes;
24314 rc = Serialize_UINT32(command_size, &command_size_bytes);
24315 if (rc != TPM_RC_SUCCESS) {
24316 return rc;
24317 }
24318 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24319 handle_section_bytes + authorization_size_bytes +
24320 authorization_section_bytes + parameter_section_bytes;
24321 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24322 VLOG(2) << "Command: "
24323 << base::HexEncode(serialized_command->data(),
24324 serialized_command->size());
24325 return TPM_RC_SUCCESS;
24326 }
24327
ParseResponse_PolicyAuthorize(const std::string & response,AuthorizationDelegate * authorization_delegate)24328 TPM_RC Tpm::ParseResponse_PolicyAuthorize(
24329 const std::string& response,
24330 AuthorizationDelegate* authorization_delegate) {
24331 VLOG(3) << __func__;
24332 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24333 TPM_RC rc = TPM_RC_SUCCESS;
24334 std::string buffer(response);
24335 TPM_ST tag;
24336 std::string tag_bytes;
24337 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24338 if (rc != TPM_RC_SUCCESS) {
24339 return rc;
24340 }
24341 UINT32 response_size;
24342 std::string response_size_bytes;
24343 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24344 if (rc != TPM_RC_SUCCESS) {
24345 return rc;
24346 }
24347 TPM_RC response_code;
24348 std::string response_code_bytes;
24349 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24350 if (rc != TPM_RC_SUCCESS) {
24351 return rc;
24352 }
24353 if (response_size != response.size()) {
24354 return TPM_RC_SIZE;
24355 }
24356 if (response_code != TPM_RC_SUCCESS) {
24357 return response_code;
24358 }
24359 TPM_CC command_code = TPM_CC_PolicyAuthorize;
24360 std::string command_code_bytes;
24361 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24362 if (rc != TPM_RC_SUCCESS) {
24363 return rc;
24364 }
24365 std::string authorization_section_bytes;
24366 if (tag == TPM_ST_SESSIONS) {
24367 UINT32 parameter_section_size = buffer.size();
24368 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
24369 if (rc != TPM_RC_SUCCESS) {
24370 return rc;
24371 }
24372 if (parameter_section_size > buffer.size()) {
24373 return TPM_RC_INSUFFICIENT;
24374 }
24375 authorization_section_bytes = buffer.substr(parameter_section_size);
24376 // Keep the parameter section in |buffer|.
24377 buffer.erase(parameter_section_size);
24378 }
24379 std::unique_ptr<crypto::SecureHash> hash(
24380 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24381 hash->Update(response_code_bytes.data(), response_code_bytes.size());
24382 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24383 hash->Update(buffer.data(), buffer.size());
24384 std::string response_hash(32, 0);
24385 hash->Finish(std::data(response_hash), response_hash.size());
24386 if (tag == TPM_ST_SESSIONS) {
24387 if (!authorization_delegate)
24388 return TRUNKS_RC_AUTHORIZATION_FAILED;
24389 if (!authorization_delegate->CheckResponseAuthorization(
24390 response_hash, authorization_section_bytes)) {
24391 return TRUNKS_RC_AUTHORIZATION_FAILED;
24392 }
24393 }
24394 return TPM_RC_SUCCESS;
24395 }
24396
PolicyAuthorizeErrorCallback(Tpm::PolicyAuthorizeResponse callback,TPM_RC response_code)24397 void PolicyAuthorizeErrorCallback(Tpm::PolicyAuthorizeResponse callback,
24398 TPM_RC response_code) {
24399 VLOG(1) << __func__;
24400 std::move(callback).Run(response_code);
24401 }
24402
PolicyAuthorizeResponseParser(Tpm::PolicyAuthorizeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24403 void PolicyAuthorizeResponseParser(
24404 Tpm::PolicyAuthorizeResponse callback,
24405 AuthorizationDelegate* authorization_delegate,
24406 const std::string& response) {
24407 VLOG(1) << __func__;
24408 TPM_RC rc =
24409 Tpm::ParseResponse_PolicyAuthorize(response, authorization_delegate);
24410 if (rc != TPM_RC_SUCCESS) {
24411 base::OnceCallback<void(TPM_RC)> error_reporter =
24412 base::BindOnce(PolicyAuthorizeErrorCallback, std::move(callback));
24413 std::move(error_reporter).Run(rc);
24414 return;
24415 }
24416 std::move(callback).Run(rc);
24417 }
24418
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)24419 void Tpm::PolicyAuthorize(const TPMI_SH_POLICY& policy_session,
24420 const std::string& policy_session_name,
24421 const TPM2B_DIGEST& approved_policy,
24422 const TPM2B_NONCE& policy_ref,
24423 const TPM2B_NAME& key_sign,
24424 const TPMT_TK_VERIFIED& check_ticket,
24425 AuthorizationDelegate* authorization_delegate,
24426 PolicyAuthorizeResponse callback) {
24427 VLOG(1) << __func__;
24428 std::string command;
24429 TPM_RC rc = SerializeCommand_PolicyAuthorize(
24430 policy_session, policy_session_name, approved_policy, policy_ref,
24431 key_sign, check_ticket, &command, authorization_delegate);
24432 if (rc != TPM_RC_SUCCESS) {
24433 base::OnceCallback<void(TPM_RC)> error_reporter =
24434 base::BindOnce(PolicyAuthorizeErrorCallback, std::move(callback));
24435 std::move(error_reporter).Run(rc);
24436 return;
24437 }
24438 base::OnceCallback<void(const std::string&)> parser =
24439 base::BindOnce(PolicyAuthorizeResponseParser, std::move(callback),
24440 authorization_delegate);
24441 transceiver_->SendCommand(command, std::move(parser));
24442 }
24443
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)24444 TPM_RC Tpm::PolicyAuthorizeSync(const TPMI_SH_POLICY& policy_session,
24445 const std::string& policy_session_name,
24446 const TPM2B_DIGEST& approved_policy,
24447 const TPM2B_NONCE& policy_ref,
24448 const TPM2B_NAME& key_sign,
24449 const TPMT_TK_VERIFIED& check_ticket,
24450 AuthorizationDelegate* authorization_delegate) {
24451 VLOG(1) << __func__;
24452 std::string command;
24453 TPM_RC rc = SerializeCommand_PolicyAuthorize(
24454 policy_session, policy_session_name, approved_policy, policy_ref,
24455 key_sign, check_ticket, &command, authorization_delegate);
24456 if (rc != TPM_RC_SUCCESS) {
24457 return rc;
24458 }
24459 std::string response = transceiver_->SendCommandAndWait(command);
24460 rc = ParseResponse_PolicyAuthorize(response, authorization_delegate);
24461 return rc;
24462 }
24463
SerializeCommand_PolicyAuthValue(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24464 TPM_RC Tpm::SerializeCommand_PolicyAuthValue(
24465 const TPMI_SH_POLICY& policy_session,
24466 const std::string& policy_session_name,
24467 std::string* serialized_command,
24468 AuthorizationDelegate* authorization_delegate) {
24469 VLOG(3) << __func__;
24470 TPM_RC rc = TPM_RC_SUCCESS;
24471 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24472 UINT32 command_size = 10; // Header size.
24473 std::string handle_section_bytes;
24474 std::string parameter_section_bytes;
24475 TPM_CC command_code = TPM_CC_PolicyAuthValue;
24476 bool is_command_parameter_encryption_possible = false;
24477 bool is_response_parameter_encryption_possible = false;
24478 std::string command_code_bytes;
24479 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24480 if (rc != TPM_RC_SUCCESS) {
24481 return rc;
24482 }
24483 std::string policy_session_bytes;
24484 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24485 if (rc != TPM_RC_SUCCESS) {
24486 return rc;
24487 }
24488 std::unique_ptr<crypto::SecureHash> hash(
24489 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24490 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24491 hash->Update(policy_session_name.data(), policy_session_name.size());
24492 handle_section_bytes += policy_session_bytes;
24493 command_size += policy_session_bytes.size();
24494 std::string command_hash(32, 0);
24495 hash->Finish(std::data(command_hash), command_hash.size());
24496 std::string authorization_section_bytes;
24497 std::string authorization_size_bytes;
24498 if (authorization_delegate) {
24499 if (!authorization_delegate->GetCommandAuthorization(
24500 command_hash, is_command_parameter_encryption_possible,
24501 is_response_parameter_encryption_possible,
24502 &authorization_section_bytes)) {
24503 return TRUNKS_RC_AUTHORIZATION_FAILED;
24504 }
24505 if (!authorization_section_bytes.empty()) {
24506 tag = TPM_ST_SESSIONS;
24507 std::string tmp;
24508 rc = Serialize_UINT32(authorization_section_bytes.size(),
24509 &authorization_size_bytes);
24510 if (rc != TPM_RC_SUCCESS) {
24511 return rc;
24512 }
24513 command_size +=
24514 authorization_size_bytes.size() + authorization_section_bytes.size();
24515 }
24516 }
24517 std::string tag_bytes;
24518 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24519 if (rc != TPM_RC_SUCCESS) {
24520 return rc;
24521 }
24522 std::string command_size_bytes;
24523 rc = Serialize_UINT32(command_size, &command_size_bytes);
24524 if (rc != TPM_RC_SUCCESS) {
24525 return rc;
24526 }
24527 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24528 handle_section_bytes + authorization_size_bytes +
24529 authorization_section_bytes + parameter_section_bytes;
24530 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24531 VLOG(2) << "Command: "
24532 << base::HexEncode(serialized_command->data(),
24533 serialized_command->size());
24534 return TPM_RC_SUCCESS;
24535 }
24536
ParseResponse_PolicyAuthValue(const std::string & response,AuthorizationDelegate * authorization_delegate)24537 TPM_RC Tpm::ParseResponse_PolicyAuthValue(
24538 const std::string& response,
24539 AuthorizationDelegate* authorization_delegate) {
24540 VLOG(3) << __func__;
24541 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24542 TPM_RC rc = TPM_RC_SUCCESS;
24543 std::string buffer(response);
24544 TPM_ST tag;
24545 std::string tag_bytes;
24546 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24547 if (rc != TPM_RC_SUCCESS) {
24548 return rc;
24549 }
24550 UINT32 response_size;
24551 std::string response_size_bytes;
24552 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24553 if (rc != TPM_RC_SUCCESS) {
24554 return rc;
24555 }
24556 TPM_RC response_code;
24557 std::string response_code_bytes;
24558 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24559 if (rc != TPM_RC_SUCCESS) {
24560 return rc;
24561 }
24562 if (response_size != response.size()) {
24563 return TPM_RC_SIZE;
24564 }
24565 if (response_code != TPM_RC_SUCCESS) {
24566 return response_code;
24567 }
24568 TPM_CC command_code = TPM_CC_PolicyAuthValue;
24569 std::string command_code_bytes;
24570 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24571 if (rc != TPM_RC_SUCCESS) {
24572 return rc;
24573 }
24574 std::string authorization_section_bytes;
24575 if (tag == TPM_ST_SESSIONS) {
24576 UINT32 parameter_section_size = buffer.size();
24577 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
24578 if (rc != TPM_RC_SUCCESS) {
24579 return rc;
24580 }
24581 if (parameter_section_size > buffer.size()) {
24582 return TPM_RC_INSUFFICIENT;
24583 }
24584 authorization_section_bytes = buffer.substr(parameter_section_size);
24585 // Keep the parameter section in |buffer|.
24586 buffer.erase(parameter_section_size);
24587 }
24588 std::unique_ptr<crypto::SecureHash> hash(
24589 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24590 hash->Update(response_code_bytes.data(), response_code_bytes.size());
24591 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24592 hash->Update(buffer.data(), buffer.size());
24593 std::string response_hash(32, 0);
24594 hash->Finish(std::data(response_hash), response_hash.size());
24595 if (tag == TPM_ST_SESSIONS) {
24596 if (!authorization_delegate)
24597 return TRUNKS_RC_AUTHORIZATION_FAILED;
24598 if (!authorization_delegate->CheckResponseAuthorization(
24599 response_hash, authorization_section_bytes)) {
24600 return TRUNKS_RC_AUTHORIZATION_FAILED;
24601 }
24602 }
24603 return TPM_RC_SUCCESS;
24604 }
24605
PolicyAuthValueErrorCallback(Tpm::PolicyAuthValueResponse callback,TPM_RC response_code)24606 void PolicyAuthValueErrorCallback(Tpm::PolicyAuthValueResponse callback,
24607 TPM_RC response_code) {
24608 VLOG(1) << __func__;
24609 std::move(callback).Run(response_code);
24610 }
24611
PolicyAuthValueResponseParser(Tpm::PolicyAuthValueResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24612 void PolicyAuthValueResponseParser(
24613 Tpm::PolicyAuthValueResponse callback,
24614 AuthorizationDelegate* authorization_delegate,
24615 const std::string& response) {
24616 VLOG(1) << __func__;
24617 TPM_RC rc =
24618 Tpm::ParseResponse_PolicyAuthValue(response, authorization_delegate);
24619 if (rc != TPM_RC_SUCCESS) {
24620 base::OnceCallback<void(TPM_RC)> error_reporter =
24621 base::BindOnce(PolicyAuthValueErrorCallback, std::move(callback));
24622 std::move(error_reporter).Run(rc);
24623 return;
24624 }
24625 std::move(callback).Run(rc);
24626 }
24627
PolicyAuthValue(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyAuthValueResponse callback)24628 void Tpm::PolicyAuthValue(const TPMI_SH_POLICY& policy_session,
24629 const std::string& policy_session_name,
24630 AuthorizationDelegate* authorization_delegate,
24631 PolicyAuthValueResponse callback) {
24632 VLOG(1) << __func__;
24633 std::string command;
24634 TPM_RC rc = SerializeCommand_PolicyAuthValue(
24635 policy_session, policy_session_name, &command, authorization_delegate);
24636 if (rc != TPM_RC_SUCCESS) {
24637 base::OnceCallback<void(TPM_RC)> error_reporter =
24638 base::BindOnce(PolicyAuthValueErrorCallback, std::move(callback));
24639 std::move(error_reporter).Run(rc);
24640 return;
24641 }
24642 base::OnceCallback<void(const std::string&)> parser =
24643 base::BindOnce(PolicyAuthValueResponseParser, std::move(callback),
24644 authorization_delegate);
24645 transceiver_->SendCommand(command, std::move(parser));
24646 }
24647
PolicyAuthValueSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)24648 TPM_RC Tpm::PolicyAuthValueSync(const TPMI_SH_POLICY& policy_session,
24649 const std::string& policy_session_name,
24650 AuthorizationDelegate* authorization_delegate) {
24651 VLOG(1) << __func__;
24652 std::string command;
24653 TPM_RC rc = SerializeCommand_PolicyAuthValue(
24654 policy_session, policy_session_name, &command, authorization_delegate);
24655 if (rc != TPM_RC_SUCCESS) {
24656 return rc;
24657 }
24658 std::string response = transceiver_->SendCommandAndWait(command);
24659 rc = ParseResponse_PolicyAuthValue(response, authorization_delegate);
24660 return rc;
24661 }
24662
SerializeCommand_PolicyPassword(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24663 TPM_RC Tpm::SerializeCommand_PolicyPassword(
24664 const TPMI_SH_POLICY& policy_session,
24665 const std::string& policy_session_name,
24666 std::string* serialized_command,
24667 AuthorizationDelegate* authorization_delegate) {
24668 VLOG(3) << __func__;
24669 TPM_RC rc = TPM_RC_SUCCESS;
24670 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24671 UINT32 command_size = 10; // Header size.
24672 std::string handle_section_bytes;
24673 std::string parameter_section_bytes;
24674 TPM_CC command_code = TPM_CC_PolicyPassword;
24675 bool is_command_parameter_encryption_possible = false;
24676 bool is_response_parameter_encryption_possible = false;
24677 std::string command_code_bytes;
24678 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24679 if (rc != TPM_RC_SUCCESS) {
24680 return rc;
24681 }
24682 std::string policy_session_bytes;
24683 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24684 if (rc != TPM_RC_SUCCESS) {
24685 return rc;
24686 }
24687 std::unique_ptr<crypto::SecureHash> hash(
24688 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24689 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24690 hash->Update(policy_session_name.data(), policy_session_name.size());
24691 handle_section_bytes += policy_session_bytes;
24692 command_size += policy_session_bytes.size();
24693 std::string command_hash(32, 0);
24694 hash->Finish(std::data(command_hash), command_hash.size());
24695 std::string authorization_section_bytes;
24696 std::string authorization_size_bytes;
24697 if (authorization_delegate) {
24698 if (!authorization_delegate->GetCommandAuthorization(
24699 command_hash, is_command_parameter_encryption_possible,
24700 is_response_parameter_encryption_possible,
24701 &authorization_section_bytes)) {
24702 return TRUNKS_RC_AUTHORIZATION_FAILED;
24703 }
24704 if (!authorization_section_bytes.empty()) {
24705 tag = TPM_ST_SESSIONS;
24706 std::string tmp;
24707 rc = Serialize_UINT32(authorization_section_bytes.size(),
24708 &authorization_size_bytes);
24709 if (rc != TPM_RC_SUCCESS) {
24710 return rc;
24711 }
24712 command_size +=
24713 authorization_size_bytes.size() + authorization_section_bytes.size();
24714 }
24715 }
24716 std::string tag_bytes;
24717 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24718 if (rc != TPM_RC_SUCCESS) {
24719 return rc;
24720 }
24721 std::string command_size_bytes;
24722 rc = Serialize_UINT32(command_size, &command_size_bytes);
24723 if (rc != TPM_RC_SUCCESS) {
24724 return rc;
24725 }
24726 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24727 handle_section_bytes + authorization_size_bytes +
24728 authorization_section_bytes + parameter_section_bytes;
24729 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24730 VLOG(2) << "Command: "
24731 << base::HexEncode(serialized_command->data(),
24732 serialized_command->size());
24733 return TPM_RC_SUCCESS;
24734 }
24735
ParseResponse_PolicyPassword(const std::string & response,AuthorizationDelegate * authorization_delegate)24736 TPM_RC Tpm::ParseResponse_PolicyPassword(
24737 const std::string& response,
24738 AuthorizationDelegate* authorization_delegate) {
24739 VLOG(3) << __func__;
24740 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24741 TPM_RC rc = TPM_RC_SUCCESS;
24742 std::string buffer(response);
24743 TPM_ST tag;
24744 std::string tag_bytes;
24745 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24746 if (rc != TPM_RC_SUCCESS) {
24747 return rc;
24748 }
24749 UINT32 response_size;
24750 std::string response_size_bytes;
24751 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24752 if (rc != TPM_RC_SUCCESS) {
24753 return rc;
24754 }
24755 TPM_RC response_code;
24756 std::string response_code_bytes;
24757 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24758 if (rc != TPM_RC_SUCCESS) {
24759 return rc;
24760 }
24761 if (response_size != response.size()) {
24762 return TPM_RC_SIZE;
24763 }
24764 if (response_code != TPM_RC_SUCCESS) {
24765 return response_code;
24766 }
24767 TPM_CC command_code = TPM_CC_PolicyPassword;
24768 std::string command_code_bytes;
24769 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24770 if (rc != TPM_RC_SUCCESS) {
24771 return rc;
24772 }
24773 std::string authorization_section_bytes;
24774 if (tag == TPM_ST_SESSIONS) {
24775 UINT32 parameter_section_size = buffer.size();
24776 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
24777 if (rc != TPM_RC_SUCCESS) {
24778 return rc;
24779 }
24780 if (parameter_section_size > buffer.size()) {
24781 return TPM_RC_INSUFFICIENT;
24782 }
24783 authorization_section_bytes = buffer.substr(parameter_section_size);
24784 // Keep the parameter section in |buffer|.
24785 buffer.erase(parameter_section_size);
24786 }
24787 std::unique_ptr<crypto::SecureHash> hash(
24788 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24789 hash->Update(response_code_bytes.data(), response_code_bytes.size());
24790 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24791 hash->Update(buffer.data(), buffer.size());
24792 std::string response_hash(32, 0);
24793 hash->Finish(std::data(response_hash), response_hash.size());
24794 if (tag == TPM_ST_SESSIONS) {
24795 if (!authorization_delegate)
24796 return TRUNKS_RC_AUTHORIZATION_FAILED;
24797 if (!authorization_delegate->CheckResponseAuthorization(
24798 response_hash, authorization_section_bytes)) {
24799 return TRUNKS_RC_AUTHORIZATION_FAILED;
24800 }
24801 }
24802 return TPM_RC_SUCCESS;
24803 }
24804
PolicyPasswordErrorCallback(Tpm::PolicyPasswordResponse callback,TPM_RC response_code)24805 void PolicyPasswordErrorCallback(Tpm::PolicyPasswordResponse callback,
24806 TPM_RC response_code) {
24807 VLOG(1) << __func__;
24808 std::move(callback).Run(response_code);
24809 }
24810
PolicyPasswordResponseParser(Tpm::PolicyPasswordResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24811 void PolicyPasswordResponseParser(Tpm::PolicyPasswordResponse callback,
24812 AuthorizationDelegate* authorization_delegate,
24813 const std::string& response) {
24814 VLOG(1) << __func__;
24815 TPM_RC rc =
24816 Tpm::ParseResponse_PolicyPassword(response, authorization_delegate);
24817 if (rc != TPM_RC_SUCCESS) {
24818 base::OnceCallback<void(TPM_RC)> error_reporter =
24819 base::BindOnce(PolicyPasswordErrorCallback, std::move(callback));
24820 std::move(error_reporter).Run(rc);
24821 return;
24822 }
24823 std::move(callback).Run(rc);
24824 }
24825
PolicyPassword(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyPasswordResponse callback)24826 void Tpm::PolicyPassword(const TPMI_SH_POLICY& policy_session,
24827 const std::string& policy_session_name,
24828 AuthorizationDelegate* authorization_delegate,
24829 PolicyPasswordResponse callback) {
24830 VLOG(1) << __func__;
24831 std::string command;
24832 TPM_RC rc = SerializeCommand_PolicyPassword(
24833 policy_session, policy_session_name, &command, authorization_delegate);
24834 if (rc != TPM_RC_SUCCESS) {
24835 base::OnceCallback<void(TPM_RC)> error_reporter =
24836 base::BindOnce(PolicyPasswordErrorCallback, std::move(callback));
24837 std::move(error_reporter).Run(rc);
24838 return;
24839 }
24840 base::OnceCallback<void(const std::string&)> parser =
24841 base::BindOnce(PolicyPasswordResponseParser, std::move(callback),
24842 authorization_delegate);
24843 transceiver_->SendCommand(command, std::move(parser));
24844 }
24845
PolicyPasswordSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)24846 TPM_RC Tpm::PolicyPasswordSync(const TPMI_SH_POLICY& policy_session,
24847 const std::string& policy_session_name,
24848 AuthorizationDelegate* authorization_delegate) {
24849 VLOG(1) << __func__;
24850 std::string command;
24851 TPM_RC rc = SerializeCommand_PolicyPassword(
24852 policy_session, policy_session_name, &command, authorization_delegate);
24853 if (rc != TPM_RC_SUCCESS) {
24854 return rc;
24855 }
24856 std::string response = transceiver_->SendCommandAndWait(command);
24857 rc = ParseResponse_PolicyPassword(response, authorization_delegate);
24858 return rc;
24859 }
24860
SerializeCommand_PolicyGetDigest(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24861 TPM_RC Tpm::SerializeCommand_PolicyGetDigest(
24862 const TPMI_SH_POLICY& policy_session,
24863 const std::string& policy_session_name,
24864 std::string* serialized_command,
24865 AuthorizationDelegate* authorization_delegate) {
24866 VLOG(3) << __func__;
24867 TPM_RC rc = TPM_RC_SUCCESS;
24868 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24869 UINT32 command_size = 10; // Header size.
24870 std::string handle_section_bytes;
24871 std::string parameter_section_bytes;
24872 TPM_CC command_code = TPM_CC_PolicyGetDigest;
24873 bool is_command_parameter_encryption_possible = false;
24874 bool is_response_parameter_encryption_possible = true;
24875 std::string command_code_bytes;
24876 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24877 if (rc != TPM_RC_SUCCESS) {
24878 return rc;
24879 }
24880 std::string policy_session_bytes;
24881 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24882 if (rc != TPM_RC_SUCCESS) {
24883 return rc;
24884 }
24885 std::unique_ptr<crypto::SecureHash> hash(
24886 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24887 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24888 hash->Update(policy_session_name.data(), policy_session_name.size());
24889 handle_section_bytes += policy_session_bytes;
24890 command_size += policy_session_bytes.size();
24891 std::string command_hash(32, 0);
24892 hash->Finish(std::data(command_hash), command_hash.size());
24893 std::string authorization_section_bytes;
24894 std::string authorization_size_bytes;
24895 if (authorization_delegate) {
24896 if (!authorization_delegate->GetCommandAuthorization(
24897 command_hash, is_command_parameter_encryption_possible,
24898 is_response_parameter_encryption_possible,
24899 &authorization_section_bytes)) {
24900 return TRUNKS_RC_AUTHORIZATION_FAILED;
24901 }
24902 if (!authorization_section_bytes.empty()) {
24903 tag = TPM_ST_SESSIONS;
24904 std::string tmp;
24905 rc = Serialize_UINT32(authorization_section_bytes.size(),
24906 &authorization_size_bytes);
24907 if (rc != TPM_RC_SUCCESS) {
24908 return rc;
24909 }
24910 command_size +=
24911 authorization_size_bytes.size() + authorization_section_bytes.size();
24912 }
24913 }
24914 std::string tag_bytes;
24915 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24916 if (rc != TPM_RC_SUCCESS) {
24917 return rc;
24918 }
24919 std::string command_size_bytes;
24920 rc = Serialize_UINT32(command_size, &command_size_bytes);
24921 if (rc != TPM_RC_SUCCESS) {
24922 return rc;
24923 }
24924 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24925 handle_section_bytes + authorization_size_bytes +
24926 authorization_section_bytes + parameter_section_bytes;
24927 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24928 VLOG(2) << "Command: "
24929 << base::HexEncode(serialized_command->data(),
24930 serialized_command->size());
24931 return TPM_RC_SUCCESS;
24932 }
24933
ParseResponse_PolicyGetDigest(const std::string & response,TPM2B_DIGEST * policy_digest,AuthorizationDelegate * authorization_delegate)24934 TPM_RC Tpm::ParseResponse_PolicyGetDigest(
24935 const std::string& response,
24936 TPM2B_DIGEST* policy_digest,
24937 AuthorizationDelegate* authorization_delegate) {
24938 VLOG(3) << __func__;
24939 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24940 TPM_RC rc = TPM_RC_SUCCESS;
24941 std::string buffer(response);
24942 TPM_ST tag;
24943 std::string tag_bytes;
24944 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24945 if (rc != TPM_RC_SUCCESS) {
24946 return rc;
24947 }
24948 UINT32 response_size;
24949 std::string response_size_bytes;
24950 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24951 if (rc != TPM_RC_SUCCESS) {
24952 return rc;
24953 }
24954 TPM_RC response_code;
24955 std::string response_code_bytes;
24956 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24957 if (rc != TPM_RC_SUCCESS) {
24958 return rc;
24959 }
24960 if (response_size != response.size()) {
24961 return TPM_RC_SIZE;
24962 }
24963 if (response_code != TPM_RC_SUCCESS) {
24964 return response_code;
24965 }
24966 TPM_CC command_code = TPM_CC_PolicyGetDigest;
24967 std::string command_code_bytes;
24968 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24969 if (rc != TPM_RC_SUCCESS) {
24970 return rc;
24971 }
24972 std::string authorization_section_bytes;
24973 if (tag == TPM_ST_SESSIONS) {
24974 UINT32 parameter_section_size = buffer.size();
24975 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
24976 if (rc != TPM_RC_SUCCESS) {
24977 return rc;
24978 }
24979 if (parameter_section_size > buffer.size()) {
24980 return TPM_RC_INSUFFICIENT;
24981 }
24982 authorization_section_bytes = buffer.substr(parameter_section_size);
24983 // Keep the parameter section in |buffer|.
24984 buffer.erase(parameter_section_size);
24985 }
24986 std::unique_ptr<crypto::SecureHash> hash(
24987 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24988 hash->Update(response_code_bytes.data(), response_code_bytes.size());
24989 hash->Update(command_code_bytes.data(), command_code_bytes.size());
24990 hash->Update(buffer.data(), buffer.size());
24991 std::string response_hash(32, 0);
24992 hash->Finish(std::data(response_hash), response_hash.size());
24993 if (tag == TPM_ST_SESSIONS) {
24994 if (!authorization_delegate)
24995 return TRUNKS_RC_AUTHORIZATION_FAILED;
24996 if (!authorization_delegate->CheckResponseAuthorization(
24997 response_hash, authorization_section_bytes)) {
24998 return TRUNKS_RC_AUTHORIZATION_FAILED;
24999 }
25000 }
25001 if (tag == TPM_ST_SESSIONS) {
25002 if (!authorization_delegate)
25003 return TRUNKS_RC_AUTHORIZATION_FAILED;
25004
25005 // Parse the encrypted parameter size.
25006 UINT16 size;
25007 std::string size_buffer = buffer.substr(0, 2);
25008 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
25009 return result;
25010 }
25011 if (buffer.size() < 2 + size) {
25012 return TPM_RC_INSUFFICIENT;
25013 }
25014
25015 // Decrypt just the parameter data, not the size.
25016 std::string decrypted_data = buffer.substr(2, size);
25017 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
25018 return TRUNKS_RC_ENCRYPTION_FAILED;
25019 }
25020 buffer.replace(2, size, decrypted_data);
25021 }
25022 std::string policy_digest_bytes;
25023 rc = Parse_TPM2B_DIGEST(&buffer, policy_digest, &policy_digest_bytes);
25024 if (rc != TPM_RC_SUCCESS) {
25025 return rc;
25026 }
25027 return TPM_RC_SUCCESS;
25028 }
25029
PolicyGetDigestErrorCallback(Tpm::PolicyGetDigestResponse callback,TPM_RC response_code)25030 void PolicyGetDigestErrorCallback(Tpm::PolicyGetDigestResponse callback,
25031 TPM_RC response_code) {
25032 VLOG(1) << __func__;
25033 std::move(callback).Run(response_code, TPM2B_DIGEST());
25034 }
25035
PolicyGetDigestResponseParser(Tpm::PolicyGetDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25036 void PolicyGetDigestResponseParser(
25037 Tpm::PolicyGetDigestResponse callback,
25038 AuthorizationDelegate* authorization_delegate,
25039 const std::string& response) {
25040 VLOG(1) << __func__;
25041 TPM2B_DIGEST policy_digest;
25042 TPM_RC rc = Tpm::ParseResponse_PolicyGetDigest(response, &policy_digest,
25043 authorization_delegate);
25044 if (rc != TPM_RC_SUCCESS) {
25045 base::OnceCallback<void(TPM_RC)> error_reporter =
25046 base::BindOnce(PolicyGetDigestErrorCallback, std::move(callback));
25047 std::move(error_reporter).Run(rc);
25048 return;
25049 }
25050 std::move(callback).Run(rc, policy_digest);
25051 }
25052
PolicyGetDigest(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyGetDigestResponse callback)25053 void Tpm::PolicyGetDigest(const TPMI_SH_POLICY& policy_session,
25054 const std::string& policy_session_name,
25055 AuthorizationDelegate* authorization_delegate,
25056 PolicyGetDigestResponse callback) {
25057 VLOG(1) << __func__;
25058 std::string command;
25059 TPM_RC rc = SerializeCommand_PolicyGetDigest(
25060 policy_session, policy_session_name, &command, authorization_delegate);
25061 if (rc != TPM_RC_SUCCESS) {
25062 base::OnceCallback<void(TPM_RC)> error_reporter =
25063 base::BindOnce(PolicyGetDigestErrorCallback, std::move(callback));
25064 std::move(error_reporter).Run(rc);
25065 return;
25066 }
25067 base::OnceCallback<void(const std::string&)> parser =
25068 base::BindOnce(PolicyGetDigestResponseParser, std::move(callback),
25069 authorization_delegate);
25070 transceiver_->SendCommand(command, std::move(parser));
25071 }
25072
PolicyGetDigestSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,TPM2B_DIGEST * policy_digest,AuthorizationDelegate * authorization_delegate)25073 TPM_RC Tpm::PolicyGetDigestSync(const TPMI_SH_POLICY& policy_session,
25074 const std::string& policy_session_name,
25075 TPM2B_DIGEST* policy_digest,
25076 AuthorizationDelegate* authorization_delegate) {
25077 VLOG(1) << __func__;
25078 std::string command;
25079 TPM_RC rc = SerializeCommand_PolicyGetDigest(
25080 policy_session, policy_session_name, &command, authorization_delegate);
25081 if (rc != TPM_RC_SUCCESS) {
25082 return rc;
25083 }
25084 std::string response = transceiver_->SendCommandAndWait(command);
25085 rc = ParseResponse_PolicyGetDigest(response, policy_digest,
25086 authorization_delegate);
25087 return rc;
25088 }
25089
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)25090 TPM_RC Tpm::SerializeCommand_PolicyNvWritten(
25091 const TPMI_SH_POLICY& policy_session,
25092 const std::string& policy_session_name,
25093 const TPMI_YES_NO& written_set,
25094 std::string* serialized_command,
25095 AuthorizationDelegate* authorization_delegate) {
25096 VLOG(3) << __func__;
25097 TPM_RC rc = TPM_RC_SUCCESS;
25098 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25099 UINT32 command_size = 10; // Header size.
25100 std::string handle_section_bytes;
25101 std::string parameter_section_bytes;
25102 TPM_CC command_code = TPM_CC_PolicyNvWritten;
25103 bool is_command_parameter_encryption_possible = false;
25104 bool is_response_parameter_encryption_possible = false;
25105 std::string command_code_bytes;
25106 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25107 if (rc != TPM_RC_SUCCESS) {
25108 return rc;
25109 }
25110 std::string policy_session_bytes;
25111 rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
25112 if (rc != TPM_RC_SUCCESS) {
25113 return rc;
25114 }
25115 std::string written_set_bytes;
25116 rc = Serialize_TPMI_YES_NO(written_set, &written_set_bytes);
25117 if (rc != TPM_RC_SUCCESS) {
25118 return rc;
25119 }
25120 std::unique_ptr<crypto::SecureHash> hash(
25121 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25122 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25123 hash->Update(policy_session_name.data(), policy_session_name.size());
25124 handle_section_bytes += policy_session_bytes;
25125 command_size += policy_session_bytes.size();
25126 hash->Update(written_set_bytes.data(), written_set_bytes.size());
25127 parameter_section_bytes += written_set_bytes;
25128 command_size += written_set_bytes.size();
25129 std::string command_hash(32, 0);
25130 hash->Finish(std::data(command_hash), command_hash.size());
25131 std::string authorization_section_bytes;
25132 std::string authorization_size_bytes;
25133 if (authorization_delegate) {
25134 if (!authorization_delegate->GetCommandAuthorization(
25135 command_hash, is_command_parameter_encryption_possible,
25136 is_response_parameter_encryption_possible,
25137 &authorization_section_bytes)) {
25138 return TRUNKS_RC_AUTHORIZATION_FAILED;
25139 }
25140 if (!authorization_section_bytes.empty()) {
25141 tag = TPM_ST_SESSIONS;
25142 std::string tmp;
25143 rc = Serialize_UINT32(authorization_section_bytes.size(),
25144 &authorization_size_bytes);
25145 if (rc != TPM_RC_SUCCESS) {
25146 return rc;
25147 }
25148 command_size +=
25149 authorization_size_bytes.size() + authorization_section_bytes.size();
25150 }
25151 }
25152 std::string tag_bytes;
25153 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25154 if (rc != TPM_RC_SUCCESS) {
25155 return rc;
25156 }
25157 std::string command_size_bytes;
25158 rc = Serialize_UINT32(command_size, &command_size_bytes);
25159 if (rc != TPM_RC_SUCCESS) {
25160 return rc;
25161 }
25162 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25163 handle_section_bytes + authorization_size_bytes +
25164 authorization_section_bytes + parameter_section_bytes;
25165 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25166 VLOG(2) << "Command: "
25167 << base::HexEncode(serialized_command->data(),
25168 serialized_command->size());
25169 return TPM_RC_SUCCESS;
25170 }
25171
ParseResponse_PolicyNvWritten(const std::string & response,AuthorizationDelegate * authorization_delegate)25172 TPM_RC Tpm::ParseResponse_PolicyNvWritten(
25173 const std::string& response,
25174 AuthorizationDelegate* authorization_delegate) {
25175 VLOG(3) << __func__;
25176 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25177 TPM_RC rc = TPM_RC_SUCCESS;
25178 std::string buffer(response);
25179 TPM_ST tag;
25180 std::string tag_bytes;
25181 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25182 if (rc != TPM_RC_SUCCESS) {
25183 return rc;
25184 }
25185 UINT32 response_size;
25186 std::string response_size_bytes;
25187 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25188 if (rc != TPM_RC_SUCCESS) {
25189 return rc;
25190 }
25191 TPM_RC response_code;
25192 std::string response_code_bytes;
25193 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25194 if (rc != TPM_RC_SUCCESS) {
25195 return rc;
25196 }
25197 if (response_size != response.size()) {
25198 return TPM_RC_SIZE;
25199 }
25200 if (response_code != TPM_RC_SUCCESS) {
25201 return response_code;
25202 }
25203 TPM_CC command_code = TPM_CC_PolicyNvWritten;
25204 std::string command_code_bytes;
25205 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25206 if (rc != TPM_RC_SUCCESS) {
25207 return rc;
25208 }
25209 std::string authorization_section_bytes;
25210 if (tag == TPM_ST_SESSIONS) {
25211 UINT32 parameter_section_size = buffer.size();
25212 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
25213 if (rc != TPM_RC_SUCCESS) {
25214 return rc;
25215 }
25216 if (parameter_section_size > buffer.size()) {
25217 return TPM_RC_INSUFFICIENT;
25218 }
25219 authorization_section_bytes = buffer.substr(parameter_section_size);
25220 // Keep the parameter section in |buffer|.
25221 buffer.erase(parameter_section_size);
25222 }
25223 std::unique_ptr<crypto::SecureHash> hash(
25224 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25225 hash->Update(response_code_bytes.data(), response_code_bytes.size());
25226 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25227 hash->Update(buffer.data(), buffer.size());
25228 std::string response_hash(32, 0);
25229 hash->Finish(std::data(response_hash), response_hash.size());
25230 if (tag == TPM_ST_SESSIONS) {
25231 if (!authorization_delegate)
25232 return TRUNKS_RC_AUTHORIZATION_FAILED;
25233 if (!authorization_delegate->CheckResponseAuthorization(
25234 response_hash, authorization_section_bytes)) {
25235 return TRUNKS_RC_AUTHORIZATION_FAILED;
25236 }
25237 }
25238 return TPM_RC_SUCCESS;
25239 }
25240
PolicyNvWrittenErrorCallback(Tpm::PolicyNvWrittenResponse callback,TPM_RC response_code)25241 void PolicyNvWrittenErrorCallback(Tpm::PolicyNvWrittenResponse callback,
25242 TPM_RC response_code) {
25243 VLOG(1) << __func__;
25244 std::move(callback).Run(response_code);
25245 }
25246
PolicyNvWrittenResponseParser(Tpm::PolicyNvWrittenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25247 void PolicyNvWrittenResponseParser(
25248 Tpm::PolicyNvWrittenResponse callback,
25249 AuthorizationDelegate* authorization_delegate,
25250 const std::string& response) {
25251 VLOG(1) << __func__;
25252 TPM_RC rc =
25253 Tpm::ParseResponse_PolicyNvWritten(response, authorization_delegate);
25254 if (rc != TPM_RC_SUCCESS) {
25255 base::OnceCallback<void(TPM_RC)> error_reporter =
25256 base::BindOnce(PolicyNvWrittenErrorCallback, std::move(callback));
25257 std::move(error_reporter).Run(rc);
25258 return;
25259 }
25260 std::move(callback).Run(rc);
25261 }
25262
PolicyNvWritten(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,AuthorizationDelegate * authorization_delegate,PolicyNvWrittenResponse callback)25263 void Tpm::PolicyNvWritten(const TPMI_SH_POLICY& policy_session,
25264 const std::string& policy_session_name,
25265 const TPMI_YES_NO& written_set,
25266 AuthorizationDelegate* authorization_delegate,
25267 PolicyNvWrittenResponse callback) {
25268 VLOG(1) << __func__;
25269 std::string command;
25270 TPM_RC rc = SerializeCommand_PolicyNvWritten(
25271 policy_session, policy_session_name, written_set, &command,
25272 authorization_delegate);
25273 if (rc != TPM_RC_SUCCESS) {
25274 base::OnceCallback<void(TPM_RC)> error_reporter =
25275 base::BindOnce(PolicyNvWrittenErrorCallback, std::move(callback));
25276 std::move(error_reporter).Run(rc);
25277 return;
25278 }
25279 base::OnceCallback<void(const std::string&)> parser =
25280 base::BindOnce(PolicyNvWrittenResponseParser, std::move(callback),
25281 authorization_delegate);
25282 transceiver_->SendCommand(command, std::move(parser));
25283 }
25284
PolicyNvWrittenSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,AuthorizationDelegate * authorization_delegate)25285 TPM_RC Tpm::PolicyNvWrittenSync(const TPMI_SH_POLICY& policy_session,
25286 const std::string& policy_session_name,
25287 const TPMI_YES_NO& written_set,
25288 AuthorizationDelegate* authorization_delegate) {
25289 VLOG(1) << __func__;
25290 std::string command;
25291 TPM_RC rc = SerializeCommand_PolicyNvWritten(
25292 policy_session, policy_session_name, written_set, &command,
25293 authorization_delegate);
25294 if (rc != TPM_RC_SUCCESS) {
25295 return rc;
25296 }
25297 std::string response = transceiver_->SendCommandAndWait(command);
25298 rc = ParseResponse_PolicyNvWritten(response, authorization_delegate);
25299 return rc;
25300 }
25301
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)25302 TPM_RC Tpm::SerializeCommand_CreatePrimary(
25303 const TPMI_RH_HIERARCHY& primary_handle,
25304 const std::string& primary_handle_name,
25305 const TPM2B_SENSITIVE_CREATE& in_sensitive,
25306 const TPM2B_PUBLIC& in_public,
25307 const TPM2B_DATA& outside_info,
25308 const TPML_PCR_SELECTION& creation_pcr,
25309 std::string* serialized_command,
25310 AuthorizationDelegate* authorization_delegate) {
25311 VLOG(3) << __func__;
25312 TPM_RC rc = TPM_RC_SUCCESS;
25313 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25314 UINT32 command_size = 10; // Header size.
25315 std::string handle_section_bytes;
25316 std::string parameter_section_bytes;
25317 TPM_CC command_code = TPM_CC_CreatePrimary;
25318 bool is_command_parameter_encryption_possible = true;
25319 bool is_response_parameter_encryption_possible = true;
25320 std::string command_code_bytes;
25321 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25322 if (rc != TPM_RC_SUCCESS) {
25323 return rc;
25324 }
25325 std::string primary_handle_bytes;
25326 rc = Serialize_TPMI_RH_HIERARCHY(primary_handle, &primary_handle_bytes);
25327 if (rc != TPM_RC_SUCCESS) {
25328 return rc;
25329 }
25330 std::string in_sensitive_bytes;
25331 rc = Serialize_TPM2B_SENSITIVE_CREATE(in_sensitive, &in_sensitive_bytes);
25332 if (rc != TPM_RC_SUCCESS) {
25333 return rc;
25334 }
25335 std::string in_public_bytes;
25336 rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
25337 if (rc != TPM_RC_SUCCESS) {
25338 return rc;
25339 }
25340 std::string outside_info_bytes;
25341 rc = Serialize_TPM2B_DATA(outside_info, &outside_info_bytes);
25342 if (rc != TPM_RC_SUCCESS) {
25343 return rc;
25344 }
25345 std::string creation_pcr_bytes;
25346 rc = Serialize_TPML_PCR_SELECTION(creation_pcr, &creation_pcr_bytes);
25347 if (rc != TPM_RC_SUCCESS) {
25348 return rc;
25349 }
25350 if (authorization_delegate) {
25351 // Encrypt just the parameter data, not the size.
25352 std::string tmp = in_sensitive_bytes.substr(2);
25353 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
25354 return TRUNKS_RC_ENCRYPTION_FAILED;
25355 }
25356 in_sensitive_bytes.replace(2, std::string::npos, tmp);
25357 }
25358 std::unique_ptr<crypto::SecureHash> hash(
25359 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25360 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25361 hash->Update(primary_handle_name.data(), primary_handle_name.size());
25362 handle_section_bytes += primary_handle_bytes;
25363 command_size += primary_handle_bytes.size();
25364 hash->Update(in_sensitive_bytes.data(), in_sensitive_bytes.size());
25365 parameter_section_bytes += in_sensitive_bytes;
25366 command_size += in_sensitive_bytes.size();
25367 hash->Update(in_public_bytes.data(), in_public_bytes.size());
25368 parameter_section_bytes += in_public_bytes;
25369 command_size += in_public_bytes.size();
25370 hash->Update(outside_info_bytes.data(), outside_info_bytes.size());
25371 parameter_section_bytes += outside_info_bytes;
25372 command_size += outside_info_bytes.size();
25373 hash->Update(creation_pcr_bytes.data(), creation_pcr_bytes.size());
25374 parameter_section_bytes += creation_pcr_bytes;
25375 command_size += creation_pcr_bytes.size();
25376 std::string command_hash(32, 0);
25377 hash->Finish(std::data(command_hash), command_hash.size());
25378 std::string authorization_section_bytes;
25379 std::string authorization_size_bytes;
25380 if (authorization_delegate) {
25381 if (!authorization_delegate->GetCommandAuthorization(
25382 command_hash, is_command_parameter_encryption_possible,
25383 is_response_parameter_encryption_possible,
25384 &authorization_section_bytes)) {
25385 return TRUNKS_RC_AUTHORIZATION_FAILED;
25386 }
25387 if (!authorization_section_bytes.empty()) {
25388 tag = TPM_ST_SESSIONS;
25389 std::string tmp;
25390 rc = Serialize_UINT32(authorization_section_bytes.size(),
25391 &authorization_size_bytes);
25392 if (rc != TPM_RC_SUCCESS) {
25393 return rc;
25394 }
25395 command_size +=
25396 authorization_size_bytes.size() + authorization_section_bytes.size();
25397 }
25398 }
25399 std::string tag_bytes;
25400 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25401 if (rc != TPM_RC_SUCCESS) {
25402 return rc;
25403 }
25404 std::string command_size_bytes;
25405 rc = Serialize_UINT32(command_size, &command_size_bytes);
25406 if (rc != TPM_RC_SUCCESS) {
25407 return rc;
25408 }
25409 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25410 handle_section_bytes + authorization_size_bytes +
25411 authorization_section_bytes + parameter_section_bytes;
25412 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25413 VLOG(2) << "Command: "
25414 << base::HexEncode(serialized_command->data(),
25415 serialized_command->size());
25416 return TPM_RC_SUCCESS;
25417 }
25418
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)25419 TPM_RC Tpm::ParseResponse_CreatePrimary(
25420 const std::string& response,
25421 TPM_HANDLE* object_handle,
25422 TPM2B_PUBLIC* out_public,
25423 TPM2B_CREATION_DATA* creation_data,
25424 TPM2B_DIGEST* creation_hash,
25425 TPMT_TK_CREATION* creation_ticket,
25426 TPM2B_NAME* name,
25427 AuthorizationDelegate* authorization_delegate) {
25428 VLOG(3) << __func__;
25429 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25430 TPM_RC rc = TPM_RC_SUCCESS;
25431 std::string buffer(response);
25432 TPM_ST tag;
25433 std::string tag_bytes;
25434 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25435 if (rc != TPM_RC_SUCCESS) {
25436 return rc;
25437 }
25438 UINT32 response_size;
25439 std::string response_size_bytes;
25440 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25441 if (rc != TPM_RC_SUCCESS) {
25442 return rc;
25443 }
25444 TPM_RC response_code;
25445 std::string response_code_bytes;
25446 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25447 if (rc != TPM_RC_SUCCESS) {
25448 return rc;
25449 }
25450 if (response_size != response.size()) {
25451 return TPM_RC_SIZE;
25452 }
25453 if (response_code != TPM_RC_SUCCESS) {
25454 return response_code;
25455 }
25456 std::string object_handle_bytes;
25457 rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
25458 if (rc != TPM_RC_SUCCESS) {
25459 return rc;
25460 }
25461 TPM_CC command_code = TPM_CC_CreatePrimary;
25462 std::string command_code_bytes;
25463 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25464 if (rc != TPM_RC_SUCCESS) {
25465 return rc;
25466 }
25467 std::string authorization_section_bytes;
25468 if (tag == TPM_ST_SESSIONS) {
25469 UINT32 parameter_section_size = buffer.size();
25470 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
25471 if (rc != TPM_RC_SUCCESS) {
25472 return rc;
25473 }
25474 if (parameter_section_size > buffer.size()) {
25475 return TPM_RC_INSUFFICIENT;
25476 }
25477 authorization_section_bytes = buffer.substr(parameter_section_size);
25478 // Keep the parameter section in |buffer|.
25479 buffer.erase(parameter_section_size);
25480 }
25481 std::unique_ptr<crypto::SecureHash> hash(
25482 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25483 hash->Update(response_code_bytes.data(), response_code_bytes.size());
25484 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25485 hash->Update(buffer.data(), buffer.size());
25486 std::string response_hash(32, 0);
25487 hash->Finish(std::data(response_hash), response_hash.size());
25488 if (tag == TPM_ST_SESSIONS) {
25489 if (!authorization_delegate)
25490 return TRUNKS_RC_AUTHORIZATION_FAILED;
25491 if (!authorization_delegate->CheckResponseAuthorization(
25492 response_hash, authorization_section_bytes)) {
25493 return TRUNKS_RC_AUTHORIZATION_FAILED;
25494 }
25495 }
25496 if (tag == TPM_ST_SESSIONS) {
25497 if (!authorization_delegate)
25498 return TRUNKS_RC_AUTHORIZATION_FAILED;
25499
25500 // Parse the encrypted parameter size.
25501 UINT16 size;
25502 std::string size_buffer = buffer.substr(0, 2);
25503 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
25504 return result;
25505 }
25506 if (buffer.size() < 2 + size) {
25507 return TPM_RC_INSUFFICIENT;
25508 }
25509
25510 // Decrypt just the parameter data, not the size.
25511 std::string decrypted_data = buffer.substr(2, size);
25512 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
25513 return TRUNKS_RC_ENCRYPTION_FAILED;
25514 }
25515 buffer.replace(2, size, decrypted_data);
25516 }
25517 std::string out_public_bytes;
25518 rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
25519 if (rc != TPM_RC_SUCCESS) {
25520 return rc;
25521 }
25522 std::string creation_data_bytes;
25523 rc = Parse_TPM2B_CREATION_DATA(&buffer, creation_data, &creation_data_bytes);
25524 if (rc != TPM_RC_SUCCESS) {
25525 return rc;
25526 }
25527 std::string creation_hash_bytes;
25528 rc = Parse_TPM2B_DIGEST(&buffer, creation_hash, &creation_hash_bytes);
25529 if (rc != TPM_RC_SUCCESS) {
25530 return rc;
25531 }
25532 std::string creation_ticket_bytes;
25533 rc = Parse_TPMT_TK_CREATION(&buffer, creation_ticket, &creation_ticket_bytes);
25534 if (rc != TPM_RC_SUCCESS) {
25535 return rc;
25536 }
25537 std::string name_bytes;
25538 rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
25539 if (rc != TPM_RC_SUCCESS) {
25540 return rc;
25541 }
25542 return TPM_RC_SUCCESS;
25543 }
25544
CreatePrimaryErrorCallback(Tpm::CreatePrimaryResponse callback,TPM_RC response_code)25545 void CreatePrimaryErrorCallback(Tpm::CreatePrimaryResponse callback,
25546 TPM_RC response_code) {
25547 VLOG(1) << __func__;
25548 std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_PUBLIC(),
25549 TPM2B_CREATION_DATA(), TPM2B_DIGEST(),
25550 TPMT_TK_CREATION(), TPM2B_NAME());
25551 }
25552
CreatePrimaryResponseParser(Tpm::CreatePrimaryResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25553 void CreatePrimaryResponseParser(Tpm::CreatePrimaryResponse callback,
25554 AuthorizationDelegate* authorization_delegate,
25555 const std::string& response) {
25556 VLOG(1) << __func__;
25557 TPM_HANDLE object_handle;
25558 TPM2B_PUBLIC out_public;
25559 TPM2B_CREATION_DATA creation_data;
25560 TPM2B_DIGEST creation_hash;
25561 TPMT_TK_CREATION creation_ticket;
25562 TPM2B_NAME name;
25563 TPM_RC rc = Tpm::ParseResponse_CreatePrimary(
25564 response, &object_handle, &out_public, &creation_data, &creation_hash,
25565 &creation_ticket, &name, authorization_delegate);
25566 if (rc != TPM_RC_SUCCESS) {
25567 base::OnceCallback<void(TPM_RC)> error_reporter =
25568 base::BindOnce(CreatePrimaryErrorCallback, std::move(callback));
25569 std::move(error_reporter).Run(rc);
25570 return;
25571 }
25572 std::move(callback).Run(rc, object_handle, out_public, creation_data,
25573 creation_hash, creation_ticket, name);
25574 }
25575
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)25576 void Tpm::CreatePrimary(const TPMI_RH_HIERARCHY& primary_handle,
25577 const std::string& primary_handle_name,
25578 const TPM2B_SENSITIVE_CREATE& in_sensitive,
25579 const TPM2B_PUBLIC& in_public,
25580 const TPM2B_DATA& outside_info,
25581 const TPML_PCR_SELECTION& creation_pcr,
25582 AuthorizationDelegate* authorization_delegate,
25583 CreatePrimaryResponse callback) {
25584 VLOG(1) << __func__;
25585 std::string command;
25586 TPM_RC rc = SerializeCommand_CreatePrimary(
25587 primary_handle, primary_handle_name, in_sensitive, in_public,
25588 outside_info, creation_pcr, &command, authorization_delegate);
25589 if (rc != TPM_RC_SUCCESS) {
25590 base::OnceCallback<void(TPM_RC)> error_reporter =
25591 base::BindOnce(CreatePrimaryErrorCallback, std::move(callback));
25592 std::move(error_reporter).Run(rc);
25593 return;
25594 }
25595 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
25596 CreatePrimaryResponseParser, std::move(callback), authorization_delegate);
25597 transceiver_->SendCommand(command, std::move(parser));
25598 }
25599
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)25600 TPM_RC Tpm::CreatePrimarySync(const TPMI_RH_HIERARCHY& primary_handle,
25601 const std::string& primary_handle_name,
25602 const TPM2B_SENSITIVE_CREATE& in_sensitive,
25603 const TPM2B_PUBLIC& in_public,
25604 const TPM2B_DATA& outside_info,
25605 const TPML_PCR_SELECTION& creation_pcr,
25606 TPM_HANDLE* object_handle,
25607 TPM2B_PUBLIC* out_public,
25608 TPM2B_CREATION_DATA* creation_data,
25609 TPM2B_DIGEST* creation_hash,
25610 TPMT_TK_CREATION* creation_ticket,
25611 TPM2B_NAME* name,
25612 AuthorizationDelegate* authorization_delegate) {
25613 VLOG(1) << __func__;
25614 std::string command;
25615 TPM_RC rc = SerializeCommand_CreatePrimary(
25616 primary_handle, primary_handle_name, in_sensitive, in_public,
25617 outside_info, creation_pcr, &command, authorization_delegate);
25618 if (rc != TPM_RC_SUCCESS) {
25619 return rc;
25620 }
25621 std::string response = transceiver_->SendCommandAndWait(command);
25622 rc = ParseResponse_CreatePrimary(
25623 response, object_handle, out_public, creation_data, creation_hash,
25624 creation_ticket, name, authorization_delegate);
25625 return rc;
25626 }
25627
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)25628 TPM_RC Tpm::SerializeCommand_HierarchyControl(
25629 const TPMI_RH_HIERARCHY& auth_handle,
25630 const std::string& auth_handle_name,
25631 const TPMI_RH_ENABLES& enable,
25632 const TPMI_YES_NO& state,
25633 std::string* serialized_command,
25634 AuthorizationDelegate* authorization_delegate) {
25635 VLOG(3) << __func__;
25636 TPM_RC rc = TPM_RC_SUCCESS;
25637 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25638 UINT32 command_size = 10; // Header size.
25639 std::string handle_section_bytes;
25640 std::string parameter_section_bytes;
25641 TPM_CC command_code = TPM_CC_HierarchyControl;
25642 bool is_command_parameter_encryption_possible = false;
25643 bool is_response_parameter_encryption_possible = false;
25644 std::string command_code_bytes;
25645 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25646 if (rc != TPM_RC_SUCCESS) {
25647 return rc;
25648 }
25649 std::string auth_handle_bytes;
25650 rc = Serialize_TPMI_RH_HIERARCHY(auth_handle, &auth_handle_bytes);
25651 if (rc != TPM_RC_SUCCESS) {
25652 return rc;
25653 }
25654 std::string enable_bytes;
25655 rc = Serialize_TPMI_RH_ENABLES(enable, &enable_bytes);
25656 if (rc != TPM_RC_SUCCESS) {
25657 return rc;
25658 }
25659 std::string state_bytes;
25660 rc = Serialize_TPMI_YES_NO(state, &state_bytes);
25661 if (rc != TPM_RC_SUCCESS) {
25662 return rc;
25663 }
25664 std::unique_ptr<crypto::SecureHash> hash(
25665 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25666 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25667 hash->Update(auth_handle_name.data(), auth_handle_name.size());
25668 handle_section_bytes += auth_handle_bytes;
25669 command_size += auth_handle_bytes.size();
25670 hash->Update(enable_bytes.data(), enable_bytes.size());
25671 parameter_section_bytes += enable_bytes;
25672 command_size += enable_bytes.size();
25673 hash->Update(state_bytes.data(), state_bytes.size());
25674 parameter_section_bytes += state_bytes;
25675 command_size += state_bytes.size();
25676 std::string command_hash(32, 0);
25677 hash->Finish(std::data(command_hash), command_hash.size());
25678 std::string authorization_section_bytes;
25679 std::string authorization_size_bytes;
25680 if (authorization_delegate) {
25681 if (!authorization_delegate->GetCommandAuthorization(
25682 command_hash, is_command_parameter_encryption_possible,
25683 is_response_parameter_encryption_possible,
25684 &authorization_section_bytes)) {
25685 return TRUNKS_RC_AUTHORIZATION_FAILED;
25686 }
25687 if (!authorization_section_bytes.empty()) {
25688 tag = TPM_ST_SESSIONS;
25689 std::string tmp;
25690 rc = Serialize_UINT32(authorization_section_bytes.size(),
25691 &authorization_size_bytes);
25692 if (rc != TPM_RC_SUCCESS) {
25693 return rc;
25694 }
25695 command_size +=
25696 authorization_size_bytes.size() + authorization_section_bytes.size();
25697 }
25698 }
25699 std::string tag_bytes;
25700 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25701 if (rc != TPM_RC_SUCCESS) {
25702 return rc;
25703 }
25704 std::string command_size_bytes;
25705 rc = Serialize_UINT32(command_size, &command_size_bytes);
25706 if (rc != TPM_RC_SUCCESS) {
25707 return rc;
25708 }
25709 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25710 handle_section_bytes + authorization_size_bytes +
25711 authorization_section_bytes + parameter_section_bytes;
25712 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25713 VLOG(2) << "Command: "
25714 << base::HexEncode(serialized_command->data(),
25715 serialized_command->size());
25716 return TPM_RC_SUCCESS;
25717 }
25718
ParseResponse_HierarchyControl(const std::string & response,AuthorizationDelegate * authorization_delegate)25719 TPM_RC Tpm::ParseResponse_HierarchyControl(
25720 const std::string& response,
25721 AuthorizationDelegate* authorization_delegate) {
25722 VLOG(3) << __func__;
25723 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25724 TPM_RC rc = TPM_RC_SUCCESS;
25725 std::string buffer(response);
25726 TPM_ST tag;
25727 std::string tag_bytes;
25728 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25729 if (rc != TPM_RC_SUCCESS) {
25730 return rc;
25731 }
25732 UINT32 response_size;
25733 std::string response_size_bytes;
25734 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25735 if (rc != TPM_RC_SUCCESS) {
25736 return rc;
25737 }
25738 TPM_RC response_code;
25739 std::string response_code_bytes;
25740 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25741 if (rc != TPM_RC_SUCCESS) {
25742 return rc;
25743 }
25744 if (response_size != response.size()) {
25745 return TPM_RC_SIZE;
25746 }
25747 if (response_code != TPM_RC_SUCCESS) {
25748 return response_code;
25749 }
25750 TPM_CC command_code = TPM_CC_HierarchyControl;
25751 std::string command_code_bytes;
25752 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25753 if (rc != TPM_RC_SUCCESS) {
25754 return rc;
25755 }
25756 std::string authorization_section_bytes;
25757 if (tag == TPM_ST_SESSIONS) {
25758 UINT32 parameter_section_size = buffer.size();
25759 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
25760 if (rc != TPM_RC_SUCCESS) {
25761 return rc;
25762 }
25763 if (parameter_section_size > buffer.size()) {
25764 return TPM_RC_INSUFFICIENT;
25765 }
25766 authorization_section_bytes = buffer.substr(parameter_section_size);
25767 // Keep the parameter section in |buffer|.
25768 buffer.erase(parameter_section_size);
25769 }
25770 std::unique_ptr<crypto::SecureHash> hash(
25771 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25772 hash->Update(response_code_bytes.data(), response_code_bytes.size());
25773 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25774 hash->Update(buffer.data(), buffer.size());
25775 std::string response_hash(32, 0);
25776 hash->Finish(std::data(response_hash), response_hash.size());
25777 if (tag == TPM_ST_SESSIONS) {
25778 if (!authorization_delegate)
25779 return TRUNKS_RC_AUTHORIZATION_FAILED;
25780 if (!authorization_delegate->CheckResponseAuthorization(
25781 response_hash, authorization_section_bytes)) {
25782 return TRUNKS_RC_AUTHORIZATION_FAILED;
25783 }
25784 }
25785 return TPM_RC_SUCCESS;
25786 }
25787
HierarchyControlErrorCallback(Tpm::HierarchyControlResponse callback,TPM_RC response_code)25788 void HierarchyControlErrorCallback(Tpm::HierarchyControlResponse callback,
25789 TPM_RC response_code) {
25790 VLOG(1) << __func__;
25791 std::move(callback).Run(response_code);
25792 }
25793
HierarchyControlResponseParser(Tpm::HierarchyControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25794 void HierarchyControlResponseParser(
25795 Tpm::HierarchyControlResponse callback,
25796 AuthorizationDelegate* authorization_delegate,
25797 const std::string& response) {
25798 VLOG(1) << __func__;
25799 TPM_RC rc =
25800 Tpm::ParseResponse_HierarchyControl(response, authorization_delegate);
25801 if (rc != TPM_RC_SUCCESS) {
25802 base::OnceCallback<void(TPM_RC)> error_reporter =
25803 base::BindOnce(HierarchyControlErrorCallback, std::move(callback));
25804 std::move(error_reporter).Run(rc);
25805 return;
25806 }
25807 std::move(callback).Run(rc);
25808 }
25809
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)25810 void Tpm::HierarchyControl(const TPMI_RH_HIERARCHY& auth_handle,
25811 const std::string& auth_handle_name,
25812 const TPMI_RH_ENABLES& enable,
25813 const TPMI_YES_NO& state,
25814 AuthorizationDelegate* authorization_delegate,
25815 HierarchyControlResponse callback) {
25816 VLOG(1) << __func__;
25817 std::string command;
25818 TPM_RC rc = SerializeCommand_HierarchyControl(auth_handle, auth_handle_name,
25819 enable, state, &command,
25820 authorization_delegate);
25821 if (rc != TPM_RC_SUCCESS) {
25822 base::OnceCallback<void(TPM_RC)> error_reporter =
25823 base::BindOnce(HierarchyControlErrorCallback, std::move(callback));
25824 std::move(error_reporter).Run(rc);
25825 return;
25826 }
25827 base::OnceCallback<void(const std::string&)> parser =
25828 base::BindOnce(HierarchyControlResponseParser, std::move(callback),
25829 authorization_delegate);
25830 transceiver_->SendCommand(command, std::move(parser));
25831 }
25832
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)25833 TPM_RC Tpm::HierarchyControlSync(
25834 const TPMI_RH_HIERARCHY& auth_handle,
25835 const std::string& auth_handle_name,
25836 const TPMI_RH_ENABLES& enable,
25837 const TPMI_YES_NO& state,
25838 AuthorizationDelegate* authorization_delegate) {
25839 VLOG(1) << __func__;
25840 std::string command;
25841 TPM_RC rc = SerializeCommand_HierarchyControl(auth_handle, auth_handle_name,
25842 enable, state, &command,
25843 authorization_delegate);
25844 if (rc != TPM_RC_SUCCESS) {
25845 return rc;
25846 }
25847 std::string response = transceiver_->SendCommandAndWait(command);
25848 rc = ParseResponse_HierarchyControl(response, authorization_delegate);
25849 return rc;
25850 }
25851
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)25852 TPM_RC Tpm::SerializeCommand_SetPrimaryPolicy(
25853 const TPMI_RH_HIERARCHY& auth_handle,
25854 const std::string& auth_handle_name,
25855 const TPM2B_DIGEST& auth_policy,
25856 const TPMI_ALG_HASH& hash_alg,
25857 std::string* serialized_command,
25858 AuthorizationDelegate* authorization_delegate) {
25859 VLOG(3) << __func__;
25860 TPM_RC rc = TPM_RC_SUCCESS;
25861 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25862 UINT32 command_size = 10; // Header size.
25863 std::string handle_section_bytes;
25864 std::string parameter_section_bytes;
25865 TPM_CC command_code = TPM_CC_SetPrimaryPolicy;
25866 bool is_command_parameter_encryption_possible = true;
25867 bool is_response_parameter_encryption_possible = false;
25868 std::string command_code_bytes;
25869 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25870 if (rc != TPM_RC_SUCCESS) {
25871 return rc;
25872 }
25873 std::string auth_handle_bytes;
25874 rc = Serialize_TPMI_RH_HIERARCHY(auth_handle, &auth_handle_bytes);
25875 if (rc != TPM_RC_SUCCESS) {
25876 return rc;
25877 }
25878 std::string auth_policy_bytes;
25879 rc = Serialize_TPM2B_DIGEST(auth_policy, &auth_policy_bytes);
25880 if (rc != TPM_RC_SUCCESS) {
25881 return rc;
25882 }
25883 std::string hash_alg_bytes;
25884 rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
25885 if (rc != TPM_RC_SUCCESS) {
25886 return rc;
25887 }
25888 if (authorization_delegate) {
25889 // Encrypt just the parameter data, not the size.
25890 std::string tmp = auth_policy_bytes.substr(2);
25891 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
25892 return TRUNKS_RC_ENCRYPTION_FAILED;
25893 }
25894 auth_policy_bytes.replace(2, std::string::npos, tmp);
25895 }
25896 std::unique_ptr<crypto::SecureHash> hash(
25897 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25898 hash->Update(command_code_bytes.data(), command_code_bytes.size());
25899 hash->Update(auth_handle_name.data(), auth_handle_name.size());
25900 handle_section_bytes += auth_handle_bytes;
25901 command_size += auth_handle_bytes.size();
25902 hash->Update(auth_policy_bytes.data(), auth_policy_bytes.size());
25903 parameter_section_bytes += auth_policy_bytes;
25904 command_size += auth_policy_bytes.size();
25905 hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
25906 parameter_section_bytes += hash_alg_bytes;
25907 command_size += hash_alg_bytes.size();
25908 std::string command_hash(32, 0);
25909 hash->Finish(std::data(command_hash), command_hash.size());
25910 std::string authorization_section_bytes;
25911 std::string authorization_size_bytes;
25912 if (authorization_delegate) {
25913 if (!authorization_delegate->GetCommandAuthorization(
25914 command_hash, is_command_parameter_encryption_possible,
25915 is_response_parameter_encryption_possible,
25916 &authorization_section_bytes)) {
25917 return TRUNKS_RC_AUTHORIZATION_FAILED;
25918 }
25919 if (!authorization_section_bytes.empty()) {
25920 tag = TPM_ST_SESSIONS;
25921 std::string tmp;
25922 rc = Serialize_UINT32(authorization_section_bytes.size(),
25923 &authorization_size_bytes);
25924 if (rc != TPM_RC_SUCCESS) {
25925 return rc;
25926 }
25927 command_size +=
25928 authorization_size_bytes.size() + authorization_section_bytes.size();
25929 }
25930 }
25931 std::string tag_bytes;
25932 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25933 if (rc != TPM_RC_SUCCESS) {
25934 return rc;
25935 }
25936 std::string command_size_bytes;
25937 rc = Serialize_UINT32(command_size, &command_size_bytes);
25938 if (rc != TPM_RC_SUCCESS) {
25939 return rc;
25940 }
25941 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25942 handle_section_bytes + authorization_size_bytes +
25943 authorization_section_bytes + parameter_section_bytes;
25944 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25945 VLOG(2) << "Command: "
25946 << base::HexEncode(serialized_command->data(),
25947 serialized_command->size());
25948 return TPM_RC_SUCCESS;
25949 }
25950
ParseResponse_SetPrimaryPolicy(const std::string & response,AuthorizationDelegate * authorization_delegate)25951 TPM_RC Tpm::ParseResponse_SetPrimaryPolicy(
25952 const std::string& response,
25953 AuthorizationDelegate* authorization_delegate) {
25954 VLOG(3) << __func__;
25955 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25956 TPM_RC rc = TPM_RC_SUCCESS;
25957 std::string buffer(response);
25958 TPM_ST tag;
25959 std::string tag_bytes;
25960 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25961 if (rc != TPM_RC_SUCCESS) {
25962 return rc;
25963 }
25964 UINT32 response_size;
25965 std::string response_size_bytes;
25966 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25967 if (rc != TPM_RC_SUCCESS) {
25968 return rc;
25969 }
25970 TPM_RC response_code;
25971 std::string response_code_bytes;
25972 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25973 if (rc != TPM_RC_SUCCESS) {
25974 return rc;
25975 }
25976 if (response_size != response.size()) {
25977 return TPM_RC_SIZE;
25978 }
25979 if (response_code != TPM_RC_SUCCESS) {
25980 return response_code;
25981 }
25982 TPM_CC command_code = TPM_CC_SetPrimaryPolicy;
25983 std::string command_code_bytes;
25984 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25985 if (rc != TPM_RC_SUCCESS) {
25986 return rc;
25987 }
25988 std::string authorization_section_bytes;
25989 if (tag == TPM_ST_SESSIONS) {
25990 UINT32 parameter_section_size = buffer.size();
25991 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
25992 if (rc != TPM_RC_SUCCESS) {
25993 return rc;
25994 }
25995 if (parameter_section_size > buffer.size()) {
25996 return TPM_RC_INSUFFICIENT;
25997 }
25998 authorization_section_bytes = buffer.substr(parameter_section_size);
25999 // Keep the parameter section in |buffer|.
26000 buffer.erase(parameter_section_size);
26001 }
26002 std::unique_ptr<crypto::SecureHash> hash(
26003 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26004 hash->Update(response_code_bytes.data(), response_code_bytes.size());
26005 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26006 hash->Update(buffer.data(), buffer.size());
26007 std::string response_hash(32, 0);
26008 hash->Finish(std::data(response_hash), response_hash.size());
26009 if (tag == TPM_ST_SESSIONS) {
26010 if (!authorization_delegate)
26011 return TRUNKS_RC_AUTHORIZATION_FAILED;
26012 if (!authorization_delegate->CheckResponseAuthorization(
26013 response_hash, authorization_section_bytes)) {
26014 return TRUNKS_RC_AUTHORIZATION_FAILED;
26015 }
26016 }
26017 return TPM_RC_SUCCESS;
26018 }
26019
SetPrimaryPolicyErrorCallback(Tpm::SetPrimaryPolicyResponse callback,TPM_RC response_code)26020 void SetPrimaryPolicyErrorCallback(Tpm::SetPrimaryPolicyResponse callback,
26021 TPM_RC response_code) {
26022 VLOG(1) << __func__;
26023 std::move(callback).Run(response_code);
26024 }
26025
SetPrimaryPolicyResponseParser(Tpm::SetPrimaryPolicyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26026 void SetPrimaryPolicyResponseParser(
26027 Tpm::SetPrimaryPolicyResponse callback,
26028 AuthorizationDelegate* authorization_delegate,
26029 const std::string& response) {
26030 VLOG(1) << __func__;
26031 TPM_RC rc =
26032 Tpm::ParseResponse_SetPrimaryPolicy(response, authorization_delegate);
26033 if (rc != TPM_RC_SUCCESS) {
26034 base::OnceCallback<void(TPM_RC)> error_reporter =
26035 base::BindOnce(SetPrimaryPolicyErrorCallback, std::move(callback));
26036 std::move(error_reporter).Run(rc);
26037 return;
26038 }
26039 std::move(callback).Run(rc);
26040 }
26041
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)26042 void Tpm::SetPrimaryPolicy(const TPMI_RH_HIERARCHY& auth_handle,
26043 const std::string& auth_handle_name,
26044 const TPM2B_DIGEST& auth_policy,
26045 const TPMI_ALG_HASH& hash_alg,
26046 AuthorizationDelegate* authorization_delegate,
26047 SetPrimaryPolicyResponse callback) {
26048 VLOG(1) << __func__;
26049 std::string command;
26050 TPM_RC rc = SerializeCommand_SetPrimaryPolicy(auth_handle, auth_handle_name,
26051 auth_policy, hash_alg, &command,
26052 authorization_delegate);
26053 if (rc != TPM_RC_SUCCESS) {
26054 base::OnceCallback<void(TPM_RC)> error_reporter =
26055 base::BindOnce(SetPrimaryPolicyErrorCallback, std::move(callback));
26056 std::move(error_reporter).Run(rc);
26057 return;
26058 }
26059 base::OnceCallback<void(const std::string&)> parser =
26060 base::BindOnce(SetPrimaryPolicyResponseParser, std::move(callback),
26061 authorization_delegate);
26062 transceiver_->SendCommand(command, std::move(parser));
26063 }
26064
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)26065 TPM_RC Tpm::SetPrimaryPolicySync(
26066 const TPMI_RH_HIERARCHY& auth_handle,
26067 const std::string& auth_handle_name,
26068 const TPM2B_DIGEST& auth_policy,
26069 const TPMI_ALG_HASH& hash_alg,
26070 AuthorizationDelegate* authorization_delegate) {
26071 VLOG(1) << __func__;
26072 std::string command;
26073 TPM_RC rc = SerializeCommand_SetPrimaryPolicy(auth_handle, auth_handle_name,
26074 auth_policy, hash_alg, &command,
26075 authorization_delegate);
26076 if (rc != TPM_RC_SUCCESS) {
26077 return rc;
26078 }
26079 std::string response = transceiver_->SendCommandAndWait(command);
26080 rc = ParseResponse_SetPrimaryPolicy(response, authorization_delegate);
26081 return rc;
26082 }
26083
SerializeCommand_ChangePPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26084 TPM_RC Tpm::SerializeCommand_ChangePPS(
26085 const TPMI_RH_PLATFORM& auth_handle,
26086 const std::string& auth_handle_name,
26087 std::string* serialized_command,
26088 AuthorizationDelegate* authorization_delegate) {
26089 VLOG(3) << __func__;
26090 TPM_RC rc = TPM_RC_SUCCESS;
26091 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26092 UINT32 command_size = 10; // Header size.
26093 std::string handle_section_bytes;
26094 std::string parameter_section_bytes;
26095 TPM_CC command_code = TPM_CC_ChangePPS;
26096 bool is_command_parameter_encryption_possible = false;
26097 bool is_response_parameter_encryption_possible = false;
26098 std::string command_code_bytes;
26099 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26100 if (rc != TPM_RC_SUCCESS) {
26101 return rc;
26102 }
26103 std::string auth_handle_bytes;
26104 rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
26105 if (rc != TPM_RC_SUCCESS) {
26106 return rc;
26107 }
26108 std::unique_ptr<crypto::SecureHash> hash(
26109 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26110 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26111 hash->Update(auth_handle_name.data(), auth_handle_name.size());
26112 handle_section_bytes += auth_handle_bytes;
26113 command_size += auth_handle_bytes.size();
26114 std::string command_hash(32, 0);
26115 hash->Finish(std::data(command_hash), command_hash.size());
26116 std::string authorization_section_bytes;
26117 std::string authorization_size_bytes;
26118 if (authorization_delegate) {
26119 if (!authorization_delegate->GetCommandAuthorization(
26120 command_hash, is_command_parameter_encryption_possible,
26121 is_response_parameter_encryption_possible,
26122 &authorization_section_bytes)) {
26123 return TRUNKS_RC_AUTHORIZATION_FAILED;
26124 }
26125 if (!authorization_section_bytes.empty()) {
26126 tag = TPM_ST_SESSIONS;
26127 std::string tmp;
26128 rc = Serialize_UINT32(authorization_section_bytes.size(),
26129 &authorization_size_bytes);
26130 if (rc != TPM_RC_SUCCESS) {
26131 return rc;
26132 }
26133 command_size +=
26134 authorization_size_bytes.size() + authorization_section_bytes.size();
26135 }
26136 }
26137 std::string tag_bytes;
26138 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26139 if (rc != TPM_RC_SUCCESS) {
26140 return rc;
26141 }
26142 std::string command_size_bytes;
26143 rc = Serialize_UINT32(command_size, &command_size_bytes);
26144 if (rc != TPM_RC_SUCCESS) {
26145 return rc;
26146 }
26147 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26148 handle_section_bytes + authorization_size_bytes +
26149 authorization_section_bytes + parameter_section_bytes;
26150 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26151 VLOG(2) << "Command: "
26152 << base::HexEncode(serialized_command->data(),
26153 serialized_command->size());
26154 return TPM_RC_SUCCESS;
26155 }
26156
ParseResponse_ChangePPS(const std::string & response,AuthorizationDelegate * authorization_delegate)26157 TPM_RC Tpm::ParseResponse_ChangePPS(
26158 const std::string& response,
26159 AuthorizationDelegate* authorization_delegate) {
26160 VLOG(3) << __func__;
26161 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26162 TPM_RC rc = TPM_RC_SUCCESS;
26163 std::string buffer(response);
26164 TPM_ST tag;
26165 std::string tag_bytes;
26166 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26167 if (rc != TPM_RC_SUCCESS) {
26168 return rc;
26169 }
26170 UINT32 response_size;
26171 std::string response_size_bytes;
26172 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26173 if (rc != TPM_RC_SUCCESS) {
26174 return rc;
26175 }
26176 TPM_RC response_code;
26177 std::string response_code_bytes;
26178 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26179 if (rc != TPM_RC_SUCCESS) {
26180 return rc;
26181 }
26182 if (response_size != response.size()) {
26183 return TPM_RC_SIZE;
26184 }
26185 if (response_code != TPM_RC_SUCCESS) {
26186 return response_code;
26187 }
26188 TPM_CC command_code = TPM_CC_ChangePPS;
26189 std::string command_code_bytes;
26190 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26191 if (rc != TPM_RC_SUCCESS) {
26192 return rc;
26193 }
26194 std::string authorization_section_bytes;
26195 if (tag == TPM_ST_SESSIONS) {
26196 UINT32 parameter_section_size = buffer.size();
26197 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
26198 if (rc != TPM_RC_SUCCESS) {
26199 return rc;
26200 }
26201 if (parameter_section_size > buffer.size()) {
26202 return TPM_RC_INSUFFICIENT;
26203 }
26204 authorization_section_bytes = buffer.substr(parameter_section_size);
26205 // Keep the parameter section in |buffer|.
26206 buffer.erase(parameter_section_size);
26207 }
26208 std::unique_ptr<crypto::SecureHash> hash(
26209 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26210 hash->Update(response_code_bytes.data(), response_code_bytes.size());
26211 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26212 hash->Update(buffer.data(), buffer.size());
26213 std::string response_hash(32, 0);
26214 hash->Finish(std::data(response_hash), response_hash.size());
26215 if (tag == TPM_ST_SESSIONS) {
26216 if (!authorization_delegate)
26217 return TRUNKS_RC_AUTHORIZATION_FAILED;
26218 if (!authorization_delegate->CheckResponseAuthorization(
26219 response_hash, authorization_section_bytes)) {
26220 return TRUNKS_RC_AUTHORIZATION_FAILED;
26221 }
26222 }
26223 return TPM_RC_SUCCESS;
26224 }
26225
ChangePPSErrorCallback(Tpm::ChangePPSResponse callback,TPM_RC response_code)26226 void ChangePPSErrorCallback(Tpm::ChangePPSResponse callback,
26227 TPM_RC response_code) {
26228 VLOG(1) << __func__;
26229 std::move(callback).Run(response_code);
26230 }
26231
ChangePPSResponseParser(Tpm::ChangePPSResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26232 void ChangePPSResponseParser(Tpm::ChangePPSResponse callback,
26233 AuthorizationDelegate* authorization_delegate,
26234 const std::string& response) {
26235 VLOG(1) << __func__;
26236 TPM_RC rc = Tpm::ParseResponse_ChangePPS(response, authorization_delegate);
26237 if (rc != TPM_RC_SUCCESS) {
26238 base::OnceCallback<void(TPM_RC)> error_reporter =
26239 base::BindOnce(ChangePPSErrorCallback, std::move(callback));
26240 std::move(error_reporter).Run(rc);
26241 return;
26242 }
26243 std::move(callback).Run(rc);
26244 }
26245
ChangePPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ChangePPSResponse callback)26246 void Tpm::ChangePPS(const TPMI_RH_PLATFORM& auth_handle,
26247 const std::string& auth_handle_name,
26248 AuthorizationDelegate* authorization_delegate,
26249 ChangePPSResponse callback) {
26250 VLOG(1) << __func__;
26251 std::string command;
26252 TPM_RC rc = SerializeCommand_ChangePPS(auth_handle, auth_handle_name,
26253 &command, authorization_delegate);
26254 if (rc != TPM_RC_SUCCESS) {
26255 base::OnceCallback<void(TPM_RC)> error_reporter =
26256 base::BindOnce(ChangePPSErrorCallback, std::move(callback));
26257 std::move(error_reporter).Run(rc);
26258 return;
26259 }
26260 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26261 ChangePPSResponseParser, std::move(callback), authorization_delegate);
26262 transceiver_->SendCommand(command, std::move(parser));
26263 }
26264
ChangePPSSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26265 TPM_RC Tpm::ChangePPSSync(const TPMI_RH_PLATFORM& auth_handle,
26266 const std::string& auth_handle_name,
26267 AuthorizationDelegate* authorization_delegate) {
26268 VLOG(1) << __func__;
26269 std::string command;
26270 TPM_RC rc = SerializeCommand_ChangePPS(auth_handle, auth_handle_name,
26271 &command, authorization_delegate);
26272 if (rc != TPM_RC_SUCCESS) {
26273 return rc;
26274 }
26275 std::string response = transceiver_->SendCommandAndWait(command);
26276 rc = ParseResponse_ChangePPS(response, authorization_delegate);
26277 return rc;
26278 }
26279
SerializeCommand_ChangeEPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26280 TPM_RC Tpm::SerializeCommand_ChangeEPS(
26281 const TPMI_RH_PLATFORM& auth_handle,
26282 const std::string& auth_handle_name,
26283 std::string* serialized_command,
26284 AuthorizationDelegate* authorization_delegate) {
26285 VLOG(3) << __func__;
26286 TPM_RC rc = TPM_RC_SUCCESS;
26287 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26288 UINT32 command_size = 10; // Header size.
26289 std::string handle_section_bytes;
26290 std::string parameter_section_bytes;
26291 TPM_CC command_code = TPM_CC_ChangeEPS;
26292 bool is_command_parameter_encryption_possible = false;
26293 bool is_response_parameter_encryption_possible = false;
26294 std::string command_code_bytes;
26295 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26296 if (rc != TPM_RC_SUCCESS) {
26297 return rc;
26298 }
26299 std::string auth_handle_bytes;
26300 rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
26301 if (rc != TPM_RC_SUCCESS) {
26302 return rc;
26303 }
26304 std::unique_ptr<crypto::SecureHash> hash(
26305 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26306 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26307 hash->Update(auth_handle_name.data(), auth_handle_name.size());
26308 handle_section_bytes += auth_handle_bytes;
26309 command_size += auth_handle_bytes.size();
26310 std::string command_hash(32, 0);
26311 hash->Finish(std::data(command_hash), command_hash.size());
26312 std::string authorization_section_bytes;
26313 std::string authorization_size_bytes;
26314 if (authorization_delegate) {
26315 if (!authorization_delegate->GetCommandAuthorization(
26316 command_hash, is_command_parameter_encryption_possible,
26317 is_response_parameter_encryption_possible,
26318 &authorization_section_bytes)) {
26319 return TRUNKS_RC_AUTHORIZATION_FAILED;
26320 }
26321 if (!authorization_section_bytes.empty()) {
26322 tag = TPM_ST_SESSIONS;
26323 std::string tmp;
26324 rc = Serialize_UINT32(authorization_section_bytes.size(),
26325 &authorization_size_bytes);
26326 if (rc != TPM_RC_SUCCESS) {
26327 return rc;
26328 }
26329 command_size +=
26330 authorization_size_bytes.size() + authorization_section_bytes.size();
26331 }
26332 }
26333 std::string tag_bytes;
26334 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26335 if (rc != TPM_RC_SUCCESS) {
26336 return rc;
26337 }
26338 std::string command_size_bytes;
26339 rc = Serialize_UINT32(command_size, &command_size_bytes);
26340 if (rc != TPM_RC_SUCCESS) {
26341 return rc;
26342 }
26343 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26344 handle_section_bytes + authorization_size_bytes +
26345 authorization_section_bytes + parameter_section_bytes;
26346 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26347 VLOG(2) << "Command: "
26348 << base::HexEncode(serialized_command->data(),
26349 serialized_command->size());
26350 return TPM_RC_SUCCESS;
26351 }
26352
ParseResponse_ChangeEPS(const std::string & response,AuthorizationDelegate * authorization_delegate)26353 TPM_RC Tpm::ParseResponse_ChangeEPS(
26354 const std::string& response,
26355 AuthorizationDelegate* authorization_delegate) {
26356 VLOG(3) << __func__;
26357 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26358 TPM_RC rc = TPM_RC_SUCCESS;
26359 std::string buffer(response);
26360 TPM_ST tag;
26361 std::string tag_bytes;
26362 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26363 if (rc != TPM_RC_SUCCESS) {
26364 return rc;
26365 }
26366 UINT32 response_size;
26367 std::string response_size_bytes;
26368 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26369 if (rc != TPM_RC_SUCCESS) {
26370 return rc;
26371 }
26372 TPM_RC response_code;
26373 std::string response_code_bytes;
26374 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26375 if (rc != TPM_RC_SUCCESS) {
26376 return rc;
26377 }
26378 if (response_size != response.size()) {
26379 return TPM_RC_SIZE;
26380 }
26381 if (response_code != TPM_RC_SUCCESS) {
26382 return response_code;
26383 }
26384 TPM_CC command_code = TPM_CC_ChangeEPS;
26385 std::string command_code_bytes;
26386 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26387 if (rc != TPM_RC_SUCCESS) {
26388 return rc;
26389 }
26390 std::string authorization_section_bytes;
26391 if (tag == TPM_ST_SESSIONS) {
26392 UINT32 parameter_section_size = buffer.size();
26393 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
26394 if (rc != TPM_RC_SUCCESS) {
26395 return rc;
26396 }
26397 if (parameter_section_size > buffer.size()) {
26398 return TPM_RC_INSUFFICIENT;
26399 }
26400 authorization_section_bytes = buffer.substr(parameter_section_size);
26401 // Keep the parameter section in |buffer|.
26402 buffer.erase(parameter_section_size);
26403 }
26404 std::unique_ptr<crypto::SecureHash> hash(
26405 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26406 hash->Update(response_code_bytes.data(), response_code_bytes.size());
26407 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26408 hash->Update(buffer.data(), buffer.size());
26409 std::string response_hash(32, 0);
26410 hash->Finish(std::data(response_hash), response_hash.size());
26411 if (tag == TPM_ST_SESSIONS) {
26412 if (!authorization_delegate)
26413 return TRUNKS_RC_AUTHORIZATION_FAILED;
26414 if (!authorization_delegate->CheckResponseAuthorization(
26415 response_hash, authorization_section_bytes)) {
26416 return TRUNKS_RC_AUTHORIZATION_FAILED;
26417 }
26418 }
26419 return TPM_RC_SUCCESS;
26420 }
26421
ChangeEPSErrorCallback(Tpm::ChangeEPSResponse callback,TPM_RC response_code)26422 void ChangeEPSErrorCallback(Tpm::ChangeEPSResponse callback,
26423 TPM_RC response_code) {
26424 VLOG(1) << __func__;
26425 std::move(callback).Run(response_code);
26426 }
26427
ChangeEPSResponseParser(Tpm::ChangeEPSResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26428 void ChangeEPSResponseParser(Tpm::ChangeEPSResponse callback,
26429 AuthorizationDelegate* authorization_delegate,
26430 const std::string& response) {
26431 VLOG(1) << __func__;
26432 TPM_RC rc = Tpm::ParseResponse_ChangeEPS(response, authorization_delegate);
26433 if (rc != TPM_RC_SUCCESS) {
26434 base::OnceCallback<void(TPM_RC)> error_reporter =
26435 base::BindOnce(ChangeEPSErrorCallback, std::move(callback));
26436 std::move(error_reporter).Run(rc);
26437 return;
26438 }
26439 std::move(callback).Run(rc);
26440 }
26441
ChangeEPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ChangeEPSResponse callback)26442 void Tpm::ChangeEPS(const TPMI_RH_PLATFORM& auth_handle,
26443 const std::string& auth_handle_name,
26444 AuthorizationDelegate* authorization_delegate,
26445 ChangeEPSResponse callback) {
26446 VLOG(1) << __func__;
26447 std::string command;
26448 TPM_RC rc = SerializeCommand_ChangeEPS(auth_handle, auth_handle_name,
26449 &command, authorization_delegate);
26450 if (rc != TPM_RC_SUCCESS) {
26451 base::OnceCallback<void(TPM_RC)> error_reporter =
26452 base::BindOnce(ChangeEPSErrorCallback, std::move(callback));
26453 std::move(error_reporter).Run(rc);
26454 return;
26455 }
26456 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26457 ChangeEPSResponseParser, std::move(callback), authorization_delegate);
26458 transceiver_->SendCommand(command, std::move(parser));
26459 }
26460
ChangeEPSSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26461 TPM_RC Tpm::ChangeEPSSync(const TPMI_RH_PLATFORM& auth_handle,
26462 const std::string& auth_handle_name,
26463 AuthorizationDelegate* authorization_delegate) {
26464 VLOG(1) << __func__;
26465 std::string command;
26466 TPM_RC rc = SerializeCommand_ChangeEPS(auth_handle, auth_handle_name,
26467 &command, authorization_delegate);
26468 if (rc != TPM_RC_SUCCESS) {
26469 return rc;
26470 }
26471 std::string response = transceiver_->SendCommandAndWait(command);
26472 rc = ParseResponse_ChangeEPS(response, authorization_delegate);
26473 return rc;
26474 }
26475
SerializeCommand_Clear(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26476 TPM_RC Tpm::SerializeCommand_Clear(
26477 const TPMI_RH_CLEAR& auth_handle,
26478 const std::string& auth_handle_name,
26479 std::string* serialized_command,
26480 AuthorizationDelegate* authorization_delegate) {
26481 VLOG(3) << __func__;
26482 TPM_RC rc = TPM_RC_SUCCESS;
26483 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26484 UINT32 command_size = 10; // Header size.
26485 std::string handle_section_bytes;
26486 std::string parameter_section_bytes;
26487 TPM_CC command_code = TPM_CC_Clear;
26488 bool is_command_parameter_encryption_possible = false;
26489 bool is_response_parameter_encryption_possible = false;
26490 std::string command_code_bytes;
26491 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26492 if (rc != TPM_RC_SUCCESS) {
26493 return rc;
26494 }
26495 std::string auth_handle_bytes;
26496 rc = Serialize_TPMI_RH_CLEAR(auth_handle, &auth_handle_bytes);
26497 if (rc != TPM_RC_SUCCESS) {
26498 return rc;
26499 }
26500 std::unique_ptr<crypto::SecureHash> hash(
26501 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26502 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26503 hash->Update(auth_handle_name.data(), auth_handle_name.size());
26504 handle_section_bytes += auth_handle_bytes;
26505 command_size += auth_handle_bytes.size();
26506 std::string command_hash(32, 0);
26507 hash->Finish(std::data(command_hash), command_hash.size());
26508 std::string authorization_section_bytes;
26509 std::string authorization_size_bytes;
26510 if (authorization_delegate) {
26511 if (!authorization_delegate->GetCommandAuthorization(
26512 command_hash, is_command_parameter_encryption_possible,
26513 is_response_parameter_encryption_possible,
26514 &authorization_section_bytes)) {
26515 return TRUNKS_RC_AUTHORIZATION_FAILED;
26516 }
26517 if (!authorization_section_bytes.empty()) {
26518 tag = TPM_ST_SESSIONS;
26519 std::string tmp;
26520 rc = Serialize_UINT32(authorization_section_bytes.size(),
26521 &authorization_size_bytes);
26522 if (rc != TPM_RC_SUCCESS) {
26523 return rc;
26524 }
26525 command_size +=
26526 authorization_size_bytes.size() + authorization_section_bytes.size();
26527 }
26528 }
26529 std::string tag_bytes;
26530 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26531 if (rc != TPM_RC_SUCCESS) {
26532 return rc;
26533 }
26534 std::string command_size_bytes;
26535 rc = Serialize_UINT32(command_size, &command_size_bytes);
26536 if (rc != TPM_RC_SUCCESS) {
26537 return rc;
26538 }
26539 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26540 handle_section_bytes + authorization_size_bytes +
26541 authorization_section_bytes + parameter_section_bytes;
26542 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26543 VLOG(2) << "Command: "
26544 << base::HexEncode(serialized_command->data(),
26545 serialized_command->size());
26546 return TPM_RC_SUCCESS;
26547 }
26548
ParseResponse_Clear(const std::string & response,AuthorizationDelegate * authorization_delegate)26549 TPM_RC Tpm::ParseResponse_Clear(const std::string& response,
26550 AuthorizationDelegate* authorization_delegate) {
26551 VLOG(3) << __func__;
26552 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26553 TPM_RC rc = TPM_RC_SUCCESS;
26554 std::string buffer(response);
26555 TPM_ST tag;
26556 std::string tag_bytes;
26557 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26558 if (rc != TPM_RC_SUCCESS) {
26559 return rc;
26560 }
26561 UINT32 response_size;
26562 std::string response_size_bytes;
26563 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26564 if (rc != TPM_RC_SUCCESS) {
26565 return rc;
26566 }
26567 TPM_RC response_code;
26568 std::string response_code_bytes;
26569 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26570 if (rc != TPM_RC_SUCCESS) {
26571 return rc;
26572 }
26573 if (response_size != response.size()) {
26574 return TPM_RC_SIZE;
26575 }
26576 if (response_code != TPM_RC_SUCCESS) {
26577 return response_code;
26578 }
26579 TPM_CC command_code = TPM_CC_Clear;
26580 std::string command_code_bytes;
26581 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26582 if (rc != TPM_RC_SUCCESS) {
26583 return rc;
26584 }
26585 std::string authorization_section_bytes;
26586 if (tag == TPM_ST_SESSIONS) {
26587 UINT32 parameter_section_size = buffer.size();
26588 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
26589 if (rc != TPM_RC_SUCCESS) {
26590 return rc;
26591 }
26592 if (parameter_section_size > buffer.size()) {
26593 return TPM_RC_INSUFFICIENT;
26594 }
26595 authorization_section_bytes = buffer.substr(parameter_section_size);
26596 // Keep the parameter section in |buffer|.
26597 buffer.erase(parameter_section_size);
26598 }
26599 std::unique_ptr<crypto::SecureHash> hash(
26600 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26601 hash->Update(response_code_bytes.data(), response_code_bytes.size());
26602 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26603 hash->Update(buffer.data(), buffer.size());
26604 std::string response_hash(32, 0);
26605 hash->Finish(std::data(response_hash), response_hash.size());
26606 if (tag == TPM_ST_SESSIONS) {
26607 if (!authorization_delegate)
26608 return TRUNKS_RC_AUTHORIZATION_FAILED;
26609 if (!authorization_delegate->CheckResponseAuthorization(
26610 response_hash, authorization_section_bytes)) {
26611 return TRUNKS_RC_AUTHORIZATION_FAILED;
26612 }
26613 }
26614 return TPM_RC_SUCCESS;
26615 }
26616
ClearErrorCallback(Tpm::ClearResponse callback,TPM_RC response_code)26617 void ClearErrorCallback(Tpm::ClearResponse callback, TPM_RC response_code) {
26618 VLOG(1) << __func__;
26619 std::move(callback).Run(response_code);
26620 }
26621
ClearResponseParser(Tpm::ClearResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26622 void ClearResponseParser(Tpm::ClearResponse callback,
26623 AuthorizationDelegate* authorization_delegate,
26624 const std::string& response) {
26625 VLOG(1) << __func__;
26626 TPM_RC rc = Tpm::ParseResponse_Clear(response, authorization_delegate);
26627 if (rc != TPM_RC_SUCCESS) {
26628 base::OnceCallback<void(TPM_RC)> error_reporter =
26629 base::BindOnce(ClearErrorCallback, std::move(callback));
26630 std::move(error_reporter).Run(rc);
26631 return;
26632 }
26633 std::move(callback).Run(rc);
26634 }
26635
Clear(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ClearResponse callback)26636 void Tpm::Clear(const TPMI_RH_CLEAR& auth_handle,
26637 const std::string& auth_handle_name,
26638 AuthorizationDelegate* authorization_delegate,
26639 ClearResponse callback) {
26640 VLOG(1) << __func__;
26641 std::string command;
26642 TPM_RC rc = SerializeCommand_Clear(auth_handle, auth_handle_name, &command,
26643 authorization_delegate);
26644 if (rc != TPM_RC_SUCCESS) {
26645 base::OnceCallback<void(TPM_RC)> error_reporter =
26646 base::BindOnce(ClearErrorCallback, std::move(callback));
26647 std::move(error_reporter).Run(rc);
26648 return;
26649 }
26650 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26651 ClearResponseParser, std::move(callback), authorization_delegate);
26652 transceiver_->SendCommand(command, std::move(parser));
26653 }
26654
ClearSync(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26655 TPM_RC Tpm::ClearSync(const TPMI_RH_CLEAR& auth_handle,
26656 const std::string& auth_handle_name,
26657 AuthorizationDelegate* authorization_delegate) {
26658 VLOG(1) << __func__;
26659 std::string command;
26660 TPM_RC rc = SerializeCommand_Clear(auth_handle, auth_handle_name, &command,
26661 authorization_delegate);
26662 if (rc != TPM_RC_SUCCESS) {
26663 return rc;
26664 }
26665 std::string response = transceiver_->SendCommandAndWait(command);
26666 rc = ParseResponse_Clear(response, authorization_delegate);
26667 return rc;
26668 }
26669
SerializeCommand_ClearControl(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26670 TPM_RC Tpm::SerializeCommand_ClearControl(
26671 const TPMI_RH_CLEAR& auth,
26672 const std::string& auth_name,
26673 const TPMI_YES_NO& disable,
26674 std::string* serialized_command,
26675 AuthorizationDelegate* authorization_delegate) {
26676 VLOG(3) << __func__;
26677 TPM_RC rc = TPM_RC_SUCCESS;
26678 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26679 UINT32 command_size = 10; // Header size.
26680 std::string handle_section_bytes;
26681 std::string parameter_section_bytes;
26682 TPM_CC command_code = TPM_CC_ClearControl;
26683 bool is_command_parameter_encryption_possible = false;
26684 bool is_response_parameter_encryption_possible = false;
26685 std::string command_code_bytes;
26686 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26687 if (rc != TPM_RC_SUCCESS) {
26688 return rc;
26689 }
26690 std::string auth_bytes;
26691 rc = Serialize_TPMI_RH_CLEAR(auth, &auth_bytes);
26692 if (rc != TPM_RC_SUCCESS) {
26693 return rc;
26694 }
26695 std::string disable_bytes;
26696 rc = Serialize_TPMI_YES_NO(disable, &disable_bytes);
26697 if (rc != TPM_RC_SUCCESS) {
26698 return rc;
26699 }
26700 std::unique_ptr<crypto::SecureHash> hash(
26701 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26702 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26703 hash->Update(auth_name.data(), auth_name.size());
26704 handle_section_bytes += auth_bytes;
26705 command_size += auth_bytes.size();
26706 hash->Update(disable_bytes.data(), disable_bytes.size());
26707 parameter_section_bytes += disable_bytes;
26708 command_size += disable_bytes.size();
26709 std::string command_hash(32, 0);
26710 hash->Finish(std::data(command_hash), command_hash.size());
26711 std::string authorization_section_bytes;
26712 std::string authorization_size_bytes;
26713 if (authorization_delegate) {
26714 if (!authorization_delegate->GetCommandAuthorization(
26715 command_hash, is_command_parameter_encryption_possible,
26716 is_response_parameter_encryption_possible,
26717 &authorization_section_bytes)) {
26718 return TRUNKS_RC_AUTHORIZATION_FAILED;
26719 }
26720 if (!authorization_section_bytes.empty()) {
26721 tag = TPM_ST_SESSIONS;
26722 std::string tmp;
26723 rc = Serialize_UINT32(authorization_section_bytes.size(),
26724 &authorization_size_bytes);
26725 if (rc != TPM_RC_SUCCESS) {
26726 return rc;
26727 }
26728 command_size +=
26729 authorization_size_bytes.size() + authorization_section_bytes.size();
26730 }
26731 }
26732 std::string tag_bytes;
26733 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26734 if (rc != TPM_RC_SUCCESS) {
26735 return rc;
26736 }
26737 std::string command_size_bytes;
26738 rc = Serialize_UINT32(command_size, &command_size_bytes);
26739 if (rc != TPM_RC_SUCCESS) {
26740 return rc;
26741 }
26742 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26743 handle_section_bytes + authorization_size_bytes +
26744 authorization_section_bytes + parameter_section_bytes;
26745 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26746 VLOG(2) << "Command: "
26747 << base::HexEncode(serialized_command->data(),
26748 serialized_command->size());
26749 return TPM_RC_SUCCESS;
26750 }
26751
ParseResponse_ClearControl(const std::string & response,AuthorizationDelegate * authorization_delegate)26752 TPM_RC Tpm::ParseResponse_ClearControl(
26753 const std::string& response,
26754 AuthorizationDelegate* authorization_delegate) {
26755 VLOG(3) << __func__;
26756 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26757 TPM_RC rc = TPM_RC_SUCCESS;
26758 std::string buffer(response);
26759 TPM_ST tag;
26760 std::string tag_bytes;
26761 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26762 if (rc != TPM_RC_SUCCESS) {
26763 return rc;
26764 }
26765 UINT32 response_size;
26766 std::string response_size_bytes;
26767 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26768 if (rc != TPM_RC_SUCCESS) {
26769 return rc;
26770 }
26771 TPM_RC response_code;
26772 std::string response_code_bytes;
26773 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26774 if (rc != TPM_RC_SUCCESS) {
26775 return rc;
26776 }
26777 if (response_size != response.size()) {
26778 return TPM_RC_SIZE;
26779 }
26780 if (response_code != TPM_RC_SUCCESS) {
26781 return response_code;
26782 }
26783 TPM_CC command_code = TPM_CC_ClearControl;
26784 std::string command_code_bytes;
26785 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26786 if (rc != TPM_RC_SUCCESS) {
26787 return rc;
26788 }
26789 std::string authorization_section_bytes;
26790 if (tag == TPM_ST_SESSIONS) {
26791 UINT32 parameter_section_size = buffer.size();
26792 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
26793 if (rc != TPM_RC_SUCCESS) {
26794 return rc;
26795 }
26796 if (parameter_section_size > buffer.size()) {
26797 return TPM_RC_INSUFFICIENT;
26798 }
26799 authorization_section_bytes = buffer.substr(parameter_section_size);
26800 // Keep the parameter section in |buffer|.
26801 buffer.erase(parameter_section_size);
26802 }
26803 std::unique_ptr<crypto::SecureHash> hash(
26804 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26805 hash->Update(response_code_bytes.data(), response_code_bytes.size());
26806 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26807 hash->Update(buffer.data(), buffer.size());
26808 std::string response_hash(32, 0);
26809 hash->Finish(std::data(response_hash), response_hash.size());
26810 if (tag == TPM_ST_SESSIONS) {
26811 if (!authorization_delegate)
26812 return TRUNKS_RC_AUTHORIZATION_FAILED;
26813 if (!authorization_delegate->CheckResponseAuthorization(
26814 response_hash, authorization_section_bytes)) {
26815 return TRUNKS_RC_AUTHORIZATION_FAILED;
26816 }
26817 }
26818 return TPM_RC_SUCCESS;
26819 }
26820
ClearControlErrorCallback(Tpm::ClearControlResponse callback,TPM_RC response_code)26821 void ClearControlErrorCallback(Tpm::ClearControlResponse callback,
26822 TPM_RC response_code) {
26823 VLOG(1) << __func__;
26824 std::move(callback).Run(response_code);
26825 }
26826
ClearControlResponseParser(Tpm::ClearControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26827 void ClearControlResponseParser(Tpm::ClearControlResponse callback,
26828 AuthorizationDelegate* authorization_delegate,
26829 const std::string& response) {
26830 VLOG(1) << __func__;
26831 TPM_RC rc = Tpm::ParseResponse_ClearControl(response, authorization_delegate);
26832 if (rc != TPM_RC_SUCCESS) {
26833 base::OnceCallback<void(TPM_RC)> error_reporter =
26834 base::BindOnce(ClearControlErrorCallback, std::move(callback));
26835 std::move(error_reporter).Run(rc);
26836 return;
26837 }
26838 std::move(callback).Run(rc);
26839 }
26840
ClearControl(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,AuthorizationDelegate * authorization_delegate,ClearControlResponse callback)26841 void Tpm::ClearControl(const TPMI_RH_CLEAR& auth,
26842 const std::string& auth_name,
26843 const TPMI_YES_NO& disable,
26844 AuthorizationDelegate* authorization_delegate,
26845 ClearControlResponse callback) {
26846 VLOG(1) << __func__;
26847 std::string command;
26848 TPM_RC rc = SerializeCommand_ClearControl(auth, auth_name, disable, &command,
26849 authorization_delegate);
26850 if (rc != TPM_RC_SUCCESS) {
26851 base::OnceCallback<void(TPM_RC)> error_reporter =
26852 base::BindOnce(ClearControlErrorCallback, std::move(callback));
26853 std::move(error_reporter).Run(rc);
26854 return;
26855 }
26856 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26857 ClearControlResponseParser, std::move(callback), authorization_delegate);
26858 transceiver_->SendCommand(command, std::move(parser));
26859 }
26860
ClearControlSync(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,AuthorizationDelegate * authorization_delegate)26861 TPM_RC Tpm::ClearControlSync(const TPMI_RH_CLEAR& auth,
26862 const std::string& auth_name,
26863 const TPMI_YES_NO& disable,
26864 AuthorizationDelegate* authorization_delegate) {
26865 VLOG(1) << __func__;
26866 std::string command;
26867 TPM_RC rc = SerializeCommand_ClearControl(auth, auth_name, disable, &command,
26868 authorization_delegate);
26869 if (rc != TPM_RC_SUCCESS) {
26870 return rc;
26871 }
26872 std::string response = transceiver_->SendCommandAndWait(command);
26873 rc = ParseResponse_ClearControl(response, authorization_delegate);
26874 return rc;
26875 }
26876
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)26877 TPM_RC Tpm::SerializeCommand_HierarchyChangeAuth(
26878 const TPMI_RH_HIERARCHY_AUTH& auth_handle,
26879 const std::string& auth_handle_name,
26880 const TPM2B_AUTH& new_auth,
26881 std::string* serialized_command,
26882 AuthorizationDelegate* authorization_delegate) {
26883 VLOG(3) << __func__;
26884 TPM_RC rc = TPM_RC_SUCCESS;
26885 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26886 UINT32 command_size = 10; // Header size.
26887 std::string handle_section_bytes;
26888 std::string parameter_section_bytes;
26889 TPM_CC command_code = TPM_CC_HierarchyChangeAuth;
26890 bool is_command_parameter_encryption_possible = true;
26891 bool is_response_parameter_encryption_possible = false;
26892 std::string command_code_bytes;
26893 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26894 if (rc != TPM_RC_SUCCESS) {
26895 return rc;
26896 }
26897 std::string auth_handle_bytes;
26898 rc = Serialize_TPMI_RH_HIERARCHY_AUTH(auth_handle, &auth_handle_bytes);
26899 if (rc != TPM_RC_SUCCESS) {
26900 return rc;
26901 }
26902 std::string new_auth_bytes;
26903 rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
26904 if (rc != TPM_RC_SUCCESS) {
26905 return rc;
26906 }
26907 if (authorization_delegate) {
26908 // Encrypt just the parameter data, not the size.
26909 std::string tmp = new_auth_bytes.substr(2);
26910 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
26911 return TRUNKS_RC_ENCRYPTION_FAILED;
26912 }
26913 new_auth_bytes.replace(2, std::string::npos, tmp);
26914 }
26915 std::unique_ptr<crypto::SecureHash> hash(
26916 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26917 hash->Update(command_code_bytes.data(), command_code_bytes.size());
26918 hash->Update(auth_handle_name.data(), auth_handle_name.size());
26919 handle_section_bytes += auth_handle_bytes;
26920 command_size += auth_handle_bytes.size();
26921 hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
26922 parameter_section_bytes += new_auth_bytes;
26923 command_size += new_auth_bytes.size();
26924 std::string command_hash(32, 0);
26925 hash->Finish(std::data(command_hash), command_hash.size());
26926 std::string authorization_section_bytes;
26927 std::string authorization_size_bytes;
26928 if (authorization_delegate) {
26929 if (!authorization_delegate->GetCommandAuthorization(
26930 command_hash, is_command_parameter_encryption_possible,
26931 is_response_parameter_encryption_possible,
26932 &authorization_section_bytes)) {
26933 return TRUNKS_RC_AUTHORIZATION_FAILED;
26934 }
26935 if (!authorization_section_bytes.empty()) {
26936 tag = TPM_ST_SESSIONS;
26937 std::string tmp;
26938 rc = Serialize_UINT32(authorization_section_bytes.size(),
26939 &authorization_size_bytes);
26940 if (rc != TPM_RC_SUCCESS) {
26941 return rc;
26942 }
26943 command_size +=
26944 authorization_size_bytes.size() + authorization_section_bytes.size();
26945 }
26946 }
26947 std::string tag_bytes;
26948 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26949 if (rc != TPM_RC_SUCCESS) {
26950 return rc;
26951 }
26952 std::string command_size_bytes;
26953 rc = Serialize_UINT32(command_size, &command_size_bytes);
26954 if (rc != TPM_RC_SUCCESS) {
26955 return rc;
26956 }
26957 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26958 handle_section_bytes + authorization_size_bytes +
26959 authorization_section_bytes + parameter_section_bytes;
26960 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26961 VLOG(2) << "Command: "
26962 << base::HexEncode(serialized_command->data(),
26963 serialized_command->size());
26964 return TPM_RC_SUCCESS;
26965 }
26966
ParseResponse_HierarchyChangeAuth(const std::string & response,AuthorizationDelegate * authorization_delegate)26967 TPM_RC Tpm::ParseResponse_HierarchyChangeAuth(
26968 const std::string& response,
26969 AuthorizationDelegate* authorization_delegate) {
26970 VLOG(3) << __func__;
26971 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26972 TPM_RC rc = TPM_RC_SUCCESS;
26973 std::string buffer(response);
26974 TPM_ST tag;
26975 std::string tag_bytes;
26976 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26977 if (rc != TPM_RC_SUCCESS) {
26978 return rc;
26979 }
26980 UINT32 response_size;
26981 std::string response_size_bytes;
26982 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26983 if (rc != TPM_RC_SUCCESS) {
26984 return rc;
26985 }
26986 TPM_RC response_code;
26987 std::string response_code_bytes;
26988 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26989 if (rc != TPM_RC_SUCCESS) {
26990 return rc;
26991 }
26992 if (response_size != response.size()) {
26993 return TPM_RC_SIZE;
26994 }
26995 if (response_code != TPM_RC_SUCCESS) {
26996 return response_code;
26997 }
26998 TPM_CC command_code = TPM_CC_HierarchyChangeAuth;
26999 std::string command_code_bytes;
27000 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27001 if (rc != TPM_RC_SUCCESS) {
27002 return rc;
27003 }
27004 std::string authorization_section_bytes;
27005 if (tag == TPM_ST_SESSIONS) {
27006 UINT32 parameter_section_size = buffer.size();
27007 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
27008 if (rc != TPM_RC_SUCCESS) {
27009 return rc;
27010 }
27011 if (parameter_section_size > buffer.size()) {
27012 return TPM_RC_INSUFFICIENT;
27013 }
27014 authorization_section_bytes = buffer.substr(parameter_section_size);
27015 // Keep the parameter section in |buffer|.
27016 buffer.erase(parameter_section_size);
27017 }
27018 std::unique_ptr<crypto::SecureHash> hash(
27019 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27020 hash->Update(response_code_bytes.data(), response_code_bytes.size());
27021 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27022 hash->Update(buffer.data(), buffer.size());
27023 std::string response_hash(32, 0);
27024 hash->Finish(std::data(response_hash), response_hash.size());
27025 if (tag == TPM_ST_SESSIONS) {
27026 if (!authorization_delegate)
27027 return TRUNKS_RC_AUTHORIZATION_FAILED;
27028 if (!authorization_delegate->CheckResponseAuthorization(
27029 response_hash, authorization_section_bytes)) {
27030 return TRUNKS_RC_AUTHORIZATION_FAILED;
27031 }
27032 }
27033 return TPM_RC_SUCCESS;
27034 }
27035
HierarchyChangeAuthErrorCallback(Tpm::HierarchyChangeAuthResponse callback,TPM_RC response_code)27036 void HierarchyChangeAuthErrorCallback(Tpm::HierarchyChangeAuthResponse callback,
27037 TPM_RC response_code) {
27038 VLOG(1) << __func__;
27039 std::move(callback).Run(response_code);
27040 }
27041
HierarchyChangeAuthResponseParser(Tpm::HierarchyChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27042 void HierarchyChangeAuthResponseParser(
27043 Tpm::HierarchyChangeAuthResponse callback,
27044 AuthorizationDelegate* authorization_delegate,
27045 const std::string& response) {
27046 VLOG(1) << __func__;
27047 TPM_RC rc =
27048 Tpm::ParseResponse_HierarchyChangeAuth(response, authorization_delegate);
27049 if (rc != TPM_RC_SUCCESS) {
27050 base::OnceCallback<void(TPM_RC)> error_reporter =
27051 base::BindOnce(HierarchyChangeAuthErrorCallback, std::move(callback));
27052 std::move(error_reporter).Run(rc);
27053 return;
27054 }
27055 std::move(callback).Run(rc);
27056 }
27057
HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate,HierarchyChangeAuthResponse callback)27058 void Tpm::HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH& auth_handle,
27059 const std::string& auth_handle_name,
27060 const TPM2B_AUTH& new_auth,
27061 AuthorizationDelegate* authorization_delegate,
27062 HierarchyChangeAuthResponse callback) {
27063 VLOG(1) << __func__;
27064 std::string command;
27065 TPM_RC rc = SerializeCommand_HierarchyChangeAuth(
27066 auth_handle, auth_handle_name, new_auth, &command,
27067 authorization_delegate);
27068 if (rc != TPM_RC_SUCCESS) {
27069 base::OnceCallback<void(TPM_RC)> error_reporter =
27070 base::BindOnce(HierarchyChangeAuthErrorCallback, std::move(callback));
27071 std::move(error_reporter).Run(rc);
27072 return;
27073 }
27074 base::OnceCallback<void(const std::string&)> parser =
27075 base::BindOnce(HierarchyChangeAuthResponseParser, std::move(callback),
27076 authorization_delegate);
27077 transceiver_->SendCommand(command, std::move(parser));
27078 }
27079
HierarchyChangeAuthSync(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate)27080 TPM_RC Tpm::HierarchyChangeAuthSync(
27081 const TPMI_RH_HIERARCHY_AUTH& auth_handle,
27082 const std::string& auth_handle_name,
27083 const TPM2B_AUTH& new_auth,
27084 AuthorizationDelegate* authorization_delegate) {
27085 VLOG(1) << __func__;
27086 std::string command;
27087 TPM_RC rc = SerializeCommand_HierarchyChangeAuth(
27088 auth_handle, auth_handle_name, new_auth, &command,
27089 authorization_delegate);
27090 if (rc != TPM_RC_SUCCESS) {
27091 return rc;
27092 }
27093 std::string response = transceiver_->SendCommandAndWait(command);
27094 rc = ParseResponse_HierarchyChangeAuth(response, authorization_delegate);
27095 return rc;
27096 }
27097
SerializeCommand_DictionaryAttackLockReset(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27098 TPM_RC Tpm::SerializeCommand_DictionaryAttackLockReset(
27099 const TPMI_RH_LOCKOUT& lock_handle,
27100 const std::string& lock_handle_name,
27101 std::string* serialized_command,
27102 AuthorizationDelegate* authorization_delegate) {
27103 VLOG(3) << __func__;
27104 TPM_RC rc = TPM_RC_SUCCESS;
27105 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27106 UINT32 command_size = 10; // Header size.
27107 std::string handle_section_bytes;
27108 std::string parameter_section_bytes;
27109 TPM_CC command_code = TPM_CC_DictionaryAttackLockReset;
27110 bool is_command_parameter_encryption_possible = false;
27111 bool is_response_parameter_encryption_possible = false;
27112 std::string command_code_bytes;
27113 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27114 if (rc != TPM_RC_SUCCESS) {
27115 return rc;
27116 }
27117 std::string lock_handle_bytes;
27118 rc = Serialize_TPMI_RH_LOCKOUT(lock_handle, &lock_handle_bytes);
27119 if (rc != TPM_RC_SUCCESS) {
27120 return rc;
27121 }
27122 std::unique_ptr<crypto::SecureHash> hash(
27123 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27124 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27125 hash->Update(lock_handle_name.data(), lock_handle_name.size());
27126 handle_section_bytes += lock_handle_bytes;
27127 command_size += lock_handle_bytes.size();
27128 std::string command_hash(32, 0);
27129 hash->Finish(std::data(command_hash), command_hash.size());
27130 std::string authorization_section_bytes;
27131 std::string authorization_size_bytes;
27132 if (authorization_delegate) {
27133 if (!authorization_delegate->GetCommandAuthorization(
27134 command_hash, is_command_parameter_encryption_possible,
27135 is_response_parameter_encryption_possible,
27136 &authorization_section_bytes)) {
27137 return TRUNKS_RC_AUTHORIZATION_FAILED;
27138 }
27139 if (!authorization_section_bytes.empty()) {
27140 tag = TPM_ST_SESSIONS;
27141 std::string tmp;
27142 rc = Serialize_UINT32(authorization_section_bytes.size(),
27143 &authorization_size_bytes);
27144 if (rc != TPM_RC_SUCCESS) {
27145 return rc;
27146 }
27147 command_size +=
27148 authorization_size_bytes.size() + authorization_section_bytes.size();
27149 }
27150 }
27151 std::string tag_bytes;
27152 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27153 if (rc != TPM_RC_SUCCESS) {
27154 return rc;
27155 }
27156 std::string command_size_bytes;
27157 rc = Serialize_UINT32(command_size, &command_size_bytes);
27158 if (rc != TPM_RC_SUCCESS) {
27159 return rc;
27160 }
27161 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27162 handle_section_bytes + authorization_size_bytes +
27163 authorization_section_bytes + parameter_section_bytes;
27164 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27165 VLOG(2) << "Command: "
27166 << base::HexEncode(serialized_command->data(),
27167 serialized_command->size());
27168 return TPM_RC_SUCCESS;
27169 }
27170
ParseResponse_DictionaryAttackLockReset(const std::string & response,AuthorizationDelegate * authorization_delegate)27171 TPM_RC Tpm::ParseResponse_DictionaryAttackLockReset(
27172 const std::string& response,
27173 AuthorizationDelegate* authorization_delegate) {
27174 VLOG(3) << __func__;
27175 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27176 TPM_RC rc = TPM_RC_SUCCESS;
27177 std::string buffer(response);
27178 TPM_ST tag;
27179 std::string tag_bytes;
27180 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27181 if (rc != TPM_RC_SUCCESS) {
27182 return rc;
27183 }
27184 UINT32 response_size;
27185 std::string response_size_bytes;
27186 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27187 if (rc != TPM_RC_SUCCESS) {
27188 return rc;
27189 }
27190 TPM_RC response_code;
27191 std::string response_code_bytes;
27192 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27193 if (rc != TPM_RC_SUCCESS) {
27194 return rc;
27195 }
27196 if (response_size != response.size()) {
27197 return TPM_RC_SIZE;
27198 }
27199 if (response_code != TPM_RC_SUCCESS) {
27200 return response_code;
27201 }
27202 TPM_CC command_code = TPM_CC_DictionaryAttackLockReset;
27203 std::string command_code_bytes;
27204 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27205 if (rc != TPM_RC_SUCCESS) {
27206 return rc;
27207 }
27208 std::string authorization_section_bytes;
27209 if (tag == TPM_ST_SESSIONS) {
27210 UINT32 parameter_section_size = buffer.size();
27211 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
27212 if (rc != TPM_RC_SUCCESS) {
27213 return rc;
27214 }
27215 if (parameter_section_size > buffer.size()) {
27216 return TPM_RC_INSUFFICIENT;
27217 }
27218 authorization_section_bytes = buffer.substr(parameter_section_size);
27219 // Keep the parameter section in |buffer|.
27220 buffer.erase(parameter_section_size);
27221 }
27222 std::unique_ptr<crypto::SecureHash> hash(
27223 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27224 hash->Update(response_code_bytes.data(), response_code_bytes.size());
27225 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27226 hash->Update(buffer.data(), buffer.size());
27227 std::string response_hash(32, 0);
27228 hash->Finish(std::data(response_hash), response_hash.size());
27229 if (tag == TPM_ST_SESSIONS) {
27230 if (!authorization_delegate)
27231 return TRUNKS_RC_AUTHORIZATION_FAILED;
27232 if (!authorization_delegate->CheckResponseAuthorization(
27233 response_hash, authorization_section_bytes)) {
27234 return TRUNKS_RC_AUTHORIZATION_FAILED;
27235 }
27236 }
27237 return TPM_RC_SUCCESS;
27238 }
27239
DictionaryAttackLockResetErrorCallback(Tpm::DictionaryAttackLockResetResponse callback,TPM_RC response_code)27240 void DictionaryAttackLockResetErrorCallback(
27241 Tpm::DictionaryAttackLockResetResponse callback, TPM_RC response_code) {
27242 VLOG(1) << __func__;
27243 std::move(callback).Run(response_code);
27244 }
27245
DictionaryAttackLockResetResponseParser(Tpm::DictionaryAttackLockResetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27246 void DictionaryAttackLockResetResponseParser(
27247 Tpm::DictionaryAttackLockResetResponse callback,
27248 AuthorizationDelegate* authorization_delegate,
27249 const std::string& response) {
27250 VLOG(1) << __func__;
27251 TPM_RC rc = Tpm::ParseResponse_DictionaryAttackLockReset(
27252 response, authorization_delegate);
27253 if (rc != TPM_RC_SUCCESS) {
27254 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27255 DictionaryAttackLockResetErrorCallback, std::move(callback));
27256 std::move(error_reporter).Run(rc);
27257 return;
27258 }
27259 std::move(callback).Run(rc);
27260 }
27261
DictionaryAttackLockReset(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,AuthorizationDelegate * authorization_delegate,DictionaryAttackLockResetResponse callback)27262 void Tpm::DictionaryAttackLockReset(
27263 const TPMI_RH_LOCKOUT& lock_handle,
27264 const std::string& lock_handle_name,
27265 AuthorizationDelegate* authorization_delegate,
27266 DictionaryAttackLockResetResponse callback) {
27267 VLOG(1) << __func__;
27268 std::string command;
27269 TPM_RC rc = SerializeCommand_DictionaryAttackLockReset(
27270 lock_handle, lock_handle_name, &command, authorization_delegate);
27271 if (rc != TPM_RC_SUCCESS) {
27272 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27273 DictionaryAttackLockResetErrorCallback, std::move(callback));
27274 std::move(error_reporter).Run(rc);
27275 return;
27276 }
27277 base::OnceCallback<void(const std::string&)> parser =
27278 base::BindOnce(DictionaryAttackLockResetResponseParser,
27279 std::move(callback), authorization_delegate);
27280 transceiver_->SendCommand(command, std::move(parser));
27281 }
27282
DictionaryAttackLockResetSync(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,AuthorizationDelegate * authorization_delegate)27283 TPM_RC Tpm::DictionaryAttackLockResetSync(
27284 const TPMI_RH_LOCKOUT& lock_handle,
27285 const std::string& lock_handle_name,
27286 AuthorizationDelegate* authorization_delegate) {
27287 VLOG(1) << __func__;
27288 std::string command;
27289 TPM_RC rc = SerializeCommand_DictionaryAttackLockReset(
27290 lock_handle, lock_handle_name, &command, authorization_delegate);
27291 if (rc != TPM_RC_SUCCESS) {
27292 return rc;
27293 }
27294 std::string response = transceiver_->SendCommandAndWait(command);
27295 rc =
27296 ParseResponse_DictionaryAttackLockReset(response, authorization_delegate);
27297 return rc;
27298 }
27299
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)27300 TPM_RC Tpm::SerializeCommand_DictionaryAttackParameters(
27301 const TPMI_RH_LOCKOUT& lock_handle,
27302 const std::string& lock_handle_name,
27303 const UINT32& new_max_tries,
27304 const UINT32& new_recovery_time,
27305 const UINT32& lockout_recovery,
27306 std::string* serialized_command,
27307 AuthorizationDelegate* authorization_delegate) {
27308 VLOG(3) << __func__;
27309 TPM_RC rc = TPM_RC_SUCCESS;
27310 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27311 UINT32 command_size = 10; // Header size.
27312 std::string handle_section_bytes;
27313 std::string parameter_section_bytes;
27314 TPM_CC command_code = TPM_CC_DictionaryAttackParameters;
27315 bool is_command_parameter_encryption_possible = false;
27316 bool is_response_parameter_encryption_possible = false;
27317 std::string command_code_bytes;
27318 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27319 if (rc != TPM_RC_SUCCESS) {
27320 return rc;
27321 }
27322 std::string lock_handle_bytes;
27323 rc = Serialize_TPMI_RH_LOCKOUT(lock_handle, &lock_handle_bytes);
27324 if (rc != TPM_RC_SUCCESS) {
27325 return rc;
27326 }
27327 std::string new_max_tries_bytes;
27328 rc = Serialize_UINT32(new_max_tries, &new_max_tries_bytes);
27329 if (rc != TPM_RC_SUCCESS) {
27330 return rc;
27331 }
27332 std::string new_recovery_time_bytes;
27333 rc = Serialize_UINT32(new_recovery_time, &new_recovery_time_bytes);
27334 if (rc != TPM_RC_SUCCESS) {
27335 return rc;
27336 }
27337 std::string lockout_recovery_bytes;
27338 rc = Serialize_UINT32(lockout_recovery, &lockout_recovery_bytes);
27339 if (rc != TPM_RC_SUCCESS) {
27340 return rc;
27341 }
27342 std::unique_ptr<crypto::SecureHash> hash(
27343 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27344 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27345 hash->Update(lock_handle_name.data(), lock_handle_name.size());
27346 handle_section_bytes += lock_handle_bytes;
27347 command_size += lock_handle_bytes.size();
27348 hash->Update(new_max_tries_bytes.data(), new_max_tries_bytes.size());
27349 parameter_section_bytes += new_max_tries_bytes;
27350 command_size += new_max_tries_bytes.size();
27351 hash->Update(new_recovery_time_bytes.data(), new_recovery_time_bytes.size());
27352 parameter_section_bytes += new_recovery_time_bytes;
27353 command_size += new_recovery_time_bytes.size();
27354 hash->Update(lockout_recovery_bytes.data(), lockout_recovery_bytes.size());
27355 parameter_section_bytes += lockout_recovery_bytes;
27356 command_size += lockout_recovery_bytes.size();
27357 std::string command_hash(32, 0);
27358 hash->Finish(std::data(command_hash), command_hash.size());
27359 std::string authorization_section_bytes;
27360 std::string authorization_size_bytes;
27361 if (authorization_delegate) {
27362 if (!authorization_delegate->GetCommandAuthorization(
27363 command_hash, is_command_parameter_encryption_possible,
27364 is_response_parameter_encryption_possible,
27365 &authorization_section_bytes)) {
27366 return TRUNKS_RC_AUTHORIZATION_FAILED;
27367 }
27368 if (!authorization_section_bytes.empty()) {
27369 tag = TPM_ST_SESSIONS;
27370 std::string tmp;
27371 rc = Serialize_UINT32(authorization_section_bytes.size(),
27372 &authorization_size_bytes);
27373 if (rc != TPM_RC_SUCCESS) {
27374 return rc;
27375 }
27376 command_size +=
27377 authorization_size_bytes.size() + authorization_section_bytes.size();
27378 }
27379 }
27380 std::string tag_bytes;
27381 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27382 if (rc != TPM_RC_SUCCESS) {
27383 return rc;
27384 }
27385 std::string command_size_bytes;
27386 rc = Serialize_UINT32(command_size, &command_size_bytes);
27387 if (rc != TPM_RC_SUCCESS) {
27388 return rc;
27389 }
27390 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27391 handle_section_bytes + authorization_size_bytes +
27392 authorization_section_bytes + parameter_section_bytes;
27393 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27394 VLOG(2) << "Command: "
27395 << base::HexEncode(serialized_command->data(),
27396 serialized_command->size());
27397 return TPM_RC_SUCCESS;
27398 }
27399
ParseResponse_DictionaryAttackParameters(const std::string & response,AuthorizationDelegate * authorization_delegate)27400 TPM_RC Tpm::ParseResponse_DictionaryAttackParameters(
27401 const std::string& response,
27402 AuthorizationDelegate* authorization_delegate) {
27403 VLOG(3) << __func__;
27404 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27405 TPM_RC rc = TPM_RC_SUCCESS;
27406 std::string buffer(response);
27407 TPM_ST tag;
27408 std::string tag_bytes;
27409 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27410 if (rc != TPM_RC_SUCCESS) {
27411 return rc;
27412 }
27413 UINT32 response_size;
27414 std::string response_size_bytes;
27415 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27416 if (rc != TPM_RC_SUCCESS) {
27417 return rc;
27418 }
27419 TPM_RC response_code;
27420 std::string response_code_bytes;
27421 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27422 if (rc != TPM_RC_SUCCESS) {
27423 return rc;
27424 }
27425 if (response_size != response.size()) {
27426 return TPM_RC_SIZE;
27427 }
27428 if (response_code != TPM_RC_SUCCESS) {
27429 return response_code;
27430 }
27431 TPM_CC command_code = TPM_CC_DictionaryAttackParameters;
27432 std::string command_code_bytes;
27433 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27434 if (rc != TPM_RC_SUCCESS) {
27435 return rc;
27436 }
27437 std::string authorization_section_bytes;
27438 if (tag == TPM_ST_SESSIONS) {
27439 UINT32 parameter_section_size = buffer.size();
27440 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
27441 if (rc != TPM_RC_SUCCESS) {
27442 return rc;
27443 }
27444 if (parameter_section_size > buffer.size()) {
27445 return TPM_RC_INSUFFICIENT;
27446 }
27447 authorization_section_bytes = buffer.substr(parameter_section_size);
27448 // Keep the parameter section in |buffer|.
27449 buffer.erase(parameter_section_size);
27450 }
27451 std::unique_ptr<crypto::SecureHash> hash(
27452 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27453 hash->Update(response_code_bytes.data(), response_code_bytes.size());
27454 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27455 hash->Update(buffer.data(), buffer.size());
27456 std::string response_hash(32, 0);
27457 hash->Finish(std::data(response_hash), response_hash.size());
27458 if (tag == TPM_ST_SESSIONS) {
27459 if (!authorization_delegate)
27460 return TRUNKS_RC_AUTHORIZATION_FAILED;
27461 if (!authorization_delegate->CheckResponseAuthorization(
27462 response_hash, authorization_section_bytes)) {
27463 return TRUNKS_RC_AUTHORIZATION_FAILED;
27464 }
27465 }
27466 return TPM_RC_SUCCESS;
27467 }
27468
DictionaryAttackParametersErrorCallback(Tpm::DictionaryAttackParametersResponse callback,TPM_RC response_code)27469 void DictionaryAttackParametersErrorCallback(
27470 Tpm::DictionaryAttackParametersResponse callback, TPM_RC response_code) {
27471 VLOG(1) << __func__;
27472 std::move(callback).Run(response_code);
27473 }
27474
DictionaryAttackParametersResponseParser(Tpm::DictionaryAttackParametersResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27475 void DictionaryAttackParametersResponseParser(
27476 Tpm::DictionaryAttackParametersResponse callback,
27477 AuthorizationDelegate* authorization_delegate,
27478 const std::string& response) {
27479 VLOG(1) << __func__;
27480 TPM_RC rc = Tpm::ParseResponse_DictionaryAttackParameters(
27481 response, authorization_delegate);
27482 if (rc != TPM_RC_SUCCESS) {
27483 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27484 DictionaryAttackParametersErrorCallback, std::move(callback));
27485 std::move(error_reporter).Run(rc);
27486 return;
27487 }
27488 std::move(callback).Run(rc);
27489 }
27490
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)27491 void Tpm::DictionaryAttackParameters(
27492 const TPMI_RH_LOCKOUT& lock_handle,
27493 const std::string& lock_handle_name,
27494 const UINT32& new_max_tries,
27495 const UINT32& new_recovery_time,
27496 const UINT32& lockout_recovery,
27497 AuthorizationDelegate* authorization_delegate,
27498 DictionaryAttackParametersResponse callback) {
27499 VLOG(1) << __func__;
27500 std::string command;
27501 TPM_RC rc = SerializeCommand_DictionaryAttackParameters(
27502 lock_handle, lock_handle_name, new_max_tries, new_recovery_time,
27503 lockout_recovery, &command, authorization_delegate);
27504 if (rc != TPM_RC_SUCCESS) {
27505 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27506 DictionaryAttackParametersErrorCallback, std::move(callback));
27507 std::move(error_reporter).Run(rc);
27508 return;
27509 }
27510 base::OnceCallback<void(const std::string&)> parser =
27511 base::BindOnce(DictionaryAttackParametersResponseParser,
27512 std::move(callback), authorization_delegate);
27513 transceiver_->SendCommand(command, std::move(parser));
27514 }
27515
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)27516 TPM_RC Tpm::DictionaryAttackParametersSync(
27517 const TPMI_RH_LOCKOUT& lock_handle,
27518 const std::string& lock_handle_name,
27519 const UINT32& new_max_tries,
27520 const UINT32& new_recovery_time,
27521 const UINT32& lockout_recovery,
27522 AuthorizationDelegate* authorization_delegate) {
27523 VLOG(1) << __func__;
27524 std::string command;
27525 TPM_RC rc = SerializeCommand_DictionaryAttackParameters(
27526 lock_handle, lock_handle_name, new_max_tries, new_recovery_time,
27527 lockout_recovery, &command, authorization_delegate);
27528 if (rc != TPM_RC_SUCCESS) {
27529 return rc;
27530 }
27531 std::string response = transceiver_->SendCommandAndWait(command);
27532 rc = ParseResponse_DictionaryAttackParameters(response,
27533 authorization_delegate);
27534 return rc;
27535 }
27536
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)27537 TPM_RC Tpm::SerializeCommand_PP_Commands(
27538 const TPMI_RH_PLATFORM& auth,
27539 const std::string& auth_name,
27540 const TPML_CC& set_list,
27541 const TPML_CC& clear_list,
27542 std::string* serialized_command,
27543 AuthorizationDelegate* authorization_delegate) {
27544 VLOG(3) << __func__;
27545 TPM_RC rc = TPM_RC_SUCCESS;
27546 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27547 UINT32 command_size = 10; // Header size.
27548 std::string handle_section_bytes;
27549 std::string parameter_section_bytes;
27550 TPM_CC command_code = TPM_CC_PP_Commands;
27551 bool is_command_parameter_encryption_possible = false;
27552 bool is_response_parameter_encryption_possible = false;
27553 std::string command_code_bytes;
27554 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27555 if (rc != TPM_RC_SUCCESS) {
27556 return rc;
27557 }
27558 std::string auth_bytes;
27559 rc = Serialize_TPMI_RH_PLATFORM(auth, &auth_bytes);
27560 if (rc != TPM_RC_SUCCESS) {
27561 return rc;
27562 }
27563 std::string set_list_bytes;
27564 rc = Serialize_TPML_CC(set_list, &set_list_bytes);
27565 if (rc != TPM_RC_SUCCESS) {
27566 return rc;
27567 }
27568 std::string clear_list_bytes;
27569 rc = Serialize_TPML_CC(clear_list, &clear_list_bytes);
27570 if (rc != TPM_RC_SUCCESS) {
27571 return rc;
27572 }
27573 std::unique_ptr<crypto::SecureHash> hash(
27574 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27575 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27576 hash->Update(auth_name.data(), auth_name.size());
27577 handle_section_bytes += auth_bytes;
27578 command_size += auth_bytes.size();
27579 hash->Update(set_list_bytes.data(), set_list_bytes.size());
27580 parameter_section_bytes += set_list_bytes;
27581 command_size += set_list_bytes.size();
27582 hash->Update(clear_list_bytes.data(), clear_list_bytes.size());
27583 parameter_section_bytes += clear_list_bytes;
27584 command_size += clear_list_bytes.size();
27585 std::string command_hash(32, 0);
27586 hash->Finish(std::data(command_hash), command_hash.size());
27587 std::string authorization_section_bytes;
27588 std::string authorization_size_bytes;
27589 if (authorization_delegate) {
27590 if (!authorization_delegate->GetCommandAuthorization(
27591 command_hash, is_command_parameter_encryption_possible,
27592 is_response_parameter_encryption_possible,
27593 &authorization_section_bytes)) {
27594 return TRUNKS_RC_AUTHORIZATION_FAILED;
27595 }
27596 if (!authorization_section_bytes.empty()) {
27597 tag = TPM_ST_SESSIONS;
27598 std::string tmp;
27599 rc = Serialize_UINT32(authorization_section_bytes.size(),
27600 &authorization_size_bytes);
27601 if (rc != TPM_RC_SUCCESS) {
27602 return rc;
27603 }
27604 command_size +=
27605 authorization_size_bytes.size() + authorization_section_bytes.size();
27606 }
27607 }
27608 std::string tag_bytes;
27609 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27610 if (rc != TPM_RC_SUCCESS) {
27611 return rc;
27612 }
27613 std::string command_size_bytes;
27614 rc = Serialize_UINT32(command_size, &command_size_bytes);
27615 if (rc != TPM_RC_SUCCESS) {
27616 return rc;
27617 }
27618 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27619 handle_section_bytes + authorization_size_bytes +
27620 authorization_section_bytes + parameter_section_bytes;
27621 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27622 VLOG(2) << "Command: "
27623 << base::HexEncode(serialized_command->data(),
27624 serialized_command->size());
27625 return TPM_RC_SUCCESS;
27626 }
27627
ParseResponse_PP_Commands(const std::string & response,AuthorizationDelegate * authorization_delegate)27628 TPM_RC Tpm::ParseResponse_PP_Commands(
27629 const std::string& response,
27630 AuthorizationDelegate* authorization_delegate) {
27631 VLOG(3) << __func__;
27632 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27633 TPM_RC rc = TPM_RC_SUCCESS;
27634 std::string buffer(response);
27635 TPM_ST tag;
27636 std::string tag_bytes;
27637 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27638 if (rc != TPM_RC_SUCCESS) {
27639 return rc;
27640 }
27641 UINT32 response_size;
27642 std::string response_size_bytes;
27643 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27644 if (rc != TPM_RC_SUCCESS) {
27645 return rc;
27646 }
27647 TPM_RC response_code;
27648 std::string response_code_bytes;
27649 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27650 if (rc != TPM_RC_SUCCESS) {
27651 return rc;
27652 }
27653 if (response_size != response.size()) {
27654 return TPM_RC_SIZE;
27655 }
27656 if (response_code != TPM_RC_SUCCESS) {
27657 return response_code;
27658 }
27659 TPM_CC command_code = TPM_CC_PP_Commands;
27660 std::string command_code_bytes;
27661 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27662 if (rc != TPM_RC_SUCCESS) {
27663 return rc;
27664 }
27665 std::string authorization_section_bytes;
27666 if (tag == TPM_ST_SESSIONS) {
27667 UINT32 parameter_section_size = buffer.size();
27668 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
27669 if (rc != TPM_RC_SUCCESS) {
27670 return rc;
27671 }
27672 if (parameter_section_size > buffer.size()) {
27673 return TPM_RC_INSUFFICIENT;
27674 }
27675 authorization_section_bytes = buffer.substr(parameter_section_size);
27676 // Keep the parameter section in |buffer|.
27677 buffer.erase(parameter_section_size);
27678 }
27679 std::unique_ptr<crypto::SecureHash> hash(
27680 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27681 hash->Update(response_code_bytes.data(), response_code_bytes.size());
27682 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27683 hash->Update(buffer.data(), buffer.size());
27684 std::string response_hash(32, 0);
27685 hash->Finish(std::data(response_hash), response_hash.size());
27686 if (tag == TPM_ST_SESSIONS) {
27687 if (!authorization_delegate)
27688 return TRUNKS_RC_AUTHORIZATION_FAILED;
27689 if (!authorization_delegate->CheckResponseAuthorization(
27690 response_hash, authorization_section_bytes)) {
27691 return TRUNKS_RC_AUTHORIZATION_FAILED;
27692 }
27693 }
27694 return TPM_RC_SUCCESS;
27695 }
27696
PP_CommandsErrorCallback(Tpm::PP_CommandsResponse callback,TPM_RC response_code)27697 void PP_CommandsErrorCallback(Tpm::PP_CommandsResponse callback,
27698 TPM_RC response_code) {
27699 VLOG(1) << __func__;
27700 std::move(callback).Run(response_code);
27701 }
27702
PP_CommandsResponseParser(Tpm::PP_CommandsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27703 void PP_CommandsResponseParser(Tpm::PP_CommandsResponse callback,
27704 AuthorizationDelegate* authorization_delegate,
27705 const std::string& response) {
27706 VLOG(1) << __func__;
27707 TPM_RC rc = Tpm::ParseResponse_PP_Commands(response, authorization_delegate);
27708 if (rc != TPM_RC_SUCCESS) {
27709 base::OnceCallback<void(TPM_RC)> error_reporter =
27710 base::BindOnce(PP_CommandsErrorCallback, std::move(callback));
27711 std::move(error_reporter).Run(rc);
27712 return;
27713 }
27714 std::move(callback).Run(rc);
27715 }
27716
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)27717 void Tpm::PP_Commands(const TPMI_RH_PLATFORM& auth,
27718 const std::string& auth_name,
27719 const TPML_CC& set_list,
27720 const TPML_CC& clear_list,
27721 AuthorizationDelegate* authorization_delegate,
27722 PP_CommandsResponse callback) {
27723 VLOG(1) << __func__;
27724 std::string command;
27725 TPM_RC rc = SerializeCommand_PP_Commands(
27726 auth, auth_name, set_list, clear_list, &command, authorization_delegate);
27727 if (rc != TPM_RC_SUCCESS) {
27728 base::OnceCallback<void(TPM_RC)> error_reporter =
27729 base::BindOnce(PP_CommandsErrorCallback, std::move(callback));
27730 std::move(error_reporter).Run(rc);
27731 return;
27732 }
27733 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
27734 PP_CommandsResponseParser, std::move(callback), authorization_delegate);
27735 transceiver_->SendCommand(command, std::move(parser));
27736 }
27737
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)27738 TPM_RC Tpm::PP_CommandsSync(const TPMI_RH_PLATFORM& auth,
27739 const std::string& auth_name,
27740 const TPML_CC& set_list,
27741 const TPML_CC& clear_list,
27742 AuthorizationDelegate* authorization_delegate) {
27743 VLOG(1) << __func__;
27744 std::string command;
27745 TPM_RC rc = SerializeCommand_PP_Commands(
27746 auth, auth_name, set_list, clear_list, &command, authorization_delegate);
27747 if (rc != TPM_RC_SUCCESS) {
27748 return rc;
27749 }
27750 std::string response = transceiver_->SendCommandAndWait(command);
27751 rc = ParseResponse_PP_Commands(response, authorization_delegate);
27752 return rc;
27753 }
27754
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)27755 TPM_RC Tpm::SerializeCommand_SetAlgorithmSet(
27756 const TPMI_RH_PLATFORM& auth_handle,
27757 const std::string& auth_handle_name,
27758 const UINT32& algorithm_set,
27759 std::string* serialized_command,
27760 AuthorizationDelegate* authorization_delegate) {
27761 VLOG(3) << __func__;
27762 TPM_RC rc = TPM_RC_SUCCESS;
27763 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27764 UINT32 command_size = 10; // Header size.
27765 std::string handle_section_bytes;
27766 std::string parameter_section_bytes;
27767 TPM_CC command_code = TPM_CC_SetAlgorithmSet;
27768 bool is_command_parameter_encryption_possible = false;
27769 bool is_response_parameter_encryption_possible = false;
27770 std::string command_code_bytes;
27771 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27772 if (rc != TPM_RC_SUCCESS) {
27773 return rc;
27774 }
27775 std::string auth_handle_bytes;
27776 rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
27777 if (rc != TPM_RC_SUCCESS) {
27778 return rc;
27779 }
27780 std::string algorithm_set_bytes;
27781 rc = Serialize_UINT32(algorithm_set, &algorithm_set_bytes);
27782 if (rc != TPM_RC_SUCCESS) {
27783 return rc;
27784 }
27785 std::unique_ptr<crypto::SecureHash> hash(
27786 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27787 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27788 hash->Update(auth_handle_name.data(), auth_handle_name.size());
27789 handle_section_bytes += auth_handle_bytes;
27790 command_size += auth_handle_bytes.size();
27791 hash->Update(algorithm_set_bytes.data(), algorithm_set_bytes.size());
27792 parameter_section_bytes += algorithm_set_bytes;
27793 command_size += algorithm_set_bytes.size();
27794 std::string command_hash(32, 0);
27795 hash->Finish(std::data(command_hash), command_hash.size());
27796 std::string authorization_section_bytes;
27797 std::string authorization_size_bytes;
27798 if (authorization_delegate) {
27799 if (!authorization_delegate->GetCommandAuthorization(
27800 command_hash, is_command_parameter_encryption_possible,
27801 is_response_parameter_encryption_possible,
27802 &authorization_section_bytes)) {
27803 return TRUNKS_RC_AUTHORIZATION_FAILED;
27804 }
27805 if (!authorization_section_bytes.empty()) {
27806 tag = TPM_ST_SESSIONS;
27807 std::string tmp;
27808 rc = Serialize_UINT32(authorization_section_bytes.size(),
27809 &authorization_size_bytes);
27810 if (rc != TPM_RC_SUCCESS) {
27811 return rc;
27812 }
27813 command_size +=
27814 authorization_size_bytes.size() + authorization_section_bytes.size();
27815 }
27816 }
27817 std::string tag_bytes;
27818 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27819 if (rc != TPM_RC_SUCCESS) {
27820 return rc;
27821 }
27822 std::string command_size_bytes;
27823 rc = Serialize_UINT32(command_size, &command_size_bytes);
27824 if (rc != TPM_RC_SUCCESS) {
27825 return rc;
27826 }
27827 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27828 handle_section_bytes + authorization_size_bytes +
27829 authorization_section_bytes + parameter_section_bytes;
27830 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27831 VLOG(2) << "Command: "
27832 << base::HexEncode(serialized_command->data(),
27833 serialized_command->size());
27834 return TPM_RC_SUCCESS;
27835 }
27836
ParseResponse_SetAlgorithmSet(const std::string & response,AuthorizationDelegate * authorization_delegate)27837 TPM_RC Tpm::ParseResponse_SetAlgorithmSet(
27838 const std::string& response,
27839 AuthorizationDelegate* authorization_delegate) {
27840 VLOG(3) << __func__;
27841 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27842 TPM_RC rc = TPM_RC_SUCCESS;
27843 std::string buffer(response);
27844 TPM_ST tag;
27845 std::string tag_bytes;
27846 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27847 if (rc != TPM_RC_SUCCESS) {
27848 return rc;
27849 }
27850 UINT32 response_size;
27851 std::string response_size_bytes;
27852 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27853 if (rc != TPM_RC_SUCCESS) {
27854 return rc;
27855 }
27856 TPM_RC response_code;
27857 std::string response_code_bytes;
27858 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27859 if (rc != TPM_RC_SUCCESS) {
27860 return rc;
27861 }
27862 if (response_size != response.size()) {
27863 return TPM_RC_SIZE;
27864 }
27865 if (response_code != TPM_RC_SUCCESS) {
27866 return response_code;
27867 }
27868 TPM_CC command_code = TPM_CC_SetAlgorithmSet;
27869 std::string command_code_bytes;
27870 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27871 if (rc != TPM_RC_SUCCESS) {
27872 return rc;
27873 }
27874 std::string authorization_section_bytes;
27875 if (tag == TPM_ST_SESSIONS) {
27876 UINT32 parameter_section_size = buffer.size();
27877 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
27878 if (rc != TPM_RC_SUCCESS) {
27879 return rc;
27880 }
27881 if (parameter_section_size > buffer.size()) {
27882 return TPM_RC_INSUFFICIENT;
27883 }
27884 authorization_section_bytes = buffer.substr(parameter_section_size);
27885 // Keep the parameter section in |buffer|.
27886 buffer.erase(parameter_section_size);
27887 }
27888 std::unique_ptr<crypto::SecureHash> hash(
27889 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27890 hash->Update(response_code_bytes.data(), response_code_bytes.size());
27891 hash->Update(command_code_bytes.data(), command_code_bytes.size());
27892 hash->Update(buffer.data(), buffer.size());
27893 std::string response_hash(32, 0);
27894 hash->Finish(std::data(response_hash), response_hash.size());
27895 if (tag == TPM_ST_SESSIONS) {
27896 if (!authorization_delegate)
27897 return TRUNKS_RC_AUTHORIZATION_FAILED;
27898 if (!authorization_delegate->CheckResponseAuthorization(
27899 response_hash, authorization_section_bytes)) {
27900 return TRUNKS_RC_AUTHORIZATION_FAILED;
27901 }
27902 }
27903 return TPM_RC_SUCCESS;
27904 }
27905
SetAlgorithmSetErrorCallback(Tpm::SetAlgorithmSetResponse callback,TPM_RC response_code)27906 void SetAlgorithmSetErrorCallback(Tpm::SetAlgorithmSetResponse callback,
27907 TPM_RC response_code) {
27908 VLOG(1) << __func__;
27909 std::move(callback).Run(response_code);
27910 }
27911
SetAlgorithmSetResponseParser(Tpm::SetAlgorithmSetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27912 void SetAlgorithmSetResponseParser(
27913 Tpm::SetAlgorithmSetResponse callback,
27914 AuthorizationDelegate* authorization_delegate,
27915 const std::string& response) {
27916 VLOG(1) << __func__;
27917 TPM_RC rc =
27918 Tpm::ParseResponse_SetAlgorithmSet(response, authorization_delegate);
27919 if (rc != TPM_RC_SUCCESS) {
27920 base::OnceCallback<void(TPM_RC)> error_reporter =
27921 base::BindOnce(SetAlgorithmSetErrorCallback, std::move(callback));
27922 std::move(error_reporter).Run(rc);
27923 return;
27924 }
27925 std::move(callback).Run(rc);
27926 }
27927
SetAlgorithmSet(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,AuthorizationDelegate * authorization_delegate,SetAlgorithmSetResponse callback)27928 void Tpm::SetAlgorithmSet(const TPMI_RH_PLATFORM& auth_handle,
27929 const std::string& auth_handle_name,
27930 const UINT32& algorithm_set,
27931 AuthorizationDelegate* authorization_delegate,
27932 SetAlgorithmSetResponse callback) {
27933 VLOG(1) << __func__;
27934 std::string command;
27935 TPM_RC rc = SerializeCommand_SetAlgorithmSet(auth_handle, auth_handle_name,
27936 algorithm_set, &command,
27937 authorization_delegate);
27938 if (rc != TPM_RC_SUCCESS) {
27939 base::OnceCallback<void(TPM_RC)> error_reporter =
27940 base::BindOnce(SetAlgorithmSetErrorCallback, std::move(callback));
27941 std::move(error_reporter).Run(rc);
27942 return;
27943 }
27944 base::OnceCallback<void(const std::string&)> parser =
27945 base::BindOnce(SetAlgorithmSetResponseParser, std::move(callback),
27946 authorization_delegate);
27947 transceiver_->SendCommand(command, std::move(parser));
27948 }
27949
SetAlgorithmSetSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,AuthorizationDelegate * authorization_delegate)27950 TPM_RC Tpm::SetAlgorithmSetSync(const TPMI_RH_PLATFORM& auth_handle,
27951 const std::string& auth_handle_name,
27952 const UINT32& algorithm_set,
27953 AuthorizationDelegate* authorization_delegate) {
27954 VLOG(1) << __func__;
27955 std::string command;
27956 TPM_RC rc = SerializeCommand_SetAlgorithmSet(auth_handle, auth_handle_name,
27957 algorithm_set, &command,
27958 authorization_delegate);
27959 if (rc != TPM_RC_SUCCESS) {
27960 return rc;
27961 }
27962 std::string response = transceiver_->SendCommandAndWait(command);
27963 rc = ParseResponse_SetAlgorithmSet(response, authorization_delegate);
27964 return rc;
27965 }
27966
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)27967 TPM_RC Tpm::SerializeCommand_FieldUpgradeStart(
27968 const TPMI_RH_PLATFORM& authorization,
27969 const std::string& authorization_name,
27970 const TPMI_DH_OBJECT& key_handle,
27971 const std::string& key_handle_name,
27972 const TPM2B_DIGEST& fu_digest,
27973 const TPMT_SIGNATURE& manifest_signature,
27974 std::string* serialized_command,
27975 AuthorizationDelegate* authorization_delegate) {
27976 VLOG(3) << __func__;
27977 TPM_RC rc = TPM_RC_SUCCESS;
27978 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27979 UINT32 command_size = 10; // Header size.
27980 std::string handle_section_bytes;
27981 std::string parameter_section_bytes;
27982 TPM_CC command_code = TPM_CC_FieldUpgradeStart;
27983 bool is_command_parameter_encryption_possible = true;
27984 bool is_response_parameter_encryption_possible = false;
27985 std::string command_code_bytes;
27986 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27987 if (rc != TPM_RC_SUCCESS) {
27988 return rc;
27989 }
27990 std::string authorization_bytes;
27991 rc = Serialize_TPMI_RH_PLATFORM(authorization, &authorization_bytes);
27992 if (rc != TPM_RC_SUCCESS) {
27993 return rc;
27994 }
27995 std::string key_handle_bytes;
27996 rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
27997 if (rc != TPM_RC_SUCCESS) {
27998 return rc;
27999 }
28000 std::string fu_digest_bytes;
28001 rc = Serialize_TPM2B_DIGEST(fu_digest, &fu_digest_bytes);
28002 if (rc != TPM_RC_SUCCESS) {
28003 return rc;
28004 }
28005 std::string manifest_signature_bytes;
28006 rc = Serialize_TPMT_SIGNATURE(manifest_signature, &manifest_signature_bytes);
28007 if (rc != TPM_RC_SUCCESS) {
28008 return rc;
28009 }
28010 if (authorization_delegate) {
28011 // Encrypt just the parameter data, not the size.
28012 std::string tmp = fu_digest_bytes.substr(2);
28013 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
28014 return TRUNKS_RC_ENCRYPTION_FAILED;
28015 }
28016 fu_digest_bytes.replace(2, std::string::npos, tmp);
28017 }
28018 std::unique_ptr<crypto::SecureHash> hash(
28019 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28020 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28021 hash->Update(authorization_name.data(), authorization_name.size());
28022 handle_section_bytes += authorization_bytes;
28023 command_size += authorization_bytes.size();
28024 hash->Update(key_handle_name.data(), key_handle_name.size());
28025 handle_section_bytes += key_handle_bytes;
28026 command_size += key_handle_bytes.size();
28027 hash->Update(fu_digest_bytes.data(), fu_digest_bytes.size());
28028 parameter_section_bytes += fu_digest_bytes;
28029 command_size += fu_digest_bytes.size();
28030 hash->Update(manifest_signature_bytes.data(),
28031 manifest_signature_bytes.size());
28032 parameter_section_bytes += manifest_signature_bytes;
28033 command_size += manifest_signature_bytes.size();
28034 std::string command_hash(32, 0);
28035 hash->Finish(std::data(command_hash), command_hash.size());
28036 std::string authorization_section_bytes;
28037 std::string authorization_size_bytes;
28038 if (authorization_delegate) {
28039 if (!authorization_delegate->GetCommandAuthorization(
28040 command_hash, is_command_parameter_encryption_possible,
28041 is_response_parameter_encryption_possible,
28042 &authorization_section_bytes)) {
28043 return TRUNKS_RC_AUTHORIZATION_FAILED;
28044 }
28045 if (!authorization_section_bytes.empty()) {
28046 tag = TPM_ST_SESSIONS;
28047 std::string tmp;
28048 rc = Serialize_UINT32(authorization_section_bytes.size(),
28049 &authorization_size_bytes);
28050 if (rc != TPM_RC_SUCCESS) {
28051 return rc;
28052 }
28053 command_size +=
28054 authorization_size_bytes.size() + authorization_section_bytes.size();
28055 }
28056 }
28057 std::string tag_bytes;
28058 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28059 if (rc != TPM_RC_SUCCESS) {
28060 return rc;
28061 }
28062 std::string command_size_bytes;
28063 rc = Serialize_UINT32(command_size, &command_size_bytes);
28064 if (rc != TPM_RC_SUCCESS) {
28065 return rc;
28066 }
28067 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28068 handle_section_bytes + authorization_size_bytes +
28069 authorization_section_bytes + parameter_section_bytes;
28070 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28071 VLOG(2) << "Command: "
28072 << base::HexEncode(serialized_command->data(),
28073 serialized_command->size());
28074 return TPM_RC_SUCCESS;
28075 }
28076
ParseResponse_FieldUpgradeStart(const std::string & response,AuthorizationDelegate * authorization_delegate)28077 TPM_RC Tpm::ParseResponse_FieldUpgradeStart(
28078 const std::string& response,
28079 AuthorizationDelegate* authorization_delegate) {
28080 VLOG(3) << __func__;
28081 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28082 TPM_RC rc = TPM_RC_SUCCESS;
28083 std::string buffer(response);
28084 TPM_ST tag;
28085 std::string tag_bytes;
28086 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28087 if (rc != TPM_RC_SUCCESS) {
28088 return rc;
28089 }
28090 UINT32 response_size;
28091 std::string response_size_bytes;
28092 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28093 if (rc != TPM_RC_SUCCESS) {
28094 return rc;
28095 }
28096 TPM_RC response_code;
28097 std::string response_code_bytes;
28098 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28099 if (rc != TPM_RC_SUCCESS) {
28100 return rc;
28101 }
28102 if (response_size != response.size()) {
28103 return TPM_RC_SIZE;
28104 }
28105 if (response_code != TPM_RC_SUCCESS) {
28106 return response_code;
28107 }
28108 TPM_CC command_code = TPM_CC_FieldUpgradeStart;
28109 std::string command_code_bytes;
28110 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28111 if (rc != TPM_RC_SUCCESS) {
28112 return rc;
28113 }
28114 std::string authorization_section_bytes;
28115 if (tag == TPM_ST_SESSIONS) {
28116 UINT32 parameter_section_size = buffer.size();
28117 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
28118 if (rc != TPM_RC_SUCCESS) {
28119 return rc;
28120 }
28121 if (parameter_section_size > buffer.size()) {
28122 return TPM_RC_INSUFFICIENT;
28123 }
28124 authorization_section_bytes = buffer.substr(parameter_section_size);
28125 // Keep the parameter section in |buffer|.
28126 buffer.erase(parameter_section_size);
28127 }
28128 std::unique_ptr<crypto::SecureHash> hash(
28129 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28130 hash->Update(response_code_bytes.data(), response_code_bytes.size());
28131 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28132 hash->Update(buffer.data(), buffer.size());
28133 std::string response_hash(32, 0);
28134 hash->Finish(std::data(response_hash), response_hash.size());
28135 if (tag == TPM_ST_SESSIONS) {
28136 if (!authorization_delegate)
28137 return TRUNKS_RC_AUTHORIZATION_FAILED;
28138 if (!authorization_delegate->CheckResponseAuthorization(
28139 response_hash, authorization_section_bytes)) {
28140 return TRUNKS_RC_AUTHORIZATION_FAILED;
28141 }
28142 }
28143 return TPM_RC_SUCCESS;
28144 }
28145
FieldUpgradeStartErrorCallback(Tpm::FieldUpgradeStartResponse callback,TPM_RC response_code)28146 void FieldUpgradeStartErrorCallback(Tpm::FieldUpgradeStartResponse callback,
28147 TPM_RC response_code) {
28148 VLOG(1) << __func__;
28149 std::move(callback).Run(response_code);
28150 }
28151
FieldUpgradeStartResponseParser(Tpm::FieldUpgradeStartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28152 void FieldUpgradeStartResponseParser(
28153 Tpm::FieldUpgradeStartResponse callback,
28154 AuthorizationDelegate* authorization_delegate,
28155 const std::string& response) {
28156 VLOG(1) << __func__;
28157 TPM_RC rc =
28158 Tpm::ParseResponse_FieldUpgradeStart(response, authorization_delegate);
28159 if (rc != TPM_RC_SUCCESS) {
28160 base::OnceCallback<void(TPM_RC)> error_reporter =
28161 base::BindOnce(FieldUpgradeStartErrorCallback, std::move(callback));
28162 std::move(error_reporter).Run(rc);
28163 return;
28164 }
28165 std::move(callback).Run(rc);
28166 }
28167
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)28168 void Tpm::FieldUpgradeStart(const TPMI_RH_PLATFORM& authorization,
28169 const std::string& authorization_name,
28170 const TPMI_DH_OBJECT& key_handle,
28171 const std::string& key_handle_name,
28172 const TPM2B_DIGEST& fu_digest,
28173 const TPMT_SIGNATURE& manifest_signature,
28174 AuthorizationDelegate* authorization_delegate,
28175 FieldUpgradeStartResponse callback) {
28176 VLOG(1) << __func__;
28177 std::string command;
28178 TPM_RC rc = SerializeCommand_FieldUpgradeStart(
28179 authorization, authorization_name, key_handle, key_handle_name, fu_digest,
28180 manifest_signature, &command, authorization_delegate);
28181 if (rc != TPM_RC_SUCCESS) {
28182 base::OnceCallback<void(TPM_RC)> error_reporter =
28183 base::BindOnce(FieldUpgradeStartErrorCallback, std::move(callback));
28184 std::move(error_reporter).Run(rc);
28185 return;
28186 }
28187 base::OnceCallback<void(const std::string&)> parser =
28188 base::BindOnce(FieldUpgradeStartResponseParser, std::move(callback),
28189 authorization_delegate);
28190 transceiver_->SendCommand(command, std::move(parser));
28191 }
28192
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)28193 TPM_RC Tpm::FieldUpgradeStartSync(
28194 const TPMI_RH_PLATFORM& authorization,
28195 const std::string& authorization_name,
28196 const TPMI_DH_OBJECT& key_handle,
28197 const std::string& key_handle_name,
28198 const TPM2B_DIGEST& fu_digest,
28199 const TPMT_SIGNATURE& manifest_signature,
28200 AuthorizationDelegate* authorization_delegate) {
28201 VLOG(1) << __func__;
28202 std::string command;
28203 TPM_RC rc = SerializeCommand_FieldUpgradeStart(
28204 authorization, authorization_name, key_handle, key_handle_name, fu_digest,
28205 manifest_signature, &command, authorization_delegate);
28206 if (rc != TPM_RC_SUCCESS) {
28207 return rc;
28208 }
28209 std::string response = transceiver_->SendCommandAndWait(command);
28210 rc = ParseResponse_FieldUpgradeStart(response, authorization_delegate);
28211 return rc;
28212 }
28213
SerializeCommand_FieldUpgradeData(const TPM2B_MAX_BUFFER & fu_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28214 TPM_RC Tpm::SerializeCommand_FieldUpgradeData(
28215 const TPM2B_MAX_BUFFER& fu_data,
28216 std::string* serialized_command,
28217 AuthorizationDelegate* authorization_delegate) {
28218 VLOG(3) << __func__;
28219 TPM_RC rc = TPM_RC_SUCCESS;
28220 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28221 UINT32 command_size = 10; // Header size.
28222 std::string handle_section_bytes;
28223 std::string parameter_section_bytes;
28224 TPM_CC command_code = TPM_CC_FieldUpgradeData;
28225 bool is_command_parameter_encryption_possible = true;
28226 bool is_response_parameter_encryption_possible = false;
28227 std::string command_code_bytes;
28228 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28229 if (rc != TPM_RC_SUCCESS) {
28230 return rc;
28231 }
28232 std::string fu_data_bytes;
28233 rc = Serialize_TPM2B_MAX_BUFFER(fu_data, &fu_data_bytes);
28234 if (rc != TPM_RC_SUCCESS) {
28235 return rc;
28236 }
28237 if (authorization_delegate) {
28238 // Encrypt just the parameter data, not the size.
28239 std::string tmp = fu_data_bytes.substr(2);
28240 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
28241 return TRUNKS_RC_ENCRYPTION_FAILED;
28242 }
28243 fu_data_bytes.replace(2, std::string::npos, tmp);
28244 }
28245 std::unique_ptr<crypto::SecureHash> hash(
28246 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28247 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28248 hash->Update(fu_data_bytes.data(), fu_data_bytes.size());
28249 parameter_section_bytes += fu_data_bytes;
28250 command_size += fu_data_bytes.size();
28251 std::string command_hash(32, 0);
28252 hash->Finish(std::data(command_hash), command_hash.size());
28253 std::string authorization_section_bytes;
28254 std::string authorization_size_bytes;
28255 if (authorization_delegate) {
28256 if (!authorization_delegate->GetCommandAuthorization(
28257 command_hash, is_command_parameter_encryption_possible,
28258 is_response_parameter_encryption_possible,
28259 &authorization_section_bytes)) {
28260 return TRUNKS_RC_AUTHORIZATION_FAILED;
28261 }
28262 if (!authorization_section_bytes.empty()) {
28263 tag = TPM_ST_SESSIONS;
28264 std::string tmp;
28265 rc = Serialize_UINT32(authorization_section_bytes.size(),
28266 &authorization_size_bytes);
28267 if (rc != TPM_RC_SUCCESS) {
28268 return rc;
28269 }
28270 command_size +=
28271 authorization_size_bytes.size() + authorization_section_bytes.size();
28272 }
28273 }
28274 std::string tag_bytes;
28275 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28276 if (rc != TPM_RC_SUCCESS) {
28277 return rc;
28278 }
28279 std::string command_size_bytes;
28280 rc = Serialize_UINT32(command_size, &command_size_bytes);
28281 if (rc != TPM_RC_SUCCESS) {
28282 return rc;
28283 }
28284 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28285 handle_section_bytes + authorization_size_bytes +
28286 authorization_section_bytes + parameter_section_bytes;
28287 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28288 VLOG(2) << "Command: "
28289 << base::HexEncode(serialized_command->data(),
28290 serialized_command->size());
28291 return TPM_RC_SUCCESS;
28292 }
28293
ParseResponse_FieldUpgradeData(const std::string & response,TPMT_HA * next_digest,TPMT_HA * first_digest,AuthorizationDelegate * authorization_delegate)28294 TPM_RC Tpm::ParseResponse_FieldUpgradeData(
28295 const std::string& response,
28296 TPMT_HA* next_digest,
28297 TPMT_HA* first_digest,
28298 AuthorizationDelegate* authorization_delegate) {
28299 VLOG(3) << __func__;
28300 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28301 TPM_RC rc = TPM_RC_SUCCESS;
28302 std::string buffer(response);
28303 TPM_ST tag;
28304 std::string tag_bytes;
28305 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28306 if (rc != TPM_RC_SUCCESS) {
28307 return rc;
28308 }
28309 UINT32 response_size;
28310 std::string response_size_bytes;
28311 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28312 if (rc != TPM_RC_SUCCESS) {
28313 return rc;
28314 }
28315 TPM_RC response_code;
28316 std::string response_code_bytes;
28317 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28318 if (rc != TPM_RC_SUCCESS) {
28319 return rc;
28320 }
28321 if (response_size != response.size()) {
28322 return TPM_RC_SIZE;
28323 }
28324 if (response_code != TPM_RC_SUCCESS) {
28325 return response_code;
28326 }
28327 TPM_CC command_code = TPM_CC_FieldUpgradeData;
28328 std::string command_code_bytes;
28329 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28330 if (rc != TPM_RC_SUCCESS) {
28331 return rc;
28332 }
28333 std::string authorization_section_bytes;
28334 if (tag == TPM_ST_SESSIONS) {
28335 UINT32 parameter_section_size = buffer.size();
28336 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
28337 if (rc != TPM_RC_SUCCESS) {
28338 return rc;
28339 }
28340 if (parameter_section_size > buffer.size()) {
28341 return TPM_RC_INSUFFICIENT;
28342 }
28343 authorization_section_bytes = buffer.substr(parameter_section_size);
28344 // Keep the parameter section in |buffer|.
28345 buffer.erase(parameter_section_size);
28346 }
28347 std::unique_ptr<crypto::SecureHash> hash(
28348 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28349 hash->Update(response_code_bytes.data(), response_code_bytes.size());
28350 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28351 hash->Update(buffer.data(), buffer.size());
28352 std::string response_hash(32, 0);
28353 hash->Finish(std::data(response_hash), response_hash.size());
28354 if (tag == TPM_ST_SESSIONS) {
28355 if (!authorization_delegate)
28356 return TRUNKS_RC_AUTHORIZATION_FAILED;
28357 if (!authorization_delegate->CheckResponseAuthorization(
28358 response_hash, authorization_section_bytes)) {
28359 return TRUNKS_RC_AUTHORIZATION_FAILED;
28360 }
28361 }
28362 std::string next_digest_bytes;
28363 rc = Parse_TPMT_HA(&buffer, next_digest, &next_digest_bytes);
28364 if (rc != TPM_RC_SUCCESS) {
28365 return rc;
28366 }
28367 std::string first_digest_bytes;
28368 rc = Parse_TPMT_HA(&buffer, first_digest, &first_digest_bytes);
28369 if (rc != TPM_RC_SUCCESS) {
28370 return rc;
28371 }
28372 return TPM_RC_SUCCESS;
28373 }
28374
FieldUpgradeDataErrorCallback(Tpm::FieldUpgradeDataResponse callback,TPM_RC response_code)28375 void FieldUpgradeDataErrorCallback(Tpm::FieldUpgradeDataResponse callback,
28376 TPM_RC response_code) {
28377 VLOG(1) << __func__;
28378 std::move(callback).Run(response_code, TPMT_HA(), TPMT_HA());
28379 }
28380
FieldUpgradeDataResponseParser(Tpm::FieldUpgradeDataResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28381 void FieldUpgradeDataResponseParser(
28382 Tpm::FieldUpgradeDataResponse callback,
28383 AuthorizationDelegate* authorization_delegate,
28384 const std::string& response) {
28385 VLOG(1) << __func__;
28386 TPMT_HA next_digest;
28387 TPMT_HA first_digest;
28388 TPM_RC rc = Tpm::ParseResponse_FieldUpgradeData(
28389 response, &next_digest, &first_digest, authorization_delegate);
28390 if (rc != TPM_RC_SUCCESS) {
28391 base::OnceCallback<void(TPM_RC)> error_reporter =
28392 base::BindOnce(FieldUpgradeDataErrorCallback, std::move(callback));
28393 std::move(error_reporter).Run(rc);
28394 return;
28395 }
28396 std::move(callback).Run(rc, next_digest, first_digest);
28397 }
28398
FieldUpgradeData(const TPM2B_MAX_BUFFER & fu_data,AuthorizationDelegate * authorization_delegate,FieldUpgradeDataResponse callback)28399 void Tpm::FieldUpgradeData(const TPM2B_MAX_BUFFER& fu_data,
28400 AuthorizationDelegate* authorization_delegate,
28401 FieldUpgradeDataResponse callback) {
28402 VLOG(1) << __func__;
28403 std::string command;
28404 TPM_RC rc = SerializeCommand_FieldUpgradeData(fu_data, &command,
28405 authorization_delegate);
28406 if (rc != TPM_RC_SUCCESS) {
28407 base::OnceCallback<void(TPM_RC)> error_reporter =
28408 base::BindOnce(FieldUpgradeDataErrorCallback, std::move(callback));
28409 std::move(error_reporter).Run(rc);
28410 return;
28411 }
28412 base::OnceCallback<void(const std::string&)> parser =
28413 base::BindOnce(FieldUpgradeDataResponseParser, std::move(callback),
28414 authorization_delegate);
28415 transceiver_->SendCommand(command, std::move(parser));
28416 }
28417
FieldUpgradeDataSync(const TPM2B_MAX_BUFFER & fu_data,TPMT_HA * next_digest,TPMT_HA * first_digest,AuthorizationDelegate * authorization_delegate)28418 TPM_RC Tpm::FieldUpgradeDataSync(
28419 const TPM2B_MAX_BUFFER& fu_data,
28420 TPMT_HA* next_digest,
28421 TPMT_HA* first_digest,
28422 AuthorizationDelegate* authorization_delegate) {
28423 VLOG(1) << __func__;
28424 std::string command;
28425 TPM_RC rc = SerializeCommand_FieldUpgradeData(fu_data, &command,
28426 authorization_delegate);
28427 if (rc != TPM_RC_SUCCESS) {
28428 return rc;
28429 }
28430 std::string response = transceiver_->SendCommandAndWait(command);
28431 rc = ParseResponse_FieldUpgradeData(response, next_digest, first_digest,
28432 authorization_delegate);
28433 return rc;
28434 }
28435
SerializeCommand_FirmwareRead(const UINT32 & sequence_number,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28436 TPM_RC Tpm::SerializeCommand_FirmwareRead(
28437 const UINT32& sequence_number,
28438 std::string* serialized_command,
28439 AuthorizationDelegate* authorization_delegate) {
28440 VLOG(3) << __func__;
28441 TPM_RC rc = TPM_RC_SUCCESS;
28442 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28443 UINT32 command_size = 10; // Header size.
28444 std::string handle_section_bytes;
28445 std::string parameter_section_bytes;
28446 TPM_CC command_code = TPM_CC_FirmwareRead;
28447 bool is_command_parameter_encryption_possible = false;
28448 bool is_response_parameter_encryption_possible = true;
28449 std::string command_code_bytes;
28450 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28451 if (rc != TPM_RC_SUCCESS) {
28452 return rc;
28453 }
28454 std::string sequence_number_bytes;
28455 rc = Serialize_UINT32(sequence_number, &sequence_number_bytes);
28456 if (rc != TPM_RC_SUCCESS) {
28457 return rc;
28458 }
28459 std::unique_ptr<crypto::SecureHash> hash(
28460 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28461 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28462 hash->Update(sequence_number_bytes.data(), sequence_number_bytes.size());
28463 parameter_section_bytes += sequence_number_bytes;
28464 command_size += sequence_number_bytes.size();
28465 std::string command_hash(32, 0);
28466 hash->Finish(std::data(command_hash), command_hash.size());
28467 std::string authorization_section_bytes;
28468 std::string authorization_size_bytes;
28469 if (authorization_delegate) {
28470 if (!authorization_delegate->GetCommandAuthorization(
28471 command_hash, is_command_parameter_encryption_possible,
28472 is_response_parameter_encryption_possible,
28473 &authorization_section_bytes)) {
28474 return TRUNKS_RC_AUTHORIZATION_FAILED;
28475 }
28476 if (!authorization_section_bytes.empty()) {
28477 tag = TPM_ST_SESSIONS;
28478 std::string tmp;
28479 rc = Serialize_UINT32(authorization_section_bytes.size(),
28480 &authorization_size_bytes);
28481 if (rc != TPM_RC_SUCCESS) {
28482 return rc;
28483 }
28484 command_size +=
28485 authorization_size_bytes.size() + authorization_section_bytes.size();
28486 }
28487 }
28488 std::string tag_bytes;
28489 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28490 if (rc != TPM_RC_SUCCESS) {
28491 return rc;
28492 }
28493 std::string command_size_bytes;
28494 rc = Serialize_UINT32(command_size, &command_size_bytes);
28495 if (rc != TPM_RC_SUCCESS) {
28496 return rc;
28497 }
28498 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28499 handle_section_bytes + authorization_size_bytes +
28500 authorization_section_bytes + parameter_section_bytes;
28501 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28502 VLOG(2) << "Command: "
28503 << base::HexEncode(serialized_command->data(),
28504 serialized_command->size());
28505 return TPM_RC_SUCCESS;
28506 }
28507
ParseResponse_FirmwareRead(const std::string & response,TPM2B_MAX_BUFFER * fu_data,AuthorizationDelegate * authorization_delegate)28508 TPM_RC Tpm::ParseResponse_FirmwareRead(
28509 const std::string& response,
28510 TPM2B_MAX_BUFFER* fu_data,
28511 AuthorizationDelegate* authorization_delegate) {
28512 VLOG(3) << __func__;
28513 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28514 TPM_RC rc = TPM_RC_SUCCESS;
28515 std::string buffer(response);
28516 TPM_ST tag;
28517 std::string tag_bytes;
28518 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28519 if (rc != TPM_RC_SUCCESS) {
28520 return rc;
28521 }
28522 UINT32 response_size;
28523 std::string response_size_bytes;
28524 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28525 if (rc != TPM_RC_SUCCESS) {
28526 return rc;
28527 }
28528 TPM_RC response_code;
28529 std::string response_code_bytes;
28530 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28531 if (rc != TPM_RC_SUCCESS) {
28532 return rc;
28533 }
28534 if (response_size != response.size()) {
28535 return TPM_RC_SIZE;
28536 }
28537 if (response_code != TPM_RC_SUCCESS) {
28538 return response_code;
28539 }
28540 TPM_CC command_code = TPM_CC_FirmwareRead;
28541 std::string command_code_bytes;
28542 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28543 if (rc != TPM_RC_SUCCESS) {
28544 return rc;
28545 }
28546 std::string authorization_section_bytes;
28547 if (tag == TPM_ST_SESSIONS) {
28548 UINT32 parameter_section_size = buffer.size();
28549 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
28550 if (rc != TPM_RC_SUCCESS) {
28551 return rc;
28552 }
28553 if (parameter_section_size > buffer.size()) {
28554 return TPM_RC_INSUFFICIENT;
28555 }
28556 authorization_section_bytes = buffer.substr(parameter_section_size);
28557 // Keep the parameter section in |buffer|.
28558 buffer.erase(parameter_section_size);
28559 }
28560 std::unique_ptr<crypto::SecureHash> hash(
28561 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28562 hash->Update(response_code_bytes.data(), response_code_bytes.size());
28563 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28564 hash->Update(buffer.data(), buffer.size());
28565 std::string response_hash(32, 0);
28566 hash->Finish(std::data(response_hash), response_hash.size());
28567 if (tag == TPM_ST_SESSIONS) {
28568 if (!authorization_delegate)
28569 return TRUNKS_RC_AUTHORIZATION_FAILED;
28570 if (!authorization_delegate->CheckResponseAuthorization(
28571 response_hash, authorization_section_bytes)) {
28572 return TRUNKS_RC_AUTHORIZATION_FAILED;
28573 }
28574 }
28575 if (tag == TPM_ST_SESSIONS) {
28576 if (!authorization_delegate)
28577 return TRUNKS_RC_AUTHORIZATION_FAILED;
28578
28579 // Parse the encrypted parameter size.
28580 UINT16 size;
28581 std::string size_buffer = buffer.substr(0, 2);
28582 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
28583 return result;
28584 }
28585 if (buffer.size() < 2 + size) {
28586 return TPM_RC_INSUFFICIENT;
28587 }
28588
28589 // Decrypt just the parameter data, not the size.
28590 std::string decrypted_data = buffer.substr(2, size);
28591 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
28592 return TRUNKS_RC_ENCRYPTION_FAILED;
28593 }
28594 buffer.replace(2, size, decrypted_data);
28595 }
28596 std::string fu_data_bytes;
28597 rc = Parse_TPM2B_MAX_BUFFER(&buffer, fu_data, &fu_data_bytes);
28598 if (rc != TPM_RC_SUCCESS) {
28599 return rc;
28600 }
28601 return TPM_RC_SUCCESS;
28602 }
28603
FirmwareReadErrorCallback(Tpm::FirmwareReadResponse callback,TPM_RC response_code)28604 void FirmwareReadErrorCallback(Tpm::FirmwareReadResponse callback,
28605 TPM_RC response_code) {
28606 VLOG(1) << __func__;
28607 std::move(callback).Run(response_code, TPM2B_MAX_BUFFER());
28608 }
28609
FirmwareReadResponseParser(Tpm::FirmwareReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28610 void FirmwareReadResponseParser(Tpm::FirmwareReadResponse callback,
28611 AuthorizationDelegate* authorization_delegate,
28612 const std::string& response) {
28613 VLOG(1) << __func__;
28614 TPM2B_MAX_BUFFER fu_data;
28615 TPM_RC rc = Tpm::ParseResponse_FirmwareRead(response, &fu_data,
28616 authorization_delegate);
28617 if (rc != TPM_RC_SUCCESS) {
28618 base::OnceCallback<void(TPM_RC)> error_reporter =
28619 base::BindOnce(FirmwareReadErrorCallback, std::move(callback));
28620 std::move(error_reporter).Run(rc);
28621 return;
28622 }
28623 std::move(callback).Run(rc, fu_data);
28624 }
28625
FirmwareRead(const UINT32 & sequence_number,AuthorizationDelegate * authorization_delegate,FirmwareReadResponse callback)28626 void Tpm::FirmwareRead(const UINT32& sequence_number,
28627 AuthorizationDelegate* authorization_delegate,
28628 FirmwareReadResponse callback) {
28629 VLOG(1) << __func__;
28630 std::string command;
28631 TPM_RC rc = SerializeCommand_FirmwareRead(sequence_number, &command,
28632 authorization_delegate);
28633 if (rc != TPM_RC_SUCCESS) {
28634 base::OnceCallback<void(TPM_RC)> error_reporter =
28635 base::BindOnce(FirmwareReadErrorCallback, std::move(callback));
28636 std::move(error_reporter).Run(rc);
28637 return;
28638 }
28639 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
28640 FirmwareReadResponseParser, std::move(callback), authorization_delegate);
28641 transceiver_->SendCommand(command, std::move(parser));
28642 }
28643
FirmwareReadSync(const UINT32 & sequence_number,TPM2B_MAX_BUFFER * fu_data,AuthorizationDelegate * authorization_delegate)28644 TPM_RC Tpm::FirmwareReadSync(const UINT32& sequence_number,
28645 TPM2B_MAX_BUFFER* fu_data,
28646 AuthorizationDelegate* authorization_delegate) {
28647 VLOG(1) << __func__;
28648 std::string command;
28649 TPM_RC rc = SerializeCommand_FirmwareRead(sequence_number, &command,
28650 authorization_delegate);
28651 if (rc != TPM_RC_SUCCESS) {
28652 return rc;
28653 }
28654 std::string response = transceiver_->SendCommandAndWait(command);
28655 rc = ParseResponse_FirmwareRead(response, fu_data, authorization_delegate);
28656 return rc;
28657 }
28658
SerializeCommand_ContextSave(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28659 TPM_RC Tpm::SerializeCommand_ContextSave(
28660 const TPMI_DH_CONTEXT& save_handle,
28661 const std::string& save_handle_name,
28662 std::string* serialized_command,
28663 AuthorizationDelegate* authorization_delegate) {
28664 VLOG(3) << __func__;
28665 TPM_RC rc = TPM_RC_SUCCESS;
28666 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28667 UINT32 command_size = 10; // Header size.
28668 std::string handle_section_bytes;
28669 std::string parameter_section_bytes;
28670 TPM_CC command_code = TPM_CC_ContextSave;
28671 bool is_command_parameter_encryption_possible = false;
28672 bool is_response_parameter_encryption_possible = false;
28673 std::string command_code_bytes;
28674 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28675 if (rc != TPM_RC_SUCCESS) {
28676 return rc;
28677 }
28678 std::string save_handle_bytes;
28679 rc = Serialize_TPMI_DH_CONTEXT(save_handle, &save_handle_bytes);
28680 if (rc != TPM_RC_SUCCESS) {
28681 return rc;
28682 }
28683 std::unique_ptr<crypto::SecureHash> hash(
28684 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28685 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28686 hash->Update(save_handle_name.data(), save_handle_name.size());
28687 handle_section_bytes += save_handle_bytes;
28688 command_size += save_handle_bytes.size();
28689 std::string command_hash(32, 0);
28690 hash->Finish(std::data(command_hash), command_hash.size());
28691 std::string authorization_section_bytes;
28692 std::string authorization_size_bytes;
28693 if (authorization_delegate) {
28694 if (!authorization_delegate->GetCommandAuthorization(
28695 command_hash, is_command_parameter_encryption_possible,
28696 is_response_parameter_encryption_possible,
28697 &authorization_section_bytes)) {
28698 return TRUNKS_RC_AUTHORIZATION_FAILED;
28699 }
28700 if (!authorization_section_bytes.empty()) {
28701 tag = TPM_ST_SESSIONS;
28702 std::string tmp;
28703 rc = Serialize_UINT32(authorization_section_bytes.size(),
28704 &authorization_size_bytes);
28705 if (rc != TPM_RC_SUCCESS) {
28706 return rc;
28707 }
28708 command_size +=
28709 authorization_size_bytes.size() + authorization_section_bytes.size();
28710 }
28711 }
28712 std::string tag_bytes;
28713 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28714 if (rc != TPM_RC_SUCCESS) {
28715 return rc;
28716 }
28717 std::string command_size_bytes;
28718 rc = Serialize_UINT32(command_size, &command_size_bytes);
28719 if (rc != TPM_RC_SUCCESS) {
28720 return rc;
28721 }
28722 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28723 handle_section_bytes + authorization_size_bytes +
28724 authorization_section_bytes + parameter_section_bytes;
28725 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28726 VLOG(2) << "Command: "
28727 << base::HexEncode(serialized_command->data(),
28728 serialized_command->size());
28729 return TPM_RC_SUCCESS;
28730 }
28731
ParseResponse_ContextSave(const std::string & response,TPMS_CONTEXT * context,AuthorizationDelegate * authorization_delegate)28732 TPM_RC Tpm::ParseResponse_ContextSave(
28733 const std::string& response,
28734 TPMS_CONTEXT* context,
28735 AuthorizationDelegate* authorization_delegate) {
28736 VLOG(3) << __func__;
28737 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28738 TPM_RC rc = TPM_RC_SUCCESS;
28739 std::string buffer(response);
28740 TPM_ST tag;
28741 std::string tag_bytes;
28742 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28743 if (rc != TPM_RC_SUCCESS) {
28744 return rc;
28745 }
28746 UINT32 response_size;
28747 std::string response_size_bytes;
28748 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28749 if (rc != TPM_RC_SUCCESS) {
28750 return rc;
28751 }
28752 TPM_RC response_code;
28753 std::string response_code_bytes;
28754 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28755 if (rc != TPM_RC_SUCCESS) {
28756 return rc;
28757 }
28758 if (response_size != response.size()) {
28759 return TPM_RC_SIZE;
28760 }
28761 if (response_code != TPM_RC_SUCCESS) {
28762 return response_code;
28763 }
28764 TPM_CC command_code = TPM_CC_ContextSave;
28765 std::string command_code_bytes;
28766 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28767 if (rc != TPM_RC_SUCCESS) {
28768 return rc;
28769 }
28770 std::string authorization_section_bytes;
28771 if (tag == TPM_ST_SESSIONS) {
28772 UINT32 parameter_section_size = buffer.size();
28773 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
28774 if (rc != TPM_RC_SUCCESS) {
28775 return rc;
28776 }
28777 if (parameter_section_size > buffer.size()) {
28778 return TPM_RC_INSUFFICIENT;
28779 }
28780 authorization_section_bytes = buffer.substr(parameter_section_size);
28781 // Keep the parameter section in |buffer|.
28782 buffer.erase(parameter_section_size);
28783 }
28784 std::unique_ptr<crypto::SecureHash> hash(
28785 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28786 hash->Update(response_code_bytes.data(), response_code_bytes.size());
28787 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28788 hash->Update(buffer.data(), buffer.size());
28789 std::string response_hash(32, 0);
28790 hash->Finish(std::data(response_hash), response_hash.size());
28791 if (tag == TPM_ST_SESSIONS) {
28792 if (!authorization_delegate)
28793 return TRUNKS_RC_AUTHORIZATION_FAILED;
28794 if (!authorization_delegate->CheckResponseAuthorization(
28795 response_hash, authorization_section_bytes)) {
28796 return TRUNKS_RC_AUTHORIZATION_FAILED;
28797 }
28798 }
28799 std::string context_bytes;
28800 rc = Parse_TPMS_CONTEXT(&buffer, context, &context_bytes);
28801 if (rc != TPM_RC_SUCCESS) {
28802 return rc;
28803 }
28804 return TPM_RC_SUCCESS;
28805 }
28806
ContextSaveErrorCallback(Tpm::ContextSaveResponse callback,TPM_RC response_code)28807 void ContextSaveErrorCallback(Tpm::ContextSaveResponse callback,
28808 TPM_RC response_code) {
28809 VLOG(1) << __func__;
28810 std::move(callback).Run(response_code, TPMS_CONTEXT());
28811 }
28812
ContextSaveResponseParser(Tpm::ContextSaveResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28813 void ContextSaveResponseParser(Tpm::ContextSaveResponse callback,
28814 AuthorizationDelegate* authorization_delegate,
28815 const std::string& response) {
28816 VLOG(1) << __func__;
28817 TPMS_CONTEXT context;
28818 TPM_RC rc = Tpm::ParseResponse_ContextSave(response, &context,
28819 authorization_delegate);
28820 if (rc != TPM_RC_SUCCESS) {
28821 base::OnceCallback<void(TPM_RC)> error_reporter =
28822 base::BindOnce(ContextSaveErrorCallback, std::move(callback));
28823 std::move(error_reporter).Run(rc);
28824 return;
28825 }
28826 std::move(callback).Run(rc, context);
28827 }
28828
ContextSave(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,AuthorizationDelegate * authorization_delegate,ContextSaveResponse callback)28829 void Tpm::ContextSave(const TPMI_DH_CONTEXT& save_handle,
28830 const std::string& save_handle_name,
28831 AuthorizationDelegate* authorization_delegate,
28832 ContextSaveResponse callback) {
28833 VLOG(1) << __func__;
28834 std::string command;
28835 TPM_RC rc = SerializeCommand_ContextSave(save_handle, save_handle_name,
28836 &command, authorization_delegate);
28837 if (rc != TPM_RC_SUCCESS) {
28838 base::OnceCallback<void(TPM_RC)> error_reporter =
28839 base::BindOnce(ContextSaveErrorCallback, std::move(callback));
28840 std::move(error_reporter).Run(rc);
28841 return;
28842 }
28843 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
28844 ContextSaveResponseParser, std::move(callback), authorization_delegate);
28845 transceiver_->SendCommand(command, std::move(parser));
28846 }
28847
ContextSaveSync(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,TPMS_CONTEXT * context,AuthorizationDelegate * authorization_delegate)28848 TPM_RC Tpm::ContextSaveSync(const TPMI_DH_CONTEXT& save_handle,
28849 const std::string& save_handle_name,
28850 TPMS_CONTEXT* context,
28851 AuthorizationDelegate* authorization_delegate) {
28852 VLOG(1) << __func__;
28853 std::string command;
28854 TPM_RC rc = SerializeCommand_ContextSave(save_handle, save_handle_name,
28855 &command, authorization_delegate);
28856 if (rc != TPM_RC_SUCCESS) {
28857 return rc;
28858 }
28859 std::string response = transceiver_->SendCommandAndWait(command);
28860 rc = ParseResponse_ContextSave(response, context, authorization_delegate);
28861 return rc;
28862 }
28863
SerializeCommand_ContextLoad(const TPMS_CONTEXT & context,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28864 TPM_RC Tpm::SerializeCommand_ContextLoad(
28865 const TPMS_CONTEXT& context,
28866 std::string* serialized_command,
28867 AuthorizationDelegate* authorization_delegate) {
28868 VLOG(3) << __func__;
28869 TPM_RC rc = TPM_RC_SUCCESS;
28870 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28871 UINT32 command_size = 10; // Header size.
28872 std::string handle_section_bytes;
28873 std::string parameter_section_bytes;
28874 TPM_CC command_code = TPM_CC_ContextLoad;
28875 bool is_command_parameter_encryption_possible = false;
28876 bool is_response_parameter_encryption_possible = false;
28877 std::string command_code_bytes;
28878 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28879 if (rc != TPM_RC_SUCCESS) {
28880 return rc;
28881 }
28882 std::string context_bytes;
28883 rc = Serialize_TPMS_CONTEXT(context, &context_bytes);
28884 if (rc != TPM_RC_SUCCESS) {
28885 return rc;
28886 }
28887 std::unique_ptr<crypto::SecureHash> hash(
28888 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28889 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28890 hash->Update(context_bytes.data(), context_bytes.size());
28891 parameter_section_bytes += context_bytes;
28892 command_size += context_bytes.size();
28893 std::string command_hash(32, 0);
28894 hash->Finish(std::data(command_hash), command_hash.size());
28895 std::string authorization_section_bytes;
28896 std::string authorization_size_bytes;
28897 if (authorization_delegate) {
28898 if (!authorization_delegate->GetCommandAuthorization(
28899 command_hash, is_command_parameter_encryption_possible,
28900 is_response_parameter_encryption_possible,
28901 &authorization_section_bytes)) {
28902 return TRUNKS_RC_AUTHORIZATION_FAILED;
28903 }
28904 if (!authorization_section_bytes.empty()) {
28905 tag = TPM_ST_SESSIONS;
28906 std::string tmp;
28907 rc = Serialize_UINT32(authorization_section_bytes.size(),
28908 &authorization_size_bytes);
28909 if (rc != TPM_RC_SUCCESS) {
28910 return rc;
28911 }
28912 command_size +=
28913 authorization_size_bytes.size() + authorization_section_bytes.size();
28914 }
28915 }
28916 std::string tag_bytes;
28917 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28918 if (rc != TPM_RC_SUCCESS) {
28919 return rc;
28920 }
28921 std::string command_size_bytes;
28922 rc = Serialize_UINT32(command_size, &command_size_bytes);
28923 if (rc != TPM_RC_SUCCESS) {
28924 return rc;
28925 }
28926 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28927 handle_section_bytes + authorization_size_bytes +
28928 authorization_section_bytes + parameter_section_bytes;
28929 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28930 VLOG(2) << "Command: "
28931 << base::HexEncode(serialized_command->data(),
28932 serialized_command->size());
28933 return TPM_RC_SUCCESS;
28934 }
28935
ParseResponse_ContextLoad(const std::string & response,TPMI_DH_CONTEXT * loaded_handle,AuthorizationDelegate * authorization_delegate)28936 TPM_RC Tpm::ParseResponse_ContextLoad(
28937 const std::string& response,
28938 TPMI_DH_CONTEXT* loaded_handle,
28939 AuthorizationDelegate* authorization_delegate) {
28940 VLOG(3) << __func__;
28941 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28942 TPM_RC rc = TPM_RC_SUCCESS;
28943 std::string buffer(response);
28944 TPM_ST tag;
28945 std::string tag_bytes;
28946 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28947 if (rc != TPM_RC_SUCCESS) {
28948 return rc;
28949 }
28950 UINT32 response_size;
28951 std::string response_size_bytes;
28952 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28953 if (rc != TPM_RC_SUCCESS) {
28954 return rc;
28955 }
28956 TPM_RC response_code;
28957 std::string response_code_bytes;
28958 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28959 if (rc != TPM_RC_SUCCESS) {
28960 return rc;
28961 }
28962 if (response_size != response.size()) {
28963 return TPM_RC_SIZE;
28964 }
28965 if (response_code != TPM_RC_SUCCESS) {
28966 return response_code;
28967 }
28968 std::string loaded_handle_bytes;
28969 rc = Parse_TPMI_DH_CONTEXT(&buffer, loaded_handle, &loaded_handle_bytes);
28970 if (rc != TPM_RC_SUCCESS) {
28971 return rc;
28972 }
28973 TPM_CC command_code = TPM_CC_ContextLoad;
28974 std::string command_code_bytes;
28975 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28976 if (rc != TPM_RC_SUCCESS) {
28977 return rc;
28978 }
28979 std::string authorization_section_bytes;
28980 if (tag == TPM_ST_SESSIONS) {
28981 UINT32 parameter_section_size = buffer.size();
28982 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
28983 if (rc != TPM_RC_SUCCESS) {
28984 return rc;
28985 }
28986 if (parameter_section_size > buffer.size()) {
28987 return TPM_RC_INSUFFICIENT;
28988 }
28989 authorization_section_bytes = buffer.substr(parameter_section_size);
28990 // Keep the parameter section in |buffer|.
28991 buffer.erase(parameter_section_size);
28992 }
28993 std::unique_ptr<crypto::SecureHash> hash(
28994 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28995 hash->Update(response_code_bytes.data(), response_code_bytes.size());
28996 hash->Update(command_code_bytes.data(), command_code_bytes.size());
28997 hash->Update(buffer.data(), buffer.size());
28998 std::string response_hash(32, 0);
28999 hash->Finish(std::data(response_hash), response_hash.size());
29000 if (tag == TPM_ST_SESSIONS) {
29001 if (!authorization_delegate)
29002 return TRUNKS_RC_AUTHORIZATION_FAILED;
29003 if (!authorization_delegate->CheckResponseAuthorization(
29004 response_hash, authorization_section_bytes)) {
29005 return TRUNKS_RC_AUTHORIZATION_FAILED;
29006 }
29007 }
29008 return TPM_RC_SUCCESS;
29009 }
29010
ContextLoadErrorCallback(Tpm::ContextLoadResponse callback,TPM_RC response_code)29011 void ContextLoadErrorCallback(Tpm::ContextLoadResponse callback,
29012 TPM_RC response_code) {
29013 VLOG(1) << __func__;
29014 std::move(callback).Run(response_code, TPMI_DH_CONTEXT());
29015 }
29016
ContextLoadResponseParser(Tpm::ContextLoadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29017 void ContextLoadResponseParser(Tpm::ContextLoadResponse callback,
29018 AuthorizationDelegate* authorization_delegate,
29019 const std::string& response) {
29020 VLOG(1) << __func__;
29021 TPMI_DH_CONTEXT loaded_handle;
29022 TPM_RC rc = Tpm::ParseResponse_ContextLoad(response, &loaded_handle,
29023 authorization_delegate);
29024 if (rc != TPM_RC_SUCCESS) {
29025 base::OnceCallback<void(TPM_RC)> error_reporter =
29026 base::BindOnce(ContextLoadErrorCallback, std::move(callback));
29027 std::move(error_reporter).Run(rc);
29028 return;
29029 }
29030 std::move(callback).Run(rc, loaded_handle);
29031 }
29032
ContextLoad(const TPMS_CONTEXT & context,AuthorizationDelegate * authorization_delegate,ContextLoadResponse callback)29033 void Tpm::ContextLoad(const TPMS_CONTEXT& context,
29034 AuthorizationDelegate* authorization_delegate,
29035 ContextLoadResponse callback) {
29036 VLOG(1) << __func__;
29037 std::string command;
29038 TPM_RC rc =
29039 SerializeCommand_ContextLoad(context, &command, authorization_delegate);
29040 if (rc != TPM_RC_SUCCESS) {
29041 base::OnceCallback<void(TPM_RC)> error_reporter =
29042 base::BindOnce(ContextLoadErrorCallback, std::move(callback));
29043 std::move(error_reporter).Run(rc);
29044 return;
29045 }
29046 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29047 ContextLoadResponseParser, std::move(callback), authorization_delegate);
29048 transceiver_->SendCommand(command, std::move(parser));
29049 }
29050
ContextLoadSync(const TPMS_CONTEXT & context,TPMI_DH_CONTEXT * loaded_handle,AuthorizationDelegate * authorization_delegate)29051 TPM_RC Tpm::ContextLoadSync(const TPMS_CONTEXT& context,
29052 TPMI_DH_CONTEXT* loaded_handle,
29053 AuthorizationDelegate* authorization_delegate) {
29054 VLOG(1) << __func__;
29055 std::string command;
29056 TPM_RC rc =
29057 SerializeCommand_ContextLoad(context, &command, authorization_delegate);
29058 if (rc != TPM_RC_SUCCESS) {
29059 return rc;
29060 }
29061 std::string response = transceiver_->SendCommandAndWait(command);
29062 rc = ParseResponse_ContextLoad(response, loaded_handle,
29063 authorization_delegate);
29064 return rc;
29065 }
29066
SerializeCommand_FlushContext(const TPMI_DH_CONTEXT & flush_handle,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29067 TPM_RC Tpm::SerializeCommand_FlushContext(
29068 const TPMI_DH_CONTEXT& flush_handle,
29069 std::string* serialized_command,
29070 AuthorizationDelegate* authorization_delegate) {
29071 VLOG(3) << __func__;
29072 TPM_RC rc = TPM_RC_SUCCESS;
29073 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29074 UINT32 command_size = 10; // Header size.
29075 std::string handle_section_bytes;
29076 std::string parameter_section_bytes;
29077 TPM_CC command_code = TPM_CC_FlushContext;
29078 bool is_command_parameter_encryption_possible = false;
29079 bool is_response_parameter_encryption_possible = false;
29080 std::string command_code_bytes;
29081 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29082 if (rc != TPM_RC_SUCCESS) {
29083 return rc;
29084 }
29085 std::string flush_handle_bytes;
29086 rc = Serialize_TPMI_DH_CONTEXT(flush_handle, &flush_handle_bytes);
29087 if (rc != TPM_RC_SUCCESS) {
29088 return rc;
29089 }
29090 std::unique_ptr<crypto::SecureHash> hash(
29091 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29092 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29093 hash->Update(flush_handle_bytes.data(), flush_handle_bytes.size());
29094 parameter_section_bytes += flush_handle_bytes;
29095 command_size += flush_handle_bytes.size();
29096 std::string command_hash(32, 0);
29097 hash->Finish(std::data(command_hash), command_hash.size());
29098 std::string authorization_section_bytes;
29099 std::string authorization_size_bytes;
29100 if (authorization_delegate) {
29101 if (!authorization_delegate->GetCommandAuthorization(
29102 command_hash, is_command_parameter_encryption_possible,
29103 is_response_parameter_encryption_possible,
29104 &authorization_section_bytes)) {
29105 return TRUNKS_RC_AUTHORIZATION_FAILED;
29106 }
29107 if (!authorization_section_bytes.empty()) {
29108 tag = TPM_ST_SESSIONS;
29109 std::string tmp;
29110 rc = Serialize_UINT32(authorization_section_bytes.size(),
29111 &authorization_size_bytes);
29112 if (rc != TPM_RC_SUCCESS) {
29113 return rc;
29114 }
29115 command_size +=
29116 authorization_size_bytes.size() + authorization_section_bytes.size();
29117 }
29118 }
29119 std::string tag_bytes;
29120 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29121 if (rc != TPM_RC_SUCCESS) {
29122 return rc;
29123 }
29124 std::string command_size_bytes;
29125 rc = Serialize_UINT32(command_size, &command_size_bytes);
29126 if (rc != TPM_RC_SUCCESS) {
29127 return rc;
29128 }
29129 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29130 handle_section_bytes + authorization_size_bytes +
29131 authorization_section_bytes + parameter_section_bytes;
29132 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29133 VLOG(2) << "Command: "
29134 << base::HexEncode(serialized_command->data(),
29135 serialized_command->size());
29136 return TPM_RC_SUCCESS;
29137 }
29138
ParseResponse_FlushContext(const std::string & response,AuthorizationDelegate * authorization_delegate)29139 TPM_RC Tpm::ParseResponse_FlushContext(
29140 const std::string& response,
29141 AuthorizationDelegate* authorization_delegate) {
29142 VLOG(3) << __func__;
29143 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29144 TPM_RC rc = TPM_RC_SUCCESS;
29145 std::string buffer(response);
29146 TPM_ST tag;
29147 std::string tag_bytes;
29148 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29149 if (rc != TPM_RC_SUCCESS) {
29150 return rc;
29151 }
29152 UINT32 response_size;
29153 std::string response_size_bytes;
29154 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29155 if (rc != TPM_RC_SUCCESS) {
29156 return rc;
29157 }
29158 TPM_RC response_code;
29159 std::string response_code_bytes;
29160 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29161 if (rc != TPM_RC_SUCCESS) {
29162 return rc;
29163 }
29164 if (response_size != response.size()) {
29165 return TPM_RC_SIZE;
29166 }
29167 if (response_code != TPM_RC_SUCCESS) {
29168 return response_code;
29169 }
29170 TPM_CC command_code = TPM_CC_FlushContext;
29171 std::string command_code_bytes;
29172 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29173 if (rc != TPM_RC_SUCCESS) {
29174 return rc;
29175 }
29176 std::string authorization_section_bytes;
29177 if (tag == TPM_ST_SESSIONS) {
29178 UINT32 parameter_section_size = buffer.size();
29179 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
29180 if (rc != TPM_RC_SUCCESS) {
29181 return rc;
29182 }
29183 if (parameter_section_size > buffer.size()) {
29184 return TPM_RC_INSUFFICIENT;
29185 }
29186 authorization_section_bytes = buffer.substr(parameter_section_size);
29187 // Keep the parameter section in |buffer|.
29188 buffer.erase(parameter_section_size);
29189 }
29190 std::unique_ptr<crypto::SecureHash> hash(
29191 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29192 hash->Update(response_code_bytes.data(), response_code_bytes.size());
29193 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29194 hash->Update(buffer.data(), buffer.size());
29195 std::string response_hash(32, 0);
29196 hash->Finish(std::data(response_hash), response_hash.size());
29197 if (tag == TPM_ST_SESSIONS) {
29198 if (!authorization_delegate)
29199 return TRUNKS_RC_AUTHORIZATION_FAILED;
29200 if (!authorization_delegate->CheckResponseAuthorization(
29201 response_hash, authorization_section_bytes)) {
29202 return TRUNKS_RC_AUTHORIZATION_FAILED;
29203 }
29204 }
29205 return TPM_RC_SUCCESS;
29206 }
29207
FlushContextErrorCallback(Tpm::FlushContextResponse callback,TPM_RC response_code)29208 void FlushContextErrorCallback(Tpm::FlushContextResponse callback,
29209 TPM_RC response_code) {
29210 VLOG(1) << __func__;
29211 std::move(callback).Run(response_code);
29212 }
29213
FlushContextResponseParser(Tpm::FlushContextResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29214 void FlushContextResponseParser(Tpm::FlushContextResponse callback,
29215 AuthorizationDelegate* authorization_delegate,
29216 const std::string& response) {
29217 VLOG(1) << __func__;
29218 TPM_RC rc = Tpm::ParseResponse_FlushContext(response, authorization_delegate);
29219 if (rc != TPM_RC_SUCCESS) {
29220 base::OnceCallback<void(TPM_RC)> error_reporter =
29221 base::BindOnce(FlushContextErrorCallback, std::move(callback));
29222 std::move(error_reporter).Run(rc);
29223 return;
29224 }
29225 std::move(callback).Run(rc);
29226 }
29227
FlushContext(const TPMI_DH_CONTEXT & flush_handle,AuthorizationDelegate * authorization_delegate,FlushContextResponse callback)29228 void Tpm::FlushContext(const TPMI_DH_CONTEXT& flush_handle,
29229 AuthorizationDelegate* authorization_delegate,
29230 FlushContextResponse callback) {
29231 VLOG(1) << __func__;
29232 std::string command;
29233 TPM_RC rc = SerializeCommand_FlushContext(flush_handle, &command,
29234 authorization_delegate);
29235 if (rc != TPM_RC_SUCCESS) {
29236 base::OnceCallback<void(TPM_RC)> error_reporter =
29237 base::BindOnce(FlushContextErrorCallback, std::move(callback));
29238 std::move(error_reporter).Run(rc);
29239 return;
29240 }
29241 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29242 FlushContextResponseParser, std::move(callback), authorization_delegate);
29243 transceiver_->SendCommand(command, std::move(parser));
29244 }
29245
FlushContextSync(const TPMI_DH_CONTEXT & flush_handle,AuthorizationDelegate * authorization_delegate)29246 TPM_RC Tpm::FlushContextSync(const TPMI_DH_CONTEXT& flush_handle,
29247 AuthorizationDelegate* authorization_delegate) {
29248 VLOG(1) << __func__;
29249 std::string command;
29250 TPM_RC rc = SerializeCommand_FlushContext(flush_handle, &command,
29251 authorization_delegate);
29252 if (rc != TPM_RC_SUCCESS) {
29253 return rc;
29254 }
29255 std::string response = transceiver_->SendCommandAndWait(command);
29256 rc = ParseResponse_FlushContext(response, authorization_delegate);
29257 return rc;
29258 }
29259
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)29260 TPM_RC Tpm::SerializeCommand_EvictControl(
29261 const TPMI_RH_PROVISION& auth,
29262 const std::string& auth_name,
29263 const TPMI_DH_OBJECT& object_handle,
29264 const std::string& object_handle_name,
29265 const TPMI_DH_PERSISTENT& persistent_handle,
29266 std::string* serialized_command,
29267 AuthorizationDelegate* authorization_delegate) {
29268 VLOG(3) << __func__;
29269 TPM_RC rc = TPM_RC_SUCCESS;
29270 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29271 UINT32 command_size = 10; // Header size.
29272 std::string handle_section_bytes;
29273 std::string parameter_section_bytes;
29274 TPM_CC command_code = TPM_CC_EvictControl;
29275 bool is_command_parameter_encryption_possible = false;
29276 bool is_response_parameter_encryption_possible = false;
29277 std::string command_code_bytes;
29278 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29279 if (rc != TPM_RC_SUCCESS) {
29280 return rc;
29281 }
29282 std::string auth_bytes;
29283 rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29284 if (rc != TPM_RC_SUCCESS) {
29285 return rc;
29286 }
29287 std::string object_handle_bytes;
29288 rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
29289 if (rc != TPM_RC_SUCCESS) {
29290 return rc;
29291 }
29292 std::string persistent_handle_bytes;
29293 rc =
29294 Serialize_TPMI_DH_PERSISTENT(persistent_handle, &persistent_handle_bytes);
29295 if (rc != TPM_RC_SUCCESS) {
29296 return rc;
29297 }
29298 std::unique_ptr<crypto::SecureHash> hash(
29299 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29300 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29301 hash->Update(auth_name.data(), auth_name.size());
29302 handle_section_bytes += auth_bytes;
29303 command_size += auth_bytes.size();
29304 hash->Update(object_handle_name.data(), object_handle_name.size());
29305 handle_section_bytes += object_handle_bytes;
29306 command_size += object_handle_bytes.size();
29307 hash->Update(persistent_handle_bytes.data(), persistent_handle_bytes.size());
29308 parameter_section_bytes += persistent_handle_bytes;
29309 command_size += persistent_handle_bytes.size();
29310 std::string command_hash(32, 0);
29311 hash->Finish(std::data(command_hash), command_hash.size());
29312 std::string authorization_section_bytes;
29313 std::string authorization_size_bytes;
29314 if (authorization_delegate) {
29315 if (!authorization_delegate->GetCommandAuthorization(
29316 command_hash, is_command_parameter_encryption_possible,
29317 is_response_parameter_encryption_possible,
29318 &authorization_section_bytes)) {
29319 return TRUNKS_RC_AUTHORIZATION_FAILED;
29320 }
29321 if (!authorization_section_bytes.empty()) {
29322 tag = TPM_ST_SESSIONS;
29323 std::string tmp;
29324 rc = Serialize_UINT32(authorization_section_bytes.size(),
29325 &authorization_size_bytes);
29326 if (rc != TPM_RC_SUCCESS) {
29327 return rc;
29328 }
29329 command_size +=
29330 authorization_size_bytes.size() + authorization_section_bytes.size();
29331 }
29332 }
29333 std::string tag_bytes;
29334 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29335 if (rc != TPM_RC_SUCCESS) {
29336 return rc;
29337 }
29338 std::string command_size_bytes;
29339 rc = Serialize_UINT32(command_size, &command_size_bytes);
29340 if (rc != TPM_RC_SUCCESS) {
29341 return rc;
29342 }
29343 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29344 handle_section_bytes + authorization_size_bytes +
29345 authorization_section_bytes + parameter_section_bytes;
29346 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29347 VLOG(2) << "Command: "
29348 << base::HexEncode(serialized_command->data(),
29349 serialized_command->size());
29350 return TPM_RC_SUCCESS;
29351 }
29352
ParseResponse_EvictControl(const std::string & response,AuthorizationDelegate * authorization_delegate)29353 TPM_RC Tpm::ParseResponse_EvictControl(
29354 const std::string& response,
29355 AuthorizationDelegate* authorization_delegate) {
29356 VLOG(3) << __func__;
29357 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29358 TPM_RC rc = TPM_RC_SUCCESS;
29359 std::string buffer(response);
29360 TPM_ST tag;
29361 std::string tag_bytes;
29362 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29363 if (rc != TPM_RC_SUCCESS) {
29364 return rc;
29365 }
29366 UINT32 response_size;
29367 std::string response_size_bytes;
29368 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29369 if (rc != TPM_RC_SUCCESS) {
29370 return rc;
29371 }
29372 TPM_RC response_code;
29373 std::string response_code_bytes;
29374 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29375 if (rc != TPM_RC_SUCCESS) {
29376 return rc;
29377 }
29378 if (response_size != response.size()) {
29379 return TPM_RC_SIZE;
29380 }
29381 if (response_code != TPM_RC_SUCCESS) {
29382 return response_code;
29383 }
29384 TPM_CC command_code = TPM_CC_EvictControl;
29385 std::string command_code_bytes;
29386 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29387 if (rc != TPM_RC_SUCCESS) {
29388 return rc;
29389 }
29390 std::string authorization_section_bytes;
29391 if (tag == TPM_ST_SESSIONS) {
29392 UINT32 parameter_section_size = buffer.size();
29393 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
29394 if (rc != TPM_RC_SUCCESS) {
29395 return rc;
29396 }
29397 if (parameter_section_size > buffer.size()) {
29398 return TPM_RC_INSUFFICIENT;
29399 }
29400 authorization_section_bytes = buffer.substr(parameter_section_size);
29401 // Keep the parameter section in |buffer|.
29402 buffer.erase(parameter_section_size);
29403 }
29404 std::unique_ptr<crypto::SecureHash> hash(
29405 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29406 hash->Update(response_code_bytes.data(), response_code_bytes.size());
29407 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29408 hash->Update(buffer.data(), buffer.size());
29409 std::string response_hash(32, 0);
29410 hash->Finish(std::data(response_hash), response_hash.size());
29411 if (tag == TPM_ST_SESSIONS) {
29412 if (!authorization_delegate)
29413 return TRUNKS_RC_AUTHORIZATION_FAILED;
29414 if (!authorization_delegate->CheckResponseAuthorization(
29415 response_hash, authorization_section_bytes)) {
29416 return TRUNKS_RC_AUTHORIZATION_FAILED;
29417 }
29418 }
29419 return TPM_RC_SUCCESS;
29420 }
29421
EvictControlErrorCallback(Tpm::EvictControlResponse callback,TPM_RC response_code)29422 void EvictControlErrorCallback(Tpm::EvictControlResponse callback,
29423 TPM_RC response_code) {
29424 VLOG(1) << __func__;
29425 std::move(callback).Run(response_code);
29426 }
29427
EvictControlResponseParser(Tpm::EvictControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29428 void EvictControlResponseParser(Tpm::EvictControlResponse callback,
29429 AuthorizationDelegate* authorization_delegate,
29430 const std::string& response) {
29431 VLOG(1) << __func__;
29432 TPM_RC rc = Tpm::ParseResponse_EvictControl(response, authorization_delegate);
29433 if (rc != TPM_RC_SUCCESS) {
29434 base::OnceCallback<void(TPM_RC)> error_reporter =
29435 base::BindOnce(EvictControlErrorCallback, std::move(callback));
29436 std::move(error_reporter).Run(rc);
29437 return;
29438 }
29439 std::move(callback).Run(rc);
29440 }
29441
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)29442 void Tpm::EvictControl(const TPMI_RH_PROVISION& auth,
29443 const std::string& auth_name,
29444 const TPMI_DH_OBJECT& object_handle,
29445 const std::string& object_handle_name,
29446 const TPMI_DH_PERSISTENT& persistent_handle,
29447 AuthorizationDelegate* authorization_delegate,
29448 EvictControlResponse callback) {
29449 VLOG(1) << __func__;
29450 std::string command;
29451 TPM_RC rc = SerializeCommand_EvictControl(
29452 auth, auth_name, object_handle, object_handle_name, persistent_handle,
29453 &command, authorization_delegate);
29454 if (rc != TPM_RC_SUCCESS) {
29455 base::OnceCallback<void(TPM_RC)> error_reporter =
29456 base::BindOnce(EvictControlErrorCallback, std::move(callback));
29457 std::move(error_reporter).Run(rc);
29458 return;
29459 }
29460 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29461 EvictControlResponseParser, std::move(callback), authorization_delegate);
29462 transceiver_->SendCommand(command, std::move(parser));
29463 }
29464
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)29465 TPM_RC Tpm::EvictControlSync(const TPMI_RH_PROVISION& auth,
29466 const std::string& auth_name,
29467 const TPMI_DH_OBJECT& object_handle,
29468 const std::string& object_handle_name,
29469 const TPMI_DH_PERSISTENT& persistent_handle,
29470 AuthorizationDelegate* authorization_delegate) {
29471 VLOG(1) << __func__;
29472 std::string command;
29473 TPM_RC rc = SerializeCommand_EvictControl(
29474 auth, auth_name, object_handle, object_handle_name, persistent_handle,
29475 &command, authorization_delegate);
29476 if (rc != TPM_RC_SUCCESS) {
29477 return rc;
29478 }
29479 std::string response = transceiver_->SendCommandAndWait(command);
29480 rc = ParseResponse_EvictControl(response, authorization_delegate);
29481 return rc;
29482 }
29483
SerializeCommand_ReadClock(std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29484 TPM_RC Tpm::SerializeCommand_ReadClock(
29485 std::string* serialized_command,
29486 AuthorizationDelegate* authorization_delegate) {
29487 VLOG(3) << __func__;
29488 TPM_RC rc = TPM_RC_SUCCESS;
29489 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29490 UINT32 command_size = 10; // Header size.
29491 std::string handle_section_bytes;
29492 std::string parameter_section_bytes;
29493 TPM_CC command_code = TPM_CC_ReadClock;
29494 bool is_command_parameter_encryption_possible = false;
29495 bool is_response_parameter_encryption_possible = false;
29496 std::string command_code_bytes;
29497 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29498 if (rc != TPM_RC_SUCCESS) {
29499 return rc;
29500 }
29501 std::unique_ptr<crypto::SecureHash> hash(
29502 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29503 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29504 std::string command_hash(32, 0);
29505 hash->Finish(std::data(command_hash), command_hash.size());
29506 std::string authorization_section_bytes;
29507 std::string authorization_size_bytes;
29508 if (authorization_delegate) {
29509 if (!authorization_delegate->GetCommandAuthorization(
29510 command_hash, is_command_parameter_encryption_possible,
29511 is_response_parameter_encryption_possible,
29512 &authorization_section_bytes)) {
29513 return TRUNKS_RC_AUTHORIZATION_FAILED;
29514 }
29515 if (!authorization_section_bytes.empty()) {
29516 tag = TPM_ST_SESSIONS;
29517 std::string tmp;
29518 rc = Serialize_UINT32(authorization_section_bytes.size(),
29519 &authorization_size_bytes);
29520 if (rc != TPM_RC_SUCCESS) {
29521 return rc;
29522 }
29523 command_size +=
29524 authorization_size_bytes.size() + authorization_section_bytes.size();
29525 }
29526 }
29527 std::string tag_bytes;
29528 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29529 if (rc != TPM_RC_SUCCESS) {
29530 return rc;
29531 }
29532 std::string command_size_bytes;
29533 rc = Serialize_UINT32(command_size, &command_size_bytes);
29534 if (rc != TPM_RC_SUCCESS) {
29535 return rc;
29536 }
29537 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29538 handle_section_bytes + authorization_size_bytes +
29539 authorization_section_bytes + parameter_section_bytes;
29540 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29541 VLOG(2) << "Command: "
29542 << base::HexEncode(serialized_command->data(),
29543 serialized_command->size());
29544 return TPM_RC_SUCCESS;
29545 }
29546
ParseResponse_ReadClock(const std::string & response,TPMS_TIME_INFO * current_time,AuthorizationDelegate * authorization_delegate)29547 TPM_RC Tpm::ParseResponse_ReadClock(
29548 const std::string& response,
29549 TPMS_TIME_INFO* current_time,
29550 AuthorizationDelegate* authorization_delegate) {
29551 VLOG(3) << __func__;
29552 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29553 TPM_RC rc = TPM_RC_SUCCESS;
29554 std::string buffer(response);
29555 TPM_ST tag;
29556 std::string tag_bytes;
29557 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29558 if (rc != TPM_RC_SUCCESS) {
29559 return rc;
29560 }
29561 UINT32 response_size;
29562 std::string response_size_bytes;
29563 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29564 if (rc != TPM_RC_SUCCESS) {
29565 return rc;
29566 }
29567 TPM_RC response_code;
29568 std::string response_code_bytes;
29569 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29570 if (rc != TPM_RC_SUCCESS) {
29571 return rc;
29572 }
29573 if (response_size != response.size()) {
29574 return TPM_RC_SIZE;
29575 }
29576 if (response_code != TPM_RC_SUCCESS) {
29577 return response_code;
29578 }
29579 TPM_CC command_code = TPM_CC_ReadClock;
29580 std::string command_code_bytes;
29581 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29582 if (rc != TPM_RC_SUCCESS) {
29583 return rc;
29584 }
29585 std::string authorization_section_bytes;
29586 if (tag == TPM_ST_SESSIONS) {
29587 UINT32 parameter_section_size = buffer.size();
29588 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
29589 if (rc != TPM_RC_SUCCESS) {
29590 return rc;
29591 }
29592 if (parameter_section_size > buffer.size()) {
29593 return TPM_RC_INSUFFICIENT;
29594 }
29595 authorization_section_bytes = buffer.substr(parameter_section_size);
29596 // Keep the parameter section in |buffer|.
29597 buffer.erase(parameter_section_size);
29598 }
29599 std::unique_ptr<crypto::SecureHash> hash(
29600 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29601 hash->Update(response_code_bytes.data(), response_code_bytes.size());
29602 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29603 hash->Update(buffer.data(), buffer.size());
29604 std::string response_hash(32, 0);
29605 hash->Finish(std::data(response_hash), response_hash.size());
29606 if (tag == TPM_ST_SESSIONS) {
29607 if (!authorization_delegate)
29608 return TRUNKS_RC_AUTHORIZATION_FAILED;
29609 if (!authorization_delegate->CheckResponseAuthorization(
29610 response_hash, authorization_section_bytes)) {
29611 return TRUNKS_RC_AUTHORIZATION_FAILED;
29612 }
29613 }
29614 std::string current_time_bytes;
29615 rc = Parse_TPMS_TIME_INFO(&buffer, current_time, ¤t_time_bytes);
29616 if (rc != TPM_RC_SUCCESS) {
29617 return rc;
29618 }
29619 return TPM_RC_SUCCESS;
29620 }
29621
ReadClockErrorCallback(Tpm::ReadClockResponse callback,TPM_RC response_code)29622 void ReadClockErrorCallback(Tpm::ReadClockResponse callback,
29623 TPM_RC response_code) {
29624 VLOG(1) << __func__;
29625 std::move(callback).Run(response_code, TPMS_TIME_INFO());
29626 }
29627
ReadClockResponseParser(Tpm::ReadClockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29628 void ReadClockResponseParser(Tpm::ReadClockResponse callback,
29629 AuthorizationDelegate* authorization_delegate,
29630 const std::string& response) {
29631 VLOG(1) << __func__;
29632 TPMS_TIME_INFO current_time;
29633 TPM_RC rc = Tpm::ParseResponse_ReadClock(response, ¤t_time,
29634 authorization_delegate);
29635 if (rc != TPM_RC_SUCCESS) {
29636 base::OnceCallback<void(TPM_RC)> error_reporter =
29637 base::BindOnce(ReadClockErrorCallback, std::move(callback));
29638 std::move(error_reporter).Run(rc);
29639 return;
29640 }
29641 std::move(callback).Run(rc, current_time);
29642 }
29643
ReadClock(AuthorizationDelegate * authorization_delegate,ReadClockResponse callback)29644 void Tpm::ReadClock(AuthorizationDelegate* authorization_delegate,
29645 ReadClockResponse callback) {
29646 VLOG(1) << __func__;
29647 std::string command;
29648 TPM_RC rc = SerializeCommand_ReadClock(&command, authorization_delegate);
29649 if (rc != TPM_RC_SUCCESS) {
29650 base::OnceCallback<void(TPM_RC)> error_reporter =
29651 base::BindOnce(ReadClockErrorCallback, std::move(callback));
29652 std::move(error_reporter).Run(rc);
29653 return;
29654 }
29655 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29656 ReadClockResponseParser, std::move(callback), authorization_delegate);
29657 transceiver_->SendCommand(command, std::move(parser));
29658 }
29659
ReadClockSync(TPMS_TIME_INFO * current_time,AuthorizationDelegate * authorization_delegate)29660 TPM_RC Tpm::ReadClockSync(TPMS_TIME_INFO* current_time,
29661 AuthorizationDelegate* authorization_delegate) {
29662 VLOG(1) << __func__;
29663 std::string command;
29664 TPM_RC rc = SerializeCommand_ReadClock(&command, authorization_delegate);
29665 if (rc != TPM_RC_SUCCESS) {
29666 return rc;
29667 }
29668 std::string response = transceiver_->SendCommandAndWait(command);
29669 rc = ParseResponse_ReadClock(response, current_time, authorization_delegate);
29670 return rc;
29671 }
29672
SerializeCommand_ClockSet(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29673 TPM_RC Tpm::SerializeCommand_ClockSet(
29674 const TPMI_RH_PROVISION& auth,
29675 const std::string& auth_name,
29676 const UINT64& new_time,
29677 std::string* serialized_command,
29678 AuthorizationDelegate* authorization_delegate) {
29679 VLOG(3) << __func__;
29680 TPM_RC rc = TPM_RC_SUCCESS;
29681 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29682 UINT32 command_size = 10; // Header size.
29683 std::string handle_section_bytes;
29684 std::string parameter_section_bytes;
29685 TPM_CC command_code = TPM_CC_ClockSet;
29686 bool is_command_parameter_encryption_possible = false;
29687 bool is_response_parameter_encryption_possible = false;
29688 std::string command_code_bytes;
29689 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29690 if (rc != TPM_RC_SUCCESS) {
29691 return rc;
29692 }
29693 std::string auth_bytes;
29694 rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29695 if (rc != TPM_RC_SUCCESS) {
29696 return rc;
29697 }
29698 std::string new_time_bytes;
29699 rc = Serialize_UINT64(new_time, &new_time_bytes);
29700 if (rc != TPM_RC_SUCCESS) {
29701 return rc;
29702 }
29703 std::unique_ptr<crypto::SecureHash> hash(
29704 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29705 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29706 hash->Update(auth_name.data(), auth_name.size());
29707 handle_section_bytes += auth_bytes;
29708 command_size += auth_bytes.size();
29709 hash->Update(new_time_bytes.data(), new_time_bytes.size());
29710 parameter_section_bytes += new_time_bytes;
29711 command_size += new_time_bytes.size();
29712 std::string command_hash(32, 0);
29713 hash->Finish(std::data(command_hash), command_hash.size());
29714 std::string authorization_section_bytes;
29715 std::string authorization_size_bytes;
29716 if (authorization_delegate) {
29717 if (!authorization_delegate->GetCommandAuthorization(
29718 command_hash, is_command_parameter_encryption_possible,
29719 is_response_parameter_encryption_possible,
29720 &authorization_section_bytes)) {
29721 return TRUNKS_RC_AUTHORIZATION_FAILED;
29722 }
29723 if (!authorization_section_bytes.empty()) {
29724 tag = TPM_ST_SESSIONS;
29725 std::string tmp;
29726 rc = Serialize_UINT32(authorization_section_bytes.size(),
29727 &authorization_size_bytes);
29728 if (rc != TPM_RC_SUCCESS) {
29729 return rc;
29730 }
29731 command_size +=
29732 authorization_size_bytes.size() + authorization_section_bytes.size();
29733 }
29734 }
29735 std::string tag_bytes;
29736 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29737 if (rc != TPM_RC_SUCCESS) {
29738 return rc;
29739 }
29740 std::string command_size_bytes;
29741 rc = Serialize_UINT32(command_size, &command_size_bytes);
29742 if (rc != TPM_RC_SUCCESS) {
29743 return rc;
29744 }
29745 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29746 handle_section_bytes + authorization_size_bytes +
29747 authorization_section_bytes + parameter_section_bytes;
29748 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29749 VLOG(2) << "Command: "
29750 << base::HexEncode(serialized_command->data(),
29751 serialized_command->size());
29752 return TPM_RC_SUCCESS;
29753 }
29754
ParseResponse_ClockSet(const std::string & response,AuthorizationDelegate * authorization_delegate)29755 TPM_RC Tpm::ParseResponse_ClockSet(
29756 const std::string& response,
29757 AuthorizationDelegate* authorization_delegate) {
29758 VLOG(3) << __func__;
29759 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29760 TPM_RC rc = TPM_RC_SUCCESS;
29761 std::string buffer(response);
29762 TPM_ST tag;
29763 std::string tag_bytes;
29764 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29765 if (rc != TPM_RC_SUCCESS) {
29766 return rc;
29767 }
29768 UINT32 response_size;
29769 std::string response_size_bytes;
29770 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29771 if (rc != TPM_RC_SUCCESS) {
29772 return rc;
29773 }
29774 TPM_RC response_code;
29775 std::string response_code_bytes;
29776 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29777 if (rc != TPM_RC_SUCCESS) {
29778 return rc;
29779 }
29780 if (response_size != response.size()) {
29781 return TPM_RC_SIZE;
29782 }
29783 if (response_code != TPM_RC_SUCCESS) {
29784 return response_code;
29785 }
29786 TPM_CC command_code = TPM_CC_ClockSet;
29787 std::string command_code_bytes;
29788 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29789 if (rc != TPM_RC_SUCCESS) {
29790 return rc;
29791 }
29792 std::string authorization_section_bytes;
29793 if (tag == TPM_ST_SESSIONS) {
29794 UINT32 parameter_section_size = buffer.size();
29795 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
29796 if (rc != TPM_RC_SUCCESS) {
29797 return rc;
29798 }
29799 if (parameter_section_size > buffer.size()) {
29800 return TPM_RC_INSUFFICIENT;
29801 }
29802 authorization_section_bytes = buffer.substr(parameter_section_size);
29803 // Keep the parameter section in |buffer|.
29804 buffer.erase(parameter_section_size);
29805 }
29806 std::unique_ptr<crypto::SecureHash> hash(
29807 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29808 hash->Update(response_code_bytes.data(), response_code_bytes.size());
29809 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29810 hash->Update(buffer.data(), buffer.size());
29811 std::string response_hash(32, 0);
29812 hash->Finish(std::data(response_hash), response_hash.size());
29813 if (tag == TPM_ST_SESSIONS) {
29814 if (!authorization_delegate)
29815 return TRUNKS_RC_AUTHORIZATION_FAILED;
29816 if (!authorization_delegate->CheckResponseAuthorization(
29817 response_hash, authorization_section_bytes)) {
29818 return TRUNKS_RC_AUTHORIZATION_FAILED;
29819 }
29820 }
29821 return TPM_RC_SUCCESS;
29822 }
29823
ClockSetErrorCallback(Tpm::ClockSetResponse callback,TPM_RC response_code)29824 void ClockSetErrorCallback(Tpm::ClockSetResponse callback,
29825 TPM_RC response_code) {
29826 VLOG(1) << __func__;
29827 std::move(callback).Run(response_code);
29828 }
29829
ClockSetResponseParser(Tpm::ClockSetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29830 void ClockSetResponseParser(Tpm::ClockSetResponse callback,
29831 AuthorizationDelegate* authorization_delegate,
29832 const std::string& response) {
29833 VLOG(1) << __func__;
29834 TPM_RC rc = Tpm::ParseResponse_ClockSet(response, authorization_delegate);
29835 if (rc != TPM_RC_SUCCESS) {
29836 base::OnceCallback<void(TPM_RC)> error_reporter =
29837 base::BindOnce(ClockSetErrorCallback, std::move(callback));
29838 std::move(error_reporter).Run(rc);
29839 return;
29840 }
29841 std::move(callback).Run(rc);
29842 }
29843
ClockSet(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,AuthorizationDelegate * authorization_delegate,ClockSetResponse callback)29844 void Tpm::ClockSet(const TPMI_RH_PROVISION& auth,
29845 const std::string& auth_name,
29846 const UINT64& new_time,
29847 AuthorizationDelegate* authorization_delegate,
29848 ClockSetResponse callback) {
29849 VLOG(1) << __func__;
29850 std::string command;
29851 TPM_RC rc = SerializeCommand_ClockSet(auth, auth_name, new_time, &command,
29852 authorization_delegate);
29853 if (rc != TPM_RC_SUCCESS) {
29854 base::OnceCallback<void(TPM_RC)> error_reporter =
29855 base::BindOnce(ClockSetErrorCallback, std::move(callback));
29856 std::move(error_reporter).Run(rc);
29857 return;
29858 }
29859 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29860 ClockSetResponseParser, std::move(callback), authorization_delegate);
29861 transceiver_->SendCommand(command, std::move(parser));
29862 }
29863
ClockSetSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,AuthorizationDelegate * authorization_delegate)29864 TPM_RC Tpm::ClockSetSync(const TPMI_RH_PROVISION& auth,
29865 const std::string& auth_name,
29866 const UINT64& new_time,
29867 AuthorizationDelegate* authorization_delegate) {
29868 VLOG(1) << __func__;
29869 std::string command;
29870 TPM_RC rc = SerializeCommand_ClockSet(auth, auth_name, new_time, &command,
29871 authorization_delegate);
29872 if (rc != TPM_RC_SUCCESS) {
29873 return rc;
29874 }
29875 std::string response = transceiver_->SendCommandAndWait(command);
29876 rc = ParseResponse_ClockSet(response, authorization_delegate);
29877 return rc;
29878 }
29879
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)29880 TPM_RC Tpm::SerializeCommand_ClockRateAdjust(
29881 const TPMI_RH_PROVISION& auth,
29882 const std::string& auth_name,
29883 const TPM_CLOCK_ADJUST& rate_adjust,
29884 std::string* serialized_command,
29885 AuthorizationDelegate* authorization_delegate) {
29886 VLOG(3) << __func__;
29887 TPM_RC rc = TPM_RC_SUCCESS;
29888 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29889 UINT32 command_size = 10; // Header size.
29890 std::string handle_section_bytes;
29891 std::string parameter_section_bytes;
29892 TPM_CC command_code = TPM_CC_ClockRateAdjust;
29893 bool is_command_parameter_encryption_possible = false;
29894 bool is_response_parameter_encryption_possible = false;
29895 std::string command_code_bytes;
29896 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29897 if (rc != TPM_RC_SUCCESS) {
29898 return rc;
29899 }
29900 std::string auth_bytes;
29901 rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29902 if (rc != TPM_RC_SUCCESS) {
29903 return rc;
29904 }
29905 std::string rate_adjust_bytes;
29906 rc = Serialize_TPM_CLOCK_ADJUST(rate_adjust, &rate_adjust_bytes);
29907 if (rc != TPM_RC_SUCCESS) {
29908 return rc;
29909 }
29910 std::unique_ptr<crypto::SecureHash> hash(
29911 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29912 hash->Update(command_code_bytes.data(), command_code_bytes.size());
29913 hash->Update(auth_name.data(), auth_name.size());
29914 handle_section_bytes += auth_bytes;
29915 command_size += auth_bytes.size();
29916 hash->Update(rate_adjust_bytes.data(), rate_adjust_bytes.size());
29917 parameter_section_bytes += rate_adjust_bytes;
29918 command_size += rate_adjust_bytes.size();
29919 std::string command_hash(32, 0);
29920 hash->Finish(std::data(command_hash), command_hash.size());
29921 std::string authorization_section_bytes;
29922 std::string authorization_size_bytes;
29923 if (authorization_delegate) {
29924 if (!authorization_delegate->GetCommandAuthorization(
29925 command_hash, is_command_parameter_encryption_possible,
29926 is_response_parameter_encryption_possible,
29927 &authorization_section_bytes)) {
29928 return TRUNKS_RC_AUTHORIZATION_FAILED;
29929 }
29930 if (!authorization_section_bytes.empty()) {
29931 tag = TPM_ST_SESSIONS;
29932 std::string tmp;
29933 rc = Serialize_UINT32(authorization_section_bytes.size(),
29934 &authorization_size_bytes);
29935 if (rc != TPM_RC_SUCCESS) {
29936 return rc;
29937 }
29938 command_size +=
29939 authorization_size_bytes.size() + authorization_section_bytes.size();
29940 }
29941 }
29942 std::string tag_bytes;
29943 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29944 if (rc != TPM_RC_SUCCESS) {
29945 return rc;
29946 }
29947 std::string command_size_bytes;
29948 rc = Serialize_UINT32(command_size, &command_size_bytes);
29949 if (rc != TPM_RC_SUCCESS) {
29950 return rc;
29951 }
29952 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29953 handle_section_bytes + authorization_size_bytes +
29954 authorization_section_bytes + parameter_section_bytes;
29955 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29956 VLOG(2) << "Command: "
29957 << base::HexEncode(serialized_command->data(),
29958 serialized_command->size());
29959 return TPM_RC_SUCCESS;
29960 }
29961
ParseResponse_ClockRateAdjust(const std::string & response,AuthorizationDelegate * authorization_delegate)29962 TPM_RC Tpm::ParseResponse_ClockRateAdjust(
29963 const std::string& response,
29964 AuthorizationDelegate* authorization_delegate) {
29965 VLOG(3) << __func__;
29966 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29967 TPM_RC rc = TPM_RC_SUCCESS;
29968 std::string buffer(response);
29969 TPM_ST tag;
29970 std::string tag_bytes;
29971 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29972 if (rc != TPM_RC_SUCCESS) {
29973 return rc;
29974 }
29975 UINT32 response_size;
29976 std::string response_size_bytes;
29977 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29978 if (rc != TPM_RC_SUCCESS) {
29979 return rc;
29980 }
29981 TPM_RC response_code;
29982 std::string response_code_bytes;
29983 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29984 if (rc != TPM_RC_SUCCESS) {
29985 return rc;
29986 }
29987 if (response_size != response.size()) {
29988 return TPM_RC_SIZE;
29989 }
29990 if (response_code != TPM_RC_SUCCESS) {
29991 return response_code;
29992 }
29993 TPM_CC command_code = TPM_CC_ClockRateAdjust;
29994 std::string command_code_bytes;
29995 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29996 if (rc != TPM_RC_SUCCESS) {
29997 return rc;
29998 }
29999 std::string authorization_section_bytes;
30000 if (tag == TPM_ST_SESSIONS) {
30001 UINT32 parameter_section_size = buffer.size();
30002 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
30003 if (rc != TPM_RC_SUCCESS) {
30004 return rc;
30005 }
30006 if (parameter_section_size > buffer.size()) {
30007 return TPM_RC_INSUFFICIENT;
30008 }
30009 authorization_section_bytes = buffer.substr(parameter_section_size);
30010 // Keep the parameter section in |buffer|.
30011 buffer.erase(parameter_section_size);
30012 }
30013 std::unique_ptr<crypto::SecureHash> hash(
30014 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30015 hash->Update(response_code_bytes.data(), response_code_bytes.size());
30016 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30017 hash->Update(buffer.data(), buffer.size());
30018 std::string response_hash(32, 0);
30019 hash->Finish(std::data(response_hash), response_hash.size());
30020 if (tag == TPM_ST_SESSIONS) {
30021 if (!authorization_delegate)
30022 return TRUNKS_RC_AUTHORIZATION_FAILED;
30023 if (!authorization_delegate->CheckResponseAuthorization(
30024 response_hash, authorization_section_bytes)) {
30025 return TRUNKS_RC_AUTHORIZATION_FAILED;
30026 }
30027 }
30028 return TPM_RC_SUCCESS;
30029 }
30030
ClockRateAdjustErrorCallback(Tpm::ClockRateAdjustResponse callback,TPM_RC response_code)30031 void ClockRateAdjustErrorCallback(Tpm::ClockRateAdjustResponse callback,
30032 TPM_RC response_code) {
30033 VLOG(1) << __func__;
30034 std::move(callback).Run(response_code);
30035 }
30036
ClockRateAdjustResponseParser(Tpm::ClockRateAdjustResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30037 void ClockRateAdjustResponseParser(
30038 Tpm::ClockRateAdjustResponse callback,
30039 AuthorizationDelegate* authorization_delegate,
30040 const std::string& response) {
30041 VLOG(1) << __func__;
30042 TPM_RC rc =
30043 Tpm::ParseResponse_ClockRateAdjust(response, authorization_delegate);
30044 if (rc != TPM_RC_SUCCESS) {
30045 base::OnceCallback<void(TPM_RC)> error_reporter =
30046 base::BindOnce(ClockRateAdjustErrorCallback, std::move(callback));
30047 std::move(error_reporter).Run(rc);
30048 return;
30049 }
30050 std::move(callback).Run(rc);
30051 }
30052
ClockRateAdjust(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,AuthorizationDelegate * authorization_delegate,ClockRateAdjustResponse callback)30053 void Tpm::ClockRateAdjust(const TPMI_RH_PROVISION& auth,
30054 const std::string& auth_name,
30055 const TPM_CLOCK_ADJUST& rate_adjust,
30056 AuthorizationDelegate* authorization_delegate,
30057 ClockRateAdjustResponse callback) {
30058 VLOG(1) << __func__;
30059 std::string command;
30060 TPM_RC rc = SerializeCommand_ClockRateAdjust(
30061 auth, auth_name, rate_adjust, &command, authorization_delegate);
30062 if (rc != TPM_RC_SUCCESS) {
30063 base::OnceCallback<void(TPM_RC)> error_reporter =
30064 base::BindOnce(ClockRateAdjustErrorCallback, std::move(callback));
30065 std::move(error_reporter).Run(rc);
30066 return;
30067 }
30068 base::OnceCallback<void(const std::string&)> parser =
30069 base::BindOnce(ClockRateAdjustResponseParser, std::move(callback),
30070 authorization_delegate);
30071 transceiver_->SendCommand(command, std::move(parser));
30072 }
30073
ClockRateAdjustSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,AuthorizationDelegate * authorization_delegate)30074 TPM_RC Tpm::ClockRateAdjustSync(const TPMI_RH_PROVISION& auth,
30075 const std::string& auth_name,
30076 const TPM_CLOCK_ADJUST& rate_adjust,
30077 AuthorizationDelegate* authorization_delegate) {
30078 VLOG(1) << __func__;
30079 std::string command;
30080 TPM_RC rc = SerializeCommand_ClockRateAdjust(
30081 auth, auth_name, rate_adjust, &command, authorization_delegate);
30082 if (rc != TPM_RC_SUCCESS) {
30083 return rc;
30084 }
30085 std::string response = transceiver_->SendCommandAndWait(command);
30086 rc = ParseResponse_ClockRateAdjust(response, authorization_delegate);
30087 return rc;
30088 }
30089
SerializeCommand_GetCapability(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30090 TPM_RC Tpm::SerializeCommand_GetCapability(
30091 const TPM_CAP& capability,
30092 const UINT32& property,
30093 const UINT32& property_count,
30094 std::string* serialized_command,
30095 AuthorizationDelegate* authorization_delegate) {
30096 VLOG(3) << __func__;
30097 TPM_RC rc = TPM_RC_SUCCESS;
30098 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30099 UINT32 command_size = 10; // Header size.
30100 std::string handle_section_bytes;
30101 std::string parameter_section_bytes;
30102 TPM_CC command_code = TPM_CC_GetCapability;
30103 bool is_command_parameter_encryption_possible = false;
30104 bool is_response_parameter_encryption_possible = false;
30105 std::string command_code_bytes;
30106 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30107 if (rc != TPM_RC_SUCCESS) {
30108 return rc;
30109 }
30110 std::string capability_bytes;
30111 rc = Serialize_TPM_CAP(capability, &capability_bytes);
30112 if (rc != TPM_RC_SUCCESS) {
30113 return rc;
30114 }
30115 std::string property_bytes;
30116 rc = Serialize_UINT32(property, &property_bytes);
30117 if (rc != TPM_RC_SUCCESS) {
30118 return rc;
30119 }
30120 std::string property_count_bytes;
30121 rc = Serialize_UINT32(property_count, &property_count_bytes);
30122 if (rc != TPM_RC_SUCCESS) {
30123 return rc;
30124 }
30125 std::unique_ptr<crypto::SecureHash> hash(
30126 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30127 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30128 hash->Update(capability_bytes.data(), capability_bytes.size());
30129 parameter_section_bytes += capability_bytes;
30130 command_size += capability_bytes.size();
30131 hash->Update(property_bytes.data(), property_bytes.size());
30132 parameter_section_bytes += property_bytes;
30133 command_size += property_bytes.size();
30134 hash->Update(property_count_bytes.data(), property_count_bytes.size());
30135 parameter_section_bytes += property_count_bytes;
30136 command_size += property_count_bytes.size();
30137 std::string command_hash(32, 0);
30138 hash->Finish(std::data(command_hash), command_hash.size());
30139 std::string authorization_section_bytes;
30140 std::string authorization_size_bytes;
30141 if (authorization_delegate) {
30142 if (!authorization_delegate->GetCommandAuthorization(
30143 command_hash, is_command_parameter_encryption_possible,
30144 is_response_parameter_encryption_possible,
30145 &authorization_section_bytes)) {
30146 return TRUNKS_RC_AUTHORIZATION_FAILED;
30147 }
30148 if (!authorization_section_bytes.empty()) {
30149 tag = TPM_ST_SESSIONS;
30150 std::string tmp;
30151 rc = Serialize_UINT32(authorization_section_bytes.size(),
30152 &authorization_size_bytes);
30153 if (rc != TPM_RC_SUCCESS) {
30154 return rc;
30155 }
30156 command_size +=
30157 authorization_size_bytes.size() + authorization_section_bytes.size();
30158 }
30159 }
30160 std::string tag_bytes;
30161 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30162 if (rc != TPM_RC_SUCCESS) {
30163 return rc;
30164 }
30165 std::string command_size_bytes;
30166 rc = Serialize_UINT32(command_size, &command_size_bytes);
30167 if (rc != TPM_RC_SUCCESS) {
30168 return rc;
30169 }
30170 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30171 handle_section_bytes + authorization_size_bytes +
30172 authorization_section_bytes + parameter_section_bytes;
30173 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30174 VLOG(2) << "Command: "
30175 << base::HexEncode(serialized_command->data(),
30176 serialized_command->size());
30177 return TPM_RC_SUCCESS;
30178 }
30179
ParseResponse_GetCapability(const std::string & response,TPMI_YES_NO * more_data,TPMS_CAPABILITY_DATA * capability_data,AuthorizationDelegate * authorization_delegate)30180 TPM_RC Tpm::ParseResponse_GetCapability(
30181 const std::string& response,
30182 TPMI_YES_NO* more_data,
30183 TPMS_CAPABILITY_DATA* capability_data,
30184 AuthorizationDelegate* authorization_delegate) {
30185 VLOG(3) << __func__;
30186 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30187 TPM_RC rc = TPM_RC_SUCCESS;
30188 std::string buffer(response);
30189 TPM_ST tag;
30190 std::string tag_bytes;
30191 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30192 if (rc != TPM_RC_SUCCESS) {
30193 return rc;
30194 }
30195 UINT32 response_size;
30196 std::string response_size_bytes;
30197 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30198 if (rc != TPM_RC_SUCCESS) {
30199 return rc;
30200 }
30201 TPM_RC response_code;
30202 std::string response_code_bytes;
30203 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30204 if (rc != TPM_RC_SUCCESS) {
30205 return rc;
30206 }
30207 if (response_size != response.size()) {
30208 return TPM_RC_SIZE;
30209 }
30210 if (response_code != TPM_RC_SUCCESS) {
30211 return response_code;
30212 }
30213 TPM_CC command_code = TPM_CC_GetCapability;
30214 std::string command_code_bytes;
30215 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30216 if (rc != TPM_RC_SUCCESS) {
30217 return rc;
30218 }
30219 std::string authorization_section_bytes;
30220 if (tag == TPM_ST_SESSIONS) {
30221 UINT32 parameter_section_size = buffer.size();
30222 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
30223 if (rc != TPM_RC_SUCCESS) {
30224 return rc;
30225 }
30226 if (parameter_section_size > buffer.size()) {
30227 return TPM_RC_INSUFFICIENT;
30228 }
30229 authorization_section_bytes = buffer.substr(parameter_section_size);
30230 // Keep the parameter section in |buffer|.
30231 buffer.erase(parameter_section_size);
30232 }
30233 std::unique_ptr<crypto::SecureHash> hash(
30234 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30235 hash->Update(response_code_bytes.data(), response_code_bytes.size());
30236 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30237 hash->Update(buffer.data(), buffer.size());
30238 std::string response_hash(32, 0);
30239 hash->Finish(std::data(response_hash), response_hash.size());
30240 if (tag == TPM_ST_SESSIONS) {
30241 if (!authorization_delegate)
30242 return TRUNKS_RC_AUTHORIZATION_FAILED;
30243 if (!authorization_delegate->CheckResponseAuthorization(
30244 response_hash, authorization_section_bytes)) {
30245 return TRUNKS_RC_AUTHORIZATION_FAILED;
30246 }
30247 }
30248 std::string more_data_bytes;
30249 rc = Parse_TPMI_YES_NO(&buffer, more_data, &more_data_bytes);
30250 if (rc != TPM_RC_SUCCESS) {
30251 return rc;
30252 }
30253 std::string capability_data_bytes;
30254 rc = Parse_TPMS_CAPABILITY_DATA(&buffer, capability_data,
30255 &capability_data_bytes);
30256 if (rc != TPM_RC_SUCCESS) {
30257 return rc;
30258 }
30259 return TPM_RC_SUCCESS;
30260 }
30261
GetCapabilityErrorCallback(Tpm::GetCapabilityResponse callback,TPM_RC response_code)30262 void GetCapabilityErrorCallback(Tpm::GetCapabilityResponse callback,
30263 TPM_RC response_code) {
30264 VLOG(1) << __func__;
30265 std::move(callback).Run(response_code, TPMI_YES_NO(), TPMS_CAPABILITY_DATA());
30266 }
30267
GetCapabilityResponseParser(Tpm::GetCapabilityResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30268 void GetCapabilityResponseParser(Tpm::GetCapabilityResponse callback,
30269 AuthorizationDelegate* authorization_delegate,
30270 const std::string& response) {
30271 VLOG(1) << __func__;
30272 TPMI_YES_NO more_data;
30273 TPMS_CAPABILITY_DATA capability_data;
30274 TPM_RC rc = Tpm::ParseResponse_GetCapability(
30275 response, &more_data, &capability_data, authorization_delegate);
30276 if (rc != TPM_RC_SUCCESS) {
30277 base::OnceCallback<void(TPM_RC)> error_reporter =
30278 base::BindOnce(GetCapabilityErrorCallback, std::move(callback));
30279 std::move(error_reporter).Run(rc);
30280 return;
30281 }
30282 std::move(callback).Run(rc, more_data, capability_data);
30283 }
30284
GetCapability(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,AuthorizationDelegate * authorization_delegate,GetCapabilityResponse callback)30285 void Tpm::GetCapability(const TPM_CAP& capability,
30286 const UINT32& property,
30287 const UINT32& property_count,
30288 AuthorizationDelegate* authorization_delegate,
30289 GetCapabilityResponse callback) {
30290 VLOG(1) << __func__;
30291 std::string command;
30292 TPM_RC rc = SerializeCommand_GetCapability(
30293 capability, property, property_count, &command, authorization_delegate);
30294 if (rc != TPM_RC_SUCCESS) {
30295 base::OnceCallback<void(TPM_RC)> error_reporter =
30296 base::BindOnce(GetCapabilityErrorCallback, std::move(callback));
30297 std::move(error_reporter).Run(rc);
30298 return;
30299 }
30300 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
30301 GetCapabilityResponseParser, std::move(callback), authorization_delegate);
30302 transceiver_->SendCommand(command, std::move(parser));
30303 }
30304
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)30305 TPM_RC Tpm::GetCapabilitySync(const TPM_CAP& capability,
30306 const UINT32& property,
30307 const UINT32& property_count,
30308 TPMI_YES_NO* more_data,
30309 TPMS_CAPABILITY_DATA* capability_data,
30310 AuthorizationDelegate* authorization_delegate) {
30311 VLOG(1) << __func__;
30312 std::string command;
30313 TPM_RC rc = SerializeCommand_GetCapability(
30314 capability, property, property_count, &command, authorization_delegate);
30315 if (rc != TPM_RC_SUCCESS) {
30316 return rc;
30317 }
30318 std::string response = transceiver_->SendCommandAndWait(command);
30319 rc = ParseResponse_GetCapability(response, more_data, capability_data,
30320 authorization_delegate);
30321 return rc;
30322 }
30323
SerializeCommand_TestParms(const TPMT_PUBLIC_PARMS & parameters,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30324 TPM_RC Tpm::SerializeCommand_TestParms(
30325 const TPMT_PUBLIC_PARMS& parameters,
30326 std::string* serialized_command,
30327 AuthorizationDelegate* authorization_delegate) {
30328 VLOG(3) << __func__;
30329 TPM_RC rc = TPM_RC_SUCCESS;
30330 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30331 UINT32 command_size = 10; // Header size.
30332 std::string handle_section_bytes;
30333 std::string parameter_section_bytes;
30334 TPM_CC command_code = TPM_CC_TestParms;
30335 bool is_command_parameter_encryption_possible = false;
30336 bool is_response_parameter_encryption_possible = false;
30337 std::string command_code_bytes;
30338 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30339 if (rc != TPM_RC_SUCCESS) {
30340 return rc;
30341 }
30342 std::string parameters_bytes;
30343 rc = Serialize_TPMT_PUBLIC_PARMS(parameters, ¶meters_bytes);
30344 if (rc != TPM_RC_SUCCESS) {
30345 return rc;
30346 }
30347 std::unique_ptr<crypto::SecureHash> hash(
30348 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30349 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30350 hash->Update(parameters_bytes.data(), parameters_bytes.size());
30351 parameter_section_bytes += parameters_bytes;
30352 command_size += parameters_bytes.size();
30353 std::string command_hash(32, 0);
30354 hash->Finish(std::data(command_hash), command_hash.size());
30355 std::string authorization_section_bytes;
30356 std::string authorization_size_bytes;
30357 if (authorization_delegate) {
30358 if (!authorization_delegate->GetCommandAuthorization(
30359 command_hash, is_command_parameter_encryption_possible,
30360 is_response_parameter_encryption_possible,
30361 &authorization_section_bytes)) {
30362 return TRUNKS_RC_AUTHORIZATION_FAILED;
30363 }
30364 if (!authorization_section_bytes.empty()) {
30365 tag = TPM_ST_SESSIONS;
30366 std::string tmp;
30367 rc = Serialize_UINT32(authorization_section_bytes.size(),
30368 &authorization_size_bytes);
30369 if (rc != TPM_RC_SUCCESS) {
30370 return rc;
30371 }
30372 command_size +=
30373 authorization_size_bytes.size() + authorization_section_bytes.size();
30374 }
30375 }
30376 std::string tag_bytes;
30377 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30378 if (rc != TPM_RC_SUCCESS) {
30379 return rc;
30380 }
30381 std::string command_size_bytes;
30382 rc = Serialize_UINT32(command_size, &command_size_bytes);
30383 if (rc != TPM_RC_SUCCESS) {
30384 return rc;
30385 }
30386 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30387 handle_section_bytes + authorization_size_bytes +
30388 authorization_section_bytes + parameter_section_bytes;
30389 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30390 VLOG(2) << "Command: "
30391 << base::HexEncode(serialized_command->data(),
30392 serialized_command->size());
30393 return TPM_RC_SUCCESS;
30394 }
30395
ParseResponse_TestParms(const std::string & response,AuthorizationDelegate * authorization_delegate)30396 TPM_RC Tpm::ParseResponse_TestParms(
30397 const std::string& response,
30398 AuthorizationDelegate* authorization_delegate) {
30399 VLOG(3) << __func__;
30400 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30401 TPM_RC rc = TPM_RC_SUCCESS;
30402 std::string buffer(response);
30403 TPM_ST tag;
30404 std::string tag_bytes;
30405 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30406 if (rc != TPM_RC_SUCCESS) {
30407 return rc;
30408 }
30409 UINT32 response_size;
30410 std::string response_size_bytes;
30411 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30412 if (rc != TPM_RC_SUCCESS) {
30413 return rc;
30414 }
30415 TPM_RC response_code;
30416 std::string response_code_bytes;
30417 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30418 if (rc != TPM_RC_SUCCESS) {
30419 return rc;
30420 }
30421 if (response_size != response.size()) {
30422 return TPM_RC_SIZE;
30423 }
30424 if (response_code != TPM_RC_SUCCESS) {
30425 return response_code;
30426 }
30427 TPM_CC command_code = TPM_CC_TestParms;
30428 std::string command_code_bytes;
30429 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30430 if (rc != TPM_RC_SUCCESS) {
30431 return rc;
30432 }
30433 std::string authorization_section_bytes;
30434 if (tag == TPM_ST_SESSIONS) {
30435 UINT32 parameter_section_size = buffer.size();
30436 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
30437 if (rc != TPM_RC_SUCCESS) {
30438 return rc;
30439 }
30440 if (parameter_section_size > buffer.size()) {
30441 return TPM_RC_INSUFFICIENT;
30442 }
30443 authorization_section_bytes = buffer.substr(parameter_section_size);
30444 // Keep the parameter section in |buffer|.
30445 buffer.erase(parameter_section_size);
30446 }
30447 std::unique_ptr<crypto::SecureHash> hash(
30448 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30449 hash->Update(response_code_bytes.data(), response_code_bytes.size());
30450 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30451 hash->Update(buffer.data(), buffer.size());
30452 std::string response_hash(32, 0);
30453 hash->Finish(std::data(response_hash), response_hash.size());
30454 if (tag == TPM_ST_SESSIONS) {
30455 if (!authorization_delegate)
30456 return TRUNKS_RC_AUTHORIZATION_FAILED;
30457 if (!authorization_delegate->CheckResponseAuthorization(
30458 response_hash, authorization_section_bytes)) {
30459 return TRUNKS_RC_AUTHORIZATION_FAILED;
30460 }
30461 }
30462 return TPM_RC_SUCCESS;
30463 }
30464
TestParmsErrorCallback(Tpm::TestParmsResponse callback,TPM_RC response_code)30465 void TestParmsErrorCallback(Tpm::TestParmsResponse callback,
30466 TPM_RC response_code) {
30467 VLOG(1) << __func__;
30468 std::move(callback).Run(response_code);
30469 }
30470
TestParmsResponseParser(Tpm::TestParmsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30471 void TestParmsResponseParser(Tpm::TestParmsResponse callback,
30472 AuthorizationDelegate* authorization_delegate,
30473 const std::string& response) {
30474 VLOG(1) << __func__;
30475 TPM_RC rc = Tpm::ParseResponse_TestParms(response, authorization_delegate);
30476 if (rc != TPM_RC_SUCCESS) {
30477 base::OnceCallback<void(TPM_RC)> error_reporter =
30478 base::BindOnce(TestParmsErrorCallback, std::move(callback));
30479 std::move(error_reporter).Run(rc);
30480 return;
30481 }
30482 std::move(callback).Run(rc);
30483 }
30484
TestParms(const TPMT_PUBLIC_PARMS & parameters,AuthorizationDelegate * authorization_delegate,TestParmsResponse callback)30485 void Tpm::TestParms(const TPMT_PUBLIC_PARMS& parameters,
30486 AuthorizationDelegate* authorization_delegate,
30487 TestParmsResponse callback) {
30488 VLOG(1) << __func__;
30489 std::string command;
30490 TPM_RC rc =
30491 SerializeCommand_TestParms(parameters, &command, authorization_delegate);
30492 if (rc != TPM_RC_SUCCESS) {
30493 base::OnceCallback<void(TPM_RC)> error_reporter =
30494 base::BindOnce(TestParmsErrorCallback, std::move(callback));
30495 std::move(error_reporter).Run(rc);
30496 return;
30497 }
30498 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
30499 TestParmsResponseParser, std::move(callback), authorization_delegate);
30500 transceiver_->SendCommand(command, std::move(parser));
30501 }
30502
TestParmsSync(const TPMT_PUBLIC_PARMS & parameters,AuthorizationDelegate * authorization_delegate)30503 TPM_RC Tpm::TestParmsSync(const TPMT_PUBLIC_PARMS& parameters,
30504 AuthorizationDelegate* authorization_delegate) {
30505 VLOG(1) << __func__;
30506 std::string command;
30507 TPM_RC rc =
30508 SerializeCommand_TestParms(parameters, &command, authorization_delegate);
30509 if (rc != TPM_RC_SUCCESS) {
30510 return rc;
30511 }
30512 std::string response = transceiver_->SendCommandAndWait(command);
30513 rc = ParseResponse_TestParms(response, authorization_delegate);
30514 return rc;
30515 }
30516
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)30517 TPM_RC Tpm::SerializeCommand_NV_DefineSpace(
30518 const TPMI_RH_PROVISION& auth_handle,
30519 const std::string& auth_handle_name,
30520 const TPM2B_AUTH& auth,
30521 const TPM2B_NV_PUBLIC& public_info,
30522 std::string* serialized_command,
30523 AuthorizationDelegate* authorization_delegate) {
30524 VLOG(3) << __func__;
30525 TPM_RC rc = TPM_RC_SUCCESS;
30526 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30527 UINT32 command_size = 10; // Header size.
30528 std::string handle_section_bytes;
30529 std::string parameter_section_bytes;
30530 TPM_CC command_code = TPM_CC_NV_DefineSpace;
30531 bool is_command_parameter_encryption_possible = true;
30532 bool is_response_parameter_encryption_possible = false;
30533 std::string command_code_bytes;
30534 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30535 if (rc != TPM_RC_SUCCESS) {
30536 return rc;
30537 }
30538 std::string auth_handle_bytes;
30539 rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
30540 if (rc != TPM_RC_SUCCESS) {
30541 return rc;
30542 }
30543 std::string auth_bytes;
30544 rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
30545 if (rc != TPM_RC_SUCCESS) {
30546 return rc;
30547 }
30548 std::string public_info_bytes;
30549 rc = Serialize_TPM2B_NV_PUBLIC(public_info, &public_info_bytes);
30550 if (rc != TPM_RC_SUCCESS) {
30551 return rc;
30552 }
30553 if (authorization_delegate) {
30554 // Encrypt just the parameter data, not the size.
30555 std::string tmp = auth_bytes.substr(2);
30556 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
30557 return TRUNKS_RC_ENCRYPTION_FAILED;
30558 }
30559 auth_bytes.replace(2, std::string::npos, tmp);
30560 }
30561 std::unique_ptr<crypto::SecureHash> hash(
30562 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30563 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30564 hash->Update(auth_handle_name.data(), auth_handle_name.size());
30565 handle_section_bytes += auth_handle_bytes;
30566 command_size += auth_handle_bytes.size();
30567 hash->Update(auth_bytes.data(), auth_bytes.size());
30568 parameter_section_bytes += auth_bytes;
30569 command_size += auth_bytes.size();
30570 hash->Update(public_info_bytes.data(), public_info_bytes.size());
30571 parameter_section_bytes += public_info_bytes;
30572 command_size += public_info_bytes.size();
30573 std::string command_hash(32, 0);
30574 hash->Finish(std::data(command_hash), command_hash.size());
30575 std::string authorization_section_bytes;
30576 std::string authorization_size_bytes;
30577 if (authorization_delegate) {
30578 if (!authorization_delegate->GetCommandAuthorization(
30579 command_hash, is_command_parameter_encryption_possible,
30580 is_response_parameter_encryption_possible,
30581 &authorization_section_bytes)) {
30582 return TRUNKS_RC_AUTHORIZATION_FAILED;
30583 }
30584 if (!authorization_section_bytes.empty()) {
30585 tag = TPM_ST_SESSIONS;
30586 std::string tmp;
30587 rc = Serialize_UINT32(authorization_section_bytes.size(),
30588 &authorization_size_bytes);
30589 if (rc != TPM_RC_SUCCESS) {
30590 return rc;
30591 }
30592 command_size +=
30593 authorization_size_bytes.size() + authorization_section_bytes.size();
30594 }
30595 }
30596 std::string tag_bytes;
30597 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30598 if (rc != TPM_RC_SUCCESS) {
30599 return rc;
30600 }
30601 std::string command_size_bytes;
30602 rc = Serialize_UINT32(command_size, &command_size_bytes);
30603 if (rc != TPM_RC_SUCCESS) {
30604 return rc;
30605 }
30606 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30607 handle_section_bytes + authorization_size_bytes +
30608 authorization_section_bytes + parameter_section_bytes;
30609 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30610 VLOG(2) << "Command: "
30611 << base::HexEncode(serialized_command->data(),
30612 serialized_command->size());
30613 return TPM_RC_SUCCESS;
30614 }
30615
ParseResponse_NV_DefineSpace(const std::string & response,AuthorizationDelegate * authorization_delegate)30616 TPM_RC Tpm::ParseResponse_NV_DefineSpace(
30617 const std::string& response,
30618 AuthorizationDelegate* authorization_delegate) {
30619 VLOG(3) << __func__;
30620 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30621 TPM_RC rc = TPM_RC_SUCCESS;
30622 std::string buffer(response);
30623 TPM_ST tag;
30624 std::string tag_bytes;
30625 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30626 if (rc != TPM_RC_SUCCESS) {
30627 return rc;
30628 }
30629 UINT32 response_size;
30630 std::string response_size_bytes;
30631 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30632 if (rc != TPM_RC_SUCCESS) {
30633 return rc;
30634 }
30635 TPM_RC response_code;
30636 std::string response_code_bytes;
30637 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30638 if (rc != TPM_RC_SUCCESS) {
30639 return rc;
30640 }
30641 if (response_size != response.size()) {
30642 return TPM_RC_SIZE;
30643 }
30644 if (response_code != TPM_RC_SUCCESS) {
30645 return response_code;
30646 }
30647 TPM_CC command_code = TPM_CC_NV_DefineSpace;
30648 std::string command_code_bytes;
30649 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30650 if (rc != TPM_RC_SUCCESS) {
30651 return rc;
30652 }
30653 std::string authorization_section_bytes;
30654 if (tag == TPM_ST_SESSIONS) {
30655 UINT32 parameter_section_size = buffer.size();
30656 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
30657 if (rc != TPM_RC_SUCCESS) {
30658 return rc;
30659 }
30660 if (parameter_section_size > buffer.size()) {
30661 return TPM_RC_INSUFFICIENT;
30662 }
30663 authorization_section_bytes = buffer.substr(parameter_section_size);
30664 // Keep the parameter section in |buffer|.
30665 buffer.erase(parameter_section_size);
30666 }
30667 std::unique_ptr<crypto::SecureHash> hash(
30668 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30669 hash->Update(response_code_bytes.data(), response_code_bytes.size());
30670 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30671 hash->Update(buffer.data(), buffer.size());
30672 std::string response_hash(32, 0);
30673 hash->Finish(std::data(response_hash), response_hash.size());
30674 if (tag == TPM_ST_SESSIONS) {
30675 if (!authorization_delegate)
30676 return TRUNKS_RC_AUTHORIZATION_FAILED;
30677 if (!authorization_delegate->CheckResponseAuthorization(
30678 response_hash, authorization_section_bytes)) {
30679 return TRUNKS_RC_AUTHORIZATION_FAILED;
30680 }
30681 }
30682 return TPM_RC_SUCCESS;
30683 }
30684
NV_DefineSpaceErrorCallback(Tpm::NV_DefineSpaceResponse callback,TPM_RC response_code)30685 void NV_DefineSpaceErrorCallback(Tpm::NV_DefineSpaceResponse callback,
30686 TPM_RC response_code) {
30687 VLOG(1) << __func__;
30688 std::move(callback).Run(response_code);
30689 }
30690
NV_DefineSpaceResponseParser(Tpm::NV_DefineSpaceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30691 void NV_DefineSpaceResponseParser(Tpm::NV_DefineSpaceResponse callback,
30692 AuthorizationDelegate* authorization_delegate,
30693 const std::string& response) {
30694 VLOG(1) << __func__;
30695 TPM_RC rc =
30696 Tpm::ParseResponse_NV_DefineSpace(response, authorization_delegate);
30697 if (rc != TPM_RC_SUCCESS) {
30698 base::OnceCallback<void(TPM_RC)> error_reporter =
30699 base::BindOnce(NV_DefineSpaceErrorCallback, std::move(callback));
30700 std::move(error_reporter).Run(rc);
30701 return;
30702 }
30703 std::move(callback).Run(rc);
30704 }
30705
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)30706 void Tpm::NV_DefineSpace(const TPMI_RH_PROVISION& auth_handle,
30707 const std::string& auth_handle_name,
30708 const TPM2B_AUTH& auth,
30709 const TPM2B_NV_PUBLIC& public_info,
30710 AuthorizationDelegate* authorization_delegate,
30711 NV_DefineSpaceResponse callback) {
30712 VLOG(1) << __func__;
30713 std::string command;
30714 TPM_RC rc = SerializeCommand_NV_DefineSpace(auth_handle, auth_handle_name,
30715 auth, public_info, &command,
30716 authorization_delegate);
30717 if (rc != TPM_RC_SUCCESS) {
30718 base::OnceCallback<void(TPM_RC)> error_reporter =
30719 base::BindOnce(NV_DefineSpaceErrorCallback, std::move(callback));
30720 std::move(error_reporter).Run(rc);
30721 return;
30722 }
30723 base::OnceCallback<void(const std::string&)> parser =
30724 base::BindOnce(NV_DefineSpaceResponseParser, std::move(callback),
30725 authorization_delegate);
30726 transceiver_->SendCommand(command, std::move(parser));
30727 }
30728
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)30729 TPM_RC Tpm::NV_DefineSpaceSync(const TPMI_RH_PROVISION& auth_handle,
30730 const std::string& auth_handle_name,
30731 const TPM2B_AUTH& auth,
30732 const TPM2B_NV_PUBLIC& public_info,
30733 AuthorizationDelegate* authorization_delegate) {
30734 VLOG(1) << __func__;
30735 std::string command;
30736 TPM_RC rc = SerializeCommand_NV_DefineSpace(auth_handle, auth_handle_name,
30737 auth, public_info, &command,
30738 authorization_delegate);
30739 if (rc != TPM_RC_SUCCESS) {
30740 return rc;
30741 }
30742 std::string response = transceiver_->SendCommandAndWait(command);
30743 rc = ParseResponse_NV_DefineSpace(response, authorization_delegate);
30744 return rc;
30745 }
30746
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)30747 TPM_RC Tpm::SerializeCommand_NV_UndefineSpace(
30748 const TPMI_RH_PROVISION& auth_handle,
30749 const std::string& auth_handle_name,
30750 const TPMI_RH_NV_INDEX& nv_index,
30751 const std::string& nv_index_name,
30752 std::string* serialized_command,
30753 AuthorizationDelegate* authorization_delegate) {
30754 VLOG(3) << __func__;
30755 TPM_RC rc = TPM_RC_SUCCESS;
30756 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30757 UINT32 command_size = 10; // Header size.
30758 std::string handle_section_bytes;
30759 std::string parameter_section_bytes;
30760 TPM_CC command_code = TPM_CC_NV_UndefineSpace;
30761 bool is_command_parameter_encryption_possible = false;
30762 bool is_response_parameter_encryption_possible = false;
30763 std::string command_code_bytes;
30764 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30765 if (rc != TPM_RC_SUCCESS) {
30766 return rc;
30767 }
30768 std::string auth_handle_bytes;
30769 rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
30770 if (rc != TPM_RC_SUCCESS) {
30771 return rc;
30772 }
30773 std::string nv_index_bytes;
30774 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30775 if (rc != TPM_RC_SUCCESS) {
30776 return rc;
30777 }
30778 std::unique_ptr<crypto::SecureHash> hash(
30779 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30780 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30781 hash->Update(auth_handle_name.data(), auth_handle_name.size());
30782 handle_section_bytes += auth_handle_bytes;
30783 command_size += auth_handle_bytes.size();
30784 hash->Update(nv_index_name.data(), nv_index_name.size());
30785 handle_section_bytes += nv_index_bytes;
30786 command_size += nv_index_bytes.size();
30787 std::string command_hash(32, 0);
30788 hash->Finish(std::data(command_hash), command_hash.size());
30789 std::string authorization_section_bytes;
30790 std::string authorization_size_bytes;
30791 if (authorization_delegate) {
30792 if (!authorization_delegate->GetCommandAuthorization(
30793 command_hash, is_command_parameter_encryption_possible,
30794 is_response_parameter_encryption_possible,
30795 &authorization_section_bytes)) {
30796 return TRUNKS_RC_AUTHORIZATION_FAILED;
30797 }
30798 if (!authorization_section_bytes.empty()) {
30799 tag = TPM_ST_SESSIONS;
30800 std::string tmp;
30801 rc = Serialize_UINT32(authorization_section_bytes.size(),
30802 &authorization_size_bytes);
30803 if (rc != TPM_RC_SUCCESS) {
30804 return rc;
30805 }
30806 command_size +=
30807 authorization_size_bytes.size() + authorization_section_bytes.size();
30808 }
30809 }
30810 std::string tag_bytes;
30811 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30812 if (rc != TPM_RC_SUCCESS) {
30813 return rc;
30814 }
30815 std::string command_size_bytes;
30816 rc = Serialize_UINT32(command_size, &command_size_bytes);
30817 if (rc != TPM_RC_SUCCESS) {
30818 return rc;
30819 }
30820 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30821 handle_section_bytes + authorization_size_bytes +
30822 authorization_section_bytes + parameter_section_bytes;
30823 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30824 VLOG(2) << "Command: "
30825 << base::HexEncode(serialized_command->data(),
30826 serialized_command->size());
30827 return TPM_RC_SUCCESS;
30828 }
30829
ParseResponse_NV_UndefineSpace(const std::string & response,AuthorizationDelegate * authorization_delegate)30830 TPM_RC Tpm::ParseResponse_NV_UndefineSpace(
30831 const std::string& response,
30832 AuthorizationDelegate* authorization_delegate) {
30833 VLOG(3) << __func__;
30834 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30835 TPM_RC rc = TPM_RC_SUCCESS;
30836 std::string buffer(response);
30837 TPM_ST tag;
30838 std::string tag_bytes;
30839 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30840 if (rc != TPM_RC_SUCCESS) {
30841 return rc;
30842 }
30843 UINT32 response_size;
30844 std::string response_size_bytes;
30845 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30846 if (rc != TPM_RC_SUCCESS) {
30847 return rc;
30848 }
30849 TPM_RC response_code;
30850 std::string response_code_bytes;
30851 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30852 if (rc != TPM_RC_SUCCESS) {
30853 return rc;
30854 }
30855 if (response_size != response.size()) {
30856 return TPM_RC_SIZE;
30857 }
30858 if (response_code != TPM_RC_SUCCESS) {
30859 return response_code;
30860 }
30861 TPM_CC command_code = TPM_CC_NV_UndefineSpace;
30862 std::string command_code_bytes;
30863 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30864 if (rc != TPM_RC_SUCCESS) {
30865 return rc;
30866 }
30867 std::string authorization_section_bytes;
30868 if (tag == TPM_ST_SESSIONS) {
30869 UINT32 parameter_section_size = buffer.size();
30870 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
30871 if (rc != TPM_RC_SUCCESS) {
30872 return rc;
30873 }
30874 if (parameter_section_size > buffer.size()) {
30875 return TPM_RC_INSUFFICIENT;
30876 }
30877 authorization_section_bytes = buffer.substr(parameter_section_size);
30878 // Keep the parameter section in |buffer|.
30879 buffer.erase(parameter_section_size);
30880 }
30881 std::unique_ptr<crypto::SecureHash> hash(
30882 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30883 hash->Update(response_code_bytes.data(), response_code_bytes.size());
30884 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30885 hash->Update(buffer.data(), buffer.size());
30886 std::string response_hash(32, 0);
30887 hash->Finish(std::data(response_hash), response_hash.size());
30888 if (tag == TPM_ST_SESSIONS) {
30889 if (!authorization_delegate)
30890 return TRUNKS_RC_AUTHORIZATION_FAILED;
30891 if (!authorization_delegate->CheckResponseAuthorization(
30892 response_hash, authorization_section_bytes)) {
30893 return TRUNKS_RC_AUTHORIZATION_FAILED;
30894 }
30895 }
30896 return TPM_RC_SUCCESS;
30897 }
30898
NV_UndefineSpaceErrorCallback(Tpm::NV_UndefineSpaceResponse callback,TPM_RC response_code)30899 void NV_UndefineSpaceErrorCallback(Tpm::NV_UndefineSpaceResponse callback,
30900 TPM_RC response_code) {
30901 VLOG(1) << __func__;
30902 std::move(callback).Run(response_code);
30903 }
30904
NV_UndefineSpaceResponseParser(Tpm::NV_UndefineSpaceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30905 void NV_UndefineSpaceResponseParser(
30906 Tpm::NV_UndefineSpaceResponse callback,
30907 AuthorizationDelegate* authorization_delegate,
30908 const std::string& response) {
30909 VLOG(1) << __func__;
30910 TPM_RC rc =
30911 Tpm::ParseResponse_NV_UndefineSpace(response, authorization_delegate);
30912 if (rc != TPM_RC_SUCCESS) {
30913 base::OnceCallback<void(TPM_RC)> error_reporter =
30914 base::BindOnce(NV_UndefineSpaceErrorCallback, std::move(callback));
30915 std::move(error_reporter).Run(rc);
30916 return;
30917 }
30918 std::move(callback).Run(rc);
30919 }
30920
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)30921 void Tpm::NV_UndefineSpace(const TPMI_RH_PROVISION& auth_handle,
30922 const std::string& auth_handle_name,
30923 const TPMI_RH_NV_INDEX& nv_index,
30924 const std::string& nv_index_name,
30925 AuthorizationDelegate* authorization_delegate,
30926 NV_UndefineSpaceResponse callback) {
30927 VLOG(1) << __func__;
30928 std::string command;
30929 TPM_RC rc = SerializeCommand_NV_UndefineSpace(
30930 auth_handle, auth_handle_name, nv_index, nv_index_name, &command,
30931 authorization_delegate);
30932 if (rc != TPM_RC_SUCCESS) {
30933 base::OnceCallback<void(TPM_RC)> error_reporter =
30934 base::BindOnce(NV_UndefineSpaceErrorCallback, std::move(callback));
30935 std::move(error_reporter).Run(rc);
30936 return;
30937 }
30938 base::OnceCallback<void(const std::string&)> parser =
30939 base::BindOnce(NV_UndefineSpaceResponseParser, std::move(callback),
30940 authorization_delegate);
30941 transceiver_->SendCommand(command, std::move(parser));
30942 }
30943
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)30944 TPM_RC Tpm::NV_UndefineSpaceSync(
30945 const TPMI_RH_PROVISION& auth_handle,
30946 const std::string& auth_handle_name,
30947 const TPMI_RH_NV_INDEX& nv_index,
30948 const std::string& nv_index_name,
30949 AuthorizationDelegate* authorization_delegate) {
30950 VLOG(1) << __func__;
30951 std::string command;
30952 TPM_RC rc = SerializeCommand_NV_UndefineSpace(
30953 auth_handle, auth_handle_name, nv_index, nv_index_name, &command,
30954 authorization_delegate);
30955 if (rc != TPM_RC_SUCCESS) {
30956 return rc;
30957 }
30958 std::string response = transceiver_->SendCommandAndWait(command);
30959 rc = ParseResponse_NV_UndefineSpace(response, authorization_delegate);
30960 return rc;
30961 }
30962
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)30963 TPM_RC Tpm::SerializeCommand_NV_UndefineSpaceSpecial(
30964 const TPMI_RH_NV_INDEX& nv_index,
30965 const std::string& nv_index_name,
30966 const TPMI_RH_PLATFORM& platform,
30967 const std::string& platform_name,
30968 std::string* serialized_command,
30969 AuthorizationDelegate* authorization_delegate) {
30970 VLOG(3) << __func__;
30971 TPM_RC rc = TPM_RC_SUCCESS;
30972 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30973 UINT32 command_size = 10; // Header size.
30974 std::string handle_section_bytes;
30975 std::string parameter_section_bytes;
30976 TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial;
30977 bool is_command_parameter_encryption_possible = false;
30978 bool is_response_parameter_encryption_possible = false;
30979 std::string command_code_bytes;
30980 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30981 if (rc != TPM_RC_SUCCESS) {
30982 return rc;
30983 }
30984 std::string nv_index_bytes;
30985 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30986 if (rc != TPM_RC_SUCCESS) {
30987 return rc;
30988 }
30989 std::string platform_bytes;
30990 rc = Serialize_TPMI_RH_PLATFORM(platform, &platform_bytes);
30991 if (rc != TPM_RC_SUCCESS) {
30992 return rc;
30993 }
30994 std::unique_ptr<crypto::SecureHash> hash(
30995 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30996 hash->Update(command_code_bytes.data(), command_code_bytes.size());
30997 hash->Update(nv_index_name.data(), nv_index_name.size());
30998 handle_section_bytes += nv_index_bytes;
30999 command_size += nv_index_bytes.size();
31000 hash->Update(platform_name.data(), platform_name.size());
31001 handle_section_bytes += platform_bytes;
31002 command_size += platform_bytes.size();
31003 std::string command_hash(32, 0);
31004 hash->Finish(std::data(command_hash), command_hash.size());
31005 std::string authorization_section_bytes;
31006 std::string authorization_size_bytes;
31007 if (authorization_delegate) {
31008 if (!authorization_delegate->GetCommandAuthorization(
31009 command_hash, is_command_parameter_encryption_possible,
31010 is_response_parameter_encryption_possible,
31011 &authorization_section_bytes)) {
31012 return TRUNKS_RC_AUTHORIZATION_FAILED;
31013 }
31014 if (!authorization_section_bytes.empty()) {
31015 tag = TPM_ST_SESSIONS;
31016 std::string tmp;
31017 rc = Serialize_UINT32(authorization_section_bytes.size(),
31018 &authorization_size_bytes);
31019 if (rc != TPM_RC_SUCCESS) {
31020 return rc;
31021 }
31022 command_size +=
31023 authorization_size_bytes.size() + authorization_section_bytes.size();
31024 }
31025 }
31026 std::string tag_bytes;
31027 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31028 if (rc != TPM_RC_SUCCESS) {
31029 return rc;
31030 }
31031 std::string command_size_bytes;
31032 rc = Serialize_UINT32(command_size, &command_size_bytes);
31033 if (rc != TPM_RC_SUCCESS) {
31034 return rc;
31035 }
31036 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31037 handle_section_bytes + authorization_size_bytes +
31038 authorization_section_bytes + parameter_section_bytes;
31039 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31040 VLOG(2) << "Command: "
31041 << base::HexEncode(serialized_command->data(),
31042 serialized_command->size());
31043 return TPM_RC_SUCCESS;
31044 }
31045
ParseResponse_NV_UndefineSpaceSpecial(const std::string & response,AuthorizationDelegate * authorization_delegate)31046 TPM_RC Tpm::ParseResponse_NV_UndefineSpaceSpecial(
31047 const std::string& response,
31048 AuthorizationDelegate* authorization_delegate) {
31049 VLOG(3) << __func__;
31050 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31051 TPM_RC rc = TPM_RC_SUCCESS;
31052 std::string buffer(response);
31053 TPM_ST tag;
31054 std::string tag_bytes;
31055 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31056 if (rc != TPM_RC_SUCCESS) {
31057 return rc;
31058 }
31059 UINT32 response_size;
31060 std::string response_size_bytes;
31061 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31062 if (rc != TPM_RC_SUCCESS) {
31063 return rc;
31064 }
31065 TPM_RC response_code;
31066 std::string response_code_bytes;
31067 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31068 if (rc != TPM_RC_SUCCESS) {
31069 return rc;
31070 }
31071 if (response_size != response.size()) {
31072 return TPM_RC_SIZE;
31073 }
31074 if (response_code != TPM_RC_SUCCESS) {
31075 return response_code;
31076 }
31077 TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial;
31078 std::string command_code_bytes;
31079 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31080 if (rc != TPM_RC_SUCCESS) {
31081 return rc;
31082 }
31083 std::string authorization_section_bytes;
31084 if (tag == TPM_ST_SESSIONS) {
31085 UINT32 parameter_section_size = buffer.size();
31086 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
31087 if (rc != TPM_RC_SUCCESS) {
31088 return rc;
31089 }
31090 if (parameter_section_size > buffer.size()) {
31091 return TPM_RC_INSUFFICIENT;
31092 }
31093 authorization_section_bytes = buffer.substr(parameter_section_size);
31094 // Keep the parameter section in |buffer|.
31095 buffer.erase(parameter_section_size);
31096 }
31097 std::unique_ptr<crypto::SecureHash> hash(
31098 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31099 hash->Update(response_code_bytes.data(), response_code_bytes.size());
31100 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31101 hash->Update(buffer.data(), buffer.size());
31102 std::string response_hash(32, 0);
31103 hash->Finish(std::data(response_hash), response_hash.size());
31104 if (tag == TPM_ST_SESSIONS) {
31105 if (!authorization_delegate)
31106 return TRUNKS_RC_AUTHORIZATION_FAILED;
31107 if (!authorization_delegate->CheckResponseAuthorization(
31108 response_hash, authorization_section_bytes)) {
31109 return TRUNKS_RC_AUTHORIZATION_FAILED;
31110 }
31111 }
31112 return TPM_RC_SUCCESS;
31113 }
31114
NV_UndefineSpaceSpecialErrorCallback(Tpm::NV_UndefineSpaceSpecialResponse callback,TPM_RC response_code)31115 void NV_UndefineSpaceSpecialErrorCallback(
31116 Tpm::NV_UndefineSpaceSpecialResponse callback, TPM_RC response_code) {
31117 VLOG(1) << __func__;
31118 std::move(callback).Run(response_code);
31119 }
31120
NV_UndefineSpaceSpecialResponseParser(Tpm::NV_UndefineSpaceSpecialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31121 void NV_UndefineSpaceSpecialResponseParser(
31122 Tpm::NV_UndefineSpaceSpecialResponse callback,
31123 AuthorizationDelegate* authorization_delegate,
31124 const std::string& response) {
31125 VLOG(1) << __func__;
31126 TPM_RC rc = Tpm::ParseResponse_NV_UndefineSpaceSpecial(
31127 response, authorization_delegate);
31128 if (rc != TPM_RC_SUCCESS) {
31129 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
31130 NV_UndefineSpaceSpecialErrorCallback, std::move(callback));
31131 std::move(error_reporter).Run(rc);
31132 return;
31133 }
31134 std::move(callback).Run(rc);
31135 }
31136
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)31137 void Tpm::NV_UndefineSpaceSpecial(const TPMI_RH_NV_INDEX& nv_index,
31138 const std::string& nv_index_name,
31139 const TPMI_RH_PLATFORM& platform,
31140 const std::string& platform_name,
31141 AuthorizationDelegate* authorization_delegate,
31142 NV_UndefineSpaceSpecialResponse callback) {
31143 VLOG(1) << __func__;
31144 std::string command;
31145 TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial(
31146 nv_index, nv_index_name, platform, platform_name, &command,
31147 authorization_delegate);
31148 if (rc != TPM_RC_SUCCESS) {
31149 base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
31150 NV_UndefineSpaceSpecialErrorCallback, std::move(callback));
31151 std::move(error_reporter).Run(rc);
31152 return;
31153 }
31154 base::OnceCallback<void(const std::string&)> parser =
31155 base::BindOnce(NV_UndefineSpaceSpecialResponseParser, std::move(callback),
31156 authorization_delegate);
31157 transceiver_->SendCommand(command, std::move(parser));
31158 }
31159
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)31160 TPM_RC Tpm::NV_UndefineSpaceSpecialSync(
31161 const TPMI_RH_NV_INDEX& nv_index,
31162 const std::string& nv_index_name,
31163 const TPMI_RH_PLATFORM& platform,
31164 const std::string& platform_name,
31165 AuthorizationDelegate* authorization_delegate) {
31166 VLOG(1) << __func__;
31167 std::string command;
31168 TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial(
31169 nv_index, nv_index_name, platform, platform_name, &command,
31170 authorization_delegate);
31171 if (rc != TPM_RC_SUCCESS) {
31172 return rc;
31173 }
31174 std::string response = transceiver_->SendCommandAndWait(command);
31175 rc = ParseResponse_NV_UndefineSpaceSpecial(response, authorization_delegate);
31176 return rc;
31177 }
31178
SerializeCommand_NV_ReadPublic(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31179 TPM_RC Tpm::SerializeCommand_NV_ReadPublic(
31180 const TPMI_RH_NV_INDEX& nv_index,
31181 const std::string& nv_index_name,
31182 std::string* serialized_command,
31183 AuthorizationDelegate* authorization_delegate) {
31184 VLOG(3) << __func__;
31185 TPM_RC rc = TPM_RC_SUCCESS;
31186 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31187 UINT32 command_size = 10; // Header size.
31188 std::string handle_section_bytes;
31189 std::string parameter_section_bytes;
31190 TPM_CC command_code = TPM_CC_NV_ReadPublic;
31191 bool is_command_parameter_encryption_possible = false;
31192 bool is_response_parameter_encryption_possible = true;
31193 std::string command_code_bytes;
31194 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31195 if (rc != TPM_RC_SUCCESS) {
31196 return rc;
31197 }
31198 std::string nv_index_bytes;
31199 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31200 if (rc != TPM_RC_SUCCESS) {
31201 return rc;
31202 }
31203 std::unique_ptr<crypto::SecureHash> hash(
31204 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31205 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31206 hash->Update(nv_index_name.data(), nv_index_name.size());
31207 handle_section_bytes += nv_index_bytes;
31208 command_size += nv_index_bytes.size();
31209 std::string command_hash(32, 0);
31210 hash->Finish(std::data(command_hash), command_hash.size());
31211 std::string authorization_section_bytes;
31212 std::string authorization_size_bytes;
31213 if (authorization_delegate) {
31214 if (!authorization_delegate->GetCommandAuthorization(
31215 command_hash, is_command_parameter_encryption_possible,
31216 is_response_parameter_encryption_possible,
31217 &authorization_section_bytes)) {
31218 return TRUNKS_RC_AUTHORIZATION_FAILED;
31219 }
31220 if (!authorization_section_bytes.empty()) {
31221 tag = TPM_ST_SESSIONS;
31222 std::string tmp;
31223 rc = Serialize_UINT32(authorization_section_bytes.size(),
31224 &authorization_size_bytes);
31225 if (rc != TPM_RC_SUCCESS) {
31226 return rc;
31227 }
31228 command_size +=
31229 authorization_size_bytes.size() + authorization_section_bytes.size();
31230 }
31231 }
31232 std::string tag_bytes;
31233 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31234 if (rc != TPM_RC_SUCCESS) {
31235 return rc;
31236 }
31237 std::string command_size_bytes;
31238 rc = Serialize_UINT32(command_size, &command_size_bytes);
31239 if (rc != TPM_RC_SUCCESS) {
31240 return rc;
31241 }
31242 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31243 handle_section_bytes + authorization_size_bytes +
31244 authorization_section_bytes + parameter_section_bytes;
31245 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31246 VLOG(2) << "Command: "
31247 << base::HexEncode(serialized_command->data(),
31248 serialized_command->size());
31249 return TPM_RC_SUCCESS;
31250 }
31251
ParseResponse_NV_ReadPublic(const std::string & response,TPM2B_NV_PUBLIC * nv_public,TPM2B_NAME * nv_name,AuthorizationDelegate * authorization_delegate)31252 TPM_RC Tpm::ParseResponse_NV_ReadPublic(
31253 const std::string& response,
31254 TPM2B_NV_PUBLIC* nv_public,
31255 TPM2B_NAME* nv_name,
31256 AuthorizationDelegate* authorization_delegate) {
31257 VLOG(3) << __func__;
31258 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31259 TPM_RC rc = TPM_RC_SUCCESS;
31260 std::string buffer(response);
31261 TPM_ST tag;
31262 std::string tag_bytes;
31263 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31264 if (rc != TPM_RC_SUCCESS) {
31265 return rc;
31266 }
31267 UINT32 response_size;
31268 std::string response_size_bytes;
31269 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31270 if (rc != TPM_RC_SUCCESS) {
31271 return rc;
31272 }
31273 TPM_RC response_code;
31274 std::string response_code_bytes;
31275 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31276 if (rc != TPM_RC_SUCCESS) {
31277 return rc;
31278 }
31279 if (response_size != response.size()) {
31280 return TPM_RC_SIZE;
31281 }
31282 if (response_code != TPM_RC_SUCCESS) {
31283 return response_code;
31284 }
31285 TPM_CC command_code = TPM_CC_NV_ReadPublic;
31286 std::string command_code_bytes;
31287 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31288 if (rc != TPM_RC_SUCCESS) {
31289 return rc;
31290 }
31291 std::string authorization_section_bytes;
31292 if (tag == TPM_ST_SESSIONS) {
31293 UINT32 parameter_section_size = buffer.size();
31294 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
31295 if (rc != TPM_RC_SUCCESS) {
31296 return rc;
31297 }
31298 if (parameter_section_size > buffer.size()) {
31299 return TPM_RC_INSUFFICIENT;
31300 }
31301 authorization_section_bytes = buffer.substr(parameter_section_size);
31302 // Keep the parameter section in |buffer|.
31303 buffer.erase(parameter_section_size);
31304 }
31305 std::unique_ptr<crypto::SecureHash> hash(
31306 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31307 hash->Update(response_code_bytes.data(), response_code_bytes.size());
31308 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31309 hash->Update(buffer.data(), buffer.size());
31310 std::string response_hash(32, 0);
31311 hash->Finish(std::data(response_hash), response_hash.size());
31312 if (tag == TPM_ST_SESSIONS) {
31313 if (!authorization_delegate)
31314 return TRUNKS_RC_AUTHORIZATION_FAILED;
31315 if (!authorization_delegate->CheckResponseAuthorization(
31316 response_hash, authorization_section_bytes)) {
31317 return TRUNKS_RC_AUTHORIZATION_FAILED;
31318 }
31319 }
31320 if (tag == TPM_ST_SESSIONS) {
31321 if (!authorization_delegate)
31322 return TRUNKS_RC_AUTHORIZATION_FAILED;
31323
31324 // Parse the encrypted parameter size.
31325 UINT16 size;
31326 std::string size_buffer = buffer.substr(0, 2);
31327 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
31328 return result;
31329 }
31330 if (buffer.size() < 2 + size) {
31331 return TPM_RC_INSUFFICIENT;
31332 }
31333
31334 // Decrypt just the parameter data, not the size.
31335 std::string decrypted_data = buffer.substr(2, size);
31336 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
31337 return TRUNKS_RC_ENCRYPTION_FAILED;
31338 }
31339 buffer.replace(2, size, decrypted_data);
31340 }
31341 std::string nv_public_bytes;
31342 rc = Parse_TPM2B_NV_PUBLIC(&buffer, nv_public, &nv_public_bytes);
31343 if (rc != TPM_RC_SUCCESS) {
31344 return rc;
31345 }
31346 std::string nv_name_bytes;
31347 rc = Parse_TPM2B_NAME(&buffer, nv_name, &nv_name_bytes);
31348 if (rc != TPM_RC_SUCCESS) {
31349 return rc;
31350 }
31351 return TPM_RC_SUCCESS;
31352 }
31353
NV_ReadPublicErrorCallback(Tpm::NV_ReadPublicResponse callback,TPM_RC response_code)31354 void NV_ReadPublicErrorCallback(Tpm::NV_ReadPublicResponse callback,
31355 TPM_RC response_code) {
31356 VLOG(1) << __func__;
31357 std::move(callback).Run(response_code, TPM2B_NV_PUBLIC(), TPM2B_NAME());
31358 }
31359
NV_ReadPublicResponseParser(Tpm::NV_ReadPublicResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31360 void NV_ReadPublicResponseParser(Tpm::NV_ReadPublicResponse callback,
31361 AuthorizationDelegate* authorization_delegate,
31362 const std::string& response) {
31363 VLOG(1) << __func__;
31364 TPM2B_NV_PUBLIC nv_public;
31365 TPM2B_NAME nv_name;
31366 TPM_RC rc = Tpm::ParseResponse_NV_ReadPublic(response, &nv_public, &nv_name,
31367 authorization_delegate);
31368 if (rc != TPM_RC_SUCCESS) {
31369 base::OnceCallback<void(TPM_RC)> error_reporter =
31370 base::BindOnce(NV_ReadPublicErrorCallback, std::move(callback));
31371 std::move(error_reporter).Run(rc);
31372 return;
31373 }
31374 std::move(callback).Run(rc, nv_public, nv_name);
31375 }
31376
NV_ReadPublic(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_ReadPublicResponse callback)31377 void Tpm::NV_ReadPublic(const TPMI_RH_NV_INDEX& nv_index,
31378 const std::string& nv_index_name,
31379 AuthorizationDelegate* authorization_delegate,
31380 NV_ReadPublicResponse callback) {
31381 VLOG(1) << __func__;
31382 std::string command;
31383 TPM_RC rc = SerializeCommand_NV_ReadPublic(nv_index, nv_index_name, &command,
31384 authorization_delegate);
31385 if (rc != TPM_RC_SUCCESS) {
31386 base::OnceCallback<void(TPM_RC)> error_reporter =
31387 base::BindOnce(NV_ReadPublicErrorCallback, std::move(callback));
31388 std::move(error_reporter).Run(rc);
31389 return;
31390 }
31391 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31392 NV_ReadPublicResponseParser, std::move(callback), authorization_delegate);
31393 transceiver_->SendCommand(command, std::move(parser));
31394 }
31395
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)31396 TPM_RC Tpm::NV_ReadPublicSync(const TPMI_RH_NV_INDEX& nv_index,
31397 const std::string& nv_index_name,
31398 TPM2B_NV_PUBLIC* nv_public,
31399 TPM2B_NAME* nv_name,
31400 AuthorizationDelegate* authorization_delegate) {
31401 VLOG(1) << __func__;
31402 std::string command;
31403 TPM_RC rc = SerializeCommand_NV_ReadPublic(nv_index, nv_index_name, &command,
31404 authorization_delegate);
31405 if (rc != TPM_RC_SUCCESS) {
31406 return rc;
31407 }
31408 std::string response = transceiver_->SendCommandAndWait(command);
31409 rc = ParseResponse_NV_ReadPublic(response, nv_public, nv_name,
31410 authorization_delegate);
31411 return rc;
31412 }
31413
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)31414 TPM_RC Tpm::SerializeCommand_NV_Write(
31415 const TPMI_RH_NV_AUTH& auth_handle,
31416 const std::string& auth_handle_name,
31417 const TPMI_RH_NV_INDEX& nv_index,
31418 const std::string& nv_index_name,
31419 const TPM2B_MAX_NV_BUFFER& data,
31420 const UINT16& offset,
31421 std::string* serialized_command,
31422 AuthorizationDelegate* authorization_delegate) {
31423 VLOG(3) << __func__;
31424 TPM_RC rc = TPM_RC_SUCCESS;
31425 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31426 UINT32 command_size = 10; // Header size.
31427 std::string handle_section_bytes;
31428 std::string parameter_section_bytes;
31429 TPM_CC command_code = TPM_CC_NV_Write;
31430 bool is_command_parameter_encryption_possible = true;
31431 bool is_response_parameter_encryption_possible = false;
31432 std::string command_code_bytes;
31433 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31434 if (rc != TPM_RC_SUCCESS) {
31435 return rc;
31436 }
31437 std::string auth_handle_bytes;
31438 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31439 if (rc != TPM_RC_SUCCESS) {
31440 return rc;
31441 }
31442 std::string nv_index_bytes;
31443 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31444 if (rc != TPM_RC_SUCCESS) {
31445 return rc;
31446 }
31447 std::string data_bytes;
31448 rc = Serialize_TPM2B_MAX_NV_BUFFER(data, &data_bytes);
31449 if (rc != TPM_RC_SUCCESS) {
31450 return rc;
31451 }
31452 std::string offset_bytes;
31453 rc = Serialize_UINT16(offset, &offset_bytes);
31454 if (rc != TPM_RC_SUCCESS) {
31455 return rc;
31456 }
31457 if (authorization_delegate) {
31458 // Encrypt just the parameter data, not the size.
31459 std::string tmp = data_bytes.substr(2);
31460 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
31461 return TRUNKS_RC_ENCRYPTION_FAILED;
31462 }
31463 data_bytes.replace(2, std::string::npos, tmp);
31464 }
31465 std::unique_ptr<crypto::SecureHash> hash(
31466 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31467 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31468 hash->Update(auth_handle_name.data(), auth_handle_name.size());
31469 handle_section_bytes += auth_handle_bytes;
31470 command_size += auth_handle_bytes.size();
31471 hash->Update(nv_index_name.data(), nv_index_name.size());
31472 handle_section_bytes += nv_index_bytes;
31473 command_size += nv_index_bytes.size();
31474 hash->Update(data_bytes.data(), data_bytes.size());
31475 parameter_section_bytes += data_bytes;
31476 command_size += data_bytes.size();
31477 hash->Update(offset_bytes.data(), offset_bytes.size());
31478 parameter_section_bytes += offset_bytes;
31479 command_size += offset_bytes.size();
31480 std::string command_hash(32, 0);
31481 hash->Finish(std::data(command_hash), command_hash.size());
31482 std::string authorization_section_bytes;
31483 std::string authorization_size_bytes;
31484 if (authorization_delegate) {
31485 if (!authorization_delegate->GetCommandAuthorization(
31486 command_hash, is_command_parameter_encryption_possible,
31487 is_response_parameter_encryption_possible,
31488 &authorization_section_bytes)) {
31489 return TRUNKS_RC_AUTHORIZATION_FAILED;
31490 }
31491 if (!authorization_section_bytes.empty()) {
31492 tag = TPM_ST_SESSIONS;
31493 std::string tmp;
31494 rc = Serialize_UINT32(authorization_section_bytes.size(),
31495 &authorization_size_bytes);
31496 if (rc != TPM_RC_SUCCESS) {
31497 return rc;
31498 }
31499 command_size +=
31500 authorization_size_bytes.size() + authorization_section_bytes.size();
31501 }
31502 }
31503 std::string tag_bytes;
31504 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31505 if (rc != TPM_RC_SUCCESS) {
31506 return rc;
31507 }
31508 std::string command_size_bytes;
31509 rc = Serialize_UINT32(command_size, &command_size_bytes);
31510 if (rc != TPM_RC_SUCCESS) {
31511 return rc;
31512 }
31513 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31514 handle_section_bytes + authorization_size_bytes +
31515 authorization_section_bytes + parameter_section_bytes;
31516 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31517 VLOG(2) << "Command: "
31518 << base::HexEncode(serialized_command->data(),
31519 serialized_command->size());
31520 return TPM_RC_SUCCESS;
31521 }
31522
ParseResponse_NV_Write(const std::string & response,AuthorizationDelegate * authorization_delegate)31523 TPM_RC Tpm::ParseResponse_NV_Write(
31524 const std::string& response,
31525 AuthorizationDelegate* authorization_delegate) {
31526 VLOG(3) << __func__;
31527 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31528 TPM_RC rc = TPM_RC_SUCCESS;
31529 std::string buffer(response);
31530 TPM_ST tag;
31531 std::string tag_bytes;
31532 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31533 if (rc != TPM_RC_SUCCESS) {
31534 return rc;
31535 }
31536 UINT32 response_size;
31537 std::string response_size_bytes;
31538 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31539 if (rc != TPM_RC_SUCCESS) {
31540 return rc;
31541 }
31542 TPM_RC response_code;
31543 std::string response_code_bytes;
31544 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31545 if (rc != TPM_RC_SUCCESS) {
31546 return rc;
31547 }
31548 if (response_size != response.size()) {
31549 return TPM_RC_SIZE;
31550 }
31551 if (response_code != TPM_RC_SUCCESS) {
31552 return response_code;
31553 }
31554 TPM_CC command_code = TPM_CC_NV_Write;
31555 std::string command_code_bytes;
31556 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31557 if (rc != TPM_RC_SUCCESS) {
31558 return rc;
31559 }
31560 std::string authorization_section_bytes;
31561 if (tag == TPM_ST_SESSIONS) {
31562 UINT32 parameter_section_size = buffer.size();
31563 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
31564 if (rc != TPM_RC_SUCCESS) {
31565 return rc;
31566 }
31567 if (parameter_section_size > buffer.size()) {
31568 return TPM_RC_INSUFFICIENT;
31569 }
31570 authorization_section_bytes = buffer.substr(parameter_section_size);
31571 // Keep the parameter section in |buffer|.
31572 buffer.erase(parameter_section_size);
31573 }
31574 std::unique_ptr<crypto::SecureHash> hash(
31575 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31576 hash->Update(response_code_bytes.data(), response_code_bytes.size());
31577 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31578 hash->Update(buffer.data(), buffer.size());
31579 std::string response_hash(32, 0);
31580 hash->Finish(std::data(response_hash), response_hash.size());
31581 if (tag == TPM_ST_SESSIONS) {
31582 if (!authorization_delegate)
31583 return TRUNKS_RC_AUTHORIZATION_FAILED;
31584 if (!authorization_delegate->CheckResponseAuthorization(
31585 response_hash, authorization_section_bytes)) {
31586 return TRUNKS_RC_AUTHORIZATION_FAILED;
31587 }
31588 }
31589 return TPM_RC_SUCCESS;
31590 }
31591
NV_WriteErrorCallback(Tpm::NV_WriteResponse callback,TPM_RC response_code)31592 void NV_WriteErrorCallback(Tpm::NV_WriteResponse callback,
31593 TPM_RC response_code) {
31594 VLOG(1) << __func__;
31595 std::move(callback).Run(response_code);
31596 }
31597
NV_WriteResponseParser(Tpm::NV_WriteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31598 void NV_WriteResponseParser(Tpm::NV_WriteResponse callback,
31599 AuthorizationDelegate* authorization_delegate,
31600 const std::string& response) {
31601 VLOG(1) << __func__;
31602 TPM_RC rc = Tpm::ParseResponse_NV_Write(response, authorization_delegate);
31603 if (rc != TPM_RC_SUCCESS) {
31604 base::OnceCallback<void(TPM_RC)> error_reporter =
31605 base::BindOnce(NV_WriteErrorCallback, std::move(callback));
31606 std::move(error_reporter).Run(rc);
31607 return;
31608 }
31609 std::move(callback).Run(rc);
31610 }
31611
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)31612 void Tpm::NV_Write(const TPMI_RH_NV_AUTH& auth_handle,
31613 const std::string& auth_handle_name,
31614 const TPMI_RH_NV_INDEX& nv_index,
31615 const std::string& nv_index_name,
31616 const TPM2B_MAX_NV_BUFFER& data,
31617 const UINT16& offset,
31618 AuthorizationDelegate* authorization_delegate,
31619 NV_WriteResponse callback) {
31620 VLOG(1) << __func__;
31621 std::string command;
31622 TPM_RC rc = SerializeCommand_NV_Write(auth_handle, auth_handle_name, nv_index,
31623 nv_index_name, data, offset, &command,
31624 authorization_delegate);
31625 if (rc != TPM_RC_SUCCESS) {
31626 base::OnceCallback<void(TPM_RC)> error_reporter =
31627 base::BindOnce(NV_WriteErrorCallback, std::move(callback));
31628 std::move(error_reporter).Run(rc);
31629 return;
31630 }
31631 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31632 NV_WriteResponseParser, std::move(callback), authorization_delegate);
31633 transceiver_->SendCommand(command, std::move(parser));
31634 }
31635
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)31636 TPM_RC Tpm::NV_WriteSync(const TPMI_RH_NV_AUTH& auth_handle,
31637 const std::string& auth_handle_name,
31638 const TPMI_RH_NV_INDEX& nv_index,
31639 const std::string& nv_index_name,
31640 const TPM2B_MAX_NV_BUFFER& data,
31641 const UINT16& offset,
31642 AuthorizationDelegate* authorization_delegate) {
31643 VLOG(1) << __func__;
31644 std::string command;
31645 TPM_RC rc = SerializeCommand_NV_Write(auth_handle, auth_handle_name, nv_index,
31646 nv_index_name, data, offset, &command,
31647 authorization_delegate);
31648 if (rc != TPM_RC_SUCCESS) {
31649 return rc;
31650 }
31651 std::string response = transceiver_->SendCommandAndWait(command);
31652 rc = ParseResponse_NV_Write(response, authorization_delegate);
31653 return rc;
31654 }
31655
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)31656 TPM_RC Tpm::SerializeCommand_NV_Increment(
31657 const TPMI_RH_NV_AUTH& auth_handle,
31658 const std::string& auth_handle_name,
31659 const TPMI_RH_NV_INDEX& nv_index,
31660 const std::string& nv_index_name,
31661 std::string* serialized_command,
31662 AuthorizationDelegate* authorization_delegate) {
31663 VLOG(3) << __func__;
31664 TPM_RC rc = TPM_RC_SUCCESS;
31665 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31666 UINT32 command_size = 10; // Header size.
31667 std::string handle_section_bytes;
31668 std::string parameter_section_bytes;
31669 TPM_CC command_code = TPM_CC_NV_Increment;
31670 bool is_command_parameter_encryption_possible = false;
31671 bool is_response_parameter_encryption_possible = false;
31672 std::string command_code_bytes;
31673 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31674 if (rc != TPM_RC_SUCCESS) {
31675 return rc;
31676 }
31677 std::string auth_handle_bytes;
31678 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31679 if (rc != TPM_RC_SUCCESS) {
31680 return rc;
31681 }
31682 std::string nv_index_bytes;
31683 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31684 if (rc != TPM_RC_SUCCESS) {
31685 return rc;
31686 }
31687 std::unique_ptr<crypto::SecureHash> hash(
31688 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31689 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31690 hash->Update(auth_handle_name.data(), auth_handle_name.size());
31691 handle_section_bytes += auth_handle_bytes;
31692 command_size += auth_handle_bytes.size();
31693 hash->Update(nv_index_name.data(), nv_index_name.size());
31694 handle_section_bytes += nv_index_bytes;
31695 command_size += nv_index_bytes.size();
31696 std::string command_hash(32, 0);
31697 hash->Finish(std::data(command_hash), command_hash.size());
31698 std::string authorization_section_bytes;
31699 std::string authorization_size_bytes;
31700 if (authorization_delegate) {
31701 if (!authorization_delegate->GetCommandAuthorization(
31702 command_hash, is_command_parameter_encryption_possible,
31703 is_response_parameter_encryption_possible,
31704 &authorization_section_bytes)) {
31705 return TRUNKS_RC_AUTHORIZATION_FAILED;
31706 }
31707 if (!authorization_section_bytes.empty()) {
31708 tag = TPM_ST_SESSIONS;
31709 std::string tmp;
31710 rc = Serialize_UINT32(authorization_section_bytes.size(),
31711 &authorization_size_bytes);
31712 if (rc != TPM_RC_SUCCESS) {
31713 return rc;
31714 }
31715 command_size +=
31716 authorization_size_bytes.size() + authorization_section_bytes.size();
31717 }
31718 }
31719 std::string tag_bytes;
31720 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31721 if (rc != TPM_RC_SUCCESS) {
31722 return rc;
31723 }
31724 std::string command_size_bytes;
31725 rc = Serialize_UINT32(command_size, &command_size_bytes);
31726 if (rc != TPM_RC_SUCCESS) {
31727 return rc;
31728 }
31729 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31730 handle_section_bytes + authorization_size_bytes +
31731 authorization_section_bytes + parameter_section_bytes;
31732 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31733 VLOG(2) << "Command: "
31734 << base::HexEncode(serialized_command->data(),
31735 serialized_command->size());
31736 return TPM_RC_SUCCESS;
31737 }
31738
ParseResponse_NV_Increment(const std::string & response,AuthorizationDelegate * authorization_delegate)31739 TPM_RC Tpm::ParseResponse_NV_Increment(
31740 const std::string& response,
31741 AuthorizationDelegate* authorization_delegate) {
31742 VLOG(3) << __func__;
31743 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31744 TPM_RC rc = TPM_RC_SUCCESS;
31745 std::string buffer(response);
31746 TPM_ST tag;
31747 std::string tag_bytes;
31748 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31749 if (rc != TPM_RC_SUCCESS) {
31750 return rc;
31751 }
31752 UINT32 response_size;
31753 std::string response_size_bytes;
31754 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31755 if (rc != TPM_RC_SUCCESS) {
31756 return rc;
31757 }
31758 TPM_RC response_code;
31759 std::string response_code_bytes;
31760 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31761 if (rc != TPM_RC_SUCCESS) {
31762 return rc;
31763 }
31764 if (response_size != response.size()) {
31765 return TPM_RC_SIZE;
31766 }
31767 if (response_code != TPM_RC_SUCCESS) {
31768 return response_code;
31769 }
31770 TPM_CC command_code = TPM_CC_NV_Increment;
31771 std::string command_code_bytes;
31772 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31773 if (rc != TPM_RC_SUCCESS) {
31774 return rc;
31775 }
31776 std::string authorization_section_bytes;
31777 if (tag == TPM_ST_SESSIONS) {
31778 UINT32 parameter_section_size = buffer.size();
31779 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
31780 if (rc != TPM_RC_SUCCESS) {
31781 return rc;
31782 }
31783 if (parameter_section_size > buffer.size()) {
31784 return TPM_RC_INSUFFICIENT;
31785 }
31786 authorization_section_bytes = buffer.substr(parameter_section_size);
31787 // Keep the parameter section in |buffer|.
31788 buffer.erase(parameter_section_size);
31789 }
31790 std::unique_ptr<crypto::SecureHash> hash(
31791 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31792 hash->Update(response_code_bytes.data(), response_code_bytes.size());
31793 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31794 hash->Update(buffer.data(), buffer.size());
31795 std::string response_hash(32, 0);
31796 hash->Finish(std::data(response_hash), response_hash.size());
31797 if (tag == TPM_ST_SESSIONS) {
31798 if (!authorization_delegate)
31799 return TRUNKS_RC_AUTHORIZATION_FAILED;
31800 if (!authorization_delegate->CheckResponseAuthorization(
31801 response_hash, authorization_section_bytes)) {
31802 return TRUNKS_RC_AUTHORIZATION_FAILED;
31803 }
31804 }
31805 return TPM_RC_SUCCESS;
31806 }
31807
NV_IncrementErrorCallback(Tpm::NV_IncrementResponse callback,TPM_RC response_code)31808 void NV_IncrementErrorCallback(Tpm::NV_IncrementResponse callback,
31809 TPM_RC response_code) {
31810 VLOG(1) << __func__;
31811 std::move(callback).Run(response_code);
31812 }
31813
NV_IncrementResponseParser(Tpm::NV_IncrementResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31814 void NV_IncrementResponseParser(Tpm::NV_IncrementResponse callback,
31815 AuthorizationDelegate* authorization_delegate,
31816 const std::string& response) {
31817 VLOG(1) << __func__;
31818 TPM_RC rc = Tpm::ParseResponse_NV_Increment(response, authorization_delegate);
31819 if (rc != TPM_RC_SUCCESS) {
31820 base::OnceCallback<void(TPM_RC)> error_reporter =
31821 base::BindOnce(NV_IncrementErrorCallback, std::move(callback));
31822 std::move(error_reporter).Run(rc);
31823 return;
31824 }
31825 std::move(callback).Run(rc);
31826 }
31827
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)31828 void Tpm::NV_Increment(const TPMI_RH_NV_AUTH& auth_handle,
31829 const std::string& auth_handle_name,
31830 const TPMI_RH_NV_INDEX& nv_index,
31831 const std::string& nv_index_name,
31832 AuthorizationDelegate* authorization_delegate,
31833 NV_IncrementResponse callback) {
31834 VLOG(1) << __func__;
31835 std::string command;
31836 TPM_RC rc = SerializeCommand_NV_Increment(auth_handle, auth_handle_name,
31837 nv_index, nv_index_name, &command,
31838 authorization_delegate);
31839 if (rc != TPM_RC_SUCCESS) {
31840 base::OnceCallback<void(TPM_RC)> error_reporter =
31841 base::BindOnce(NV_IncrementErrorCallback, std::move(callback));
31842 std::move(error_reporter).Run(rc);
31843 return;
31844 }
31845 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31846 NV_IncrementResponseParser, std::move(callback), authorization_delegate);
31847 transceiver_->SendCommand(command, std::move(parser));
31848 }
31849
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)31850 TPM_RC Tpm::NV_IncrementSync(const TPMI_RH_NV_AUTH& auth_handle,
31851 const std::string& auth_handle_name,
31852 const TPMI_RH_NV_INDEX& nv_index,
31853 const std::string& nv_index_name,
31854 AuthorizationDelegate* authorization_delegate) {
31855 VLOG(1) << __func__;
31856 std::string command;
31857 TPM_RC rc = SerializeCommand_NV_Increment(auth_handle, auth_handle_name,
31858 nv_index, nv_index_name, &command,
31859 authorization_delegate);
31860 if (rc != TPM_RC_SUCCESS) {
31861 return rc;
31862 }
31863 std::string response = transceiver_->SendCommandAndWait(command);
31864 rc = ParseResponse_NV_Increment(response, authorization_delegate);
31865 return rc;
31866 }
31867
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)31868 TPM_RC Tpm::SerializeCommand_NV_Extend(
31869 const TPMI_RH_NV_AUTH& auth_handle,
31870 const std::string& auth_handle_name,
31871 const TPMI_RH_NV_INDEX& nv_index,
31872 const std::string& nv_index_name,
31873 const TPM2B_MAX_NV_BUFFER& data,
31874 std::string* serialized_command,
31875 AuthorizationDelegate* authorization_delegate) {
31876 VLOG(3) << __func__;
31877 TPM_RC rc = TPM_RC_SUCCESS;
31878 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31879 UINT32 command_size = 10; // Header size.
31880 std::string handle_section_bytes;
31881 std::string parameter_section_bytes;
31882 TPM_CC command_code = TPM_CC_NV_Extend;
31883 bool is_command_parameter_encryption_possible = true;
31884 bool is_response_parameter_encryption_possible = false;
31885 std::string command_code_bytes;
31886 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31887 if (rc != TPM_RC_SUCCESS) {
31888 return rc;
31889 }
31890 std::string auth_handle_bytes;
31891 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31892 if (rc != TPM_RC_SUCCESS) {
31893 return rc;
31894 }
31895 std::string nv_index_bytes;
31896 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31897 if (rc != TPM_RC_SUCCESS) {
31898 return rc;
31899 }
31900 std::string data_bytes;
31901 rc = Serialize_TPM2B_MAX_NV_BUFFER(data, &data_bytes);
31902 if (rc != TPM_RC_SUCCESS) {
31903 return rc;
31904 }
31905 if (authorization_delegate) {
31906 // Encrypt just the parameter data, not the size.
31907 std::string tmp = data_bytes.substr(2);
31908 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
31909 return TRUNKS_RC_ENCRYPTION_FAILED;
31910 }
31911 data_bytes.replace(2, std::string::npos, tmp);
31912 }
31913 std::unique_ptr<crypto::SecureHash> hash(
31914 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31915 hash->Update(command_code_bytes.data(), command_code_bytes.size());
31916 hash->Update(auth_handle_name.data(), auth_handle_name.size());
31917 handle_section_bytes += auth_handle_bytes;
31918 command_size += auth_handle_bytes.size();
31919 hash->Update(nv_index_name.data(), nv_index_name.size());
31920 handle_section_bytes += nv_index_bytes;
31921 command_size += nv_index_bytes.size();
31922 hash->Update(data_bytes.data(), data_bytes.size());
31923 parameter_section_bytes += data_bytes;
31924 command_size += data_bytes.size();
31925 std::string command_hash(32, 0);
31926 hash->Finish(std::data(command_hash), command_hash.size());
31927 std::string authorization_section_bytes;
31928 std::string authorization_size_bytes;
31929 if (authorization_delegate) {
31930 if (!authorization_delegate->GetCommandAuthorization(
31931 command_hash, is_command_parameter_encryption_possible,
31932 is_response_parameter_encryption_possible,
31933 &authorization_section_bytes)) {
31934 return TRUNKS_RC_AUTHORIZATION_FAILED;
31935 }
31936 if (!authorization_section_bytes.empty()) {
31937 tag = TPM_ST_SESSIONS;
31938 std::string tmp;
31939 rc = Serialize_UINT32(authorization_section_bytes.size(),
31940 &authorization_size_bytes);
31941 if (rc != TPM_RC_SUCCESS) {
31942 return rc;
31943 }
31944 command_size +=
31945 authorization_size_bytes.size() + authorization_section_bytes.size();
31946 }
31947 }
31948 std::string tag_bytes;
31949 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31950 if (rc != TPM_RC_SUCCESS) {
31951 return rc;
31952 }
31953 std::string command_size_bytes;
31954 rc = Serialize_UINT32(command_size, &command_size_bytes);
31955 if (rc != TPM_RC_SUCCESS) {
31956 return rc;
31957 }
31958 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31959 handle_section_bytes + authorization_size_bytes +
31960 authorization_section_bytes + parameter_section_bytes;
31961 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31962 VLOG(2) << "Command: "
31963 << base::HexEncode(serialized_command->data(),
31964 serialized_command->size());
31965 return TPM_RC_SUCCESS;
31966 }
31967
ParseResponse_NV_Extend(const std::string & response,AuthorizationDelegate * authorization_delegate)31968 TPM_RC Tpm::ParseResponse_NV_Extend(
31969 const std::string& response,
31970 AuthorizationDelegate* authorization_delegate) {
31971 VLOG(3) << __func__;
31972 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31973 TPM_RC rc = TPM_RC_SUCCESS;
31974 std::string buffer(response);
31975 TPM_ST tag;
31976 std::string tag_bytes;
31977 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31978 if (rc != TPM_RC_SUCCESS) {
31979 return rc;
31980 }
31981 UINT32 response_size;
31982 std::string response_size_bytes;
31983 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31984 if (rc != TPM_RC_SUCCESS) {
31985 return rc;
31986 }
31987 TPM_RC response_code;
31988 std::string response_code_bytes;
31989 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31990 if (rc != TPM_RC_SUCCESS) {
31991 return rc;
31992 }
31993 if (response_size != response.size()) {
31994 return TPM_RC_SIZE;
31995 }
31996 if (response_code != TPM_RC_SUCCESS) {
31997 return response_code;
31998 }
31999 TPM_CC command_code = TPM_CC_NV_Extend;
32000 std::string command_code_bytes;
32001 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32002 if (rc != TPM_RC_SUCCESS) {
32003 return rc;
32004 }
32005 std::string authorization_section_bytes;
32006 if (tag == TPM_ST_SESSIONS) {
32007 UINT32 parameter_section_size = buffer.size();
32008 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
32009 if (rc != TPM_RC_SUCCESS) {
32010 return rc;
32011 }
32012 if (parameter_section_size > buffer.size()) {
32013 return TPM_RC_INSUFFICIENT;
32014 }
32015 authorization_section_bytes = buffer.substr(parameter_section_size);
32016 // Keep the parameter section in |buffer|.
32017 buffer.erase(parameter_section_size);
32018 }
32019 std::unique_ptr<crypto::SecureHash> hash(
32020 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32021 hash->Update(response_code_bytes.data(), response_code_bytes.size());
32022 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32023 hash->Update(buffer.data(), buffer.size());
32024 std::string response_hash(32, 0);
32025 hash->Finish(std::data(response_hash), response_hash.size());
32026 if (tag == TPM_ST_SESSIONS) {
32027 if (!authorization_delegate)
32028 return TRUNKS_RC_AUTHORIZATION_FAILED;
32029 if (!authorization_delegate->CheckResponseAuthorization(
32030 response_hash, authorization_section_bytes)) {
32031 return TRUNKS_RC_AUTHORIZATION_FAILED;
32032 }
32033 }
32034 return TPM_RC_SUCCESS;
32035 }
32036
NV_ExtendErrorCallback(Tpm::NV_ExtendResponse callback,TPM_RC response_code)32037 void NV_ExtendErrorCallback(Tpm::NV_ExtendResponse callback,
32038 TPM_RC response_code) {
32039 VLOG(1) << __func__;
32040 std::move(callback).Run(response_code);
32041 }
32042
NV_ExtendResponseParser(Tpm::NV_ExtendResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32043 void NV_ExtendResponseParser(Tpm::NV_ExtendResponse callback,
32044 AuthorizationDelegate* authorization_delegate,
32045 const std::string& response) {
32046 VLOG(1) << __func__;
32047 TPM_RC rc = Tpm::ParseResponse_NV_Extend(response, authorization_delegate);
32048 if (rc != TPM_RC_SUCCESS) {
32049 base::OnceCallback<void(TPM_RC)> error_reporter =
32050 base::BindOnce(NV_ExtendErrorCallback, std::move(callback));
32051 std::move(error_reporter).Run(rc);
32052 return;
32053 }
32054 std::move(callback).Run(rc);
32055 }
32056
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)32057 void Tpm::NV_Extend(const TPMI_RH_NV_AUTH& auth_handle,
32058 const std::string& auth_handle_name,
32059 const TPMI_RH_NV_INDEX& nv_index,
32060 const std::string& nv_index_name,
32061 const TPM2B_MAX_NV_BUFFER& data,
32062 AuthorizationDelegate* authorization_delegate,
32063 NV_ExtendResponse callback) {
32064 VLOG(1) << __func__;
32065 std::string command;
32066 TPM_RC rc = SerializeCommand_NV_Extend(auth_handle, auth_handle_name,
32067 nv_index, nv_index_name, data,
32068 &command, authorization_delegate);
32069 if (rc != TPM_RC_SUCCESS) {
32070 base::OnceCallback<void(TPM_RC)> error_reporter =
32071 base::BindOnce(NV_ExtendErrorCallback, std::move(callback));
32072 std::move(error_reporter).Run(rc);
32073 return;
32074 }
32075 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32076 NV_ExtendResponseParser, std::move(callback), authorization_delegate);
32077 transceiver_->SendCommand(command, std::move(parser));
32078 }
32079
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)32080 TPM_RC Tpm::NV_ExtendSync(const TPMI_RH_NV_AUTH& auth_handle,
32081 const std::string& auth_handle_name,
32082 const TPMI_RH_NV_INDEX& nv_index,
32083 const std::string& nv_index_name,
32084 const TPM2B_MAX_NV_BUFFER& data,
32085 AuthorizationDelegate* authorization_delegate) {
32086 VLOG(1) << __func__;
32087 std::string command;
32088 TPM_RC rc = SerializeCommand_NV_Extend(auth_handle, auth_handle_name,
32089 nv_index, nv_index_name, data,
32090 &command, authorization_delegate);
32091 if (rc != TPM_RC_SUCCESS) {
32092 return rc;
32093 }
32094 std::string response = transceiver_->SendCommandAndWait(command);
32095 rc = ParseResponse_NV_Extend(response, authorization_delegate);
32096 return rc;
32097 }
32098
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)32099 TPM_RC Tpm::SerializeCommand_NV_SetBits(
32100 const TPMI_RH_NV_AUTH& auth_handle,
32101 const std::string& auth_handle_name,
32102 const TPMI_RH_NV_INDEX& nv_index,
32103 const std::string& nv_index_name,
32104 const UINT64& bits,
32105 std::string* serialized_command,
32106 AuthorizationDelegate* authorization_delegate) {
32107 VLOG(3) << __func__;
32108 TPM_RC rc = TPM_RC_SUCCESS;
32109 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32110 UINT32 command_size = 10; // Header size.
32111 std::string handle_section_bytes;
32112 std::string parameter_section_bytes;
32113 TPM_CC command_code = TPM_CC_NV_SetBits;
32114 bool is_command_parameter_encryption_possible = false;
32115 bool is_response_parameter_encryption_possible = false;
32116 std::string command_code_bytes;
32117 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32118 if (rc != TPM_RC_SUCCESS) {
32119 return rc;
32120 }
32121 std::string auth_handle_bytes;
32122 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32123 if (rc != TPM_RC_SUCCESS) {
32124 return rc;
32125 }
32126 std::string nv_index_bytes;
32127 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32128 if (rc != TPM_RC_SUCCESS) {
32129 return rc;
32130 }
32131 std::string bits_bytes;
32132 rc = Serialize_UINT64(bits, &bits_bytes);
32133 if (rc != TPM_RC_SUCCESS) {
32134 return rc;
32135 }
32136 std::unique_ptr<crypto::SecureHash> hash(
32137 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32138 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32139 hash->Update(auth_handle_name.data(), auth_handle_name.size());
32140 handle_section_bytes += auth_handle_bytes;
32141 command_size += auth_handle_bytes.size();
32142 hash->Update(nv_index_name.data(), nv_index_name.size());
32143 handle_section_bytes += nv_index_bytes;
32144 command_size += nv_index_bytes.size();
32145 hash->Update(bits_bytes.data(), bits_bytes.size());
32146 parameter_section_bytes += bits_bytes;
32147 command_size += bits_bytes.size();
32148 std::string command_hash(32, 0);
32149 hash->Finish(std::data(command_hash), command_hash.size());
32150 std::string authorization_section_bytes;
32151 std::string authorization_size_bytes;
32152 if (authorization_delegate) {
32153 if (!authorization_delegate->GetCommandAuthorization(
32154 command_hash, is_command_parameter_encryption_possible,
32155 is_response_parameter_encryption_possible,
32156 &authorization_section_bytes)) {
32157 return TRUNKS_RC_AUTHORIZATION_FAILED;
32158 }
32159 if (!authorization_section_bytes.empty()) {
32160 tag = TPM_ST_SESSIONS;
32161 std::string tmp;
32162 rc = Serialize_UINT32(authorization_section_bytes.size(),
32163 &authorization_size_bytes);
32164 if (rc != TPM_RC_SUCCESS) {
32165 return rc;
32166 }
32167 command_size +=
32168 authorization_size_bytes.size() + authorization_section_bytes.size();
32169 }
32170 }
32171 std::string tag_bytes;
32172 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32173 if (rc != TPM_RC_SUCCESS) {
32174 return rc;
32175 }
32176 std::string command_size_bytes;
32177 rc = Serialize_UINT32(command_size, &command_size_bytes);
32178 if (rc != TPM_RC_SUCCESS) {
32179 return rc;
32180 }
32181 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32182 handle_section_bytes + authorization_size_bytes +
32183 authorization_section_bytes + parameter_section_bytes;
32184 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32185 VLOG(2) << "Command: "
32186 << base::HexEncode(serialized_command->data(),
32187 serialized_command->size());
32188 return TPM_RC_SUCCESS;
32189 }
32190
ParseResponse_NV_SetBits(const std::string & response,AuthorizationDelegate * authorization_delegate)32191 TPM_RC Tpm::ParseResponse_NV_SetBits(
32192 const std::string& response,
32193 AuthorizationDelegate* authorization_delegate) {
32194 VLOG(3) << __func__;
32195 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32196 TPM_RC rc = TPM_RC_SUCCESS;
32197 std::string buffer(response);
32198 TPM_ST tag;
32199 std::string tag_bytes;
32200 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32201 if (rc != TPM_RC_SUCCESS) {
32202 return rc;
32203 }
32204 UINT32 response_size;
32205 std::string response_size_bytes;
32206 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32207 if (rc != TPM_RC_SUCCESS) {
32208 return rc;
32209 }
32210 TPM_RC response_code;
32211 std::string response_code_bytes;
32212 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32213 if (rc != TPM_RC_SUCCESS) {
32214 return rc;
32215 }
32216 if (response_size != response.size()) {
32217 return TPM_RC_SIZE;
32218 }
32219 if (response_code != TPM_RC_SUCCESS) {
32220 return response_code;
32221 }
32222 TPM_CC command_code = TPM_CC_NV_SetBits;
32223 std::string command_code_bytes;
32224 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32225 if (rc != TPM_RC_SUCCESS) {
32226 return rc;
32227 }
32228 std::string authorization_section_bytes;
32229 if (tag == TPM_ST_SESSIONS) {
32230 UINT32 parameter_section_size = buffer.size();
32231 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
32232 if (rc != TPM_RC_SUCCESS) {
32233 return rc;
32234 }
32235 if (parameter_section_size > buffer.size()) {
32236 return TPM_RC_INSUFFICIENT;
32237 }
32238 authorization_section_bytes = buffer.substr(parameter_section_size);
32239 // Keep the parameter section in |buffer|.
32240 buffer.erase(parameter_section_size);
32241 }
32242 std::unique_ptr<crypto::SecureHash> hash(
32243 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32244 hash->Update(response_code_bytes.data(), response_code_bytes.size());
32245 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32246 hash->Update(buffer.data(), buffer.size());
32247 std::string response_hash(32, 0);
32248 hash->Finish(std::data(response_hash), response_hash.size());
32249 if (tag == TPM_ST_SESSIONS) {
32250 if (!authorization_delegate)
32251 return TRUNKS_RC_AUTHORIZATION_FAILED;
32252 if (!authorization_delegate->CheckResponseAuthorization(
32253 response_hash, authorization_section_bytes)) {
32254 return TRUNKS_RC_AUTHORIZATION_FAILED;
32255 }
32256 }
32257 return TPM_RC_SUCCESS;
32258 }
32259
NV_SetBitsErrorCallback(Tpm::NV_SetBitsResponse callback,TPM_RC response_code)32260 void NV_SetBitsErrorCallback(Tpm::NV_SetBitsResponse callback,
32261 TPM_RC response_code) {
32262 VLOG(1) << __func__;
32263 std::move(callback).Run(response_code);
32264 }
32265
NV_SetBitsResponseParser(Tpm::NV_SetBitsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32266 void NV_SetBitsResponseParser(Tpm::NV_SetBitsResponse callback,
32267 AuthorizationDelegate* authorization_delegate,
32268 const std::string& response) {
32269 VLOG(1) << __func__;
32270 TPM_RC rc = Tpm::ParseResponse_NV_SetBits(response, authorization_delegate);
32271 if (rc != TPM_RC_SUCCESS) {
32272 base::OnceCallback<void(TPM_RC)> error_reporter =
32273 base::BindOnce(NV_SetBitsErrorCallback, std::move(callback));
32274 std::move(error_reporter).Run(rc);
32275 return;
32276 }
32277 std::move(callback).Run(rc);
32278 }
32279
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)32280 void Tpm::NV_SetBits(const TPMI_RH_NV_AUTH& auth_handle,
32281 const std::string& auth_handle_name,
32282 const TPMI_RH_NV_INDEX& nv_index,
32283 const std::string& nv_index_name,
32284 const UINT64& bits,
32285 AuthorizationDelegate* authorization_delegate,
32286 NV_SetBitsResponse callback) {
32287 VLOG(1) << __func__;
32288 std::string command;
32289 TPM_RC rc = SerializeCommand_NV_SetBits(auth_handle, auth_handle_name,
32290 nv_index, nv_index_name, bits,
32291 &command, authorization_delegate);
32292 if (rc != TPM_RC_SUCCESS) {
32293 base::OnceCallback<void(TPM_RC)> error_reporter =
32294 base::BindOnce(NV_SetBitsErrorCallback, std::move(callback));
32295 std::move(error_reporter).Run(rc);
32296 return;
32297 }
32298 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32299 NV_SetBitsResponseParser, std::move(callback), authorization_delegate);
32300 transceiver_->SendCommand(command, std::move(parser));
32301 }
32302
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)32303 TPM_RC Tpm::NV_SetBitsSync(const TPMI_RH_NV_AUTH& auth_handle,
32304 const std::string& auth_handle_name,
32305 const TPMI_RH_NV_INDEX& nv_index,
32306 const std::string& nv_index_name,
32307 const UINT64& bits,
32308 AuthorizationDelegate* authorization_delegate) {
32309 VLOG(1) << __func__;
32310 std::string command;
32311 TPM_RC rc = SerializeCommand_NV_SetBits(auth_handle, auth_handle_name,
32312 nv_index, nv_index_name, bits,
32313 &command, authorization_delegate);
32314 if (rc != TPM_RC_SUCCESS) {
32315 return rc;
32316 }
32317 std::string response = transceiver_->SendCommandAndWait(command);
32318 rc = ParseResponse_NV_SetBits(response, authorization_delegate);
32319 return rc;
32320 }
32321
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)32322 TPM_RC Tpm::SerializeCommand_NV_WriteLock(
32323 const TPMI_RH_NV_AUTH& auth_handle,
32324 const std::string& auth_handle_name,
32325 const TPMI_RH_NV_INDEX& nv_index,
32326 const std::string& nv_index_name,
32327 std::string* serialized_command,
32328 AuthorizationDelegate* authorization_delegate) {
32329 VLOG(3) << __func__;
32330 TPM_RC rc = TPM_RC_SUCCESS;
32331 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32332 UINT32 command_size = 10; // Header size.
32333 std::string handle_section_bytes;
32334 std::string parameter_section_bytes;
32335 TPM_CC command_code = TPM_CC_NV_WriteLock;
32336 bool is_command_parameter_encryption_possible = false;
32337 bool is_response_parameter_encryption_possible = false;
32338 std::string command_code_bytes;
32339 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32340 if (rc != TPM_RC_SUCCESS) {
32341 return rc;
32342 }
32343 std::string auth_handle_bytes;
32344 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32345 if (rc != TPM_RC_SUCCESS) {
32346 return rc;
32347 }
32348 std::string nv_index_bytes;
32349 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32350 if (rc != TPM_RC_SUCCESS) {
32351 return rc;
32352 }
32353 std::unique_ptr<crypto::SecureHash> hash(
32354 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32355 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32356 hash->Update(auth_handle_name.data(), auth_handle_name.size());
32357 handle_section_bytes += auth_handle_bytes;
32358 command_size += auth_handle_bytes.size();
32359 hash->Update(nv_index_name.data(), nv_index_name.size());
32360 handle_section_bytes += nv_index_bytes;
32361 command_size += nv_index_bytes.size();
32362 std::string command_hash(32, 0);
32363 hash->Finish(std::data(command_hash), command_hash.size());
32364 std::string authorization_section_bytes;
32365 std::string authorization_size_bytes;
32366 if (authorization_delegate) {
32367 if (!authorization_delegate->GetCommandAuthorization(
32368 command_hash, is_command_parameter_encryption_possible,
32369 is_response_parameter_encryption_possible,
32370 &authorization_section_bytes)) {
32371 return TRUNKS_RC_AUTHORIZATION_FAILED;
32372 }
32373 if (!authorization_section_bytes.empty()) {
32374 tag = TPM_ST_SESSIONS;
32375 std::string tmp;
32376 rc = Serialize_UINT32(authorization_section_bytes.size(),
32377 &authorization_size_bytes);
32378 if (rc != TPM_RC_SUCCESS) {
32379 return rc;
32380 }
32381 command_size +=
32382 authorization_size_bytes.size() + authorization_section_bytes.size();
32383 }
32384 }
32385 std::string tag_bytes;
32386 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32387 if (rc != TPM_RC_SUCCESS) {
32388 return rc;
32389 }
32390 std::string command_size_bytes;
32391 rc = Serialize_UINT32(command_size, &command_size_bytes);
32392 if (rc != TPM_RC_SUCCESS) {
32393 return rc;
32394 }
32395 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32396 handle_section_bytes + authorization_size_bytes +
32397 authorization_section_bytes + parameter_section_bytes;
32398 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32399 VLOG(2) << "Command: "
32400 << base::HexEncode(serialized_command->data(),
32401 serialized_command->size());
32402 return TPM_RC_SUCCESS;
32403 }
32404
ParseResponse_NV_WriteLock(const std::string & response,AuthorizationDelegate * authorization_delegate)32405 TPM_RC Tpm::ParseResponse_NV_WriteLock(
32406 const std::string& response,
32407 AuthorizationDelegate* authorization_delegate) {
32408 VLOG(3) << __func__;
32409 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32410 TPM_RC rc = TPM_RC_SUCCESS;
32411 std::string buffer(response);
32412 TPM_ST tag;
32413 std::string tag_bytes;
32414 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32415 if (rc != TPM_RC_SUCCESS) {
32416 return rc;
32417 }
32418 UINT32 response_size;
32419 std::string response_size_bytes;
32420 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32421 if (rc != TPM_RC_SUCCESS) {
32422 return rc;
32423 }
32424 TPM_RC response_code;
32425 std::string response_code_bytes;
32426 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32427 if (rc != TPM_RC_SUCCESS) {
32428 return rc;
32429 }
32430 if (response_size != response.size()) {
32431 return TPM_RC_SIZE;
32432 }
32433 if (response_code != TPM_RC_SUCCESS) {
32434 return response_code;
32435 }
32436 TPM_CC command_code = TPM_CC_NV_WriteLock;
32437 std::string command_code_bytes;
32438 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32439 if (rc != TPM_RC_SUCCESS) {
32440 return rc;
32441 }
32442 std::string authorization_section_bytes;
32443 if (tag == TPM_ST_SESSIONS) {
32444 UINT32 parameter_section_size = buffer.size();
32445 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
32446 if (rc != TPM_RC_SUCCESS) {
32447 return rc;
32448 }
32449 if (parameter_section_size > buffer.size()) {
32450 return TPM_RC_INSUFFICIENT;
32451 }
32452 authorization_section_bytes = buffer.substr(parameter_section_size);
32453 // Keep the parameter section in |buffer|.
32454 buffer.erase(parameter_section_size);
32455 }
32456 std::unique_ptr<crypto::SecureHash> hash(
32457 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32458 hash->Update(response_code_bytes.data(), response_code_bytes.size());
32459 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32460 hash->Update(buffer.data(), buffer.size());
32461 std::string response_hash(32, 0);
32462 hash->Finish(std::data(response_hash), response_hash.size());
32463 if (tag == TPM_ST_SESSIONS) {
32464 if (!authorization_delegate)
32465 return TRUNKS_RC_AUTHORIZATION_FAILED;
32466 if (!authorization_delegate->CheckResponseAuthorization(
32467 response_hash, authorization_section_bytes)) {
32468 return TRUNKS_RC_AUTHORIZATION_FAILED;
32469 }
32470 }
32471 return TPM_RC_SUCCESS;
32472 }
32473
NV_WriteLockErrorCallback(Tpm::NV_WriteLockResponse callback,TPM_RC response_code)32474 void NV_WriteLockErrorCallback(Tpm::NV_WriteLockResponse callback,
32475 TPM_RC response_code) {
32476 VLOG(1) << __func__;
32477 std::move(callback).Run(response_code);
32478 }
32479
NV_WriteLockResponseParser(Tpm::NV_WriteLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32480 void NV_WriteLockResponseParser(Tpm::NV_WriteLockResponse callback,
32481 AuthorizationDelegate* authorization_delegate,
32482 const std::string& response) {
32483 VLOG(1) << __func__;
32484 TPM_RC rc = Tpm::ParseResponse_NV_WriteLock(response, authorization_delegate);
32485 if (rc != TPM_RC_SUCCESS) {
32486 base::OnceCallback<void(TPM_RC)> error_reporter =
32487 base::BindOnce(NV_WriteLockErrorCallback, std::move(callback));
32488 std::move(error_reporter).Run(rc);
32489 return;
32490 }
32491 std::move(callback).Run(rc);
32492 }
32493
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)32494 void Tpm::NV_WriteLock(const TPMI_RH_NV_AUTH& auth_handle,
32495 const std::string& auth_handle_name,
32496 const TPMI_RH_NV_INDEX& nv_index,
32497 const std::string& nv_index_name,
32498 AuthorizationDelegate* authorization_delegate,
32499 NV_WriteLockResponse callback) {
32500 VLOG(1) << __func__;
32501 std::string command;
32502 TPM_RC rc = SerializeCommand_NV_WriteLock(auth_handle, auth_handle_name,
32503 nv_index, nv_index_name, &command,
32504 authorization_delegate);
32505 if (rc != TPM_RC_SUCCESS) {
32506 base::OnceCallback<void(TPM_RC)> error_reporter =
32507 base::BindOnce(NV_WriteLockErrorCallback, std::move(callback));
32508 std::move(error_reporter).Run(rc);
32509 return;
32510 }
32511 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32512 NV_WriteLockResponseParser, std::move(callback), authorization_delegate);
32513 transceiver_->SendCommand(command, std::move(parser));
32514 }
32515
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)32516 TPM_RC Tpm::NV_WriteLockSync(const TPMI_RH_NV_AUTH& auth_handle,
32517 const std::string& auth_handle_name,
32518 const TPMI_RH_NV_INDEX& nv_index,
32519 const std::string& nv_index_name,
32520 AuthorizationDelegate* authorization_delegate) {
32521 VLOG(1) << __func__;
32522 std::string command;
32523 TPM_RC rc = SerializeCommand_NV_WriteLock(auth_handle, auth_handle_name,
32524 nv_index, nv_index_name, &command,
32525 authorization_delegate);
32526 if (rc != TPM_RC_SUCCESS) {
32527 return rc;
32528 }
32529 std::string response = transceiver_->SendCommandAndWait(command);
32530 rc = ParseResponse_NV_WriteLock(response, authorization_delegate);
32531 return rc;
32532 }
32533
SerializeCommand_NV_GlobalWriteLock(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32534 TPM_RC Tpm::SerializeCommand_NV_GlobalWriteLock(
32535 const TPMI_RH_PROVISION& auth_handle,
32536 const std::string& auth_handle_name,
32537 std::string* serialized_command,
32538 AuthorizationDelegate* authorization_delegate) {
32539 VLOG(3) << __func__;
32540 TPM_RC rc = TPM_RC_SUCCESS;
32541 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32542 UINT32 command_size = 10; // Header size.
32543 std::string handle_section_bytes;
32544 std::string parameter_section_bytes;
32545 TPM_CC command_code = TPM_CC_NV_GlobalWriteLock;
32546 bool is_command_parameter_encryption_possible = false;
32547 bool is_response_parameter_encryption_possible = false;
32548 std::string command_code_bytes;
32549 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32550 if (rc != TPM_RC_SUCCESS) {
32551 return rc;
32552 }
32553 std::string auth_handle_bytes;
32554 rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
32555 if (rc != TPM_RC_SUCCESS) {
32556 return rc;
32557 }
32558 std::unique_ptr<crypto::SecureHash> hash(
32559 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32560 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32561 hash->Update(auth_handle_name.data(), auth_handle_name.size());
32562 handle_section_bytes += auth_handle_bytes;
32563 command_size += auth_handle_bytes.size();
32564 std::string command_hash(32, 0);
32565 hash->Finish(std::data(command_hash), command_hash.size());
32566 std::string authorization_section_bytes;
32567 std::string authorization_size_bytes;
32568 if (authorization_delegate) {
32569 if (!authorization_delegate->GetCommandAuthorization(
32570 command_hash, is_command_parameter_encryption_possible,
32571 is_response_parameter_encryption_possible,
32572 &authorization_section_bytes)) {
32573 return TRUNKS_RC_AUTHORIZATION_FAILED;
32574 }
32575 if (!authorization_section_bytes.empty()) {
32576 tag = TPM_ST_SESSIONS;
32577 std::string tmp;
32578 rc = Serialize_UINT32(authorization_section_bytes.size(),
32579 &authorization_size_bytes);
32580 if (rc != TPM_RC_SUCCESS) {
32581 return rc;
32582 }
32583 command_size +=
32584 authorization_size_bytes.size() + authorization_section_bytes.size();
32585 }
32586 }
32587 std::string tag_bytes;
32588 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32589 if (rc != TPM_RC_SUCCESS) {
32590 return rc;
32591 }
32592 std::string command_size_bytes;
32593 rc = Serialize_UINT32(command_size, &command_size_bytes);
32594 if (rc != TPM_RC_SUCCESS) {
32595 return rc;
32596 }
32597 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32598 handle_section_bytes + authorization_size_bytes +
32599 authorization_section_bytes + parameter_section_bytes;
32600 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32601 VLOG(2) << "Command: "
32602 << base::HexEncode(serialized_command->data(),
32603 serialized_command->size());
32604 return TPM_RC_SUCCESS;
32605 }
32606
ParseResponse_NV_GlobalWriteLock(const std::string & response,AuthorizationDelegate * authorization_delegate)32607 TPM_RC Tpm::ParseResponse_NV_GlobalWriteLock(
32608 const std::string& response,
32609 AuthorizationDelegate* authorization_delegate) {
32610 VLOG(3) << __func__;
32611 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32612 TPM_RC rc = TPM_RC_SUCCESS;
32613 std::string buffer(response);
32614 TPM_ST tag;
32615 std::string tag_bytes;
32616 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32617 if (rc != TPM_RC_SUCCESS) {
32618 return rc;
32619 }
32620 UINT32 response_size;
32621 std::string response_size_bytes;
32622 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32623 if (rc != TPM_RC_SUCCESS) {
32624 return rc;
32625 }
32626 TPM_RC response_code;
32627 std::string response_code_bytes;
32628 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32629 if (rc != TPM_RC_SUCCESS) {
32630 return rc;
32631 }
32632 if (response_size != response.size()) {
32633 return TPM_RC_SIZE;
32634 }
32635 if (response_code != TPM_RC_SUCCESS) {
32636 return response_code;
32637 }
32638 TPM_CC command_code = TPM_CC_NV_GlobalWriteLock;
32639 std::string command_code_bytes;
32640 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32641 if (rc != TPM_RC_SUCCESS) {
32642 return rc;
32643 }
32644 std::string authorization_section_bytes;
32645 if (tag == TPM_ST_SESSIONS) {
32646 UINT32 parameter_section_size = buffer.size();
32647 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
32648 if (rc != TPM_RC_SUCCESS) {
32649 return rc;
32650 }
32651 if (parameter_section_size > buffer.size()) {
32652 return TPM_RC_INSUFFICIENT;
32653 }
32654 authorization_section_bytes = buffer.substr(parameter_section_size);
32655 // Keep the parameter section in |buffer|.
32656 buffer.erase(parameter_section_size);
32657 }
32658 std::unique_ptr<crypto::SecureHash> hash(
32659 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32660 hash->Update(response_code_bytes.data(), response_code_bytes.size());
32661 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32662 hash->Update(buffer.data(), buffer.size());
32663 std::string response_hash(32, 0);
32664 hash->Finish(std::data(response_hash), response_hash.size());
32665 if (tag == TPM_ST_SESSIONS) {
32666 if (!authorization_delegate)
32667 return TRUNKS_RC_AUTHORIZATION_FAILED;
32668 if (!authorization_delegate->CheckResponseAuthorization(
32669 response_hash, authorization_section_bytes)) {
32670 return TRUNKS_RC_AUTHORIZATION_FAILED;
32671 }
32672 }
32673 return TPM_RC_SUCCESS;
32674 }
32675
NV_GlobalWriteLockErrorCallback(Tpm::NV_GlobalWriteLockResponse callback,TPM_RC response_code)32676 void NV_GlobalWriteLockErrorCallback(Tpm::NV_GlobalWriteLockResponse callback,
32677 TPM_RC response_code) {
32678 VLOG(1) << __func__;
32679 std::move(callback).Run(response_code);
32680 }
32681
NV_GlobalWriteLockResponseParser(Tpm::NV_GlobalWriteLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32682 void NV_GlobalWriteLockResponseParser(
32683 Tpm::NV_GlobalWriteLockResponse callback,
32684 AuthorizationDelegate* authorization_delegate,
32685 const std::string& response) {
32686 VLOG(1) << __func__;
32687 TPM_RC rc =
32688 Tpm::ParseResponse_NV_GlobalWriteLock(response, authorization_delegate);
32689 if (rc != TPM_RC_SUCCESS) {
32690 base::OnceCallback<void(TPM_RC)> error_reporter =
32691 base::BindOnce(NV_GlobalWriteLockErrorCallback, std::move(callback));
32692 std::move(error_reporter).Run(rc);
32693 return;
32694 }
32695 std::move(callback).Run(rc);
32696 }
32697
NV_GlobalWriteLock(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,NV_GlobalWriteLockResponse callback)32698 void Tpm::NV_GlobalWriteLock(const TPMI_RH_PROVISION& auth_handle,
32699 const std::string& auth_handle_name,
32700 AuthorizationDelegate* authorization_delegate,
32701 NV_GlobalWriteLockResponse callback) {
32702 VLOG(1) << __func__;
32703 std::string command;
32704 TPM_RC rc = SerializeCommand_NV_GlobalWriteLock(
32705 auth_handle, auth_handle_name, &command, authorization_delegate);
32706 if (rc != TPM_RC_SUCCESS) {
32707 base::OnceCallback<void(TPM_RC)> error_reporter =
32708 base::BindOnce(NV_GlobalWriteLockErrorCallback, std::move(callback));
32709 std::move(error_reporter).Run(rc);
32710 return;
32711 }
32712 base::OnceCallback<void(const std::string&)> parser =
32713 base::BindOnce(NV_GlobalWriteLockResponseParser, std::move(callback),
32714 authorization_delegate);
32715 transceiver_->SendCommand(command, std::move(parser));
32716 }
32717
NV_GlobalWriteLockSync(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)32718 TPM_RC Tpm::NV_GlobalWriteLockSync(
32719 const TPMI_RH_PROVISION& auth_handle,
32720 const std::string& auth_handle_name,
32721 AuthorizationDelegate* authorization_delegate) {
32722 VLOG(1) << __func__;
32723 std::string command;
32724 TPM_RC rc = SerializeCommand_NV_GlobalWriteLock(
32725 auth_handle, auth_handle_name, &command, authorization_delegate);
32726 if (rc != TPM_RC_SUCCESS) {
32727 return rc;
32728 }
32729 std::string response = transceiver_->SendCommandAndWait(command);
32730 rc = ParseResponse_NV_GlobalWriteLock(response, authorization_delegate);
32731 return rc;
32732 }
32733
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)32734 TPM_RC Tpm::SerializeCommand_NV_Read(
32735 const TPMI_RH_NV_AUTH& auth_handle,
32736 const std::string& auth_handle_name,
32737 const TPMI_RH_NV_INDEX& nv_index,
32738 const std::string& nv_index_name,
32739 const UINT16& size,
32740 const UINT16& offset,
32741 std::string* serialized_command,
32742 AuthorizationDelegate* authorization_delegate) {
32743 VLOG(3) << __func__;
32744 TPM_RC rc = TPM_RC_SUCCESS;
32745 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32746 UINT32 command_size = 10; // Header size.
32747 std::string handle_section_bytes;
32748 std::string parameter_section_bytes;
32749 TPM_CC command_code = TPM_CC_NV_Read;
32750 bool is_command_parameter_encryption_possible = false;
32751 bool is_response_parameter_encryption_possible = true;
32752 std::string command_code_bytes;
32753 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32754 if (rc != TPM_RC_SUCCESS) {
32755 return rc;
32756 }
32757 std::string auth_handle_bytes;
32758 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32759 if (rc != TPM_RC_SUCCESS) {
32760 return rc;
32761 }
32762 std::string nv_index_bytes;
32763 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32764 if (rc != TPM_RC_SUCCESS) {
32765 return rc;
32766 }
32767 std::string size_bytes;
32768 rc = Serialize_UINT16(size, &size_bytes);
32769 if (rc != TPM_RC_SUCCESS) {
32770 return rc;
32771 }
32772 std::string offset_bytes;
32773 rc = Serialize_UINT16(offset, &offset_bytes);
32774 if (rc != TPM_RC_SUCCESS) {
32775 return rc;
32776 }
32777 std::unique_ptr<crypto::SecureHash> hash(
32778 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32779 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32780 hash->Update(auth_handle_name.data(), auth_handle_name.size());
32781 handle_section_bytes += auth_handle_bytes;
32782 command_size += auth_handle_bytes.size();
32783 hash->Update(nv_index_name.data(), nv_index_name.size());
32784 handle_section_bytes += nv_index_bytes;
32785 command_size += nv_index_bytes.size();
32786 hash->Update(size_bytes.data(), size_bytes.size());
32787 parameter_section_bytes += size_bytes;
32788 command_size += size_bytes.size();
32789 hash->Update(offset_bytes.data(), offset_bytes.size());
32790 parameter_section_bytes += offset_bytes;
32791 command_size += offset_bytes.size();
32792 std::string command_hash(32, 0);
32793 hash->Finish(std::data(command_hash), command_hash.size());
32794 std::string authorization_section_bytes;
32795 std::string authorization_size_bytes;
32796 if (authorization_delegate) {
32797 if (!authorization_delegate->GetCommandAuthorization(
32798 command_hash, is_command_parameter_encryption_possible,
32799 is_response_parameter_encryption_possible,
32800 &authorization_section_bytes)) {
32801 return TRUNKS_RC_AUTHORIZATION_FAILED;
32802 }
32803 if (!authorization_section_bytes.empty()) {
32804 tag = TPM_ST_SESSIONS;
32805 std::string tmp;
32806 rc = Serialize_UINT32(authorization_section_bytes.size(),
32807 &authorization_size_bytes);
32808 if (rc != TPM_RC_SUCCESS) {
32809 return rc;
32810 }
32811 command_size +=
32812 authorization_size_bytes.size() + authorization_section_bytes.size();
32813 }
32814 }
32815 std::string tag_bytes;
32816 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32817 if (rc != TPM_RC_SUCCESS) {
32818 return rc;
32819 }
32820 std::string command_size_bytes;
32821 rc = Serialize_UINT32(command_size, &command_size_bytes);
32822 if (rc != TPM_RC_SUCCESS) {
32823 return rc;
32824 }
32825 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32826 handle_section_bytes + authorization_size_bytes +
32827 authorization_section_bytes + parameter_section_bytes;
32828 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32829 VLOG(2) << "Command: "
32830 << base::HexEncode(serialized_command->data(),
32831 serialized_command->size());
32832 return TPM_RC_SUCCESS;
32833 }
32834
ParseResponse_NV_Read(const std::string & response,TPM2B_MAX_NV_BUFFER * data,AuthorizationDelegate * authorization_delegate)32835 TPM_RC Tpm::ParseResponse_NV_Read(
32836 const std::string& response,
32837 TPM2B_MAX_NV_BUFFER* data,
32838 AuthorizationDelegate* authorization_delegate) {
32839 VLOG(3) << __func__;
32840 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32841 TPM_RC rc = TPM_RC_SUCCESS;
32842 std::string buffer(response);
32843 TPM_ST tag;
32844 std::string tag_bytes;
32845 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32846 if (rc != TPM_RC_SUCCESS) {
32847 return rc;
32848 }
32849 UINT32 response_size;
32850 std::string response_size_bytes;
32851 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32852 if (rc != TPM_RC_SUCCESS) {
32853 return rc;
32854 }
32855 TPM_RC response_code;
32856 std::string response_code_bytes;
32857 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32858 if (rc != TPM_RC_SUCCESS) {
32859 return rc;
32860 }
32861 if (response_size != response.size()) {
32862 return TPM_RC_SIZE;
32863 }
32864 if (response_code != TPM_RC_SUCCESS) {
32865 return response_code;
32866 }
32867 TPM_CC command_code = TPM_CC_NV_Read;
32868 std::string command_code_bytes;
32869 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32870 if (rc != TPM_RC_SUCCESS) {
32871 return rc;
32872 }
32873 std::string authorization_section_bytes;
32874 if (tag == TPM_ST_SESSIONS) {
32875 UINT32 parameter_section_size = buffer.size();
32876 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
32877 if (rc != TPM_RC_SUCCESS) {
32878 return rc;
32879 }
32880 if (parameter_section_size > buffer.size()) {
32881 return TPM_RC_INSUFFICIENT;
32882 }
32883 authorization_section_bytes = buffer.substr(parameter_section_size);
32884 // Keep the parameter section in |buffer|.
32885 buffer.erase(parameter_section_size);
32886 }
32887 std::unique_ptr<crypto::SecureHash> hash(
32888 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32889 hash->Update(response_code_bytes.data(), response_code_bytes.size());
32890 hash->Update(command_code_bytes.data(), command_code_bytes.size());
32891 hash->Update(buffer.data(), buffer.size());
32892 std::string response_hash(32, 0);
32893 hash->Finish(std::data(response_hash), response_hash.size());
32894 if (tag == TPM_ST_SESSIONS) {
32895 if (!authorization_delegate)
32896 return TRUNKS_RC_AUTHORIZATION_FAILED;
32897 if (!authorization_delegate->CheckResponseAuthorization(
32898 response_hash, authorization_section_bytes)) {
32899 return TRUNKS_RC_AUTHORIZATION_FAILED;
32900 }
32901 }
32902 if (tag == TPM_ST_SESSIONS) {
32903 if (!authorization_delegate)
32904 return TRUNKS_RC_AUTHORIZATION_FAILED;
32905
32906 // Parse the encrypted parameter size.
32907 UINT16 size;
32908 std::string size_buffer = buffer.substr(0, 2);
32909 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
32910 return result;
32911 }
32912 if (buffer.size() < 2 + size) {
32913 return TPM_RC_INSUFFICIENT;
32914 }
32915
32916 // Decrypt just the parameter data, not the size.
32917 std::string decrypted_data = buffer.substr(2, size);
32918 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
32919 return TRUNKS_RC_ENCRYPTION_FAILED;
32920 }
32921 buffer.replace(2, size, decrypted_data);
32922 }
32923 std::string data_bytes;
32924 rc = Parse_TPM2B_MAX_NV_BUFFER(&buffer, data, &data_bytes);
32925 if (rc != TPM_RC_SUCCESS) {
32926 return rc;
32927 }
32928 return TPM_RC_SUCCESS;
32929 }
32930
NV_ReadErrorCallback(Tpm::NV_ReadResponse callback,TPM_RC response_code)32931 void NV_ReadErrorCallback(Tpm::NV_ReadResponse callback, TPM_RC response_code) {
32932 VLOG(1) << __func__;
32933 std::move(callback).Run(response_code, TPM2B_MAX_NV_BUFFER());
32934 }
32935
NV_ReadResponseParser(Tpm::NV_ReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32936 void NV_ReadResponseParser(Tpm::NV_ReadResponse callback,
32937 AuthorizationDelegate* authorization_delegate,
32938 const std::string& response) {
32939 VLOG(1) << __func__;
32940 TPM2B_MAX_NV_BUFFER data;
32941 TPM_RC rc =
32942 Tpm::ParseResponse_NV_Read(response, &data, authorization_delegate);
32943 if (rc != TPM_RC_SUCCESS) {
32944 base::OnceCallback<void(TPM_RC)> error_reporter =
32945 base::BindOnce(NV_ReadErrorCallback, std::move(callback));
32946 std::move(error_reporter).Run(rc);
32947 return;
32948 }
32949 std::move(callback).Run(rc, data);
32950 }
32951
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)32952 void Tpm::NV_Read(const TPMI_RH_NV_AUTH& auth_handle,
32953 const std::string& auth_handle_name,
32954 const TPMI_RH_NV_INDEX& nv_index,
32955 const std::string& nv_index_name,
32956 const UINT16& size,
32957 const UINT16& offset,
32958 AuthorizationDelegate* authorization_delegate,
32959 NV_ReadResponse callback) {
32960 VLOG(1) << __func__;
32961 std::string command;
32962 TPM_RC rc = SerializeCommand_NV_Read(auth_handle, auth_handle_name, nv_index,
32963 nv_index_name, size, offset, &command,
32964 authorization_delegate);
32965 if (rc != TPM_RC_SUCCESS) {
32966 base::OnceCallback<void(TPM_RC)> error_reporter =
32967 base::BindOnce(NV_ReadErrorCallback, std::move(callback));
32968 std::move(error_reporter).Run(rc);
32969 return;
32970 }
32971 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32972 NV_ReadResponseParser, std::move(callback), authorization_delegate);
32973 transceiver_->SendCommand(command, std::move(parser));
32974 }
32975
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)32976 TPM_RC Tpm::NV_ReadSync(const TPMI_RH_NV_AUTH& auth_handle,
32977 const std::string& auth_handle_name,
32978 const TPMI_RH_NV_INDEX& nv_index,
32979 const std::string& nv_index_name,
32980 const UINT16& size,
32981 const UINT16& offset,
32982 TPM2B_MAX_NV_BUFFER* data,
32983 AuthorizationDelegate* authorization_delegate) {
32984 VLOG(1) << __func__;
32985 std::string command;
32986 TPM_RC rc = SerializeCommand_NV_Read(auth_handle, auth_handle_name, nv_index,
32987 nv_index_name, size, offset, &command,
32988 authorization_delegate);
32989 if (rc != TPM_RC_SUCCESS) {
32990 return rc;
32991 }
32992 std::string response = transceiver_->SendCommandAndWait(command);
32993 rc = ParseResponse_NV_Read(response, data, authorization_delegate);
32994 return rc;
32995 }
32996
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)32997 TPM_RC Tpm::SerializeCommand_NV_ReadLock(
32998 const TPMI_RH_NV_AUTH& auth_handle,
32999 const std::string& auth_handle_name,
33000 const TPMI_RH_NV_INDEX& nv_index,
33001 const std::string& nv_index_name,
33002 std::string* serialized_command,
33003 AuthorizationDelegate* authorization_delegate) {
33004 VLOG(3) << __func__;
33005 TPM_RC rc = TPM_RC_SUCCESS;
33006 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33007 UINT32 command_size = 10; // Header size.
33008 std::string handle_section_bytes;
33009 std::string parameter_section_bytes;
33010 TPM_CC command_code = TPM_CC_NV_ReadLock;
33011 bool is_command_parameter_encryption_possible = false;
33012 bool is_response_parameter_encryption_possible = false;
33013 std::string command_code_bytes;
33014 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33015 if (rc != TPM_RC_SUCCESS) {
33016 return rc;
33017 }
33018 std::string auth_handle_bytes;
33019 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
33020 if (rc != TPM_RC_SUCCESS) {
33021 return rc;
33022 }
33023 std::string nv_index_bytes;
33024 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33025 if (rc != TPM_RC_SUCCESS) {
33026 return rc;
33027 }
33028 std::unique_ptr<crypto::SecureHash> hash(
33029 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33030 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33031 hash->Update(auth_handle_name.data(), auth_handle_name.size());
33032 handle_section_bytes += auth_handle_bytes;
33033 command_size += auth_handle_bytes.size();
33034 hash->Update(nv_index_name.data(), nv_index_name.size());
33035 handle_section_bytes += nv_index_bytes;
33036 command_size += nv_index_bytes.size();
33037 std::string command_hash(32, 0);
33038 hash->Finish(std::data(command_hash), command_hash.size());
33039 std::string authorization_section_bytes;
33040 std::string authorization_size_bytes;
33041 if (authorization_delegate) {
33042 if (!authorization_delegate->GetCommandAuthorization(
33043 command_hash, is_command_parameter_encryption_possible,
33044 is_response_parameter_encryption_possible,
33045 &authorization_section_bytes)) {
33046 return TRUNKS_RC_AUTHORIZATION_FAILED;
33047 }
33048 if (!authorization_section_bytes.empty()) {
33049 tag = TPM_ST_SESSIONS;
33050 std::string tmp;
33051 rc = Serialize_UINT32(authorization_section_bytes.size(),
33052 &authorization_size_bytes);
33053 if (rc != TPM_RC_SUCCESS) {
33054 return rc;
33055 }
33056 command_size +=
33057 authorization_size_bytes.size() + authorization_section_bytes.size();
33058 }
33059 }
33060 std::string tag_bytes;
33061 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33062 if (rc != TPM_RC_SUCCESS) {
33063 return rc;
33064 }
33065 std::string command_size_bytes;
33066 rc = Serialize_UINT32(command_size, &command_size_bytes);
33067 if (rc != TPM_RC_SUCCESS) {
33068 return rc;
33069 }
33070 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33071 handle_section_bytes + authorization_size_bytes +
33072 authorization_section_bytes + parameter_section_bytes;
33073 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33074 VLOG(2) << "Command: "
33075 << base::HexEncode(serialized_command->data(),
33076 serialized_command->size());
33077 return TPM_RC_SUCCESS;
33078 }
33079
ParseResponse_NV_ReadLock(const std::string & response,AuthorizationDelegate * authorization_delegate)33080 TPM_RC Tpm::ParseResponse_NV_ReadLock(
33081 const std::string& response,
33082 AuthorizationDelegate* authorization_delegate) {
33083 VLOG(3) << __func__;
33084 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33085 TPM_RC rc = TPM_RC_SUCCESS;
33086 std::string buffer(response);
33087 TPM_ST tag;
33088 std::string tag_bytes;
33089 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33090 if (rc != TPM_RC_SUCCESS) {
33091 return rc;
33092 }
33093 UINT32 response_size;
33094 std::string response_size_bytes;
33095 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33096 if (rc != TPM_RC_SUCCESS) {
33097 return rc;
33098 }
33099 TPM_RC response_code;
33100 std::string response_code_bytes;
33101 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33102 if (rc != TPM_RC_SUCCESS) {
33103 return rc;
33104 }
33105 if (response_size != response.size()) {
33106 return TPM_RC_SIZE;
33107 }
33108 if (response_code != TPM_RC_SUCCESS) {
33109 return response_code;
33110 }
33111 TPM_CC command_code = TPM_CC_NV_ReadLock;
33112 std::string command_code_bytes;
33113 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33114 if (rc != TPM_RC_SUCCESS) {
33115 return rc;
33116 }
33117 std::string authorization_section_bytes;
33118 if (tag == TPM_ST_SESSIONS) {
33119 UINT32 parameter_section_size = buffer.size();
33120 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
33121 if (rc != TPM_RC_SUCCESS) {
33122 return rc;
33123 }
33124 if (parameter_section_size > buffer.size()) {
33125 return TPM_RC_INSUFFICIENT;
33126 }
33127 authorization_section_bytes = buffer.substr(parameter_section_size);
33128 // Keep the parameter section in |buffer|.
33129 buffer.erase(parameter_section_size);
33130 }
33131 std::unique_ptr<crypto::SecureHash> hash(
33132 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33133 hash->Update(response_code_bytes.data(), response_code_bytes.size());
33134 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33135 hash->Update(buffer.data(), buffer.size());
33136 std::string response_hash(32, 0);
33137 hash->Finish(std::data(response_hash), response_hash.size());
33138 if (tag == TPM_ST_SESSIONS) {
33139 if (!authorization_delegate)
33140 return TRUNKS_RC_AUTHORIZATION_FAILED;
33141 if (!authorization_delegate->CheckResponseAuthorization(
33142 response_hash, authorization_section_bytes)) {
33143 return TRUNKS_RC_AUTHORIZATION_FAILED;
33144 }
33145 }
33146 return TPM_RC_SUCCESS;
33147 }
33148
NV_ReadLockErrorCallback(Tpm::NV_ReadLockResponse callback,TPM_RC response_code)33149 void NV_ReadLockErrorCallback(Tpm::NV_ReadLockResponse callback,
33150 TPM_RC response_code) {
33151 VLOG(1) << __func__;
33152 std::move(callback).Run(response_code);
33153 }
33154
NV_ReadLockResponseParser(Tpm::NV_ReadLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33155 void NV_ReadLockResponseParser(Tpm::NV_ReadLockResponse callback,
33156 AuthorizationDelegate* authorization_delegate,
33157 const std::string& response) {
33158 VLOG(1) << __func__;
33159 TPM_RC rc = Tpm::ParseResponse_NV_ReadLock(response, authorization_delegate);
33160 if (rc != TPM_RC_SUCCESS) {
33161 base::OnceCallback<void(TPM_RC)> error_reporter =
33162 base::BindOnce(NV_ReadLockErrorCallback, std::move(callback));
33163 std::move(error_reporter).Run(rc);
33164 return;
33165 }
33166 std::move(callback).Run(rc);
33167 }
33168
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)33169 void Tpm::NV_ReadLock(const TPMI_RH_NV_AUTH& auth_handle,
33170 const std::string& auth_handle_name,
33171 const TPMI_RH_NV_INDEX& nv_index,
33172 const std::string& nv_index_name,
33173 AuthorizationDelegate* authorization_delegate,
33174 NV_ReadLockResponse callback) {
33175 VLOG(1) << __func__;
33176 std::string command;
33177 TPM_RC rc = SerializeCommand_NV_ReadLock(auth_handle, auth_handle_name,
33178 nv_index, nv_index_name, &command,
33179 authorization_delegate);
33180 if (rc != TPM_RC_SUCCESS) {
33181 base::OnceCallback<void(TPM_RC)> error_reporter =
33182 base::BindOnce(NV_ReadLockErrorCallback, std::move(callback));
33183 std::move(error_reporter).Run(rc);
33184 return;
33185 }
33186 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33187 NV_ReadLockResponseParser, std::move(callback), authorization_delegate);
33188 transceiver_->SendCommand(command, std::move(parser));
33189 }
33190
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)33191 TPM_RC Tpm::NV_ReadLockSync(const TPMI_RH_NV_AUTH& auth_handle,
33192 const std::string& auth_handle_name,
33193 const TPMI_RH_NV_INDEX& nv_index,
33194 const std::string& nv_index_name,
33195 AuthorizationDelegate* authorization_delegate) {
33196 VLOG(1) << __func__;
33197 std::string command;
33198 TPM_RC rc = SerializeCommand_NV_ReadLock(auth_handle, auth_handle_name,
33199 nv_index, nv_index_name, &command,
33200 authorization_delegate);
33201 if (rc != TPM_RC_SUCCESS) {
33202 return rc;
33203 }
33204 std::string response = transceiver_->SendCommandAndWait(command);
33205 rc = ParseResponse_NV_ReadLock(response, authorization_delegate);
33206 return rc;
33207 }
33208
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)33209 TPM_RC Tpm::SerializeCommand_NV_ChangeAuth(
33210 const TPMI_RH_NV_INDEX& nv_index,
33211 const std::string& nv_index_name,
33212 const TPM2B_AUTH& new_auth,
33213 std::string* serialized_command,
33214 AuthorizationDelegate* authorization_delegate) {
33215 VLOG(3) << __func__;
33216 TPM_RC rc = TPM_RC_SUCCESS;
33217 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33218 UINT32 command_size = 10; // Header size.
33219 std::string handle_section_bytes;
33220 std::string parameter_section_bytes;
33221 TPM_CC command_code = TPM_CC_NV_ChangeAuth;
33222 bool is_command_parameter_encryption_possible = true;
33223 bool is_response_parameter_encryption_possible = false;
33224 std::string command_code_bytes;
33225 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33226 if (rc != TPM_RC_SUCCESS) {
33227 return rc;
33228 }
33229 std::string nv_index_bytes;
33230 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33231 if (rc != TPM_RC_SUCCESS) {
33232 return rc;
33233 }
33234 std::string new_auth_bytes;
33235 rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
33236 if (rc != TPM_RC_SUCCESS) {
33237 return rc;
33238 }
33239 if (authorization_delegate) {
33240 // Encrypt just the parameter data, not the size.
33241 std::string tmp = new_auth_bytes.substr(2);
33242 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
33243 return TRUNKS_RC_ENCRYPTION_FAILED;
33244 }
33245 new_auth_bytes.replace(2, std::string::npos, tmp);
33246 }
33247 std::unique_ptr<crypto::SecureHash> hash(
33248 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33249 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33250 hash->Update(nv_index_name.data(), nv_index_name.size());
33251 handle_section_bytes += nv_index_bytes;
33252 command_size += nv_index_bytes.size();
33253 hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
33254 parameter_section_bytes += new_auth_bytes;
33255 command_size += new_auth_bytes.size();
33256 std::string command_hash(32, 0);
33257 hash->Finish(std::data(command_hash), command_hash.size());
33258 std::string authorization_section_bytes;
33259 std::string authorization_size_bytes;
33260 if (authorization_delegate) {
33261 if (!authorization_delegate->GetCommandAuthorization(
33262 command_hash, is_command_parameter_encryption_possible,
33263 is_response_parameter_encryption_possible,
33264 &authorization_section_bytes)) {
33265 return TRUNKS_RC_AUTHORIZATION_FAILED;
33266 }
33267 if (!authorization_section_bytes.empty()) {
33268 tag = TPM_ST_SESSIONS;
33269 std::string tmp;
33270 rc = Serialize_UINT32(authorization_section_bytes.size(),
33271 &authorization_size_bytes);
33272 if (rc != TPM_RC_SUCCESS) {
33273 return rc;
33274 }
33275 command_size +=
33276 authorization_size_bytes.size() + authorization_section_bytes.size();
33277 }
33278 }
33279 std::string tag_bytes;
33280 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33281 if (rc != TPM_RC_SUCCESS) {
33282 return rc;
33283 }
33284 std::string command_size_bytes;
33285 rc = Serialize_UINT32(command_size, &command_size_bytes);
33286 if (rc != TPM_RC_SUCCESS) {
33287 return rc;
33288 }
33289 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33290 handle_section_bytes + authorization_size_bytes +
33291 authorization_section_bytes + parameter_section_bytes;
33292 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33293 VLOG(2) << "Command: "
33294 << base::HexEncode(serialized_command->data(),
33295 serialized_command->size());
33296 return TPM_RC_SUCCESS;
33297 }
33298
ParseResponse_NV_ChangeAuth(const std::string & response,AuthorizationDelegate * authorization_delegate)33299 TPM_RC Tpm::ParseResponse_NV_ChangeAuth(
33300 const std::string& response,
33301 AuthorizationDelegate* authorization_delegate) {
33302 VLOG(3) << __func__;
33303 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33304 TPM_RC rc = TPM_RC_SUCCESS;
33305 std::string buffer(response);
33306 TPM_ST tag;
33307 std::string tag_bytes;
33308 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33309 if (rc != TPM_RC_SUCCESS) {
33310 return rc;
33311 }
33312 UINT32 response_size;
33313 std::string response_size_bytes;
33314 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33315 if (rc != TPM_RC_SUCCESS) {
33316 return rc;
33317 }
33318 TPM_RC response_code;
33319 std::string response_code_bytes;
33320 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33321 if (rc != TPM_RC_SUCCESS) {
33322 return rc;
33323 }
33324 if (response_size != response.size()) {
33325 return TPM_RC_SIZE;
33326 }
33327 if (response_code != TPM_RC_SUCCESS) {
33328 return response_code;
33329 }
33330 TPM_CC command_code = TPM_CC_NV_ChangeAuth;
33331 std::string command_code_bytes;
33332 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33333 if (rc != TPM_RC_SUCCESS) {
33334 return rc;
33335 }
33336 std::string authorization_section_bytes;
33337 if (tag == TPM_ST_SESSIONS) {
33338 UINT32 parameter_section_size = buffer.size();
33339 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
33340 if (rc != TPM_RC_SUCCESS) {
33341 return rc;
33342 }
33343 if (parameter_section_size > buffer.size()) {
33344 return TPM_RC_INSUFFICIENT;
33345 }
33346 authorization_section_bytes = buffer.substr(parameter_section_size);
33347 // Keep the parameter section in |buffer|.
33348 buffer.erase(parameter_section_size);
33349 }
33350 std::unique_ptr<crypto::SecureHash> hash(
33351 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33352 hash->Update(response_code_bytes.data(), response_code_bytes.size());
33353 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33354 hash->Update(buffer.data(), buffer.size());
33355 std::string response_hash(32, 0);
33356 hash->Finish(std::data(response_hash), response_hash.size());
33357 if (tag == TPM_ST_SESSIONS) {
33358 if (!authorization_delegate)
33359 return TRUNKS_RC_AUTHORIZATION_FAILED;
33360 if (!authorization_delegate->CheckResponseAuthorization(
33361 response_hash, authorization_section_bytes)) {
33362 return TRUNKS_RC_AUTHORIZATION_FAILED;
33363 }
33364 }
33365 return TPM_RC_SUCCESS;
33366 }
33367
NV_ChangeAuthErrorCallback(Tpm::NV_ChangeAuthResponse callback,TPM_RC response_code)33368 void NV_ChangeAuthErrorCallback(Tpm::NV_ChangeAuthResponse callback,
33369 TPM_RC response_code) {
33370 VLOG(1) << __func__;
33371 std::move(callback).Run(response_code);
33372 }
33373
NV_ChangeAuthResponseParser(Tpm::NV_ChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33374 void NV_ChangeAuthResponseParser(Tpm::NV_ChangeAuthResponse callback,
33375 AuthorizationDelegate* authorization_delegate,
33376 const std::string& response) {
33377 VLOG(1) << __func__;
33378 TPM_RC rc =
33379 Tpm::ParseResponse_NV_ChangeAuth(response, authorization_delegate);
33380 if (rc != TPM_RC_SUCCESS) {
33381 base::OnceCallback<void(TPM_RC)> error_reporter =
33382 base::BindOnce(NV_ChangeAuthErrorCallback, std::move(callback));
33383 std::move(error_reporter).Run(rc);
33384 return;
33385 }
33386 std::move(callback).Run(rc);
33387 }
33388
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)33389 void Tpm::NV_ChangeAuth(const TPMI_RH_NV_INDEX& nv_index,
33390 const std::string& nv_index_name,
33391 const TPM2B_AUTH& new_auth,
33392 AuthorizationDelegate* authorization_delegate,
33393 NV_ChangeAuthResponse callback) {
33394 VLOG(1) << __func__;
33395 std::string command;
33396 TPM_RC rc = SerializeCommand_NV_ChangeAuth(nv_index, nv_index_name, new_auth,
33397 &command, authorization_delegate);
33398 if (rc != TPM_RC_SUCCESS) {
33399 base::OnceCallback<void(TPM_RC)> error_reporter =
33400 base::BindOnce(NV_ChangeAuthErrorCallback, std::move(callback));
33401 std::move(error_reporter).Run(rc);
33402 return;
33403 }
33404 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33405 NV_ChangeAuthResponseParser, std::move(callback), authorization_delegate);
33406 transceiver_->SendCommand(command, std::move(parser));
33407 }
33408
NV_ChangeAuthSync(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate)33409 TPM_RC Tpm::NV_ChangeAuthSync(const TPMI_RH_NV_INDEX& nv_index,
33410 const std::string& nv_index_name,
33411 const TPM2B_AUTH& new_auth,
33412 AuthorizationDelegate* authorization_delegate) {
33413 VLOG(1) << __func__;
33414 std::string command;
33415 TPM_RC rc = SerializeCommand_NV_ChangeAuth(nv_index, nv_index_name, new_auth,
33416 &command, authorization_delegate);
33417 if (rc != TPM_RC_SUCCESS) {
33418 return rc;
33419 }
33420 std::string response = transceiver_->SendCommandAndWait(command);
33421 rc = ParseResponse_NV_ChangeAuth(response, authorization_delegate);
33422 return rc;
33423 }
33424
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)33425 TPM_RC Tpm::SerializeCommand_NV_Certify(
33426 const TPMI_DH_OBJECT& sign_handle,
33427 const std::string& sign_handle_name,
33428 const TPMI_RH_NV_AUTH& auth_handle,
33429 const std::string& auth_handle_name,
33430 const TPMI_RH_NV_INDEX& nv_index,
33431 const std::string& nv_index_name,
33432 const TPM2B_DATA& qualifying_data,
33433 const TPMT_SIG_SCHEME& in_scheme,
33434 const UINT16& size,
33435 const UINT16& offset,
33436 std::string* serialized_command,
33437 AuthorizationDelegate* authorization_delegate) {
33438 VLOG(3) << __func__;
33439 TPM_RC rc = TPM_RC_SUCCESS;
33440 TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33441 UINT32 command_size = 10; // Header size.
33442 std::string handle_section_bytes;
33443 std::string parameter_section_bytes;
33444 TPM_CC command_code = TPM_CC_NV_Certify;
33445 bool is_command_parameter_encryption_possible = true;
33446 bool is_response_parameter_encryption_possible = true;
33447 std::string command_code_bytes;
33448 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33449 if (rc != TPM_RC_SUCCESS) {
33450 return rc;
33451 }
33452 std::string sign_handle_bytes;
33453 rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
33454 if (rc != TPM_RC_SUCCESS) {
33455 return rc;
33456 }
33457 std::string auth_handle_bytes;
33458 rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
33459 if (rc != TPM_RC_SUCCESS) {
33460 return rc;
33461 }
33462 std::string nv_index_bytes;
33463 rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33464 if (rc != TPM_RC_SUCCESS) {
33465 return rc;
33466 }
33467 std::string qualifying_data_bytes;
33468 rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
33469 if (rc != TPM_RC_SUCCESS) {
33470 return rc;
33471 }
33472 std::string in_scheme_bytes;
33473 rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
33474 if (rc != TPM_RC_SUCCESS) {
33475 return rc;
33476 }
33477 std::string size_bytes;
33478 rc = Serialize_UINT16(size, &size_bytes);
33479 if (rc != TPM_RC_SUCCESS) {
33480 return rc;
33481 }
33482 std::string offset_bytes;
33483 rc = Serialize_UINT16(offset, &offset_bytes);
33484 if (rc != TPM_RC_SUCCESS) {
33485 return rc;
33486 }
33487 if (authorization_delegate) {
33488 // Encrypt just the parameter data, not the size.
33489 std::string tmp = qualifying_data_bytes.substr(2);
33490 if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
33491 return TRUNKS_RC_ENCRYPTION_FAILED;
33492 }
33493 qualifying_data_bytes.replace(2, std::string::npos, tmp);
33494 }
33495 std::unique_ptr<crypto::SecureHash> hash(
33496 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33497 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33498 hash->Update(sign_handle_name.data(), sign_handle_name.size());
33499 handle_section_bytes += sign_handle_bytes;
33500 command_size += sign_handle_bytes.size();
33501 hash->Update(auth_handle_name.data(), auth_handle_name.size());
33502 handle_section_bytes += auth_handle_bytes;
33503 command_size += auth_handle_bytes.size();
33504 hash->Update(nv_index_name.data(), nv_index_name.size());
33505 handle_section_bytes += nv_index_bytes;
33506 command_size += nv_index_bytes.size();
33507 hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
33508 parameter_section_bytes += qualifying_data_bytes;
33509 command_size += qualifying_data_bytes.size();
33510 hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
33511 parameter_section_bytes += in_scheme_bytes;
33512 command_size += in_scheme_bytes.size();
33513 hash->Update(size_bytes.data(), size_bytes.size());
33514 parameter_section_bytes += size_bytes;
33515 command_size += size_bytes.size();
33516 hash->Update(offset_bytes.data(), offset_bytes.size());
33517 parameter_section_bytes += offset_bytes;
33518 command_size += offset_bytes.size();
33519 std::string command_hash(32, 0);
33520 hash->Finish(std::data(command_hash), command_hash.size());
33521 std::string authorization_section_bytes;
33522 std::string authorization_size_bytes;
33523 if (authorization_delegate) {
33524 if (!authorization_delegate->GetCommandAuthorization(
33525 command_hash, is_command_parameter_encryption_possible,
33526 is_response_parameter_encryption_possible,
33527 &authorization_section_bytes)) {
33528 return TRUNKS_RC_AUTHORIZATION_FAILED;
33529 }
33530 if (!authorization_section_bytes.empty()) {
33531 tag = TPM_ST_SESSIONS;
33532 std::string tmp;
33533 rc = Serialize_UINT32(authorization_section_bytes.size(),
33534 &authorization_size_bytes);
33535 if (rc != TPM_RC_SUCCESS) {
33536 return rc;
33537 }
33538 command_size +=
33539 authorization_size_bytes.size() + authorization_section_bytes.size();
33540 }
33541 }
33542 std::string tag_bytes;
33543 rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33544 if (rc != TPM_RC_SUCCESS) {
33545 return rc;
33546 }
33547 std::string command_size_bytes;
33548 rc = Serialize_UINT32(command_size, &command_size_bytes);
33549 if (rc != TPM_RC_SUCCESS) {
33550 return rc;
33551 }
33552 *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33553 handle_section_bytes + authorization_size_bytes +
33554 authorization_section_bytes + parameter_section_bytes;
33555 CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33556 VLOG(2) << "Command: "
33557 << base::HexEncode(serialized_command->data(),
33558 serialized_command->size());
33559 return TPM_RC_SUCCESS;
33560 }
33561
ParseResponse_NV_Certify(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)33562 TPM_RC Tpm::ParseResponse_NV_Certify(
33563 const std::string& response,
33564 TPM2B_ATTEST* certify_info,
33565 TPMT_SIGNATURE* signature,
33566 AuthorizationDelegate* authorization_delegate) {
33567 VLOG(3) << __func__;
33568 VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33569 TPM_RC rc = TPM_RC_SUCCESS;
33570 std::string buffer(response);
33571 TPM_ST tag;
33572 std::string tag_bytes;
33573 rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33574 if (rc != TPM_RC_SUCCESS) {
33575 return rc;
33576 }
33577 UINT32 response_size;
33578 std::string response_size_bytes;
33579 rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33580 if (rc != TPM_RC_SUCCESS) {
33581 return rc;
33582 }
33583 TPM_RC response_code;
33584 std::string response_code_bytes;
33585 rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33586 if (rc != TPM_RC_SUCCESS) {
33587 return rc;
33588 }
33589 if (response_size != response.size()) {
33590 return TPM_RC_SIZE;
33591 }
33592 if (response_code != TPM_RC_SUCCESS) {
33593 return response_code;
33594 }
33595 TPM_CC command_code = TPM_CC_NV_Certify;
33596 std::string command_code_bytes;
33597 rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33598 if (rc != TPM_RC_SUCCESS) {
33599 return rc;
33600 }
33601 std::string authorization_section_bytes;
33602 if (tag == TPM_ST_SESSIONS) {
33603 UINT32 parameter_section_size = buffer.size();
33604 rc = Parse_UINT32(&buffer, ¶meter_section_size, nullptr);
33605 if (rc != TPM_RC_SUCCESS) {
33606 return rc;
33607 }
33608 if (parameter_section_size > buffer.size()) {
33609 return TPM_RC_INSUFFICIENT;
33610 }
33611 authorization_section_bytes = buffer.substr(parameter_section_size);
33612 // Keep the parameter section in |buffer|.
33613 buffer.erase(parameter_section_size);
33614 }
33615 std::unique_ptr<crypto::SecureHash> hash(
33616 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33617 hash->Update(response_code_bytes.data(), response_code_bytes.size());
33618 hash->Update(command_code_bytes.data(), command_code_bytes.size());
33619 hash->Update(buffer.data(), buffer.size());
33620 std::string response_hash(32, 0);
33621 hash->Finish(std::data(response_hash), response_hash.size());
33622 if (tag == TPM_ST_SESSIONS) {
33623 if (!authorization_delegate)
33624 return TRUNKS_RC_AUTHORIZATION_FAILED;
33625 if (!authorization_delegate->CheckResponseAuthorization(
33626 response_hash, authorization_section_bytes)) {
33627 return TRUNKS_RC_AUTHORIZATION_FAILED;
33628 }
33629 }
33630 if (tag == TPM_ST_SESSIONS) {
33631 if (!authorization_delegate)
33632 return TRUNKS_RC_AUTHORIZATION_FAILED;
33633
33634 // Parse the encrypted parameter size.
33635 UINT16 size;
33636 std::string size_buffer = buffer.substr(0, 2);
33637 if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
33638 return result;
33639 }
33640 if (buffer.size() < 2 + size) {
33641 return TPM_RC_INSUFFICIENT;
33642 }
33643
33644 // Decrypt just the parameter data, not the size.
33645 std::string decrypted_data = buffer.substr(2, size);
33646 if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
33647 return TRUNKS_RC_ENCRYPTION_FAILED;
33648 }
33649 buffer.replace(2, size, decrypted_data);
33650 }
33651 std::string certify_info_bytes;
33652 rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
33653 if (rc != TPM_RC_SUCCESS) {
33654 return rc;
33655 }
33656 std::string signature_bytes;
33657 rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
33658 if (rc != TPM_RC_SUCCESS) {
33659 return rc;
33660 }
33661 return TPM_RC_SUCCESS;
33662 }
33663
NV_CertifyErrorCallback(Tpm::NV_CertifyResponse callback,TPM_RC response_code)33664 void NV_CertifyErrorCallback(Tpm::NV_CertifyResponse callback,
33665 TPM_RC response_code) {
33666 VLOG(1) << __func__;
33667 std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
33668 }
33669
NV_CertifyResponseParser(Tpm::NV_CertifyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33670 void NV_CertifyResponseParser(Tpm::NV_CertifyResponse callback,
33671 AuthorizationDelegate* authorization_delegate,
33672 const std::string& response) {
33673 VLOG(1) << __func__;
33674 TPM2B_ATTEST certify_info;
33675 TPMT_SIGNATURE signature;
33676 TPM_RC rc = Tpm::ParseResponse_NV_Certify(response, &certify_info, &signature,
33677 authorization_delegate);
33678 if (rc != TPM_RC_SUCCESS) {
33679 base::OnceCallback<void(TPM_RC)> error_reporter =
33680 base::BindOnce(NV_CertifyErrorCallback, std::move(callback));
33681 std::move(error_reporter).Run(rc);
33682 return;
33683 }
33684 std::move(callback).Run(rc, certify_info, signature);
33685 }
33686
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)33687 void Tpm::NV_Certify(const TPMI_DH_OBJECT& sign_handle,
33688 const std::string& sign_handle_name,
33689 const TPMI_RH_NV_AUTH& auth_handle,
33690 const std::string& auth_handle_name,
33691 const TPMI_RH_NV_INDEX& nv_index,
33692 const std::string& nv_index_name,
33693 const TPM2B_DATA& qualifying_data,
33694 const TPMT_SIG_SCHEME& in_scheme,
33695 const UINT16& size,
33696 const UINT16& offset,
33697 AuthorizationDelegate* authorization_delegate,
33698 NV_CertifyResponse callback) {
33699 VLOG(1) << __func__;
33700 std::string command;
33701 TPM_RC rc = SerializeCommand_NV_Certify(
33702 sign_handle, sign_handle_name, auth_handle, auth_handle_name, nv_index,
33703 nv_index_name, qualifying_data, in_scheme, size, offset, &command,
33704 authorization_delegate);
33705 if (rc != TPM_RC_SUCCESS) {
33706 base::OnceCallback<void(TPM_RC)> error_reporter =
33707 base::BindOnce(NV_CertifyErrorCallback, std::move(callback));
33708 std::move(error_reporter).Run(rc);
33709 return;
33710 }
33711 base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33712 NV_CertifyResponseParser, std::move(callback), authorization_delegate);
33713 transceiver_->SendCommand(command, std::move(parser));
33714 }
33715
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)33716 TPM_RC Tpm::NV_CertifySync(const TPMI_DH_OBJECT& sign_handle,
33717 const std::string& sign_handle_name,
33718 const TPMI_RH_NV_AUTH& auth_handle,
33719 const std::string& auth_handle_name,
33720 const TPMI_RH_NV_INDEX& nv_index,
33721 const std::string& nv_index_name,
33722 const TPM2B_DATA& qualifying_data,
33723 const TPMT_SIG_SCHEME& in_scheme,
33724 const UINT16& size,
33725 const UINT16& offset,
33726 TPM2B_ATTEST* certify_info,
33727 TPMT_SIGNATURE* signature,
33728 AuthorizationDelegate* authorization_delegate) {
33729 VLOG(1) << __func__;
33730 std::string command;
33731 TPM_RC rc = SerializeCommand_NV_Certify(
33732 sign_handle, sign_handle_name, auth_handle, auth_handle_name, nv_index,
33733 nv_index_name, qualifying_data, in_scheme, size, offset, &command,
33734 authorization_delegate);
33735 if (rc != TPM_RC_SUCCESS) {
33736 return rc;
33737 }
33738 std::string response = transceiver_->SendCommandAndWait(command);
33739 rc = ParseResponse_NV_Certify(response, certify_info, signature,
33740 authorization_delegate);
33741 return rc;
33742 }
33743
33744 } // namespace trunks
33745