xref: /aosp_15_r20/external/gsc-utils/tpm_generated/tpm_generated.cc (revision 4f2df630800bdcf1d4f0decf95d8a1cb87344f5f)
1 // Copyright 2015 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // THIS CODE IS GENERATED - DO NOT MODIFY!
6 
7 #include "tpm_generated.h"
8 
9 #include <iterator>
10 #include <memory>
11 #include <string>
12 
13 #include <android-base/endian.h>
14 #include <android-base/logging.h>
15 #include <secure_hash.h>
16 
17 #include "authorization_delegate.h"
18 #include "callback.h"
19 #include "command_transceiver.h"
20 #include "error_codes.h"
21 
22 // Redirect VLOG invocations written for libchrome to android-base's LOG macro.
23 #define VLOG(x) LOG(INFO)
24 
25 namespace trunks {
26 
GetNumberOfRequestHandles(TPM_CC command_code)27 size_t GetNumberOfRequestHandles(TPM_CC command_code) {
28   switch (command_code) {
29     case TPM_CC_Startup:
30       return 0;
31     case TPM_CC_Shutdown:
32       return 0;
33     case TPM_CC_SelfTest:
34       return 0;
35     case TPM_CC_IncrementalSelfTest:
36       return 0;
37     case TPM_CC_GetTestResult:
38       return 0;
39     case TPM_CC_StartAuthSession:
40       return 2;
41     case TPM_CC_PolicyRestart:
42       return 1;
43     case TPM_CC_Create:
44       return 1;
45     case TPM_CC_Load:
46       return 1;
47     case TPM_CC_LoadExternal:
48       return 0;
49     case TPM_CC_ReadPublic:
50       return 1;
51     case TPM_CC_ActivateCredential:
52       return 2;
53     case TPM_CC_MakeCredential:
54       return 1;
55     case TPM_CC_Unseal:
56       return 1;
57     case TPM_CC_ObjectChangeAuth:
58       return 2;
59     case TPM_CC_Duplicate:
60       return 2;
61     case TPM_CC_Rewrap:
62       return 2;
63     case TPM_CC_Import:
64       return 1;
65     case TPM_CC_RSA_Encrypt:
66       return 1;
67     case TPM_CC_RSA_Decrypt:
68       return 1;
69     case TPM_CC_ECDH_KeyGen:
70       return 1;
71     case TPM_CC_ECDH_ZGen:
72       return 1;
73     case TPM_CC_ECC_Parameters:
74       return 0;
75     case TPM_CC_ZGen_2Phase:
76       return 1;
77     case TPM_CC_EncryptDecrypt:
78       return 1;
79     case TPM_CC_Hash:
80       return 0;
81     case TPM_CC_HMAC:
82       return 1;
83     case TPM_CC_GetRandom:
84       return 0;
85     case TPM_CC_StirRandom:
86       return 0;
87     case TPM_CC_HMAC_Start:
88       return 1;
89     case TPM_CC_HashSequenceStart:
90       return 0;
91     case TPM_CC_SequenceUpdate:
92       return 1;
93     case TPM_CC_SequenceComplete:
94       return 1;
95     case TPM_CC_EventSequenceComplete:
96       return 2;
97     case TPM_CC_Certify:
98       return 2;
99     case TPM_CC_CertifyCreation:
100       return 2;
101     case TPM_CC_Quote:
102       return 1;
103     case TPM_CC_GetSessionAuditDigest:
104       return 3;
105     case TPM_CC_GetCommandAuditDigest:
106       return 2;
107     case TPM_CC_GetTime:
108       return 2;
109     case TPM_CC_Commit:
110       return 1;
111     case TPM_CC_EC_Ephemeral:
112       return 0;
113     case TPM_CC_VerifySignature:
114       return 1;
115     case TPM_CC_Sign:
116       return 1;
117     case TPM_CC_SetCommandCodeAuditStatus:
118       return 1;
119     case TPM_CC_PCR_Extend:
120       return 1;
121     case TPM_CC_PCR_Event:
122       return 1;
123     case TPM_CC_PCR_Read:
124       return 0;
125     case TPM_CC_PCR_Allocate:
126       return 1;
127     case TPM_CC_PCR_SetAuthPolicy:
128       return 2;
129     case TPM_CC_PCR_SetAuthValue:
130       return 1;
131     case TPM_CC_PCR_Reset:
132       return 1;
133     case TPM_CC_PolicySigned:
134       return 2;
135     case TPM_CC_PolicySecret:
136       return 2;
137     case TPM_CC_PolicyTicket:
138       return 1;
139     case TPM_CC_PolicyOR:
140       return 1;
141     case TPM_CC_PolicyPCR:
142       return 1;
143     case TPM_CC_PolicyLocality:
144       return 1;
145     case TPM_CC_PolicyNV:
146       return 3;
147     case TPM_CC_PolicyCounterTimer:
148       return 1;
149     case TPM_CC_PolicyCommandCode:
150       return 1;
151     case TPM_CC_PolicyPhysicalPresence:
152       return 1;
153     case TPM_CC_PolicyCpHash:
154       return 1;
155     case TPM_CC_PolicyNameHash:
156       return 1;
157     case TPM_CC_PolicyDuplicationSelect:
158       return 1;
159     case TPM_CC_PolicyAuthorize:
160       return 1;
161     case TPM_CC_PolicyAuthValue:
162       return 1;
163     case TPM_CC_PolicyPassword:
164       return 1;
165     case TPM_CC_PolicyGetDigest:
166       return 1;
167     case TPM_CC_PolicyNvWritten:
168       return 1;
169     case TPM_CC_CreatePrimary:
170       return 1;
171     case TPM_CC_HierarchyControl:
172       return 1;
173     case TPM_CC_SetPrimaryPolicy:
174       return 1;
175     case TPM_CC_ChangePPS:
176       return 1;
177     case TPM_CC_ChangeEPS:
178       return 1;
179     case TPM_CC_Clear:
180       return 1;
181     case TPM_CC_ClearControl:
182       return 1;
183     case TPM_CC_HierarchyChangeAuth:
184       return 1;
185     case TPM_CC_DictionaryAttackLockReset:
186       return 1;
187     case TPM_CC_DictionaryAttackParameters:
188       return 1;
189     case TPM_CC_PP_Commands:
190       return 1;
191     case TPM_CC_SetAlgorithmSet:
192       return 1;
193     case TPM_CC_FieldUpgradeStart:
194       return 2;
195     case TPM_CC_FieldUpgradeData:
196       return 0;
197     case TPM_CC_FirmwareRead:
198       return 0;
199     case TPM_CC_ContextSave:
200       return 1;
201     case TPM_CC_ContextLoad:
202       return 0;
203     case TPM_CC_FlushContext:
204       return 0;
205     case TPM_CC_EvictControl:
206       return 2;
207     case TPM_CC_ReadClock:
208       return 0;
209     case TPM_CC_ClockSet:
210       return 1;
211     case TPM_CC_ClockRateAdjust:
212       return 1;
213     case TPM_CC_GetCapability:
214       return 0;
215     case TPM_CC_TestParms:
216       return 0;
217     case TPM_CC_NV_DefineSpace:
218       return 1;
219     case TPM_CC_NV_UndefineSpace:
220       return 2;
221     case TPM_CC_NV_UndefineSpaceSpecial:
222       return 2;
223     case TPM_CC_NV_ReadPublic:
224       return 1;
225     case TPM_CC_NV_Write:
226       return 2;
227     case TPM_CC_NV_Increment:
228       return 2;
229     case TPM_CC_NV_Extend:
230       return 2;
231     case TPM_CC_NV_SetBits:
232       return 2;
233     case TPM_CC_NV_WriteLock:
234       return 2;
235     case TPM_CC_NV_GlobalWriteLock:
236       return 1;
237     case TPM_CC_NV_Read:
238       return 2;
239     case TPM_CC_NV_ReadLock:
240       return 2;
241     case TPM_CC_NV_ChangeAuth:
242       return 1;
243     case TPM_CC_NV_Certify:
244       return 3;
245     case TPM_CCE_PolicyFidoSigned:
246       return 2;
247     default:
248       LOG(WARNING) << "Unknown command code: " << command_code;
249   }
250   return 0;
251 }
252 
GetNumberOfResponseHandles(TPM_CC command_code)253 size_t GetNumberOfResponseHandles(TPM_CC command_code) {
254   switch (command_code) {
255     case TPM_CC_Startup:
256       return 0;
257     case TPM_CC_Shutdown:
258       return 0;
259     case TPM_CC_SelfTest:
260       return 0;
261     case TPM_CC_IncrementalSelfTest:
262       return 0;
263     case TPM_CC_GetTestResult:
264       return 0;
265     case TPM_CC_StartAuthSession:
266       return 1;
267     case TPM_CC_PolicyRestart:
268       return 0;
269     case TPM_CC_Create:
270       return 0;
271     case TPM_CC_Load:
272       return 1;
273     case TPM_CC_LoadExternal:
274       return 1;
275     case TPM_CC_ReadPublic:
276       return 0;
277     case TPM_CC_ActivateCredential:
278       return 0;
279     case TPM_CC_MakeCredential:
280       return 0;
281     case TPM_CC_Unseal:
282       return 0;
283     case TPM_CC_ObjectChangeAuth:
284       return 0;
285     case TPM_CC_Duplicate:
286       return 0;
287     case TPM_CC_Rewrap:
288       return 0;
289     case TPM_CC_Import:
290       return 0;
291     case TPM_CC_RSA_Encrypt:
292       return 0;
293     case TPM_CC_RSA_Decrypt:
294       return 0;
295     case TPM_CC_ECDH_KeyGen:
296       return 0;
297     case TPM_CC_ECDH_ZGen:
298       return 0;
299     case TPM_CC_ECC_Parameters:
300       return 0;
301     case TPM_CC_ZGen_2Phase:
302       return 0;
303     case TPM_CC_EncryptDecrypt:
304       return 0;
305     case TPM_CC_Hash:
306       return 0;
307     case TPM_CC_HMAC:
308       return 0;
309     case TPM_CC_GetRandom:
310       return 0;
311     case TPM_CC_StirRandom:
312       return 0;
313     case TPM_CC_HMAC_Start:
314       return 1;
315     case TPM_CC_HashSequenceStart:
316       return 1;
317     case TPM_CC_SequenceUpdate:
318       return 0;
319     case TPM_CC_SequenceComplete:
320       return 0;
321     case TPM_CC_EventSequenceComplete:
322       return 0;
323     case TPM_CC_Certify:
324       return 0;
325     case TPM_CC_CertifyCreation:
326       return 0;
327     case TPM_CC_Quote:
328       return 0;
329     case TPM_CC_GetSessionAuditDigest:
330       return 0;
331     case TPM_CC_GetCommandAuditDigest:
332       return 0;
333     case TPM_CC_GetTime:
334       return 0;
335     case TPM_CC_Commit:
336       return 0;
337     case TPM_CC_EC_Ephemeral:
338       return 0;
339     case TPM_CC_VerifySignature:
340       return 0;
341     case TPM_CC_Sign:
342       return 0;
343     case TPM_CC_SetCommandCodeAuditStatus:
344       return 0;
345     case TPM_CC_PCR_Extend:
346       return 0;
347     case TPM_CC_PCR_Event:
348       return 0;
349     case TPM_CC_PCR_Read:
350       return 0;
351     case TPM_CC_PCR_Allocate:
352       return 0;
353     case TPM_CC_PCR_SetAuthPolicy:
354       return 0;
355     case TPM_CC_PCR_SetAuthValue:
356       return 0;
357     case TPM_CC_PCR_Reset:
358       return 0;
359     case TPM_CC_PolicySigned:
360       return 0;
361     case TPM_CC_PolicySecret:
362       return 0;
363     case TPM_CC_PolicyTicket:
364       return 0;
365     case TPM_CC_PolicyOR:
366       return 0;
367     case TPM_CC_PolicyPCR:
368       return 0;
369     case TPM_CC_PolicyLocality:
370       return 0;
371     case TPM_CC_PolicyNV:
372       return 0;
373     case TPM_CC_PolicyCounterTimer:
374       return 0;
375     case TPM_CC_PolicyCommandCode:
376       return 0;
377     case TPM_CC_PolicyPhysicalPresence:
378       return 0;
379     case TPM_CC_PolicyCpHash:
380       return 0;
381     case TPM_CC_PolicyNameHash:
382       return 0;
383     case TPM_CC_PolicyDuplicationSelect:
384       return 0;
385     case TPM_CC_PolicyAuthorize:
386       return 0;
387     case TPM_CC_PolicyAuthValue:
388       return 0;
389     case TPM_CC_PolicyPassword:
390       return 0;
391     case TPM_CC_PolicyGetDigest:
392       return 0;
393     case TPM_CC_PolicyNvWritten:
394       return 0;
395     case TPM_CC_CreatePrimary:
396       return 1;
397     case TPM_CC_HierarchyControl:
398       return 0;
399     case TPM_CC_SetPrimaryPolicy:
400       return 0;
401     case TPM_CC_ChangePPS:
402       return 0;
403     case TPM_CC_ChangeEPS:
404       return 0;
405     case TPM_CC_Clear:
406       return 0;
407     case TPM_CC_ClearControl:
408       return 0;
409     case TPM_CC_HierarchyChangeAuth:
410       return 0;
411     case TPM_CC_DictionaryAttackLockReset:
412       return 0;
413     case TPM_CC_DictionaryAttackParameters:
414       return 0;
415     case TPM_CC_PP_Commands:
416       return 0;
417     case TPM_CC_SetAlgorithmSet:
418       return 0;
419     case TPM_CC_FieldUpgradeStart:
420       return 0;
421     case TPM_CC_FieldUpgradeData:
422       return 0;
423     case TPM_CC_FirmwareRead:
424       return 0;
425     case TPM_CC_ContextSave:
426       return 0;
427     case TPM_CC_ContextLoad:
428       return 1;
429     case TPM_CC_FlushContext:
430       return 0;
431     case TPM_CC_EvictControl:
432       return 0;
433     case TPM_CC_ReadClock:
434       return 0;
435     case TPM_CC_ClockSet:
436       return 0;
437     case TPM_CC_ClockRateAdjust:
438       return 0;
439     case TPM_CC_GetCapability:
440       return 0;
441     case TPM_CC_TestParms:
442       return 0;
443     case TPM_CC_NV_DefineSpace:
444       return 0;
445     case TPM_CC_NV_UndefineSpace:
446       return 0;
447     case TPM_CC_NV_UndefineSpaceSpecial:
448       return 0;
449     case TPM_CC_NV_ReadPublic:
450       return 0;
451     case TPM_CC_NV_Write:
452       return 0;
453     case TPM_CC_NV_Increment:
454       return 0;
455     case TPM_CC_NV_Extend:
456       return 0;
457     case TPM_CC_NV_SetBits:
458       return 0;
459     case TPM_CC_NV_WriteLock:
460       return 0;
461     case TPM_CC_NV_GlobalWriteLock:
462       return 0;
463     case TPM_CC_NV_Read:
464       return 0;
465     case TPM_CC_NV_ReadLock:
466       return 0;
467     case TPM_CC_NV_ChangeAuth:
468       return 0;
469     case TPM_CC_NV_Certify:
470       return 0;
471     case TPM_CCE_PolicyFidoSigned:
472       return 0;
473     default:
474       LOG(WARNING) << "Unknown command code: " << command_code;
475   }
476   return 0;
477 }
478 
Serialize_uint8_t(const uint8_t & value,std::string * buffer)479 TPM_RC Serialize_uint8_t(const uint8_t& value, std::string* buffer) {
480   VLOG(3) << __func__;
481   uint8_t value_net = value;
482   switch (sizeof(uint8_t)) {
483     case 2:
484       value_net = htons(value);
485       break;
486     case 4:
487       value_net = htonl(value);
488       break;
489     case 8:
490       value_net = htonq(value);
491       break;
492     default:
493       break;
494   }
495   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
496   buffer->append(value_bytes, sizeof(uint8_t));
497   return TPM_RC_SUCCESS;
498 }
499 
Parse_uint8_t(std::string * buffer,uint8_t * value,std::string * value_bytes)500 TPM_RC Parse_uint8_t(std::string* buffer,
501                      uint8_t* value,
502                      std::string* value_bytes) {
503   VLOG(3) << __func__;
504   if (buffer->size() < sizeof(uint8_t))
505     return TPM_RC_INSUFFICIENT;
506   uint8_t value_net = 0;
507   memcpy(&value_net, buffer->data(), sizeof(uint8_t));
508   switch (sizeof(uint8_t)) {
509     case 2:
510       *value = ntohs(value_net);
511       break;
512     case 4:
513       *value = ntohl(value_net);
514       break;
515     case 8:
516       *value = ntohq(value_net);
517       break;
518     default:
519       *value = value_net;
520   }
521   if (value_bytes) {
522     value_bytes->append(buffer->substr(0, sizeof(uint8_t)));
523   }
524   buffer->erase(0, sizeof(uint8_t));
525   return TPM_RC_SUCCESS;
526 }
527 
Serialize_int8_t(const int8_t & value,std::string * buffer)528 TPM_RC Serialize_int8_t(const int8_t& value, std::string* buffer) {
529   VLOG(3) << __func__;
530   int8_t value_net = value;
531   switch (sizeof(int8_t)) {
532     case 2:
533       value_net = htons(value);
534       break;
535     case 4:
536       value_net = htonl(value);
537       break;
538     case 8:
539       value_net = htonq(value);
540       break;
541     default:
542       break;
543   }
544   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
545   buffer->append(value_bytes, sizeof(int8_t));
546   return TPM_RC_SUCCESS;
547 }
548 
Parse_int8_t(std::string * buffer,int8_t * value,std::string * value_bytes)549 TPM_RC Parse_int8_t(std::string* buffer,
550                     int8_t* value,
551                     std::string* value_bytes) {
552   VLOG(3) << __func__;
553   if (buffer->size() < sizeof(int8_t))
554     return TPM_RC_INSUFFICIENT;
555   int8_t value_net = 0;
556   memcpy(&value_net, buffer->data(), sizeof(int8_t));
557   switch (sizeof(int8_t)) {
558     case 2:
559       *value = ntohs(value_net);
560       break;
561     case 4:
562       *value = ntohl(value_net);
563       break;
564     case 8:
565       *value = ntohq(value_net);
566       break;
567     default:
568       *value = value_net;
569   }
570   if (value_bytes) {
571     value_bytes->append(buffer->substr(0, sizeof(int8_t)));
572   }
573   buffer->erase(0, sizeof(int8_t));
574   return TPM_RC_SUCCESS;
575 }
576 
Serialize_int(const int & value,std::string * buffer)577 TPM_RC Serialize_int(const int& value, std::string* buffer) {
578   VLOG(3) << __func__;
579   int value_net = value;
580   switch (sizeof(int)) {
581     case 2:
582       value_net = htons(value);
583       break;
584     case 4:
585       value_net = htonl(value);
586       break;
587     case 8:
588       value_net = htonq(value);
589       break;
590     default:
591       break;
592   }
593   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
594   buffer->append(value_bytes, sizeof(int));
595   return TPM_RC_SUCCESS;
596 }
597 
Parse_int(std::string * buffer,int * value,std::string * value_bytes)598 TPM_RC Parse_int(std::string* buffer, int* value, std::string* value_bytes) {
599   VLOG(3) << __func__;
600   if (buffer->size() < sizeof(int))
601     return TPM_RC_INSUFFICIENT;
602   int value_net = 0;
603   memcpy(&value_net, buffer->data(), sizeof(int));
604   switch (sizeof(int)) {
605     case 2:
606       *value = ntohs(value_net);
607       break;
608     case 4:
609       *value = ntohl(value_net);
610       break;
611     case 8:
612       *value = ntohq(value_net);
613       break;
614     default:
615       *value = value_net;
616   }
617   if (value_bytes) {
618     value_bytes->append(buffer->substr(0, sizeof(int)));
619   }
620   buffer->erase(0, sizeof(int));
621   return TPM_RC_SUCCESS;
622 }
623 
Serialize_uint16_t(const uint16_t & value,std::string * buffer)624 TPM_RC Serialize_uint16_t(const uint16_t& value, std::string* buffer) {
625   VLOG(3) << __func__;
626   uint16_t value_net = value;
627   switch (sizeof(uint16_t)) {
628     case 2:
629       value_net = htons(value);
630       break;
631     case 4:
632       value_net = htonl(value);
633       break;
634     case 8:
635       value_net = htonq(value);
636       break;
637     default:
638       break;
639   }
640   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
641   buffer->append(value_bytes, sizeof(uint16_t));
642   return TPM_RC_SUCCESS;
643 }
644 
Parse_uint16_t(std::string * buffer,uint16_t * value,std::string * value_bytes)645 TPM_RC Parse_uint16_t(std::string* buffer,
646                       uint16_t* value,
647                       std::string* value_bytes) {
648   VLOG(3) << __func__;
649   if (buffer->size() < sizeof(uint16_t))
650     return TPM_RC_INSUFFICIENT;
651   uint16_t value_net = 0;
652   memcpy(&value_net, buffer->data(), sizeof(uint16_t));
653   switch (sizeof(uint16_t)) {
654     case 2:
655       *value = ntohs(value_net);
656       break;
657     case 4:
658       *value = ntohl(value_net);
659       break;
660     case 8:
661       *value = ntohq(value_net);
662       break;
663     default:
664       *value = value_net;
665   }
666   if (value_bytes) {
667     value_bytes->append(buffer->substr(0, sizeof(uint16_t)));
668   }
669   buffer->erase(0, sizeof(uint16_t));
670   return TPM_RC_SUCCESS;
671 }
672 
Serialize_int16_t(const int16_t & value,std::string * buffer)673 TPM_RC Serialize_int16_t(const int16_t& value, std::string* buffer) {
674   VLOG(3) << __func__;
675   int16_t value_net = value;
676   switch (sizeof(int16_t)) {
677     case 2:
678       value_net = htons(value);
679       break;
680     case 4:
681       value_net = htonl(value);
682       break;
683     case 8:
684       value_net = htonq(value);
685       break;
686     default:
687       break;
688   }
689   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
690   buffer->append(value_bytes, sizeof(int16_t));
691   return TPM_RC_SUCCESS;
692 }
693 
Parse_int16_t(std::string * buffer,int16_t * value,std::string * value_bytes)694 TPM_RC Parse_int16_t(std::string* buffer,
695                      int16_t* value,
696                      std::string* value_bytes) {
697   VLOG(3) << __func__;
698   if (buffer->size() < sizeof(int16_t))
699     return TPM_RC_INSUFFICIENT;
700   int16_t value_net = 0;
701   memcpy(&value_net, buffer->data(), sizeof(int16_t));
702   switch (sizeof(int16_t)) {
703     case 2:
704       *value = ntohs(value_net);
705       break;
706     case 4:
707       *value = ntohl(value_net);
708       break;
709     case 8:
710       *value = ntohq(value_net);
711       break;
712     default:
713       *value = value_net;
714   }
715   if (value_bytes) {
716     value_bytes->append(buffer->substr(0, sizeof(int16_t)));
717   }
718   buffer->erase(0, sizeof(int16_t));
719   return TPM_RC_SUCCESS;
720 }
721 
Serialize_uint32_t(const uint32_t & value,std::string * buffer)722 TPM_RC Serialize_uint32_t(const uint32_t& value, std::string* buffer) {
723   VLOG(3) << __func__;
724   uint32_t value_net = value;
725   switch (sizeof(uint32_t)) {
726     case 2:
727       value_net = htons(value);
728       break;
729     case 4:
730       value_net = htonl(value);
731       break;
732     case 8:
733       value_net = htonq(value);
734       break;
735     default:
736       break;
737   }
738   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
739   buffer->append(value_bytes, sizeof(uint32_t));
740   return TPM_RC_SUCCESS;
741 }
742 
Parse_uint32_t(std::string * buffer,uint32_t * value,std::string * value_bytes)743 TPM_RC Parse_uint32_t(std::string* buffer,
744                       uint32_t* value,
745                       std::string* value_bytes) {
746   VLOG(3) << __func__;
747   if (buffer->size() < sizeof(uint32_t))
748     return TPM_RC_INSUFFICIENT;
749   uint32_t value_net = 0;
750   memcpy(&value_net, buffer->data(), sizeof(uint32_t));
751   switch (sizeof(uint32_t)) {
752     case 2:
753       *value = ntohs(value_net);
754       break;
755     case 4:
756       *value = ntohl(value_net);
757       break;
758     case 8:
759       *value = ntohq(value_net);
760       break;
761     default:
762       *value = value_net;
763   }
764   if (value_bytes) {
765     value_bytes->append(buffer->substr(0, sizeof(uint32_t)));
766   }
767   buffer->erase(0, sizeof(uint32_t));
768   return TPM_RC_SUCCESS;
769 }
770 
Serialize_int32_t(const int32_t & value,std::string * buffer)771 TPM_RC Serialize_int32_t(const int32_t& value, std::string* buffer) {
772   VLOG(3) << __func__;
773   int32_t value_net = value;
774   switch (sizeof(int32_t)) {
775     case 2:
776       value_net = htons(value);
777       break;
778     case 4:
779       value_net = htonl(value);
780       break;
781     case 8:
782       value_net = htonq(value);
783       break;
784     default:
785       break;
786   }
787   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
788   buffer->append(value_bytes, sizeof(int32_t));
789   return TPM_RC_SUCCESS;
790 }
791 
Parse_int32_t(std::string * buffer,int32_t * value,std::string * value_bytes)792 TPM_RC Parse_int32_t(std::string* buffer,
793                      int32_t* value,
794                      std::string* value_bytes) {
795   VLOG(3) << __func__;
796   if (buffer->size() < sizeof(int32_t))
797     return TPM_RC_INSUFFICIENT;
798   int32_t value_net = 0;
799   memcpy(&value_net, buffer->data(), sizeof(int32_t));
800   switch (sizeof(int32_t)) {
801     case 2:
802       *value = ntohs(value_net);
803       break;
804     case 4:
805       *value = ntohl(value_net);
806       break;
807     case 8:
808       *value = ntohq(value_net);
809       break;
810     default:
811       *value = value_net;
812   }
813   if (value_bytes) {
814     value_bytes->append(buffer->substr(0, sizeof(int32_t)));
815   }
816   buffer->erase(0, sizeof(int32_t));
817   return TPM_RC_SUCCESS;
818 }
819 
Serialize_uint64_t(const uint64_t & value,std::string * buffer)820 TPM_RC Serialize_uint64_t(const uint64_t& value, std::string* buffer) {
821   VLOG(3) << __func__;
822   uint64_t value_net = value;
823   switch (sizeof(uint64_t)) {
824     case 2:
825       value_net = htons(value);
826       break;
827     case 4:
828       value_net = htonl(value);
829       break;
830     case 8:
831       value_net = htonq(value);
832       break;
833     default:
834       break;
835   }
836   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
837   buffer->append(value_bytes, sizeof(uint64_t));
838   return TPM_RC_SUCCESS;
839 }
840 
Parse_uint64_t(std::string * buffer,uint64_t * value,std::string * value_bytes)841 TPM_RC Parse_uint64_t(std::string* buffer,
842                       uint64_t* value,
843                       std::string* value_bytes) {
844   VLOG(3) << __func__;
845   if (buffer->size() < sizeof(uint64_t))
846     return TPM_RC_INSUFFICIENT;
847   uint64_t value_net = 0;
848   memcpy(&value_net, buffer->data(), sizeof(uint64_t));
849   switch (sizeof(uint64_t)) {
850     case 2:
851       *value = ntohs(value_net);
852       break;
853     case 4:
854       *value = ntohl(value_net);
855       break;
856     case 8:
857       *value = ntohq(value_net);
858       break;
859     default:
860       *value = value_net;
861   }
862   if (value_bytes) {
863     value_bytes->append(buffer->substr(0, sizeof(uint64_t)));
864   }
865   buffer->erase(0, sizeof(uint64_t));
866   return TPM_RC_SUCCESS;
867 }
868 
Serialize_int64_t(const int64_t & value,std::string * buffer)869 TPM_RC Serialize_int64_t(const int64_t& value, std::string* buffer) {
870   VLOG(3) << __func__;
871   int64_t value_net = value;
872   switch (sizeof(int64_t)) {
873     case 2:
874       value_net = htons(value);
875       break;
876     case 4:
877       value_net = htonl(value);
878       break;
879     case 8:
880       value_net = htonq(value);
881       break;
882     default:
883       break;
884   }
885   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
886   buffer->append(value_bytes, sizeof(int64_t));
887   return TPM_RC_SUCCESS;
888 }
889 
Parse_int64_t(std::string * buffer,int64_t * value,std::string * value_bytes)890 TPM_RC Parse_int64_t(std::string* buffer,
891                      int64_t* value,
892                      std::string* value_bytes) {
893   VLOG(3) << __func__;
894   if (buffer->size() < sizeof(int64_t))
895     return TPM_RC_INSUFFICIENT;
896   int64_t value_net = 0;
897   memcpy(&value_net, buffer->data(), sizeof(int64_t));
898   switch (sizeof(int64_t)) {
899     case 2:
900       *value = ntohs(value_net);
901       break;
902     case 4:
903       *value = ntohl(value_net);
904       break;
905     case 8:
906       *value = ntohq(value_net);
907       break;
908     default:
909       *value = value_net;
910   }
911   if (value_bytes) {
912     value_bytes->append(buffer->substr(0, sizeof(int64_t)));
913   }
914   buffer->erase(0, sizeof(int64_t));
915   return TPM_RC_SUCCESS;
916 }
917 
Serialize_UINT8(const UINT8 & value,std::string * buffer)918 TPM_RC Serialize_UINT8(const UINT8& value, std::string* buffer) {
919   VLOG(3) << __func__;
920   return Serialize_uint8_t(value, buffer);
921 }
922 
Parse_UINT8(std::string * buffer,UINT8 * value,std::string * value_bytes)923 TPM_RC Parse_UINT8(std::string* buffer,
924                    UINT8* value,
925                    std::string* value_bytes) {
926   VLOG(3) << __func__;
927   return Parse_uint8_t(buffer, value, value_bytes);
928 }
929 
Serialize_BYTE(const BYTE & value,std::string * buffer)930 TPM_RC Serialize_BYTE(const BYTE& value, std::string* buffer) {
931   VLOG(3) << __func__;
932   return Serialize_uint8_t(value, buffer);
933 }
934 
Parse_BYTE(std::string * buffer,BYTE * value,std::string * value_bytes)935 TPM_RC Parse_BYTE(std::string* buffer, BYTE* value, std::string* value_bytes) {
936   VLOG(3) << __func__;
937   return Parse_uint8_t(buffer, value, value_bytes);
938 }
939 
Serialize_INT8(const INT8 & value,std::string * buffer)940 TPM_RC Serialize_INT8(const INT8& value, std::string* buffer) {
941   VLOG(3) << __func__;
942   return Serialize_int8_t(value, buffer);
943 }
944 
Parse_INT8(std::string * buffer,INT8 * value,std::string * value_bytes)945 TPM_RC Parse_INT8(std::string* buffer, INT8* value, std::string* value_bytes) {
946   VLOG(3) << __func__;
947   return Parse_int8_t(buffer, value, value_bytes);
948 }
949 
Serialize_BOOL(const BOOL & value,std::string * buffer)950 TPM_RC Serialize_BOOL(const BOOL& value, std::string* buffer) {
951   VLOG(3) << __func__;
952   return Serialize_int(value, buffer);
953 }
954 
Parse_BOOL(std::string * buffer,BOOL * value,std::string * value_bytes)955 TPM_RC Parse_BOOL(std::string* buffer, BOOL* value, std::string* value_bytes) {
956   VLOG(3) << __func__;
957   return Parse_int(buffer, value, value_bytes);
958 }
959 
Serialize_UINT16(const UINT16 & value,std::string * buffer)960 TPM_RC Serialize_UINT16(const UINT16& value, std::string* buffer) {
961   VLOG(3) << __func__;
962   return Serialize_uint16_t(value, buffer);
963 }
964 
Parse_UINT16(std::string * buffer,UINT16 * value,std::string * value_bytes)965 TPM_RC Parse_UINT16(std::string* buffer,
966                     UINT16* value,
967                     std::string* value_bytes) {
968   VLOG(3) << __func__;
969   return Parse_uint16_t(buffer, value, value_bytes);
970 }
971 
Serialize_INT16(const INT16 & value,std::string * buffer)972 TPM_RC Serialize_INT16(const INT16& value, std::string* buffer) {
973   VLOG(3) << __func__;
974   return Serialize_int16_t(value, buffer);
975 }
976 
Parse_INT16(std::string * buffer,INT16 * value,std::string * value_bytes)977 TPM_RC Parse_INT16(std::string* buffer,
978                    INT16* value,
979                    std::string* value_bytes) {
980   VLOG(3) << __func__;
981   return Parse_int16_t(buffer, value, value_bytes);
982 }
983 
Serialize_UINT32(const UINT32 & value,std::string * buffer)984 TPM_RC Serialize_UINT32(const UINT32& value, std::string* buffer) {
985   VLOG(3) << __func__;
986   return Serialize_uint32_t(value, buffer);
987 }
988 
Parse_UINT32(std::string * buffer,UINT32 * value,std::string * value_bytes)989 TPM_RC Parse_UINT32(std::string* buffer,
990                     UINT32* value,
991                     std::string* value_bytes) {
992   VLOG(3) << __func__;
993   return Parse_uint32_t(buffer, value, value_bytes);
994 }
995 
Serialize_INT32(const INT32 & value,std::string * buffer)996 TPM_RC Serialize_INT32(const INT32& value, std::string* buffer) {
997   VLOG(3) << __func__;
998   return Serialize_int32_t(value, buffer);
999 }
1000 
Parse_INT32(std::string * buffer,INT32 * value,std::string * value_bytes)1001 TPM_RC Parse_INT32(std::string* buffer,
1002                    INT32* value,
1003                    std::string* value_bytes) {
1004   VLOG(3) << __func__;
1005   return Parse_int32_t(buffer, value, value_bytes);
1006 }
1007 
Serialize_UINT64(const UINT64 & value,std::string * buffer)1008 TPM_RC Serialize_UINT64(const UINT64& value, std::string* buffer) {
1009   VLOG(3) << __func__;
1010   return Serialize_uint64_t(value, buffer);
1011 }
1012 
Parse_UINT64(std::string * buffer,UINT64 * value,std::string * value_bytes)1013 TPM_RC Parse_UINT64(std::string* buffer,
1014                     UINT64* value,
1015                     std::string* value_bytes) {
1016   VLOG(3) << __func__;
1017   return Parse_uint64_t(buffer, value, value_bytes);
1018 }
1019 
Serialize_INT64(const INT64 & value,std::string * buffer)1020 TPM_RC Serialize_INT64(const INT64& value, std::string* buffer) {
1021   VLOG(3) << __func__;
1022   return Serialize_int64_t(value, buffer);
1023 }
1024 
Parse_INT64(std::string * buffer,INT64 * value,std::string * value_bytes)1025 TPM_RC Parse_INT64(std::string* buffer,
1026                    INT64* value,
1027                    std::string* value_bytes) {
1028   VLOG(3) << __func__;
1029   return Parse_int64_t(buffer, value, value_bytes);
1030 }
1031 
Serialize_TPM_ALGORITHM_ID(const TPM_ALGORITHM_ID & value,std::string * buffer)1032 TPM_RC Serialize_TPM_ALGORITHM_ID(const TPM_ALGORITHM_ID& value,
1033                                   std::string* buffer) {
1034   VLOG(3) << __func__;
1035   return Serialize_UINT32(value, buffer);
1036 }
1037 
Parse_TPM_ALGORITHM_ID(std::string * buffer,TPM_ALGORITHM_ID * value,std::string * value_bytes)1038 TPM_RC Parse_TPM_ALGORITHM_ID(std::string* buffer,
1039                               TPM_ALGORITHM_ID* value,
1040                               std::string* value_bytes) {
1041   VLOG(3) << __func__;
1042   return Parse_UINT32(buffer, value, value_bytes);
1043 }
1044 
Serialize_TPM_MODIFIER_INDICATOR(const TPM_MODIFIER_INDICATOR & value,std::string * buffer)1045 TPM_RC Serialize_TPM_MODIFIER_INDICATOR(const TPM_MODIFIER_INDICATOR& value,
1046                                         std::string* buffer) {
1047   VLOG(3) << __func__;
1048   return Serialize_UINT32(value, buffer);
1049 }
1050 
Parse_TPM_MODIFIER_INDICATOR(std::string * buffer,TPM_MODIFIER_INDICATOR * value,std::string * value_bytes)1051 TPM_RC Parse_TPM_MODIFIER_INDICATOR(std::string* buffer,
1052                                     TPM_MODIFIER_INDICATOR* value,
1053                                     std::string* value_bytes) {
1054   VLOG(3) << __func__;
1055   return Parse_UINT32(buffer, value, value_bytes);
1056 }
1057 
Serialize_TPM_AUTHORIZATION_SIZE(const TPM_AUTHORIZATION_SIZE & value,std::string * buffer)1058 TPM_RC Serialize_TPM_AUTHORIZATION_SIZE(const TPM_AUTHORIZATION_SIZE& value,
1059                                         std::string* buffer) {
1060   VLOG(3) << __func__;
1061   return Serialize_UINT32(value, buffer);
1062 }
1063 
Parse_TPM_AUTHORIZATION_SIZE(std::string * buffer,TPM_AUTHORIZATION_SIZE * value,std::string * value_bytes)1064 TPM_RC Parse_TPM_AUTHORIZATION_SIZE(std::string* buffer,
1065                                     TPM_AUTHORIZATION_SIZE* value,
1066                                     std::string* value_bytes) {
1067   VLOG(3) << __func__;
1068   return Parse_UINT32(buffer, value, value_bytes);
1069 }
1070 
Serialize_TPM_PARAMETER_SIZE(const TPM_PARAMETER_SIZE & value,std::string * buffer)1071 TPM_RC Serialize_TPM_PARAMETER_SIZE(const TPM_PARAMETER_SIZE& value,
1072                                     std::string* buffer) {
1073   VLOG(3) << __func__;
1074   return Serialize_UINT32(value, buffer);
1075 }
1076 
Parse_TPM_PARAMETER_SIZE(std::string * buffer,TPM_PARAMETER_SIZE * value,std::string * value_bytes)1077 TPM_RC Parse_TPM_PARAMETER_SIZE(std::string* buffer,
1078                                 TPM_PARAMETER_SIZE* value,
1079                                 std::string* value_bytes) {
1080   VLOG(3) << __func__;
1081   return Parse_UINT32(buffer, value, value_bytes);
1082 }
1083 
Serialize_TPM_KEY_SIZE(const TPM_KEY_SIZE & value,std::string * buffer)1084 TPM_RC Serialize_TPM_KEY_SIZE(const TPM_KEY_SIZE& value, std::string* buffer) {
1085   VLOG(3) << __func__;
1086   return Serialize_UINT16(value, buffer);
1087 }
1088 
Parse_TPM_KEY_SIZE(std::string * buffer,TPM_KEY_SIZE * value,std::string * value_bytes)1089 TPM_RC Parse_TPM_KEY_SIZE(std::string* buffer,
1090                           TPM_KEY_SIZE* value,
1091                           std::string* value_bytes) {
1092   VLOG(3) << __func__;
1093   return Parse_UINT16(buffer, value, value_bytes);
1094 }
1095 
Serialize_TPM_KEY_BITS(const TPM_KEY_BITS & value,std::string * buffer)1096 TPM_RC Serialize_TPM_KEY_BITS(const TPM_KEY_BITS& value, std::string* buffer) {
1097   VLOG(3) << __func__;
1098   return Serialize_UINT16(value, buffer);
1099 }
1100 
Parse_TPM_KEY_BITS(std::string * buffer,TPM_KEY_BITS * value,std::string * value_bytes)1101 TPM_RC Parse_TPM_KEY_BITS(std::string* buffer,
1102                           TPM_KEY_BITS* value,
1103                           std::string* value_bytes) {
1104   VLOG(3) << __func__;
1105   return Parse_UINT16(buffer, value, value_bytes);
1106 }
1107 
Serialize_TPM_HANDLE(const TPM_HANDLE & value,std::string * buffer)1108 TPM_RC Serialize_TPM_HANDLE(const TPM_HANDLE& value, std::string* buffer) {
1109   VLOG(3) << __func__;
1110   return Serialize_UINT32(value, buffer);
1111 }
1112 
Parse_TPM_HANDLE(std::string * buffer,TPM_HANDLE * value,std::string * value_bytes)1113 TPM_RC Parse_TPM_HANDLE(std::string* buffer,
1114                         TPM_HANDLE* value,
1115                         std::string* value_bytes) {
1116   VLOG(3) << __func__;
1117   return Parse_UINT32(buffer, value, value_bytes);
1118 }
1119 
Serialize_TPM2B_DIGEST(const TPM2B_DIGEST & value,std::string * buffer)1120 TPM_RC Serialize_TPM2B_DIGEST(const TPM2B_DIGEST& value, std::string* buffer) {
1121   TPM_RC result = TPM_RC_SUCCESS;
1122   VLOG(3) << __func__;
1123 
1124   result = Serialize_UINT16(value.size, buffer);
1125   if (result) {
1126     return result;
1127   }
1128 
1129   if (std::size(value.buffer) < value.size) {
1130     return TPM_RC_INSUFFICIENT;
1131   }
1132   for (uint32_t i = 0; i < value.size; ++i) {
1133     result = Serialize_BYTE(value.buffer[i], buffer);
1134     if (result) {
1135       return result;
1136     }
1137   }
1138   return result;
1139 }
1140 
Parse_TPM2B_DIGEST(std::string * buffer,TPM2B_DIGEST * value,std::string * value_bytes)1141 TPM_RC Parse_TPM2B_DIGEST(std::string* buffer,
1142                           TPM2B_DIGEST* value,
1143                           std::string* value_bytes) {
1144   TPM_RC result = TPM_RC_SUCCESS;
1145   VLOG(3) << __func__;
1146 
1147   result = Parse_UINT16(buffer, &value->size, value_bytes);
1148   if (result) {
1149     return result;
1150   }
1151 
1152   if (std::size(value->buffer) < value->size) {
1153     return TPM_RC_INSUFFICIENT;
1154   }
1155   for (uint32_t i = 0; i < value->size; ++i) {
1156     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
1157     if (result) {
1158       return result;
1159     }
1160   }
1161   return result;
1162 }
1163 
Make_TPM2B_DIGEST(const std::string & bytes)1164 TPM2B_DIGEST Make_TPM2B_DIGEST(const std::string& bytes) {
1165   TPM2B_DIGEST tpm2b;
1166   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
1167   memset(&tpm2b, 0, sizeof(TPM2B_DIGEST));
1168   tpm2b.size = bytes.size();
1169   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
1170   return tpm2b;
1171 }
1172 
StringFrom_TPM2B_DIGEST(const TPM2B_DIGEST & tpm2b)1173 std::string StringFrom_TPM2B_DIGEST(const TPM2B_DIGEST& tpm2b) {
1174   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
1175   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
1176   return std::string(char_buffer, tpm2b.size);
1177 }
1178 
Serialize_TPM2B_NONCE(const TPM2B_NONCE & value,std::string * buffer)1179 TPM_RC Serialize_TPM2B_NONCE(const TPM2B_NONCE& value, std::string* buffer) {
1180   VLOG(3) << __func__;
1181   return Serialize_TPM2B_DIGEST(value, buffer);
1182 }
1183 
Parse_TPM2B_NONCE(std::string * buffer,TPM2B_NONCE * value,std::string * value_bytes)1184 TPM_RC Parse_TPM2B_NONCE(std::string* buffer,
1185                          TPM2B_NONCE* value,
1186                          std::string* value_bytes) {
1187   VLOG(3) << __func__;
1188   return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1189 }
1190 
Serialize_TPM2B_AUTH(const TPM2B_AUTH & value,std::string * buffer)1191 TPM_RC Serialize_TPM2B_AUTH(const TPM2B_AUTH& value, std::string* buffer) {
1192   VLOG(3) << __func__;
1193   return Serialize_TPM2B_DIGEST(value, buffer);
1194 }
1195 
Parse_TPM2B_AUTH(std::string * buffer,TPM2B_AUTH * value,std::string * value_bytes)1196 TPM_RC Parse_TPM2B_AUTH(std::string* buffer,
1197                         TPM2B_AUTH* value,
1198                         std::string* value_bytes) {
1199   VLOG(3) << __func__;
1200   return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1201 }
1202 
Serialize_TPM2B_OPERAND(const TPM2B_OPERAND & value,std::string * buffer)1203 TPM_RC Serialize_TPM2B_OPERAND(const TPM2B_OPERAND& value,
1204                                std::string* buffer) {
1205   VLOG(3) << __func__;
1206   return Serialize_TPM2B_DIGEST(value, buffer);
1207 }
1208 
Parse_TPM2B_OPERAND(std::string * buffer,TPM2B_OPERAND * value,std::string * value_bytes)1209 TPM_RC Parse_TPM2B_OPERAND(std::string* buffer,
1210                            TPM2B_OPERAND* value,
1211                            std::string* value_bytes) {
1212   VLOG(3) << __func__;
1213   return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1214 }
1215 
Serialize_TPM_ALG_ID(const TPM_ALG_ID & value,std::string * buffer)1216 TPM_RC Serialize_TPM_ALG_ID(const TPM_ALG_ID& value, std::string* buffer) {
1217   VLOG(3) << __func__;
1218   return Serialize_UINT16(value, buffer);
1219 }
1220 
Parse_TPM_ALG_ID(std::string * buffer,TPM_ALG_ID * value,std::string * value_bytes)1221 TPM_RC Parse_TPM_ALG_ID(std::string* buffer,
1222                         TPM_ALG_ID* value,
1223                         std::string* value_bytes) {
1224   VLOG(3) << __func__;
1225   return Parse_UINT16(buffer, value, value_bytes);
1226 }
1227 
Serialize_TPMI_ALG_HASH(const TPMI_ALG_HASH & value,std::string * buffer)1228 TPM_RC Serialize_TPMI_ALG_HASH(const TPMI_ALG_HASH& value,
1229                                std::string* buffer) {
1230   VLOG(3) << __func__;
1231   return Serialize_TPM_ALG_ID(value, buffer);
1232 }
1233 
Parse_TPMI_ALG_HASH(std::string * buffer,TPMI_ALG_HASH * value,std::string * value_bytes)1234 TPM_RC Parse_TPMI_ALG_HASH(std::string* buffer,
1235                            TPMI_ALG_HASH* value,
1236                            std::string* value_bytes) {
1237   VLOG(3) << __func__;
1238   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1239 }
1240 
Serialize_TPMS_SCHEME_SIGHASH(const TPMS_SCHEME_SIGHASH & value,std::string * buffer)1241 TPM_RC Serialize_TPMS_SCHEME_SIGHASH(const TPMS_SCHEME_SIGHASH& value,
1242                                      std::string* buffer) {
1243   TPM_RC result = TPM_RC_SUCCESS;
1244   VLOG(3) << __func__;
1245 
1246   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
1247   if (result) {
1248     return result;
1249   }
1250   return result;
1251 }
1252 
Parse_TPMS_SCHEME_SIGHASH(std::string * buffer,TPMS_SCHEME_SIGHASH * value,std::string * value_bytes)1253 TPM_RC Parse_TPMS_SCHEME_SIGHASH(std::string* buffer,
1254                                  TPMS_SCHEME_SIGHASH* value,
1255                                  std::string* value_bytes) {
1256   TPM_RC result = TPM_RC_SUCCESS;
1257   VLOG(3) << __func__;
1258 
1259   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
1260   if (result) {
1261     return result;
1262   }
1263   return result;
1264 }
1265 
Serialize_TPMS_SCHEME_HMAC(const TPMS_SCHEME_HMAC & value,std::string * buffer)1266 TPM_RC Serialize_TPMS_SCHEME_HMAC(const TPMS_SCHEME_HMAC& value,
1267                                   std::string* buffer) {
1268   VLOG(3) << __func__;
1269   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1270 }
1271 
Parse_TPMS_SCHEME_HMAC(std::string * buffer,TPMS_SCHEME_HMAC * value,std::string * value_bytes)1272 TPM_RC Parse_TPMS_SCHEME_HMAC(std::string* buffer,
1273                               TPMS_SCHEME_HMAC* value,
1274                               std::string* value_bytes) {
1275   VLOG(3) << __func__;
1276   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1277 }
1278 
Serialize_TPMS_SCHEME_RSASSA(const TPMS_SCHEME_RSASSA & value,std::string * buffer)1279 TPM_RC Serialize_TPMS_SCHEME_RSASSA(const TPMS_SCHEME_RSASSA& value,
1280                                     std::string* buffer) {
1281   VLOG(3) << __func__;
1282   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1283 }
1284 
Parse_TPMS_SCHEME_RSASSA(std::string * buffer,TPMS_SCHEME_RSASSA * value,std::string * value_bytes)1285 TPM_RC Parse_TPMS_SCHEME_RSASSA(std::string* buffer,
1286                                 TPMS_SCHEME_RSASSA* value,
1287                                 std::string* value_bytes) {
1288   VLOG(3) << __func__;
1289   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1290 }
1291 
Serialize_TPMS_SCHEME_RSAPSS(const TPMS_SCHEME_RSAPSS & value,std::string * buffer)1292 TPM_RC Serialize_TPMS_SCHEME_RSAPSS(const TPMS_SCHEME_RSAPSS& value,
1293                                     std::string* buffer) {
1294   VLOG(3) << __func__;
1295   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1296 }
1297 
Parse_TPMS_SCHEME_RSAPSS(std::string * buffer,TPMS_SCHEME_RSAPSS * value,std::string * value_bytes)1298 TPM_RC Parse_TPMS_SCHEME_RSAPSS(std::string* buffer,
1299                                 TPMS_SCHEME_RSAPSS* value,
1300                                 std::string* value_bytes) {
1301   VLOG(3) << __func__;
1302   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1303 }
1304 
Serialize_TPMS_SCHEME_ECDSA(const TPMS_SCHEME_ECDSA & value,std::string * buffer)1305 TPM_RC Serialize_TPMS_SCHEME_ECDSA(const TPMS_SCHEME_ECDSA& value,
1306                                    std::string* buffer) {
1307   VLOG(3) << __func__;
1308   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1309 }
1310 
Parse_TPMS_SCHEME_ECDSA(std::string * buffer,TPMS_SCHEME_ECDSA * value,std::string * value_bytes)1311 TPM_RC Parse_TPMS_SCHEME_ECDSA(std::string* buffer,
1312                                TPMS_SCHEME_ECDSA* value,
1313                                std::string* value_bytes) {
1314   VLOG(3) << __func__;
1315   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1316 }
1317 
Serialize_TPMS_SCHEME_SM2(const TPMS_SCHEME_SM2 & value,std::string * buffer)1318 TPM_RC Serialize_TPMS_SCHEME_SM2(const TPMS_SCHEME_SM2& value,
1319                                  std::string* buffer) {
1320   VLOG(3) << __func__;
1321   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1322 }
1323 
Parse_TPMS_SCHEME_SM2(std::string * buffer,TPMS_SCHEME_SM2 * value,std::string * value_bytes)1324 TPM_RC Parse_TPMS_SCHEME_SM2(std::string* buffer,
1325                              TPMS_SCHEME_SM2* value,
1326                              std::string* value_bytes) {
1327   VLOG(3) << __func__;
1328   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1329 }
1330 
Serialize_TPMS_SCHEME_ECSCHNORR(const TPMS_SCHEME_ECSCHNORR & value,std::string * buffer)1331 TPM_RC Serialize_TPMS_SCHEME_ECSCHNORR(const TPMS_SCHEME_ECSCHNORR& value,
1332                                        std::string* buffer) {
1333   VLOG(3) << __func__;
1334   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1335 }
1336 
Parse_TPMS_SCHEME_ECSCHNORR(std::string * buffer,TPMS_SCHEME_ECSCHNORR * value,std::string * value_bytes)1337 TPM_RC Parse_TPMS_SCHEME_ECSCHNORR(std::string* buffer,
1338                                    TPMS_SCHEME_ECSCHNORR* value,
1339                                    std::string* value_bytes) {
1340   VLOG(3) << __func__;
1341   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1342 }
1343 
Serialize_TPMI_YES_NO(const TPMI_YES_NO & value,std::string * buffer)1344 TPM_RC Serialize_TPMI_YES_NO(const TPMI_YES_NO& value, std::string* buffer) {
1345   VLOG(3) << __func__;
1346   return Serialize_BYTE(value, buffer);
1347 }
1348 
Parse_TPMI_YES_NO(std::string * buffer,TPMI_YES_NO * value,std::string * value_bytes)1349 TPM_RC Parse_TPMI_YES_NO(std::string* buffer,
1350                          TPMI_YES_NO* value,
1351                          std::string* value_bytes) {
1352   VLOG(3) << __func__;
1353   return Parse_BYTE(buffer, value, value_bytes);
1354 }
1355 
Serialize_TPMI_DH_OBJECT(const TPMI_DH_OBJECT & value,std::string * buffer)1356 TPM_RC Serialize_TPMI_DH_OBJECT(const TPMI_DH_OBJECT& value,
1357                                 std::string* buffer) {
1358   VLOG(3) << __func__;
1359   return Serialize_TPM_HANDLE(value, buffer);
1360 }
1361 
Parse_TPMI_DH_OBJECT(std::string * buffer,TPMI_DH_OBJECT * value,std::string * value_bytes)1362 TPM_RC Parse_TPMI_DH_OBJECT(std::string* buffer,
1363                             TPMI_DH_OBJECT* value,
1364                             std::string* value_bytes) {
1365   VLOG(3) << __func__;
1366   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1367 }
1368 
Serialize_TPMI_DH_PERSISTENT(const TPMI_DH_PERSISTENT & value,std::string * buffer)1369 TPM_RC Serialize_TPMI_DH_PERSISTENT(const TPMI_DH_PERSISTENT& value,
1370                                     std::string* buffer) {
1371   VLOG(3) << __func__;
1372   return Serialize_TPM_HANDLE(value, buffer);
1373 }
1374 
Parse_TPMI_DH_PERSISTENT(std::string * buffer,TPMI_DH_PERSISTENT * value,std::string * value_bytes)1375 TPM_RC Parse_TPMI_DH_PERSISTENT(std::string* buffer,
1376                                 TPMI_DH_PERSISTENT* value,
1377                                 std::string* value_bytes) {
1378   VLOG(3) << __func__;
1379   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1380 }
1381 
Serialize_TPMI_DH_ENTITY(const TPMI_DH_ENTITY & value,std::string * buffer)1382 TPM_RC Serialize_TPMI_DH_ENTITY(const TPMI_DH_ENTITY& value,
1383                                 std::string* buffer) {
1384   VLOG(3) << __func__;
1385   return Serialize_TPM_HANDLE(value, buffer);
1386 }
1387 
Parse_TPMI_DH_ENTITY(std::string * buffer,TPMI_DH_ENTITY * value,std::string * value_bytes)1388 TPM_RC Parse_TPMI_DH_ENTITY(std::string* buffer,
1389                             TPMI_DH_ENTITY* value,
1390                             std::string* value_bytes) {
1391   VLOG(3) << __func__;
1392   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1393 }
1394 
Serialize_TPMI_DH_PCR(const TPMI_DH_PCR & value,std::string * buffer)1395 TPM_RC Serialize_TPMI_DH_PCR(const TPMI_DH_PCR& value, std::string* buffer) {
1396   VLOG(3) << __func__;
1397   return Serialize_TPM_HANDLE(value, buffer);
1398 }
1399 
Parse_TPMI_DH_PCR(std::string * buffer,TPMI_DH_PCR * value,std::string * value_bytes)1400 TPM_RC Parse_TPMI_DH_PCR(std::string* buffer,
1401                          TPMI_DH_PCR* value,
1402                          std::string* value_bytes) {
1403   VLOG(3) << __func__;
1404   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1405 }
1406 
Serialize_TPMI_SH_AUTH_SESSION(const TPMI_SH_AUTH_SESSION & value,std::string * buffer)1407 TPM_RC Serialize_TPMI_SH_AUTH_SESSION(const TPMI_SH_AUTH_SESSION& value,
1408                                       std::string* buffer) {
1409   VLOG(3) << __func__;
1410   return Serialize_TPM_HANDLE(value, buffer);
1411 }
1412 
Parse_TPMI_SH_AUTH_SESSION(std::string * buffer,TPMI_SH_AUTH_SESSION * value,std::string * value_bytes)1413 TPM_RC Parse_TPMI_SH_AUTH_SESSION(std::string* buffer,
1414                                   TPMI_SH_AUTH_SESSION* value,
1415                                   std::string* value_bytes) {
1416   VLOG(3) << __func__;
1417   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1418 }
1419 
Serialize_TPMI_SH_HMAC(const TPMI_SH_HMAC & value,std::string * buffer)1420 TPM_RC Serialize_TPMI_SH_HMAC(const TPMI_SH_HMAC& value, std::string* buffer) {
1421   VLOG(3) << __func__;
1422   return Serialize_TPM_HANDLE(value, buffer);
1423 }
1424 
Parse_TPMI_SH_HMAC(std::string * buffer,TPMI_SH_HMAC * value,std::string * value_bytes)1425 TPM_RC Parse_TPMI_SH_HMAC(std::string* buffer,
1426                           TPMI_SH_HMAC* value,
1427                           std::string* value_bytes) {
1428   VLOG(3) << __func__;
1429   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1430 }
1431 
Serialize_TPMI_SH_POLICY(const TPMI_SH_POLICY & value,std::string * buffer)1432 TPM_RC Serialize_TPMI_SH_POLICY(const TPMI_SH_POLICY& value,
1433                                 std::string* buffer) {
1434   VLOG(3) << __func__;
1435   return Serialize_TPM_HANDLE(value, buffer);
1436 }
1437 
Parse_TPMI_SH_POLICY(std::string * buffer,TPMI_SH_POLICY * value,std::string * value_bytes)1438 TPM_RC Parse_TPMI_SH_POLICY(std::string* buffer,
1439                             TPMI_SH_POLICY* value,
1440                             std::string* value_bytes) {
1441   VLOG(3) << __func__;
1442   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1443 }
1444 
Serialize_TPMI_DH_CONTEXT(const TPMI_DH_CONTEXT & value,std::string * buffer)1445 TPM_RC Serialize_TPMI_DH_CONTEXT(const TPMI_DH_CONTEXT& value,
1446                                  std::string* buffer) {
1447   VLOG(3) << __func__;
1448   return Serialize_TPM_HANDLE(value, buffer);
1449 }
1450 
Parse_TPMI_DH_CONTEXT(std::string * buffer,TPMI_DH_CONTEXT * value,std::string * value_bytes)1451 TPM_RC Parse_TPMI_DH_CONTEXT(std::string* buffer,
1452                              TPMI_DH_CONTEXT* value,
1453                              std::string* value_bytes) {
1454   VLOG(3) << __func__;
1455   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1456 }
1457 
Serialize_TPMI_RH_HIERARCHY(const TPMI_RH_HIERARCHY & value,std::string * buffer)1458 TPM_RC Serialize_TPMI_RH_HIERARCHY(const TPMI_RH_HIERARCHY& value,
1459                                    std::string* buffer) {
1460   VLOG(3) << __func__;
1461   return Serialize_TPM_HANDLE(value, buffer);
1462 }
1463 
Parse_TPMI_RH_HIERARCHY(std::string * buffer,TPMI_RH_HIERARCHY * value,std::string * value_bytes)1464 TPM_RC Parse_TPMI_RH_HIERARCHY(std::string* buffer,
1465                                TPMI_RH_HIERARCHY* value,
1466                                std::string* value_bytes) {
1467   VLOG(3) << __func__;
1468   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1469 }
1470 
Serialize_TPMI_RH_ENABLES(const TPMI_RH_ENABLES & value,std::string * buffer)1471 TPM_RC Serialize_TPMI_RH_ENABLES(const TPMI_RH_ENABLES& value,
1472                                  std::string* buffer) {
1473   VLOG(3) << __func__;
1474   return Serialize_TPM_HANDLE(value, buffer);
1475 }
1476 
Parse_TPMI_RH_ENABLES(std::string * buffer,TPMI_RH_ENABLES * value,std::string * value_bytes)1477 TPM_RC Parse_TPMI_RH_ENABLES(std::string* buffer,
1478                              TPMI_RH_ENABLES* value,
1479                              std::string* value_bytes) {
1480   VLOG(3) << __func__;
1481   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1482 }
1483 
Serialize_TPMI_RH_HIERARCHY_AUTH(const TPMI_RH_HIERARCHY_AUTH & value,std::string * buffer)1484 TPM_RC Serialize_TPMI_RH_HIERARCHY_AUTH(const TPMI_RH_HIERARCHY_AUTH& value,
1485                                         std::string* buffer) {
1486   VLOG(3) << __func__;
1487   return Serialize_TPM_HANDLE(value, buffer);
1488 }
1489 
Parse_TPMI_RH_HIERARCHY_AUTH(std::string * buffer,TPMI_RH_HIERARCHY_AUTH * value,std::string * value_bytes)1490 TPM_RC Parse_TPMI_RH_HIERARCHY_AUTH(std::string* buffer,
1491                                     TPMI_RH_HIERARCHY_AUTH* value,
1492                                     std::string* value_bytes) {
1493   VLOG(3) << __func__;
1494   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1495 }
1496 
Serialize_TPMI_RH_PLATFORM(const TPMI_RH_PLATFORM & value,std::string * buffer)1497 TPM_RC Serialize_TPMI_RH_PLATFORM(const TPMI_RH_PLATFORM& value,
1498                                   std::string* buffer) {
1499   VLOG(3) << __func__;
1500   return Serialize_TPM_HANDLE(value, buffer);
1501 }
1502 
Parse_TPMI_RH_PLATFORM(std::string * buffer,TPMI_RH_PLATFORM * value,std::string * value_bytes)1503 TPM_RC Parse_TPMI_RH_PLATFORM(std::string* buffer,
1504                               TPMI_RH_PLATFORM* value,
1505                               std::string* value_bytes) {
1506   VLOG(3) << __func__;
1507   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1508 }
1509 
Serialize_TPMI_RH_OWNER(const TPMI_RH_OWNER & value,std::string * buffer)1510 TPM_RC Serialize_TPMI_RH_OWNER(const TPMI_RH_OWNER& value,
1511                                std::string* buffer) {
1512   VLOG(3) << __func__;
1513   return Serialize_TPM_HANDLE(value, buffer);
1514 }
1515 
Parse_TPMI_RH_OWNER(std::string * buffer,TPMI_RH_OWNER * value,std::string * value_bytes)1516 TPM_RC Parse_TPMI_RH_OWNER(std::string* buffer,
1517                            TPMI_RH_OWNER* value,
1518                            std::string* value_bytes) {
1519   VLOG(3) << __func__;
1520   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1521 }
1522 
Serialize_TPMI_RH_ENDORSEMENT(const TPMI_RH_ENDORSEMENT & value,std::string * buffer)1523 TPM_RC Serialize_TPMI_RH_ENDORSEMENT(const TPMI_RH_ENDORSEMENT& value,
1524                                      std::string* buffer) {
1525   VLOG(3) << __func__;
1526   return Serialize_TPM_HANDLE(value, buffer);
1527 }
1528 
Parse_TPMI_RH_ENDORSEMENT(std::string * buffer,TPMI_RH_ENDORSEMENT * value,std::string * value_bytes)1529 TPM_RC Parse_TPMI_RH_ENDORSEMENT(std::string* buffer,
1530                                  TPMI_RH_ENDORSEMENT* value,
1531                                  std::string* value_bytes) {
1532   VLOG(3) << __func__;
1533   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1534 }
1535 
Serialize_TPMI_RH_PROVISION(const TPMI_RH_PROVISION & value,std::string * buffer)1536 TPM_RC Serialize_TPMI_RH_PROVISION(const TPMI_RH_PROVISION& value,
1537                                    std::string* buffer) {
1538   VLOG(3) << __func__;
1539   return Serialize_TPM_HANDLE(value, buffer);
1540 }
1541 
Parse_TPMI_RH_PROVISION(std::string * buffer,TPMI_RH_PROVISION * value,std::string * value_bytes)1542 TPM_RC Parse_TPMI_RH_PROVISION(std::string* buffer,
1543                                TPMI_RH_PROVISION* value,
1544                                std::string* value_bytes) {
1545   VLOG(3) << __func__;
1546   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1547 }
1548 
Serialize_TPMI_RH_CLEAR(const TPMI_RH_CLEAR & value,std::string * buffer)1549 TPM_RC Serialize_TPMI_RH_CLEAR(const TPMI_RH_CLEAR& value,
1550                                std::string* buffer) {
1551   VLOG(3) << __func__;
1552   return Serialize_TPM_HANDLE(value, buffer);
1553 }
1554 
Parse_TPMI_RH_CLEAR(std::string * buffer,TPMI_RH_CLEAR * value,std::string * value_bytes)1555 TPM_RC Parse_TPMI_RH_CLEAR(std::string* buffer,
1556                            TPMI_RH_CLEAR* value,
1557                            std::string* value_bytes) {
1558   VLOG(3) << __func__;
1559   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1560 }
1561 
Serialize_TPMI_RH_NV_AUTH(const TPMI_RH_NV_AUTH & value,std::string * buffer)1562 TPM_RC Serialize_TPMI_RH_NV_AUTH(const TPMI_RH_NV_AUTH& value,
1563                                  std::string* buffer) {
1564   VLOG(3) << __func__;
1565   return Serialize_TPM_HANDLE(value, buffer);
1566 }
1567 
Parse_TPMI_RH_NV_AUTH(std::string * buffer,TPMI_RH_NV_AUTH * value,std::string * value_bytes)1568 TPM_RC Parse_TPMI_RH_NV_AUTH(std::string* buffer,
1569                              TPMI_RH_NV_AUTH* value,
1570                              std::string* value_bytes) {
1571   VLOG(3) << __func__;
1572   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1573 }
1574 
Serialize_TPMI_RH_LOCKOUT(const TPMI_RH_LOCKOUT & value,std::string * buffer)1575 TPM_RC Serialize_TPMI_RH_LOCKOUT(const TPMI_RH_LOCKOUT& value,
1576                                  std::string* buffer) {
1577   VLOG(3) << __func__;
1578   return Serialize_TPM_HANDLE(value, buffer);
1579 }
1580 
Parse_TPMI_RH_LOCKOUT(std::string * buffer,TPMI_RH_LOCKOUT * value,std::string * value_bytes)1581 TPM_RC Parse_TPMI_RH_LOCKOUT(std::string* buffer,
1582                              TPMI_RH_LOCKOUT* value,
1583                              std::string* value_bytes) {
1584   VLOG(3) << __func__;
1585   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1586 }
1587 
Serialize_TPMI_RH_NV_INDEX(const TPMI_RH_NV_INDEX & value,std::string * buffer)1588 TPM_RC Serialize_TPMI_RH_NV_INDEX(const TPMI_RH_NV_INDEX& value,
1589                                   std::string* buffer) {
1590   VLOG(3) << __func__;
1591   return Serialize_TPM_HANDLE(value, buffer);
1592 }
1593 
Parse_TPMI_RH_NV_INDEX(std::string * buffer,TPMI_RH_NV_INDEX * value,std::string * value_bytes)1594 TPM_RC Parse_TPMI_RH_NV_INDEX(std::string* buffer,
1595                               TPMI_RH_NV_INDEX* value,
1596                               std::string* value_bytes) {
1597   VLOG(3) << __func__;
1598   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1599 }
1600 
Serialize_TPMI_ALG_ASYM(const TPMI_ALG_ASYM & value,std::string * buffer)1601 TPM_RC Serialize_TPMI_ALG_ASYM(const TPMI_ALG_ASYM& value,
1602                                std::string* buffer) {
1603   VLOG(3) << __func__;
1604   return Serialize_TPM_ALG_ID(value, buffer);
1605 }
1606 
Parse_TPMI_ALG_ASYM(std::string * buffer,TPMI_ALG_ASYM * value,std::string * value_bytes)1607 TPM_RC Parse_TPMI_ALG_ASYM(std::string* buffer,
1608                            TPMI_ALG_ASYM* value,
1609                            std::string* value_bytes) {
1610   VLOG(3) << __func__;
1611   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1612 }
1613 
Serialize_TPMI_ALG_SYM(const TPMI_ALG_SYM & value,std::string * buffer)1614 TPM_RC Serialize_TPMI_ALG_SYM(const TPMI_ALG_SYM& value, std::string* buffer) {
1615   VLOG(3) << __func__;
1616   return Serialize_TPM_ALG_ID(value, buffer);
1617 }
1618 
Parse_TPMI_ALG_SYM(std::string * buffer,TPMI_ALG_SYM * value,std::string * value_bytes)1619 TPM_RC Parse_TPMI_ALG_SYM(std::string* buffer,
1620                           TPMI_ALG_SYM* value,
1621                           std::string* value_bytes) {
1622   VLOG(3) << __func__;
1623   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1624 }
1625 
Serialize_TPMI_ALG_SYM_OBJECT(const TPMI_ALG_SYM_OBJECT & value,std::string * buffer)1626 TPM_RC Serialize_TPMI_ALG_SYM_OBJECT(const TPMI_ALG_SYM_OBJECT& value,
1627                                      std::string* buffer) {
1628   VLOG(3) << __func__;
1629   return Serialize_TPM_ALG_ID(value, buffer);
1630 }
1631 
Parse_TPMI_ALG_SYM_OBJECT(std::string * buffer,TPMI_ALG_SYM_OBJECT * value,std::string * value_bytes)1632 TPM_RC Parse_TPMI_ALG_SYM_OBJECT(std::string* buffer,
1633                                  TPMI_ALG_SYM_OBJECT* value,
1634                                  std::string* value_bytes) {
1635   VLOG(3) << __func__;
1636   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1637 }
1638 
Serialize_TPMI_ALG_SYM_MODE(const TPMI_ALG_SYM_MODE & value,std::string * buffer)1639 TPM_RC Serialize_TPMI_ALG_SYM_MODE(const TPMI_ALG_SYM_MODE& value,
1640                                    std::string* buffer) {
1641   VLOG(3) << __func__;
1642   return Serialize_TPM_ALG_ID(value, buffer);
1643 }
1644 
Parse_TPMI_ALG_SYM_MODE(std::string * buffer,TPMI_ALG_SYM_MODE * value,std::string * value_bytes)1645 TPM_RC Parse_TPMI_ALG_SYM_MODE(std::string* buffer,
1646                                TPMI_ALG_SYM_MODE* value,
1647                                std::string* value_bytes) {
1648   VLOG(3) << __func__;
1649   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1650 }
1651 
Serialize_TPMI_ALG_KDF(const TPMI_ALG_KDF & value,std::string * buffer)1652 TPM_RC Serialize_TPMI_ALG_KDF(const TPMI_ALG_KDF& value, std::string* buffer) {
1653   VLOG(3) << __func__;
1654   return Serialize_TPM_ALG_ID(value, buffer);
1655 }
1656 
Parse_TPMI_ALG_KDF(std::string * buffer,TPMI_ALG_KDF * value,std::string * value_bytes)1657 TPM_RC Parse_TPMI_ALG_KDF(std::string* buffer,
1658                           TPMI_ALG_KDF* value,
1659                           std::string* value_bytes) {
1660   VLOG(3) << __func__;
1661   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1662 }
1663 
Serialize_TPMI_ALG_SIG_SCHEME(const TPMI_ALG_SIG_SCHEME & value,std::string * buffer)1664 TPM_RC Serialize_TPMI_ALG_SIG_SCHEME(const TPMI_ALG_SIG_SCHEME& value,
1665                                      std::string* buffer) {
1666   VLOG(3) << __func__;
1667   return Serialize_TPM_ALG_ID(value, buffer);
1668 }
1669 
Parse_TPMI_ALG_SIG_SCHEME(std::string * buffer,TPMI_ALG_SIG_SCHEME * value,std::string * value_bytes)1670 TPM_RC Parse_TPMI_ALG_SIG_SCHEME(std::string* buffer,
1671                                  TPMI_ALG_SIG_SCHEME* value,
1672                                  std::string* value_bytes) {
1673   VLOG(3) << __func__;
1674   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1675 }
1676 
Serialize_TPMI_ECC_KEY_EXCHANGE(const TPMI_ECC_KEY_EXCHANGE & value,std::string * buffer)1677 TPM_RC Serialize_TPMI_ECC_KEY_EXCHANGE(const TPMI_ECC_KEY_EXCHANGE& value,
1678                                        std::string* buffer) {
1679   VLOG(3) << __func__;
1680   return Serialize_TPM_ALG_ID(value, buffer);
1681 }
1682 
Parse_TPMI_ECC_KEY_EXCHANGE(std::string * buffer,TPMI_ECC_KEY_EXCHANGE * value,std::string * value_bytes)1683 TPM_RC Parse_TPMI_ECC_KEY_EXCHANGE(std::string* buffer,
1684                                    TPMI_ECC_KEY_EXCHANGE* value,
1685                                    std::string* value_bytes) {
1686   VLOG(3) << __func__;
1687   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1688 }
1689 
Serialize_TPM_ST(const TPM_ST & value,std::string * buffer)1690 TPM_RC Serialize_TPM_ST(const TPM_ST& value, std::string* buffer) {
1691   VLOG(3) << __func__;
1692   return Serialize_UINT16(value, buffer);
1693 }
1694 
Parse_TPM_ST(std::string * buffer,TPM_ST * value,std::string * value_bytes)1695 TPM_RC Parse_TPM_ST(std::string* buffer,
1696                     TPM_ST* value,
1697                     std::string* value_bytes) {
1698   VLOG(3) << __func__;
1699   return Parse_UINT16(buffer, value, value_bytes);
1700 }
1701 
Serialize_TPMI_ST_COMMAND_TAG(const TPMI_ST_COMMAND_TAG & value,std::string * buffer)1702 TPM_RC Serialize_TPMI_ST_COMMAND_TAG(const TPMI_ST_COMMAND_TAG& value,
1703                                      std::string* buffer) {
1704   VLOG(3) << __func__;
1705   return Serialize_TPM_ST(value, buffer);
1706 }
1707 
Parse_TPMI_ST_COMMAND_TAG(std::string * buffer,TPMI_ST_COMMAND_TAG * value,std::string * value_bytes)1708 TPM_RC Parse_TPMI_ST_COMMAND_TAG(std::string* buffer,
1709                                  TPMI_ST_COMMAND_TAG* value,
1710                                  std::string* value_bytes) {
1711   VLOG(3) << __func__;
1712   return Parse_TPM_ST(buffer, value, value_bytes);
1713 }
1714 
Serialize_TPMI_ST_ATTEST(const TPMI_ST_ATTEST & value,std::string * buffer)1715 TPM_RC Serialize_TPMI_ST_ATTEST(const TPMI_ST_ATTEST& value,
1716                                 std::string* buffer) {
1717   VLOG(3) << __func__;
1718   return Serialize_TPM_ST(value, buffer);
1719 }
1720 
Parse_TPMI_ST_ATTEST(std::string * buffer,TPMI_ST_ATTEST * value,std::string * value_bytes)1721 TPM_RC Parse_TPMI_ST_ATTEST(std::string* buffer,
1722                             TPMI_ST_ATTEST* value,
1723                             std::string* value_bytes) {
1724   VLOG(3) << __func__;
1725   return Parse_TPM_ST(buffer, value, value_bytes);
1726 }
1727 
Serialize_TPMI_AES_KEY_BITS(const TPMI_AES_KEY_BITS & value,std::string * buffer)1728 TPM_RC Serialize_TPMI_AES_KEY_BITS(const TPMI_AES_KEY_BITS& value,
1729                                    std::string* buffer) {
1730   VLOG(3) << __func__;
1731   return Serialize_TPM_KEY_BITS(value, buffer);
1732 }
1733 
Parse_TPMI_AES_KEY_BITS(std::string * buffer,TPMI_AES_KEY_BITS * value,std::string * value_bytes)1734 TPM_RC Parse_TPMI_AES_KEY_BITS(std::string* buffer,
1735                                TPMI_AES_KEY_BITS* value,
1736                                std::string* value_bytes) {
1737   VLOG(3) << __func__;
1738   return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1739 }
1740 
Serialize_TPMI_SM4_KEY_BITS(const TPMI_SM4_KEY_BITS & value,std::string * buffer)1741 TPM_RC Serialize_TPMI_SM4_KEY_BITS(const TPMI_SM4_KEY_BITS& value,
1742                                    std::string* buffer) {
1743   VLOG(3) << __func__;
1744   return Serialize_TPM_KEY_BITS(value, buffer);
1745 }
1746 
Parse_TPMI_SM4_KEY_BITS(std::string * buffer,TPMI_SM4_KEY_BITS * value,std::string * value_bytes)1747 TPM_RC Parse_TPMI_SM4_KEY_BITS(std::string* buffer,
1748                                TPMI_SM4_KEY_BITS* value,
1749                                std::string* value_bytes) {
1750   VLOG(3) << __func__;
1751   return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1752 }
1753 
Serialize_TPMI_ALG_KEYEDHASH_SCHEME(const TPMI_ALG_KEYEDHASH_SCHEME & value,std::string * buffer)1754 TPM_RC Serialize_TPMI_ALG_KEYEDHASH_SCHEME(
1755     const TPMI_ALG_KEYEDHASH_SCHEME& value, std::string* buffer) {
1756   VLOG(3) << __func__;
1757   return Serialize_TPM_ALG_ID(value, buffer);
1758 }
1759 
Parse_TPMI_ALG_KEYEDHASH_SCHEME(std::string * buffer,TPMI_ALG_KEYEDHASH_SCHEME * value,std::string * value_bytes)1760 TPM_RC Parse_TPMI_ALG_KEYEDHASH_SCHEME(std::string* buffer,
1761                                        TPMI_ALG_KEYEDHASH_SCHEME* value,
1762                                        std::string* value_bytes) {
1763   VLOG(3) << __func__;
1764   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1765 }
1766 
Serialize_TPMI_ALG_ASYM_SCHEME(const TPMI_ALG_ASYM_SCHEME & value,std::string * buffer)1767 TPM_RC Serialize_TPMI_ALG_ASYM_SCHEME(const TPMI_ALG_ASYM_SCHEME& value,
1768                                       std::string* buffer) {
1769   VLOG(3) << __func__;
1770   return Serialize_TPM_ALG_ID(value, buffer);
1771 }
1772 
Parse_TPMI_ALG_ASYM_SCHEME(std::string * buffer,TPMI_ALG_ASYM_SCHEME * value,std::string * value_bytes)1773 TPM_RC Parse_TPMI_ALG_ASYM_SCHEME(std::string* buffer,
1774                                   TPMI_ALG_ASYM_SCHEME* value,
1775                                   std::string* value_bytes) {
1776   VLOG(3) << __func__;
1777   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1778 }
1779 
Serialize_TPMI_ALG_RSA_SCHEME(const TPMI_ALG_RSA_SCHEME & value,std::string * buffer)1780 TPM_RC Serialize_TPMI_ALG_RSA_SCHEME(const TPMI_ALG_RSA_SCHEME& value,
1781                                      std::string* buffer) {
1782   VLOG(3) << __func__;
1783   return Serialize_TPM_ALG_ID(value, buffer);
1784 }
1785 
Parse_TPMI_ALG_RSA_SCHEME(std::string * buffer,TPMI_ALG_RSA_SCHEME * value,std::string * value_bytes)1786 TPM_RC Parse_TPMI_ALG_RSA_SCHEME(std::string* buffer,
1787                                  TPMI_ALG_RSA_SCHEME* value,
1788                                  std::string* value_bytes) {
1789   VLOG(3) << __func__;
1790   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1791 }
1792 
Serialize_TPMI_ALG_RSA_DECRYPT(const TPMI_ALG_RSA_DECRYPT & value,std::string * buffer)1793 TPM_RC Serialize_TPMI_ALG_RSA_DECRYPT(const TPMI_ALG_RSA_DECRYPT& value,
1794                                       std::string* buffer) {
1795   VLOG(3) << __func__;
1796   return Serialize_TPM_ALG_ID(value, buffer);
1797 }
1798 
Parse_TPMI_ALG_RSA_DECRYPT(std::string * buffer,TPMI_ALG_RSA_DECRYPT * value,std::string * value_bytes)1799 TPM_RC Parse_TPMI_ALG_RSA_DECRYPT(std::string* buffer,
1800                                   TPMI_ALG_RSA_DECRYPT* value,
1801                                   std::string* value_bytes) {
1802   VLOG(3) << __func__;
1803   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1804 }
1805 
Serialize_TPMI_RSA_KEY_BITS(const TPMI_RSA_KEY_BITS & value,std::string * buffer)1806 TPM_RC Serialize_TPMI_RSA_KEY_BITS(const TPMI_RSA_KEY_BITS& value,
1807                                    std::string* buffer) {
1808   VLOG(3) << __func__;
1809   return Serialize_TPM_KEY_BITS(value, buffer);
1810 }
1811 
Parse_TPMI_RSA_KEY_BITS(std::string * buffer,TPMI_RSA_KEY_BITS * value,std::string * value_bytes)1812 TPM_RC Parse_TPMI_RSA_KEY_BITS(std::string* buffer,
1813                                TPMI_RSA_KEY_BITS* value,
1814                                std::string* value_bytes) {
1815   VLOG(3) << __func__;
1816   return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1817 }
1818 
Serialize_TPMI_ALG_ECC_SCHEME(const TPMI_ALG_ECC_SCHEME & value,std::string * buffer)1819 TPM_RC Serialize_TPMI_ALG_ECC_SCHEME(const TPMI_ALG_ECC_SCHEME& value,
1820                                      std::string* buffer) {
1821   VLOG(3) << __func__;
1822   return Serialize_TPM_ALG_ID(value, buffer);
1823 }
1824 
Parse_TPMI_ALG_ECC_SCHEME(std::string * buffer,TPMI_ALG_ECC_SCHEME * value,std::string * value_bytes)1825 TPM_RC Parse_TPMI_ALG_ECC_SCHEME(std::string* buffer,
1826                                  TPMI_ALG_ECC_SCHEME* value,
1827                                  std::string* value_bytes) {
1828   VLOG(3) << __func__;
1829   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1830 }
1831 
Serialize_TPM_ECC_CURVE(const TPM_ECC_CURVE & value,std::string * buffer)1832 TPM_RC Serialize_TPM_ECC_CURVE(const TPM_ECC_CURVE& value,
1833                                std::string* buffer) {
1834   VLOG(3) << __func__;
1835   return Serialize_UINT16(value, buffer);
1836 }
1837 
Parse_TPM_ECC_CURVE(std::string * buffer,TPM_ECC_CURVE * value,std::string * value_bytes)1838 TPM_RC Parse_TPM_ECC_CURVE(std::string* buffer,
1839                            TPM_ECC_CURVE* value,
1840                            std::string* value_bytes) {
1841   VLOG(3) << __func__;
1842   return Parse_UINT16(buffer, value, value_bytes);
1843 }
1844 
Serialize_TPMI_ECC_CURVE(const TPMI_ECC_CURVE & value,std::string * buffer)1845 TPM_RC Serialize_TPMI_ECC_CURVE(const TPMI_ECC_CURVE& value,
1846                                 std::string* buffer) {
1847   VLOG(3) << __func__;
1848   return Serialize_TPM_ECC_CURVE(value, buffer);
1849 }
1850 
Parse_TPMI_ECC_CURVE(std::string * buffer,TPMI_ECC_CURVE * value,std::string * value_bytes)1851 TPM_RC Parse_TPMI_ECC_CURVE(std::string* buffer,
1852                             TPMI_ECC_CURVE* value,
1853                             std::string* value_bytes) {
1854   VLOG(3) << __func__;
1855   return Parse_TPM_ECC_CURVE(buffer, value, value_bytes);
1856 }
1857 
Serialize_TPMI_ALG_PUBLIC(const TPMI_ALG_PUBLIC & value,std::string * buffer)1858 TPM_RC Serialize_TPMI_ALG_PUBLIC(const TPMI_ALG_PUBLIC& value,
1859                                  std::string* buffer) {
1860   VLOG(3) << __func__;
1861   return Serialize_TPM_ALG_ID(value, buffer);
1862 }
1863 
Parse_TPMI_ALG_PUBLIC(std::string * buffer,TPMI_ALG_PUBLIC * value,std::string * value_bytes)1864 TPM_RC Parse_TPMI_ALG_PUBLIC(std::string* buffer,
1865                              TPMI_ALG_PUBLIC* value,
1866                              std::string* value_bytes) {
1867   VLOG(3) << __func__;
1868   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1869 }
1870 
Serialize_TPMA_ALGORITHM(const TPMA_ALGORITHM & value,std::string * buffer)1871 TPM_RC Serialize_TPMA_ALGORITHM(const TPMA_ALGORITHM& value,
1872                                 std::string* buffer) {
1873   VLOG(3) << __func__;
1874   return Serialize_UINT32(value, buffer);
1875 }
1876 
Parse_TPMA_ALGORITHM(std::string * buffer,TPMA_ALGORITHM * value,std::string * value_bytes)1877 TPM_RC Parse_TPMA_ALGORITHM(std::string* buffer,
1878                             TPMA_ALGORITHM* value,
1879                             std::string* value_bytes) {
1880   VLOG(3) << __func__;
1881   return Parse_UINT32(buffer, value, value_bytes);
1882 }
1883 
Serialize_TPMA_OBJECT(const TPMA_OBJECT & value,std::string * buffer)1884 TPM_RC Serialize_TPMA_OBJECT(const TPMA_OBJECT& value, std::string* buffer) {
1885   VLOG(3) << __func__;
1886   return Serialize_UINT32(value, buffer);
1887 }
1888 
Parse_TPMA_OBJECT(std::string * buffer,TPMA_OBJECT * value,std::string * value_bytes)1889 TPM_RC Parse_TPMA_OBJECT(std::string* buffer,
1890                          TPMA_OBJECT* value,
1891                          std::string* value_bytes) {
1892   VLOG(3) << __func__;
1893   return Parse_UINT32(buffer, value, value_bytes);
1894 }
1895 
Serialize_TPMA_SESSION(const TPMA_SESSION & value,std::string * buffer)1896 TPM_RC Serialize_TPMA_SESSION(const TPMA_SESSION& value, std::string* buffer) {
1897   VLOG(3) << __func__;
1898   return Serialize_UINT8(value, buffer);
1899 }
1900 
Parse_TPMA_SESSION(std::string * buffer,TPMA_SESSION * value,std::string * value_bytes)1901 TPM_RC Parse_TPMA_SESSION(std::string* buffer,
1902                           TPMA_SESSION* value,
1903                           std::string* value_bytes) {
1904   VLOG(3) << __func__;
1905   return Parse_UINT8(buffer, value, value_bytes);
1906 }
1907 
Serialize_TPMA_LOCALITY(const TPMA_LOCALITY & value,std::string * buffer)1908 TPM_RC Serialize_TPMA_LOCALITY(const TPMA_LOCALITY& value,
1909                                std::string* buffer) {
1910   VLOG(3) << __func__;
1911   return Serialize_UINT8(value, buffer);
1912 }
1913 
Parse_TPMA_LOCALITY(std::string * buffer,TPMA_LOCALITY * value,std::string * value_bytes)1914 TPM_RC Parse_TPMA_LOCALITY(std::string* buffer,
1915                            TPMA_LOCALITY* value,
1916                            std::string* value_bytes) {
1917   VLOG(3) << __func__;
1918   return Parse_UINT8(buffer, value, value_bytes);
1919 }
1920 
Serialize_TPMA_PERMANENT(const TPMA_PERMANENT & value,std::string * buffer)1921 TPM_RC Serialize_TPMA_PERMANENT(const TPMA_PERMANENT& value,
1922                                 std::string* buffer) {
1923   VLOG(3) << __func__;
1924   return Serialize_UINT32(value, buffer);
1925 }
1926 
Parse_TPMA_PERMANENT(std::string * buffer,TPMA_PERMANENT * value,std::string * value_bytes)1927 TPM_RC Parse_TPMA_PERMANENT(std::string* buffer,
1928                             TPMA_PERMANENT* value,
1929                             std::string* value_bytes) {
1930   VLOG(3) << __func__;
1931   return Parse_UINT32(buffer, value, value_bytes);
1932 }
1933 
Serialize_TPMA_STARTUP_CLEAR(const TPMA_STARTUP_CLEAR & value,std::string * buffer)1934 TPM_RC Serialize_TPMA_STARTUP_CLEAR(const TPMA_STARTUP_CLEAR& value,
1935                                     std::string* buffer) {
1936   VLOG(3) << __func__;
1937   return Serialize_UINT32(value, buffer);
1938 }
1939 
Parse_TPMA_STARTUP_CLEAR(std::string * buffer,TPMA_STARTUP_CLEAR * value,std::string * value_bytes)1940 TPM_RC Parse_TPMA_STARTUP_CLEAR(std::string* buffer,
1941                                 TPMA_STARTUP_CLEAR* value,
1942                                 std::string* value_bytes) {
1943   VLOG(3) << __func__;
1944   return Parse_UINT32(buffer, value, value_bytes);
1945 }
1946 
Serialize_TPMA_MEMORY(const TPMA_MEMORY & value,std::string * buffer)1947 TPM_RC Serialize_TPMA_MEMORY(const TPMA_MEMORY& value, std::string* buffer) {
1948   VLOG(3) << __func__;
1949   return Serialize_UINT32(value, buffer);
1950 }
1951 
Parse_TPMA_MEMORY(std::string * buffer,TPMA_MEMORY * value,std::string * value_bytes)1952 TPM_RC Parse_TPMA_MEMORY(std::string* buffer,
1953                          TPMA_MEMORY* value,
1954                          std::string* value_bytes) {
1955   VLOG(3) << __func__;
1956   return Parse_UINT32(buffer, value, value_bytes);
1957 }
1958 
Serialize_TPM_CC(const TPM_CC & value,std::string * buffer)1959 TPM_RC Serialize_TPM_CC(const TPM_CC& value, std::string* buffer) {
1960   VLOG(3) << __func__;
1961   return Serialize_UINT32(value, buffer);
1962 }
1963 
Parse_TPM_CC(std::string * buffer,TPM_CC * value,std::string * value_bytes)1964 TPM_RC Parse_TPM_CC(std::string* buffer,
1965                     TPM_CC* value,
1966                     std::string* value_bytes) {
1967   VLOG(3) << __func__;
1968   return Parse_UINT32(buffer, value, value_bytes);
1969 }
1970 
Serialize_TPMA_CC(const TPMA_CC & value,std::string * buffer)1971 TPM_RC Serialize_TPMA_CC(const TPMA_CC& value, std::string* buffer) {
1972   VLOG(3) << __func__;
1973   return Serialize_TPM_CC(value, buffer);
1974 }
1975 
Parse_TPMA_CC(std::string * buffer,TPMA_CC * value,std::string * value_bytes)1976 TPM_RC Parse_TPMA_CC(std::string* buffer,
1977                      TPMA_CC* value,
1978                      std::string* value_bytes) {
1979   VLOG(3) << __func__;
1980   return Parse_TPM_CC(buffer, value, value_bytes);
1981 }
1982 
Serialize_TPM_NV_INDEX(const TPM_NV_INDEX & value,std::string * buffer)1983 TPM_RC Serialize_TPM_NV_INDEX(const TPM_NV_INDEX& value, std::string* buffer) {
1984   VLOG(3) << __func__;
1985   return Serialize_UINT32(value, buffer);
1986 }
1987 
Parse_TPM_NV_INDEX(std::string * buffer,TPM_NV_INDEX * value,std::string * value_bytes)1988 TPM_RC Parse_TPM_NV_INDEX(std::string* buffer,
1989                           TPM_NV_INDEX* value,
1990                           std::string* value_bytes) {
1991   VLOG(3) << __func__;
1992   return Parse_UINT32(buffer, value, value_bytes);
1993 }
1994 
Serialize_TPMA_NV(const TPMA_NV & value,std::string * buffer)1995 TPM_RC Serialize_TPMA_NV(const TPMA_NV& value, std::string* buffer) {
1996   VLOG(3) << __func__;
1997   return Serialize_UINT32(value, buffer);
1998 }
1999 
Parse_TPMA_NV(std::string * buffer,TPMA_NV * value,std::string * value_bytes)2000 TPM_RC Parse_TPMA_NV(std::string* buffer,
2001                      TPMA_NV* value,
2002                      std::string* value_bytes) {
2003   VLOG(3) << __func__;
2004   return Parse_UINT32(buffer, value, value_bytes);
2005 }
2006 
Serialize_TPM_SPEC(const TPM_SPEC & value,std::string * buffer)2007 TPM_RC Serialize_TPM_SPEC(const TPM_SPEC& value, std::string* buffer) {
2008   VLOG(3) << __func__;
2009   return Serialize_UINT32(value, buffer);
2010 }
2011 
Parse_TPM_SPEC(std::string * buffer,TPM_SPEC * value,std::string * value_bytes)2012 TPM_RC Parse_TPM_SPEC(std::string* buffer,
2013                       TPM_SPEC* value,
2014                       std::string* value_bytes) {
2015   VLOG(3) << __func__;
2016   return Parse_UINT32(buffer, value, value_bytes);
2017 }
2018 
Serialize_TPM_GENERATED(const TPM_GENERATED & value,std::string * buffer)2019 TPM_RC Serialize_TPM_GENERATED(const TPM_GENERATED& value,
2020                                std::string* buffer) {
2021   VLOG(3) << __func__;
2022   return Serialize_UINT32(value, buffer);
2023 }
2024 
Parse_TPM_GENERATED(std::string * buffer,TPM_GENERATED * value,std::string * value_bytes)2025 TPM_RC Parse_TPM_GENERATED(std::string* buffer,
2026                            TPM_GENERATED* value,
2027                            std::string* value_bytes) {
2028   VLOG(3) << __func__;
2029   return Parse_UINT32(buffer, value, value_bytes);
2030 }
2031 
Serialize_TPM_RC(const TPM_RC & value,std::string * buffer)2032 TPM_RC Serialize_TPM_RC(const TPM_RC& value, std::string* buffer) {
2033   VLOG(3) << __func__;
2034   return Serialize_UINT32(value, buffer);
2035 }
2036 
Parse_TPM_RC(std::string * buffer,TPM_RC * value,std::string * value_bytes)2037 TPM_RC Parse_TPM_RC(std::string* buffer,
2038                     TPM_RC* value,
2039                     std::string* value_bytes) {
2040   VLOG(3) << __func__;
2041   return Parse_UINT32(buffer, value, value_bytes);
2042 }
2043 
Serialize_TPM_CLOCK_ADJUST(const TPM_CLOCK_ADJUST & value,std::string * buffer)2044 TPM_RC Serialize_TPM_CLOCK_ADJUST(const TPM_CLOCK_ADJUST& value,
2045                                   std::string* buffer) {
2046   VLOG(3) << __func__;
2047   return Serialize_INT8(value, buffer);
2048 }
2049 
Parse_TPM_CLOCK_ADJUST(std::string * buffer,TPM_CLOCK_ADJUST * value,std::string * value_bytes)2050 TPM_RC Parse_TPM_CLOCK_ADJUST(std::string* buffer,
2051                               TPM_CLOCK_ADJUST* value,
2052                               std::string* value_bytes) {
2053   VLOG(3) << __func__;
2054   return Parse_INT8(buffer, value, value_bytes);
2055 }
2056 
Serialize_TPM_EO(const TPM_EO & value,std::string * buffer)2057 TPM_RC Serialize_TPM_EO(const TPM_EO& value, std::string* buffer) {
2058   VLOG(3) << __func__;
2059   return Serialize_UINT16(value, buffer);
2060 }
2061 
Parse_TPM_EO(std::string * buffer,TPM_EO * value,std::string * value_bytes)2062 TPM_RC Parse_TPM_EO(std::string* buffer,
2063                     TPM_EO* value,
2064                     std::string* value_bytes) {
2065   VLOG(3) << __func__;
2066   return Parse_UINT16(buffer, value, value_bytes);
2067 }
2068 
Serialize_TPM_SU(const TPM_SU & value,std::string * buffer)2069 TPM_RC Serialize_TPM_SU(const TPM_SU& value, std::string* buffer) {
2070   VLOG(3) << __func__;
2071   return Serialize_UINT16(value, buffer);
2072 }
2073 
Parse_TPM_SU(std::string * buffer,TPM_SU * value,std::string * value_bytes)2074 TPM_RC Parse_TPM_SU(std::string* buffer,
2075                     TPM_SU* value,
2076                     std::string* value_bytes) {
2077   VLOG(3) << __func__;
2078   return Parse_UINT16(buffer, value, value_bytes);
2079 }
2080 
Serialize_TPM_SE(const TPM_SE & value,std::string * buffer)2081 TPM_RC Serialize_TPM_SE(const TPM_SE& value, std::string* buffer) {
2082   VLOG(3) << __func__;
2083   return Serialize_UINT8(value, buffer);
2084 }
2085 
Parse_TPM_SE(std::string * buffer,TPM_SE * value,std::string * value_bytes)2086 TPM_RC Parse_TPM_SE(std::string* buffer,
2087                     TPM_SE* value,
2088                     std::string* value_bytes) {
2089   VLOG(3) << __func__;
2090   return Parse_UINT8(buffer, value, value_bytes);
2091 }
2092 
Serialize_TPM_CAP(const TPM_CAP & value,std::string * buffer)2093 TPM_RC Serialize_TPM_CAP(const TPM_CAP& value, std::string* buffer) {
2094   VLOG(3) << __func__;
2095   return Serialize_UINT32(value, buffer);
2096 }
2097 
Parse_TPM_CAP(std::string * buffer,TPM_CAP * value,std::string * value_bytes)2098 TPM_RC Parse_TPM_CAP(std::string* buffer,
2099                      TPM_CAP* value,
2100                      std::string* value_bytes) {
2101   VLOG(3) << __func__;
2102   return Parse_UINT32(buffer, value, value_bytes);
2103 }
2104 
Serialize_TPM_PT(const TPM_PT & value,std::string * buffer)2105 TPM_RC Serialize_TPM_PT(const TPM_PT& value, std::string* buffer) {
2106   VLOG(3) << __func__;
2107   return Serialize_UINT32(value, buffer);
2108 }
2109 
Parse_TPM_PT(std::string * buffer,TPM_PT * value,std::string * value_bytes)2110 TPM_RC Parse_TPM_PT(std::string* buffer,
2111                     TPM_PT* value,
2112                     std::string* value_bytes) {
2113   VLOG(3) << __func__;
2114   return Parse_UINT32(buffer, value, value_bytes);
2115 }
2116 
Serialize_TPM_PT_PCR(const TPM_PT_PCR & value,std::string * buffer)2117 TPM_RC Serialize_TPM_PT_PCR(const TPM_PT_PCR& value, std::string* buffer) {
2118   VLOG(3) << __func__;
2119   return Serialize_UINT32(value, buffer);
2120 }
2121 
Parse_TPM_PT_PCR(std::string * buffer,TPM_PT_PCR * value,std::string * value_bytes)2122 TPM_RC Parse_TPM_PT_PCR(std::string* buffer,
2123                         TPM_PT_PCR* value,
2124                         std::string* value_bytes) {
2125   VLOG(3) << __func__;
2126   return Parse_UINT32(buffer, value, value_bytes);
2127 }
2128 
Serialize_TPM_PS(const TPM_PS & value,std::string * buffer)2129 TPM_RC Serialize_TPM_PS(const TPM_PS& value, std::string* buffer) {
2130   VLOG(3) << __func__;
2131   return Serialize_UINT32(value, buffer);
2132 }
2133 
Parse_TPM_PS(std::string * buffer,TPM_PS * value,std::string * value_bytes)2134 TPM_RC Parse_TPM_PS(std::string* buffer,
2135                     TPM_PS* value,
2136                     std::string* value_bytes) {
2137   VLOG(3) << __func__;
2138   return Parse_UINT32(buffer, value, value_bytes);
2139 }
2140 
Serialize_TPM_HT(const TPM_HT & value,std::string * buffer)2141 TPM_RC Serialize_TPM_HT(const TPM_HT& value, std::string* buffer) {
2142   VLOG(3) << __func__;
2143   return Serialize_UINT8(value, buffer);
2144 }
2145 
Parse_TPM_HT(std::string * buffer,TPM_HT * value,std::string * value_bytes)2146 TPM_RC Parse_TPM_HT(std::string* buffer,
2147                     TPM_HT* value,
2148                     std::string* value_bytes) {
2149   VLOG(3) << __func__;
2150   return Parse_UINT8(buffer, value, value_bytes);
2151 }
2152 
Serialize_TPM_RH(const TPM_RH & value,std::string * buffer)2153 TPM_RC Serialize_TPM_RH(const TPM_RH& value, std::string* buffer) {
2154   VLOG(3) << __func__;
2155   return Serialize_UINT32(value, buffer);
2156 }
2157 
Parse_TPM_RH(std::string * buffer,TPM_RH * value,std::string * value_bytes)2158 TPM_RC Parse_TPM_RH(std::string* buffer,
2159                     TPM_RH* value,
2160                     std::string* value_bytes) {
2161   VLOG(3) << __func__;
2162   return Parse_UINT32(buffer, value, value_bytes);
2163 }
2164 
Serialize_TPM_HC(const TPM_HC & value,std::string * buffer)2165 TPM_RC Serialize_TPM_HC(const TPM_HC& value, std::string* buffer) {
2166   VLOG(3) << __func__;
2167   return Serialize_TPM_HANDLE(value, buffer);
2168 }
2169 
Parse_TPM_HC(std::string * buffer,TPM_HC * value,std::string * value_bytes)2170 TPM_RC Parse_TPM_HC(std::string* buffer,
2171                     TPM_HC* value,
2172                     std::string* value_bytes) {
2173   VLOG(3) << __func__;
2174   return Parse_TPM_HANDLE(buffer, value, value_bytes);
2175 }
2176 
Serialize_TPMS_ALGORITHM_DESCRIPTION(const TPMS_ALGORITHM_DESCRIPTION & value,std::string * buffer)2177 TPM_RC Serialize_TPMS_ALGORITHM_DESCRIPTION(
2178     const TPMS_ALGORITHM_DESCRIPTION& value, std::string* buffer) {
2179   TPM_RC result = TPM_RC_SUCCESS;
2180   VLOG(3) << __func__;
2181 
2182   result = Serialize_TPM_ALG_ID(value.alg, buffer);
2183   if (result) {
2184     return result;
2185   }
2186 
2187   result = Serialize_TPMA_ALGORITHM(value.attributes, buffer);
2188   if (result) {
2189     return result;
2190   }
2191   return result;
2192 }
2193 
Parse_TPMS_ALGORITHM_DESCRIPTION(std::string * buffer,TPMS_ALGORITHM_DESCRIPTION * value,std::string * value_bytes)2194 TPM_RC Parse_TPMS_ALGORITHM_DESCRIPTION(std::string* buffer,
2195                                         TPMS_ALGORITHM_DESCRIPTION* value,
2196                                         std::string* value_bytes) {
2197   TPM_RC result = TPM_RC_SUCCESS;
2198   VLOG(3) << __func__;
2199 
2200   result = Parse_TPM_ALG_ID(buffer, &value->alg, value_bytes);
2201   if (result) {
2202     return result;
2203   }
2204 
2205   result = Parse_TPMA_ALGORITHM(buffer, &value->attributes, value_bytes);
2206   if (result) {
2207     return result;
2208   }
2209   return result;
2210 }
2211 
Serialize_TPMU_HA(const TPMU_HA & value,TPMI_ALG_HASH selector,std::string * buffer)2212 TPM_RC Serialize_TPMU_HA(const TPMU_HA& value,
2213                          TPMI_ALG_HASH selector,
2214                          std::string* buffer) {
2215   TPM_RC result = TPM_RC_SUCCESS;
2216   VLOG(3) << __func__;
2217 
2218   if (selector == TPM_ALG_SHA384) {
2219     if (std::size(value.sha384) < SHA384_DIGEST_SIZE) {
2220       return TPM_RC_INSUFFICIENT;
2221     }
2222     for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) {
2223       result = Serialize_BYTE(value.sha384[i], buffer);
2224       if (result) {
2225         return result;
2226       }
2227     }
2228   }
2229 
2230   if (selector == TPM_ALG_SHA1) {
2231     if (std::size(value.sha1) < SHA1_DIGEST_SIZE) {
2232       return TPM_RC_INSUFFICIENT;
2233     }
2234     for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) {
2235       result = Serialize_BYTE(value.sha1[i], buffer);
2236       if (result) {
2237         return result;
2238       }
2239     }
2240   }
2241 
2242   if (selector == TPM_ALG_SM3_256) {
2243     if (std::size(value.sm3_256) < SM3_256_DIGEST_SIZE) {
2244       return TPM_RC_INSUFFICIENT;
2245     }
2246     for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) {
2247       result = Serialize_BYTE(value.sm3_256[i], buffer);
2248       if (result) {
2249         return result;
2250       }
2251     }
2252   }
2253 
2254   if (selector == TPM_ALG_NULL) {
2255     // Do nothing.
2256   }
2257 
2258   if (selector == TPM_ALG_SHA256) {
2259     if (std::size(value.sha256) < SHA256_DIGEST_SIZE) {
2260       return TPM_RC_INSUFFICIENT;
2261     }
2262     for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) {
2263       result = Serialize_BYTE(value.sha256[i], buffer);
2264       if (result) {
2265         return result;
2266       }
2267     }
2268   }
2269 
2270   if (selector == TPM_ALG_SHA512) {
2271     if (std::size(value.sha512) < SHA512_DIGEST_SIZE) {
2272       return TPM_RC_INSUFFICIENT;
2273     }
2274     for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) {
2275       result = Serialize_BYTE(value.sha512[i], buffer);
2276       if (result) {
2277         return result;
2278       }
2279     }
2280   }
2281   return result;
2282 }
2283 
Parse_TPMU_HA(std::string * buffer,TPMI_ALG_HASH selector,TPMU_HA * value,std::string * value_bytes)2284 TPM_RC Parse_TPMU_HA(std::string* buffer,
2285                      TPMI_ALG_HASH selector,
2286                      TPMU_HA* value,
2287                      std::string* value_bytes) {
2288   TPM_RC result = TPM_RC_SUCCESS;
2289   VLOG(3) << __func__;
2290 
2291   if (selector == TPM_ALG_SHA384) {
2292     if (std::size(value->sha384) < SHA384_DIGEST_SIZE) {
2293       return TPM_RC_INSUFFICIENT;
2294     }
2295     for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) {
2296       result = Parse_BYTE(buffer, &value->sha384[i], value_bytes);
2297       if (result) {
2298         return result;
2299       }
2300     }
2301   }
2302 
2303   if (selector == TPM_ALG_SHA1) {
2304     if (std::size(value->sha1) < SHA1_DIGEST_SIZE) {
2305       return TPM_RC_INSUFFICIENT;
2306     }
2307     for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) {
2308       result = Parse_BYTE(buffer, &value->sha1[i], value_bytes);
2309       if (result) {
2310         return result;
2311       }
2312     }
2313   }
2314 
2315   if (selector == TPM_ALG_SM3_256) {
2316     if (std::size(value->sm3_256) < SM3_256_DIGEST_SIZE) {
2317       return TPM_RC_INSUFFICIENT;
2318     }
2319     for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) {
2320       result = Parse_BYTE(buffer, &value->sm3_256[i], value_bytes);
2321       if (result) {
2322         return result;
2323       }
2324     }
2325   }
2326 
2327   if (selector == TPM_ALG_NULL) {
2328     // Do nothing.
2329   }
2330 
2331   if (selector == TPM_ALG_SHA256) {
2332     if (std::size(value->sha256) < SHA256_DIGEST_SIZE) {
2333       return TPM_RC_INSUFFICIENT;
2334     }
2335     for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) {
2336       result = Parse_BYTE(buffer, &value->sha256[i], value_bytes);
2337       if (result) {
2338         return result;
2339       }
2340     }
2341   }
2342 
2343   if (selector == TPM_ALG_SHA512) {
2344     if (std::size(value->sha512) < SHA512_DIGEST_SIZE) {
2345       return TPM_RC_INSUFFICIENT;
2346     }
2347     for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) {
2348       result = Parse_BYTE(buffer, &value->sha512[i], value_bytes);
2349       if (result) {
2350         return result;
2351       }
2352     }
2353   }
2354   return result;
2355 }
2356 
Serialize_TPMT_HA(const TPMT_HA & value,std::string * buffer)2357 TPM_RC Serialize_TPMT_HA(const TPMT_HA& value, std::string* buffer) {
2358   TPM_RC result = TPM_RC_SUCCESS;
2359   VLOG(3) << __func__;
2360 
2361   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
2362   if (result) {
2363     return result;
2364   }
2365 
2366   result = Serialize_TPMU_HA(value.digest, value.hash_alg, buffer);
2367   if (result) {
2368     return result;
2369   }
2370   return result;
2371 }
2372 
Parse_TPMT_HA(std::string * buffer,TPMT_HA * value,std::string * value_bytes)2373 TPM_RC Parse_TPMT_HA(std::string* buffer,
2374                      TPMT_HA* value,
2375                      std::string* value_bytes) {
2376   TPM_RC result = TPM_RC_SUCCESS;
2377   VLOG(3) << __func__;
2378 
2379   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
2380   if (result) {
2381     return result;
2382   }
2383 
2384   result = Parse_TPMU_HA(buffer, value->hash_alg, &value->digest, value_bytes);
2385   if (result) {
2386     return result;
2387   }
2388   return result;
2389 }
2390 
Serialize_TPM2B_DATA(const TPM2B_DATA & value,std::string * buffer)2391 TPM_RC Serialize_TPM2B_DATA(const TPM2B_DATA& value, std::string* buffer) {
2392   TPM_RC result = TPM_RC_SUCCESS;
2393   VLOG(3) << __func__;
2394 
2395   result = Serialize_UINT16(value.size, buffer);
2396   if (result) {
2397     return result;
2398   }
2399 
2400   if (std::size(value.buffer) < value.size) {
2401     return TPM_RC_INSUFFICIENT;
2402   }
2403   for (uint32_t i = 0; i < value.size; ++i) {
2404     result = Serialize_BYTE(value.buffer[i], buffer);
2405     if (result) {
2406       return result;
2407     }
2408   }
2409   return result;
2410 }
2411 
Parse_TPM2B_DATA(std::string * buffer,TPM2B_DATA * value,std::string * value_bytes)2412 TPM_RC Parse_TPM2B_DATA(std::string* buffer,
2413                         TPM2B_DATA* value,
2414                         std::string* value_bytes) {
2415   TPM_RC result = TPM_RC_SUCCESS;
2416   VLOG(3) << __func__;
2417 
2418   result = Parse_UINT16(buffer, &value->size, value_bytes);
2419   if (result) {
2420     return result;
2421   }
2422 
2423   if (std::size(value->buffer) < value->size) {
2424     return TPM_RC_INSUFFICIENT;
2425   }
2426   for (uint32_t i = 0; i < value->size; ++i) {
2427     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2428     if (result) {
2429       return result;
2430     }
2431   }
2432   return result;
2433 }
2434 
Make_TPM2B_DATA(const std::string & bytes)2435 TPM2B_DATA Make_TPM2B_DATA(const std::string& bytes) {
2436   TPM2B_DATA tpm2b;
2437   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2438   memset(&tpm2b, 0, sizeof(TPM2B_DATA));
2439   tpm2b.size = bytes.size();
2440   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2441   return tpm2b;
2442 }
2443 
StringFrom_TPM2B_DATA(const TPM2B_DATA & tpm2b)2444 std::string StringFrom_TPM2B_DATA(const TPM2B_DATA& tpm2b) {
2445   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2446   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2447   return std::string(char_buffer, tpm2b.size);
2448 }
2449 
Serialize_TPM2B_EVENT(const TPM2B_EVENT & value,std::string * buffer)2450 TPM_RC Serialize_TPM2B_EVENT(const TPM2B_EVENT& value, std::string* buffer) {
2451   TPM_RC result = TPM_RC_SUCCESS;
2452   VLOG(3) << __func__;
2453 
2454   result = Serialize_UINT16(value.size, buffer);
2455   if (result) {
2456     return result;
2457   }
2458 
2459   if (std::size(value.buffer) < value.size) {
2460     return TPM_RC_INSUFFICIENT;
2461   }
2462   for (uint32_t i = 0; i < value.size; ++i) {
2463     result = Serialize_BYTE(value.buffer[i], buffer);
2464     if (result) {
2465       return result;
2466     }
2467   }
2468   return result;
2469 }
2470 
Parse_TPM2B_EVENT(std::string * buffer,TPM2B_EVENT * value,std::string * value_bytes)2471 TPM_RC Parse_TPM2B_EVENT(std::string* buffer,
2472                          TPM2B_EVENT* value,
2473                          std::string* value_bytes) {
2474   TPM_RC result = TPM_RC_SUCCESS;
2475   VLOG(3) << __func__;
2476 
2477   result = Parse_UINT16(buffer, &value->size, value_bytes);
2478   if (result) {
2479     return result;
2480   }
2481 
2482   if (std::size(value->buffer) < value->size) {
2483     return TPM_RC_INSUFFICIENT;
2484   }
2485   for (uint32_t i = 0; i < value->size; ++i) {
2486     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2487     if (result) {
2488       return result;
2489     }
2490   }
2491   return result;
2492 }
2493 
Make_TPM2B_EVENT(const std::string & bytes)2494 TPM2B_EVENT Make_TPM2B_EVENT(const std::string& bytes) {
2495   TPM2B_EVENT tpm2b;
2496   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2497   memset(&tpm2b, 0, sizeof(TPM2B_EVENT));
2498   tpm2b.size = bytes.size();
2499   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2500   return tpm2b;
2501 }
2502 
StringFrom_TPM2B_EVENT(const TPM2B_EVENT & tpm2b)2503 std::string StringFrom_TPM2B_EVENT(const TPM2B_EVENT& tpm2b) {
2504   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2505   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2506   return std::string(char_buffer, tpm2b.size);
2507 }
2508 
Serialize_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER & value,std::string * buffer)2509 TPM_RC Serialize_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER& value,
2510                                   std::string* buffer) {
2511   TPM_RC result = TPM_RC_SUCCESS;
2512   VLOG(3) << __func__;
2513 
2514   result = Serialize_UINT16(value.size, buffer);
2515   if (result) {
2516     return result;
2517   }
2518 
2519   if (std::size(value.buffer) < value.size) {
2520     return TPM_RC_INSUFFICIENT;
2521   }
2522   for (uint32_t i = 0; i < value.size; ++i) {
2523     result = Serialize_BYTE(value.buffer[i], buffer);
2524     if (result) {
2525       return result;
2526     }
2527   }
2528   return result;
2529 }
2530 
Parse_TPM2B_MAX_BUFFER(std::string * buffer,TPM2B_MAX_BUFFER * value,std::string * value_bytes)2531 TPM_RC Parse_TPM2B_MAX_BUFFER(std::string* buffer,
2532                               TPM2B_MAX_BUFFER* value,
2533                               std::string* value_bytes) {
2534   TPM_RC result = TPM_RC_SUCCESS;
2535   VLOG(3) << __func__;
2536 
2537   result = Parse_UINT16(buffer, &value->size, value_bytes);
2538   if (result) {
2539     return result;
2540   }
2541 
2542   if (std::size(value->buffer) < value->size) {
2543     return TPM_RC_INSUFFICIENT;
2544   }
2545   for (uint32_t i = 0; i < value->size; ++i) {
2546     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2547     if (result) {
2548       return result;
2549     }
2550   }
2551   return result;
2552 }
2553 
Make_TPM2B_MAX_BUFFER(const std::string & bytes)2554 TPM2B_MAX_BUFFER Make_TPM2B_MAX_BUFFER(const std::string& bytes) {
2555   TPM2B_MAX_BUFFER tpm2b;
2556   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2557   memset(&tpm2b, 0, sizeof(TPM2B_MAX_BUFFER));
2558   tpm2b.size = bytes.size();
2559   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2560   return tpm2b;
2561 }
2562 
StringFrom_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER & tpm2b)2563 std::string StringFrom_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER& tpm2b) {
2564   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2565   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2566   return std::string(char_buffer, tpm2b.size);
2567 }
2568 
Serialize_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER & value,std::string * buffer)2569 TPM_RC Serialize_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER& value,
2570                                      std::string* buffer) {
2571   TPM_RC result = TPM_RC_SUCCESS;
2572   VLOG(3) << __func__;
2573 
2574   result = Serialize_UINT16(value.size, buffer);
2575   if (result) {
2576     return result;
2577   }
2578 
2579   if (std::size(value.buffer) < value.size) {
2580     return TPM_RC_INSUFFICIENT;
2581   }
2582   for (uint32_t i = 0; i < value.size; ++i) {
2583     result = Serialize_BYTE(value.buffer[i], buffer);
2584     if (result) {
2585       return result;
2586     }
2587   }
2588   return result;
2589 }
2590 
Parse_TPM2B_MAX_NV_BUFFER(std::string * buffer,TPM2B_MAX_NV_BUFFER * value,std::string * value_bytes)2591 TPM_RC Parse_TPM2B_MAX_NV_BUFFER(std::string* buffer,
2592                                  TPM2B_MAX_NV_BUFFER* value,
2593                                  std::string* value_bytes) {
2594   TPM_RC result = TPM_RC_SUCCESS;
2595   VLOG(3) << __func__;
2596 
2597   result = Parse_UINT16(buffer, &value->size, value_bytes);
2598   if (result) {
2599     return result;
2600   }
2601 
2602   if (std::size(value->buffer) < value->size) {
2603     return TPM_RC_INSUFFICIENT;
2604   }
2605   for (uint32_t i = 0; i < value->size; ++i) {
2606     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2607     if (result) {
2608       return result;
2609     }
2610   }
2611   return result;
2612 }
2613 
Make_TPM2B_MAX_NV_BUFFER(const std::string & bytes)2614 TPM2B_MAX_NV_BUFFER Make_TPM2B_MAX_NV_BUFFER(const std::string& bytes) {
2615   TPM2B_MAX_NV_BUFFER tpm2b;
2616   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2617   memset(&tpm2b, 0, sizeof(TPM2B_MAX_NV_BUFFER));
2618   tpm2b.size = bytes.size();
2619   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2620   return tpm2b;
2621 }
2622 
StringFrom_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER & tpm2b)2623 std::string StringFrom_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER& tpm2b) {
2624   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2625   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2626   return std::string(char_buffer, tpm2b.size);
2627 }
2628 
Serialize_TPM2B_TIMEOUT(const TPM2B_TIMEOUT & value,std::string * buffer)2629 TPM_RC Serialize_TPM2B_TIMEOUT(const TPM2B_TIMEOUT& value,
2630                                std::string* buffer) {
2631   TPM_RC result = TPM_RC_SUCCESS;
2632   VLOG(3) << __func__;
2633 
2634   result = Serialize_UINT16(value.size, buffer);
2635   if (result) {
2636     return result;
2637   }
2638 
2639   if (std::size(value.buffer) < value.size) {
2640     return TPM_RC_INSUFFICIENT;
2641   }
2642   for (uint32_t i = 0; i < value.size; ++i) {
2643     result = Serialize_BYTE(value.buffer[i], buffer);
2644     if (result) {
2645       return result;
2646     }
2647   }
2648   return result;
2649 }
2650 
Parse_TPM2B_TIMEOUT(std::string * buffer,TPM2B_TIMEOUT * value,std::string * value_bytes)2651 TPM_RC Parse_TPM2B_TIMEOUT(std::string* buffer,
2652                            TPM2B_TIMEOUT* value,
2653                            std::string* value_bytes) {
2654   TPM_RC result = TPM_RC_SUCCESS;
2655   VLOG(3) << __func__;
2656 
2657   result = Parse_UINT16(buffer, &value->size, value_bytes);
2658   if (result) {
2659     return result;
2660   }
2661 
2662   if (std::size(value->buffer) < value->size) {
2663     return TPM_RC_INSUFFICIENT;
2664   }
2665   for (uint32_t i = 0; i < value->size; ++i) {
2666     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2667     if (result) {
2668       return result;
2669     }
2670   }
2671   return result;
2672 }
2673 
Make_TPM2B_TIMEOUT(const std::string & bytes)2674 TPM2B_TIMEOUT Make_TPM2B_TIMEOUT(const std::string& bytes) {
2675   TPM2B_TIMEOUT tpm2b;
2676   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2677   memset(&tpm2b, 0, sizeof(TPM2B_TIMEOUT));
2678   tpm2b.size = bytes.size();
2679   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2680   return tpm2b;
2681 }
2682 
StringFrom_TPM2B_TIMEOUT(const TPM2B_TIMEOUT & tpm2b)2683 std::string StringFrom_TPM2B_TIMEOUT(const TPM2B_TIMEOUT& tpm2b) {
2684   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2685   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2686   return std::string(char_buffer, tpm2b.size);
2687 }
2688 
Serialize_TPM2B_IV(const TPM2B_IV & value,std::string * buffer)2689 TPM_RC Serialize_TPM2B_IV(const TPM2B_IV& value, std::string* buffer) {
2690   TPM_RC result = TPM_RC_SUCCESS;
2691   VLOG(3) << __func__;
2692 
2693   result = Serialize_UINT16(value.size, buffer);
2694   if (result) {
2695     return result;
2696   }
2697 
2698   if (std::size(value.buffer) < value.size) {
2699     return TPM_RC_INSUFFICIENT;
2700   }
2701   for (uint32_t i = 0; i < value.size; ++i) {
2702     result = Serialize_BYTE(value.buffer[i], buffer);
2703     if (result) {
2704       return result;
2705     }
2706   }
2707   return result;
2708 }
2709 
Parse_TPM2B_IV(std::string * buffer,TPM2B_IV * value,std::string * value_bytes)2710 TPM_RC Parse_TPM2B_IV(std::string* buffer,
2711                       TPM2B_IV* value,
2712                       std::string* value_bytes) {
2713   TPM_RC result = TPM_RC_SUCCESS;
2714   VLOG(3) << __func__;
2715 
2716   result = Parse_UINT16(buffer, &value->size, value_bytes);
2717   if (result) {
2718     return result;
2719   }
2720 
2721   if (std::size(value->buffer) < value->size) {
2722     return TPM_RC_INSUFFICIENT;
2723   }
2724   for (uint32_t i = 0; i < value->size; ++i) {
2725     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2726     if (result) {
2727       return result;
2728     }
2729   }
2730   return result;
2731 }
2732 
Make_TPM2B_IV(const std::string & bytes)2733 TPM2B_IV Make_TPM2B_IV(const std::string& bytes) {
2734   TPM2B_IV tpm2b;
2735   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2736   memset(&tpm2b, 0, sizeof(TPM2B_IV));
2737   tpm2b.size = bytes.size();
2738   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2739   return tpm2b;
2740 }
2741 
StringFrom_TPM2B_IV(const TPM2B_IV & tpm2b)2742 std::string StringFrom_TPM2B_IV(const TPM2B_IV& tpm2b) {
2743   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2744   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2745   return std::string(char_buffer, tpm2b.size);
2746 }
2747 
Serialize_TPM2B_NAME(const TPM2B_NAME & value,std::string * buffer)2748 TPM_RC Serialize_TPM2B_NAME(const TPM2B_NAME& value, std::string* buffer) {
2749   TPM_RC result = TPM_RC_SUCCESS;
2750   VLOG(3) << __func__;
2751 
2752   result = Serialize_UINT16(value.size, buffer);
2753   if (result) {
2754     return result;
2755   }
2756 
2757   if (std::size(value.name) < value.size) {
2758     return TPM_RC_INSUFFICIENT;
2759   }
2760   for (uint32_t i = 0; i < value.size; ++i) {
2761     result = Serialize_BYTE(value.name[i], buffer);
2762     if (result) {
2763       return result;
2764     }
2765   }
2766   return result;
2767 }
2768 
Parse_TPM2B_NAME(std::string * buffer,TPM2B_NAME * value,std::string * value_bytes)2769 TPM_RC Parse_TPM2B_NAME(std::string* buffer,
2770                         TPM2B_NAME* value,
2771                         std::string* value_bytes) {
2772   TPM_RC result = TPM_RC_SUCCESS;
2773   VLOG(3) << __func__;
2774 
2775   result = Parse_UINT16(buffer, &value->size, value_bytes);
2776   if (result) {
2777     return result;
2778   }
2779 
2780   if (std::size(value->name) < value->size) {
2781     return TPM_RC_INSUFFICIENT;
2782   }
2783   for (uint32_t i = 0; i < value->size; ++i) {
2784     result = Parse_BYTE(buffer, &value->name[i], value_bytes);
2785     if (result) {
2786       return result;
2787     }
2788   }
2789   return result;
2790 }
2791 
Make_TPM2B_NAME(const std::string & bytes)2792 TPM2B_NAME Make_TPM2B_NAME(const std::string& bytes) {
2793   TPM2B_NAME tpm2b;
2794   CHECK(bytes.size() <= sizeof(tpm2b.name));
2795   memset(&tpm2b, 0, sizeof(TPM2B_NAME));
2796   tpm2b.size = bytes.size();
2797   memcpy(tpm2b.name, bytes.data(), bytes.size());
2798   return tpm2b;
2799 }
2800 
StringFrom_TPM2B_NAME(const TPM2B_NAME & tpm2b)2801 std::string StringFrom_TPM2B_NAME(const TPM2B_NAME& tpm2b) {
2802   CHECK(tpm2b.size <= std::size(tpm2b.name));
2803   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.name);
2804   return std::string(char_buffer, tpm2b.size);
2805 }
2806 
Serialize_TPMS_PCR_SELECT(const TPMS_PCR_SELECT & value,std::string * buffer)2807 TPM_RC Serialize_TPMS_PCR_SELECT(const TPMS_PCR_SELECT& value,
2808                                  std::string* buffer) {
2809   TPM_RC result = TPM_RC_SUCCESS;
2810   VLOG(3) << __func__;
2811 
2812   result = Serialize_UINT8(value.sizeof_select, buffer);
2813   if (result) {
2814     return result;
2815   }
2816 
2817   if (std::size(value.pcr_select) < value.sizeof_select) {
2818     return TPM_RC_INSUFFICIENT;
2819   }
2820   for (uint32_t i = 0; i < value.sizeof_select; ++i) {
2821     result = Serialize_BYTE(value.pcr_select[i], buffer);
2822     if (result) {
2823       return result;
2824     }
2825   }
2826   return result;
2827 }
2828 
Parse_TPMS_PCR_SELECT(std::string * buffer,TPMS_PCR_SELECT * value,std::string * value_bytes)2829 TPM_RC Parse_TPMS_PCR_SELECT(std::string* buffer,
2830                              TPMS_PCR_SELECT* value,
2831                              std::string* value_bytes) {
2832   TPM_RC result = TPM_RC_SUCCESS;
2833   VLOG(3) << __func__;
2834 
2835   result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
2836   if (result) {
2837     return result;
2838   }
2839 
2840   if (std::size(value->pcr_select) < value->sizeof_select) {
2841     return TPM_RC_INSUFFICIENT;
2842   }
2843   for (uint32_t i = 0; i < value->sizeof_select; ++i) {
2844     result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
2845     if (result) {
2846       return result;
2847     }
2848   }
2849   return result;
2850 }
2851 
Serialize_TPMS_PCR_SELECTION(const TPMS_PCR_SELECTION & value,std::string * buffer)2852 TPM_RC Serialize_TPMS_PCR_SELECTION(const TPMS_PCR_SELECTION& value,
2853                                     std::string* buffer) {
2854   TPM_RC result = TPM_RC_SUCCESS;
2855   VLOG(3) << __func__;
2856 
2857   result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
2858   if (result) {
2859     return result;
2860   }
2861 
2862   result = Serialize_UINT8(value.sizeof_select, buffer);
2863   if (result) {
2864     return result;
2865   }
2866 
2867   if (std::size(value.pcr_select) < value.sizeof_select) {
2868     return TPM_RC_INSUFFICIENT;
2869   }
2870   for (uint32_t i = 0; i < value.sizeof_select; ++i) {
2871     result = Serialize_BYTE(value.pcr_select[i], buffer);
2872     if (result) {
2873       return result;
2874     }
2875   }
2876   return result;
2877 }
2878 
Parse_TPMS_PCR_SELECTION(std::string * buffer,TPMS_PCR_SELECTION * value,std::string * value_bytes)2879 TPM_RC Parse_TPMS_PCR_SELECTION(std::string* buffer,
2880                                 TPMS_PCR_SELECTION* value,
2881                                 std::string* value_bytes) {
2882   TPM_RC result = TPM_RC_SUCCESS;
2883   VLOG(3) << __func__;
2884 
2885   result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
2886   if (result) {
2887     return result;
2888   }
2889 
2890   result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
2891   if (result) {
2892     return result;
2893   }
2894 
2895   if (std::size(value->pcr_select) < value->sizeof_select) {
2896     return TPM_RC_INSUFFICIENT;
2897   }
2898   for (uint32_t i = 0; i < value->sizeof_select; ++i) {
2899     result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
2900     if (result) {
2901       return result;
2902     }
2903   }
2904   return result;
2905 }
2906 
Serialize_TPMT_TK_CREATION(const TPMT_TK_CREATION & value,std::string * buffer)2907 TPM_RC Serialize_TPMT_TK_CREATION(const TPMT_TK_CREATION& value,
2908                                   std::string* buffer) {
2909   TPM_RC result = TPM_RC_SUCCESS;
2910   VLOG(3) << __func__;
2911 
2912   result = Serialize_TPM_ST(value.tag, buffer);
2913   if (result) {
2914     return result;
2915   }
2916 
2917   result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
2918   if (result) {
2919     return result;
2920   }
2921 
2922   result = Serialize_TPM2B_DIGEST(value.digest, buffer);
2923   if (result) {
2924     return result;
2925   }
2926   return result;
2927 }
2928 
Parse_TPMT_TK_CREATION(std::string * buffer,TPMT_TK_CREATION * value,std::string * value_bytes)2929 TPM_RC Parse_TPMT_TK_CREATION(std::string* buffer,
2930                               TPMT_TK_CREATION* value,
2931                               std::string* value_bytes) {
2932   TPM_RC result = TPM_RC_SUCCESS;
2933   VLOG(3) << __func__;
2934 
2935   result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
2936   if (result) {
2937     return result;
2938   }
2939 
2940   result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
2941   if (result) {
2942     return result;
2943   }
2944 
2945   result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
2946   if (result) {
2947     return result;
2948   }
2949   return result;
2950 }
2951 
Serialize_TPMT_TK_VERIFIED(const TPMT_TK_VERIFIED & value,std::string * buffer)2952 TPM_RC Serialize_TPMT_TK_VERIFIED(const TPMT_TK_VERIFIED& value,
2953                                   std::string* buffer) {
2954   TPM_RC result = TPM_RC_SUCCESS;
2955   VLOG(3) << __func__;
2956 
2957   result = Serialize_TPM_ST(value.tag, buffer);
2958   if (result) {
2959     return result;
2960   }
2961 
2962   result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
2963   if (result) {
2964     return result;
2965   }
2966 
2967   result = Serialize_TPM2B_DIGEST(value.digest, buffer);
2968   if (result) {
2969     return result;
2970   }
2971   return result;
2972 }
2973 
Parse_TPMT_TK_VERIFIED(std::string * buffer,TPMT_TK_VERIFIED * value,std::string * value_bytes)2974 TPM_RC Parse_TPMT_TK_VERIFIED(std::string* buffer,
2975                               TPMT_TK_VERIFIED* value,
2976                               std::string* value_bytes) {
2977   TPM_RC result = TPM_RC_SUCCESS;
2978   VLOG(3) << __func__;
2979 
2980   result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
2981   if (result) {
2982     return result;
2983   }
2984 
2985   result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
2986   if (result) {
2987     return result;
2988   }
2989 
2990   result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
2991   if (result) {
2992     return result;
2993   }
2994   return result;
2995 }
2996 
Serialize_TPMT_TK_AUTH(const TPMT_TK_AUTH & value,std::string * buffer)2997 TPM_RC Serialize_TPMT_TK_AUTH(const TPMT_TK_AUTH& value, std::string* buffer) {
2998   TPM_RC result = TPM_RC_SUCCESS;
2999   VLOG(3) << __func__;
3000 
3001   result = Serialize_TPM_ST(value.tag, buffer);
3002   if (result) {
3003     return result;
3004   }
3005 
3006   result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
3007   if (result) {
3008     return result;
3009   }
3010 
3011   result = Serialize_TPM2B_DIGEST(value.digest, buffer);
3012   if (result) {
3013     return result;
3014   }
3015   return result;
3016 }
3017 
Parse_TPMT_TK_AUTH(std::string * buffer,TPMT_TK_AUTH * value,std::string * value_bytes)3018 TPM_RC Parse_TPMT_TK_AUTH(std::string* buffer,
3019                           TPMT_TK_AUTH* value,
3020                           std::string* value_bytes) {
3021   TPM_RC result = TPM_RC_SUCCESS;
3022   VLOG(3) << __func__;
3023 
3024   result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
3025   if (result) {
3026     return result;
3027   }
3028 
3029   result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
3030   if (result) {
3031     return result;
3032   }
3033 
3034   result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
3035   if (result) {
3036     return result;
3037   }
3038   return result;
3039 }
3040 
Serialize_TPMT_TK_HASHCHECK(const TPMT_TK_HASHCHECK & value,std::string * buffer)3041 TPM_RC Serialize_TPMT_TK_HASHCHECK(const TPMT_TK_HASHCHECK& value,
3042                                    std::string* buffer) {
3043   TPM_RC result = TPM_RC_SUCCESS;
3044   VLOG(3) << __func__;
3045 
3046   result = Serialize_TPM_ST(value.tag, buffer);
3047   if (result) {
3048     return result;
3049   }
3050 
3051   result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
3052   if (result) {
3053     return result;
3054   }
3055 
3056   result = Serialize_TPM2B_DIGEST(value.digest, buffer);
3057   if (result) {
3058     return result;
3059   }
3060   return result;
3061 }
3062 
Parse_TPMT_TK_HASHCHECK(std::string * buffer,TPMT_TK_HASHCHECK * value,std::string * value_bytes)3063 TPM_RC Parse_TPMT_TK_HASHCHECK(std::string* buffer,
3064                                TPMT_TK_HASHCHECK* value,
3065                                std::string* value_bytes) {
3066   TPM_RC result = TPM_RC_SUCCESS;
3067   VLOG(3) << __func__;
3068 
3069   result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
3070   if (result) {
3071     return result;
3072   }
3073 
3074   result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
3075   if (result) {
3076     return result;
3077   }
3078 
3079   result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
3080   if (result) {
3081     return result;
3082   }
3083   return result;
3084 }
3085 
Serialize_TPMS_ALG_PROPERTY(const TPMS_ALG_PROPERTY & value,std::string * buffer)3086 TPM_RC Serialize_TPMS_ALG_PROPERTY(const TPMS_ALG_PROPERTY& value,
3087                                    std::string* buffer) {
3088   TPM_RC result = TPM_RC_SUCCESS;
3089   VLOG(3) << __func__;
3090 
3091   result = Serialize_TPM_ALG_ID(value.alg, buffer);
3092   if (result) {
3093     return result;
3094   }
3095 
3096   result = Serialize_TPMA_ALGORITHM(value.alg_properties, buffer);
3097   if (result) {
3098     return result;
3099   }
3100   return result;
3101 }
3102 
Parse_TPMS_ALG_PROPERTY(std::string * buffer,TPMS_ALG_PROPERTY * value,std::string * value_bytes)3103 TPM_RC Parse_TPMS_ALG_PROPERTY(std::string* buffer,
3104                                TPMS_ALG_PROPERTY* value,
3105                                std::string* value_bytes) {
3106   TPM_RC result = TPM_RC_SUCCESS;
3107   VLOG(3) << __func__;
3108 
3109   result = Parse_TPM_ALG_ID(buffer, &value->alg, value_bytes);
3110   if (result) {
3111     return result;
3112   }
3113 
3114   result = Parse_TPMA_ALGORITHM(buffer, &value->alg_properties, value_bytes);
3115   if (result) {
3116     return result;
3117   }
3118   return result;
3119 }
3120 
Serialize_TPMS_TAGGED_PROPERTY(const TPMS_TAGGED_PROPERTY & value,std::string * buffer)3121 TPM_RC Serialize_TPMS_TAGGED_PROPERTY(const TPMS_TAGGED_PROPERTY& value,
3122                                       std::string* buffer) {
3123   TPM_RC result = TPM_RC_SUCCESS;
3124   VLOG(3) << __func__;
3125 
3126   result = Serialize_TPM_PT(value.property, buffer);
3127   if (result) {
3128     return result;
3129   }
3130 
3131   result = Serialize_UINT32(value.value, buffer);
3132   if (result) {
3133     return result;
3134   }
3135   return result;
3136 }
3137 
Parse_TPMS_TAGGED_PROPERTY(std::string * buffer,TPMS_TAGGED_PROPERTY * value,std::string * value_bytes)3138 TPM_RC Parse_TPMS_TAGGED_PROPERTY(std::string* buffer,
3139                                   TPMS_TAGGED_PROPERTY* value,
3140                                   std::string* value_bytes) {
3141   TPM_RC result = TPM_RC_SUCCESS;
3142   VLOG(3) << __func__;
3143 
3144   result = Parse_TPM_PT(buffer, &value->property, value_bytes);
3145   if (result) {
3146     return result;
3147   }
3148 
3149   result = Parse_UINT32(buffer, &value->value, value_bytes);
3150   if (result) {
3151     return result;
3152   }
3153   return result;
3154 }
3155 
Serialize_TPMS_TAGGED_PCR_SELECT(const TPMS_TAGGED_PCR_SELECT & value,std::string * buffer)3156 TPM_RC Serialize_TPMS_TAGGED_PCR_SELECT(const TPMS_TAGGED_PCR_SELECT& value,
3157                                         std::string* buffer) {
3158   TPM_RC result = TPM_RC_SUCCESS;
3159   VLOG(3) << __func__;
3160 
3161   result = Serialize_TPM_PT(value.tag, buffer);
3162   if (result) {
3163     return result;
3164   }
3165 
3166   result = Serialize_UINT8(value.sizeof_select, buffer);
3167   if (result) {
3168     return result;
3169   }
3170 
3171   if (std::size(value.pcr_select) < value.sizeof_select) {
3172     return TPM_RC_INSUFFICIENT;
3173   }
3174   for (uint32_t i = 0; i < value.sizeof_select; ++i) {
3175     result = Serialize_BYTE(value.pcr_select[i], buffer);
3176     if (result) {
3177       return result;
3178     }
3179   }
3180   return result;
3181 }
3182 
Parse_TPMS_TAGGED_PCR_SELECT(std::string * buffer,TPMS_TAGGED_PCR_SELECT * value,std::string * value_bytes)3183 TPM_RC Parse_TPMS_TAGGED_PCR_SELECT(std::string* buffer,
3184                                     TPMS_TAGGED_PCR_SELECT* value,
3185                                     std::string* value_bytes) {
3186   TPM_RC result = TPM_RC_SUCCESS;
3187   VLOG(3) << __func__;
3188 
3189   result = Parse_TPM_PT(buffer, &value->tag, value_bytes);
3190   if (result) {
3191     return result;
3192   }
3193 
3194   result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
3195   if (result) {
3196     return result;
3197   }
3198 
3199   if (std::size(value->pcr_select) < value->sizeof_select) {
3200     return TPM_RC_INSUFFICIENT;
3201   }
3202   for (uint32_t i = 0; i < value->sizeof_select; ++i) {
3203     result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
3204     if (result) {
3205       return result;
3206     }
3207   }
3208   return result;
3209 }
3210 
Serialize_TPML_CC(const TPML_CC & value,std::string * buffer)3211 TPM_RC Serialize_TPML_CC(const TPML_CC& value, std::string* buffer) {
3212   TPM_RC result = TPM_RC_SUCCESS;
3213   VLOG(3) << __func__;
3214 
3215   result = Serialize_UINT32(value.count, buffer);
3216   if (result) {
3217     return result;
3218   }
3219 
3220   if (std::size(value.command_codes) < value.count) {
3221     return TPM_RC_INSUFFICIENT;
3222   }
3223   for (uint32_t i = 0; i < value.count; ++i) {
3224     result = Serialize_TPM_CC(value.command_codes[i], buffer);
3225     if (result) {
3226       return result;
3227     }
3228   }
3229   return result;
3230 }
3231 
Parse_TPML_CC(std::string * buffer,TPML_CC * value,std::string * value_bytes)3232 TPM_RC Parse_TPML_CC(std::string* buffer,
3233                      TPML_CC* value,
3234                      std::string* value_bytes) {
3235   TPM_RC result = TPM_RC_SUCCESS;
3236   VLOG(3) << __func__;
3237 
3238   result = Parse_UINT32(buffer, &value->count, value_bytes);
3239   if (result) {
3240     return result;
3241   }
3242 
3243   if (std::size(value->command_codes) < value->count) {
3244     return TPM_RC_INSUFFICIENT;
3245   }
3246   for (uint32_t i = 0; i < value->count; ++i) {
3247     result = Parse_TPM_CC(buffer, &value->command_codes[i], value_bytes);
3248     if (result) {
3249       return result;
3250     }
3251   }
3252   return result;
3253 }
3254 
Serialize_TPML_CCA(const TPML_CCA & value,std::string * buffer)3255 TPM_RC Serialize_TPML_CCA(const TPML_CCA& value, std::string* buffer) {
3256   TPM_RC result = TPM_RC_SUCCESS;
3257   VLOG(3) << __func__;
3258 
3259   result = Serialize_UINT32(value.count, buffer);
3260   if (result) {
3261     return result;
3262   }
3263 
3264   if (std::size(value.command_attributes) < value.count) {
3265     return TPM_RC_INSUFFICIENT;
3266   }
3267   for (uint32_t i = 0; i < value.count; ++i) {
3268     result = Serialize_TPMA_CC(value.command_attributes[i], buffer);
3269     if (result) {
3270       return result;
3271     }
3272   }
3273   return result;
3274 }
3275 
Parse_TPML_CCA(std::string * buffer,TPML_CCA * value,std::string * value_bytes)3276 TPM_RC Parse_TPML_CCA(std::string* buffer,
3277                       TPML_CCA* value,
3278                       std::string* value_bytes) {
3279   TPM_RC result = TPM_RC_SUCCESS;
3280   VLOG(3) << __func__;
3281 
3282   result = Parse_UINT32(buffer, &value->count, value_bytes);
3283   if (result) {
3284     return result;
3285   }
3286 
3287   if (std::size(value->command_attributes) < value->count) {
3288     return TPM_RC_INSUFFICIENT;
3289   }
3290   for (uint32_t i = 0; i < value->count; ++i) {
3291     result = Parse_TPMA_CC(buffer, &value->command_attributes[i], value_bytes);
3292     if (result) {
3293       return result;
3294     }
3295   }
3296   return result;
3297 }
3298 
Serialize_TPML_ALG(const TPML_ALG & value,std::string * buffer)3299 TPM_RC Serialize_TPML_ALG(const TPML_ALG& value, std::string* buffer) {
3300   TPM_RC result = TPM_RC_SUCCESS;
3301   VLOG(3) << __func__;
3302 
3303   result = Serialize_UINT32(value.count, buffer);
3304   if (result) {
3305     return result;
3306   }
3307 
3308   if (std::size(value.algorithms) < value.count) {
3309     return TPM_RC_INSUFFICIENT;
3310   }
3311   for (uint32_t i = 0; i < value.count; ++i) {
3312     result = Serialize_TPM_ALG_ID(value.algorithms[i], buffer);
3313     if (result) {
3314       return result;
3315     }
3316   }
3317   return result;
3318 }
3319 
Parse_TPML_ALG(std::string * buffer,TPML_ALG * value,std::string * value_bytes)3320 TPM_RC Parse_TPML_ALG(std::string* buffer,
3321                       TPML_ALG* value,
3322                       std::string* value_bytes) {
3323   TPM_RC result = TPM_RC_SUCCESS;
3324   VLOG(3) << __func__;
3325 
3326   result = Parse_UINT32(buffer, &value->count, value_bytes);
3327   if (result) {
3328     return result;
3329   }
3330 
3331   if (std::size(value->algorithms) < value->count) {
3332     return TPM_RC_INSUFFICIENT;
3333   }
3334   for (uint32_t i = 0; i < value->count; ++i) {
3335     result = Parse_TPM_ALG_ID(buffer, &value->algorithms[i], value_bytes);
3336     if (result) {
3337       return result;
3338     }
3339   }
3340   return result;
3341 }
3342 
Serialize_TPML_HANDLE(const TPML_HANDLE & value,std::string * buffer)3343 TPM_RC Serialize_TPML_HANDLE(const TPML_HANDLE& value, std::string* buffer) {
3344   TPM_RC result = TPM_RC_SUCCESS;
3345   VLOG(3) << __func__;
3346 
3347   result = Serialize_UINT32(value.count, buffer);
3348   if (result) {
3349     return result;
3350   }
3351 
3352   if (std::size(value.handle) < value.count) {
3353     return TPM_RC_INSUFFICIENT;
3354   }
3355   for (uint32_t i = 0; i < value.count; ++i) {
3356     result = Serialize_TPM_HANDLE(value.handle[i], buffer);
3357     if (result) {
3358       return result;
3359     }
3360   }
3361   return result;
3362 }
3363 
Parse_TPML_HANDLE(std::string * buffer,TPML_HANDLE * value,std::string * value_bytes)3364 TPM_RC Parse_TPML_HANDLE(std::string* buffer,
3365                          TPML_HANDLE* value,
3366                          std::string* value_bytes) {
3367   TPM_RC result = TPM_RC_SUCCESS;
3368   VLOG(3) << __func__;
3369 
3370   result = Parse_UINT32(buffer, &value->count, value_bytes);
3371   if (result) {
3372     return result;
3373   }
3374 
3375   if (std::size(value->handle) < value->count) {
3376     return TPM_RC_INSUFFICIENT;
3377   }
3378   for (uint32_t i = 0; i < value->count; ++i) {
3379     result = Parse_TPM_HANDLE(buffer, &value->handle[i], value_bytes);
3380     if (result) {
3381       return result;
3382     }
3383   }
3384   return result;
3385 }
3386 
Serialize_TPML_DIGEST(const TPML_DIGEST & value,std::string * buffer)3387 TPM_RC Serialize_TPML_DIGEST(const TPML_DIGEST& value, std::string* buffer) {
3388   TPM_RC result = TPM_RC_SUCCESS;
3389   VLOG(3) << __func__;
3390 
3391   result = Serialize_UINT32(value.count, buffer);
3392   if (result) {
3393     return result;
3394   }
3395 
3396   if (std::size(value.digests) < value.count) {
3397     return TPM_RC_INSUFFICIENT;
3398   }
3399   for (uint32_t i = 0; i < value.count; ++i) {
3400     result = Serialize_TPM2B_DIGEST(value.digests[i], buffer);
3401     if (result) {
3402       return result;
3403     }
3404   }
3405   return result;
3406 }
3407 
Parse_TPML_DIGEST(std::string * buffer,TPML_DIGEST * value,std::string * value_bytes)3408 TPM_RC Parse_TPML_DIGEST(std::string* buffer,
3409                          TPML_DIGEST* value,
3410                          std::string* value_bytes) {
3411   TPM_RC result = TPM_RC_SUCCESS;
3412   VLOG(3) << __func__;
3413 
3414   result = Parse_UINT32(buffer, &value->count, value_bytes);
3415   if (result) {
3416     return result;
3417   }
3418 
3419   if (std::size(value->digests) < value->count) {
3420     return TPM_RC_INSUFFICIENT;
3421   }
3422   for (uint32_t i = 0; i < value->count; ++i) {
3423     result = Parse_TPM2B_DIGEST(buffer, &value->digests[i], value_bytes);
3424     if (result) {
3425       return result;
3426     }
3427   }
3428   return result;
3429 }
3430 
Serialize_TPML_DIGEST_VALUES(const TPML_DIGEST_VALUES & value,std::string * buffer)3431 TPM_RC Serialize_TPML_DIGEST_VALUES(const TPML_DIGEST_VALUES& value,
3432                                     std::string* buffer) {
3433   TPM_RC result = TPM_RC_SUCCESS;
3434   VLOG(3) << __func__;
3435 
3436   result = Serialize_UINT32(value.count, buffer);
3437   if (result) {
3438     return result;
3439   }
3440 
3441   if (std::size(value.digests) < value.count) {
3442     return TPM_RC_INSUFFICIENT;
3443   }
3444   for (uint32_t i = 0; i < value.count; ++i) {
3445     result = Serialize_TPMT_HA(value.digests[i], buffer);
3446     if (result) {
3447       return result;
3448     }
3449   }
3450   return result;
3451 }
3452 
Parse_TPML_DIGEST_VALUES(std::string * buffer,TPML_DIGEST_VALUES * value,std::string * value_bytes)3453 TPM_RC Parse_TPML_DIGEST_VALUES(std::string* buffer,
3454                                 TPML_DIGEST_VALUES* value,
3455                                 std::string* value_bytes) {
3456   TPM_RC result = TPM_RC_SUCCESS;
3457   VLOG(3) << __func__;
3458 
3459   result = Parse_UINT32(buffer, &value->count, value_bytes);
3460   if (result) {
3461     return result;
3462   }
3463 
3464   if (std::size(value->digests) < value->count) {
3465     return TPM_RC_INSUFFICIENT;
3466   }
3467   for (uint32_t i = 0; i < value->count; ++i) {
3468     result = Parse_TPMT_HA(buffer, &value->digests[i], value_bytes);
3469     if (result) {
3470       return result;
3471     }
3472   }
3473   return result;
3474 }
3475 
Serialize_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES & value,std::string * buffer)3476 TPM_RC Serialize_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES& value,
3477                                      std::string* buffer) {
3478   TPM_RC result = TPM_RC_SUCCESS;
3479   VLOG(3) << __func__;
3480 
3481   result = Serialize_UINT16(value.size, buffer);
3482   if (result) {
3483     return result;
3484   }
3485 
3486   if (std::size(value.buffer) < value.size) {
3487     return TPM_RC_INSUFFICIENT;
3488   }
3489   for (uint32_t i = 0; i < value.size; ++i) {
3490     result = Serialize_BYTE(value.buffer[i], buffer);
3491     if (result) {
3492       return result;
3493     }
3494   }
3495   return result;
3496 }
3497 
Parse_TPM2B_DIGEST_VALUES(std::string * buffer,TPM2B_DIGEST_VALUES * value,std::string * value_bytes)3498 TPM_RC Parse_TPM2B_DIGEST_VALUES(std::string* buffer,
3499                                  TPM2B_DIGEST_VALUES* value,
3500                                  std::string* value_bytes) {
3501   TPM_RC result = TPM_RC_SUCCESS;
3502   VLOG(3) << __func__;
3503 
3504   result = Parse_UINT16(buffer, &value->size, value_bytes);
3505   if (result) {
3506     return result;
3507   }
3508 
3509   if (std::size(value->buffer) < value->size) {
3510     return TPM_RC_INSUFFICIENT;
3511   }
3512   for (uint32_t i = 0; i < value->size; ++i) {
3513     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
3514     if (result) {
3515       return result;
3516     }
3517   }
3518   return result;
3519 }
3520 
Make_TPM2B_DIGEST_VALUES(const std::string & bytes)3521 TPM2B_DIGEST_VALUES Make_TPM2B_DIGEST_VALUES(const std::string& bytes) {
3522   TPM2B_DIGEST_VALUES tpm2b;
3523   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
3524   memset(&tpm2b, 0, sizeof(TPM2B_DIGEST_VALUES));
3525   tpm2b.size = bytes.size();
3526   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
3527   return tpm2b;
3528 }
3529 
StringFrom_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES & tpm2b)3530 std::string StringFrom_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES& tpm2b) {
3531   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
3532   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
3533   return std::string(char_buffer, tpm2b.size);
3534 }
3535 
Serialize_TPML_PCR_SELECTION(const TPML_PCR_SELECTION & value,std::string * buffer)3536 TPM_RC Serialize_TPML_PCR_SELECTION(const TPML_PCR_SELECTION& value,
3537                                     std::string* buffer) {
3538   TPM_RC result = TPM_RC_SUCCESS;
3539   VLOG(3) << __func__;
3540 
3541   result = Serialize_UINT32(value.count, buffer);
3542   if (result) {
3543     return result;
3544   }
3545 
3546   if (std::size(value.pcr_selections) < value.count) {
3547     return TPM_RC_INSUFFICIENT;
3548   }
3549   for (uint32_t i = 0; i < value.count; ++i) {
3550     result = Serialize_TPMS_PCR_SELECTION(value.pcr_selections[i], buffer);
3551     if (result) {
3552       return result;
3553     }
3554   }
3555   return result;
3556 }
3557 
Parse_TPML_PCR_SELECTION(std::string * buffer,TPML_PCR_SELECTION * value,std::string * value_bytes)3558 TPM_RC Parse_TPML_PCR_SELECTION(std::string* buffer,
3559                                 TPML_PCR_SELECTION* value,
3560                                 std::string* value_bytes) {
3561   TPM_RC result = TPM_RC_SUCCESS;
3562   VLOG(3) << __func__;
3563 
3564   result = Parse_UINT32(buffer, &value->count, value_bytes);
3565   if (result) {
3566     return result;
3567   }
3568 
3569   if (std::size(value->pcr_selections) < value->count) {
3570     return TPM_RC_INSUFFICIENT;
3571   }
3572   for (uint32_t i = 0; i < value->count; ++i) {
3573     result = Parse_TPMS_PCR_SELECTION(buffer, &value->pcr_selections[i],
3574                                       value_bytes);
3575     if (result) {
3576       return result;
3577     }
3578   }
3579   return result;
3580 }
3581 
Serialize_TPML_ALG_PROPERTY(const TPML_ALG_PROPERTY & value,std::string * buffer)3582 TPM_RC Serialize_TPML_ALG_PROPERTY(const TPML_ALG_PROPERTY& value,
3583                                    std::string* buffer) {
3584   TPM_RC result = TPM_RC_SUCCESS;
3585   VLOG(3) << __func__;
3586 
3587   result = Serialize_UINT32(value.count, buffer);
3588   if (result) {
3589     return result;
3590   }
3591 
3592   if (std::size(value.alg_properties) < value.count) {
3593     return TPM_RC_INSUFFICIENT;
3594   }
3595   for (uint32_t i = 0; i < value.count; ++i) {
3596     result = Serialize_TPMS_ALG_PROPERTY(value.alg_properties[i], buffer);
3597     if (result) {
3598       return result;
3599     }
3600   }
3601   return result;
3602 }
3603 
Parse_TPML_ALG_PROPERTY(std::string * buffer,TPML_ALG_PROPERTY * value,std::string * value_bytes)3604 TPM_RC Parse_TPML_ALG_PROPERTY(std::string* buffer,
3605                                TPML_ALG_PROPERTY* value,
3606                                std::string* value_bytes) {
3607   TPM_RC result = TPM_RC_SUCCESS;
3608   VLOG(3) << __func__;
3609 
3610   result = Parse_UINT32(buffer, &value->count, value_bytes);
3611   if (result) {
3612     return result;
3613   }
3614 
3615   if (std::size(value->alg_properties) < value->count) {
3616     return TPM_RC_INSUFFICIENT;
3617   }
3618   for (uint32_t i = 0; i < value->count; ++i) {
3619     result =
3620         Parse_TPMS_ALG_PROPERTY(buffer, &value->alg_properties[i], value_bytes);
3621     if (result) {
3622       return result;
3623     }
3624   }
3625   return result;
3626 }
3627 
Serialize_TPML_TAGGED_TPM_PROPERTY(const TPML_TAGGED_TPM_PROPERTY & value,std::string * buffer)3628 TPM_RC Serialize_TPML_TAGGED_TPM_PROPERTY(const TPML_TAGGED_TPM_PROPERTY& value,
3629                                           std::string* buffer) {
3630   TPM_RC result = TPM_RC_SUCCESS;
3631   VLOG(3) << __func__;
3632 
3633   result = Serialize_UINT32(value.count, buffer);
3634   if (result) {
3635     return result;
3636   }
3637 
3638   if (std::size(value.tpm_property) < value.count) {
3639     return TPM_RC_INSUFFICIENT;
3640   }
3641   for (uint32_t i = 0; i < value.count; ++i) {
3642     result = Serialize_TPMS_TAGGED_PROPERTY(value.tpm_property[i], buffer);
3643     if (result) {
3644       return result;
3645     }
3646   }
3647   return result;
3648 }
3649 
Parse_TPML_TAGGED_TPM_PROPERTY(std::string * buffer,TPML_TAGGED_TPM_PROPERTY * value,std::string * value_bytes)3650 TPM_RC Parse_TPML_TAGGED_TPM_PROPERTY(std::string* buffer,
3651                                       TPML_TAGGED_TPM_PROPERTY* value,
3652                                       std::string* value_bytes) {
3653   TPM_RC result = TPM_RC_SUCCESS;
3654   VLOG(3) << __func__;
3655 
3656   result = Parse_UINT32(buffer, &value->count, value_bytes);
3657   if (result) {
3658     return result;
3659   }
3660 
3661   if (std::size(value->tpm_property) < value->count) {
3662     return TPM_RC_INSUFFICIENT;
3663   }
3664   for (uint32_t i = 0; i < value->count; ++i) {
3665     result = Parse_TPMS_TAGGED_PROPERTY(buffer, &value->tpm_property[i],
3666                                         value_bytes);
3667     if (result) {
3668       return result;
3669     }
3670   }
3671   return result;
3672 }
3673 
Serialize_TPML_TAGGED_PCR_PROPERTY(const TPML_TAGGED_PCR_PROPERTY & value,std::string * buffer)3674 TPM_RC Serialize_TPML_TAGGED_PCR_PROPERTY(const TPML_TAGGED_PCR_PROPERTY& value,
3675                                           std::string* buffer) {
3676   TPM_RC result = TPM_RC_SUCCESS;
3677   VLOG(3) << __func__;
3678 
3679   result = Serialize_UINT32(value.count, buffer);
3680   if (result) {
3681     return result;
3682   }
3683 
3684   if (std::size(value.pcr_property) < value.count) {
3685     return TPM_RC_INSUFFICIENT;
3686   }
3687   for (uint32_t i = 0; i < value.count; ++i) {
3688     result = Serialize_TPMS_TAGGED_PCR_SELECT(value.pcr_property[i], buffer);
3689     if (result) {
3690       return result;
3691     }
3692   }
3693   return result;
3694 }
3695 
Parse_TPML_TAGGED_PCR_PROPERTY(std::string * buffer,TPML_TAGGED_PCR_PROPERTY * value,std::string * value_bytes)3696 TPM_RC Parse_TPML_TAGGED_PCR_PROPERTY(std::string* buffer,
3697                                       TPML_TAGGED_PCR_PROPERTY* value,
3698                                       std::string* value_bytes) {
3699   TPM_RC result = TPM_RC_SUCCESS;
3700   VLOG(3) << __func__;
3701 
3702   result = Parse_UINT32(buffer, &value->count, value_bytes);
3703   if (result) {
3704     return result;
3705   }
3706 
3707   if (std::size(value->pcr_property) < value->count) {
3708     return TPM_RC_INSUFFICIENT;
3709   }
3710   for (uint32_t i = 0; i < value->count; ++i) {
3711     result = Parse_TPMS_TAGGED_PCR_SELECT(buffer, &value->pcr_property[i],
3712                                           value_bytes);
3713     if (result) {
3714       return result;
3715     }
3716   }
3717   return result;
3718 }
3719 
Serialize_TPML_ECC_CURVE(const TPML_ECC_CURVE & value,std::string * buffer)3720 TPM_RC Serialize_TPML_ECC_CURVE(const TPML_ECC_CURVE& value,
3721                                 std::string* buffer) {
3722   TPM_RC result = TPM_RC_SUCCESS;
3723   VLOG(3) << __func__;
3724 
3725   result = Serialize_UINT32(value.count, buffer);
3726   if (result) {
3727     return result;
3728   }
3729 
3730   if (std::size(value.ecc_curves) < value.count) {
3731     return TPM_RC_INSUFFICIENT;
3732   }
3733   for (uint32_t i = 0; i < value.count; ++i) {
3734     result = Serialize_TPM_ECC_CURVE(value.ecc_curves[i], buffer);
3735     if (result) {
3736       return result;
3737     }
3738   }
3739   return result;
3740 }
3741 
Parse_TPML_ECC_CURVE(std::string * buffer,TPML_ECC_CURVE * value,std::string * value_bytes)3742 TPM_RC Parse_TPML_ECC_CURVE(std::string* buffer,
3743                             TPML_ECC_CURVE* value,
3744                             std::string* value_bytes) {
3745   TPM_RC result = TPM_RC_SUCCESS;
3746   VLOG(3) << __func__;
3747 
3748   result = Parse_UINT32(buffer, &value->count, value_bytes);
3749   if (result) {
3750     return result;
3751   }
3752 
3753   if (std::size(value->ecc_curves) < value->count) {
3754     return TPM_RC_INSUFFICIENT;
3755   }
3756   for (uint32_t i = 0; i < value->count; ++i) {
3757     result = Parse_TPM_ECC_CURVE(buffer, &value->ecc_curves[i], value_bytes);
3758     if (result) {
3759       return result;
3760     }
3761   }
3762   return result;
3763 }
3764 
Serialize_TPMU_CAPABILITIES(const TPMU_CAPABILITIES & value,TPM_CAP selector,std::string * buffer)3765 TPM_RC Serialize_TPMU_CAPABILITIES(const TPMU_CAPABILITIES& value,
3766                                    TPM_CAP selector,
3767                                    std::string* buffer) {
3768   TPM_RC result = TPM_RC_SUCCESS;
3769   VLOG(3) << __func__;
3770 
3771   if (selector == TPM_CAP_PCRS) {
3772     result = Serialize_TPML_PCR_SELECTION(value.assigned_pcr, buffer);
3773     if (result) {
3774       return result;
3775     }
3776   }
3777 
3778   if (selector == TPM_CAP_TPM_PROPERTIES) {
3779     result = Serialize_TPML_TAGGED_TPM_PROPERTY(value.tpm_properties, buffer);
3780     if (result) {
3781       return result;
3782     }
3783   }
3784 
3785   if (selector == TPM_CAP_PP_COMMANDS) {
3786     result = Serialize_TPML_CC(value.pp_commands, buffer);
3787     if (result) {
3788       return result;
3789     }
3790   }
3791 
3792   if (selector == TPM_CAP_AUDIT_COMMANDS) {
3793     result = Serialize_TPML_CC(value.audit_commands, buffer);
3794     if (result) {
3795       return result;
3796     }
3797   }
3798 
3799   if (selector == TPM_CAP_COMMANDS) {
3800     result = Serialize_TPML_CCA(value.command, buffer);
3801     if (result) {
3802       return result;
3803     }
3804   }
3805 
3806   if (selector == TPM_CAP_ECC_CURVES) {
3807     result = Serialize_TPML_ECC_CURVE(value.ecc_curves, buffer);
3808     if (result) {
3809       return result;
3810     }
3811   }
3812 
3813   if (selector == TPM_CAP_PCR_PROPERTIES) {
3814     result = Serialize_TPML_TAGGED_PCR_PROPERTY(value.pcr_properties, buffer);
3815     if (result) {
3816       return result;
3817     }
3818   }
3819 
3820   if (selector == TPM_CAP_HANDLES) {
3821     result = Serialize_TPML_HANDLE(value.handles, buffer);
3822     if (result) {
3823       return result;
3824     }
3825   }
3826 
3827   if (selector == TPM_CAP_ALGS) {
3828     result = Serialize_TPML_ALG_PROPERTY(value.algorithms, buffer);
3829     if (result) {
3830       return result;
3831     }
3832   }
3833   return result;
3834 }
3835 
Parse_TPMU_CAPABILITIES(std::string * buffer,TPM_CAP selector,TPMU_CAPABILITIES * value,std::string * value_bytes)3836 TPM_RC Parse_TPMU_CAPABILITIES(std::string* buffer,
3837                                TPM_CAP selector,
3838                                TPMU_CAPABILITIES* value,
3839                                std::string* value_bytes) {
3840   TPM_RC result = TPM_RC_SUCCESS;
3841   VLOG(3) << __func__;
3842 
3843   if (selector == TPM_CAP_PCRS) {
3844     result =
3845         Parse_TPML_PCR_SELECTION(buffer, &value->assigned_pcr, value_bytes);
3846     if (result) {
3847       return result;
3848     }
3849   }
3850 
3851   if (selector == TPM_CAP_TPM_PROPERTIES) {
3852     result = Parse_TPML_TAGGED_TPM_PROPERTY(buffer, &value->tpm_properties,
3853                                             value_bytes);
3854     if (result) {
3855       return result;
3856     }
3857   }
3858 
3859   if (selector == TPM_CAP_PP_COMMANDS) {
3860     result = Parse_TPML_CC(buffer, &value->pp_commands, value_bytes);
3861     if (result) {
3862       return result;
3863     }
3864   }
3865 
3866   if (selector == TPM_CAP_AUDIT_COMMANDS) {
3867     result = Parse_TPML_CC(buffer, &value->audit_commands, value_bytes);
3868     if (result) {
3869       return result;
3870     }
3871   }
3872 
3873   if (selector == TPM_CAP_COMMANDS) {
3874     result = Parse_TPML_CCA(buffer, &value->command, value_bytes);
3875     if (result) {
3876       return result;
3877     }
3878   }
3879 
3880   if (selector == TPM_CAP_ECC_CURVES) {
3881     result = Parse_TPML_ECC_CURVE(buffer, &value->ecc_curves, value_bytes);
3882     if (result) {
3883       return result;
3884     }
3885   }
3886 
3887   if (selector == TPM_CAP_PCR_PROPERTIES) {
3888     result = Parse_TPML_TAGGED_PCR_PROPERTY(buffer, &value->pcr_properties,
3889                                             value_bytes);
3890     if (result) {
3891       return result;
3892     }
3893   }
3894 
3895   if (selector == TPM_CAP_HANDLES) {
3896     result = Parse_TPML_HANDLE(buffer, &value->handles, value_bytes);
3897     if (result) {
3898       return result;
3899     }
3900   }
3901 
3902   if (selector == TPM_CAP_ALGS) {
3903     result = Parse_TPML_ALG_PROPERTY(buffer, &value->algorithms, value_bytes);
3904     if (result) {
3905       return result;
3906     }
3907   }
3908   return result;
3909 }
3910 
Serialize_TPMS_CAPABILITY_DATA(const TPMS_CAPABILITY_DATA & value,std::string * buffer)3911 TPM_RC Serialize_TPMS_CAPABILITY_DATA(const TPMS_CAPABILITY_DATA& value,
3912                                       std::string* buffer) {
3913   TPM_RC result = TPM_RC_SUCCESS;
3914   VLOG(3) << __func__;
3915 
3916   result = Serialize_TPM_CAP(value.capability, buffer);
3917   if (result) {
3918     return result;
3919   }
3920 
3921   result = Serialize_TPMU_CAPABILITIES(value.data, value.capability, buffer);
3922   if (result) {
3923     return result;
3924   }
3925   return result;
3926 }
3927 
Parse_TPMS_CAPABILITY_DATA(std::string * buffer,TPMS_CAPABILITY_DATA * value,std::string * value_bytes)3928 TPM_RC Parse_TPMS_CAPABILITY_DATA(std::string* buffer,
3929                                   TPMS_CAPABILITY_DATA* value,
3930                                   std::string* value_bytes) {
3931   TPM_RC result = TPM_RC_SUCCESS;
3932   VLOG(3) << __func__;
3933 
3934   result = Parse_TPM_CAP(buffer, &value->capability, value_bytes);
3935   if (result) {
3936     return result;
3937   }
3938 
3939   result = Parse_TPMU_CAPABILITIES(buffer, value->capability, &value->data,
3940                                    value_bytes);
3941   if (result) {
3942     return result;
3943   }
3944   return result;
3945 }
3946 
Serialize_TPMS_CLOCK_INFO(const TPMS_CLOCK_INFO & value,std::string * buffer)3947 TPM_RC Serialize_TPMS_CLOCK_INFO(const TPMS_CLOCK_INFO& value,
3948                                  std::string* buffer) {
3949   TPM_RC result = TPM_RC_SUCCESS;
3950   VLOG(3) << __func__;
3951 
3952   result = Serialize_UINT64(value.clock, buffer);
3953   if (result) {
3954     return result;
3955   }
3956 
3957   result = Serialize_UINT32(value.reset_count, buffer);
3958   if (result) {
3959     return result;
3960   }
3961 
3962   result = Serialize_UINT32(value.restart_count, buffer);
3963   if (result) {
3964     return result;
3965   }
3966 
3967   result = Serialize_TPMI_YES_NO(value.safe, buffer);
3968   if (result) {
3969     return result;
3970   }
3971   return result;
3972 }
3973 
Parse_TPMS_CLOCK_INFO(std::string * buffer,TPMS_CLOCK_INFO * value,std::string * value_bytes)3974 TPM_RC Parse_TPMS_CLOCK_INFO(std::string* buffer,
3975                              TPMS_CLOCK_INFO* value,
3976                              std::string* value_bytes) {
3977   TPM_RC result = TPM_RC_SUCCESS;
3978   VLOG(3) << __func__;
3979 
3980   result = Parse_UINT64(buffer, &value->clock, value_bytes);
3981   if (result) {
3982     return result;
3983   }
3984 
3985   result = Parse_UINT32(buffer, &value->reset_count, value_bytes);
3986   if (result) {
3987     return result;
3988   }
3989 
3990   result = Parse_UINT32(buffer, &value->restart_count, value_bytes);
3991   if (result) {
3992     return result;
3993   }
3994 
3995   result = Parse_TPMI_YES_NO(buffer, &value->safe, value_bytes);
3996   if (result) {
3997     return result;
3998   }
3999   return result;
4000 }
4001 
Serialize_TPMS_TIME_INFO(const TPMS_TIME_INFO & value,std::string * buffer)4002 TPM_RC Serialize_TPMS_TIME_INFO(const TPMS_TIME_INFO& value,
4003                                 std::string* buffer) {
4004   TPM_RC result = TPM_RC_SUCCESS;
4005   VLOG(3) << __func__;
4006 
4007   result = Serialize_UINT64(value.time, buffer);
4008   if (result) {
4009     return result;
4010   }
4011 
4012   result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer);
4013   if (result) {
4014     return result;
4015   }
4016   return result;
4017 }
4018 
Parse_TPMS_TIME_INFO(std::string * buffer,TPMS_TIME_INFO * value,std::string * value_bytes)4019 TPM_RC Parse_TPMS_TIME_INFO(std::string* buffer,
4020                             TPMS_TIME_INFO* value,
4021                             std::string* value_bytes) {
4022   TPM_RC result = TPM_RC_SUCCESS;
4023   VLOG(3) << __func__;
4024 
4025   result = Parse_UINT64(buffer, &value->time, value_bytes);
4026   if (result) {
4027     return result;
4028   }
4029 
4030   result = Parse_TPMS_CLOCK_INFO(buffer, &value->clock_info, value_bytes);
4031   if (result) {
4032     return result;
4033   }
4034   return result;
4035 }
4036 
Serialize_TPMS_TIME_ATTEST_INFO(const TPMS_TIME_ATTEST_INFO & value,std::string * buffer)4037 TPM_RC Serialize_TPMS_TIME_ATTEST_INFO(const TPMS_TIME_ATTEST_INFO& value,
4038                                        std::string* buffer) {
4039   TPM_RC result = TPM_RC_SUCCESS;
4040   VLOG(3) << __func__;
4041 
4042   result = Serialize_TPMS_TIME_INFO(value.time, buffer);
4043   if (result) {
4044     return result;
4045   }
4046 
4047   result = Serialize_UINT64(value.firmware_version, buffer);
4048   if (result) {
4049     return result;
4050   }
4051   return result;
4052 }
4053 
Parse_TPMS_TIME_ATTEST_INFO(std::string * buffer,TPMS_TIME_ATTEST_INFO * value,std::string * value_bytes)4054 TPM_RC Parse_TPMS_TIME_ATTEST_INFO(std::string* buffer,
4055                                    TPMS_TIME_ATTEST_INFO* value,
4056                                    std::string* value_bytes) {
4057   TPM_RC result = TPM_RC_SUCCESS;
4058   VLOG(3) << __func__;
4059 
4060   result = Parse_TPMS_TIME_INFO(buffer, &value->time, value_bytes);
4061   if (result) {
4062     return result;
4063   }
4064 
4065   result = Parse_UINT64(buffer, &value->firmware_version, value_bytes);
4066   if (result) {
4067     return result;
4068   }
4069   return result;
4070 }
4071 
Serialize_TPMS_CERTIFY_INFO(const TPMS_CERTIFY_INFO & value,std::string * buffer)4072 TPM_RC Serialize_TPMS_CERTIFY_INFO(const TPMS_CERTIFY_INFO& value,
4073                                    std::string* buffer) {
4074   TPM_RC result = TPM_RC_SUCCESS;
4075   VLOG(3) << __func__;
4076 
4077   result = Serialize_TPM2B_NAME(value.name, buffer);
4078   if (result) {
4079     return result;
4080   }
4081 
4082   result = Serialize_TPM2B_NAME(value.qualified_name, buffer);
4083   if (result) {
4084     return result;
4085   }
4086   return result;
4087 }
4088 
Parse_TPMS_CERTIFY_INFO(std::string * buffer,TPMS_CERTIFY_INFO * value,std::string * value_bytes)4089 TPM_RC Parse_TPMS_CERTIFY_INFO(std::string* buffer,
4090                                TPMS_CERTIFY_INFO* value,
4091                                std::string* value_bytes) {
4092   TPM_RC result = TPM_RC_SUCCESS;
4093   VLOG(3) << __func__;
4094 
4095   result = Parse_TPM2B_NAME(buffer, &value->name, value_bytes);
4096   if (result) {
4097     return result;
4098   }
4099 
4100   result = Parse_TPM2B_NAME(buffer, &value->qualified_name, value_bytes);
4101   if (result) {
4102     return result;
4103   }
4104   return result;
4105 }
4106 
Serialize_TPMS_QUOTE_INFO(const TPMS_QUOTE_INFO & value,std::string * buffer)4107 TPM_RC Serialize_TPMS_QUOTE_INFO(const TPMS_QUOTE_INFO& value,
4108                                  std::string* buffer) {
4109   TPM_RC result = TPM_RC_SUCCESS;
4110   VLOG(3) << __func__;
4111 
4112   result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer);
4113   if (result) {
4114     return result;
4115   }
4116 
4117   result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer);
4118   if (result) {
4119     return result;
4120   }
4121   return result;
4122 }
4123 
Parse_TPMS_QUOTE_INFO(std::string * buffer,TPMS_QUOTE_INFO * value,std::string * value_bytes)4124 TPM_RC Parse_TPMS_QUOTE_INFO(std::string* buffer,
4125                              TPMS_QUOTE_INFO* value,
4126                              std::string* value_bytes) {
4127   TPM_RC result = TPM_RC_SUCCESS;
4128   VLOG(3) << __func__;
4129 
4130   result = Parse_TPML_PCR_SELECTION(buffer, &value->pcr_select, value_bytes);
4131   if (result) {
4132     return result;
4133   }
4134 
4135   result = Parse_TPM2B_DIGEST(buffer, &value->pcr_digest, value_bytes);
4136   if (result) {
4137     return result;
4138   }
4139   return result;
4140 }
4141 
Serialize_TPMS_COMMAND_AUDIT_INFO(const TPMS_COMMAND_AUDIT_INFO & value,std::string * buffer)4142 TPM_RC Serialize_TPMS_COMMAND_AUDIT_INFO(const TPMS_COMMAND_AUDIT_INFO& value,
4143                                          std::string* buffer) {
4144   TPM_RC result = TPM_RC_SUCCESS;
4145   VLOG(3) << __func__;
4146 
4147   result = Serialize_UINT64(value.audit_counter, buffer);
4148   if (result) {
4149     return result;
4150   }
4151 
4152   result = Serialize_TPM_ALG_ID(value.digest_alg, buffer);
4153   if (result) {
4154     return result;
4155   }
4156 
4157   result = Serialize_TPM2B_DIGEST(value.audit_digest, buffer);
4158   if (result) {
4159     return result;
4160   }
4161 
4162   result = Serialize_TPM2B_DIGEST(value.command_digest, buffer);
4163   if (result) {
4164     return result;
4165   }
4166   return result;
4167 }
4168 
Parse_TPMS_COMMAND_AUDIT_INFO(std::string * buffer,TPMS_COMMAND_AUDIT_INFO * value,std::string * value_bytes)4169 TPM_RC Parse_TPMS_COMMAND_AUDIT_INFO(std::string* buffer,
4170                                      TPMS_COMMAND_AUDIT_INFO* value,
4171                                      std::string* value_bytes) {
4172   TPM_RC result = TPM_RC_SUCCESS;
4173   VLOG(3) << __func__;
4174 
4175   result = Parse_UINT64(buffer, &value->audit_counter, value_bytes);
4176   if (result) {
4177     return result;
4178   }
4179 
4180   result = Parse_TPM_ALG_ID(buffer, &value->digest_alg, value_bytes);
4181   if (result) {
4182     return result;
4183   }
4184 
4185   result = Parse_TPM2B_DIGEST(buffer, &value->audit_digest, value_bytes);
4186   if (result) {
4187     return result;
4188   }
4189 
4190   result = Parse_TPM2B_DIGEST(buffer, &value->command_digest, value_bytes);
4191   if (result) {
4192     return result;
4193   }
4194   return result;
4195 }
4196 
Serialize_TPMS_SESSION_AUDIT_INFO(const TPMS_SESSION_AUDIT_INFO & value,std::string * buffer)4197 TPM_RC Serialize_TPMS_SESSION_AUDIT_INFO(const TPMS_SESSION_AUDIT_INFO& value,
4198                                          std::string* buffer) {
4199   TPM_RC result = TPM_RC_SUCCESS;
4200   VLOG(3) << __func__;
4201 
4202   result = Serialize_TPMI_YES_NO(value.exclusive_session, buffer);
4203   if (result) {
4204     return result;
4205   }
4206 
4207   result = Serialize_TPM2B_DIGEST(value.session_digest, buffer);
4208   if (result) {
4209     return result;
4210   }
4211   return result;
4212 }
4213 
Parse_TPMS_SESSION_AUDIT_INFO(std::string * buffer,TPMS_SESSION_AUDIT_INFO * value,std::string * value_bytes)4214 TPM_RC Parse_TPMS_SESSION_AUDIT_INFO(std::string* buffer,
4215                                      TPMS_SESSION_AUDIT_INFO* value,
4216                                      std::string* value_bytes) {
4217   TPM_RC result = TPM_RC_SUCCESS;
4218   VLOG(3) << __func__;
4219 
4220   result = Parse_TPMI_YES_NO(buffer, &value->exclusive_session, value_bytes);
4221   if (result) {
4222     return result;
4223   }
4224 
4225   result = Parse_TPM2B_DIGEST(buffer, &value->session_digest, value_bytes);
4226   if (result) {
4227     return result;
4228   }
4229   return result;
4230 }
4231 
Serialize_TPMS_CREATION_INFO(const TPMS_CREATION_INFO & value,std::string * buffer)4232 TPM_RC Serialize_TPMS_CREATION_INFO(const TPMS_CREATION_INFO& value,
4233                                     std::string* buffer) {
4234   TPM_RC result = TPM_RC_SUCCESS;
4235   VLOG(3) << __func__;
4236 
4237   result = Serialize_TPM2B_NAME(value.object_name, buffer);
4238   if (result) {
4239     return result;
4240   }
4241 
4242   result = Serialize_TPM2B_DIGEST(value.creation_hash, buffer);
4243   if (result) {
4244     return result;
4245   }
4246   return result;
4247 }
4248 
Parse_TPMS_CREATION_INFO(std::string * buffer,TPMS_CREATION_INFO * value,std::string * value_bytes)4249 TPM_RC Parse_TPMS_CREATION_INFO(std::string* buffer,
4250                                 TPMS_CREATION_INFO* value,
4251                                 std::string* value_bytes) {
4252   TPM_RC result = TPM_RC_SUCCESS;
4253   VLOG(3) << __func__;
4254 
4255   result = Parse_TPM2B_NAME(buffer, &value->object_name, value_bytes);
4256   if (result) {
4257     return result;
4258   }
4259 
4260   result = Parse_TPM2B_DIGEST(buffer, &value->creation_hash, value_bytes);
4261   if (result) {
4262     return result;
4263   }
4264   return result;
4265 }
4266 
Serialize_TPMS_NV_CERTIFY_INFO(const TPMS_NV_CERTIFY_INFO & value,std::string * buffer)4267 TPM_RC Serialize_TPMS_NV_CERTIFY_INFO(const TPMS_NV_CERTIFY_INFO& value,
4268                                       std::string* buffer) {
4269   TPM_RC result = TPM_RC_SUCCESS;
4270   VLOG(3) << __func__;
4271 
4272   result = Serialize_TPM2B_NAME(value.index_name, buffer);
4273   if (result) {
4274     return result;
4275   }
4276 
4277   result = Serialize_UINT16(value.offset, buffer);
4278   if (result) {
4279     return result;
4280   }
4281 
4282   result = Serialize_TPM2B_MAX_NV_BUFFER(value.nv_contents, buffer);
4283   if (result) {
4284     return result;
4285   }
4286   return result;
4287 }
4288 
Parse_TPMS_NV_CERTIFY_INFO(std::string * buffer,TPMS_NV_CERTIFY_INFO * value,std::string * value_bytes)4289 TPM_RC Parse_TPMS_NV_CERTIFY_INFO(std::string* buffer,
4290                                   TPMS_NV_CERTIFY_INFO* value,
4291                                   std::string* value_bytes) {
4292   TPM_RC result = TPM_RC_SUCCESS;
4293   VLOG(3) << __func__;
4294 
4295   result = Parse_TPM2B_NAME(buffer, &value->index_name, value_bytes);
4296   if (result) {
4297     return result;
4298   }
4299 
4300   result = Parse_UINT16(buffer, &value->offset, value_bytes);
4301   if (result) {
4302     return result;
4303   }
4304 
4305   result = Parse_TPM2B_MAX_NV_BUFFER(buffer, &value->nv_contents, value_bytes);
4306   if (result) {
4307     return result;
4308   }
4309   return result;
4310 }
4311 
Serialize_TPMU_ATTEST(const TPMU_ATTEST & value,TPMI_ST_ATTEST selector,std::string * buffer)4312 TPM_RC Serialize_TPMU_ATTEST(const TPMU_ATTEST& value,
4313                              TPMI_ST_ATTEST selector,
4314                              std::string* buffer) {
4315   TPM_RC result = TPM_RC_SUCCESS;
4316   VLOG(3) << __func__;
4317 
4318   if (selector == TPM_ST_ATTEST_SESSION_AUDIT) {
4319     result = Serialize_TPMS_SESSION_AUDIT_INFO(value.session_audit, buffer);
4320     if (result) {
4321       return result;
4322     }
4323   }
4324 
4325   if (selector == TPM_ST_ATTEST_QUOTE) {
4326     result = Serialize_TPMS_QUOTE_INFO(value.quote, buffer);
4327     if (result) {
4328       return result;
4329     }
4330   }
4331 
4332   if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) {
4333     result = Serialize_TPMS_COMMAND_AUDIT_INFO(value.command_audit, buffer);
4334     if (result) {
4335       return result;
4336     }
4337   }
4338 
4339   if (selector == TPM_ST_ATTEST_CERTIFY) {
4340     result = Serialize_TPMS_CERTIFY_INFO(value.certify, buffer);
4341     if (result) {
4342       return result;
4343     }
4344   }
4345 
4346   if (selector == TPM_ST_ATTEST_NV) {
4347     result = Serialize_TPMS_NV_CERTIFY_INFO(value.nv, buffer);
4348     if (result) {
4349       return result;
4350     }
4351   }
4352 
4353   if (selector == TPM_ST_ATTEST_TIME) {
4354     result = Serialize_TPMS_TIME_ATTEST_INFO(value.time, buffer);
4355     if (result) {
4356       return result;
4357     }
4358   }
4359 
4360   if (selector == TPM_ST_ATTEST_CREATION) {
4361     result = Serialize_TPMS_CREATION_INFO(value.creation, buffer);
4362     if (result) {
4363       return result;
4364     }
4365   }
4366   return result;
4367 }
4368 
Parse_TPMU_ATTEST(std::string * buffer,TPMI_ST_ATTEST selector,TPMU_ATTEST * value,std::string * value_bytes)4369 TPM_RC Parse_TPMU_ATTEST(std::string* buffer,
4370                          TPMI_ST_ATTEST selector,
4371                          TPMU_ATTEST* value,
4372                          std::string* value_bytes) {
4373   TPM_RC result = TPM_RC_SUCCESS;
4374   VLOG(3) << __func__;
4375 
4376   if (selector == TPM_ST_ATTEST_SESSION_AUDIT) {
4377     result = Parse_TPMS_SESSION_AUDIT_INFO(buffer, &value->session_audit,
4378                                            value_bytes);
4379     if (result) {
4380       return result;
4381     }
4382   }
4383 
4384   if (selector == TPM_ST_ATTEST_QUOTE) {
4385     result = Parse_TPMS_QUOTE_INFO(buffer, &value->quote, value_bytes);
4386     if (result) {
4387       return result;
4388     }
4389   }
4390 
4391   if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) {
4392     result = Parse_TPMS_COMMAND_AUDIT_INFO(buffer, &value->command_audit,
4393                                            value_bytes);
4394     if (result) {
4395       return result;
4396     }
4397   }
4398 
4399   if (selector == TPM_ST_ATTEST_CERTIFY) {
4400     result = Parse_TPMS_CERTIFY_INFO(buffer, &value->certify, value_bytes);
4401     if (result) {
4402       return result;
4403     }
4404   }
4405 
4406   if (selector == TPM_ST_ATTEST_NV) {
4407     result = Parse_TPMS_NV_CERTIFY_INFO(buffer, &value->nv, value_bytes);
4408     if (result) {
4409       return result;
4410     }
4411   }
4412 
4413   if (selector == TPM_ST_ATTEST_TIME) {
4414     result = Parse_TPMS_TIME_ATTEST_INFO(buffer, &value->time, value_bytes);
4415     if (result) {
4416       return result;
4417     }
4418   }
4419 
4420   if (selector == TPM_ST_ATTEST_CREATION) {
4421     result = Parse_TPMS_CREATION_INFO(buffer, &value->creation, value_bytes);
4422     if (result) {
4423       return result;
4424     }
4425   }
4426   return result;
4427 }
4428 
Serialize_TPMS_ATTEST(const TPMS_ATTEST & value,std::string * buffer)4429 TPM_RC Serialize_TPMS_ATTEST(const TPMS_ATTEST& value, std::string* buffer) {
4430   TPM_RC result = TPM_RC_SUCCESS;
4431   VLOG(3) << __func__;
4432 
4433   result = Serialize_TPM_GENERATED(value.magic, buffer);
4434   if (result) {
4435     return result;
4436   }
4437 
4438   result = Serialize_TPMI_ST_ATTEST(value.type, buffer);
4439   if (result) {
4440     return result;
4441   }
4442 
4443   result = Serialize_TPM2B_NAME(value.qualified_signer, buffer);
4444   if (result) {
4445     return result;
4446   }
4447 
4448   result = Serialize_TPM2B_DATA(value.extra_data, buffer);
4449   if (result) {
4450     return result;
4451   }
4452 
4453   result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer);
4454   if (result) {
4455     return result;
4456   }
4457 
4458   result = Serialize_UINT64(value.firmware_version, buffer);
4459   if (result) {
4460     return result;
4461   }
4462 
4463   result = Serialize_TPMU_ATTEST(value.attested, value.type, buffer);
4464   if (result) {
4465     return result;
4466   }
4467   return result;
4468 }
4469 
Parse_TPMS_ATTEST(std::string * buffer,TPMS_ATTEST * value,std::string * value_bytes)4470 TPM_RC Parse_TPMS_ATTEST(std::string* buffer,
4471                          TPMS_ATTEST* value,
4472                          std::string* value_bytes) {
4473   TPM_RC result = TPM_RC_SUCCESS;
4474   VLOG(3) << __func__;
4475 
4476   result = Parse_TPM_GENERATED(buffer, &value->magic, value_bytes);
4477   if (result) {
4478     return result;
4479   }
4480 
4481   result = Parse_TPMI_ST_ATTEST(buffer, &value->type, value_bytes);
4482   if (result) {
4483     return result;
4484   }
4485 
4486   result = Parse_TPM2B_NAME(buffer, &value->qualified_signer, value_bytes);
4487   if (result) {
4488     return result;
4489   }
4490 
4491   result = Parse_TPM2B_DATA(buffer, &value->extra_data, value_bytes);
4492   if (result) {
4493     return result;
4494   }
4495 
4496   result = Parse_TPMS_CLOCK_INFO(buffer, &value->clock_info, value_bytes);
4497   if (result) {
4498     return result;
4499   }
4500 
4501   result = Parse_UINT64(buffer, &value->firmware_version, value_bytes);
4502   if (result) {
4503     return result;
4504   }
4505 
4506   result =
4507       Parse_TPMU_ATTEST(buffer, value->type, &value->attested, value_bytes);
4508   if (result) {
4509     return result;
4510   }
4511   return result;
4512 }
4513 
Serialize_TPM2B_ATTEST(const TPM2B_ATTEST & value,std::string * buffer)4514 TPM_RC Serialize_TPM2B_ATTEST(const TPM2B_ATTEST& value, std::string* buffer) {
4515   TPM_RC result = TPM_RC_SUCCESS;
4516   VLOG(3) << __func__;
4517 
4518   result = Serialize_UINT16(value.size, buffer);
4519   if (result) {
4520     return result;
4521   }
4522 
4523   if (std::size(value.attestation_data) < value.size) {
4524     return TPM_RC_INSUFFICIENT;
4525   }
4526   for (uint32_t i = 0; i < value.size; ++i) {
4527     result = Serialize_BYTE(value.attestation_data[i], buffer);
4528     if (result) {
4529       return result;
4530     }
4531   }
4532   return result;
4533 }
4534 
Parse_TPM2B_ATTEST(std::string * buffer,TPM2B_ATTEST * value,std::string * value_bytes)4535 TPM_RC Parse_TPM2B_ATTEST(std::string* buffer,
4536                           TPM2B_ATTEST* value,
4537                           std::string* value_bytes) {
4538   TPM_RC result = TPM_RC_SUCCESS;
4539   VLOG(3) << __func__;
4540 
4541   result = Parse_UINT16(buffer, &value->size, value_bytes);
4542   if (result) {
4543     return result;
4544   }
4545 
4546   if (std::size(value->attestation_data) < value->size) {
4547     return TPM_RC_INSUFFICIENT;
4548   }
4549   for (uint32_t i = 0; i < value->size; ++i) {
4550     result = Parse_BYTE(buffer, &value->attestation_data[i], value_bytes);
4551     if (result) {
4552       return result;
4553     }
4554   }
4555   return result;
4556 }
4557 
Make_TPM2B_ATTEST(const std::string & bytes)4558 TPM2B_ATTEST Make_TPM2B_ATTEST(const std::string& bytes) {
4559   TPM2B_ATTEST tpm2b;
4560   CHECK(bytes.size() <= sizeof(tpm2b.attestation_data));
4561   memset(&tpm2b, 0, sizeof(TPM2B_ATTEST));
4562   tpm2b.size = bytes.size();
4563   memcpy(tpm2b.attestation_data, bytes.data(), bytes.size());
4564   return tpm2b;
4565 }
4566 
StringFrom_TPM2B_ATTEST(const TPM2B_ATTEST & tpm2b)4567 std::string StringFrom_TPM2B_ATTEST(const TPM2B_ATTEST& tpm2b) {
4568   CHECK(tpm2b.size <= std::size(tpm2b.attestation_data));
4569   const char* char_buffer =
4570       reinterpret_cast<const char*>(tpm2b.attestation_data);
4571   return std::string(char_buffer, tpm2b.size);
4572 }
4573 
Serialize_TPMS_AUTH_COMMAND(const TPMS_AUTH_COMMAND & value,std::string * buffer)4574 TPM_RC Serialize_TPMS_AUTH_COMMAND(const TPMS_AUTH_COMMAND& value,
4575                                    std::string* buffer) {
4576   TPM_RC result = TPM_RC_SUCCESS;
4577   VLOG(3) << __func__;
4578 
4579   result = Serialize_TPMI_SH_AUTH_SESSION(value.session_handle, buffer);
4580   if (result) {
4581     return result;
4582   }
4583 
4584   result = Serialize_TPM2B_NONCE(value.nonce, buffer);
4585   if (result) {
4586     return result;
4587   }
4588 
4589   result = Serialize_TPMA_SESSION(value.session_attributes, buffer);
4590   if (result) {
4591     return result;
4592   }
4593 
4594   result = Serialize_TPM2B_AUTH(value.hmac, buffer);
4595   if (result) {
4596     return result;
4597   }
4598   return result;
4599 }
4600 
Parse_TPMS_AUTH_COMMAND(std::string * buffer,TPMS_AUTH_COMMAND * value,std::string * value_bytes)4601 TPM_RC Parse_TPMS_AUTH_COMMAND(std::string* buffer,
4602                                TPMS_AUTH_COMMAND* value,
4603                                std::string* value_bytes) {
4604   TPM_RC result = TPM_RC_SUCCESS;
4605   VLOG(3) << __func__;
4606 
4607   result =
4608       Parse_TPMI_SH_AUTH_SESSION(buffer, &value->session_handle, value_bytes);
4609   if (result) {
4610     return result;
4611   }
4612 
4613   result = Parse_TPM2B_NONCE(buffer, &value->nonce, value_bytes);
4614   if (result) {
4615     return result;
4616   }
4617 
4618   result = Parse_TPMA_SESSION(buffer, &value->session_attributes, value_bytes);
4619   if (result) {
4620     return result;
4621   }
4622 
4623   result = Parse_TPM2B_AUTH(buffer, &value->hmac, value_bytes);
4624   if (result) {
4625     return result;
4626   }
4627   return result;
4628 }
4629 
Serialize_TPMS_AUTH_RESPONSE(const TPMS_AUTH_RESPONSE & value,std::string * buffer)4630 TPM_RC Serialize_TPMS_AUTH_RESPONSE(const TPMS_AUTH_RESPONSE& value,
4631                                     std::string* buffer) {
4632   TPM_RC result = TPM_RC_SUCCESS;
4633   VLOG(3) << __func__;
4634 
4635   result = Serialize_TPM2B_NONCE(value.nonce, buffer);
4636   if (result) {
4637     return result;
4638   }
4639 
4640   result = Serialize_TPMA_SESSION(value.session_attributes, buffer);
4641   if (result) {
4642     return result;
4643   }
4644 
4645   result = Serialize_TPM2B_AUTH(value.hmac, buffer);
4646   if (result) {
4647     return result;
4648   }
4649   return result;
4650 }
4651 
Parse_TPMS_AUTH_RESPONSE(std::string * buffer,TPMS_AUTH_RESPONSE * value,std::string * value_bytes)4652 TPM_RC Parse_TPMS_AUTH_RESPONSE(std::string* buffer,
4653                                 TPMS_AUTH_RESPONSE* value,
4654                                 std::string* value_bytes) {
4655   TPM_RC result = TPM_RC_SUCCESS;
4656   VLOG(3) << __func__;
4657 
4658   result = Parse_TPM2B_NONCE(buffer, &value->nonce, value_bytes);
4659   if (result) {
4660     return result;
4661   }
4662 
4663   result = Parse_TPMA_SESSION(buffer, &value->session_attributes, value_bytes);
4664   if (result) {
4665     return result;
4666   }
4667 
4668   result = Parse_TPM2B_AUTH(buffer, &value->hmac, value_bytes);
4669   if (result) {
4670     return result;
4671   }
4672   return result;
4673 }
4674 
Serialize_TPMU_SYM_KEY_BITS(const TPMU_SYM_KEY_BITS & value,TPMI_ALG_SYM selector,std::string * buffer)4675 TPM_RC Serialize_TPMU_SYM_KEY_BITS(const TPMU_SYM_KEY_BITS& value,
4676                                    TPMI_ALG_SYM selector,
4677                                    std::string* buffer) {
4678   TPM_RC result = TPM_RC_SUCCESS;
4679   VLOG(3) << __func__;
4680 
4681   if (selector == TPM_ALG_NULL) {
4682     // Do nothing.
4683   }
4684 
4685   if (selector == TPM_ALG_SM4) {
4686     result = Serialize_TPMI_SM4_KEY_BITS(value.sm4, buffer);
4687     if (result) {
4688       return result;
4689     }
4690   }
4691 
4692   if (selector == TPM_ALG_AES) {
4693     result = Serialize_TPMI_AES_KEY_BITS(value.aes, buffer);
4694     if (result) {
4695       return result;
4696     }
4697   }
4698 
4699   if (selector == TPM_ALG_XOR) {
4700     result = Serialize_TPMI_ALG_HASH(value.xor_, buffer);
4701     if (result) {
4702       return result;
4703     }
4704   }
4705   return result;
4706 }
4707 
Parse_TPMU_SYM_KEY_BITS(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_KEY_BITS * value,std::string * value_bytes)4708 TPM_RC Parse_TPMU_SYM_KEY_BITS(std::string* buffer,
4709                                TPMI_ALG_SYM selector,
4710                                TPMU_SYM_KEY_BITS* value,
4711                                std::string* value_bytes) {
4712   TPM_RC result = TPM_RC_SUCCESS;
4713   VLOG(3) << __func__;
4714 
4715   if (selector == TPM_ALG_NULL) {
4716     // Do nothing.
4717   }
4718 
4719   if (selector == TPM_ALG_SM4) {
4720     result = Parse_TPMI_SM4_KEY_BITS(buffer, &value->sm4, value_bytes);
4721     if (result) {
4722       return result;
4723     }
4724   }
4725 
4726   if (selector == TPM_ALG_AES) {
4727     result = Parse_TPMI_AES_KEY_BITS(buffer, &value->aes, value_bytes);
4728     if (result) {
4729       return result;
4730     }
4731   }
4732 
4733   if (selector == TPM_ALG_XOR) {
4734     result = Parse_TPMI_ALG_HASH(buffer, &value->xor_, value_bytes);
4735     if (result) {
4736       return result;
4737     }
4738   }
4739   return result;
4740 }
4741 
Serialize_TPMU_SYM_MODE(const TPMU_SYM_MODE & value,TPMI_ALG_SYM selector,std::string * buffer)4742 TPM_RC Serialize_TPMU_SYM_MODE(const TPMU_SYM_MODE& value,
4743                                TPMI_ALG_SYM selector,
4744                                std::string* buffer) {
4745   TPM_RC result = TPM_RC_SUCCESS;
4746   VLOG(3) << __func__;
4747 
4748   if (selector == TPM_ALG_NULL) {
4749     // Do nothing.
4750   }
4751 
4752   if (selector == TPM_ALG_SM4) {
4753     result = Serialize_TPMI_ALG_SYM_MODE(value.sm4, buffer);
4754     if (result) {
4755       return result;
4756     }
4757   }
4758 
4759   if (selector == TPM_ALG_AES) {
4760     result = Serialize_TPMI_ALG_SYM_MODE(value.aes, buffer);
4761     if (result) {
4762       return result;
4763     }
4764   }
4765 
4766   if (selector == TPM_ALG_XOR) {
4767     // Do nothing.
4768   }
4769   return result;
4770 }
4771 
Parse_TPMU_SYM_MODE(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_MODE * value,std::string * value_bytes)4772 TPM_RC Parse_TPMU_SYM_MODE(std::string* buffer,
4773                            TPMI_ALG_SYM selector,
4774                            TPMU_SYM_MODE* value,
4775                            std::string* value_bytes) {
4776   TPM_RC result = TPM_RC_SUCCESS;
4777   VLOG(3) << __func__;
4778 
4779   if (selector == TPM_ALG_NULL) {
4780     // Do nothing.
4781   }
4782 
4783   if (selector == TPM_ALG_SM4) {
4784     result = Parse_TPMI_ALG_SYM_MODE(buffer, &value->sm4, value_bytes);
4785     if (result) {
4786       return result;
4787     }
4788   }
4789 
4790   if (selector == TPM_ALG_AES) {
4791     result = Parse_TPMI_ALG_SYM_MODE(buffer, &value->aes, value_bytes);
4792     if (result) {
4793       return result;
4794     }
4795   }
4796 
4797   if (selector == TPM_ALG_XOR) {
4798     // Do nothing.
4799   }
4800   return result;
4801 }
4802 
Serialize_TPMU_SYM_DETAILS(const TPMU_SYM_DETAILS & value,TPMI_ALG_SYM selector,std::string * buffer)4803 TPM_RC Serialize_TPMU_SYM_DETAILS(const TPMU_SYM_DETAILS& value,
4804                                   TPMI_ALG_SYM selector,
4805                                   std::string* buffer) {
4806   TPM_RC result = TPM_RC_SUCCESS;
4807   VLOG(3) << __func__;
4808   return result;
4809 }
4810 
Parse_TPMU_SYM_DETAILS(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_DETAILS * value,std::string * value_bytes)4811 TPM_RC Parse_TPMU_SYM_DETAILS(std::string* buffer,
4812                               TPMI_ALG_SYM selector,
4813                               TPMU_SYM_DETAILS* value,
4814                               std::string* value_bytes) {
4815   TPM_RC result = TPM_RC_SUCCESS;
4816   VLOG(3) << __func__;
4817   return result;
4818 }
4819 
Serialize_TPMT_SYM_DEF(const TPMT_SYM_DEF & value,std::string * buffer)4820 TPM_RC Serialize_TPMT_SYM_DEF(const TPMT_SYM_DEF& value, std::string* buffer) {
4821   TPM_RC result = TPM_RC_SUCCESS;
4822   VLOG(3) << __func__;
4823 
4824   result = Serialize_TPMI_ALG_SYM(value.algorithm, buffer);
4825   if (result) {
4826     return result;
4827   }
4828 
4829   result = Serialize_TPMU_SYM_KEY_BITS(value.key_bits, value.algorithm, buffer);
4830   if (result) {
4831     return result;
4832   }
4833 
4834   result = Serialize_TPMU_SYM_MODE(value.mode, value.algorithm, buffer);
4835   if (result) {
4836     return result;
4837   }
4838 
4839   result = Serialize_TPMU_SYM_DETAILS(value.details, value.algorithm, buffer);
4840   if (result) {
4841     return result;
4842   }
4843   return result;
4844 }
4845 
Parse_TPMT_SYM_DEF(std::string * buffer,TPMT_SYM_DEF * value,std::string * value_bytes)4846 TPM_RC Parse_TPMT_SYM_DEF(std::string* buffer,
4847                           TPMT_SYM_DEF* value,
4848                           std::string* value_bytes) {
4849   TPM_RC result = TPM_RC_SUCCESS;
4850   VLOG(3) << __func__;
4851 
4852   result = Parse_TPMI_ALG_SYM(buffer, &value->algorithm, value_bytes);
4853   if (result) {
4854     return result;
4855   }
4856 
4857   result = Parse_TPMU_SYM_KEY_BITS(buffer, value->algorithm, &value->key_bits,
4858                                    value_bytes);
4859   if (result) {
4860     return result;
4861   }
4862 
4863   result =
4864       Parse_TPMU_SYM_MODE(buffer, value->algorithm, &value->mode, value_bytes);
4865   if (result) {
4866     return result;
4867   }
4868 
4869   result = Parse_TPMU_SYM_DETAILS(buffer, value->algorithm, &value->details,
4870                                   value_bytes);
4871   if (result) {
4872     return result;
4873   }
4874   return result;
4875 }
4876 
Serialize_TPMT_SYM_DEF_OBJECT(const TPMT_SYM_DEF_OBJECT & value,std::string * buffer)4877 TPM_RC Serialize_TPMT_SYM_DEF_OBJECT(const TPMT_SYM_DEF_OBJECT& value,
4878                                      std::string* buffer) {
4879   TPM_RC result = TPM_RC_SUCCESS;
4880   VLOG(3) << __func__;
4881 
4882   result = Serialize_TPMI_ALG_SYM_OBJECT(value.algorithm, buffer);
4883   if (result) {
4884     return result;
4885   }
4886 
4887   result = Serialize_TPMU_SYM_KEY_BITS(value.key_bits, value.algorithm, buffer);
4888   if (result) {
4889     return result;
4890   }
4891 
4892   result = Serialize_TPMU_SYM_MODE(value.mode, value.algorithm, buffer);
4893   if (result) {
4894     return result;
4895   }
4896 
4897   result = Serialize_TPMU_SYM_DETAILS(value.details, value.algorithm, buffer);
4898   if (result) {
4899     return result;
4900   }
4901   return result;
4902 }
4903 
Parse_TPMT_SYM_DEF_OBJECT(std::string * buffer,TPMT_SYM_DEF_OBJECT * value,std::string * value_bytes)4904 TPM_RC Parse_TPMT_SYM_DEF_OBJECT(std::string* buffer,
4905                                  TPMT_SYM_DEF_OBJECT* value,
4906                                  std::string* value_bytes) {
4907   TPM_RC result = TPM_RC_SUCCESS;
4908   VLOG(3) << __func__;
4909 
4910   result = Parse_TPMI_ALG_SYM_OBJECT(buffer, &value->algorithm, value_bytes);
4911   if (result) {
4912     return result;
4913   }
4914 
4915   result = Parse_TPMU_SYM_KEY_BITS(buffer, value->algorithm, &value->key_bits,
4916                                    value_bytes);
4917   if (result) {
4918     return result;
4919   }
4920 
4921   result =
4922       Parse_TPMU_SYM_MODE(buffer, value->algorithm, &value->mode, value_bytes);
4923   if (result) {
4924     return result;
4925   }
4926 
4927   result = Parse_TPMU_SYM_DETAILS(buffer, value->algorithm, &value->details,
4928                                   value_bytes);
4929   if (result) {
4930     return result;
4931   }
4932   return result;
4933 }
4934 
Serialize_TPM2B_SYM_KEY(const TPM2B_SYM_KEY & value,std::string * buffer)4935 TPM_RC Serialize_TPM2B_SYM_KEY(const TPM2B_SYM_KEY& value,
4936                                std::string* buffer) {
4937   TPM_RC result = TPM_RC_SUCCESS;
4938   VLOG(3) << __func__;
4939 
4940   result = Serialize_UINT16(value.size, buffer);
4941   if (result) {
4942     return result;
4943   }
4944 
4945   if (std::size(value.buffer) < value.size) {
4946     return TPM_RC_INSUFFICIENT;
4947   }
4948   for (uint32_t i = 0; i < value.size; ++i) {
4949     result = Serialize_BYTE(value.buffer[i], buffer);
4950     if (result) {
4951       return result;
4952     }
4953   }
4954   return result;
4955 }
4956 
Parse_TPM2B_SYM_KEY(std::string * buffer,TPM2B_SYM_KEY * value,std::string * value_bytes)4957 TPM_RC Parse_TPM2B_SYM_KEY(std::string* buffer,
4958                            TPM2B_SYM_KEY* value,
4959                            std::string* value_bytes) {
4960   TPM_RC result = TPM_RC_SUCCESS;
4961   VLOG(3) << __func__;
4962 
4963   result = Parse_UINT16(buffer, &value->size, value_bytes);
4964   if (result) {
4965     return result;
4966   }
4967 
4968   if (std::size(value->buffer) < value->size) {
4969     return TPM_RC_INSUFFICIENT;
4970   }
4971   for (uint32_t i = 0; i < value->size; ++i) {
4972     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
4973     if (result) {
4974       return result;
4975     }
4976   }
4977   return result;
4978 }
4979 
Make_TPM2B_SYM_KEY(const std::string & bytes)4980 TPM2B_SYM_KEY Make_TPM2B_SYM_KEY(const std::string& bytes) {
4981   TPM2B_SYM_KEY tpm2b;
4982   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
4983   memset(&tpm2b, 0, sizeof(TPM2B_SYM_KEY));
4984   tpm2b.size = bytes.size();
4985   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
4986   return tpm2b;
4987 }
4988 
StringFrom_TPM2B_SYM_KEY(const TPM2B_SYM_KEY & tpm2b)4989 std::string StringFrom_TPM2B_SYM_KEY(const TPM2B_SYM_KEY& tpm2b) {
4990   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
4991   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
4992   return std::string(char_buffer, tpm2b.size);
4993 }
4994 
Serialize_TPMS_SYMCIPHER_PARMS(const TPMS_SYMCIPHER_PARMS & value,std::string * buffer)4995 TPM_RC Serialize_TPMS_SYMCIPHER_PARMS(const TPMS_SYMCIPHER_PARMS& value,
4996                                       std::string* buffer) {
4997   TPM_RC result = TPM_RC_SUCCESS;
4998   VLOG(3) << __func__;
4999 
5000   result = Serialize_TPMT_SYM_DEF_OBJECT(value.sym, buffer);
5001   if (result) {
5002     return result;
5003   }
5004   return result;
5005 }
5006 
Parse_TPMS_SYMCIPHER_PARMS(std::string * buffer,TPMS_SYMCIPHER_PARMS * value,std::string * value_bytes)5007 TPM_RC Parse_TPMS_SYMCIPHER_PARMS(std::string* buffer,
5008                                   TPMS_SYMCIPHER_PARMS* value,
5009                                   std::string* value_bytes) {
5010   TPM_RC result = TPM_RC_SUCCESS;
5011   VLOG(3) << __func__;
5012 
5013   result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->sym, value_bytes);
5014   if (result) {
5015     return result;
5016   }
5017   return result;
5018 }
5019 
Serialize_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA & value,std::string * buffer)5020 TPM_RC Serialize_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA& value,
5021                                       std::string* buffer) {
5022   TPM_RC result = TPM_RC_SUCCESS;
5023   VLOG(3) << __func__;
5024 
5025   result = Serialize_UINT16(value.size, buffer);
5026   if (result) {
5027     return result;
5028   }
5029 
5030   if (std::size(value.buffer) < value.size) {
5031     return TPM_RC_INSUFFICIENT;
5032   }
5033   for (uint32_t i = 0; i < value.size; ++i) {
5034     result = Serialize_BYTE(value.buffer[i], buffer);
5035     if (result) {
5036       return result;
5037     }
5038   }
5039   return result;
5040 }
5041 
Parse_TPM2B_SENSITIVE_DATA(std::string * buffer,TPM2B_SENSITIVE_DATA * value,std::string * value_bytes)5042 TPM_RC Parse_TPM2B_SENSITIVE_DATA(std::string* buffer,
5043                                   TPM2B_SENSITIVE_DATA* value,
5044                                   std::string* value_bytes) {
5045   TPM_RC result = TPM_RC_SUCCESS;
5046   VLOG(3) << __func__;
5047 
5048   result = Parse_UINT16(buffer, &value->size, value_bytes);
5049   if (result) {
5050     return result;
5051   }
5052 
5053   if (std::size(value->buffer) < value->size) {
5054     return TPM_RC_INSUFFICIENT;
5055   }
5056   for (uint32_t i = 0; i < value->size; ++i) {
5057     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
5058     if (result) {
5059       return result;
5060     }
5061   }
5062   return result;
5063 }
5064 
Make_TPM2B_SENSITIVE_DATA(const std::string & bytes)5065 TPM2B_SENSITIVE_DATA Make_TPM2B_SENSITIVE_DATA(const std::string& bytes) {
5066   TPM2B_SENSITIVE_DATA tpm2b;
5067   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
5068   memset(&tpm2b, 0, sizeof(TPM2B_SENSITIVE_DATA));
5069   tpm2b.size = bytes.size();
5070   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
5071   return tpm2b;
5072 }
5073 
StringFrom_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA & tpm2b)5074 std::string StringFrom_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA& tpm2b) {
5075   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
5076   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
5077   return std::string(char_buffer, tpm2b.size);
5078 }
5079 
Serialize_TPMS_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE & value,std::string * buffer)5080 TPM_RC Serialize_TPMS_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE& value,
5081                                        std::string* buffer) {
5082   TPM_RC result = TPM_RC_SUCCESS;
5083   VLOG(3) << __func__;
5084 
5085   result = Serialize_TPM2B_AUTH(value.user_auth, buffer);
5086   if (result) {
5087     return result;
5088   }
5089 
5090   result = Serialize_TPM2B_SENSITIVE_DATA(value.data, buffer);
5091   if (result) {
5092     return result;
5093   }
5094   return result;
5095 }
5096 
Parse_TPMS_SENSITIVE_CREATE(std::string * buffer,TPMS_SENSITIVE_CREATE * value,std::string * value_bytes)5097 TPM_RC Parse_TPMS_SENSITIVE_CREATE(std::string* buffer,
5098                                    TPMS_SENSITIVE_CREATE* value,
5099                                    std::string* value_bytes) {
5100   TPM_RC result = TPM_RC_SUCCESS;
5101   VLOG(3) << __func__;
5102 
5103   result = Parse_TPM2B_AUTH(buffer, &value->user_auth, value_bytes);
5104   if (result) {
5105     return result;
5106   }
5107 
5108   result = Parse_TPM2B_SENSITIVE_DATA(buffer, &value->data, value_bytes);
5109   if (result) {
5110     return result;
5111   }
5112   return result;
5113 }
5114 
Serialize_TPM2B_SENSITIVE_CREATE(const TPM2B_SENSITIVE_CREATE & value,std::string * buffer)5115 TPM_RC Serialize_TPM2B_SENSITIVE_CREATE(const TPM2B_SENSITIVE_CREATE& value,
5116                                         std::string* buffer) {
5117   TPM_RC result = TPM_RC_SUCCESS;
5118   VLOG(3) << __func__;
5119 
5120   std::string field_bytes;
5121   if (value.size) {
5122     if (value.size != sizeof(TPMS_SENSITIVE_CREATE)) {
5123       return TPM_RC_SIZE;
5124     }
5125     result = Serialize_TPMS_SENSITIVE_CREATE(value.sensitive, &field_bytes);
5126     if (result) {
5127       return result;
5128     }
5129   }
5130   std::string size_bytes;
5131   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
5132   if (result) {
5133     return result;
5134   }
5135   buffer->append(size_bytes + field_bytes);
5136   return result;
5137 }
5138 
Parse_TPM2B_SENSITIVE_CREATE(std::string * buffer,TPM2B_SENSITIVE_CREATE * value,std::string * value_bytes)5139 TPM_RC Parse_TPM2B_SENSITIVE_CREATE(std::string* buffer,
5140                                     TPM2B_SENSITIVE_CREATE* value,
5141                                     std::string* value_bytes) {
5142   TPM_RC result = TPM_RC_SUCCESS;
5143   VLOG(3) << __func__;
5144 
5145   UINT16 parsed_size = 0;
5146   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
5147   if (result) {
5148     return result;
5149   }
5150   if (!parsed_size) {
5151     value->size = 0;
5152   } else {
5153     value->size = sizeof(TPMS_SENSITIVE_CREATE);
5154     result =
5155         Parse_TPMS_SENSITIVE_CREATE(buffer, &value->sensitive, value_bytes);
5156     if (result) {
5157       return result;
5158     }
5159   }
5160   return result;
5161 }
5162 
Make_TPM2B_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE & inner)5163 TPM2B_SENSITIVE_CREATE Make_TPM2B_SENSITIVE_CREATE(
5164     const TPMS_SENSITIVE_CREATE& inner) {
5165   TPM2B_SENSITIVE_CREATE tpm2b;
5166   tpm2b.size = sizeof(TPMS_SENSITIVE_CREATE);
5167   tpm2b.sensitive = inner;
5168   return tpm2b;
5169 }
5170 
Serialize_TPMS_SCHEME_XOR(const TPMS_SCHEME_XOR & value,std::string * buffer)5171 TPM_RC Serialize_TPMS_SCHEME_XOR(const TPMS_SCHEME_XOR& value,
5172                                  std::string* buffer) {
5173   TPM_RC result = TPM_RC_SUCCESS;
5174   VLOG(3) << __func__;
5175 
5176   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5177   if (result) {
5178     return result;
5179   }
5180 
5181   result = Serialize_TPMI_ALG_KDF(value.kdf, buffer);
5182   if (result) {
5183     return result;
5184   }
5185   return result;
5186 }
5187 
Parse_TPMS_SCHEME_XOR(std::string * buffer,TPMS_SCHEME_XOR * value,std::string * value_bytes)5188 TPM_RC Parse_TPMS_SCHEME_XOR(std::string* buffer,
5189                              TPMS_SCHEME_XOR* value,
5190                              std::string* value_bytes) {
5191   TPM_RC result = TPM_RC_SUCCESS;
5192   VLOG(3) << __func__;
5193 
5194   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5195   if (result) {
5196     return result;
5197   }
5198 
5199   result = Parse_TPMI_ALG_KDF(buffer, &value->kdf, value_bytes);
5200   if (result) {
5201     return result;
5202   }
5203   return result;
5204 }
5205 
Serialize_TPMU_SCHEME_KEYEDHASH(const TPMU_SCHEME_KEYEDHASH & value,TPMI_ALG_KEYEDHASH_SCHEME selector,std::string * buffer)5206 TPM_RC Serialize_TPMU_SCHEME_KEYEDHASH(const TPMU_SCHEME_KEYEDHASH& value,
5207                                        TPMI_ALG_KEYEDHASH_SCHEME selector,
5208                                        std::string* buffer) {
5209   TPM_RC result = TPM_RC_SUCCESS;
5210   VLOG(3) << __func__;
5211 
5212   if (selector == TPM_ALG_NULL) {
5213     // Do nothing.
5214   }
5215 
5216   if (selector == TPM_ALG_HMAC) {
5217     result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer);
5218     if (result) {
5219       return result;
5220     }
5221   }
5222 
5223   if (selector == TPM_ALG_XOR) {
5224     result = Serialize_TPMS_SCHEME_XOR(value.xor_, buffer);
5225     if (result) {
5226       return result;
5227     }
5228   }
5229   return result;
5230 }
5231 
Parse_TPMU_SCHEME_KEYEDHASH(std::string * buffer,TPMI_ALG_KEYEDHASH_SCHEME selector,TPMU_SCHEME_KEYEDHASH * value,std::string * value_bytes)5232 TPM_RC Parse_TPMU_SCHEME_KEYEDHASH(std::string* buffer,
5233                                    TPMI_ALG_KEYEDHASH_SCHEME selector,
5234                                    TPMU_SCHEME_KEYEDHASH* value,
5235                                    std::string* value_bytes) {
5236   TPM_RC result = TPM_RC_SUCCESS;
5237   VLOG(3) << __func__;
5238 
5239   if (selector == TPM_ALG_NULL) {
5240     // Do nothing.
5241   }
5242 
5243   if (selector == TPM_ALG_HMAC) {
5244     result = Parse_TPMS_SCHEME_HMAC(buffer, &value->hmac, value_bytes);
5245     if (result) {
5246       return result;
5247     }
5248   }
5249 
5250   if (selector == TPM_ALG_XOR) {
5251     result = Parse_TPMS_SCHEME_XOR(buffer, &value->xor_, value_bytes);
5252     if (result) {
5253       return result;
5254     }
5255   }
5256   return result;
5257 }
5258 
Serialize_TPMT_KEYEDHASH_SCHEME(const TPMT_KEYEDHASH_SCHEME & value,std::string * buffer)5259 TPM_RC Serialize_TPMT_KEYEDHASH_SCHEME(const TPMT_KEYEDHASH_SCHEME& value,
5260                                        std::string* buffer) {
5261   TPM_RC result = TPM_RC_SUCCESS;
5262   VLOG(3) << __func__;
5263 
5264   result = Serialize_TPMI_ALG_KEYEDHASH_SCHEME(value.scheme, buffer);
5265   if (result) {
5266     return result;
5267   }
5268 
5269   result = Serialize_TPMU_SCHEME_KEYEDHASH(value.details, value.scheme, buffer);
5270   if (result) {
5271     return result;
5272   }
5273   return result;
5274 }
5275 
Parse_TPMT_KEYEDHASH_SCHEME(std::string * buffer,TPMT_KEYEDHASH_SCHEME * value,std::string * value_bytes)5276 TPM_RC Parse_TPMT_KEYEDHASH_SCHEME(std::string* buffer,
5277                                    TPMT_KEYEDHASH_SCHEME* value,
5278                                    std::string* value_bytes) {
5279   TPM_RC result = TPM_RC_SUCCESS;
5280   VLOG(3) << __func__;
5281 
5282   result = Parse_TPMI_ALG_KEYEDHASH_SCHEME(buffer, &value->scheme, value_bytes);
5283   if (result) {
5284     return result;
5285   }
5286 
5287   result = Parse_TPMU_SCHEME_KEYEDHASH(buffer, value->scheme, &value->details,
5288                                        value_bytes);
5289   if (result) {
5290     return result;
5291   }
5292   return result;
5293 }
5294 
Serialize_TPMS_SCHEME_ECDAA(const TPMS_SCHEME_ECDAA & value,std::string * buffer)5295 TPM_RC Serialize_TPMS_SCHEME_ECDAA(const TPMS_SCHEME_ECDAA& value,
5296                                    std::string* buffer) {
5297   TPM_RC result = TPM_RC_SUCCESS;
5298   VLOG(3) << __func__;
5299 
5300   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5301   if (result) {
5302     return result;
5303   }
5304 
5305   result = Serialize_UINT16(value.count, buffer);
5306   if (result) {
5307     return result;
5308   }
5309   return result;
5310 }
5311 
Parse_TPMS_SCHEME_ECDAA(std::string * buffer,TPMS_SCHEME_ECDAA * value,std::string * value_bytes)5312 TPM_RC Parse_TPMS_SCHEME_ECDAA(std::string* buffer,
5313                                TPMS_SCHEME_ECDAA* value,
5314                                std::string* value_bytes) {
5315   TPM_RC result = TPM_RC_SUCCESS;
5316   VLOG(3) << __func__;
5317 
5318   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5319   if (result) {
5320     return result;
5321   }
5322 
5323   result = Parse_UINT16(buffer, &value->count, value_bytes);
5324   if (result) {
5325     return result;
5326   }
5327   return result;
5328 }
5329 
Serialize_TPMU_SIG_SCHEME(const TPMU_SIG_SCHEME & value,TPMI_ALG_SIG_SCHEME selector,std::string * buffer)5330 TPM_RC Serialize_TPMU_SIG_SCHEME(const TPMU_SIG_SCHEME& value,
5331                                  TPMI_ALG_SIG_SCHEME selector,
5332                                  std::string* buffer) {
5333   TPM_RC result = TPM_RC_SUCCESS;
5334   VLOG(3) << __func__;
5335 
5336   if (selector == TPM_ALG_HMAC) {
5337     result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer);
5338     if (result) {
5339       return result;
5340     }
5341   }
5342 
5343   if (selector == TPM_ALG_ECSCHNORR) {
5344     result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer);
5345     if (result) {
5346       return result;
5347     }
5348   }
5349 
5350   if (selector == TPM_ALG_RSAPSS) {
5351     result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer);
5352     if (result) {
5353       return result;
5354     }
5355   }
5356 
5357   if (selector == TPM_ALG_ECDAA) {
5358     result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer);
5359     if (result) {
5360       return result;
5361     }
5362   }
5363 
5364   if (selector == TPM_ALG_RSASSA) {
5365     result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer);
5366     if (result) {
5367       return result;
5368     }
5369   }
5370 
5371   if (selector == TPM_ALG_SM2) {
5372     result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer);
5373     if (result) {
5374       return result;
5375     }
5376   }
5377 
5378   if (selector == TPM_ALG_ECDSA) {
5379     result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer);
5380     if (result) {
5381       return result;
5382     }
5383   }
5384 
5385   if (selector == TPM_ALG_NULL) {
5386     // Do nothing.
5387   }
5388   return result;
5389 }
5390 
Parse_TPMU_SIG_SCHEME(std::string * buffer,TPMI_ALG_SIG_SCHEME selector,TPMU_SIG_SCHEME * value,std::string * value_bytes)5391 TPM_RC Parse_TPMU_SIG_SCHEME(std::string* buffer,
5392                              TPMI_ALG_SIG_SCHEME selector,
5393                              TPMU_SIG_SCHEME* value,
5394                              std::string* value_bytes) {
5395   TPM_RC result = TPM_RC_SUCCESS;
5396   VLOG(3) << __func__;
5397 
5398   if (selector == TPM_ALG_HMAC) {
5399     result = Parse_TPMS_SCHEME_HMAC(buffer, &value->hmac, value_bytes);
5400     if (result) {
5401       return result;
5402     }
5403   }
5404 
5405   if (selector == TPM_ALG_ECSCHNORR) {
5406     result =
5407         Parse_TPMS_SCHEME_ECSCHNORR(buffer, &value->ec_schnorr, value_bytes);
5408     if (result) {
5409       return result;
5410     }
5411   }
5412 
5413   if (selector == TPM_ALG_RSAPSS) {
5414     result = Parse_TPMS_SCHEME_RSAPSS(buffer, &value->rsapss, value_bytes);
5415     if (result) {
5416       return result;
5417     }
5418   }
5419 
5420   if (selector == TPM_ALG_ECDAA) {
5421     result = Parse_TPMS_SCHEME_ECDAA(buffer, &value->ecdaa, value_bytes);
5422     if (result) {
5423       return result;
5424     }
5425   }
5426 
5427   if (selector == TPM_ALG_RSASSA) {
5428     result = Parse_TPMS_SCHEME_RSASSA(buffer, &value->rsassa, value_bytes);
5429     if (result) {
5430       return result;
5431     }
5432   }
5433 
5434   if (selector == TPM_ALG_SM2) {
5435     result = Parse_TPMS_SCHEME_SM2(buffer, &value->sm2, value_bytes);
5436     if (result) {
5437       return result;
5438     }
5439   }
5440 
5441   if (selector == TPM_ALG_ECDSA) {
5442     result = Parse_TPMS_SCHEME_ECDSA(buffer, &value->ecdsa, value_bytes);
5443     if (result) {
5444       return result;
5445     }
5446   }
5447 
5448   if (selector == TPM_ALG_NULL) {
5449     // Do nothing.
5450   }
5451   return result;
5452 }
5453 
Serialize_TPMT_SIG_SCHEME(const TPMT_SIG_SCHEME & value,std::string * buffer)5454 TPM_RC Serialize_TPMT_SIG_SCHEME(const TPMT_SIG_SCHEME& value,
5455                                  std::string* buffer) {
5456   TPM_RC result = TPM_RC_SUCCESS;
5457   VLOG(3) << __func__;
5458 
5459   result = Serialize_TPMI_ALG_SIG_SCHEME(value.scheme, buffer);
5460   if (result) {
5461     return result;
5462   }
5463 
5464   result = Serialize_TPMU_SIG_SCHEME(value.details, value.scheme, buffer);
5465   if (result) {
5466     return result;
5467   }
5468   return result;
5469 }
5470 
Parse_TPMT_SIG_SCHEME(std::string * buffer,TPMT_SIG_SCHEME * value,std::string * value_bytes)5471 TPM_RC Parse_TPMT_SIG_SCHEME(std::string* buffer,
5472                              TPMT_SIG_SCHEME* value,
5473                              std::string* value_bytes) {
5474   TPM_RC result = TPM_RC_SUCCESS;
5475   VLOG(3) << __func__;
5476 
5477   result = Parse_TPMI_ALG_SIG_SCHEME(buffer, &value->scheme, value_bytes);
5478   if (result) {
5479     return result;
5480   }
5481 
5482   result = Parse_TPMU_SIG_SCHEME(buffer, value->scheme, &value->details,
5483                                  value_bytes);
5484   if (result) {
5485     return result;
5486   }
5487   return result;
5488 }
5489 
Serialize_TPMS_SCHEME_OAEP(const TPMS_SCHEME_OAEP & value,std::string * buffer)5490 TPM_RC Serialize_TPMS_SCHEME_OAEP(const TPMS_SCHEME_OAEP& value,
5491                                   std::string* buffer) {
5492   TPM_RC result = TPM_RC_SUCCESS;
5493   VLOG(3) << __func__;
5494 
5495   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5496   if (result) {
5497     return result;
5498   }
5499   return result;
5500 }
5501 
Parse_TPMS_SCHEME_OAEP(std::string * buffer,TPMS_SCHEME_OAEP * value,std::string * value_bytes)5502 TPM_RC Parse_TPMS_SCHEME_OAEP(std::string* buffer,
5503                               TPMS_SCHEME_OAEP* value,
5504                               std::string* value_bytes) {
5505   TPM_RC result = TPM_RC_SUCCESS;
5506   VLOG(3) << __func__;
5507 
5508   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5509   if (result) {
5510     return result;
5511   }
5512   return result;
5513 }
5514 
Serialize_TPMS_SCHEME_ECDH(const TPMS_SCHEME_ECDH & value,std::string * buffer)5515 TPM_RC Serialize_TPMS_SCHEME_ECDH(const TPMS_SCHEME_ECDH& value,
5516                                   std::string* buffer) {
5517   TPM_RC result = TPM_RC_SUCCESS;
5518   VLOG(3) << __func__;
5519 
5520   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5521   if (result) {
5522     return result;
5523   }
5524   return result;
5525 }
5526 
Parse_TPMS_SCHEME_ECDH(std::string * buffer,TPMS_SCHEME_ECDH * value,std::string * value_bytes)5527 TPM_RC Parse_TPMS_SCHEME_ECDH(std::string* buffer,
5528                               TPMS_SCHEME_ECDH* value,
5529                               std::string* value_bytes) {
5530   TPM_RC result = TPM_RC_SUCCESS;
5531   VLOG(3) << __func__;
5532 
5533   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5534   if (result) {
5535     return result;
5536   }
5537   return result;
5538 }
5539 
Serialize_TPMS_SCHEME_MGF1(const TPMS_SCHEME_MGF1 & value,std::string * buffer)5540 TPM_RC Serialize_TPMS_SCHEME_MGF1(const TPMS_SCHEME_MGF1& value,
5541                                   std::string* buffer) {
5542   TPM_RC result = TPM_RC_SUCCESS;
5543   VLOG(3) << __func__;
5544 
5545   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5546   if (result) {
5547     return result;
5548   }
5549   return result;
5550 }
5551 
Parse_TPMS_SCHEME_MGF1(std::string * buffer,TPMS_SCHEME_MGF1 * value,std::string * value_bytes)5552 TPM_RC Parse_TPMS_SCHEME_MGF1(std::string* buffer,
5553                               TPMS_SCHEME_MGF1* value,
5554                               std::string* value_bytes) {
5555   TPM_RC result = TPM_RC_SUCCESS;
5556   VLOG(3) << __func__;
5557 
5558   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5559   if (result) {
5560     return result;
5561   }
5562   return result;
5563 }
5564 
Serialize_TPMS_SCHEME_KDF1_SP800_56a(const TPMS_SCHEME_KDF1_SP800_56a & value,std::string * buffer)5565 TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_56a(
5566     const TPMS_SCHEME_KDF1_SP800_56a& value, std::string* buffer) {
5567   TPM_RC result = TPM_RC_SUCCESS;
5568   VLOG(3) << __func__;
5569 
5570   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5571   if (result) {
5572     return result;
5573   }
5574   return result;
5575 }
5576 
Parse_TPMS_SCHEME_KDF1_SP800_56a(std::string * buffer,TPMS_SCHEME_KDF1_SP800_56a * value,std::string * value_bytes)5577 TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_56a(std::string* buffer,
5578                                         TPMS_SCHEME_KDF1_SP800_56a* value,
5579                                         std::string* value_bytes) {
5580   TPM_RC result = TPM_RC_SUCCESS;
5581   VLOG(3) << __func__;
5582 
5583   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5584   if (result) {
5585     return result;
5586   }
5587   return result;
5588 }
5589 
Serialize_TPMS_SCHEME_KDF2(const TPMS_SCHEME_KDF2 & value,std::string * buffer)5590 TPM_RC Serialize_TPMS_SCHEME_KDF2(const TPMS_SCHEME_KDF2& value,
5591                                   std::string* buffer) {
5592   TPM_RC result = TPM_RC_SUCCESS;
5593   VLOG(3) << __func__;
5594 
5595   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5596   if (result) {
5597     return result;
5598   }
5599   return result;
5600 }
5601 
Parse_TPMS_SCHEME_KDF2(std::string * buffer,TPMS_SCHEME_KDF2 * value,std::string * value_bytes)5602 TPM_RC Parse_TPMS_SCHEME_KDF2(std::string* buffer,
5603                               TPMS_SCHEME_KDF2* value,
5604                               std::string* value_bytes) {
5605   TPM_RC result = TPM_RC_SUCCESS;
5606   VLOG(3) << __func__;
5607 
5608   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5609   if (result) {
5610     return result;
5611   }
5612   return result;
5613 }
5614 
Serialize_TPMS_SCHEME_KDF1_SP800_108(const TPMS_SCHEME_KDF1_SP800_108 & value,std::string * buffer)5615 TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_108(
5616     const TPMS_SCHEME_KDF1_SP800_108& value, std::string* buffer) {
5617   TPM_RC result = TPM_RC_SUCCESS;
5618   VLOG(3) << __func__;
5619 
5620   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5621   if (result) {
5622     return result;
5623   }
5624   return result;
5625 }
5626 
Parse_TPMS_SCHEME_KDF1_SP800_108(std::string * buffer,TPMS_SCHEME_KDF1_SP800_108 * value,std::string * value_bytes)5627 TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_108(std::string* buffer,
5628                                         TPMS_SCHEME_KDF1_SP800_108* value,
5629                                         std::string* value_bytes) {
5630   TPM_RC result = TPM_RC_SUCCESS;
5631   VLOG(3) << __func__;
5632 
5633   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5634   if (result) {
5635     return result;
5636   }
5637   return result;
5638 }
5639 
Serialize_TPMU_KDF_SCHEME(const TPMU_KDF_SCHEME & value,TPMI_ALG_KDF selector,std::string * buffer)5640 TPM_RC Serialize_TPMU_KDF_SCHEME(const TPMU_KDF_SCHEME& value,
5641                                  TPMI_ALG_KDF selector,
5642                                  std::string* buffer) {
5643   TPM_RC result = TPM_RC_SUCCESS;
5644   VLOG(3) << __func__;
5645 
5646   if (selector == TPM_ALG_KDF1_SP800_56a) {
5647     result = Serialize_TPMS_SCHEME_KDF1_SP800_56a(value.kdf1_sp800_56a, buffer);
5648     if (result) {
5649       return result;
5650     }
5651   }
5652 
5653   if (selector == TPM_ALG_MGF1) {
5654     result = Serialize_TPMS_SCHEME_MGF1(value.mgf1, buffer);
5655     if (result) {
5656       return result;
5657     }
5658   }
5659 
5660   if (selector == TPM_ALG_KDF1_SP800_108) {
5661     result = Serialize_TPMS_SCHEME_KDF1_SP800_108(value.kdf1_sp800_108, buffer);
5662     if (result) {
5663       return result;
5664     }
5665   }
5666 
5667   if (selector == TPM_ALG_KDF2) {
5668     result = Serialize_TPMS_SCHEME_KDF2(value.kdf2, buffer);
5669     if (result) {
5670       return result;
5671     }
5672   }
5673 
5674   if (selector == TPM_ALG_NULL) {
5675     // Do nothing.
5676   }
5677   return result;
5678 }
5679 
Parse_TPMU_KDF_SCHEME(std::string * buffer,TPMI_ALG_KDF selector,TPMU_KDF_SCHEME * value,std::string * value_bytes)5680 TPM_RC Parse_TPMU_KDF_SCHEME(std::string* buffer,
5681                              TPMI_ALG_KDF selector,
5682                              TPMU_KDF_SCHEME* value,
5683                              std::string* value_bytes) {
5684   TPM_RC result = TPM_RC_SUCCESS;
5685   VLOG(3) << __func__;
5686 
5687   if (selector == TPM_ALG_KDF1_SP800_56a) {
5688     result = Parse_TPMS_SCHEME_KDF1_SP800_56a(buffer, &value->kdf1_sp800_56a,
5689                                               value_bytes);
5690     if (result) {
5691       return result;
5692     }
5693   }
5694 
5695   if (selector == TPM_ALG_MGF1) {
5696     result = Parse_TPMS_SCHEME_MGF1(buffer, &value->mgf1, value_bytes);
5697     if (result) {
5698       return result;
5699     }
5700   }
5701 
5702   if (selector == TPM_ALG_KDF1_SP800_108) {
5703     result = Parse_TPMS_SCHEME_KDF1_SP800_108(buffer, &value->kdf1_sp800_108,
5704                                               value_bytes);
5705     if (result) {
5706       return result;
5707     }
5708   }
5709 
5710   if (selector == TPM_ALG_KDF2) {
5711     result = Parse_TPMS_SCHEME_KDF2(buffer, &value->kdf2, value_bytes);
5712     if (result) {
5713       return result;
5714     }
5715   }
5716 
5717   if (selector == TPM_ALG_NULL) {
5718     // Do nothing.
5719   }
5720   return result;
5721 }
5722 
Serialize_TPMT_KDF_SCHEME(const TPMT_KDF_SCHEME & value,std::string * buffer)5723 TPM_RC Serialize_TPMT_KDF_SCHEME(const TPMT_KDF_SCHEME& value,
5724                                  std::string* buffer) {
5725   TPM_RC result = TPM_RC_SUCCESS;
5726   VLOG(3) << __func__;
5727 
5728   result = Serialize_TPMI_ALG_KDF(value.scheme, buffer);
5729   if (result) {
5730     return result;
5731   }
5732 
5733   result = Serialize_TPMU_KDF_SCHEME(value.details, value.scheme, buffer);
5734   if (result) {
5735     return result;
5736   }
5737   return result;
5738 }
5739 
Parse_TPMT_KDF_SCHEME(std::string * buffer,TPMT_KDF_SCHEME * value,std::string * value_bytes)5740 TPM_RC Parse_TPMT_KDF_SCHEME(std::string* buffer,
5741                              TPMT_KDF_SCHEME* value,
5742                              std::string* value_bytes) {
5743   TPM_RC result = TPM_RC_SUCCESS;
5744   VLOG(3) << __func__;
5745 
5746   result = Parse_TPMI_ALG_KDF(buffer, &value->scheme, value_bytes);
5747   if (result) {
5748     return result;
5749   }
5750 
5751   result = Parse_TPMU_KDF_SCHEME(buffer, value->scheme, &value->details,
5752                                  value_bytes);
5753   if (result) {
5754     return result;
5755   }
5756   return result;
5757 }
5758 
Serialize_TPMU_ASYM_SCHEME(const TPMU_ASYM_SCHEME & value,TPMI_ALG_ASYM_SCHEME selector,std::string * buffer)5759 TPM_RC Serialize_TPMU_ASYM_SCHEME(const TPMU_ASYM_SCHEME& value,
5760                                   TPMI_ALG_ASYM_SCHEME selector,
5761                                   std::string* buffer) {
5762   TPM_RC result = TPM_RC_SUCCESS;
5763   VLOG(3) << __func__;
5764 
5765   if (selector == TPM_ALG_RSAES) {
5766     // Do nothing.
5767   }
5768 
5769   if (selector == TPM_ALG_ECSCHNORR) {
5770     result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer);
5771     if (result) {
5772       return result;
5773     }
5774   }
5775 
5776   if (selector == TPM_ALG_NULL) {
5777     // Do nothing.
5778   }
5779 
5780   if (selector == TPM_ALG_ECDH) {
5781     result = Serialize_TPMS_SCHEME_ECDH(value.ecdh, buffer);
5782     if (result) {
5783       return result;
5784     }
5785   }
5786 
5787   if (selector == TPM_ALG_OAEP) {
5788     result = Serialize_TPMS_SCHEME_OAEP(value.oaep, buffer);
5789     if (result) {
5790       return result;
5791     }
5792   }
5793 
5794   if (selector == TPM_ALG_RSAPSS) {
5795     result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer);
5796     if (result) {
5797       return result;
5798     }
5799   }
5800 
5801   if (selector == TPM_ALG_ECDAA) {
5802     result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer);
5803     if (result) {
5804       return result;
5805     }
5806   }
5807 
5808   if (selector == TPM_ALG_RSASSA) {
5809     result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer);
5810     if (result) {
5811       return result;
5812     }
5813   }
5814 
5815   if (selector == TPM_ALG_SM2) {
5816     result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer);
5817     if (result) {
5818       return result;
5819     }
5820   }
5821 
5822   if (selector == TPM_ALG_ECDSA) {
5823     result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer);
5824     if (result) {
5825       return result;
5826     }
5827   }
5828   return result;
5829 }
5830 
Parse_TPMU_ASYM_SCHEME(std::string * buffer,TPMI_ALG_ASYM_SCHEME selector,TPMU_ASYM_SCHEME * value,std::string * value_bytes)5831 TPM_RC Parse_TPMU_ASYM_SCHEME(std::string* buffer,
5832                               TPMI_ALG_ASYM_SCHEME selector,
5833                               TPMU_ASYM_SCHEME* value,
5834                               std::string* value_bytes) {
5835   TPM_RC result = TPM_RC_SUCCESS;
5836   VLOG(3) << __func__;
5837 
5838   if (selector == TPM_ALG_RSAES) {
5839     // Do nothing.
5840   }
5841 
5842   if (selector == TPM_ALG_ECSCHNORR) {
5843     result =
5844         Parse_TPMS_SCHEME_ECSCHNORR(buffer, &value->ec_schnorr, value_bytes);
5845     if (result) {
5846       return result;
5847     }
5848   }
5849 
5850   if (selector == TPM_ALG_NULL) {
5851     // Do nothing.
5852   }
5853 
5854   if (selector == TPM_ALG_ECDH) {
5855     result = Parse_TPMS_SCHEME_ECDH(buffer, &value->ecdh, value_bytes);
5856     if (result) {
5857       return result;
5858     }
5859   }
5860 
5861   if (selector == TPM_ALG_OAEP) {
5862     result = Parse_TPMS_SCHEME_OAEP(buffer, &value->oaep, value_bytes);
5863     if (result) {
5864       return result;
5865     }
5866   }
5867 
5868   if (selector == TPM_ALG_RSAPSS) {
5869     result = Parse_TPMS_SCHEME_RSAPSS(buffer, &value->rsapss, value_bytes);
5870     if (result) {
5871       return result;
5872     }
5873   }
5874 
5875   if (selector == TPM_ALG_ECDAA) {
5876     result = Parse_TPMS_SCHEME_ECDAA(buffer, &value->ecdaa, value_bytes);
5877     if (result) {
5878       return result;
5879     }
5880   }
5881 
5882   if (selector == TPM_ALG_RSASSA) {
5883     result = Parse_TPMS_SCHEME_RSASSA(buffer, &value->rsassa, value_bytes);
5884     if (result) {
5885       return result;
5886     }
5887   }
5888 
5889   if (selector == TPM_ALG_SM2) {
5890     result = Parse_TPMS_SCHEME_SM2(buffer, &value->sm2, value_bytes);
5891     if (result) {
5892       return result;
5893     }
5894   }
5895 
5896   if (selector == TPM_ALG_ECDSA) {
5897     result = Parse_TPMS_SCHEME_ECDSA(buffer, &value->ecdsa, value_bytes);
5898     if (result) {
5899       return result;
5900     }
5901   }
5902   return result;
5903 }
5904 
Serialize_TPMT_ASYM_SCHEME(const TPMT_ASYM_SCHEME & value,std::string * buffer)5905 TPM_RC Serialize_TPMT_ASYM_SCHEME(const TPMT_ASYM_SCHEME& value,
5906                                   std::string* buffer) {
5907   TPM_RC result = TPM_RC_SUCCESS;
5908   VLOG(3) << __func__;
5909 
5910   result = Serialize_TPMI_ALG_ASYM_SCHEME(value.scheme, buffer);
5911   if (result) {
5912     return result;
5913   }
5914 
5915   result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5916   if (result) {
5917     return result;
5918   }
5919   return result;
5920 }
5921 
Parse_TPMT_ASYM_SCHEME(std::string * buffer,TPMT_ASYM_SCHEME * value,std::string * value_bytes)5922 TPM_RC Parse_TPMT_ASYM_SCHEME(std::string* buffer,
5923                               TPMT_ASYM_SCHEME* value,
5924                               std::string* value_bytes) {
5925   TPM_RC result = TPM_RC_SUCCESS;
5926   VLOG(3) << __func__;
5927 
5928   result = Parse_TPMI_ALG_ASYM_SCHEME(buffer, &value->scheme, value_bytes);
5929   if (result) {
5930     return result;
5931   }
5932 
5933   result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5934                                   value_bytes);
5935   if (result) {
5936     return result;
5937   }
5938   return result;
5939 }
5940 
Serialize_TPMT_RSA_SCHEME(const TPMT_RSA_SCHEME & value,std::string * buffer)5941 TPM_RC Serialize_TPMT_RSA_SCHEME(const TPMT_RSA_SCHEME& value,
5942                                  std::string* buffer) {
5943   TPM_RC result = TPM_RC_SUCCESS;
5944   VLOG(3) << __func__;
5945 
5946   result = Serialize_TPMI_ALG_RSA_SCHEME(value.scheme, buffer);
5947   if (result) {
5948     return result;
5949   }
5950 
5951   result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5952   if (result) {
5953     return result;
5954   }
5955   return result;
5956 }
5957 
Parse_TPMT_RSA_SCHEME(std::string * buffer,TPMT_RSA_SCHEME * value,std::string * value_bytes)5958 TPM_RC Parse_TPMT_RSA_SCHEME(std::string* buffer,
5959                              TPMT_RSA_SCHEME* value,
5960                              std::string* value_bytes) {
5961   TPM_RC result = TPM_RC_SUCCESS;
5962   VLOG(3) << __func__;
5963 
5964   result = Parse_TPMI_ALG_RSA_SCHEME(buffer, &value->scheme, value_bytes);
5965   if (result) {
5966     return result;
5967   }
5968 
5969   result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5970                                   value_bytes);
5971   if (result) {
5972     return result;
5973   }
5974   return result;
5975 }
5976 
Serialize_TPMT_RSA_DECRYPT(const TPMT_RSA_DECRYPT & value,std::string * buffer)5977 TPM_RC Serialize_TPMT_RSA_DECRYPT(const TPMT_RSA_DECRYPT& value,
5978                                   std::string* buffer) {
5979   TPM_RC result = TPM_RC_SUCCESS;
5980   VLOG(3) << __func__;
5981 
5982   result = Serialize_TPMI_ALG_RSA_DECRYPT(value.scheme, buffer);
5983   if (result) {
5984     return result;
5985   }
5986 
5987   result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5988   if (result) {
5989     return result;
5990   }
5991   return result;
5992 }
5993 
Parse_TPMT_RSA_DECRYPT(std::string * buffer,TPMT_RSA_DECRYPT * value,std::string * value_bytes)5994 TPM_RC Parse_TPMT_RSA_DECRYPT(std::string* buffer,
5995                               TPMT_RSA_DECRYPT* value,
5996                               std::string* value_bytes) {
5997   TPM_RC result = TPM_RC_SUCCESS;
5998   VLOG(3) << __func__;
5999 
6000   result = Parse_TPMI_ALG_RSA_DECRYPT(buffer, &value->scheme, value_bytes);
6001   if (result) {
6002     return result;
6003   }
6004 
6005   result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
6006                                   value_bytes);
6007   if (result) {
6008     return result;
6009   }
6010   return result;
6011 }
6012 
Serialize_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA & value,std::string * buffer)6013 TPM_RC Serialize_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA& value,
6014                                       std::string* buffer) {
6015   TPM_RC result = TPM_RC_SUCCESS;
6016   VLOG(3) << __func__;
6017 
6018   result = Serialize_UINT16(value.size, buffer);
6019   if (result) {
6020     return result;
6021   }
6022 
6023   if (std::size(value.buffer) < value.size) {
6024     return TPM_RC_INSUFFICIENT;
6025   }
6026   for (uint32_t i = 0; i < value.size; ++i) {
6027     result = Serialize_BYTE(value.buffer[i], buffer);
6028     if (result) {
6029       return result;
6030     }
6031   }
6032   return result;
6033 }
6034 
Parse_TPM2B_PUBLIC_KEY_RSA(std::string * buffer,TPM2B_PUBLIC_KEY_RSA * value,std::string * value_bytes)6035 TPM_RC Parse_TPM2B_PUBLIC_KEY_RSA(std::string* buffer,
6036                                   TPM2B_PUBLIC_KEY_RSA* value,
6037                                   std::string* value_bytes) {
6038   TPM_RC result = TPM_RC_SUCCESS;
6039   VLOG(3) << __func__;
6040 
6041   result = Parse_UINT16(buffer, &value->size, value_bytes);
6042   if (result) {
6043     return result;
6044   }
6045 
6046   if (std::size(value->buffer) < value->size) {
6047     return TPM_RC_INSUFFICIENT;
6048   }
6049   for (uint32_t i = 0; i < value->size; ++i) {
6050     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6051     if (result) {
6052       return result;
6053     }
6054   }
6055   return result;
6056 }
6057 
Make_TPM2B_PUBLIC_KEY_RSA(const std::string & bytes)6058 TPM2B_PUBLIC_KEY_RSA Make_TPM2B_PUBLIC_KEY_RSA(const std::string& bytes) {
6059   TPM2B_PUBLIC_KEY_RSA tpm2b;
6060   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6061   memset(&tpm2b, 0, sizeof(TPM2B_PUBLIC_KEY_RSA));
6062   tpm2b.size = bytes.size();
6063   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6064   return tpm2b;
6065 }
6066 
StringFrom_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA & tpm2b)6067 std::string StringFrom_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA& tpm2b) {
6068   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6069   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6070   return std::string(char_buffer, tpm2b.size);
6071 }
6072 
Serialize_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA & value,std::string * buffer)6073 TPM_RC Serialize_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA& value,
6074                                        std::string* buffer) {
6075   TPM_RC result = TPM_RC_SUCCESS;
6076   VLOG(3) << __func__;
6077 
6078   result = Serialize_UINT16(value.size, buffer);
6079   if (result) {
6080     return result;
6081   }
6082 
6083   if (std::size(value.buffer) < value.size) {
6084     return TPM_RC_INSUFFICIENT;
6085   }
6086   for (uint32_t i = 0; i < value.size; ++i) {
6087     result = Serialize_BYTE(value.buffer[i], buffer);
6088     if (result) {
6089       return result;
6090     }
6091   }
6092   return result;
6093 }
6094 
Parse_TPM2B_PRIVATE_KEY_RSA(std::string * buffer,TPM2B_PRIVATE_KEY_RSA * value,std::string * value_bytes)6095 TPM_RC Parse_TPM2B_PRIVATE_KEY_RSA(std::string* buffer,
6096                                    TPM2B_PRIVATE_KEY_RSA* value,
6097                                    std::string* value_bytes) {
6098   TPM_RC result = TPM_RC_SUCCESS;
6099   VLOG(3) << __func__;
6100 
6101   result = Parse_UINT16(buffer, &value->size, value_bytes);
6102   if (result) {
6103     return result;
6104   }
6105 
6106   if (std::size(value->buffer) < value->size) {
6107     return TPM_RC_INSUFFICIENT;
6108   }
6109   for (uint32_t i = 0; i < value->size; ++i) {
6110     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6111     if (result) {
6112       return result;
6113     }
6114   }
6115   return result;
6116 }
6117 
Make_TPM2B_PRIVATE_KEY_RSA(const std::string & bytes)6118 TPM2B_PRIVATE_KEY_RSA Make_TPM2B_PRIVATE_KEY_RSA(const std::string& bytes) {
6119   TPM2B_PRIVATE_KEY_RSA tpm2b;
6120   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6121   memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_KEY_RSA));
6122   tpm2b.size = bytes.size();
6123   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6124   return tpm2b;
6125 }
6126 
StringFrom_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA & tpm2b)6127 std::string StringFrom_TPM2B_PRIVATE_KEY_RSA(
6128     const TPM2B_PRIVATE_KEY_RSA& tpm2b) {
6129   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6130   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6131   return std::string(char_buffer, tpm2b.size);
6132 }
6133 
Serialize_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER & value,std::string * buffer)6134 TPM_RC Serialize_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER& value,
6135                                      std::string* buffer) {
6136   TPM_RC result = TPM_RC_SUCCESS;
6137   VLOG(3) << __func__;
6138 
6139   result = Serialize_UINT16(value.size, buffer);
6140   if (result) {
6141     return result;
6142   }
6143 
6144   if (std::size(value.buffer) < value.size) {
6145     return TPM_RC_INSUFFICIENT;
6146   }
6147   for (uint32_t i = 0; i < value.size; ++i) {
6148     result = Serialize_BYTE(value.buffer[i], buffer);
6149     if (result) {
6150       return result;
6151     }
6152   }
6153   return result;
6154 }
6155 
Parse_TPM2B_ECC_PARAMETER(std::string * buffer,TPM2B_ECC_PARAMETER * value,std::string * value_bytes)6156 TPM_RC Parse_TPM2B_ECC_PARAMETER(std::string* buffer,
6157                                  TPM2B_ECC_PARAMETER* value,
6158                                  std::string* value_bytes) {
6159   TPM_RC result = TPM_RC_SUCCESS;
6160   VLOG(3) << __func__;
6161 
6162   result = Parse_UINT16(buffer, &value->size, value_bytes);
6163   if (result) {
6164     return result;
6165   }
6166 
6167   if (std::size(value->buffer) < value->size) {
6168     return TPM_RC_INSUFFICIENT;
6169   }
6170   for (uint32_t i = 0; i < value->size; ++i) {
6171     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6172     if (result) {
6173       return result;
6174     }
6175   }
6176   return result;
6177 }
6178 
Make_TPM2B_ECC_PARAMETER(const std::string & bytes)6179 TPM2B_ECC_PARAMETER Make_TPM2B_ECC_PARAMETER(const std::string& bytes) {
6180   TPM2B_ECC_PARAMETER tpm2b;
6181   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6182   memset(&tpm2b, 0, sizeof(TPM2B_ECC_PARAMETER));
6183   tpm2b.size = bytes.size();
6184   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6185   return tpm2b;
6186 }
6187 
StringFrom_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER & tpm2b)6188 std::string StringFrom_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER& tpm2b) {
6189   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6190   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6191   return std::string(char_buffer, tpm2b.size);
6192 }
6193 
Serialize_TPMS_ECC_POINT(const TPMS_ECC_POINT & value,std::string * buffer)6194 TPM_RC Serialize_TPMS_ECC_POINT(const TPMS_ECC_POINT& value,
6195                                 std::string* buffer) {
6196   TPM_RC result = TPM_RC_SUCCESS;
6197   VLOG(3) << __func__;
6198 
6199   result = Serialize_TPM2B_ECC_PARAMETER(value.x, buffer);
6200   if (result) {
6201     return result;
6202   }
6203 
6204   result = Serialize_TPM2B_ECC_PARAMETER(value.y, buffer);
6205   if (result) {
6206     return result;
6207   }
6208   return result;
6209 }
6210 
Parse_TPMS_ECC_POINT(std::string * buffer,TPMS_ECC_POINT * value,std::string * value_bytes)6211 TPM_RC Parse_TPMS_ECC_POINT(std::string* buffer,
6212                             TPMS_ECC_POINT* value,
6213                             std::string* value_bytes) {
6214   TPM_RC result = TPM_RC_SUCCESS;
6215   VLOG(3) << __func__;
6216 
6217   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->x, value_bytes);
6218   if (result) {
6219     return result;
6220   }
6221 
6222   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->y, value_bytes);
6223   if (result) {
6224     return result;
6225   }
6226   return result;
6227 }
6228 
Serialize_TPM2B_ECC_POINT(const TPM2B_ECC_POINT & value,std::string * buffer)6229 TPM_RC Serialize_TPM2B_ECC_POINT(const TPM2B_ECC_POINT& value,
6230                                  std::string* buffer) {
6231   TPM_RC result = TPM_RC_SUCCESS;
6232   VLOG(3) << __func__;
6233 
6234   std::string field_bytes;
6235   if (value.size) {
6236     if (value.size != sizeof(TPMS_ECC_POINT)) {
6237       return TPM_RC_SIZE;
6238     }
6239     result = Serialize_TPMS_ECC_POINT(value.point, &field_bytes);
6240     if (result) {
6241       return result;
6242     }
6243   }
6244   std::string size_bytes;
6245   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
6246   if (result) {
6247     return result;
6248   }
6249   buffer->append(size_bytes + field_bytes);
6250   return result;
6251 }
6252 
Parse_TPM2B_ECC_POINT(std::string * buffer,TPM2B_ECC_POINT * value,std::string * value_bytes)6253 TPM_RC Parse_TPM2B_ECC_POINT(std::string* buffer,
6254                              TPM2B_ECC_POINT* value,
6255                              std::string* value_bytes) {
6256   TPM_RC result = TPM_RC_SUCCESS;
6257   VLOG(3) << __func__;
6258 
6259   UINT16 parsed_size = 0;
6260   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
6261   if (result) {
6262     return result;
6263   }
6264   if (!parsed_size) {
6265     value->size = 0;
6266   } else {
6267     value->size = sizeof(TPMS_ECC_POINT);
6268     result = Parse_TPMS_ECC_POINT(buffer, &value->point, value_bytes);
6269     if (result) {
6270       return result;
6271     }
6272   }
6273   return result;
6274 }
6275 
Make_TPM2B_ECC_POINT(const TPMS_ECC_POINT & inner)6276 TPM2B_ECC_POINT Make_TPM2B_ECC_POINT(const TPMS_ECC_POINT& inner) {
6277   TPM2B_ECC_POINT tpm2b;
6278   tpm2b.size = sizeof(TPMS_ECC_POINT);
6279   tpm2b.point = inner;
6280   return tpm2b;
6281 }
6282 
Serialize_TPMT_ECC_SCHEME(const TPMT_ECC_SCHEME & value,std::string * buffer)6283 TPM_RC Serialize_TPMT_ECC_SCHEME(const TPMT_ECC_SCHEME& value,
6284                                  std::string* buffer) {
6285   TPM_RC result = TPM_RC_SUCCESS;
6286   VLOG(3) << __func__;
6287 
6288   result = Serialize_TPMI_ALG_ECC_SCHEME(value.scheme, buffer);
6289   if (result) {
6290     return result;
6291   }
6292 
6293   result = Serialize_TPMU_SIG_SCHEME(value.details, value.scheme, buffer);
6294   if (result) {
6295     return result;
6296   }
6297   return result;
6298 }
6299 
Parse_TPMT_ECC_SCHEME(std::string * buffer,TPMT_ECC_SCHEME * value,std::string * value_bytes)6300 TPM_RC Parse_TPMT_ECC_SCHEME(std::string* buffer,
6301                              TPMT_ECC_SCHEME* value,
6302                              std::string* value_bytes) {
6303   TPM_RC result = TPM_RC_SUCCESS;
6304   VLOG(3) << __func__;
6305 
6306   result = Parse_TPMI_ALG_ECC_SCHEME(buffer, &value->scheme, value_bytes);
6307   if (result) {
6308     return result;
6309   }
6310 
6311   result = Parse_TPMU_SIG_SCHEME(buffer, value->scheme, &value->details,
6312                                  value_bytes);
6313   if (result) {
6314     return result;
6315   }
6316   return result;
6317 }
6318 
Serialize_TPMS_ALGORITHM_DETAIL_ECC(const TPMS_ALGORITHM_DETAIL_ECC & value,std::string * buffer)6319 TPM_RC Serialize_TPMS_ALGORITHM_DETAIL_ECC(
6320     const TPMS_ALGORITHM_DETAIL_ECC& value, std::string* buffer) {
6321   TPM_RC result = TPM_RC_SUCCESS;
6322   VLOG(3) << __func__;
6323 
6324   result = Serialize_TPM_ECC_CURVE(value.curve_id, buffer);
6325   if (result) {
6326     return result;
6327   }
6328 
6329   result = Serialize_UINT16(value.key_size, buffer);
6330   if (result) {
6331     return result;
6332   }
6333 
6334   result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer);
6335   if (result) {
6336     return result;
6337   }
6338 
6339   result = Serialize_TPMT_ECC_SCHEME(value.sign, buffer);
6340   if (result) {
6341     return result;
6342   }
6343 
6344   result = Serialize_TPM2B_ECC_PARAMETER(value.p, buffer);
6345   if (result) {
6346     return result;
6347   }
6348 
6349   result = Serialize_TPM2B_ECC_PARAMETER(value.a, buffer);
6350   if (result) {
6351     return result;
6352   }
6353 
6354   result = Serialize_TPM2B_ECC_PARAMETER(value.b, buffer);
6355   if (result) {
6356     return result;
6357   }
6358 
6359   result = Serialize_TPM2B_ECC_PARAMETER(value.g_x, buffer);
6360   if (result) {
6361     return result;
6362   }
6363 
6364   result = Serialize_TPM2B_ECC_PARAMETER(value.g_y, buffer);
6365   if (result) {
6366     return result;
6367   }
6368 
6369   result = Serialize_TPM2B_ECC_PARAMETER(value.n, buffer);
6370   if (result) {
6371     return result;
6372   }
6373 
6374   result = Serialize_TPM2B_ECC_PARAMETER(value.h, buffer);
6375   if (result) {
6376     return result;
6377   }
6378   return result;
6379 }
6380 
Parse_TPMS_ALGORITHM_DETAIL_ECC(std::string * buffer,TPMS_ALGORITHM_DETAIL_ECC * value,std::string * value_bytes)6381 TPM_RC Parse_TPMS_ALGORITHM_DETAIL_ECC(std::string* buffer,
6382                                        TPMS_ALGORITHM_DETAIL_ECC* value,
6383                                        std::string* value_bytes) {
6384   TPM_RC result = TPM_RC_SUCCESS;
6385   VLOG(3) << __func__;
6386 
6387   result = Parse_TPM_ECC_CURVE(buffer, &value->curve_id, value_bytes);
6388   if (result) {
6389     return result;
6390   }
6391 
6392   result = Parse_UINT16(buffer, &value->key_size, value_bytes);
6393   if (result) {
6394     return result;
6395   }
6396 
6397   result = Parse_TPMT_KDF_SCHEME(buffer, &value->kdf, value_bytes);
6398   if (result) {
6399     return result;
6400   }
6401 
6402   result = Parse_TPMT_ECC_SCHEME(buffer, &value->sign, value_bytes);
6403   if (result) {
6404     return result;
6405   }
6406 
6407   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->p, value_bytes);
6408   if (result) {
6409     return result;
6410   }
6411 
6412   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->a, value_bytes);
6413   if (result) {
6414     return result;
6415   }
6416 
6417   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->b, value_bytes);
6418   if (result) {
6419     return result;
6420   }
6421 
6422   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->g_x, value_bytes);
6423   if (result) {
6424     return result;
6425   }
6426 
6427   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->g_y, value_bytes);
6428   if (result) {
6429     return result;
6430   }
6431 
6432   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->n, value_bytes);
6433   if (result) {
6434     return result;
6435   }
6436 
6437   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->h, value_bytes);
6438   if (result) {
6439     return result;
6440   }
6441   return result;
6442 }
6443 
Serialize_TPMS_SIGNATURE_RSASSA(const TPMS_SIGNATURE_RSASSA & value,std::string * buffer)6444 TPM_RC Serialize_TPMS_SIGNATURE_RSASSA(const TPMS_SIGNATURE_RSASSA& value,
6445                                        std::string* buffer) {
6446   TPM_RC result = TPM_RC_SUCCESS;
6447   VLOG(3) << __func__;
6448 
6449   result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6450   if (result) {
6451     return result;
6452   }
6453 
6454   result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer);
6455   if (result) {
6456     return result;
6457   }
6458   return result;
6459 }
6460 
Parse_TPMS_SIGNATURE_RSASSA(std::string * buffer,TPMS_SIGNATURE_RSASSA * value,std::string * value_bytes)6461 TPM_RC Parse_TPMS_SIGNATURE_RSASSA(std::string* buffer,
6462                                    TPMS_SIGNATURE_RSASSA* value,
6463                                    std::string* value_bytes) {
6464   TPM_RC result = TPM_RC_SUCCESS;
6465   VLOG(3) << __func__;
6466 
6467   result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6468   if (result) {
6469     return result;
6470   }
6471 
6472   result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->sig, value_bytes);
6473   if (result) {
6474     return result;
6475   }
6476   return result;
6477 }
6478 
Serialize_TPMS_SIGNATURE_RSAPSS(const TPMS_SIGNATURE_RSAPSS & value,std::string * buffer)6479 TPM_RC Serialize_TPMS_SIGNATURE_RSAPSS(const TPMS_SIGNATURE_RSAPSS& value,
6480                                        std::string* buffer) {
6481   TPM_RC result = TPM_RC_SUCCESS;
6482   VLOG(3) << __func__;
6483 
6484   result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6485   if (result) {
6486     return result;
6487   }
6488 
6489   result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer);
6490   if (result) {
6491     return result;
6492   }
6493   return result;
6494 }
6495 
Parse_TPMS_SIGNATURE_RSAPSS(std::string * buffer,TPMS_SIGNATURE_RSAPSS * value,std::string * value_bytes)6496 TPM_RC Parse_TPMS_SIGNATURE_RSAPSS(std::string* buffer,
6497                                    TPMS_SIGNATURE_RSAPSS* value,
6498                                    std::string* value_bytes) {
6499   TPM_RC result = TPM_RC_SUCCESS;
6500   VLOG(3) << __func__;
6501 
6502   result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6503   if (result) {
6504     return result;
6505   }
6506 
6507   result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->sig, value_bytes);
6508   if (result) {
6509     return result;
6510   }
6511   return result;
6512 }
6513 
Serialize_TPMS_SIGNATURE_ECDSA(const TPMS_SIGNATURE_ECDSA & value,std::string * buffer)6514 TPM_RC Serialize_TPMS_SIGNATURE_ECDSA(const TPMS_SIGNATURE_ECDSA& value,
6515                                       std::string* buffer) {
6516   TPM_RC result = TPM_RC_SUCCESS;
6517   VLOG(3) << __func__;
6518 
6519   result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6520   if (result) {
6521     return result;
6522   }
6523 
6524   result = Serialize_TPM2B_ECC_PARAMETER(value.signature_r, buffer);
6525   if (result) {
6526     return result;
6527   }
6528 
6529   result = Serialize_TPM2B_ECC_PARAMETER(value.signature_s, buffer);
6530   if (result) {
6531     return result;
6532   }
6533   return result;
6534 }
6535 
Parse_TPMS_SIGNATURE_ECDSA(std::string * buffer,TPMS_SIGNATURE_ECDSA * value,std::string * value_bytes)6536 TPM_RC Parse_TPMS_SIGNATURE_ECDSA(std::string* buffer,
6537                                   TPMS_SIGNATURE_ECDSA* value,
6538                                   std::string* value_bytes) {
6539   TPM_RC result = TPM_RC_SUCCESS;
6540   VLOG(3) << __func__;
6541 
6542   result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6543   if (result) {
6544     return result;
6545   }
6546 
6547   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->signature_r, value_bytes);
6548   if (result) {
6549     return result;
6550   }
6551 
6552   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->signature_s, value_bytes);
6553   if (result) {
6554     return result;
6555   }
6556   return result;
6557 }
6558 
Serialize_TPMU_SIGNATURE(const TPMU_SIGNATURE & value,TPMI_ALG_SIG_SCHEME selector,std::string * buffer)6559 TPM_RC Serialize_TPMU_SIGNATURE(const TPMU_SIGNATURE& value,
6560                                 TPMI_ALG_SIG_SCHEME selector,
6561                                 std::string* buffer) {
6562   TPM_RC result = TPM_RC_SUCCESS;
6563   VLOG(3) << __func__;
6564 
6565   if (selector == TPM_ALG_HMAC) {
6566     result = Serialize_TPMT_HA(value.hmac, buffer);
6567     if (result) {
6568       return result;
6569     }
6570   }
6571 
6572   if (selector == TPM_ALG_ECSCHNORR) {
6573     result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecschnorr, buffer);
6574     if (result) {
6575       return result;
6576     }
6577   }
6578 
6579   if (selector == TPM_ALG_RSAPSS) {
6580     result = Serialize_TPMS_SIGNATURE_RSAPSS(value.rsapss, buffer);
6581     if (result) {
6582       return result;
6583     }
6584   }
6585 
6586   if (selector == TPM_ALG_ECDAA) {
6587     result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdaa, buffer);
6588     if (result) {
6589       return result;
6590     }
6591   }
6592 
6593   if (selector == TPM_ALG_RSASSA) {
6594     result = Serialize_TPMS_SIGNATURE_RSASSA(value.rsassa, buffer);
6595     if (result) {
6596       return result;
6597     }
6598   }
6599 
6600   if (selector == TPM_ALG_SM2) {
6601     result = Serialize_TPMS_SIGNATURE_ECDSA(value.sm2, buffer);
6602     if (result) {
6603       return result;
6604     }
6605   }
6606 
6607   if (selector == TPM_ALG_ECDSA) {
6608     result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdsa, buffer);
6609     if (result) {
6610       return result;
6611     }
6612   }
6613 
6614   if (selector == TPM_ALG_NULL) {
6615     // Do nothing.
6616   }
6617   return result;
6618 }
6619 
Parse_TPMU_SIGNATURE(std::string * buffer,TPMI_ALG_SIG_SCHEME selector,TPMU_SIGNATURE * value,std::string * value_bytes)6620 TPM_RC Parse_TPMU_SIGNATURE(std::string* buffer,
6621                             TPMI_ALG_SIG_SCHEME selector,
6622                             TPMU_SIGNATURE* value,
6623                             std::string* value_bytes) {
6624   TPM_RC result = TPM_RC_SUCCESS;
6625   VLOG(3) << __func__;
6626 
6627   if (selector == TPM_ALG_HMAC) {
6628     result = Parse_TPMT_HA(buffer, &value->hmac, value_bytes);
6629     if (result) {
6630       return result;
6631     }
6632   }
6633 
6634   if (selector == TPM_ALG_ECSCHNORR) {
6635     result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecschnorr, value_bytes);
6636     if (result) {
6637       return result;
6638     }
6639   }
6640 
6641   if (selector == TPM_ALG_RSAPSS) {
6642     result = Parse_TPMS_SIGNATURE_RSAPSS(buffer, &value->rsapss, value_bytes);
6643     if (result) {
6644       return result;
6645     }
6646   }
6647 
6648   if (selector == TPM_ALG_ECDAA) {
6649     result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecdaa, value_bytes);
6650     if (result) {
6651       return result;
6652     }
6653   }
6654 
6655   if (selector == TPM_ALG_RSASSA) {
6656     result = Parse_TPMS_SIGNATURE_RSASSA(buffer, &value->rsassa, value_bytes);
6657     if (result) {
6658       return result;
6659     }
6660   }
6661 
6662   if (selector == TPM_ALG_SM2) {
6663     result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->sm2, value_bytes);
6664     if (result) {
6665       return result;
6666     }
6667   }
6668 
6669   if (selector == TPM_ALG_ECDSA) {
6670     result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecdsa, value_bytes);
6671     if (result) {
6672       return result;
6673     }
6674   }
6675 
6676   if (selector == TPM_ALG_NULL) {
6677     // Do nothing.
6678   }
6679   return result;
6680 }
6681 
Serialize_TPMT_SIGNATURE(const TPMT_SIGNATURE & value,std::string * buffer)6682 TPM_RC Serialize_TPMT_SIGNATURE(const TPMT_SIGNATURE& value,
6683                                 std::string* buffer) {
6684   TPM_RC result = TPM_RC_SUCCESS;
6685   VLOG(3) << __func__;
6686 
6687   result = Serialize_TPMI_ALG_SIG_SCHEME(value.sig_alg, buffer);
6688   if (result) {
6689     return result;
6690   }
6691 
6692   result = Serialize_TPMU_SIGNATURE(value.signature, value.sig_alg, buffer);
6693   if (result) {
6694     return result;
6695   }
6696   return result;
6697 }
6698 
Parse_TPMT_SIGNATURE(std::string * buffer,TPMT_SIGNATURE * value,std::string * value_bytes)6699 TPM_RC Parse_TPMT_SIGNATURE(std::string* buffer,
6700                             TPMT_SIGNATURE* value,
6701                             std::string* value_bytes) {
6702   TPM_RC result = TPM_RC_SUCCESS;
6703   VLOG(3) << __func__;
6704 
6705   result = Parse_TPMI_ALG_SIG_SCHEME(buffer, &value->sig_alg, value_bytes);
6706   if (result) {
6707     return result;
6708   }
6709 
6710   result = Parse_TPMU_SIGNATURE(buffer, value->sig_alg, &value->signature,
6711                                 value_bytes);
6712   if (result) {
6713     return result;
6714   }
6715   return result;
6716 }
6717 
Serialize_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET & value,std::string * buffer)6718 TPM_RC Serialize_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET& value,
6719                                         std::string* buffer) {
6720   TPM_RC result = TPM_RC_SUCCESS;
6721   VLOG(3) << __func__;
6722 
6723   result = Serialize_UINT16(value.size, buffer);
6724   if (result) {
6725     return result;
6726   }
6727 
6728   if (std::size(value.secret) < value.size) {
6729     return TPM_RC_INSUFFICIENT;
6730   }
6731   for (uint32_t i = 0; i < value.size; ++i) {
6732     result = Serialize_BYTE(value.secret[i], buffer);
6733     if (result) {
6734       return result;
6735     }
6736   }
6737   return result;
6738 }
6739 
Parse_TPM2B_ENCRYPTED_SECRET(std::string * buffer,TPM2B_ENCRYPTED_SECRET * value,std::string * value_bytes)6740 TPM_RC Parse_TPM2B_ENCRYPTED_SECRET(std::string* buffer,
6741                                     TPM2B_ENCRYPTED_SECRET* value,
6742                                     std::string* value_bytes) {
6743   TPM_RC result = TPM_RC_SUCCESS;
6744   VLOG(3) << __func__;
6745 
6746   result = Parse_UINT16(buffer, &value->size, value_bytes);
6747   if (result) {
6748     return result;
6749   }
6750 
6751   if (std::size(value->secret) < value->size) {
6752     return TPM_RC_INSUFFICIENT;
6753   }
6754   for (uint32_t i = 0; i < value->size; ++i) {
6755     result = Parse_BYTE(buffer, &value->secret[i], value_bytes);
6756     if (result) {
6757       return result;
6758     }
6759   }
6760   return result;
6761 }
6762 
Make_TPM2B_ENCRYPTED_SECRET(const std::string & bytes)6763 TPM2B_ENCRYPTED_SECRET Make_TPM2B_ENCRYPTED_SECRET(const std::string& bytes) {
6764   TPM2B_ENCRYPTED_SECRET tpm2b;
6765   CHECK(bytes.size() <= sizeof(tpm2b.secret));
6766   memset(&tpm2b, 0, sizeof(TPM2B_ENCRYPTED_SECRET));
6767   tpm2b.size = bytes.size();
6768   memcpy(tpm2b.secret, bytes.data(), bytes.size());
6769   return tpm2b;
6770 }
6771 
StringFrom_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET & tpm2b)6772 std::string StringFrom_TPM2B_ENCRYPTED_SECRET(
6773     const TPM2B_ENCRYPTED_SECRET& tpm2b) {
6774   CHECK(tpm2b.size <= std::size(tpm2b.secret));
6775   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.secret);
6776   return std::string(char_buffer, tpm2b.size);
6777 }
6778 
Serialize_TPMS_KEYEDHASH_PARMS(const TPMS_KEYEDHASH_PARMS & value,std::string * buffer)6779 TPM_RC Serialize_TPMS_KEYEDHASH_PARMS(const TPMS_KEYEDHASH_PARMS& value,
6780                                       std::string* buffer) {
6781   TPM_RC result = TPM_RC_SUCCESS;
6782   VLOG(3) << __func__;
6783 
6784   result = Serialize_TPMT_KEYEDHASH_SCHEME(value.scheme, buffer);
6785   if (result) {
6786     return result;
6787   }
6788   return result;
6789 }
6790 
Parse_TPMS_KEYEDHASH_PARMS(std::string * buffer,TPMS_KEYEDHASH_PARMS * value,std::string * value_bytes)6791 TPM_RC Parse_TPMS_KEYEDHASH_PARMS(std::string* buffer,
6792                                   TPMS_KEYEDHASH_PARMS* value,
6793                                   std::string* value_bytes) {
6794   TPM_RC result = TPM_RC_SUCCESS;
6795   VLOG(3) << __func__;
6796 
6797   result = Parse_TPMT_KEYEDHASH_SCHEME(buffer, &value->scheme, value_bytes);
6798   if (result) {
6799     return result;
6800   }
6801   return result;
6802 }
6803 
Serialize_TPMS_ASYM_PARMS(const TPMS_ASYM_PARMS & value,std::string * buffer)6804 TPM_RC Serialize_TPMS_ASYM_PARMS(const TPMS_ASYM_PARMS& value,
6805                                  std::string* buffer) {
6806   TPM_RC result = TPM_RC_SUCCESS;
6807   VLOG(3) << __func__;
6808 
6809   result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6810   if (result) {
6811     return result;
6812   }
6813 
6814   result = Serialize_TPMT_ASYM_SCHEME(value.scheme, buffer);
6815   if (result) {
6816     return result;
6817   }
6818   return result;
6819 }
6820 
Parse_TPMS_ASYM_PARMS(std::string * buffer,TPMS_ASYM_PARMS * value,std::string * value_bytes)6821 TPM_RC Parse_TPMS_ASYM_PARMS(std::string* buffer,
6822                              TPMS_ASYM_PARMS* value,
6823                              std::string* value_bytes) {
6824   TPM_RC result = TPM_RC_SUCCESS;
6825   VLOG(3) << __func__;
6826 
6827   result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6828   if (result) {
6829     return result;
6830   }
6831 
6832   result = Parse_TPMT_ASYM_SCHEME(buffer, &value->scheme, value_bytes);
6833   if (result) {
6834     return result;
6835   }
6836   return result;
6837 }
6838 
Serialize_TPMS_RSA_PARMS(const TPMS_RSA_PARMS & value,std::string * buffer)6839 TPM_RC Serialize_TPMS_RSA_PARMS(const TPMS_RSA_PARMS& value,
6840                                 std::string* buffer) {
6841   TPM_RC result = TPM_RC_SUCCESS;
6842   VLOG(3) << __func__;
6843 
6844   result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6845   if (result) {
6846     return result;
6847   }
6848 
6849   result = Serialize_TPMT_RSA_SCHEME(value.scheme, buffer);
6850   if (result) {
6851     return result;
6852   }
6853 
6854   result = Serialize_TPMI_RSA_KEY_BITS(value.key_bits, buffer);
6855   if (result) {
6856     return result;
6857   }
6858 
6859   result = Serialize_UINT32(value.exponent, buffer);
6860   if (result) {
6861     return result;
6862   }
6863   return result;
6864 }
6865 
Parse_TPMS_RSA_PARMS(std::string * buffer,TPMS_RSA_PARMS * value,std::string * value_bytes)6866 TPM_RC Parse_TPMS_RSA_PARMS(std::string* buffer,
6867                             TPMS_RSA_PARMS* value,
6868                             std::string* value_bytes) {
6869   TPM_RC result = TPM_RC_SUCCESS;
6870   VLOG(3) << __func__;
6871 
6872   result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6873   if (result) {
6874     return result;
6875   }
6876 
6877   result = Parse_TPMT_RSA_SCHEME(buffer, &value->scheme, value_bytes);
6878   if (result) {
6879     return result;
6880   }
6881 
6882   result = Parse_TPMI_RSA_KEY_BITS(buffer, &value->key_bits, value_bytes);
6883   if (result) {
6884     return result;
6885   }
6886 
6887   result = Parse_UINT32(buffer, &value->exponent, value_bytes);
6888   if (result) {
6889     return result;
6890   }
6891   return result;
6892 }
6893 
Serialize_TPMS_ECC_PARMS(const TPMS_ECC_PARMS & value,std::string * buffer)6894 TPM_RC Serialize_TPMS_ECC_PARMS(const TPMS_ECC_PARMS& value,
6895                                 std::string* buffer) {
6896   TPM_RC result = TPM_RC_SUCCESS;
6897   VLOG(3) << __func__;
6898 
6899   result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6900   if (result) {
6901     return result;
6902   }
6903 
6904   result = Serialize_TPMT_ECC_SCHEME(value.scheme, buffer);
6905   if (result) {
6906     return result;
6907   }
6908 
6909   result = Serialize_TPMI_ECC_CURVE(value.curve_id, buffer);
6910   if (result) {
6911     return result;
6912   }
6913 
6914   result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer);
6915   if (result) {
6916     return result;
6917   }
6918   return result;
6919 }
6920 
Parse_TPMS_ECC_PARMS(std::string * buffer,TPMS_ECC_PARMS * value,std::string * value_bytes)6921 TPM_RC Parse_TPMS_ECC_PARMS(std::string* buffer,
6922                             TPMS_ECC_PARMS* value,
6923                             std::string* value_bytes) {
6924   TPM_RC result = TPM_RC_SUCCESS;
6925   VLOG(3) << __func__;
6926 
6927   result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6928   if (result) {
6929     return result;
6930   }
6931 
6932   result = Parse_TPMT_ECC_SCHEME(buffer, &value->scheme, value_bytes);
6933   if (result) {
6934     return result;
6935   }
6936 
6937   result = Parse_TPMI_ECC_CURVE(buffer, &value->curve_id, value_bytes);
6938   if (result) {
6939     return result;
6940   }
6941 
6942   result = Parse_TPMT_KDF_SCHEME(buffer, &value->kdf, value_bytes);
6943   if (result) {
6944     return result;
6945   }
6946   return result;
6947 }
6948 
Serialize_TPMU_PUBLIC_PARMS(const TPMU_PUBLIC_PARMS & value,TPMI_ALG_PUBLIC selector,std::string * buffer)6949 TPM_RC Serialize_TPMU_PUBLIC_PARMS(const TPMU_PUBLIC_PARMS& value,
6950                                    TPMI_ALG_PUBLIC selector,
6951                                    std::string* buffer) {
6952   TPM_RC result = TPM_RC_SUCCESS;
6953   VLOG(3) << __func__;
6954 
6955   if (selector == TPM_ALG_KEYEDHASH) {
6956     result = Serialize_TPMS_KEYEDHASH_PARMS(value.keyed_hash_detail, buffer);
6957     if (result) {
6958       return result;
6959     }
6960   }
6961 
6962   if (selector == TPM_ALG_RSA) {
6963     result = Serialize_TPMS_RSA_PARMS(value.rsa_detail, buffer);
6964     if (result) {
6965       return result;
6966     }
6967   }
6968 
6969   if (selector == TPM_ALG_SYMCIPHER) {
6970     result = Serialize_TPMS_SYMCIPHER_PARMS(value.sym_detail, buffer);
6971     if (result) {
6972       return result;
6973     }
6974   }
6975 
6976   if (selector == TPM_ALG_ECC) {
6977     result = Serialize_TPMS_ECC_PARMS(value.ecc_detail, buffer);
6978     if (result) {
6979       return result;
6980     }
6981   }
6982   return result;
6983 }
6984 
Parse_TPMU_PUBLIC_PARMS(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_PUBLIC_PARMS * value,std::string * value_bytes)6985 TPM_RC Parse_TPMU_PUBLIC_PARMS(std::string* buffer,
6986                                TPMI_ALG_PUBLIC selector,
6987                                TPMU_PUBLIC_PARMS* value,
6988                                std::string* value_bytes) {
6989   TPM_RC result = TPM_RC_SUCCESS;
6990   VLOG(3) << __func__;
6991 
6992   if (selector == TPM_ALG_KEYEDHASH) {
6993     result = Parse_TPMS_KEYEDHASH_PARMS(buffer, &value->keyed_hash_detail,
6994                                         value_bytes);
6995     if (result) {
6996       return result;
6997     }
6998   }
6999 
7000   if (selector == TPM_ALG_RSA) {
7001     result = Parse_TPMS_RSA_PARMS(buffer, &value->rsa_detail, value_bytes);
7002     if (result) {
7003       return result;
7004     }
7005   }
7006 
7007   if (selector == TPM_ALG_SYMCIPHER) {
7008     result =
7009         Parse_TPMS_SYMCIPHER_PARMS(buffer, &value->sym_detail, value_bytes);
7010     if (result) {
7011       return result;
7012     }
7013   }
7014 
7015   if (selector == TPM_ALG_ECC) {
7016     result = Parse_TPMS_ECC_PARMS(buffer, &value->ecc_detail, value_bytes);
7017     if (result) {
7018       return result;
7019     }
7020   }
7021   return result;
7022 }
7023 
Serialize_TPMT_PUBLIC_PARMS(const TPMT_PUBLIC_PARMS & value,std::string * buffer)7024 TPM_RC Serialize_TPMT_PUBLIC_PARMS(const TPMT_PUBLIC_PARMS& value,
7025                                    std::string* buffer) {
7026   TPM_RC result = TPM_RC_SUCCESS;
7027   VLOG(3) << __func__;
7028 
7029   result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer);
7030   if (result) {
7031     return result;
7032   }
7033 
7034   result = Serialize_TPMU_PUBLIC_PARMS(value.parameters, value.type, buffer);
7035   if (result) {
7036     return result;
7037   }
7038   return result;
7039 }
7040 
Parse_TPMT_PUBLIC_PARMS(std::string * buffer,TPMT_PUBLIC_PARMS * value,std::string * value_bytes)7041 TPM_RC Parse_TPMT_PUBLIC_PARMS(std::string* buffer,
7042                                TPMT_PUBLIC_PARMS* value,
7043                                std::string* value_bytes) {
7044   TPM_RC result = TPM_RC_SUCCESS;
7045   VLOG(3) << __func__;
7046 
7047   result = Parse_TPMI_ALG_PUBLIC(buffer, &value->type, value_bytes);
7048   if (result) {
7049     return result;
7050   }
7051 
7052   result = Parse_TPMU_PUBLIC_PARMS(buffer, value->type, &value->parameters,
7053                                    value_bytes);
7054   if (result) {
7055     return result;
7056   }
7057   return result;
7058 }
7059 
Serialize_TPMU_PUBLIC_ID(const TPMU_PUBLIC_ID & value,TPMI_ALG_PUBLIC selector,std::string * buffer)7060 TPM_RC Serialize_TPMU_PUBLIC_ID(const TPMU_PUBLIC_ID& value,
7061                                 TPMI_ALG_PUBLIC selector,
7062                                 std::string* buffer) {
7063   TPM_RC result = TPM_RC_SUCCESS;
7064   VLOG(3) << __func__;
7065 
7066   if (selector == TPM_ALG_KEYEDHASH) {
7067     result = Serialize_TPM2B_DIGEST(value.keyed_hash, buffer);
7068     if (result) {
7069       return result;
7070     }
7071   }
7072 
7073   if (selector == TPM_ALG_RSA) {
7074     result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.rsa, buffer);
7075     if (result) {
7076       return result;
7077     }
7078   }
7079 
7080   if (selector == TPM_ALG_SYMCIPHER) {
7081     result = Serialize_TPM2B_DIGEST(value.sym, buffer);
7082     if (result) {
7083       return result;
7084     }
7085   }
7086 
7087   if (selector == TPM_ALG_ECC) {
7088     result = Serialize_TPMS_ECC_POINT(value.ecc, buffer);
7089     if (result) {
7090       return result;
7091     }
7092   }
7093   return result;
7094 }
7095 
Parse_TPMU_PUBLIC_ID(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_PUBLIC_ID * value,std::string * value_bytes)7096 TPM_RC Parse_TPMU_PUBLIC_ID(std::string* buffer,
7097                             TPMI_ALG_PUBLIC selector,
7098                             TPMU_PUBLIC_ID* value,
7099                             std::string* value_bytes) {
7100   TPM_RC result = TPM_RC_SUCCESS;
7101   VLOG(3) << __func__;
7102 
7103   if (selector == TPM_ALG_KEYEDHASH) {
7104     result = Parse_TPM2B_DIGEST(buffer, &value->keyed_hash, value_bytes);
7105     if (result) {
7106       return result;
7107     }
7108   }
7109 
7110   if (selector == TPM_ALG_RSA) {
7111     result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->rsa, value_bytes);
7112     if (result) {
7113       return result;
7114     }
7115   }
7116 
7117   if (selector == TPM_ALG_SYMCIPHER) {
7118     result = Parse_TPM2B_DIGEST(buffer, &value->sym, value_bytes);
7119     if (result) {
7120       return result;
7121     }
7122   }
7123 
7124   if (selector == TPM_ALG_ECC) {
7125     result = Parse_TPMS_ECC_POINT(buffer, &value->ecc, value_bytes);
7126     if (result) {
7127       return result;
7128     }
7129   }
7130   return result;
7131 }
7132 
Serialize_TPMT_PUBLIC(const TPMT_PUBLIC & value,std::string * buffer)7133 TPM_RC Serialize_TPMT_PUBLIC(const TPMT_PUBLIC& value, std::string* buffer) {
7134   TPM_RC result = TPM_RC_SUCCESS;
7135   VLOG(3) << __func__;
7136 
7137   result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer);
7138   if (result) {
7139     return result;
7140   }
7141 
7142   result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer);
7143   if (result) {
7144     return result;
7145   }
7146 
7147   result = Serialize_TPMA_OBJECT(value.object_attributes, buffer);
7148   if (result) {
7149     return result;
7150   }
7151 
7152   result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer);
7153   if (result) {
7154     return result;
7155   }
7156 
7157   result = Serialize_TPMU_PUBLIC_PARMS(value.parameters, value.type, buffer);
7158   if (result) {
7159     return result;
7160   }
7161 
7162   result = Serialize_TPMU_PUBLIC_ID(value.unique, value.type, buffer);
7163   if (result) {
7164     return result;
7165   }
7166   return result;
7167 }
7168 
Parse_TPMT_PUBLIC(std::string * buffer,TPMT_PUBLIC * value,std::string * value_bytes)7169 TPM_RC Parse_TPMT_PUBLIC(std::string* buffer,
7170                          TPMT_PUBLIC* value,
7171                          std::string* value_bytes) {
7172   TPM_RC result = TPM_RC_SUCCESS;
7173   VLOG(3) << __func__;
7174 
7175   result = Parse_TPMI_ALG_PUBLIC(buffer, &value->type, value_bytes);
7176   if (result) {
7177     return result;
7178   }
7179 
7180   result = Parse_TPMI_ALG_HASH(buffer, &value->name_alg, value_bytes);
7181   if (result) {
7182     return result;
7183   }
7184 
7185   result = Parse_TPMA_OBJECT(buffer, &value->object_attributes, value_bytes);
7186   if (result) {
7187     return result;
7188   }
7189 
7190   result = Parse_TPM2B_DIGEST(buffer, &value->auth_policy, value_bytes);
7191   if (result) {
7192     return result;
7193   }
7194 
7195   result = Parse_TPMU_PUBLIC_PARMS(buffer, value->type, &value->parameters,
7196                                    value_bytes);
7197   if (result) {
7198     return result;
7199   }
7200 
7201   result =
7202       Parse_TPMU_PUBLIC_ID(buffer, value->type, &value->unique, value_bytes);
7203   if (result) {
7204     return result;
7205   }
7206   return result;
7207 }
7208 
Serialize_TPM2B_PUBLIC(const TPM2B_PUBLIC & value,std::string * buffer)7209 TPM_RC Serialize_TPM2B_PUBLIC(const TPM2B_PUBLIC& value, std::string* buffer) {
7210   TPM_RC result = TPM_RC_SUCCESS;
7211   VLOG(3) << __func__;
7212 
7213   std::string field_bytes;
7214   if (value.size) {
7215     if (value.size != sizeof(TPMT_PUBLIC)) {
7216       return TPM_RC_SIZE;
7217     }
7218     result = Serialize_TPMT_PUBLIC(value.public_area, &field_bytes);
7219     if (result) {
7220       return result;
7221     }
7222   }
7223   std::string size_bytes;
7224   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7225   if (result) {
7226     return result;
7227   }
7228   buffer->append(size_bytes + field_bytes);
7229   return result;
7230 }
7231 
Parse_TPM2B_PUBLIC(std::string * buffer,TPM2B_PUBLIC * value,std::string * value_bytes)7232 TPM_RC Parse_TPM2B_PUBLIC(std::string* buffer,
7233                           TPM2B_PUBLIC* value,
7234                           std::string* value_bytes) {
7235   TPM_RC result = TPM_RC_SUCCESS;
7236   VLOG(3) << __func__;
7237 
7238   UINT16 parsed_size = 0;
7239   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7240   if (result) {
7241     return result;
7242   }
7243   if (!parsed_size) {
7244     value->size = 0;
7245   } else {
7246     value->size = sizeof(TPMT_PUBLIC);
7247     result = Parse_TPMT_PUBLIC(buffer, &value->public_area, value_bytes);
7248     if (result) {
7249       return result;
7250     }
7251   }
7252   return result;
7253 }
7254 
Make_TPM2B_PUBLIC(const TPMT_PUBLIC & inner)7255 TPM2B_PUBLIC Make_TPM2B_PUBLIC(const TPMT_PUBLIC& inner) {
7256   TPM2B_PUBLIC tpm2b;
7257   tpm2b.size = sizeof(TPMT_PUBLIC);
7258   tpm2b.public_area = inner;
7259   return tpm2b;
7260 }
7261 
Serialize_TPM2B_PRIVATE_VENDOR_SPECIFIC(const TPM2B_PRIVATE_VENDOR_SPECIFIC & value,std::string * buffer)7262 TPM_RC Serialize_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7263     const TPM2B_PRIVATE_VENDOR_SPECIFIC& value, std::string* buffer) {
7264   TPM_RC result = TPM_RC_SUCCESS;
7265   VLOG(3) << __func__;
7266 
7267   result = Serialize_UINT16(value.size, buffer);
7268   if (result) {
7269     return result;
7270   }
7271 
7272   if (std::size(value.buffer) < value.size) {
7273     return TPM_RC_INSUFFICIENT;
7274   }
7275   for (uint32_t i = 0; i < value.size; ++i) {
7276     result = Serialize_BYTE(value.buffer[i], buffer);
7277     if (result) {
7278       return result;
7279     }
7280   }
7281   return result;
7282 }
7283 
Parse_TPM2B_PRIVATE_VENDOR_SPECIFIC(std::string * buffer,TPM2B_PRIVATE_VENDOR_SPECIFIC * value,std::string * value_bytes)7284 TPM_RC Parse_TPM2B_PRIVATE_VENDOR_SPECIFIC(std::string* buffer,
7285                                            TPM2B_PRIVATE_VENDOR_SPECIFIC* value,
7286                                            std::string* value_bytes) {
7287   TPM_RC result = TPM_RC_SUCCESS;
7288   VLOG(3) << __func__;
7289 
7290   result = Parse_UINT16(buffer, &value->size, value_bytes);
7291   if (result) {
7292     return result;
7293   }
7294 
7295   if (std::size(value->buffer) < value->size) {
7296     return TPM_RC_INSUFFICIENT;
7297   }
7298   for (uint32_t i = 0; i < value->size; ++i) {
7299     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7300     if (result) {
7301       return result;
7302     }
7303   }
7304   return result;
7305 }
7306 
Make_TPM2B_PRIVATE_VENDOR_SPECIFIC(const std::string & bytes)7307 TPM2B_PRIVATE_VENDOR_SPECIFIC Make_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7308     const std::string& bytes) {
7309   TPM2B_PRIVATE_VENDOR_SPECIFIC tpm2b;
7310   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7311   memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_VENDOR_SPECIFIC));
7312   tpm2b.size = bytes.size();
7313   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7314   return tpm2b;
7315 }
7316 
StringFrom_TPM2B_PRIVATE_VENDOR_SPECIFIC(const TPM2B_PRIVATE_VENDOR_SPECIFIC & tpm2b)7317 std::string StringFrom_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7318     const TPM2B_PRIVATE_VENDOR_SPECIFIC& tpm2b) {
7319   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7320   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7321   return std::string(char_buffer, tpm2b.size);
7322 }
7323 
Serialize_TPMU_SENSITIVE_COMPOSITE(const TPMU_SENSITIVE_COMPOSITE & value,TPMI_ALG_PUBLIC selector,std::string * buffer)7324 TPM_RC Serialize_TPMU_SENSITIVE_COMPOSITE(const TPMU_SENSITIVE_COMPOSITE& value,
7325                                           TPMI_ALG_PUBLIC selector,
7326                                           std::string* buffer) {
7327   TPM_RC result = TPM_RC_SUCCESS;
7328   VLOG(3) << __func__;
7329 
7330   if (selector == TPM_ALG_KEYEDHASH) {
7331     result = Serialize_TPM2B_SENSITIVE_DATA(value.bits, buffer);
7332     if (result) {
7333       return result;
7334     }
7335   }
7336 
7337   if (selector == TPM_ALG_RSA) {
7338     result = Serialize_TPM2B_PRIVATE_KEY_RSA(value.rsa, buffer);
7339     if (result) {
7340       return result;
7341     }
7342   }
7343 
7344   if (selector == TPM_ALG_SYMCIPHER) {
7345     result = Serialize_TPM2B_SYM_KEY(value.sym, buffer);
7346     if (result) {
7347       return result;
7348     }
7349   }
7350 
7351   if (selector == TPM_ALG_ECC) {
7352     result = Serialize_TPM2B_ECC_PARAMETER(value.ecc, buffer);
7353     if (result) {
7354       return result;
7355     }
7356   }
7357   return result;
7358 }
7359 
Parse_TPMU_SENSITIVE_COMPOSITE(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_SENSITIVE_COMPOSITE * value,std::string * value_bytes)7360 TPM_RC Parse_TPMU_SENSITIVE_COMPOSITE(std::string* buffer,
7361                                       TPMI_ALG_PUBLIC selector,
7362                                       TPMU_SENSITIVE_COMPOSITE* value,
7363                                       std::string* value_bytes) {
7364   TPM_RC result = TPM_RC_SUCCESS;
7365   VLOG(3) << __func__;
7366 
7367   if (selector == TPM_ALG_KEYEDHASH) {
7368     result = Parse_TPM2B_SENSITIVE_DATA(buffer, &value->bits, value_bytes);
7369     if (result) {
7370       return result;
7371     }
7372   }
7373 
7374   if (selector == TPM_ALG_RSA) {
7375     result = Parse_TPM2B_PRIVATE_KEY_RSA(buffer, &value->rsa, value_bytes);
7376     if (result) {
7377       return result;
7378     }
7379   }
7380 
7381   if (selector == TPM_ALG_SYMCIPHER) {
7382     result = Parse_TPM2B_SYM_KEY(buffer, &value->sym, value_bytes);
7383     if (result) {
7384       return result;
7385     }
7386   }
7387 
7388   if (selector == TPM_ALG_ECC) {
7389     result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->ecc, value_bytes);
7390     if (result) {
7391       return result;
7392     }
7393   }
7394   return result;
7395 }
7396 
Serialize_TPMT_SENSITIVE(const TPMT_SENSITIVE & value,std::string * buffer)7397 TPM_RC Serialize_TPMT_SENSITIVE(const TPMT_SENSITIVE& value,
7398                                 std::string* buffer) {
7399   TPM_RC result = TPM_RC_SUCCESS;
7400   VLOG(3) << __func__;
7401 
7402   result = Serialize_TPMI_ALG_PUBLIC(value.sensitive_type, buffer);
7403   if (result) {
7404     return result;
7405   }
7406 
7407   result = Serialize_TPM2B_AUTH(value.auth_value, buffer);
7408   if (result) {
7409     return result;
7410   }
7411 
7412   result = Serialize_TPM2B_DIGEST(value.seed_value, buffer);
7413   if (result) {
7414     return result;
7415   }
7416 
7417   result = Serialize_TPMU_SENSITIVE_COMPOSITE(value.sensitive,
7418                                               value.sensitive_type, buffer);
7419   if (result) {
7420     return result;
7421   }
7422   return result;
7423 }
7424 
Parse_TPMT_SENSITIVE(std::string * buffer,TPMT_SENSITIVE * value,std::string * value_bytes)7425 TPM_RC Parse_TPMT_SENSITIVE(std::string* buffer,
7426                             TPMT_SENSITIVE* value,
7427                             std::string* value_bytes) {
7428   TPM_RC result = TPM_RC_SUCCESS;
7429   VLOG(3) << __func__;
7430 
7431   result = Parse_TPMI_ALG_PUBLIC(buffer, &value->sensitive_type, value_bytes);
7432   if (result) {
7433     return result;
7434   }
7435 
7436   result = Parse_TPM2B_AUTH(buffer, &value->auth_value, value_bytes);
7437   if (result) {
7438     return result;
7439   }
7440 
7441   result = Parse_TPM2B_DIGEST(buffer, &value->seed_value, value_bytes);
7442   if (result) {
7443     return result;
7444   }
7445 
7446   result = Parse_TPMU_SENSITIVE_COMPOSITE(buffer, value->sensitive_type,
7447                                           &value->sensitive, value_bytes);
7448   if (result) {
7449     return result;
7450   }
7451   return result;
7452 }
7453 
Serialize_TPM2B_SENSITIVE(const TPM2B_SENSITIVE & value,std::string * buffer)7454 TPM_RC Serialize_TPM2B_SENSITIVE(const TPM2B_SENSITIVE& value,
7455                                  std::string* buffer) {
7456   TPM_RC result = TPM_RC_SUCCESS;
7457   VLOG(3) << __func__;
7458 
7459   std::string field_bytes;
7460   if (value.size) {
7461     if (value.size != sizeof(TPMT_SENSITIVE)) {
7462       return TPM_RC_SIZE;
7463     }
7464     result = Serialize_TPMT_SENSITIVE(value.sensitive_area, &field_bytes);
7465     if (result) {
7466       return result;
7467     }
7468   }
7469   std::string size_bytes;
7470   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7471   if (result) {
7472     return result;
7473   }
7474   buffer->append(size_bytes + field_bytes);
7475   return result;
7476 }
7477 
Parse_TPM2B_SENSITIVE(std::string * buffer,TPM2B_SENSITIVE * value,std::string * value_bytes)7478 TPM_RC Parse_TPM2B_SENSITIVE(std::string* buffer,
7479                              TPM2B_SENSITIVE* value,
7480                              std::string* value_bytes) {
7481   TPM_RC result = TPM_RC_SUCCESS;
7482   VLOG(3) << __func__;
7483 
7484   UINT16 parsed_size = 0;
7485   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7486   if (result) {
7487     return result;
7488   }
7489   if (!parsed_size) {
7490     value->size = 0;
7491   } else {
7492     value->size = sizeof(TPMT_SENSITIVE);
7493     result = Parse_TPMT_SENSITIVE(buffer, &value->sensitive_area, value_bytes);
7494     if (result) {
7495       return result;
7496     }
7497   }
7498   return result;
7499 }
7500 
Make_TPM2B_SENSITIVE(const TPMT_SENSITIVE & inner)7501 TPM2B_SENSITIVE Make_TPM2B_SENSITIVE(const TPMT_SENSITIVE& inner) {
7502   TPM2B_SENSITIVE tpm2b;
7503   tpm2b.size = sizeof(TPMT_SENSITIVE);
7504   tpm2b.sensitive_area = inner;
7505   return tpm2b;
7506 }
7507 
Serialize_TPM2B_PRIVATE(const TPM2B_PRIVATE & value,std::string * buffer)7508 TPM_RC Serialize_TPM2B_PRIVATE(const TPM2B_PRIVATE& value,
7509                                std::string* buffer) {
7510   TPM_RC result = TPM_RC_SUCCESS;
7511   VLOG(3) << __func__;
7512 
7513   result = Serialize_UINT16(value.size, buffer);
7514   if (result) {
7515     return result;
7516   }
7517 
7518   if (std::size(value.buffer) < value.size) {
7519     return TPM_RC_INSUFFICIENT;
7520   }
7521   for (uint32_t i = 0; i < value.size; ++i) {
7522     result = Serialize_BYTE(value.buffer[i], buffer);
7523     if (result) {
7524       return result;
7525     }
7526   }
7527   return result;
7528 }
7529 
Parse_TPM2B_PRIVATE(std::string * buffer,TPM2B_PRIVATE * value,std::string * value_bytes)7530 TPM_RC Parse_TPM2B_PRIVATE(std::string* buffer,
7531                            TPM2B_PRIVATE* value,
7532                            std::string* value_bytes) {
7533   TPM_RC result = TPM_RC_SUCCESS;
7534   VLOG(3) << __func__;
7535 
7536   result = Parse_UINT16(buffer, &value->size, value_bytes);
7537   if (result) {
7538     return result;
7539   }
7540 
7541   if (std::size(value->buffer) < value->size) {
7542     return TPM_RC_INSUFFICIENT;
7543   }
7544   for (uint32_t i = 0; i < value->size; ++i) {
7545     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7546     if (result) {
7547       return result;
7548     }
7549   }
7550   return result;
7551 }
7552 
Make_TPM2B_PRIVATE(const std::string & bytes)7553 TPM2B_PRIVATE Make_TPM2B_PRIVATE(const std::string& bytes) {
7554   TPM2B_PRIVATE tpm2b;
7555   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7556   memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE));
7557   tpm2b.size = bytes.size();
7558   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7559   return tpm2b;
7560 }
7561 
StringFrom_TPM2B_PRIVATE(const TPM2B_PRIVATE & tpm2b)7562 std::string StringFrom_TPM2B_PRIVATE(const TPM2B_PRIVATE& tpm2b) {
7563   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7564   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7565   return std::string(char_buffer, tpm2b.size);
7566 }
7567 
Serialize_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT & value,std::string * buffer)7568 TPM_RC Serialize_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT& value,
7569                                  std::string* buffer) {
7570   TPM_RC result = TPM_RC_SUCCESS;
7571   VLOG(3) << __func__;
7572 
7573   result = Serialize_UINT16(value.size, buffer);
7574   if (result) {
7575     return result;
7576   }
7577 
7578   if (std::size(value.credential) < value.size) {
7579     return TPM_RC_INSUFFICIENT;
7580   }
7581   for (uint32_t i = 0; i < value.size; ++i) {
7582     result = Serialize_BYTE(value.credential[i], buffer);
7583     if (result) {
7584       return result;
7585     }
7586   }
7587   return result;
7588 }
7589 
Parse_TPM2B_ID_OBJECT(std::string * buffer,TPM2B_ID_OBJECT * value,std::string * value_bytes)7590 TPM_RC Parse_TPM2B_ID_OBJECT(std::string* buffer,
7591                              TPM2B_ID_OBJECT* value,
7592                              std::string* value_bytes) {
7593   TPM_RC result = TPM_RC_SUCCESS;
7594   VLOG(3) << __func__;
7595 
7596   result = Parse_UINT16(buffer, &value->size, value_bytes);
7597   if (result) {
7598     return result;
7599   }
7600 
7601   if (std::size(value->credential) < value->size) {
7602     return TPM_RC_INSUFFICIENT;
7603   }
7604   for (uint32_t i = 0; i < value->size; ++i) {
7605     result = Parse_BYTE(buffer, &value->credential[i], value_bytes);
7606     if (result) {
7607       return result;
7608     }
7609   }
7610   return result;
7611 }
7612 
Make_TPM2B_ID_OBJECT(const std::string & bytes)7613 TPM2B_ID_OBJECT Make_TPM2B_ID_OBJECT(const std::string& bytes) {
7614   TPM2B_ID_OBJECT tpm2b;
7615   CHECK(bytes.size() <= sizeof(tpm2b.credential));
7616   memset(&tpm2b, 0, sizeof(TPM2B_ID_OBJECT));
7617   tpm2b.size = bytes.size();
7618   memcpy(tpm2b.credential, bytes.data(), bytes.size());
7619   return tpm2b;
7620 }
7621 
StringFrom_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT & tpm2b)7622 std::string StringFrom_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT& tpm2b) {
7623   CHECK(tpm2b.size <= std::size(tpm2b.credential));
7624   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.credential);
7625   return std::string(char_buffer, tpm2b.size);
7626 }
7627 
Serialize_TPMS_NV_PUBLIC(const TPMS_NV_PUBLIC & value,std::string * buffer)7628 TPM_RC Serialize_TPMS_NV_PUBLIC(const TPMS_NV_PUBLIC& value,
7629                                 std::string* buffer) {
7630   TPM_RC result = TPM_RC_SUCCESS;
7631   VLOG(3) << __func__;
7632 
7633   result = Serialize_TPMI_RH_NV_INDEX(value.nv_index, buffer);
7634   if (result) {
7635     return result;
7636   }
7637 
7638   result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer);
7639   if (result) {
7640     return result;
7641   }
7642 
7643   result = Serialize_TPMA_NV(value.attributes, buffer);
7644   if (result) {
7645     return result;
7646   }
7647 
7648   result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer);
7649   if (result) {
7650     return result;
7651   }
7652 
7653   result = Serialize_UINT16(value.data_size, buffer);
7654   if (result) {
7655     return result;
7656   }
7657   return result;
7658 }
7659 
Parse_TPMS_NV_PUBLIC(std::string * buffer,TPMS_NV_PUBLIC * value,std::string * value_bytes)7660 TPM_RC Parse_TPMS_NV_PUBLIC(std::string* buffer,
7661                             TPMS_NV_PUBLIC* value,
7662                             std::string* value_bytes) {
7663   TPM_RC result = TPM_RC_SUCCESS;
7664   VLOG(3) << __func__;
7665 
7666   result = Parse_TPMI_RH_NV_INDEX(buffer, &value->nv_index, value_bytes);
7667   if (result) {
7668     return result;
7669   }
7670 
7671   result = Parse_TPMI_ALG_HASH(buffer, &value->name_alg, value_bytes);
7672   if (result) {
7673     return result;
7674   }
7675 
7676   result = Parse_TPMA_NV(buffer, &value->attributes, value_bytes);
7677   if (result) {
7678     return result;
7679   }
7680 
7681   result = Parse_TPM2B_DIGEST(buffer, &value->auth_policy, value_bytes);
7682   if (result) {
7683     return result;
7684   }
7685 
7686   result = Parse_UINT16(buffer, &value->data_size, value_bytes);
7687   if (result) {
7688     return result;
7689   }
7690   return result;
7691 }
7692 
Serialize_TPM2B_NV_PUBLIC(const TPM2B_NV_PUBLIC & value,std::string * buffer)7693 TPM_RC Serialize_TPM2B_NV_PUBLIC(const TPM2B_NV_PUBLIC& value,
7694                                  std::string* buffer) {
7695   TPM_RC result = TPM_RC_SUCCESS;
7696   VLOG(3) << __func__;
7697 
7698   std::string field_bytes;
7699   if (value.size) {
7700     if (value.size != sizeof(TPMS_NV_PUBLIC)) {
7701       return TPM_RC_SIZE;
7702     }
7703     result = Serialize_TPMS_NV_PUBLIC(value.nv_public, &field_bytes);
7704     if (result) {
7705       return result;
7706     }
7707   }
7708   std::string size_bytes;
7709   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7710   if (result) {
7711     return result;
7712   }
7713   buffer->append(size_bytes + field_bytes);
7714   return result;
7715 }
7716 
Parse_TPM2B_NV_PUBLIC(std::string * buffer,TPM2B_NV_PUBLIC * value,std::string * value_bytes)7717 TPM_RC Parse_TPM2B_NV_PUBLIC(std::string* buffer,
7718                              TPM2B_NV_PUBLIC* value,
7719                              std::string* value_bytes) {
7720   TPM_RC result = TPM_RC_SUCCESS;
7721   VLOG(3) << __func__;
7722 
7723   UINT16 parsed_size = 0;
7724   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7725   if (result) {
7726     return result;
7727   }
7728   if (!parsed_size) {
7729     value->size = 0;
7730   } else {
7731     value->size = sizeof(TPMS_NV_PUBLIC);
7732     result = Parse_TPMS_NV_PUBLIC(buffer, &value->nv_public, value_bytes);
7733     if (result) {
7734       return result;
7735     }
7736   }
7737   return result;
7738 }
7739 
Make_TPM2B_NV_PUBLIC(const TPMS_NV_PUBLIC & inner)7740 TPM2B_NV_PUBLIC Make_TPM2B_NV_PUBLIC(const TPMS_NV_PUBLIC& inner) {
7741   TPM2B_NV_PUBLIC tpm2b;
7742   tpm2b.size = sizeof(TPMS_NV_PUBLIC);
7743   tpm2b.nv_public = inner;
7744   return tpm2b;
7745 }
7746 
Serialize_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE & value,std::string * buffer)7747 TPM_RC Serialize_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE& value,
7748                                          std::string* buffer) {
7749   TPM_RC result = TPM_RC_SUCCESS;
7750   VLOG(3) << __func__;
7751 
7752   result = Serialize_UINT16(value.size, buffer);
7753   if (result) {
7754     return result;
7755   }
7756 
7757   if (std::size(value.buffer) < value.size) {
7758     return TPM_RC_INSUFFICIENT;
7759   }
7760   for (uint32_t i = 0; i < value.size; ++i) {
7761     result = Serialize_BYTE(value.buffer[i], buffer);
7762     if (result) {
7763       return result;
7764     }
7765   }
7766   return result;
7767 }
7768 
Parse_TPM2B_CONTEXT_SENSITIVE(std::string * buffer,TPM2B_CONTEXT_SENSITIVE * value,std::string * value_bytes)7769 TPM_RC Parse_TPM2B_CONTEXT_SENSITIVE(std::string* buffer,
7770                                      TPM2B_CONTEXT_SENSITIVE* value,
7771                                      std::string* value_bytes) {
7772   TPM_RC result = TPM_RC_SUCCESS;
7773   VLOG(3) << __func__;
7774 
7775   result = Parse_UINT16(buffer, &value->size, value_bytes);
7776   if (result) {
7777     return result;
7778   }
7779 
7780   if (std::size(value->buffer) < value->size) {
7781     return TPM_RC_INSUFFICIENT;
7782   }
7783   for (uint32_t i = 0; i < value->size; ++i) {
7784     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7785     if (result) {
7786       return result;
7787     }
7788   }
7789   return result;
7790 }
7791 
Make_TPM2B_CONTEXT_SENSITIVE(const std::string & bytes)7792 TPM2B_CONTEXT_SENSITIVE Make_TPM2B_CONTEXT_SENSITIVE(const std::string& bytes) {
7793   TPM2B_CONTEXT_SENSITIVE tpm2b;
7794   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7795   memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_SENSITIVE));
7796   tpm2b.size = bytes.size();
7797   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7798   return tpm2b;
7799 }
7800 
StringFrom_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE & tpm2b)7801 std::string StringFrom_TPM2B_CONTEXT_SENSITIVE(
7802     const TPM2B_CONTEXT_SENSITIVE& tpm2b) {
7803   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7804   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7805   return std::string(char_buffer, tpm2b.size);
7806 }
7807 
Serialize_TPMS_CONTEXT_DATA(const TPMS_CONTEXT_DATA & value,std::string * buffer)7808 TPM_RC Serialize_TPMS_CONTEXT_DATA(const TPMS_CONTEXT_DATA& value,
7809                                    std::string* buffer) {
7810   TPM_RC result = TPM_RC_SUCCESS;
7811   VLOG(3) << __func__;
7812 
7813   result = Serialize_TPM2B_DIGEST(value.integrity, buffer);
7814   if (result) {
7815     return result;
7816   }
7817 
7818   result = Serialize_TPM2B_CONTEXT_SENSITIVE(value.encrypted, buffer);
7819   if (result) {
7820     return result;
7821   }
7822   return result;
7823 }
7824 
Parse_TPMS_CONTEXT_DATA(std::string * buffer,TPMS_CONTEXT_DATA * value,std::string * value_bytes)7825 TPM_RC Parse_TPMS_CONTEXT_DATA(std::string* buffer,
7826                                TPMS_CONTEXT_DATA* value,
7827                                std::string* value_bytes) {
7828   TPM_RC result = TPM_RC_SUCCESS;
7829   VLOG(3) << __func__;
7830 
7831   result = Parse_TPM2B_DIGEST(buffer, &value->integrity, value_bytes);
7832   if (result) {
7833     return result;
7834   }
7835 
7836   result =
7837       Parse_TPM2B_CONTEXT_SENSITIVE(buffer, &value->encrypted, value_bytes);
7838   if (result) {
7839     return result;
7840   }
7841   return result;
7842 }
7843 
Serialize_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA & value,std::string * buffer)7844 TPM_RC Serialize_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA& value,
7845                                     std::string* buffer) {
7846   TPM_RC result = TPM_RC_SUCCESS;
7847   VLOG(3) << __func__;
7848 
7849   result = Serialize_UINT16(value.size, buffer);
7850   if (result) {
7851     return result;
7852   }
7853 
7854   if (std::size(value.buffer) < value.size) {
7855     return TPM_RC_INSUFFICIENT;
7856   }
7857   for (uint32_t i = 0; i < value.size; ++i) {
7858     result = Serialize_BYTE(value.buffer[i], buffer);
7859     if (result) {
7860       return result;
7861     }
7862   }
7863   return result;
7864 }
7865 
Parse_TPM2B_CONTEXT_DATA(std::string * buffer,TPM2B_CONTEXT_DATA * value,std::string * value_bytes)7866 TPM_RC Parse_TPM2B_CONTEXT_DATA(std::string* buffer,
7867                                 TPM2B_CONTEXT_DATA* value,
7868                                 std::string* value_bytes) {
7869   TPM_RC result = TPM_RC_SUCCESS;
7870   VLOG(3) << __func__;
7871 
7872   result = Parse_UINT16(buffer, &value->size, value_bytes);
7873   if (result) {
7874     return result;
7875   }
7876 
7877   if (std::size(value->buffer) < value->size) {
7878     return TPM_RC_INSUFFICIENT;
7879   }
7880   for (uint32_t i = 0; i < value->size; ++i) {
7881     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7882     if (result) {
7883       return result;
7884     }
7885   }
7886   return result;
7887 }
7888 
Make_TPM2B_CONTEXT_DATA(const std::string & bytes)7889 TPM2B_CONTEXT_DATA Make_TPM2B_CONTEXT_DATA(const std::string& bytes) {
7890   TPM2B_CONTEXT_DATA tpm2b;
7891   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7892   memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_DATA));
7893   tpm2b.size = bytes.size();
7894   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7895   return tpm2b;
7896 }
7897 
StringFrom_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA & tpm2b)7898 std::string StringFrom_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA& tpm2b) {
7899   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7900   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7901   return std::string(char_buffer, tpm2b.size);
7902 }
7903 
Serialize_TPMS_CONTEXT(const TPMS_CONTEXT & value,std::string * buffer)7904 TPM_RC Serialize_TPMS_CONTEXT(const TPMS_CONTEXT& value, std::string* buffer) {
7905   TPM_RC result = TPM_RC_SUCCESS;
7906   VLOG(3) << __func__;
7907 
7908   result = Serialize_UINT64(value.sequence, buffer);
7909   if (result) {
7910     return result;
7911   }
7912 
7913   result = Serialize_TPMI_DH_CONTEXT(value.saved_handle, buffer);
7914   if (result) {
7915     return result;
7916   }
7917 
7918   result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
7919   if (result) {
7920     return result;
7921   }
7922 
7923   result = Serialize_TPM2B_CONTEXT_DATA(value.context_blob, buffer);
7924   if (result) {
7925     return result;
7926   }
7927   return result;
7928 }
7929 
Parse_TPMS_CONTEXT(std::string * buffer,TPMS_CONTEXT * value,std::string * value_bytes)7930 TPM_RC Parse_TPMS_CONTEXT(std::string* buffer,
7931                           TPMS_CONTEXT* value,
7932                           std::string* value_bytes) {
7933   TPM_RC result = TPM_RC_SUCCESS;
7934   VLOG(3) << __func__;
7935 
7936   result = Parse_UINT64(buffer, &value->sequence, value_bytes);
7937   if (result) {
7938     return result;
7939   }
7940 
7941   result = Parse_TPMI_DH_CONTEXT(buffer, &value->saved_handle, value_bytes);
7942   if (result) {
7943     return result;
7944   }
7945 
7946   result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
7947   if (result) {
7948     return result;
7949   }
7950 
7951   result = Parse_TPM2B_CONTEXT_DATA(buffer, &value->context_blob, value_bytes);
7952   if (result) {
7953     return result;
7954   }
7955   return result;
7956 }
7957 
Serialize_TPMS_CREATION_DATA(const TPMS_CREATION_DATA & value,std::string * buffer)7958 TPM_RC Serialize_TPMS_CREATION_DATA(const TPMS_CREATION_DATA& value,
7959                                     std::string* buffer) {
7960   TPM_RC result = TPM_RC_SUCCESS;
7961   VLOG(3) << __func__;
7962 
7963   result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer);
7964   if (result) {
7965     return result;
7966   }
7967 
7968   result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer);
7969   if (result) {
7970     return result;
7971   }
7972 
7973   result = Serialize_TPMA_LOCALITY(value.locality, buffer);
7974   if (result) {
7975     return result;
7976   }
7977 
7978   result = Serialize_TPM_ALG_ID(value.parent_name_alg, buffer);
7979   if (result) {
7980     return result;
7981   }
7982 
7983   result = Serialize_TPM2B_NAME(value.parent_name, buffer);
7984   if (result) {
7985     return result;
7986   }
7987 
7988   result = Serialize_TPM2B_NAME(value.parent_qualified_name, buffer);
7989   if (result) {
7990     return result;
7991   }
7992 
7993   result = Serialize_TPM2B_DATA(value.outside_info, buffer);
7994   if (result) {
7995     return result;
7996   }
7997   return result;
7998 }
7999 
Parse_TPMS_CREATION_DATA(std::string * buffer,TPMS_CREATION_DATA * value,std::string * value_bytes)8000 TPM_RC Parse_TPMS_CREATION_DATA(std::string* buffer,
8001                                 TPMS_CREATION_DATA* value,
8002                                 std::string* value_bytes) {
8003   TPM_RC result = TPM_RC_SUCCESS;
8004   VLOG(3) << __func__;
8005 
8006   result = Parse_TPML_PCR_SELECTION(buffer, &value->pcr_select, value_bytes);
8007   if (result) {
8008     return result;
8009   }
8010 
8011   result = Parse_TPM2B_DIGEST(buffer, &value->pcr_digest, value_bytes);
8012   if (result) {
8013     return result;
8014   }
8015 
8016   result = Parse_TPMA_LOCALITY(buffer, &value->locality, value_bytes);
8017   if (result) {
8018     return result;
8019   }
8020 
8021   result = Parse_TPM_ALG_ID(buffer, &value->parent_name_alg, value_bytes);
8022   if (result) {
8023     return result;
8024   }
8025 
8026   result = Parse_TPM2B_NAME(buffer, &value->parent_name, value_bytes);
8027   if (result) {
8028     return result;
8029   }
8030 
8031   result = Parse_TPM2B_NAME(buffer, &value->parent_qualified_name, value_bytes);
8032   if (result) {
8033     return result;
8034   }
8035 
8036   result = Parse_TPM2B_DATA(buffer, &value->outside_info, value_bytes);
8037   if (result) {
8038     return result;
8039   }
8040   return result;
8041 }
8042 
Serialize_TPM2B_CREATION_DATA(const TPM2B_CREATION_DATA & value,std::string * buffer)8043 TPM_RC Serialize_TPM2B_CREATION_DATA(const TPM2B_CREATION_DATA& value,
8044                                      std::string* buffer) {
8045   TPM_RC result = TPM_RC_SUCCESS;
8046   VLOG(3) << __func__;
8047 
8048   std::string field_bytes;
8049   if (value.size) {
8050     if (value.size != sizeof(TPMS_CREATION_DATA)) {
8051       return TPM_RC_SIZE;
8052     }
8053     result = Serialize_TPMS_CREATION_DATA(value.creation_data, &field_bytes);
8054     if (result) {
8055       return result;
8056     }
8057   }
8058   std::string size_bytes;
8059   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
8060   if (result) {
8061     return result;
8062   }
8063   buffer->append(size_bytes + field_bytes);
8064   return result;
8065 }
8066 
Parse_TPM2B_CREATION_DATA(std::string * buffer,TPM2B_CREATION_DATA * value,std::string * value_bytes)8067 TPM_RC Parse_TPM2B_CREATION_DATA(std::string* buffer,
8068                                  TPM2B_CREATION_DATA* value,
8069                                  std::string* value_bytes) {
8070   TPM_RC result = TPM_RC_SUCCESS;
8071   VLOG(3) << __func__;
8072 
8073   UINT16 parsed_size = 0;
8074   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
8075   if (result) {
8076     return result;
8077   }
8078   if (!parsed_size) {
8079     value->size = 0;
8080   } else {
8081     value->size = sizeof(TPMS_CREATION_DATA);
8082     result =
8083         Parse_TPMS_CREATION_DATA(buffer, &value->creation_data, value_bytes);
8084     if (result) {
8085       return result;
8086     }
8087   }
8088   return result;
8089 }
8090 
Make_TPM2B_CREATION_DATA(const TPMS_CREATION_DATA & inner)8091 TPM2B_CREATION_DATA Make_TPM2B_CREATION_DATA(const TPMS_CREATION_DATA& inner) {
8092   TPM2B_CREATION_DATA tpm2b;
8093   tpm2b.size = sizeof(TPMS_CREATION_DATA);
8094   tpm2b.creation_data = inner;
8095   return tpm2b;
8096 }
8097 
SerializeCommand_Startup(const TPM_SU & startup_type,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8098 TPM_RC Tpm::SerializeCommand_Startup(
8099     const TPM_SU& startup_type,
8100     std::string* serialized_command,
8101     AuthorizationDelegate* authorization_delegate) {
8102   VLOG(3) << __func__;
8103   TPM_RC rc = TPM_RC_SUCCESS;
8104   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8105   UINT32 command_size = 10;  // Header size.
8106   std::string handle_section_bytes;
8107   std::string parameter_section_bytes;
8108   TPM_CC command_code = TPM_CC_Startup;
8109   bool is_command_parameter_encryption_possible = false;
8110   bool is_response_parameter_encryption_possible = false;
8111   std::string command_code_bytes;
8112   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8113   if (rc != TPM_RC_SUCCESS) {
8114     return rc;
8115   }
8116   std::string startup_type_bytes;
8117   rc = Serialize_TPM_SU(startup_type, &startup_type_bytes);
8118   if (rc != TPM_RC_SUCCESS) {
8119     return rc;
8120   }
8121   std::unique_ptr<crypto::SecureHash> hash(
8122       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8123   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8124   hash->Update(startup_type_bytes.data(), startup_type_bytes.size());
8125   parameter_section_bytes += startup_type_bytes;
8126   command_size += startup_type_bytes.size();
8127   std::string command_hash(32, 0);
8128   hash->Finish(std::data(command_hash), command_hash.size());
8129   std::string authorization_section_bytes;
8130   std::string authorization_size_bytes;
8131   if (authorization_delegate) {
8132     if (!authorization_delegate->GetCommandAuthorization(
8133             command_hash, is_command_parameter_encryption_possible,
8134             is_response_parameter_encryption_possible,
8135             &authorization_section_bytes)) {
8136       return TRUNKS_RC_AUTHORIZATION_FAILED;
8137     }
8138     if (!authorization_section_bytes.empty()) {
8139       tag = TPM_ST_SESSIONS;
8140       std::string tmp;
8141       rc = Serialize_UINT32(authorization_section_bytes.size(),
8142                             &authorization_size_bytes);
8143       if (rc != TPM_RC_SUCCESS) {
8144         return rc;
8145       }
8146       command_size +=
8147           authorization_size_bytes.size() + authorization_section_bytes.size();
8148     }
8149   }
8150   std::string tag_bytes;
8151   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8152   if (rc != TPM_RC_SUCCESS) {
8153     return rc;
8154   }
8155   std::string command_size_bytes;
8156   rc = Serialize_UINT32(command_size, &command_size_bytes);
8157   if (rc != TPM_RC_SUCCESS) {
8158     return rc;
8159   }
8160   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8161                         handle_section_bytes + authorization_size_bytes +
8162                         authorization_section_bytes + parameter_section_bytes;
8163   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8164   VLOG(2) << "Command: "
8165           << base::HexEncode(serialized_command->data(),
8166                              serialized_command->size());
8167   return TPM_RC_SUCCESS;
8168 }
8169 
ParseResponse_Startup(const std::string & response,AuthorizationDelegate * authorization_delegate)8170 TPM_RC Tpm::ParseResponse_Startup(
8171     const std::string& response,
8172     AuthorizationDelegate* authorization_delegate) {
8173   VLOG(3) << __func__;
8174   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8175   TPM_RC rc = TPM_RC_SUCCESS;
8176   std::string buffer(response);
8177   TPM_ST tag;
8178   std::string tag_bytes;
8179   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8180   if (rc != TPM_RC_SUCCESS) {
8181     return rc;
8182   }
8183   UINT32 response_size;
8184   std::string response_size_bytes;
8185   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8186   if (rc != TPM_RC_SUCCESS) {
8187     return rc;
8188   }
8189   TPM_RC response_code;
8190   std::string response_code_bytes;
8191   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8192   if (rc != TPM_RC_SUCCESS) {
8193     return rc;
8194   }
8195   if (response_size != response.size()) {
8196     return TPM_RC_SIZE;
8197   }
8198   if (response_code != TPM_RC_SUCCESS) {
8199     return response_code;
8200   }
8201   TPM_CC command_code = TPM_CC_Startup;
8202   std::string command_code_bytes;
8203   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8204   if (rc != TPM_RC_SUCCESS) {
8205     return rc;
8206   }
8207   std::string authorization_section_bytes;
8208   if (tag == TPM_ST_SESSIONS) {
8209     UINT32 parameter_section_size = buffer.size();
8210     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8211     if (rc != TPM_RC_SUCCESS) {
8212       return rc;
8213     }
8214     if (parameter_section_size > buffer.size()) {
8215       return TPM_RC_INSUFFICIENT;
8216     }
8217     authorization_section_bytes = buffer.substr(parameter_section_size);
8218     // Keep the parameter section in |buffer|.
8219     buffer.erase(parameter_section_size);
8220   }
8221   std::unique_ptr<crypto::SecureHash> hash(
8222       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8223   hash->Update(response_code_bytes.data(), response_code_bytes.size());
8224   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8225   hash->Update(buffer.data(), buffer.size());
8226   std::string response_hash(32, 0);
8227   hash->Finish(std::data(response_hash), response_hash.size());
8228   if (tag == TPM_ST_SESSIONS) {
8229     if (!authorization_delegate)
8230       return TRUNKS_RC_AUTHORIZATION_FAILED;
8231     if (!authorization_delegate->CheckResponseAuthorization(
8232             response_hash, authorization_section_bytes)) {
8233       return TRUNKS_RC_AUTHORIZATION_FAILED;
8234     }
8235   }
8236   return TPM_RC_SUCCESS;
8237 }
8238 
StartupErrorCallback(Tpm::StartupResponse callback,TPM_RC response_code)8239 void StartupErrorCallback(Tpm::StartupResponse callback, TPM_RC response_code) {
8240   VLOG(1) << __func__;
8241   std::move(callback).Run(response_code);
8242 }
8243 
StartupResponseParser(Tpm::StartupResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8244 void StartupResponseParser(Tpm::StartupResponse callback,
8245                            AuthorizationDelegate* authorization_delegate,
8246                            const std::string& response) {
8247   VLOG(1) << __func__;
8248   TPM_RC rc = Tpm::ParseResponse_Startup(response, authorization_delegate);
8249   if (rc != TPM_RC_SUCCESS) {
8250     base::OnceCallback<void(TPM_RC)> error_reporter =
8251         base::BindOnce(StartupErrorCallback, std::move(callback));
8252     std::move(error_reporter).Run(rc);
8253     return;
8254   }
8255   std::move(callback).Run(rc);
8256 }
8257 
Startup(const TPM_SU & startup_type,AuthorizationDelegate * authorization_delegate,StartupResponse callback)8258 void Tpm::Startup(const TPM_SU& startup_type,
8259                   AuthorizationDelegate* authorization_delegate,
8260                   StartupResponse callback) {
8261   VLOG(1) << __func__;
8262   std::string command;
8263   TPM_RC rc =
8264       SerializeCommand_Startup(startup_type, &command, authorization_delegate);
8265   if (rc != TPM_RC_SUCCESS) {
8266     base::OnceCallback<void(TPM_RC)> error_reporter =
8267         base::BindOnce(StartupErrorCallback, std::move(callback));
8268     std::move(error_reporter).Run(rc);
8269     return;
8270   }
8271   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8272       StartupResponseParser, std::move(callback), authorization_delegate);
8273   transceiver_->SendCommand(command, std::move(parser));
8274 }
8275 
StartupSync(const TPM_SU & startup_type,AuthorizationDelegate * authorization_delegate)8276 TPM_RC Tpm::StartupSync(const TPM_SU& startup_type,
8277                         AuthorizationDelegate* authorization_delegate) {
8278   VLOG(1) << __func__;
8279   std::string command;
8280   TPM_RC rc =
8281       SerializeCommand_Startup(startup_type, &command, authorization_delegate);
8282   if (rc != TPM_RC_SUCCESS) {
8283     return rc;
8284   }
8285   std::string response = transceiver_->SendCommandAndWait(command);
8286   rc = ParseResponse_Startup(response, authorization_delegate);
8287   return rc;
8288 }
8289 
SerializeCommand_Shutdown(const TPM_SU & shutdown_type,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8290 TPM_RC Tpm::SerializeCommand_Shutdown(
8291     const TPM_SU& shutdown_type,
8292     std::string* serialized_command,
8293     AuthorizationDelegate* authorization_delegate) {
8294   VLOG(3) << __func__;
8295   TPM_RC rc = TPM_RC_SUCCESS;
8296   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8297   UINT32 command_size = 10;  // Header size.
8298   std::string handle_section_bytes;
8299   std::string parameter_section_bytes;
8300   TPM_CC command_code = TPM_CC_Shutdown;
8301   bool is_command_parameter_encryption_possible = false;
8302   bool is_response_parameter_encryption_possible = false;
8303   std::string command_code_bytes;
8304   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8305   if (rc != TPM_RC_SUCCESS) {
8306     return rc;
8307   }
8308   std::string shutdown_type_bytes;
8309   rc = Serialize_TPM_SU(shutdown_type, &shutdown_type_bytes);
8310   if (rc != TPM_RC_SUCCESS) {
8311     return rc;
8312   }
8313   std::unique_ptr<crypto::SecureHash> hash(
8314       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8315   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8316   hash->Update(shutdown_type_bytes.data(), shutdown_type_bytes.size());
8317   parameter_section_bytes += shutdown_type_bytes;
8318   command_size += shutdown_type_bytes.size();
8319   std::string command_hash(32, 0);
8320   hash->Finish(std::data(command_hash), command_hash.size());
8321   std::string authorization_section_bytes;
8322   std::string authorization_size_bytes;
8323   if (authorization_delegate) {
8324     if (!authorization_delegate->GetCommandAuthorization(
8325             command_hash, is_command_parameter_encryption_possible,
8326             is_response_parameter_encryption_possible,
8327             &authorization_section_bytes)) {
8328       return TRUNKS_RC_AUTHORIZATION_FAILED;
8329     }
8330     if (!authorization_section_bytes.empty()) {
8331       tag = TPM_ST_SESSIONS;
8332       std::string tmp;
8333       rc = Serialize_UINT32(authorization_section_bytes.size(),
8334                             &authorization_size_bytes);
8335       if (rc != TPM_RC_SUCCESS) {
8336         return rc;
8337       }
8338       command_size +=
8339           authorization_size_bytes.size() + authorization_section_bytes.size();
8340     }
8341   }
8342   std::string tag_bytes;
8343   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8344   if (rc != TPM_RC_SUCCESS) {
8345     return rc;
8346   }
8347   std::string command_size_bytes;
8348   rc = Serialize_UINT32(command_size, &command_size_bytes);
8349   if (rc != TPM_RC_SUCCESS) {
8350     return rc;
8351   }
8352   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8353                         handle_section_bytes + authorization_size_bytes +
8354                         authorization_section_bytes + parameter_section_bytes;
8355   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8356   VLOG(2) << "Command: "
8357           << base::HexEncode(serialized_command->data(),
8358                              serialized_command->size());
8359   return TPM_RC_SUCCESS;
8360 }
8361 
ParseResponse_Shutdown(const std::string & response,AuthorizationDelegate * authorization_delegate)8362 TPM_RC Tpm::ParseResponse_Shutdown(
8363     const std::string& response,
8364     AuthorizationDelegate* authorization_delegate) {
8365   VLOG(3) << __func__;
8366   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8367   TPM_RC rc = TPM_RC_SUCCESS;
8368   std::string buffer(response);
8369   TPM_ST tag;
8370   std::string tag_bytes;
8371   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8372   if (rc != TPM_RC_SUCCESS) {
8373     return rc;
8374   }
8375   UINT32 response_size;
8376   std::string response_size_bytes;
8377   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8378   if (rc != TPM_RC_SUCCESS) {
8379     return rc;
8380   }
8381   TPM_RC response_code;
8382   std::string response_code_bytes;
8383   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8384   if (rc != TPM_RC_SUCCESS) {
8385     return rc;
8386   }
8387   if (response_size != response.size()) {
8388     return TPM_RC_SIZE;
8389   }
8390   if (response_code != TPM_RC_SUCCESS) {
8391     return response_code;
8392   }
8393   TPM_CC command_code = TPM_CC_Shutdown;
8394   std::string command_code_bytes;
8395   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8396   if (rc != TPM_RC_SUCCESS) {
8397     return rc;
8398   }
8399   std::string authorization_section_bytes;
8400   if (tag == TPM_ST_SESSIONS) {
8401     UINT32 parameter_section_size = buffer.size();
8402     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8403     if (rc != TPM_RC_SUCCESS) {
8404       return rc;
8405     }
8406     if (parameter_section_size > buffer.size()) {
8407       return TPM_RC_INSUFFICIENT;
8408     }
8409     authorization_section_bytes = buffer.substr(parameter_section_size);
8410     // Keep the parameter section in |buffer|.
8411     buffer.erase(parameter_section_size);
8412   }
8413   std::unique_ptr<crypto::SecureHash> hash(
8414       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8415   hash->Update(response_code_bytes.data(), response_code_bytes.size());
8416   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8417   hash->Update(buffer.data(), buffer.size());
8418   std::string response_hash(32, 0);
8419   hash->Finish(std::data(response_hash), response_hash.size());
8420   if (tag == TPM_ST_SESSIONS) {
8421     if (!authorization_delegate)
8422       return TRUNKS_RC_AUTHORIZATION_FAILED;
8423     if (!authorization_delegate->CheckResponseAuthorization(
8424             response_hash, authorization_section_bytes)) {
8425       return TRUNKS_RC_AUTHORIZATION_FAILED;
8426     }
8427   }
8428   return TPM_RC_SUCCESS;
8429 }
8430 
ShutdownErrorCallback(Tpm::ShutdownResponse callback,TPM_RC response_code)8431 void ShutdownErrorCallback(Tpm::ShutdownResponse callback,
8432                            TPM_RC response_code) {
8433   VLOG(1) << __func__;
8434   std::move(callback).Run(response_code);
8435 }
8436 
ShutdownResponseParser(Tpm::ShutdownResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8437 void ShutdownResponseParser(Tpm::ShutdownResponse callback,
8438                             AuthorizationDelegate* authorization_delegate,
8439                             const std::string& response) {
8440   VLOG(1) << __func__;
8441   TPM_RC rc = Tpm::ParseResponse_Shutdown(response, authorization_delegate);
8442   if (rc != TPM_RC_SUCCESS) {
8443     base::OnceCallback<void(TPM_RC)> error_reporter =
8444         base::BindOnce(ShutdownErrorCallback, std::move(callback));
8445     std::move(error_reporter).Run(rc);
8446     return;
8447   }
8448   std::move(callback).Run(rc);
8449 }
8450 
Shutdown(const TPM_SU & shutdown_type,AuthorizationDelegate * authorization_delegate,ShutdownResponse callback)8451 void Tpm::Shutdown(const TPM_SU& shutdown_type,
8452                    AuthorizationDelegate* authorization_delegate,
8453                    ShutdownResponse callback) {
8454   VLOG(1) << __func__;
8455   std::string command;
8456   TPM_RC rc = SerializeCommand_Shutdown(shutdown_type, &command,
8457                                         authorization_delegate);
8458   if (rc != TPM_RC_SUCCESS) {
8459     base::OnceCallback<void(TPM_RC)> error_reporter =
8460         base::BindOnce(ShutdownErrorCallback, std::move(callback));
8461     std::move(error_reporter).Run(rc);
8462     return;
8463   }
8464   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8465       ShutdownResponseParser, std::move(callback), authorization_delegate);
8466   transceiver_->SendCommand(command, std::move(parser));
8467 }
8468 
ShutdownSync(const TPM_SU & shutdown_type,AuthorizationDelegate * authorization_delegate)8469 TPM_RC Tpm::ShutdownSync(const TPM_SU& shutdown_type,
8470                          AuthorizationDelegate* authorization_delegate) {
8471   VLOG(1) << __func__;
8472   std::string command;
8473   TPM_RC rc = SerializeCommand_Shutdown(shutdown_type, &command,
8474                                         authorization_delegate);
8475   if (rc != TPM_RC_SUCCESS) {
8476     return rc;
8477   }
8478   std::string response = transceiver_->SendCommandAndWait(command);
8479   rc = ParseResponse_Shutdown(response, authorization_delegate);
8480   return rc;
8481 }
8482 
SerializeCommand_SelfTest(const TPMI_YES_NO & full_test,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8483 TPM_RC Tpm::SerializeCommand_SelfTest(
8484     const TPMI_YES_NO& full_test,
8485     std::string* serialized_command,
8486     AuthorizationDelegate* authorization_delegate) {
8487   VLOG(3) << __func__;
8488   TPM_RC rc = TPM_RC_SUCCESS;
8489   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8490   UINT32 command_size = 10;  // Header size.
8491   std::string handle_section_bytes;
8492   std::string parameter_section_bytes;
8493   TPM_CC command_code = TPM_CC_SelfTest;
8494   bool is_command_parameter_encryption_possible = false;
8495   bool is_response_parameter_encryption_possible = false;
8496   std::string command_code_bytes;
8497   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8498   if (rc != TPM_RC_SUCCESS) {
8499     return rc;
8500   }
8501   std::string full_test_bytes;
8502   rc = Serialize_TPMI_YES_NO(full_test, &full_test_bytes);
8503   if (rc != TPM_RC_SUCCESS) {
8504     return rc;
8505   }
8506   std::unique_ptr<crypto::SecureHash> hash(
8507       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8508   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8509   hash->Update(full_test_bytes.data(), full_test_bytes.size());
8510   parameter_section_bytes += full_test_bytes;
8511   command_size += full_test_bytes.size();
8512   std::string command_hash(32, 0);
8513   hash->Finish(std::data(command_hash), command_hash.size());
8514   std::string authorization_section_bytes;
8515   std::string authorization_size_bytes;
8516   if (authorization_delegate) {
8517     if (!authorization_delegate->GetCommandAuthorization(
8518             command_hash, is_command_parameter_encryption_possible,
8519             is_response_parameter_encryption_possible,
8520             &authorization_section_bytes)) {
8521       return TRUNKS_RC_AUTHORIZATION_FAILED;
8522     }
8523     if (!authorization_section_bytes.empty()) {
8524       tag = TPM_ST_SESSIONS;
8525       std::string tmp;
8526       rc = Serialize_UINT32(authorization_section_bytes.size(),
8527                             &authorization_size_bytes);
8528       if (rc != TPM_RC_SUCCESS) {
8529         return rc;
8530       }
8531       command_size +=
8532           authorization_size_bytes.size() + authorization_section_bytes.size();
8533     }
8534   }
8535   std::string tag_bytes;
8536   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8537   if (rc != TPM_RC_SUCCESS) {
8538     return rc;
8539   }
8540   std::string command_size_bytes;
8541   rc = Serialize_UINT32(command_size, &command_size_bytes);
8542   if (rc != TPM_RC_SUCCESS) {
8543     return rc;
8544   }
8545   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8546                         handle_section_bytes + authorization_size_bytes +
8547                         authorization_section_bytes + parameter_section_bytes;
8548   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8549   VLOG(2) << "Command: "
8550           << base::HexEncode(serialized_command->data(),
8551                              serialized_command->size());
8552   return TPM_RC_SUCCESS;
8553 }
8554 
ParseResponse_SelfTest(const std::string & response,AuthorizationDelegate * authorization_delegate)8555 TPM_RC Tpm::ParseResponse_SelfTest(
8556     const std::string& response,
8557     AuthorizationDelegate* authorization_delegate) {
8558   VLOG(3) << __func__;
8559   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8560   TPM_RC rc = TPM_RC_SUCCESS;
8561   std::string buffer(response);
8562   TPM_ST tag;
8563   std::string tag_bytes;
8564   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8565   if (rc != TPM_RC_SUCCESS) {
8566     return rc;
8567   }
8568   UINT32 response_size;
8569   std::string response_size_bytes;
8570   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8571   if (rc != TPM_RC_SUCCESS) {
8572     return rc;
8573   }
8574   TPM_RC response_code;
8575   std::string response_code_bytes;
8576   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8577   if (rc != TPM_RC_SUCCESS) {
8578     return rc;
8579   }
8580   if (response_size != response.size()) {
8581     return TPM_RC_SIZE;
8582   }
8583   if (response_code != TPM_RC_SUCCESS) {
8584     return response_code;
8585   }
8586   TPM_CC command_code = TPM_CC_SelfTest;
8587   std::string command_code_bytes;
8588   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8589   if (rc != TPM_RC_SUCCESS) {
8590     return rc;
8591   }
8592   std::string authorization_section_bytes;
8593   if (tag == TPM_ST_SESSIONS) {
8594     UINT32 parameter_section_size = buffer.size();
8595     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8596     if (rc != TPM_RC_SUCCESS) {
8597       return rc;
8598     }
8599     if (parameter_section_size > buffer.size()) {
8600       return TPM_RC_INSUFFICIENT;
8601     }
8602     authorization_section_bytes = buffer.substr(parameter_section_size);
8603     // Keep the parameter section in |buffer|.
8604     buffer.erase(parameter_section_size);
8605   }
8606   std::unique_ptr<crypto::SecureHash> hash(
8607       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8608   hash->Update(response_code_bytes.data(), response_code_bytes.size());
8609   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8610   hash->Update(buffer.data(), buffer.size());
8611   std::string response_hash(32, 0);
8612   hash->Finish(std::data(response_hash), response_hash.size());
8613   if (tag == TPM_ST_SESSIONS) {
8614     if (!authorization_delegate)
8615       return TRUNKS_RC_AUTHORIZATION_FAILED;
8616     if (!authorization_delegate->CheckResponseAuthorization(
8617             response_hash, authorization_section_bytes)) {
8618       return TRUNKS_RC_AUTHORIZATION_FAILED;
8619     }
8620   }
8621   return TPM_RC_SUCCESS;
8622 }
8623 
SelfTestErrorCallback(Tpm::SelfTestResponse callback,TPM_RC response_code)8624 void SelfTestErrorCallback(Tpm::SelfTestResponse callback,
8625                            TPM_RC response_code) {
8626   VLOG(1) << __func__;
8627   std::move(callback).Run(response_code);
8628 }
8629 
SelfTestResponseParser(Tpm::SelfTestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8630 void SelfTestResponseParser(Tpm::SelfTestResponse callback,
8631                             AuthorizationDelegate* authorization_delegate,
8632                             const std::string& response) {
8633   VLOG(1) << __func__;
8634   TPM_RC rc = Tpm::ParseResponse_SelfTest(response, authorization_delegate);
8635   if (rc != TPM_RC_SUCCESS) {
8636     base::OnceCallback<void(TPM_RC)> error_reporter =
8637         base::BindOnce(SelfTestErrorCallback, std::move(callback));
8638     std::move(error_reporter).Run(rc);
8639     return;
8640   }
8641   std::move(callback).Run(rc);
8642 }
8643 
SelfTest(const TPMI_YES_NO & full_test,AuthorizationDelegate * authorization_delegate,SelfTestResponse callback)8644 void Tpm::SelfTest(const TPMI_YES_NO& full_test,
8645                    AuthorizationDelegate* authorization_delegate,
8646                    SelfTestResponse callback) {
8647   VLOG(1) << __func__;
8648   std::string command;
8649   TPM_RC rc =
8650       SerializeCommand_SelfTest(full_test, &command, authorization_delegate);
8651   if (rc != TPM_RC_SUCCESS) {
8652     base::OnceCallback<void(TPM_RC)> error_reporter =
8653         base::BindOnce(SelfTestErrorCallback, std::move(callback));
8654     std::move(error_reporter).Run(rc);
8655     return;
8656   }
8657   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8658       SelfTestResponseParser, std::move(callback), authorization_delegate);
8659   transceiver_->SendCommand(command, std::move(parser));
8660 }
8661 
SelfTestSync(const TPMI_YES_NO & full_test,AuthorizationDelegate * authorization_delegate)8662 TPM_RC Tpm::SelfTestSync(const TPMI_YES_NO& full_test,
8663                          AuthorizationDelegate* authorization_delegate) {
8664   VLOG(1) << __func__;
8665   std::string command;
8666   TPM_RC rc =
8667       SerializeCommand_SelfTest(full_test, &command, authorization_delegate);
8668   if (rc != TPM_RC_SUCCESS) {
8669     return rc;
8670   }
8671   std::string response = transceiver_->SendCommandAndWait(command);
8672   rc = ParseResponse_SelfTest(response, authorization_delegate);
8673   return rc;
8674 }
8675 
SerializeCommand_IncrementalSelfTest(const TPML_ALG & to_test,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8676 TPM_RC Tpm::SerializeCommand_IncrementalSelfTest(
8677     const TPML_ALG& to_test,
8678     std::string* serialized_command,
8679     AuthorizationDelegate* authorization_delegate) {
8680   VLOG(3) << __func__;
8681   TPM_RC rc = TPM_RC_SUCCESS;
8682   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8683   UINT32 command_size = 10;  // Header size.
8684   std::string handle_section_bytes;
8685   std::string parameter_section_bytes;
8686   TPM_CC command_code = TPM_CC_IncrementalSelfTest;
8687   bool is_command_parameter_encryption_possible = false;
8688   bool is_response_parameter_encryption_possible = false;
8689   std::string command_code_bytes;
8690   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8691   if (rc != TPM_RC_SUCCESS) {
8692     return rc;
8693   }
8694   std::string to_test_bytes;
8695   rc = Serialize_TPML_ALG(to_test, &to_test_bytes);
8696   if (rc != TPM_RC_SUCCESS) {
8697     return rc;
8698   }
8699   std::unique_ptr<crypto::SecureHash> hash(
8700       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8701   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8702   hash->Update(to_test_bytes.data(), to_test_bytes.size());
8703   parameter_section_bytes += to_test_bytes;
8704   command_size += to_test_bytes.size();
8705   std::string command_hash(32, 0);
8706   hash->Finish(std::data(command_hash), command_hash.size());
8707   std::string authorization_section_bytes;
8708   std::string authorization_size_bytes;
8709   if (authorization_delegate) {
8710     if (!authorization_delegate->GetCommandAuthorization(
8711             command_hash, is_command_parameter_encryption_possible,
8712             is_response_parameter_encryption_possible,
8713             &authorization_section_bytes)) {
8714       return TRUNKS_RC_AUTHORIZATION_FAILED;
8715     }
8716     if (!authorization_section_bytes.empty()) {
8717       tag = TPM_ST_SESSIONS;
8718       std::string tmp;
8719       rc = Serialize_UINT32(authorization_section_bytes.size(),
8720                             &authorization_size_bytes);
8721       if (rc != TPM_RC_SUCCESS) {
8722         return rc;
8723       }
8724       command_size +=
8725           authorization_size_bytes.size() + authorization_section_bytes.size();
8726     }
8727   }
8728   std::string tag_bytes;
8729   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8730   if (rc != TPM_RC_SUCCESS) {
8731     return rc;
8732   }
8733   std::string command_size_bytes;
8734   rc = Serialize_UINT32(command_size, &command_size_bytes);
8735   if (rc != TPM_RC_SUCCESS) {
8736     return rc;
8737   }
8738   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8739                         handle_section_bytes + authorization_size_bytes +
8740                         authorization_section_bytes + parameter_section_bytes;
8741   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8742   VLOG(2) << "Command: "
8743           << base::HexEncode(serialized_command->data(),
8744                              serialized_command->size());
8745   return TPM_RC_SUCCESS;
8746 }
8747 
ParseResponse_IncrementalSelfTest(const std::string & response,TPML_ALG * to_do_list,AuthorizationDelegate * authorization_delegate)8748 TPM_RC Tpm::ParseResponse_IncrementalSelfTest(
8749     const std::string& response,
8750     TPML_ALG* to_do_list,
8751     AuthorizationDelegate* authorization_delegate) {
8752   VLOG(3) << __func__;
8753   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8754   TPM_RC rc = TPM_RC_SUCCESS;
8755   std::string buffer(response);
8756   TPM_ST tag;
8757   std::string tag_bytes;
8758   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8759   if (rc != TPM_RC_SUCCESS) {
8760     return rc;
8761   }
8762   UINT32 response_size;
8763   std::string response_size_bytes;
8764   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8765   if (rc != TPM_RC_SUCCESS) {
8766     return rc;
8767   }
8768   TPM_RC response_code;
8769   std::string response_code_bytes;
8770   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8771   if (rc != TPM_RC_SUCCESS) {
8772     return rc;
8773   }
8774   if (response_size != response.size()) {
8775     return TPM_RC_SIZE;
8776   }
8777   if (response_code != TPM_RC_SUCCESS) {
8778     return response_code;
8779   }
8780   TPM_CC command_code = TPM_CC_IncrementalSelfTest;
8781   std::string command_code_bytes;
8782   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8783   if (rc != TPM_RC_SUCCESS) {
8784     return rc;
8785   }
8786   std::string authorization_section_bytes;
8787   if (tag == TPM_ST_SESSIONS) {
8788     UINT32 parameter_section_size = buffer.size();
8789     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8790     if (rc != TPM_RC_SUCCESS) {
8791       return rc;
8792     }
8793     if (parameter_section_size > buffer.size()) {
8794       return TPM_RC_INSUFFICIENT;
8795     }
8796     authorization_section_bytes = buffer.substr(parameter_section_size);
8797     // Keep the parameter section in |buffer|.
8798     buffer.erase(parameter_section_size);
8799   }
8800   std::unique_ptr<crypto::SecureHash> hash(
8801       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8802   hash->Update(response_code_bytes.data(), response_code_bytes.size());
8803   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8804   hash->Update(buffer.data(), buffer.size());
8805   std::string response_hash(32, 0);
8806   hash->Finish(std::data(response_hash), response_hash.size());
8807   if (tag == TPM_ST_SESSIONS) {
8808     if (!authorization_delegate)
8809       return TRUNKS_RC_AUTHORIZATION_FAILED;
8810     if (!authorization_delegate->CheckResponseAuthorization(
8811             response_hash, authorization_section_bytes)) {
8812       return TRUNKS_RC_AUTHORIZATION_FAILED;
8813     }
8814   }
8815   std::string to_do_list_bytes;
8816   rc = Parse_TPML_ALG(&buffer, to_do_list, &to_do_list_bytes);
8817   if (rc != TPM_RC_SUCCESS) {
8818     return rc;
8819   }
8820   return TPM_RC_SUCCESS;
8821 }
8822 
IncrementalSelfTestErrorCallback(Tpm::IncrementalSelfTestResponse callback,TPM_RC response_code)8823 void IncrementalSelfTestErrorCallback(Tpm::IncrementalSelfTestResponse callback,
8824                                       TPM_RC response_code) {
8825   VLOG(1) << __func__;
8826   std::move(callback).Run(response_code, TPML_ALG());
8827 }
8828 
IncrementalSelfTestResponseParser(Tpm::IncrementalSelfTestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8829 void IncrementalSelfTestResponseParser(
8830     Tpm::IncrementalSelfTestResponse callback,
8831     AuthorizationDelegate* authorization_delegate,
8832     const std::string& response) {
8833   VLOG(1) << __func__;
8834   TPML_ALG to_do_list;
8835   TPM_RC rc = Tpm::ParseResponse_IncrementalSelfTest(response, &to_do_list,
8836                                                      authorization_delegate);
8837   if (rc != TPM_RC_SUCCESS) {
8838     base::OnceCallback<void(TPM_RC)> error_reporter =
8839         base::BindOnce(IncrementalSelfTestErrorCallback, std::move(callback));
8840     std::move(error_reporter).Run(rc);
8841     return;
8842   }
8843   std::move(callback).Run(rc, to_do_list);
8844 }
8845 
IncrementalSelfTest(const TPML_ALG & to_test,AuthorizationDelegate * authorization_delegate,IncrementalSelfTestResponse callback)8846 void Tpm::IncrementalSelfTest(const TPML_ALG& to_test,
8847                               AuthorizationDelegate* authorization_delegate,
8848                               IncrementalSelfTestResponse callback) {
8849   VLOG(1) << __func__;
8850   std::string command;
8851   TPM_RC rc = SerializeCommand_IncrementalSelfTest(to_test, &command,
8852                                                    authorization_delegate);
8853   if (rc != TPM_RC_SUCCESS) {
8854     base::OnceCallback<void(TPM_RC)> error_reporter =
8855         base::BindOnce(IncrementalSelfTestErrorCallback, std::move(callback));
8856     std::move(error_reporter).Run(rc);
8857     return;
8858   }
8859   base::OnceCallback<void(const std::string&)> parser =
8860       base::BindOnce(IncrementalSelfTestResponseParser, std::move(callback),
8861                      authorization_delegate);
8862   transceiver_->SendCommand(command, std::move(parser));
8863 }
8864 
IncrementalSelfTestSync(const TPML_ALG & to_test,TPML_ALG * to_do_list,AuthorizationDelegate * authorization_delegate)8865 TPM_RC Tpm::IncrementalSelfTestSync(
8866     const TPML_ALG& to_test,
8867     TPML_ALG* to_do_list,
8868     AuthorizationDelegate* authorization_delegate) {
8869   VLOG(1) << __func__;
8870   std::string command;
8871   TPM_RC rc = SerializeCommand_IncrementalSelfTest(to_test, &command,
8872                                                    authorization_delegate);
8873   if (rc != TPM_RC_SUCCESS) {
8874     return rc;
8875   }
8876   std::string response = transceiver_->SendCommandAndWait(command);
8877   rc = ParseResponse_IncrementalSelfTest(response, to_do_list,
8878                                          authorization_delegate);
8879   return rc;
8880 }
8881 
SerializeCommand_GetTestResult(std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8882 TPM_RC Tpm::SerializeCommand_GetTestResult(
8883     std::string* serialized_command,
8884     AuthorizationDelegate* authorization_delegate) {
8885   VLOG(3) << __func__;
8886   TPM_RC rc = TPM_RC_SUCCESS;
8887   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8888   UINT32 command_size = 10;  // Header size.
8889   std::string handle_section_bytes;
8890   std::string parameter_section_bytes;
8891   TPM_CC command_code = TPM_CC_GetTestResult;
8892   bool is_command_parameter_encryption_possible = false;
8893   bool is_response_parameter_encryption_possible = true;
8894   std::string command_code_bytes;
8895   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8896   if (rc != TPM_RC_SUCCESS) {
8897     return rc;
8898   }
8899   std::unique_ptr<crypto::SecureHash> hash(
8900       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8901   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8902   std::string command_hash(32, 0);
8903   hash->Finish(std::data(command_hash), command_hash.size());
8904   std::string authorization_section_bytes;
8905   std::string authorization_size_bytes;
8906   if (authorization_delegate) {
8907     if (!authorization_delegate->GetCommandAuthorization(
8908             command_hash, is_command_parameter_encryption_possible,
8909             is_response_parameter_encryption_possible,
8910             &authorization_section_bytes)) {
8911       return TRUNKS_RC_AUTHORIZATION_FAILED;
8912     }
8913     if (!authorization_section_bytes.empty()) {
8914       tag = TPM_ST_SESSIONS;
8915       std::string tmp;
8916       rc = Serialize_UINT32(authorization_section_bytes.size(),
8917                             &authorization_size_bytes);
8918       if (rc != TPM_RC_SUCCESS) {
8919         return rc;
8920       }
8921       command_size +=
8922           authorization_size_bytes.size() + authorization_section_bytes.size();
8923     }
8924   }
8925   std::string tag_bytes;
8926   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8927   if (rc != TPM_RC_SUCCESS) {
8928     return rc;
8929   }
8930   std::string command_size_bytes;
8931   rc = Serialize_UINT32(command_size, &command_size_bytes);
8932   if (rc != TPM_RC_SUCCESS) {
8933     return rc;
8934   }
8935   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8936                         handle_section_bytes + authorization_size_bytes +
8937                         authorization_section_bytes + parameter_section_bytes;
8938   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8939   VLOG(2) << "Command: "
8940           << base::HexEncode(serialized_command->data(),
8941                              serialized_command->size());
8942   return TPM_RC_SUCCESS;
8943 }
8944 
ParseResponse_GetTestResult(const std::string & response,TPM2B_MAX_BUFFER * out_data,TPM_RC * test_result,AuthorizationDelegate * authorization_delegate)8945 TPM_RC Tpm::ParseResponse_GetTestResult(
8946     const std::string& response,
8947     TPM2B_MAX_BUFFER* out_data,
8948     TPM_RC* test_result,
8949     AuthorizationDelegate* authorization_delegate) {
8950   VLOG(3) << __func__;
8951   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8952   TPM_RC rc = TPM_RC_SUCCESS;
8953   std::string buffer(response);
8954   TPM_ST tag;
8955   std::string tag_bytes;
8956   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8957   if (rc != TPM_RC_SUCCESS) {
8958     return rc;
8959   }
8960   UINT32 response_size;
8961   std::string response_size_bytes;
8962   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8963   if (rc != TPM_RC_SUCCESS) {
8964     return rc;
8965   }
8966   TPM_RC response_code;
8967   std::string response_code_bytes;
8968   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8969   if (rc != TPM_RC_SUCCESS) {
8970     return rc;
8971   }
8972   if (response_size != response.size()) {
8973     return TPM_RC_SIZE;
8974   }
8975   if (response_code != TPM_RC_SUCCESS) {
8976     return response_code;
8977   }
8978   TPM_CC command_code = TPM_CC_GetTestResult;
8979   std::string command_code_bytes;
8980   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8981   if (rc != TPM_RC_SUCCESS) {
8982     return rc;
8983   }
8984   std::string authorization_section_bytes;
8985   if (tag == TPM_ST_SESSIONS) {
8986     UINT32 parameter_section_size = buffer.size();
8987     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8988     if (rc != TPM_RC_SUCCESS) {
8989       return rc;
8990     }
8991     if (parameter_section_size > buffer.size()) {
8992       return TPM_RC_INSUFFICIENT;
8993     }
8994     authorization_section_bytes = buffer.substr(parameter_section_size);
8995     // Keep the parameter section in |buffer|.
8996     buffer.erase(parameter_section_size);
8997   }
8998   std::unique_ptr<crypto::SecureHash> hash(
8999       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9000   hash->Update(response_code_bytes.data(), response_code_bytes.size());
9001   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9002   hash->Update(buffer.data(), buffer.size());
9003   std::string response_hash(32, 0);
9004   hash->Finish(std::data(response_hash), response_hash.size());
9005   if (tag == TPM_ST_SESSIONS) {
9006     if (!authorization_delegate)
9007       return TRUNKS_RC_AUTHORIZATION_FAILED;
9008     if (!authorization_delegate->CheckResponseAuthorization(
9009             response_hash, authorization_section_bytes)) {
9010       return TRUNKS_RC_AUTHORIZATION_FAILED;
9011     }
9012   }
9013   if (tag == TPM_ST_SESSIONS) {
9014     if (!authorization_delegate)
9015       return TRUNKS_RC_AUTHORIZATION_FAILED;
9016 
9017     // Parse the encrypted parameter size.
9018     UINT16 size;
9019     std::string size_buffer = buffer.substr(0, 2);
9020     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9021       return result;
9022     }
9023     if (buffer.size() < 2 + size) {
9024       return TPM_RC_INSUFFICIENT;
9025     }
9026 
9027     // Decrypt just the parameter data, not the size.
9028     std::string decrypted_data = buffer.substr(2, size);
9029     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9030       return TRUNKS_RC_ENCRYPTION_FAILED;
9031     }
9032     buffer.replace(2, size, decrypted_data);
9033   }
9034   std::string out_data_bytes;
9035   rc = Parse_TPM2B_MAX_BUFFER(&buffer, out_data, &out_data_bytes);
9036   if (rc != TPM_RC_SUCCESS) {
9037     return rc;
9038   }
9039   std::string test_result_bytes;
9040   rc = Parse_TPM_RC(&buffer, test_result, &test_result_bytes);
9041   if (rc != TPM_RC_SUCCESS) {
9042     return rc;
9043   }
9044   return TPM_RC_SUCCESS;
9045 }
9046 
GetTestResultErrorCallback(Tpm::GetTestResultResponse callback,TPM_RC response_code)9047 void GetTestResultErrorCallback(Tpm::GetTestResultResponse callback,
9048                                 TPM_RC response_code) {
9049   VLOG(1) << __func__;
9050   std::move(callback).Run(response_code, TPM2B_MAX_BUFFER(), TPM_RC());
9051 }
9052 
GetTestResultResponseParser(Tpm::GetTestResultResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9053 void GetTestResultResponseParser(Tpm::GetTestResultResponse callback,
9054                                  AuthorizationDelegate* authorization_delegate,
9055                                  const std::string& response) {
9056   VLOG(1) << __func__;
9057   TPM2B_MAX_BUFFER out_data;
9058   TPM_RC test_result;
9059   TPM_RC rc = Tpm::ParseResponse_GetTestResult(
9060       response, &out_data, &test_result, authorization_delegate);
9061   if (rc != TPM_RC_SUCCESS) {
9062     base::OnceCallback<void(TPM_RC)> error_reporter =
9063         base::BindOnce(GetTestResultErrorCallback, std::move(callback));
9064     std::move(error_reporter).Run(rc);
9065     return;
9066   }
9067   std::move(callback).Run(rc, out_data, test_result);
9068 }
9069 
GetTestResult(AuthorizationDelegate * authorization_delegate,GetTestResultResponse callback)9070 void Tpm::GetTestResult(AuthorizationDelegate* authorization_delegate,
9071                         GetTestResultResponse callback) {
9072   VLOG(1) << __func__;
9073   std::string command;
9074   TPM_RC rc = SerializeCommand_GetTestResult(&command, authorization_delegate);
9075   if (rc != TPM_RC_SUCCESS) {
9076     base::OnceCallback<void(TPM_RC)> error_reporter =
9077         base::BindOnce(GetTestResultErrorCallback, std::move(callback));
9078     std::move(error_reporter).Run(rc);
9079     return;
9080   }
9081   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9082       GetTestResultResponseParser, std::move(callback), authorization_delegate);
9083   transceiver_->SendCommand(command, std::move(parser));
9084 }
9085 
GetTestResultSync(TPM2B_MAX_BUFFER * out_data,TPM_RC * test_result,AuthorizationDelegate * authorization_delegate)9086 TPM_RC Tpm::GetTestResultSync(TPM2B_MAX_BUFFER* out_data,
9087                               TPM_RC* test_result,
9088                               AuthorizationDelegate* authorization_delegate) {
9089   VLOG(1) << __func__;
9090   std::string command;
9091   TPM_RC rc = SerializeCommand_GetTestResult(&command, authorization_delegate);
9092   if (rc != TPM_RC_SUCCESS) {
9093     return rc;
9094   }
9095   std::string response = transceiver_->SendCommandAndWait(command);
9096   rc = ParseResponse_GetTestResult(response, out_data, test_result,
9097                                    authorization_delegate);
9098   return rc;
9099 }
9100 
SerializeCommand_StartAuthSession(const TPMI_DH_OBJECT & tpm_key,const std::string & tpm_key_name,const TPMI_DH_ENTITY & bind,const std::string & bind_name,const TPM2B_NONCE & nonce_caller,const TPM2B_ENCRYPTED_SECRET & encrypted_salt,const TPM_SE & session_type,const TPMT_SYM_DEF & symmetric,const TPMI_ALG_HASH & auth_hash,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9101 TPM_RC Tpm::SerializeCommand_StartAuthSession(
9102     const TPMI_DH_OBJECT& tpm_key,
9103     const std::string& tpm_key_name,
9104     const TPMI_DH_ENTITY& bind,
9105     const std::string& bind_name,
9106     const TPM2B_NONCE& nonce_caller,
9107     const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9108     const TPM_SE& session_type,
9109     const TPMT_SYM_DEF& symmetric,
9110     const TPMI_ALG_HASH& auth_hash,
9111     std::string* serialized_command,
9112     AuthorizationDelegate* authorization_delegate) {
9113   VLOG(3) << __func__;
9114   TPM_RC rc = TPM_RC_SUCCESS;
9115   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9116   UINT32 command_size = 10;  // Header size.
9117   std::string handle_section_bytes;
9118   std::string parameter_section_bytes;
9119   TPM_CC command_code = TPM_CC_StartAuthSession;
9120   bool is_command_parameter_encryption_possible = true;
9121   bool is_response_parameter_encryption_possible = true;
9122   std::string command_code_bytes;
9123   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9124   if (rc != TPM_RC_SUCCESS) {
9125     return rc;
9126   }
9127   std::string tpm_key_bytes;
9128   rc = Serialize_TPMI_DH_OBJECT(tpm_key, &tpm_key_bytes);
9129   if (rc != TPM_RC_SUCCESS) {
9130     return rc;
9131   }
9132   std::string bind_bytes;
9133   rc = Serialize_TPMI_DH_ENTITY(bind, &bind_bytes);
9134   if (rc != TPM_RC_SUCCESS) {
9135     return rc;
9136   }
9137   std::string nonce_caller_bytes;
9138   rc = Serialize_TPM2B_NONCE(nonce_caller, &nonce_caller_bytes);
9139   if (rc != TPM_RC_SUCCESS) {
9140     return rc;
9141   }
9142   std::string encrypted_salt_bytes;
9143   rc = Serialize_TPM2B_ENCRYPTED_SECRET(encrypted_salt, &encrypted_salt_bytes);
9144   if (rc != TPM_RC_SUCCESS) {
9145     return rc;
9146   }
9147   std::string session_type_bytes;
9148   rc = Serialize_TPM_SE(session_type, &session_type_bytes);
9149   if (rc != TPM_RC_SUCCESS) {
9150     return rc;
9151   }
9152   std::string symmetric_bytes;
9153   rc = Serialize_TPMT_SYM_DEF(symmetric, &symmetric_bytes);
9154   if (rc != TPM_RC_SUCCESS) {
9155     return rc;
9156   }
9157   std::string auth_hash_bytes;
9158   rc = Serialize_TPMI_ALG_HASH(auth_hash, &auth_hash_bytes);
9159   if (rc != TPM_RC_SUCCESS) {
9160     return rc;
9161   }
9162   if (authorization_delegate) {
9163     // Encrypt just the parameter data, not the size.
9164     std::string tmp = nonce_caller_bytes.substr(2);
9165     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9166       return TRUNKS_RC_ENCRYPTION_FAILED;
9167     }
9168     nonce_caller_bytes.replace(2, std::string::npos, tmp);
9169   }
9170   std::unique_ptr<crypto::SecureHash> hash(
9171       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9172   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9173   hash->Update(tpm_key_name.data(), tpm_key_name.size());
9174   handle_section_bytes += tpm_key_bytes;
9175   command_size += tpm_key_bytes.size();
9176   hash->Update(bind_name.data(), bind_name.size());
9177   handle_section_bytes += bind_bytes;
9178   command_size += bind_bytes.size();
9179   hash->Update(nonce_caller_bytes.data(), nonce_caller_bytes.size());
9180   parameter_section_bytes += nonce_caller_bytes;
9181   command_size += nonce_caller_bytes.size();
9182   hash->Update(encrypted_salt_bytes.data(), encrypted_salt_bytes.size());
9183   parameter_section_bytes += encrypted_salt_bytes;
9184   command_size += encrypted_salt_bytes.size();
9185   hash->Update(session_type_bytes.data(), session_type_bytes.size());
9186   parameter_section_bytes += session_type_bytes;
9187   command_size += session_type_bytes.size();
9188   hash->Update(symmetric_bytes.data(), symmetric_bytes.size());
9189   parameter_section_bytes += symmetric_bytes;
9190   command_size += symmetric_bytes.size();
9191   hash->Update(auth_hash_bytes.data(), auth_hash_bytes.size());
9192   parameter_section_bytes += auth_hash_bytes;
9193   command_size += auth_hash_bytes.size();
9194   std::string command_hash(32, 0);
9195   hash->Finish(std::data(command_hash), command_hash.size());
9196   std::string authorization_section_bytes;
9197   std::string authorization_size_bytes;
9198   if (authorization_delegate) {
9199     if (!authorization_delegate->GetCommandAuthorization(
9200             command_hash, is_command_parameter_encryption_possible,
9201             is_response_parameter_encryption_possible,
9202             &authorization_section_bytes)) {
9203       return TRUNKS_RC_AUTHORIZATION_FAILED;
9204     }
9205     if (!authorization_section_bytes.empty()) {
9206       tag = TPM_ST_SESSIONS;
9207       std::string tmp;
9208       rc = Serialize_UINT32(authorization_section_bytes.size(),
9209                             &authorization_size_bytes);
9210       if (rc != TPM_RC_SUCCESS) {
9211         return rc;
9212       }
9213       command_size +=
9214           authorization_size_bytes.size() + authorization_section_bytes.size();
9215     }
9216   }
9217   std::string tag_bytes;
9218   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9219   if (rc != TPM_RC_SUCCESS) {
9220     return rc;
9221   }
9222   std::string command_size_bytes;
9223   rc = Serialize_UINT32(command_size, &command_size_bytes);
9224   if (rc != TPM_RC_SUCCESS) {
9225     return rc;
9226   }
9227   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9228                         handle_section_bytes + authorization_size_bytes +
9229                         authorization_section_bytes + parameter_section_bytes;
9230   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9231   VLOG(2) << "Command: "
9232           << base::HexEncode(serialized_command->data(),
9233                              serialized_command->size());
9234   return TPM_RC_SUCCESS;
9235 }
9236 
ParseResponse_StartAuthSession(const std::string & response,TPMI_SH_AUTH_SESSION * session_handle,TPM2B_NONCE * nonce_tpm,AuthorizationDelegate * authorization_delegate)9237 TPM_RC Tpm::ParseResponse_StartAuthSession(
9238     const std::string& response,
9239     TPMI_SH_AUTH_SESSION* session_handle,
9240     TPM2B_NONCE* nonce_tpm,
9241     AuthorizationDelegate* authorization_delegate) {
9242   VLOG(3) << __func__;
9243   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9244   TPM_RC rc = TPM_RC_SUCCESS;
9245   std::string buffer(response);
9246   TPM_ST tag;
9247   std::string tag_bytes;
9248   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9249   if (rc != TPM_RC_SUCCESS) {
9250     return rc;
9251   }
9252   UINT32 response_size;
9253   std::string response_size_bytes;
9254   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9255   if (rc != TPM_RC_SUCCESS) {
9256     return rc;
9257   }
9258   TPM_RC response_code;
9259   std::string response_code_bytes;
9260   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9261   if (rc != TPM_RC_SUCCESS) {
9262     return rc;
9263   }
9264   if (response_size != response.size()) {
9265     return TPM_RC_SIZE;
9266   }
9267   if (response_code != TPM_RC_SUCCESS) {
9268     return response_code;
9269   }
9270   std::string session_handle_bytes;
9271   rc = Parse_TPMI_SH_AUTH_SESSION(&buffer, session_handle,
9272                                   &session_handle_bytes);
9273   if (rc != TPM_RC_SUCCESS) {
9274     return rc;
9275   }
9276   TPM_CC command_code = TPM_CC_StartAuthSession;
9277   std::string command_code_bytes;
9278   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9279   if (rc != TPM_RC_SUCCESS) {
9280     return rc;
9281   }
9282   std::string authorization_section_bytes;
9283   if (tag == TPM_ST_SESSIONS) {
9284     UINT32 parameter_section_size = buffer.size();
9285     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
9286     if (rc != TPM_RC_SUCCESS) {
9287       return rc;
9288     }
9289     if (parameter_section_size > buffer.size()) {
9290       return TPM_RC_INSUFFICIENT;
9291     }
9292     authorization_section_bytes = buffer.substr(parameter_section_size);
9293     // Keep the parameter section in |buffer|.
9294     buffer.erase(parameter_section_size);
9295   }
9296   std::unique_ptr<crypto::SecureHash> hash(
9297       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9298   hash->Update(response_code_bytes.data(), response_code_bytes.size());
9299   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9300   hash->Update(buffer.data(), buffer.size());
9301   std::string response_hash(32, 0);
9302   hash->Finish(std::data(response_hash), response_hash.size());
9303   if (tag == TPM_ST_SESSIONS) {
9304     if (!authorization_delegate)
9305       return TRUNKS_RC_AUTHORIZATION_FAILED;
9306     if (!authorization_delegate->CheckResponseAuthorization(
9307             response_hash, authorization_section_bytes)) {
9308       return TRUNKS_RC_AUTHORIZATION_FAILED;
9309     }
9310   }
9311   if (tag == TPM_ST_SESSIONS) {
9312     if (!authorization_delegate)
9313       return TRUNKS_RC_AUTHORIZATION_FAILED;
9314 
9315     // Parse the encrypted parameter size.
9316     UINT16 size;
9317     std::string size_buffer = buffer.substr(0, 2);
9318     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9319       return result;
9320     }
9321     if (buffer.size() < 2 + size) {
9322       return TPM_RC_INSUFFICIENT;
9323     }
9324 
9325     // Decrypt just the parameter data, not the size.
9326     std::string decrypted_data = buffer.substr(2, size);
9327     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9328       return TRUNKS_RC_ENCRYPTION_FAILED;
9329     }
9330     buffer.replace(2, size, decrypted_data);
9331   }
9332   std::string nonce_tpm_bytes;
9333   rc = Parse_TPM2B_NONCE(&buffer, nonce_tpm, &nonce_tpm_bytes);
9334   if (rc != TPM_RC_SUCCESS) {
9335     return rc;
9336   }
9337   return TPM_RC_SUCCESS;
9338 }
9339 
StartAuthSessionErrorCallback(Tpm::StartAuthSessionResponse callback,TPM_RC response_code)9340 void StartAuthSessionErrorCallback(Tpm::StartAuthSessionResponse callback,
9341                                    TPM_RC response_code) {
9342   VLOG(1) << __func__;
9343   std::move(callback).Run(response_code, TPMI_SH_AUTH_SESSION(), TPM2B_NONCE());
9344 }
9345 
StartAuthSessionResponseParser(Tpm::StartAuthSessionResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9346 void StartAuthSessionResponseParser(
9347     Tpm::StartAuthSessionResponse callback,
9348     AuthorizationDelegate* authorization_delegate,
9349     const std::string& response) {
9350   VLOG(1) << __func__;
9351   TPMI_SH_AUTH_SESSION session_handle;
9352   TPM2B_NONCE nonce_tpm;
9353   TPM_RC rc = Tpm::ParseResponse_StartAuthSession(
9354       response, &session_handle, &nonce_tpm, authorization_delegate);
9355   if (rc != TPM_RC_SUCCESS) {
9356     base::OnceCallback<void(TPM_RC)> error_reporter =
9357         base::BindOnce(StartAuthSessionErrorCallback, std::move(callback));
9358     std::move(error_reporter).Run(rc);
9359     return;
9360   }
9361   std::move(callback).Run(rc, session_handle, nonce_tpm);
9362 }
9363 
StartAuthSession(const TPMI_DH_OBJECT & tpm_key,const std::string & tpm_key_name,const TPMI_DH_ENTITY & bind,const std::string & bind_name,const TPM2B_NONCE & nonce_caller,const TPM2B_ENCRYPTED_SECRET & encrypted_salt,const TPM_SE & session_type,const TPMT_SYM_DEF & symmetric,const TPMI_ALG_HASH & auth_hash,AuthorizationDelegate * authorization_delegate,StartAuthSessionResponse callback)9364 void Tpm::StartAuthSession(const TPMI_DH_OBJECT& tpm_key,
9365                            const std::string& tpm_key_name,
9366                            const TPMI_DH_ENTITY& bind,
9367                            const std::string& bind_name,
9368                            const TPM2B_NONCE& nonce_caller,
9369                            const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9370                            const TPM_SE& session_type,
9371                            const TPMT_SYM_DEF& symmetric,
9372                            const TPMI_ALG_HASH& auth_hash,
9373                            AuthorizationDelegate* authorization_delegate,
9374                            StartAuthSessionResponse callback) {
9375   VLOG(1) << __func__;
9376   std::string command;
9377   TPM_RC rc = SerializeCommand_StartAuthSession(
9378       tpm_key, tpm_key_name, bind, bind_name, nonce_caller, encrypted_salt,
9379       session_type, symmetric, auth_hash, &command, authorization_delegate);
9380   if (rc != TPM_RC_SUCCESS) {
9381     base::OnceCallback<void(TPM_RC)> error_reporter =
9382         base::BindOnce(StartAuthSessionErrorCallback, std::move(callback));
9383     std::move(error_reporter).Run(rc);
9384     return;
9385   }
9386   base::OnceCallback<void(const std::string&)> parser =
9387       base::BindOnce(StartAuthSessionResponseParser, std::move(callback),
9388                      authorization_delegate);
9389   transceiver_->SendCommand(command, std::move(parser));
9390 }
9391 
StartAuthSessionSync(const TPMI_DH_OBJECT & tpm_key,const std::string & tpm_key_name,const TPMI_DH_ENTITY & bind,const std::string & bind_name,const TPM2B_NONCE & nonce_caller,const TPM2B_ENCRYPTED_SECRET & encrypted_salt,const TPM_SE & session_type,const TPMT_SYM_DEF & symmetric,const TPMI_ALG_HASH & auth_hash,TPMI_SH_AUTH_SESSION * session_handle,TPM2B_NONCE * nonce_tpm,AuthorizationDelegate * authorization_delegate)9392 TPM_RC Tpm::StartAuthSessionSync(
9393     const TPMI_DH_OBJECT& tpm_key,
9394     const std::string& tpm_key_name,
9395     const TPMI_DH_ENTITY& bind,
9396     const std::string& bind_name,
9397     const TPM2B_NONCE& nonce_caller,
9398     const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9399     const TPM_SE& session_type,
9400     const TPMT_SYM_DEF& symmetric,
9401     const TPMI_ALG_HASH& auth_hash,
9402     TPMI_SH_AUTH_SESSION* session_handle,
9403     TPM2B_NONCE* nonce_tpm,
9404     AuthorizationDelegate* authorization_delegate) {
9405   VLOG(1) << __func__;
9406   std::string command;
9407   TPM_RC rc = SerializeCommand_StartAuthSession(
9408       tpm_key, tpm_key_name, bind, bind_name, nonce_caller, encrypted_salt,
9409       session_type, symmetric, auth_hash, &command, authorization_delegate);
9410   if (rc != TPM_RC_SUCCESS) {
9411     return rc;
9412   }
9413   std::string response = transceiver_->SendCommandAndWait(command);
9414   rc = ParseResponse_StartAuthSession(response, session_handle, nonce_tpm,
9415                                       authorization_delegate);
9416   return rc;
9417 }
9418 
SerializeCommand_PolicyRestart(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9419 TPM_RC Tpm::SerializeCommand_PolicyRestart(
9420     const TPMI_SH_POLICY& session_handle,
9421     const std::string& session_handle_name,
9422     std::string* serialized_command,
9423     AuthorizationDelegate* authorization_delegate) {
9424   VLOG(3) << __func__;
9425   TPM_RC rc = TPM_RC_SUCCESS;
9426   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9427   UINT32 command_size = 10;  // Header size.
9428   std::string handle_section_bytes;
9429   std::string parameter_section_bytes;
9430   TPM_CC command_code = TPM_CC_PolicyRestart;
9431   bool is_command_parameter_encryption_possible = false;
9432   bool is_response_parameter_encryption_possible = false;
9433   std::string command_code_bytes;
9434   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9435   if (rc != TPM_RC_SUCCESS) {
9436     return rc;
9437   }
9438   std::string session_handle_bytes;
9439   rc = Serialize_TPMI_SH_POLICY(session_handle, &session_handle_bytes);
9440   if (rc != TPM_RC_SUCCESS) {
9441     return rc;
9442   }
9443   std::unique_ptr<crypto::SecureHash> hash(
9444       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9445   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9446   hash->Update(session_handle_name.data(), session_handle_name.size());
9447   handle_section_bytes += session_handle_bytes;
9448   command_size += session_handle_bytes.size();
9449   std::string command_hash(32, 0);
9450   hash->Finish(std::data(command_hash), command_hash.size());
9451   std::string authorization_section_bytes;
9452   std::string authorization_size_bytes;
9453   if (authorization_delegate) {
9454     if (!authorization_delegate->GetCommandAuthorization(
9455             command_hash, is_command_parameter_encryption_possible,
9456             is_response_parameter_encryption_possible,
9457             &authorization_section_bytes)) {
9458       return TRUNKS_RC_AUTHORIZATION_FAILED;
9459     }
9460     if (!authorization_section_bytes.empty()) {
9461       tag = TPM_ST_SESSIONS;
9462       std::string tmp;
9463       rc = Serialize_UINT32(authorization_section_bytes.size(),
9464                             &authorization_size_bytes);
9465       if (rc != TPM_RC_SUCCESS) {
9466         return rc;
9467       }
9468       command_size +=
9469           authorization_size_bytes.size() + authorization_section_bytes.size();
9470     }
9471   }
9472   std::string tag_bytes;
9473   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9474   if (rc != TPM_RC_SUCCESS) {
9475     return rc;
9476   }
9477   std::string command_size_bytes;
9478   rc = Serialize_UINT32(command_size, &command_size_bytes);
9479   if (rc != TPM_RC_SUCCESS) {
9480     return rc;
9481   }
9482   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9483                         handle_section_bytes + authorization_size_bytes +
9484                         authorization_section_bytes + parameter_section_bytes;
9485   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9486   VLOG(2) << "Command: "
9487           << base::HexEncode(serialized_command->data(),
9488                              serialized_command->size());
9489   return TPM_RC_SUCCESS;
9490 }
9491 
ParseResponse_PolicyRestart(const std::string & response,AuthorizationDelegate * authorization_delegate)9492 TPM_RC Tpm::ParseResponse_PolicyRestart(
9493     const std::string& response,
9494     AuthorizationDelegate* authorization_delegate) {
9495   VLOG(3) << __func__;
9496   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9497   TPM_RC rc = TPM_RC_SUCCESS;
9498   std::string buffer(response);
9499   TPM_ST tag;
9500   std::string tag_bytes;
9501   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9502   if (rc != TPM_RC_SUCCESS) {
9503     return rc;
9504   }
9505   UINT32 response_size;
9506   std::string response_size_bytes;
9507   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9508   if (rc != TPM_RC_SUCCESS) {
9509     return rc;
9510   }
9511   TPM_RC response_code;
9512   std::string response_code_bytes;
9513   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9514   if (rc != TPM_RC_SUCCESS) {
9515     return rc;
9516   }
9517   if (response_size != response.size()) {
9518     return TPM_RC_SIZE;
9519   }
9520   if (response_code != TPM_RC_SUCCESS) {
9521     return response_code;
9522   }
9523   TPM_CC command_code = TPM_CC_PolicyRestart;
9524   std::string command_code_bytes;
9525   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9526   if (rc != TPM_RC_SUCCESS) {
9527     return rc;
9528   }
9529   std::string authorization_section_bytes;
9530   if (tag == TPM_ST_SESSIONS) {
9531     UINT32 parameter_section_size = buffer.size();
9532     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
9533     if (rc != TPM_RC_SUCCESS) {
9534       return rc;
9535     }
9536     if (parameter_section_size > buffer.size()) {
9537       return TPM_RC_INSUFFICIENT;
9538     }
9539     authorization_section_bytes = buffer.substr(parameter_section_size);
9540     // Keep the parameter section in |buffer|.
9541     buffer.erase(parameter_section_size);
9542   }
9543   std::unique_ptr<crypto::SecureHash> hash(
9544       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9545   hash->Update(response_code_bytes.data(), response_code_bytes.size());
9546   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9547   hash->Update(buffer.data(), buffer.size());
9548   std::string response_hash(32, 0);
9549   hash->Finish(std::data(response_hash), response_hash.size());
9550   if (tag == TPM_ST_SESSIONS) {
9551     if (!authorization_delegate)
9552       return TRUNKS_RC_AUTHORIZATION_FAILED;
9553     if (!authorization_delegate->CheckResponseAuthorization(
9554             response_hash, authorization_section_bytes)) {
9555       return TRUNKS_RC_AUTHORIZATION_FAILED;
9556     }
9557   }
9558   return TPM_RC_SUCCESS;
9559 }
9560 
PolicyRestartErrorCallback(Tpm::PolicyRestartResponse callback,TPM_RC response_code)9561 void PolicyRestartErrorCallback(Tpm::PolicyRestartResponse callback,
9562                                 TPM_RC response_code) {
9563   VLOG(1) << __func__;
9564   std::move(callback).Run(response_code);
9565 }
9566 
PolicyRestartResponseParser(Tpm::PolicyRestartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9567 void PolicyRestartResponseParser(Tpm::PolicyRestartResponse callback,
9568                                  AuthorizationDelegate* authorization_delegate,
9569                                  const std::string& response) {
9570   VLOG(1) << __func__;
9571   TPM_RC rc =
9572       Tpm::ParseResponse_PolicyRestart(response, authorization_delegate);
9573   if (rc != TPM_RC_SUCCESS) {
9574     base::OnceCallback<void(TPM_RC)> error_reporter =
9575         base::BindOnce(PolicyRestartErrorCallback, std::move(callback));
9576     std::move(error_reporter).Run(rc);
9577     return;
9578   }
9579   std::move(callback).Run(rc);
9580 }
9581 
PolicyRestart(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,AuthorizationDelegate * authorization_delegate,PolicyRestartResponse callback)9582 void Tpm::PolicyRestart(const TPMI_SH_POLICY& session_handle,
9583                         const std::string& session_handle_name,
9584                         AuthorizationDelegate* authorization_delegate,
9585                         PolicyRestartResponse callback) {
9586   VLOG(1) << __func__;
9587   std::string command;
9588   TPM_RC rc = SerializeCommand_PolicyRestart(
9589       session_handle, session_handle_name, &command, authorization_delegate);
9590   if (rc != TPM_RC_SUCCESS) {
9591     base::OnceCallback<void(TPM_RC)> error_reporter =
9592         base::BindOnce(PolicyRestartErrorCallback, std::move(callback));
9593     std::move(error_reporter).Run(rc);
9594     return;
9595   }
9596   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9597       PolicyRestartResponseParser, std::move(callback), authorization_delegate);
9598   transceiver_->SendCommand(command, std::move(parser));
9599 }
9600 
PolicyRestartSync(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,AuthorizationDelegate * authorization_delegate)9601 TPM_RC Tpm::PolicyRestartSync(const TPMI_SH_POLICY& session_handle,
9602                               const std::string& session_handle_name,
9603                               AuthorizationDelegate* authorization_delegate) {
9604   VLOG(1) << __func__;
9605   std::string command;
9606   TPM_RC rc = SerializeCommand_PolicyRestart(
9607       session_handle, session_handle_name, &command, authorization_delegate);
9608   if (rc != TPM_RC_SUCCESS) {
9609     return rc;
9610   }
9611   std::string response = transceiver_->SendCommandAndWait(command);
9612   rc = ParseResponse_PolicyRestart(response, authorization_delegate);
9613   return rc;
9614 }
9615 
SerializeCommand_Create(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9616 TPM_RC Tpm::SerializeCommand_Create(
9617     const TPMI_DH_OBJECT& parent_handle,
9618     const std::string& parent_handle_name,
9619     const TPM2B_SENSITIVE_CREATE& in_sensitive,
9620     const TPM2B_PUBLIC& in_public,
9621     const TPM2B_DATA& outside_info,
9622     const TPML_PCR_SELECTION& creation_pcr,
9623     std::string* serialized_command,
9624     AuthorizationDelegate* authorization_delegate) {
9625   VLOG(3) << __func__;
9626   TPM_RC rc = TPM_RC_SUCCESS;
9627   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9628   UINT32 command_size = 10;  // Header size.
9629   std::string handle_section_bytes;
9630   std::string parameter_section_bytes;
9631   TPM_CC command_code = TPM_CC_Create;
9632   bool is_command_parameter_encryption_possible = true;
9633   bool is_response_parameter_encryption_possible = true;
9634   std::string command_code_bytes;
9635   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9636   if (rc != TPM_RC_SUCCESS) {
9637     return rc;
9638   }
9639   std::string parent_handle_bytes;
9640   rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
9641   if (rc != TPM_RC_SUCCESS) {
9642     return rc;
9643   }
9644   std::string in_sensitive_bytes;
9645   rc = Serialize_TPM2B_SENSITIVE_CREATE(in_sensitive, &in_sensitive_bytes);
9646   if (rc != TPM_RC_SUCCESS) {
9647     return rc;
9648   }
9649   std::string in_public_bytes;
9650   rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
9651   if (rc != TPM_RC_SUCCESS) {
9652     return rc;
9653   }
9654   std::string outside_info_bytes;
9655   rc = Serialize_TPM2B_DATA(outside_info, &outside_info_bytes);
9656   if (rc != TPM_RC_SUCCESS) {
9657     return rc;
9658   }
9659   std::string creation_pcr_bytes;
9660   rc = Serialize_TPML_PCR_SELECTION(creation_pcr, &creation_pcr_bytes);
9661   if (rc != TPM_RC_SUCCESS) {
9662     return rc;
9663   }
9664   if (authorization_delegate) {
9665     // Encrypt just the parameter data, not the size.
9666     std::string tmp = in_sensitive_bytes.substr(2);
9667     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9668       return TRUNKS_RC_ENCRYPTION_FAILED;
9669     }
9670     in_sensitive_bytes.replace(2, std::string::npos, tmp);
9671   }
9672   std::unique_ptr<crypto::SecureHash> hash(
9673       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9674   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9675   hash->Update(parent_handle_name.data(), parent_handle_name.size());
9676   handle_section_bytes += parent_handle_bytes;
9677   command_size += parent_handle_bytes.size();
9678   hash->Update(in_sensitive_bytes.data(), in_sensitive_bytes.size());
9679   parameter_section_bytes += in_sensitive_bytes;
9680   command_size += in_sensitive_bytes.size();
9681   hash->Update(in_public_bytes.data(), in_public_bytes.size());
9682   parameter_section_bytes += in_public_bytes;
9683   command_size += in_public_bytes.size();
9684   hash->Update(outside_info_bytes.data(), outside_info_bytes.size());
9685   parameter_section_bytes += outside_info_bytes;
9686   command_size += outside_info_bytes.size();
9687   hash->Update(creation_pcr_bytes.data(), creation_pcr_bytes.size());
9688   parameter_section_bytes += creation_pcr_bytes;
9689   command_size += creation_pcr_bytes.size();
9690   std::string command_hash(32, 0);
9691   hash->Finish(std::data(command_hash), command_hash.size());
9692   std::string authorization_section_bytes;
9693   std::string authorization_size_bytes;
9694   if (authorization_delegate) {
9695     if (!authorization_delegate->GetCommandAuthorization(
9696             command_hash, is_command_parameter_encryption_possible,
9697             is_response_parameter_encryption_possible,
9698             &authorization_section_bytes)) {
9699       return TRUNKS_RC_AUTHORIZATION_FAILED;
9700     }
9701     if (!authorization_section_bytes.empty()) {
9702       tag = TPM_ST_SESSIONS;
9703       std::string tmp;
9704       rc = Serialize_UINT32(authorization_section_bytes.size(),
9705                             &authorization_size_bytes);
9706       if (rc != TPM_RC_SUCCESS) {
9707         return rc;
9708       }
9709       command_size +=
9710           authorization_size_bytes.size() + authorization_section_bytes.size();
9711     }
9712   }
9713   std::string tag_bytes;
9714   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9715   if (rc != TPM_RC_SUCCESS) {
9716     return rc;
9717   }
9718   std::string command_size_bytes;
9719   rc = Serialize_UINT32(command_size, &command_size_bytes);
9720   if (rc != TPM_RC_SUCCESS) {
9721     return rc;
9722   }
9723   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9724                         handle_section_bytes + authorization_size_bytes +
9725                         authorization_section_bytes + parameter_section_bytes;
9726   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9727   VLOG(2) << "Command: "
9728           << base::HexEncode(serialized_command->data(),
9729                              serialized_command->size());
9730   return TPM_RC_SUCCESS;
9731 }
9732 
ParseResponse_Create(const std::string & response,TPM2B_PRIVATE * out_private,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,AuthorizationDelegate * authorization_delegate)9733 TPM_RC Tpm::ParseResponse_Create(
9734     const std::string& response,
9735     TPM2B_PRIVATE* out_private,
9736     TPM2B_PUBLIC* out_public,
9737     TPM2B_CREATION_DATA* creation_data,
9738     TPM2B_DIGEST* creation_hash,
9739     TPMT_TK_CREATION* creation_ticket,
9740     AuthorizationDelegate* authorization_delegate) {
9741   VLOG(3) << __func__;
9742   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9743   TPM_RC rc = TPM_RC_SUCCESS;
9744   std::string buffer(response);
9745   TPM_ST tag;
9746   std::string tag_bytes;
9747   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9748   if (rc != TPM_RC_SUCCESS) {
9749     return rc;
9750   }
9751   UINT32 response_size;
9752   std::string response_size_bytes;
9753   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9754   if (rc != TPM_RC_SUCCESS) {
9755     return rc;
9756   }
9757   TPM_RC response_code;
9758   std::string response_code_bytes;
9759   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9760   if (rc != TPM_RC_SUCCESS) {
9761     return rc;
9762   }
9763   if (response_size != response.size()) {
9764     return TPM_RC_SIZE;
9765   }
9766   if (response_code != TPM_RC_SUCCESS) {
9767     return response_code;
9768   }
9769   TPM_CC command_code = TPM_CC_Create;
9770   std::string command_code_bytes;
9771   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9772   if (rc != TPM_RC_SUCCESS) {
9773     return rc;
9774   }
9775   std::string authorization_section_bytes;
9776   if (tag == TPM_ST_SESSIONS) {
9777     UINT32 parameter_section_size = buffer.size();
9778     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
9779     if (rc != TPM_RC_SUCCESS) {
9780       return rc;
9781     }
9782     if (parameter_section_size > buffer.size()) {
9783       return TPM_RC_INSUFFICIENT;
9784     }
9785     authorization_section_bytes = buffer.substr(parameter_section_size);
9786     // Keep the parameter section in |buffer|.
9787     buffer.erase(parameter_section_size);
9788   }
9789   std::unique_ptr<crypto::SecureHash> hash(
9790       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9791   hash->Update(response_code_bytes.data(), response_code_bytes.size());
9792   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9793   hash->Update(buffer.data(), buffer.size());
9794   std::string response_hash(32, 0);
9795   hash->Finish(std::data(response_hash), response_hash.size());
9796   if (tag == TPM_ST_SESSIONS) {
9797     if (!authorization_delegate)
9798       return TRUNKS_RC_AUTHORIZATION_FAILED;
9799     if (!authorization_delegate->CheckResponseAuthorization(
9800             response_hash, authorization_section_bytes)) {
9801       return TRUNKS_RC_AUTHORIZATION_FAILED;
9802     }
9803   }
9804   if (tag == TPM_ST_SESSIONS) {
9805     if (!authorization_delegate)
9806       return TRUNKS_RC_AUTHORIZATION_FAILED;
9807 
9808     // Parse the encrypted parameter size.
9809     UINT16 size;
9810     std::string size_buffer = buffer.substr(0, 2);
9811     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9812       return result;
9813     }
9814     if (buffer.size() < 2 + size) {
9815       return TPM_RC_INSUFFICIENT;
9816     }
9817 
9818     // Decrypt just the parameter data, not the size.
9819     std::string decrypted_data = buffer.substr(2, size);
9820     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9821       return TRUNKS_RC_ENCRYPTION_FAILED;
9822     }
9823     buffer.replace(2, size, decrypted_data);
9824   }
9825   std::string out_private_bytes;
9826   rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
9827   if (rc != TPM_RC_SUCCESS) {
9828     return rc;
9829   }
9830   std::string out_public_bytes;
9831   rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
9832   if (rc != TPM_RC_SUCCESS) {
9833     return rc;
9834   }
9835   std::string creation_data_bytes;
9836   rc = Parse_TPM2B_CREATION_DATA(&buffer, creation_data, &creation_data_bytes);
9837   if (rc != TPM_RC_SUCCESS) {
9838     return rc;
9839   }
9840   std::string creation_hash_bytes;
9841   rc = Parse_TPM2B_DIGEST(&buffer, creation_hash, &creation_hash_bytes);
9842   if (rc != TPM_RC_SUCCESS) {
9843     return rc;
9844   }
9845   std::string creation_ticket_bytes;
9846   rc = Parse_TPMT_TK_CREATION(&buffer, creation_ticket, &creation_ticket_bytes);
9847   if (rc != TPM_RC_SUCCESS) {
9848     return rc;
9849   }
9850   return TPM_RC_SUCCESS;
9851 }
9852 
CreateErrorCallback(Tpm::CreateResponse callback,TPM_RC response_code)9853 void CreateErrorCallback(Tpm::CreateResponse callback, TPM_RC response_code) {
9854   VLOG(1) << __func__;
9855   std::move(callback).Run(response_code, TPM2B_PRIVATE(), TPM2B_PUBLIC(),
9856                           TPM2B_CREATION_DATA(), TPM2B_DIGEST(),
9857                           TPMT_TK_CREATION());
9858 }
9859 
CreateResponseParser(Tpm::CreateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9860 void CreateResponseParser(Tpm::CreateResponse callback,
9861                           AuthorizationDelegate* authorization_delegate,
9862                           const std::string& response) {
9863   VLOG(1) << __func__;
9864   TPM2B_PRIVATE out_private;
9865   TPM2B_PUBLIC out_public;
9866   TPM2B_CREATION_DATA creation_data;
9867   TPM2B_DIGEST creation_hash;
9868   TPMT_TK_CREATION creation_ticket;
9869   TPM_RC rc = Tpm::ParseResponse_Create(
9870       response, &out_private, &out_public, &creation_data, &creation_hash,
9871       &creation_ticket, authorization_delegate);
9872   if (rc != TPM_RC_SUCCESS) {
9873     base::OnceCallback<void(TPM_RC)> error_reporter =
9874         base::BindOnce(CreateErrorCallback, std::move(callback));
9875     std::move(error_reporter).Run(rc);
9876     return;
9877   }
9878   std::move(callback).Run(rc, out_private, out_public, creation_data,
9879                           creation_hash, creation_ticket);
9880 }
9881 
Create(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,AuthorizationDelegate * authorization_delegate,CreateResponse callback)9882 void Tpm::Create(const TPMI_DH_OBJECT& parent_handle,
9883                  const std::string& parent_handle_name,
9884                  const TPM2B_SENSITIVE_CREATE& in_sensitive,
9885                  const TPM2B_PUBLIC& in_public,
9886                  const TPM2B_DATA& outside_info,
9887                  const TPML_PCR_SELECTION& creation_pcr,
9888                  AuthorizationDelegate* authorization_delegate,
9889                  CreateResponse callback) {
9890   VLOG(1) << __func__;
9891   std::string command;
9892   TPM_RC rc = SerializeCommand_Create(
9893       parent_handle, parent_handle_name, in_sensitive, in_public, outside_info,
9894       creation_pcr, &command, authorization_delegate);
9895   if (rc != TPM_RC_SUCCESS) {
9896     base::OnceCallback<void(TPM_RC)> error_reporter =
9897         base::BindOnce(CreateErrorCallback, std::move(callback));
9898     std::move(error_reporter).Run(rc);
9899     return;
9900   }
9901   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9902       CreateResponseParser, std::move(callback), authorization_delegate);
9903   transceiver_->SendCommand(command, std::move(parser));
9904 }
9905 
CreateSync(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,TPM2B_PRIVATE * out_private,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,AuthorizationDelegate * authorization_delegate)9906 TPM_RC Tpm::CreateSync(const TPMI_DH_OBJECT& parent_handle,
9907                        const std::string& parent_handle_name,
9908                        const TPM2B_SENSITIVE_CREATE& in_sensitive,
9909                        const TPM2B_PUBLIC& in_public,
9910                        const TPM2B_DATA& outside_info,
9911                        const TPML_PCR_SELECTION& creation_pcr,
9912                        TPM2B_PRIVATE* out_private,
9913                        TPM2B_PUBLIC* out_public,
9914                        TPM2B_CREATION_DATA* creation_data,
9915                        TPM2B_DIGEST* creation_hash,
9916                        TPMT_TK_CREATION* creation_ticket,
9917                        AuthorizationDelegate* authorization_delegate) {
9918   VLOG(1) << __func__;
9919   std::string command;
9920   TPM_RC rc = SerializeCommand_Create(
9921       parent_handle, parent_handle_name, in_sensitive, in_public, outside_info,
9922       creation_pcr, &command, authorization_delegate);
9923   if (rc != TPM_RC_SUCCESS) {
9924     return rc;
9925   }
9926   std::string response = transceiver_->SendCommandAndWait(command);
9927   rc = ParseResponse_Create(response, out_private, out_public, creation_data,
9928                             creation_hash, creation_ticket,
9929                             authorization_delegate);
9930   return rc;
9931 }
9932 
SerializeCommand_Load(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_PRIVATE & in_private,const TPM2B_PUBLIC & in_public,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9933 TPM_RC Tpm::SerializeCommand_Load(
9934     const TPMI_DH_OBJECT& parent_handle,
9935     const std::string& parent_handle_name,
9936     const TPM2B_PRIVATE& in_private,
9937     const TPM2B_PUBLIC& in_public,
9938     std::string* serialized_command,
9939     AuthorizationDelegate* authorization_delegate) {
9940   VLOG(3) << __func__;
9941   TPM_RC rc = TPM_RC_SUCCESS;
9942   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9943   UINT32 command_size = 10;  // Header size.
9944   std::string handle_section_bytes;
9945   std::string parameter_section_bytes;
9946   TPM_CC command_code = TPM_CC_Load;
9947   bool is_command_parameter_encryption_possible = true;
9948   bool is_response_parameter_encryption_possible = true;
9949   std::string command_code_bytes;
9950   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9951   if (rc != TPM_RC_SUCCESS) {
9952     return rc;
9953   }
9954   std::string parent_handle_bytes;
9955   rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
9956   if (rc != TPM_RC_SUCCESS) {
9957     return rc;
9958   }
9959   std::string in_private_bytes;
9960   rc = Serialize_TPM2B_PRIVATE(in_private, &in_private_bytes);
9961   if (rc != TPM_RC_SUCCESS) {
9962     return rc;
9963   }
9964   std::string in_public_bytes;
9965   rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
9966   if (rc != TPM_RC_SUCCESS) {
9967     return rc;
9968   }
9969   if (authorization_delegate) {
9970     // Encrypt just the parameter data, not the size.
9971     std::string tmp = in_private_bytes.substr(2);
9972     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9973       return TRUNKS_RC_ENCRYPTION_FAILED;
9974     }
9975     in_private_bytes.replace(2, std::string::npos, tmp);
9976   }
9977   std::unique_ptr<crypto::SecureHash> hash(
9978       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9979   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9980   hash->Update(parent_handle_name.data(), parent_handle_name.size());
9981   handle_section_bytes += parent_handle_bytes;
9982   command_size += parent_handle_bytes.size();
9983   hash->Update(in_private_bytes.data(), in_private_bytes.size());
9984   parameter_section_bytes += in_private_bytes;
9985   command_size += in_private_bytes.size();
9986   hash->Update(in_public_bytes.data(), in_public_bytes.size());
9987   parameter_section_bytes += in_public_bytes;
9988   command_size += in_public_bytes.size();
9989   std::string command_hash(32, 0);
9990   hash->Finish(std::data(command_hash), command_hash.size());
9991   std::string authorization_section_bytes;
9992   std::string authorization_size_bytes;
9993   if (authorization_delegate) {
9994     if (!authorization_delegate->GetCommandAuthorization(
9995             command_hash, is_command_parameter_encryption_possible,
9996             is_response_parameter_encryption_possible,
9997             &authorization_section_bytes)) {
9998       return TRUNKS_RC_AUTHORIZATION_FAILED;
9999     }
10000     if (!authorization_section_bytes.empty()) {
10001       tag = TPM_ST_SESSIONS;
10002       std::string tmp;
10003       rc = Serialize_UINT32(authorization_section_bytes.size(),
10004                             &authorization_size_bytes);
10005       if (rc != TPM_RC_SUCCESS) {
10006         return rc;
10007       }
10008       command_size +=
10009           authorization_size_bytes.size() + authorization_section_bytes.size();
10010     }
10011   }
10012   std::string tag_bytes;
10013   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10014   if (rc != TPM_RC_SUCCESS) {
10015     return rc;
10016   }
10017   std::string command_size_bytes;
10018   rc = Serialize_UINT32(command_size, &command_size_bytes);
10019   if (rc != TPM_RC_SUCCESS) {
10020     return rc;
10021   }
10022   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10023                         handle_section_bytes + authorization_size_bytes +
10024                         authorization_section_bytes + parameter_section_bytes;
10025   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10026   VLOG(2) << "Command: "
10027           << base::HexEncode(serialized_command->data(),
10028                              serialized_command->size());
10029   return TPM_RC_SUCCESS;
10030 }
10031 
ParseResponse_Load(const std::string & response,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10032 TPM_RC Tpm::ParseResponse_Load(const std::string& response,
10033                                TPM_HANDLE* object_handle,
10034                                TPM2B_NAME* name,
10035                                AuthorizationDelegate* authorization_delegate) {
10036   VLOG(3) << __func__;
10037   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10038   TPM_RC rc = TPM_RC_SUCCESS;
10039   std::string buffer(response);
10040   TPM_ST tag;
10041   std::string tag_bytes;
10042   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10043   if (rc != TPM_RC_SUCCESS) {
10044     return rc;
10045   }
10046   UINT32 response_size;
10047   std::string response_size_bytes;
10048   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10049   if (rc != TPM_RC_SUCCESS) {
10050     return rc;
10051   }
10052   TPM_RC response_code;
10053   std::string response_code_bytes;
10054   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10055   if (rc != TPM_RC_SUCCESS) {
10056     return rc;
10057   }
10058   if (response_size != response.size()) {
10059     return TPM_RC_SIZE;
10060   }
10061   if (response_code != TPM_RC_SUCCESS) {
10062     return response_code;
10063   }
10064   std::string object_handle_bytes;
10065   rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
10066   if (rc != TPM_RC_SUCCESS) {
10067     return rc;
10068   }
10069   TPM_CC command_code = TPM_CC_Load;
10070   std::string command_code_bytes;
10071   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10072   if (rc != TPM_RC_SUCCESS) {
10073     return rc;
10074   }
10075   std::string authorization_section_bytes;
10076   if (tag == TPM_ST_SESSIONS) {
10077     UINT32 parameter_section_size = buffer.size();
10078     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10079     if (rc != TPM_RC_SUCCESS) {
10080       return rc;
10081     }
10082     if (parameter_section_size > buffer.size()) {
10083       return TPM_RC_INSUFFICIENT;
10084     }
10085     authorization_section_bytes = buffer.substr(parameter_section_size);
10086     // Keep the parameter section in |buffer|.
10087     buffer.erase(parameter_section_size);
10088   }
10089   std::unique_ptr<crypto::SecureHash> hash(
10090       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10091   hash->Update(response_code_bytes.data(), response_code_bytes.size());
10092   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10093   hash->Update(buffer.data(), buffer.size());
10094   std::string response_hash(32, 0);
10095   hash->Finish(std::data(response_hash), response_hash.size());
10096   if (tag == TPM_ST_SESSIONS) {
10097     if (!authorization_delegate)
10098       return TRUNKS_RC_AUTHORIZATION_FAILED;
10099     if (!authorization_delegate->CheckResponseAuthorization(
10100             response_hash, authorization_section_bytes)) {
10101       return TRUNKS_RC_AUTHORIZATION_FAILED;
10102     }
10103   }
10104   if (tag == TPM_ST_SESSIONS) {
10105     if (!authorization_delegate)
10106       return TRUNKS_RC_AUTHORIZATION_FAILED;
10107 
10108     // Parse the encrypted parameter size.
10109     UINT16 size;
10110     std::string size_buffer = buffer.substr(0, 2);
10111     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10112       return result;
10113     }
10114     if (buffer.size() < 2 + size) {
10115       return TPM_RC_INSUFFICIENT;
10116     }
10117 
10118     // Decrypt just the parameter data, not the size.
10119     std::string decrypted_data = buffer.substr(2, size);
10120     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10121       return TRUNKS_RC_ENCRYPTION_FAILED;
10122     }
10123     buffer.replace(2, size, decrypted_data);
10124   }
10125   std::string name_bytes;
10126   rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10127   if (rc != TPM_RC_SUCCESS) {
10128     return rc;
10129   }
10130   return TPM_RC_SUCCESS;
10131 }
10132 
LoadErrorCallback(Tpm::LoadResponse callback,TPM_RC response_code)10133 void LoadErrorCallback(Tpm::LoadResponse callback, TPM_RC response_code) {
10134   VLOG(1) << __func__;
10135   std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_NAME());
10136 }
10137 
LoadResponseParser(Tpm::LoadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10138 void LoadResponseParser(Tpm::LoadResponse callback,
10139                         AuthorizationDelegate* authorization_delegate,
10140                         const std::string& response) {
10141   VLOG(1) << __func__;
10142   TPM_HANDLE object_handle;
10143   TPM2B_NAME name;
10144   TPM_RC rc = Tpm::ParseResponse_Load(response, &object_handle, &name,
10145                                       authorization_delegate);
10146   if (rc != TPM_RC_SUCCESS) {
10147     base::OnceCallback<void(TPM_RC)> error_reporter =
10148         base::BindOnce(LoadErrorCallback, std::move(callback));
10149     std::move(error_reporter).Run(rc);
10150     return;
10151   }
10152   std::move(callback).Run(rc, object_handle, name);
10153 }
10154 
Load(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_PRIVATE & in_private,const TPM2B_PUBLIC & in_public,AuthorizationDelegate * authorization_delegate,LoadResponse callback)10155 void Tpm::Load(const TPMI_DH_OBJECT& parent_handle,
10156                const std::string& parent_handle_name,
10157                const TPM2B_PRIVATE& in_private,
10158                const TPM2B_PUBLIC& in_public,
10159                AuthorizationDelegate* authorization_delegate,
10160                LoadResponse callback) {
10161   VLOG(1) << __func__;
10162   std::string command;
10163   TPM_RC rc =
10164       SerializeCommand_Load(parent_handle, parent_handle_name, in_private,
10165                             in_public, &command, authorization_delegate);
10166   if (rc != TPM_RC_SUCCESS) {
10167     base::OnceCallback<void(TPM_RC)> error_reporter =
10168         base::BindOnce(LoadErrorCallback, std::move(callback));
10169     std::move(error_reporter).Run(rc);
10170     return;
10171   }
10172   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10173       LoadResponseParser, std::move(callback), authorization_delegate);
10174   transceiver_->SendCommand(command, std::move(parser));
10175 }
10176 
LoadSync(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_PRIVATE & in_private,const TPM2B_PUBLIC & in_public,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10177 TPM_RC Tpm::LoadSync(const TPMI_DH_OBJECT& parent_handle,
10178                      const std::string& parent_handle_name,
10179                      const TPM2B_PRIVATE& in_private,
10180                      const TPM2B_PUBLIC& in_public,
10181                      TPM_HANDLE* object_handle,
10182                      TPM2B_NAME* name,
10183                      AuthorizationDelegate* authorization_delegate) {
10184   VLOG(1) << __func__;
10185   std::string command;
10186   TPM_RC rc =
10187       SerializeCommand_Load(parent_handle, parent_handle_name, in_private,
10188                             in_public, &command, authorization_delegate);
10189   if (rc != TPM_RC_SUCCESS) {
10190     return rc;
10191   }
10192   std::string response = transceiver_->SendCommandAndWait(command);
10193   rc =
10194       ParseResponse_Load(response, object_handle, name, authorization_delegate);
10195   return rc;
10196 }
10197 
SerializeCommand_LoadExternal(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10198 TPM_RC Tpm::SerializeCommand_LoadExternal(
10199     const TPM2B_SENSITIVE& in_private,
10200     const TPM2B_PUBLIC& in_public,
10201     const TPMI_RH_HIERARCHY& hierarchy,
10202     std::string* serialized_command,
10203     AuthorizationDelegate* authorization_delegate) {
10204   VLOG(3) << __func__;
10205   TPM_RC rc = TPM_RC_SUCCESS;
10206   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10207   UINT32 command_size = 10;  // Header size.
10208   std::string handle_section_bytes;
10209   std::string parameter_section_bytes;
10210   TPM_CC command_code = TPM_CC_LoadExternal;
10211   bool is_command_parameter_encryption_possible = true;
10212   bool is_response_parameter_encryption_possible = true;
10213   std::string command_code_bytes;
10214   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10215   if (rc != TPM_RC_SUCCESS) {
10216     return rc;
10217   }
10218   std::string in_private_bytes;
10219   rc = Serialize_TPM2B_SENSITIVE(in_private, &in_private_bytes);
10220   if (rc != TPM_RC_SUCCESS) {
10221     return rc;
10222   }
10223   std::string in_public_bytes;
10224   rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
10225   if (rc != TPM_RC_SUCCESS) {
10226     return rc;
10227   }
10228   std::string hierarchy_bytes;
10229   rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
10230   if (rc != TPM_RC_SUCCESS) {
10231     return rc;
10232   }
10233   if (authorization_delegate) {
10234     // Encrypt just the parameter data, not the size.
10235     std::string tmp = in_private_bytes.substr(2);
10236     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10237       return TRUNKS_RC_ENCRYPTION_FAILED;
10238     }
10239     in_private_bytes.replace(2, std::string::npos, tmp);
10240   }
10241   std::unique_ptr<crypto::SecureHash> hash(
10242       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10243   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10244   hash->Update(in_private_bytes.data(), in_private_bytes.size());
10245   parameter_section_bytes += in_private_bytes;
10246   command_size += in_private_bytes.size();
10247   hash->Update(in_public_bytes.data(), in_public_bytes.size());
10248   parameter_section_bytes += in_public_bytes;
10249   command_size += in_public_bytes.size();
10250   hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
10251   parameter_section_bytes += hierarchy_bytes;
10252   command_size += hierarchy_bytes.size();
10253   std::string command_hash(32, 0);
10254   hash->Finish(std::data(command_hash), command_hash.size());
10255   std::string authorization_section_bytes;
10256   std::string authorization_size_bytes;
10257   if (authorization_delegate) {
10258     if (!authorization_delegate->GetCommandAuthorization(
10259             command_hash, is_command_parameter_encryption_possible,
10260             is_response_parameter_encryption_possible,
10261             &authorization_section_bytes)) {
10262       return TRUNKS_RC_AUTHORIZATION_FAILED;
10263     }
10264     if (!authorization_section_bytes.empty()) {
10265       tag = TPM_ST_SESSIONS;
10266       std::string tmp;
10267       rc = Serialize_UINT32(authorization_section_bytes.size(),
10268                             &authorization_size_bytes);
10269       if (rc != TPM_RC_SUCCESS) {
10270         return rc;
10271       }
10272       command_size +=
10273           authorization_size_bytes.size() + authorization_section_bytes.size();
10274     }
10275   }
10276   std::string tag_bytes;
10277   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10278   if (rc != TPM_RC_SUCCESS) {
10279     return rc;
10280   }
10281   std::string command_size_bytes;
10282   rc = Serialize_UINT32(command_size, &command_size_bytes);
10283   if (rc != TPM_RC_SUCCESS) {
10284     return rc;
10285   }
10286   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10287                         handle_section_bytes + authorization_size_bytes +
10288                         authorization_section_bytes + parameter_section_bytes;
10289   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10290   VLOG(2) << "Command: "
10291           << base::HexEncode(serialized_command->data(),
10292                              serialized_command->size());
10293   return TPM_RC_SUCCESS;
10294 }
10295 
ParseResponse_LoadExternal(const std::string & response,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10296 TPM_RC Tpm::ParseResponse_LoadExternal(
10297     const std::string& response,
10298     TPM_HANDLE* object_handle,
10299     TPM2B_NAME* name,
10300     AuthorizationDelegate* authorization_delegate) {
10301   VLOG(3) << __func__;
10302   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10303   TPM_RC rc = TPM_RC_SUCCESS;
10304   std::string buffer(response);
10305   TPM_ST tag;
10306   std::string tag_bytes;
10307   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10308   if (rc != TPM_RC_SUCCESS) {
10309     return rc;
10310   }
10311   UINT32 response_size;
10312   std::string response_size_bytes;
10313   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10314   if (rc != TPM_RC_SUCCESS) {
10315     return rc;
10316   }
10317   TPM_RC response_code;
10318   std::string response_code_bytes;
10319   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10320   if (rc != TPM_RC_SUCCESS) {
10321     return rc;
10322   }
10323   if (response_size != response.size()) {
10324     return TPM_RC_SIZE;
10325   }
10326   if (response_code != TPM_RC_SUCCESS) {
10327     return response_code;
10328   }
10329   std::string object_handle_bytes;
10330   rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
10331   if (rc != TPM_RC_SUCCESS) {
10332     return rc;
10333   }
10334   TPM_CC command_code = TPM_CC_LoadExternal;
10335   std::string command_code_bytes;
10336   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10337   if (rc != TPM_RC_SUCCESS) {
10338     return rc;
10339   }
10340   std::string authorization_section_bytes;
10341   if (tag == TPM_ST_SESSIONS) {
10342     UINT32 parameter_section_size = buffer.size();
10343     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10344     if (rc != TPM_RC_SUCCESS) {
10345       return rc;
10346     }
10347     if (parameter_section_size > buffer.size()) {
10348       return TPM_RC_INSUFFICIENT;
10349     }
10350     authorization_section_bytes = buffer.substr(parameter_section_size);
10351     // Keep the parameter section in |buffer|.
10352     buffer.erase(parameter_section_size);
10353   }
10354   std::unique_ptr<crypto::SecureHash> hash(
10355       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10356   hash->Update(response_code_bytes.data(), response_code_bytes.size());
10357   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10358   hash->Update(buffer.data(), buffer.size());
10359   std::string response_hash(32, 0);
10360   hash->Finish(std::data(response_hash), response_hash.size());
10361   if (tag == TPM_ST_SESSIONS) {
10362     if (!authorization_delegate)
10363       return TRUNKS_RC_AUTHORIZATION_FAILED;
10364     if (!authorization_delegate->CheckResponseAuthorization(
10365             response_hash, authorization_section_bytes)) {
10366       return TRUNKS_RC_AUTHORIZATION_FAILED;
10367     }
10368   }
10369   if (tag == TPM_ST_SESSIONS) {
10370     if (!authorization_delegate)
10371       return TRUNKS_RC_AUTHORIZATION_FAILED;
10372 
10373     // Parse the encrypted parameter size.
10374     UINT16 size;
10375     std::string size_buffer = buffer.substr(0, 2);
10376     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10377       return result;
10378     }
10379     if (buffer.size() < 2 + size) {
10380       return TPM_RC_INSUFFICIENT;
10381     }
10382 
10383     // Decrypt just the parameter data, not the size.
10384     std::string decrypted_data = buffer.substr(2, size);
10385     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10386       return TRUNKS_RC_ENCRYPTION_FAILED;
10387     }
10388     buffer.replace(2, size, decrypted_data);
10389   }
10390   std::string name_bytes;
10391   rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10392   if (rc != TPM_RC_SUCCESS) {
10393     return rc;
10394   }
10395   return TPM_RC_SUCCESS;
10396 }
10397 
LoadExternalErrorCallback(Tpm::LoadExternalResponse callback,TPM_RC response_code)10398 void LoadExternalErrorCallback(Tpm::LoadExternalResponse callback,
10399                                TPM_RC response_code) {
10400   VLOG(1) << __func__;
10401   std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_NAME());
10402 }
10403 
LoadExternalResponseParser(Tpm::LoadExternalResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10404 void LoadExternalResponseParser(Tpm::LoadExternalResponse callback,
10405                                 AuthorizationDelegate* authorization_delegate,
10406                                 const std::string& response) {
10407   VLOG(1) << __func__;
10408   TPM_HANDLE object_handle;
10409   TPM2B_NAME name;
10410   TPM_RC rc = Tpm::ParseResponse_LoadExternal(response, &object_handle, &name,
10411                                               authorization_delegate);
10412   if (rc != TPM_RC_SUCCESS) {
10413     base::OnceCallback<void(TPM_RC)> error_reporter =
10414         base::BindOnce(LoadExternalErrorCallback, std::move(callback));
10415     std::move(error_reporter).Run(rc);
10416     return;
10417   }
10418   std::move(callback).Run(rc, object_handle, name);
10419 }
10420 
LoadExternal(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,LoadExternalResponse callback)10421 void Tpm::LoadExternal(const TPM2B_SENSITIVE& in_private,
10422                        const TPM2B_PUBLIC& in_public,
10423                        const TPMI_RH_HIERARCHY& hierarchy,
10424                        AuthorizationDelegate* authorization_delegate,
10425                        LoadExternalResponse callback) {
10426   VLOG(1) << __func__;
10427   std::string command;
10428   TPM_RC rc = SerializeCommand_LoadExternal(in_private, in_public, hierarchy,
10429                                             &command, authorization_delegate);
10430   if (rc != TPM_RC_SUCCESS) {
10431     base::OnceCallback<void(TPM_RC)> error_reporter =
10432         base::BindOnce(LoadExternalErrorCallback, std::move(callback));
10433     std::move(error_reporter).Run(rc);
10434     return;
10435   }
10436   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10437       LoadExternalResponseParser, std::move(callback), authorization_delegate);
10438   transceiver_->SendCommand(command, std::move(parser));
10439 }
10440 
LoadExternalSync(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10441 TPM_RC Tpm::LoadExternalSync(const TPM2B_SENSITIVE& in_private,
10442                              const TPM2B_PUBLIC& in_public,
10443                              const TPMI_RH_HIERARCHY& hierarchy,
10444                              TPM_HANDLE* object_handle,
10445                              TPM2B_NAME* name,
10446                              AuthorizationDelegate* authorization_delegate) {
10447   VLOG(1) << __func__;
10448   std::string command;
10449   TPM_RC rc = SerializeCommand_LoadExternal(in_private, in_public, hierarchy,
10450                                             &command, authorization_delegate);
10451   if (rc != TPM_RC_SUCCESS) {
10452     return rc;
10453   }
10454   std::string response = transceiver_->SendCommandAndWait(command);
10455   rc = ParseResponse_LoadExternal(response, object_handle, name,
10456                                   authorization_delegate);
10457   return rc;
10458 }
10459 
SerializeCommand_ReadPublic(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10460 TPM_RC Tpm::SerializeCommand_ReadPublic(
10461     const TPMI_DH_OBJECT& object_handle,
10462     const std::string& object_handle_name,
10463     std::string* serialized_command,
10464     AuthorizationDelegate* authorization_delegate) {
10465   VLOG(3) << __func__;
10466   TPM_RC rc = TPM_RC_SUCCESS;
10467   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10468   UINT32 command_size = 10;  // Header size.
10469   std::string handle_section_bytes;
10470   std::string parameter_section_bytes;
10471   TPM_CC command_code = TPM_CC_ReadPublic;
10472   bool is_command_parameter_encryption_possible = false;
10473   bool is_response_parameter_encryption_possible = true;
10474   std::string command_code_bytes;
10475   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10476   if (rc != TPM_RC_SUCCESS) {
10477     return rc;
10478   }
10479   std::string object_handle_bytes;
10480   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
10481   if (rc != TPM_RC_SUCCESS) {
10482     return rc;
10483   }
10484   std::unique_ptr<crypto::SecureHash> hash(
10485       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10486   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10487   hash->Update(object_handle_name.data(), object_handle_name.size());
10488   handle_section_bytes += object_handle_bytes;
10489   command_size += object_handle_bytes.size();
10490   std::string command_hash(32, 0);
10491   hash->Finish(std::data(command_hash), command_hash.size());
10492   std::string authorization_section_bytes;
10493   std::string authorization_size_bytes;
10494   if (authorization_delegate) {
10495     if (!authorization_delegate->GetCommandAuthorization(
10496             command_hash, is_command_parameter_encryption_possible,
10497             is_response_parameter_encryption_possible,
10498             &authorization_section_bytes)) {
10499       return TRUNKS_RC_AUTHORIZATION_FAILED;
10500     }
10501     if (!authorization_section_bytes.empty()) {
10502       tag = TPM_ST_SESSIONS;
10503       std::string tmp;
10504       rc = Serialize_UINT32(authorization_section_bytes.size(),
10505                             &authorization_size_bytes);
10506       if (rc != TPM_RC_SUCCESS) {
10507         return rc;
10508       }
10509       command_size +=
10510           authorization_size_bytes.size() + authorization_section_bytes.size();
10511     }
10512   }
10513   std::string tag_bytes;
10514   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10515   if (rc != TPM_RC_SUCCESS) {
10516     return rc;
10517   }
10518   std::string command_size_bytes;
10519   rc = Serialize_UINT32(command_size, &command_size_bytes);
10520   if (rc != TPM_RC_SUCCESS) {
10521     return rc;
10522   }
10523   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10524                         handle_section_bytes + authorization_size_bytes +
10525                         authorization_section_bytes + parameter_section_bytes;
10526   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10527   VLOG(2) << "Command: "
10528           << base::HexEncode(serialized_command->data(),
10529                              serialized_command->size());
10530   return TPM_RC_SUCCESS;
10531 }
10532 
ParseResponse_ReadPublic(const std::string & response,TPM2B_PUBLIC * out_public,TPM2B_NAME * name,TPM2B_NAME * qualified_name,AuthorizationDelegate * authorization_delegate)10533 TPM_RC Tpm::ParseResponse_ReadPublic(
10534     const std::string& response,
10535     TPM2B_PUBLIC* out_public,
10536     TPM2B_NAME* name,
10537     TPM2B_NAME* qualified_name,
10538     AuthorizationDelegate* authorization_delegate) {
10539   VLOG(3) << __func__;
10540   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10541   TPM_RC rc = TPM_RC_SUCCESS;
10542   std::string buffer(response);
10543   TPM_ST tag;
10544   std::string tag_bytes;
10545   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10546   if (rc != TPM_RC_SUCCESS) {
10547     return rc;
10548   }
10549   UINT32 response_size;
10550   std::string response_size_bytes;
10551   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10552   if (rc != TPM_RC_SUCCESS) {
10553     return rc;
10554   }
10555   TPM_RC response_code;
10556   std::string response_code_bytes;
10557   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10558   if (rc != TPM_RC_SUCCESS) {
10559     return rc;
10560   }
10561   if (response_size != response.size()) {
10562     return TPM_RC_SIZE;
10563   }
10564   if (response_code != TPM_RC_SUCCESS) {
10565     return response_code;
10566   }
10567   TPM_CC command_code = TPM_CC_ReadPublic;
10568   std::string command_code_bytes;
10569   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10570   if (rc != TPM_RC_SUCCESS) {
10571     return rc;
10572   }
10573   std::string authorization_section_bytes;
10574   if (tag == TPM_ST_SESSIONS) {
10575     UINT32 parameter_section_size = buffer.size();
10576     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10577     if (rc != TPM_RC_SUCCESS) {
10578       return rc;
10579     }
10580     if (parameter_section_size > buffer.size()) {
10581       return TPM_RC_INSUFFICIENT;
10582     }
10583     authorization_section_bytes = buffer.substr(parameter_section_size);
10584     // Keep the parameter section in |buffer|.
10585     buffer.erase(parameter_section_size);
10586   }
10587   std::unique_ptr<crypto::SecureHash> hash(
10588       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10589   hash->Update(response_code_bytes.data(), response_code_bytes.size());
10590   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10591   hash->Update(buffer.data(), buffer.size());
10592   std::string response_hash(32, 0);
10593   hash->Finish(std::data(response_hash), response_hash.size());
10594   if (tag == TPM_ST_SESSIONS) {
10595     if (!authorization_delegate)
10596       return TRUNKS_RC_AUTHORIZATION_FAILED;
10597     if (!authorization_delegate->CheckResponseAuthorization(
10598             response_hash, authorization_section_bytes)) {
10599       return TRUNKS_RC_AUTHORIZATION_FAILED;
10600     }
10601   }
10602   if (tag == TPM_ST_SESSIONS) {
10603     if (!authorization_delegate)
10604       return TRUNKS_RC_AUTHORIZATION_FAILED;
10605 
10606     // Parse the encrypted parameter size.
10607     UINT16 size;
10608     std::string size_buffer = buffer.substr(0, 2);
10609     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10610       return result;
10611     }
10612     if (buffer.size() < 2 + size) {
10613       return TPM_RC_INSUFFICIENT;
10614     }
10615 
10616     // Decrypt just the parameter data, not the size.
10617     std::string decrypted_data = buffer.substr(2, size);
10618     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10619       return TRUNKS_RC_ENCRYPTION_FAILED;
10620     }
10621     buffer.replace(2, size, decrypted_data);
10622   }
10623   std::string out_public_bytes;
10624   rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
10625   if (rc != TPM_RC_SUCCESS) {
10626     return rc;
10627   }
10628   std::string name_bytes;
10629   rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10630   if (rc != TPM_RC_SUCCESS) {
10631     return rc;
10632   }
10633   std::string qualified_name_bytes;
10634   rc = Parse_TPM2B_NAME(&buffer, qualified_name, &qualified_name_bytes);
10635   if (rc != TPM_RC_SUCCESS) {
10636     return rc;
10637   }
10638   return TPM_RC_SUCCESS;
10639 }
10640 
ReadPublicErrorCallback(Tpm::ReadPublicResponse callback,TPM_RC response_code)10641 void ReadPublicErrorCallback(Tpm::ReadPublicResponse callback,
10642                              TPM_RC response_code) {
10643   VLOG(1) << __func__;
10644   std::move(callback).Run(response_code, TPM2B_PUBLIC(), TPM2B_NAME(),
10645                           TPM2B_NAME());
10646 }
10647 
ReadPublicResponseParser(Tpm::ReadPublicResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10648 void ReadPublicResponseParser(Tpm::ReadPublicResponse callback,
10649                               AuthorizationDelegate* authorization_delegate,
10650                               const std::string& response) {
10651   VLOG(1) << __func__;
10652   TPM2B_PUBLIC out_public;
10653   TPM2B_NAME name;
10654   TPM2B_NAME qualified_name;
10655   TPM_RC rc = Tpm::ParseResponse_ReadPublic(
10656       response, &out_public, &name, &qualified_name, authorization_delegate);
10657   if (rc != TPM_RC_SUCCESS) {
10658     base::OnceCallback<void(TPM_RC)> error_reporter =
10659         base::BindOnce(ReadPublicErrorCallback, std::move(callback));
10660     std::move(error_reporter).Run(rc);
10661     return;
10662   }
10663   std::move(callback).Run(rc, out_public, name, qualified_name);
10664 }
10665 
ReadPublic(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,AuthorizationDelegate * authorization_delegate,ReadPublicResponse callback)10666 void Tpm::ReadPublic(const TPMI_DH_OBJECT& object_handle,
10667                      const std::string& object_handle_name,
10668                      AuthorizationDelegate* authorization_delegate,
10669                      ReadPublicResponse callback) {
10670   VLOG(1) << __func__;
10671   std::string command;
10672   TPM_RC rc = SerializeCommand_ReadPublic(object_handle, object_handle_name,
10673                                           &command, authorization_delegate);
10674   if (rc != TPM_RC_SUCCESS) {
10675     base::OnceCallback<void(TPM_RC)> error_reporter =
10676         base::BindOnce(ReadPublicErrorCallback, std::move(callback));
10677     std::move(error_reporter).Run(rc);
10678     return;
10679   }
10680   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10681       ReadPublicResponseParser, std::move(callback), authorization_delegate);
10682   transceiver_->SendCommand(command, std::move(parser));
10683 }
10684 
ReadPublicSync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,TPM2B_PUBLIC * out_public,TPM2B_NAME * name,TPM2B_NAME * qualified_name,AuthorizationDelegate * authorization_delegate)10685 TPM_RC Tpm::ReadPublicSync(const TPMI_DH_OBJECT& object_handle,
10686                            const std::string& object_handle_name,
10687                            TPM2B_PUBLIC* out_public,
10688                            TPM2B_NAME* name,
10689                            TPM2B_NAME* qualified_name,
10690                            AuthorizationDelegate* authorization_delegate) {
10691   VLOG(1) << __func__;
10692   std::string command;
10693   TPM_RC rc = SerializeCommand_ReadPublic(object_handle, object_handle_name,
10694                                           &command, authorization_delegate);
10695   if (rc != TPM_RC_SUCCESS) {
10696     return rc;
10697   }
10698   std::string response = transceiver_->SendCommandAndWait(command);
10699   rc = ParseResponse_ReadPublic(response, out_public, name, qualified_name,
10700                                 authorization_delegate);
10701   return rc;
10702 }
10703 
SerializeCommand_ActivateCredential(const TPMI_DH_OBJECT & activate_handle,const std::string & activate_handle_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ID_OBJECT & credential_blob,const TPM2B_ENCRYPTED_SECRET & secret,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10704 TPM_RC Tpm::SerializeCommand_ActivateCredential(
10705     const TPMI_DH_OBJECT& activate_handle,
10706     const std::string& activate_handle_name,
10707     const TPMI_DH_OBJECT& key_handle,
10708     const std::string& key_handle_name,
10709     const TPM2B_ID_OBJECT& credential_blob,
10710     const TPM2B_ENCRYPTED_SECRET& secret,
10711     std::string* serialized_command,
10712     AuthorizationDelegate* authorization_delegate) {
10713   VLOG(3) << __func__;
10714   TPM_RC rc = TPM_RC_SUCCESS;
10715   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10716   UINT32 command_size = 10;  // Header size.
10717   std::string handle_section_bytes;
10718   std::string parameter_section_bytes;
10719   TPM_CC command_code = TPM_CC_ActivateCredential;
10720   bool is_command_parameter_encryption_possible = true;
10721   bool is_response_parameter_encryption_possible = true;
10722   std::string command_code_bytes;
10723   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10724   if (rc != TPM_RC_SUCCESS) {
10725     return rc;
10726   }
10727   std::string activate_handle_bytes;
10728   rc = Serialize_TPMI_DH_OBJECT(activate_handle, &activate_handle_bytes);
10729   if (rc != TPM_RC_SUCCESS) {
10730     return rc;
10731   }
10732   std::string key_handle_bytes;
10733   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
10734   if (rc != TPM_RC_SUCCESS) {
10735     return rc;
10736   }
10737   std::string credential_blob_bytes;
10738   rc = Serialize_TPM2B_ID_OBJECT(credential_blob, &credential_blob_bytes);
10739   if (rc != TPM_RC_SUCCESS) {
10740     return rc;
10741   }
10742   std::string secret_bytes;
10743   rc = Serialize_TPM2B_ENCRYPTED_SECRET(secret, &secret_bytes);
10744   if (rc != TPM_RC_SUCCESS) {
10745     return rc;
10746   }
10747   if (authorization_delegate) {
10748     // Encrypt just the parameter data, not the size.
10749     std::string tmp = credential_blob_bytes.substr(2);
10750     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10751       return TRUNKS_RC_ENCRYPTION_FAILED;
10752     }
10753     credential_blob_bytes.replace(2, std::string::npos, tmp);
10754   }
10755   std::unique_ptr<crypto::SecureHash> hash(
10756       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10757   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10758   hash->Update(activate_handle_name.data(), activate_handle_name.size());
10759   handle_section_bytes += activate_handle_bytes;
10760   command_size += activate_handle_bytes.size();
10761   hash->Update(key_handle_name.data(), key_handle_name.size());
10762   handle_section_bytes += key_handle_bytes;
10763   command_size += key_handle_bytes.size();
10764   hash->Update(credential_blob_bytes.data(), credential_blob_bytes.size());
10765   parameter_section_bytes += credential_blob_bytes;
10766   command_size += credential_blob_bytes.size();
10767   hash->Update(secret_bytes.data(), secret_bytes.size());
10768   parameter_section_bytes += secret_bytes;
10769   command_size += secret_bytes.size();
10770   std::string command_hash(32, 0);
10771   hash->Finish(std::data(command_hash), command_hash.size());
10772   std::string authorization_section_bytes;
10773   std::string authorization_size_bytes;
10774   if (authorization_delegate) {
10775     if (!authorization_delegate->GetCommandAuthorization(
10776             command_hash, is_command_parameter_encryption_possible,
10777             is_response_parameter_encryption_possible,
10778             &authorization_section_bytes)) {
10779       return TRUNKS_RC_AUTHORIZATION_FAILED;
10780     }
10781     if (!authorization_section_bytes.empty()) {
10782       tag = TPM_ST_SESSIONS;
10783       std::string tmp;
10784       rc = Serialize_UINT32(authorization_section_bytes.size(),
10785                             &authorization_size_bytes);
10786       if (rc != TPM_RC_SUCCESS) {
10787         return rc;
10788       }
10789       command_size +=
10790           authorization_size_bytes.size() + authorization_section_bytes.size();
10791     }
10792   }
10793   std::string tag_bytes;
10794   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10795   if (rc != TPM_RC_SUCCESS) {
10796     return rc;
10797   }
10798   std::string command_size_bytes;
10799   rc = Serialize_UINT32(command_size, &command_size_bytes);
10800   if (rc != TPM_RC_SUCCESS) {
10801     return rc;
10802   }
10803   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10804                         handle_section_bytes + authorization_size_bytes +
10805                         authorization_section_bytes + parameter_section_bytes;
10806   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10807   VLOG(2) << "Command: "
10808           << base::HexEncode(serialized_command->data(),
10809                              serialized_command->size());
10810   return TPM_RC_SUCCESS;
10811 }
10812 
ParseResponse_ActivateCredential(const std::string & response,TPM2B_DIGEST * cert_info,AuthorizationDelegate * authorization_delegate)10813 TPM_RC Tpm::ParseResponse_ActivateCredential(
10814     const std::string& response,
10815     TPM2B_DIGEST* cert_info,
10816     AuthorizationDelegate* authorization_delegate) {
10817   VLOG(3) << __func__;
10818   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10819   TPM_RC rc = TPM_RC_SUCCESS;
10820   std::string buffer(response);
10821   TPM_ST tag;
10822   std::string tag_bytes;
10823   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10824   if (rc != TPM_RC_SUCCESS) {
10825     return rc;
10826   }
10827   UINT32 response_size;
10828   std::string response_size_bytes;
10829   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10830   if (rc != TPM_RC_SUCCESS) {
10831     return rc;
10832   }
10833   TPM_RC response_code;
10834   std::string response_code_bytes;
10835   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10836   if (rc != TPM_RC_SUCCESS) {
10837     return rc;
10838   }
10839   if (response_size != response.size()) {
10840     return TPM_RC_SIZE;
10841   }
10842   if (response_code != TPM_RC_SUCCESS) {
10843     return response_code;
10844   }
10845   TPM_CC command_code = TPM_CC_ActivateCredential;
10846   std::string command_code_bytes;
10847   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10848   if (rc != TPM_RC_SUCCESS) {
10849     return rc;
10850   }
10851   std::string authorization_section_bytes;
10852   if (tag == TPM_ST_SESSIONS) {
10853     UINT32 parameter_section_size = buffer.size();
10854     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10855     if (rc != TPM_RC_SUCCESS) {
10856       return rc;
10857     }
10858     if (parameter_section_size > buffer.size()) {
10859       return TPM_RC_INSUFFICIENT;
10860     }
10861     authorization_section_bytes = buffer.substr(parameter_section_size);
10862     // Keep the parameter section in |buffer|.
10863     buffer.erase(parameter_section_size);
10864   }
10865   std::unique_ptr<crypto::SecureHash> hash(
10866       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10867   hash->Update(response_code_bytes.data(), response_code_bytes.size());
10868   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10869   hash->Update(buffer.data(), buffer.size());
10870   std::string response_hash(32, 0);
10871   hash->Finish(std::data(response_hash), response_hash.size());
10872   if (tag == TPM_ST_SESSIONS) {
10873     if (!authorization_delegate)
10874       return TRUNKS_RC_AUTHORIZATION_FAILED;
10875     if (!authorization_delegate->CheckResponseAuthorization(
10876             response_hash, authorization_section_bytes)) {
10877       return TRUNKS_RC_AUTHORIZATION_FAILED;
10878     }
10879   }
10880   if (tag == TPM_ST_SESSIONS) {
10881     if (!authorization_delegate)
10882       return TRUNKS_RC_AUTHORIZATION_FAILED;
10883 
10884     // Parse the encrypted parameter size.
10885     UINT16 size;
10886     std::string size_buffer = buffer.substr(0, 2);
10887     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10888       return result;
10889     }
10890     if (buffer.size() < 2 + size) {
10891       return TPM_RC_INSUFFICIENT;
10892     }
10893 
10894     // Decrypt just the parameter data, not the size.
10895     std::string decrypted_data = buffer.substr(2, size);
10896     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10897       return TRUNKS_RC_ENCRYPTION_FAILED;
10898     }
10899     buffer.replace(2, size, decrypted_data);
10900   }
10901   std::string cert_info_bytes;
10902   rc = Parse_TPM2B_DIGEST(&buffer, cert_info, &cert_info_bytes);
10903   if (rc != TPM_RC_SUCCESS) {
10904     return rc;
10905   }
10906   return TPM_RC_SUCCESS;
10907 }
10908 
ActivateCredentialErrorCallback(Tpm::ActivateCredentialResponse callback,TPM_RC response_code)10909 void ActivateCredentialErrorCallback(Tpm::ActivateCredentialResponse callback,
10910                                      TPM_RC response_code) {
10911   VLOG(1) << __func__;
10912   std::move(callback).Run(response_code, TPM2B_DIGEST());
10913 }
10914 
ActivateCredentialResponseParser(Tpm::ActivateCredentialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10915 void ActivateCredentialResponseParser(
10916     Tpm::ActivateCredentialResponse callback,
10917     AuthorizationDelegate* authorization_delegate,
10918     const std::string& response) {
10919   VLOG(1) << __func__;
10920   TPM2B_DIGEST cert_info;
10921   TPM_RC rc = Tpm::ParseResponse_ActivateCredential(response, &cert_info,
10922                                                     authorization_delegate);
10923   if (rc != TPM_RC_SUCCESS) {
10924     base::OnceCallback<void(TPM_RC)> error_reporter =
10925         base::BindOnce(ActivateCredentialErrorCallback, std::move(callback));
10926     std::move(error_reporter).Run(rc);
10927     return;
10928   }
10929   std::move(callback).Run(rc, cert_info);
10930 }
10931 
ActivateCredential(const TPMI_DH_OBJECT & activate_handle,const std::string & activate_handle_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ID_OBJECT & credential_blob,const TPM2B_ENCRYPTED_SECRET & secret,AuthorizationDelegate * authorization_delegate,ActivateCredentialResponse callback)10932 void Tpm::ActivateCredential(const TPMI_DH_OBJECT& activate_handle,
10933                              const std::string& activate_handle_name,
10934                              const TPMI_DH_OBJECT& key_handle,
10935                              const std::string& key_handle_name,
10936                              const TPM2B_ID_OBJECT& credential_blob,
10937                              const TPM2B_ENCRYPTED_SECRET& secret,
10938                              AuthorizationDelegate* authorization_delegate,
10939                              ActivateCredentialResponse callback) {
10940   VLOG(1) << __func__;
10941   std::string command;
10942   TPM_RC rc = SerializeCommand_ActivateCredential(
10943       activate_handle, activate_handle_name, key_handle, key_handle_name,
10944       credential_blob, secret, &command, authorization_delegate);
10945   if (rc != TPM_RC_SUCCESS) {
10946     base::OnceCallback<void(TPM_RC)> error_reporter =
10947         base::BindOnce(ActivateCredentialErrorCallback, std::move(callback));
10948     std::move(error_reporter).Run(rc);
10949     return;
10950   }
10951   base::OnceCallback<void(const std::string&)> parser =
10952       base::BindOnce(ActivateCredentialResponseParser, std::move(callback),
10953                      authorization_delegate);
10954   transceiver_->SendCommand(command, std::move(parser));
10955 }
10956 
ActivateCredentialSync(const TPMI_DH_OBJECT & activate_handle,const std::string & activate_handle_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ID_OBJECT & credential_blob,const TPM2B_ENCRYPTED_SECRET & secret,TPM2B_DIGEST * cert_info,AuthorizationDelegate * authorization_delegate)10957 TPM_RC Tpm::ActivateCredentialSync(
10958     const TPMI_DH_OBJECT& activate_handle,
10959     const std::string& activate_handle_name,
10960     const TPMI_DH_OBJECT& key_handle,
10961     const std::string& key_handle_name,
10962     const TPM2B_ID_OBJECT& credential_blob,
10963     const TPM2B_ENCRYPTED_SECRET& secret,
10964     TPM2B_DIGEST* cert_info,
10965     AuthorizationDelegate* authorization_delegate) {
10966   VLOG(1) << __func__;
10967   std::string command;
10968   TPM_RC rc = SerializeCommand_ActivateCredential(
10969       activate_handle, activate_handle_name, key_handle, key_handle_name,
10970       credential_blob, secret, &command, authorization_delegate);
10971   if (rc != TPM_RC_SUCCESS) {
10972     return rc;
10973   }
10974   std::string response = transceiver_->SendCommandAndWait(command);
10975   rc = ParseResponse_ActivateCredential(response, cert_info,
10976                                         authorization_delegate);
10977   return rc;
10978 }
10979 
SerializeCommand_MakeCredential(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_DIGEST & credential,const TPM2B_NAME & object_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10980 TPM_RC Tpm::SerializeCommand_MakeCredential(
10981     const TPMI_DH_OBJECT& handle,
10982     const std::string& handle_name,
10983     const TPM2B_DIGEST& credential,
10984     const TPM2B_NAME& object_name,
10985     std::string* serialized_command,
10986     AuthorizationDelegate* authorization_delegate) {
10987   VLOG(3) << __func__;
10988   TPM_RC rc = TPM_RC_SUCCESS;
10989   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10990   UINT32 command_size = 10;  // Header size.
10991   std::string handle_section_bytes;
10992   std::string parameter_section_bytes;
10993   TPM_CC command_code = TPM_CC_MakeCredential;
10994   bool is_command_parameter_encryption_possible = true;
10995   bool is_response_parameter_encryption_possible = true;
10996   std::string command_code_bytes;
10997   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10998   if (rc != TPM_RC_SUCCESS) {
10999     return rc;
11000   }
11001   std::string handle_bytes;
11002   rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
11003   if (rc != TPM_RC_SUCCESS) {
11004     return rc;
11005   }
11006   std::string credential_bytes;
11007   rc = Serialize_TPM2B_DIGEST(credential, &credential_bytes);
11008   if (rc != TPM_RC_SUCCESS) {
11009     return rc;
11010   }
11011   std::string object_name_bytes;
11012   rc = Serialize_TPM2B_NAME(object_name, &object_name_bytes);
11013   if (rc != TPM_RC_SUCCESS) {
11014     return rc;
11015   }
11016   if (authorization_delegate) {
11017     // Encrypt just the parameter data, not the size.
11018     std::string tmp = credential_bytes.substr(2);
11019     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11020       return TRUNKS_RC_ENCRYPTION_FAILED;
11021     }
11022     credential_bytes.replace(2, std::string::npos, tmp);
11023   }
11024   std::unique_ptr<crypto::SecureHash> hash(
11025       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11026   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11027   hash->Update(handle_name.data(), handle_name.size());
11028   handle_section_bytes += handle_bytes;
11029   command_size += handle_bytes.size();
11030   hash->Update(credential_bytes.data(), credential_bytes.size());
11031   parameter_section_bytes += credential_bytes;
11032   command_size += credential_bytes.size();
11033   hash->Update(object_name_bytes.data(), object_name_bytes.size());
11034   parameter_section_bytes += object_name_bytes;
11035   command_size += object_name_bytes.size();
11036   std::string command_hash(32, 0);
11037   hash->Finish(std::data(command_hash), command_hash.size());
11038   std::string authorization_section_bytes;
11039   std::string authorization_size_bytes;
11040   if (authorization_delegate) {
11041     if (!authorization_delegate->GetCommandAuthorization(
11042             command_hash, is_command_parameter_encryption_possible,
11043             is_response_parameter_encryption_possible,
11044             &authorization_section_bytes)) {
11045       return TRUNKS_RC_AUTHORIZATION_FAILED;
11046     }
11047     if (!authorization_section_bytes.empty()) {
11048       tag = TPM_ST_SESSIONS;
11049       std::string tmp;
11050       rc = Serialize_UINT32(authorization_section_bytes.size(),
11051                             &authorization_size_bytes);
11052       if (rc != TPM_RC_SUCCESS) {
11053         return rc;
11054       }
11055       command_size +=
11056           authorization_size_bytes.size() + authorization_section_bytes.size();
11057     }
11058   }
11059   std::string tag_bytes;
11060   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11061   if (rc != TPM_RC_SUCCESS) {
11062     return rc;
11063   }
11064   std::string command_size_bytes;
11065   rc = Serialize_UINT32(command_size, &command_size_bytes);
11066   if (rc != TPM_RC_SUCCESS) {
11067     return rc;
11068   }
11069   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11070                         handle_section_bytes + authorization_size_bytes +
11071                         authorization_section_bytes + parameter_section_bytes;
11072   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11073   VLOG(2) << "Command: "
11074           << base::HexEncode(serialized_command->data(),
11075                              serialized_command->size());
11076   return TPM_RC_SUCCESS;
11077 }
11078 
ParseResponse_MakeCredential(const std::string & response,TPM2B_ID_OBJECT * credential_blob,TPM2B_ENCRYPTED_SECRET * secret,AuthorizationDelegate * authorization_delegate)11079 TPM_RC Tpm::ParseResponse_MakeCredential(
11080     const std::string& response,
11081     TPM2B_ID_OBJECT* credential_blob,
11082     TPM2B_ENCRYPTED_SECRET* secret,
11083     AuthorizationDelegate* authorization_delegate) {
11084   VLOG(3) << __func__;
11085   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11086   TPM_RC rc = TPM_RC_SUCCESS;
11087   std::string buffer(response);
11088   TPM_ST tag;
11089   std::string tag_bytes;
11090   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11091   if (rc != TPM_RC_SUCCESS) {
11092     return rc;
11093   }
11094   UINT32 response_size;
11095   std::string response_size_bytes;
11096   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11097   if (rc != TPM_RC_SUCCESS) {
11098     return rc;
11099   }
11100   TPM_RC response_code;
11101   std::string response_code_bytes;
11102   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11103   if (rc != TPM_RC_SUCCESS) {
11104     return rc;
11105   }
11106   if (response_size != response.size()) {
11107     return TPM_RC_SIZE;
11108   }
11109   if (response_code != TPM_RC_SUCCESS) {
11110     return response_code;
11111   }
11112   TPM_CC command_code = TPM_CC_MakeCredential;
11113   std::string command_code_bytes;
11114   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11115   if (rc != TPM_RC_SUCCESS) {
11116     return rc;
11117   }
11118   std::string authorization_section_bytes;
11119   if (tag == TPM_ST_SESSIONS) {
11120     UINT32 parameter_section_size = buffer.size();
11121     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11122     if (rc != TPM_RC_SUCCESS) {
11123       return rc;
11124     }
11125     if (parameter_section_size > buffer.size()) {
11126       return TPM_RC_INSUFFICIENT;
11127     }
11128     authorization_section_bytes = buffer.substr(parameter_section_size);
11129     // Keep the parameter section in |buffer|.
11130     buffer.erase(parameter_section_size);
11131   }
11132   std::unique_ptr<crypto::SecureHash> hash(
11133       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11134   hash->Update(response_code_bytes.data(), response_code_bytes.size());
11135   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11136   hash->Update(buffer.data(), buffer.size());
11137   std::string response_hash(32, 0);
11138   hash->Finish(std::data(response_hash), response_hash.size());
11139   if (tag == TPM_ST_SESSIONS) {
11140     if (!authorization_delegate)
11141       return TRUNKS_RC_AUTHORIZATION_FAILED;
11142     if (!authorization_delegate->CheckResponseAuthorization(
11143             response_hash, authorization_section_bytes)) {
11144       return TRUNKS_RC_AUTHORIZATION_FAILED;
11145     }
11146   }
11147   if (tag == TPM_ST_SESSIONS) {
11148     if (!authorization_delegate)
11149       return TRUNKS_RC_AUTHORIZATION_FAILED;
11150 
11151     // Parse the encrypted parameter size.
11152     UINT16 size;
11153     std::string size_buffer = buffer.substr(0, 2);
11154     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11155       return result;
11156     }
11157     if (buffer.size() < 2 + size) {
11158       return TPM_RC_INSUFFICIENT;
11159     }
11160 
11161     // Decrypt just the parameter data, not the size.
11162     std::string decrypted_data = buffer.substr(2, size);
11163     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11164       return TRUNKS_RC_ENCRYPTION_FAILED;
11165     }
11166     buffer.replace(2, size, decrypted_data);
11167   }
11168   std::string credential_blob_bytes;
11169   rc = Parse_TPM2B_ID_OBJECT(&buffer, credential_blob, &credential_blob_bytes);
11170   if (rc != TPM_RC_SUCCESS) {
11171     return rc;
11172   }
11173   std::string secret_bytes;
11174   rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, secret, &secret_bytes);
11175   if (rc != TPM_RC_SUCCESS) {
11176     return rc;
11177   }
11178   return TPM_RC_SUCCESS;
11179 }
11180 
MakeCredentialErrorCallback(Tpm::MakeCredentialResponse callback,TPM_RC response_code)11181 void MakeCredentialErrorCallback(Tpm::MakeCredentialResponse callback,
11182                                  TPM_RC response_code) {
11183   VLOG(1) << __func__;
11184   std::move(callback).Run(response_code, TPM2B_ID_OBJECT(),
11185                           TPM2B_ENCRYPTED_SECRET());
11186 }
11187 
MakeCredentialResponseParser(Tpm::MakeCredentialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11188 void MakeCredentialResponseParser(Tpm::MakeCredentialResponse callback,
11189                                   AuthorizationDelegate* authorization_delegate,
11190                                   const std::string& response) {
11191   VLOG(1) << __func__;
11192   TPM2B_ID_OBJECT credential_blob;
11193   TPM2B_ENCRYPTED_SECRET secret;
11194   TPM_RC rc = Tpm::ParseResponse_MakeCredential(
11195       response, &credential_blob, &secret, authorization_delegate);
11196   if (rc != TPM_RC_SUCCESS) {
11197     base::OnceCallback<void(TPM_RC)> error_reporter =
11198         base::BindOnce(MakeCredentialErrorCallback, std::move(callback));
11199     std::move(error_reporter).Run(rc);
11200     return;
11201   }
11202   std::move(callback).Run(rc, credential_blob, secret);
11203 }
11204 
MakeCredential(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_DIGEST & credential,const TPM2B_NAME & object_name,AuthorizationDelegate * authorization_delegate,MakeCredentialResponse callback)11205 void Tpm::MakeCredential(const TPMI_DH_OBJECT& handle,
11206                          const std::string& handle_name,
11207                          const TPM2B_DIGEST& credential,
11208                          const TPM2B_NAME& object_name,
11209                          AuthorizationDelegate* authorization_delegate,
11210                          MakeCredentialResponse callback) {
11211   VLOG(1) << __func__;
11212   std::string command;
11213   TPM_RC rc = SerializeCommand_MakeCredential(handle, handle_name, credential,
11214                                               object_name, &command,
11215                                               authorization_delegate);
11216   if (rc != TPM_RC_SUCCESS) {
11217     base::OnceCallback<void(TPM_RC)> error_reporter =
11218         base::BindOnce(MakeCredentialErrorCallback, std::move(callback));
11219     std::move(error_reporter).Run(rc);
11220     return;
11221   }
11222   base::OnceCallback<void(const std::string&)> parser =
11223       base::BindOnce(MakeCredentialResponseParser, std::move(callback),
11224                      authorization_delegate);
11225   transceiver_->SendCommand(command, std::move(parser));
11226 }
11227 
MakeCredentialSync(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_DIGEST & credential,const TPM2B_NAME & object_name,TPM2B_ID_OBJECT * credential_blob,TPM2B_ENCRYPTED_SECRET * secret,AuthorizationDelegate * authorization_delegate)11228 TPM_RC Tpm::MakeCredentialSync(const TPMI_DH_OBJECT& handle,
11229                                const std::string& handle_name,
11230                                const TPM2B_DIGEST& credential,
11231                                const TPM2B_NAME& object_name,
11232                                TPM2B_ID_OBJECT* credential_blob,
11233                                TPM2B_ENCRYPTED_SECRET* secret,
11234                                AuthorizationDelegate* authorization_delegate) {
11235   VLOG(1) << __func__;
11236   std::string command;
11237   TPM_RC rc = SerializeCommand_MakeCredential(handle, handle_name, credential,
11238                                               object_name, &command,
11239                                               authorization_delegate);
11240   if (rc != TPM_RC_SUCCESS) {
11241     return rc;
11242   }
11243   std::string response = transceiver_->SendCommandAndWait(command);
11244   rc = ParseResponse_MakeCredential(response, credential_blob, secret,
11245                                     authorization_delegate);
11246   return rc;
11247 }
11248 
SerializeCommand_Unseal(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)11249 TPM_RC Tpm::SerializeCommand_Unseal(
11250     const TPMI_DH_OBJECT& item_handle,
11251     const std::string& item_handle_name,
11252     std::string* serialized_command,
11253     AuthorizationDelegate* authorization_delegate) {
11254   VLOG(3) << __func__;
11255   TPM_RC rc = TPM_RC_SUCCESS;
11256   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11257   UINT32 command_size = 10;  // Header size.
11258   std::string handle_section_bytes;
11259   std::string parameter_section_bytes;
11260   TPM_CC command_code = TPM_CC_Unseal;
11261   bool is_command_parameter_encryption_possible = false;
11262   bool is_response_parameter_encryption_possible = true;
11263   std::string command_code_bytes;
11264   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11265   if (rc != TPM_RC_SUCCESS) {
11266     return rc;
11267   }
11268   std::string item_handle_bytes;
11269   rc = Serialize_TPMI_DH_OBJECT(item_handle, &item_handle_bytes);
11270   if (rc != TPM_RC_SUCCESS) {
11271     return rc;
11272   }
11273   std::unique_ptr<crypto::SecureHash> hash(
11274       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11275   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11276   hash->Update(item_handle_name.data(), item_handle_name.size());
11277   handle_section_bytes += item_handle_bytes;
11278   command_size += item_handle_bytes.size();
11279   std::string command_hash(32, 0);
11280   hash->Finish(std::data(command_hash), command_hash.size());
11281   std::string authorization_section_bytes;
11282   std::string authorization_size_bytes;
11283   if (authorization_delegate) {
11284     if (!authorization_delegate->GetCommandAuthorization(
11285             command_hash, is_command_parameter_encryption_possible,
11286             is_response_parameter_encryption_possible,
11287             &authorization_section_bytes)) {
11288       return TRUNKS_RC_AUTHORIZATION_FAILED;
11289     }
11290     if (!authorization_section_bytes.empty()) {
11291       tag = TPM_ST_SESSIONS;
11292       std::string tmp;
11293       rc = Serialize_UINT32(authorization_section_bytes.size(),
11294                             &authorization_size_bytes);
11295       if (rc != TPM_RC_SUCCESS) {
11296         return rc;
11297       }
11298       command_size +=
11299           authorization_size_bytes.size() + authorization_section_bytes.size();
11300     }
11301   }
11302   std::string tag_bytes;
11303   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11304   if (rc != TPM_RC_SUCCESS) {
11305     return rc;
11306   }
11307   std::string command_size_bytes;
11308   rc = Serialize_UINT32(command_size, &command_size_bytes);
11309   if (rc != TPM_RC_SUCCESS) {
11310     return rc;
11311   }
11312   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11313                         handle_section_bytes + authorization_size_bytes +
11314                         authorization_section_bytes + parameter_section_bytes;
11315   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11316   VLOG(2) << "Command: "
11317           << base::HexEncode(serialized_command->data(),
11318                              serialized_command->size());
11319   return TPM_RC_SUCCESS;
11320 }
11321 
ParseResponse_Unseal(const std::string & response,TPM2B_SENSITIVE_DATA * out_data,AuthorizationDelegate * authorization_delegate)11322 TPM_RC Tpm::ParseResponse_Unseal(
11323     const std::string& response,
11324     TPM2B_SENSITIVE_DATA* out_data,
11325     AuthorizationDelegate* authorization_delegate) {
11326   VLOG(3) << __func__;
11327   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11328   TPM_RC rc = TPM_RC_SUCCESS;
11329   std::string buffer(response);
11330   TPM_ST tag;
11331   std::string tag_bytes;
11332   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11333   if (rc != TPM_RC_SUCCESS) {
11334     return rc;
11335   }
11336   UINT32 response_size;
11337   std::string response_size_bytes;
11338   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11339   if (rc != TPM_RC_SUCCESS) {
11340     return rc;
11341   }
11342   TPM_RC response_code;
11343   std::string response_code_bytes;
11344   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11345   if (rc != TPM_RC_SUCCESS) {
11346     return rc;
11347   }
11348   if (response_size != response.size()) {
11349     return TPM_RC_SIZE;
11350   }
11351   if (response_code != TPM_RC_SUCCESS) {
11352     return response_code;
11353   }
11354   TPM_CC command_code = TPM_CC_Unseal;
11355   std::string command_code_bytes;
11356   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11357   if (rc != TPM_RC_SUCCESS) {
11358     return rc;
11359   }
11360   std::string authorization_section_bytes;
11361   if (tag == TPM_ST_SESSIONS) {
11362     UINT32 parameter_section_size = buffer.size();
11363     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11364     if (rc != TPM_RC_SUCCESS) {
11365       return rc;
11366     }
11367     if (parameter_section_size > buffer.size()) {
11368       return TPM_RC_INSUFFICIENT;
11369     }
11370     authorization_section_bytes = buffer.substr(parameter_section_size);
11371     // Keep the parameter section in |buffer|.
11372     buffer.erase(parameter_section_size);
11373   }
11374   std::unique_ptr<crypto::SecureHash> hash(
11375       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11376   hash->Update(response_code_bytes.data(), response_code_bytes.size());
11377   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11378   hash->Update(buffer.data(), buffer.size());
11379   std::string response_hash(32, 0);
11380   hash->Finish(std::data(response_hash), response_hash.size());
11381   if (tag == TPM_ST_SESSIONS) {
11382     if (!authorization_delegate)
11383       return TRUNKS_RC_AUTHORIZATION_FAILED;
11384     if (!authorization_delegate->CheckResponseAuthorization(
11385             response_hash, authorization_section_bytes)) {
11386       return TRUNKS_RC_AUTHORIZATION_FAILED;
11387     }
11388   }
11389   if (tag == TPM_ST_SESSIONS) {
11390     if (!authorization_delegate)
11391       return TRUNKS_RC_AUTHORIZATION_FAILED;
11392 
11393     // Parse the encrypted parameter size.
11394     UINT16 size;
11395     std::string size_buffer = buffer.substr(0, 2);
11396     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11397       return result;
11398     }
11399     if (buffer.size() < 2 + size) {
11400       return TPM_RC_INSUFFICIENT;
11401     }
11402 
11403     // Decrypt just the parameter data, not the size.
11404     std::string decrypted_data = buffer.substr(2, size);
11405     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11406       return TRUNKS_RC_ENCRYPTION_FAILED;
11407     }
11408     buffer.replace(2, size, decrypted_data);
11409   }
11410   std::string out_data_bytes;
11411   rc = Parse_TPM2B_SENSITIVE_DATA(&buffer, out_data, &out_data_bytes);
11412   if (rc != TPM_RC_SUCCESS) {
11413     return rc;
11414   }
11415   return TPM_RC_SUCCESS;
11416 }
11417 
UnsealErrorCallback(Tpm::UnsealResponse callback,TPM_RC response_code)11418 void UnsealErrorCallback(Tpm::UnsealResponse callback, TPM_RC response_code) {
11419   VLOG(1) << __func__;
11420   std::move(callback).Run(response_code, TPM2B_SENSITIVE_DATA());
11421 }
11422 
UnsealResponseParser(Tpm::UnsealResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11423 void UnsealResponseParser(Tpm::UnsealResponse callback,
11424                           AuthorizationDelegate* authorization_delegate,
11425                           const std::string& response) {
11426   VLOG(1) << __func__;
11427   TPM2B_SENSITIVE_DATA out_data;
11428   TPM_RC rc =
11429       Tpm::ParseResponse_Unseal(response, &out_data, authorization_delegate);
11430   if (rc != TPM_RC_SUCCESS) {
11431     base::OnceCallback<void(TPM_RC)> error_reporter =
11432         base::BindOnce(UnsealErrorCallback, std::move(callback));
11433     std::move(error_reporter).Run(rc);
11434     return;
11435   }
11436   std::move(callback).Run(rc, out_data);
11437 }
11438 
Unseal(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,AuthorizationDelegate * authorization_delegate,UnsealResponse callback)11439 void Tpm::Unseal(const TPMI_DH_OBJECT& item_handle,
11440                  const std::string& item_handle_name,
11441                  AuthorizationDelegate* authorization_delegate,
11442                  UnsealResponse callback) {
11443   VLOG(1) << __func__;
11444   std::string command;
11445   TPM_RC rc = SerializeCommand_Unseal(item_handle, item_handle_name, &command,
11446                                       authorization_delegate);
11447   if (rc != TPM_RC_SUCCESS) {
11448     base::OnceCallback<void(TPM_RC)> error_reporter =
11449         base::BindOnce(UnsealErrorCallback, std::move(callback));
11450     std::move(error_reporter).Run(rc);
11451     return;
11452   }
11453   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
11454       UnsealResponseParser, std::move(callback), authorization_delegate);
11455   transceiver_->SendCommand(command, std::move(parser));
11456 }
11457 
UnsealSync(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,TPM2B_SENSITIVE_DATA * out_data,AuthorizationDelegate * authorization_delegate)11458 TPM_RC Tpm::UnsealSync(const TPMI_DH_OBJECT& item_handle,
11459                        const std::string& item_handle_name,
11460                        TPM2B_SENSITIVE_DATA* out_data,
11461                        AuthorizationDelegate* authorization_delegate) {
11462   VLOG(1) << __func__;
11463   std::string command;
11464   TPM_RC rc = SerializeCommand_Unseal(item_handle, item_handle_name, &command,
11465                                       authorization_delegate);
11466   if (rc != TPM_RC_SUCCESS) {
11467     return rc;
11468   }
11469   std::string response = transceiver_->SendCommandAndWait(command);
11470   rc = ParseResponse_Unseal(response, out_data, authorization_delegate);
11471   return rc;
11472 }
11473 
SerializeCommand_ObjectChangeAuth(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_AUTH & new_auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)11474 TPM_RC Tpm::SerializeCommand_ObjectChangeAuth(
11475     const TPMI_DH_OBJECT& object_handle,
11476     const std::string& object_handle_name,
11477     const TPMI_DH_OBJECT& parent_handle,
11478     const std::string& parent_handle_name,
11479     const TPM2B_AUTH& new_auth,
11480     std::string* serialized_command,
11481     AuthorizationDelegate* authorization_delegate) {
11482   VLOG(3) << __func__;
11483   TPM_RC rc = TPM_RC_SUCCESS;
11484   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11485   UINT32 command_size = 10;  // Header size.
11486   std::string handle_section_bytes;
11487   std::string parameter_section_bytes;
11488   TPM_CC command_code = TPM_CC_ObjectChangeAuth;
11489   bool is_command_parameter_encryption_possible = true;
11490   bool is_response_parameter_encryption_possible = true;
11491   std::string command_code_bytes;
11492   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11493   if (rc != TPM_RC_SUCCESS) {
11494     return rc;
11495   }
11496   std::string object_handle_bytes;
11497   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
11498   if (rc != TPM_RC_SUCCESS) {
11499     return rc;
11500   }
11501   std::string parent_handle_bytes;
11502   rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
11503   if (rc != TPM_RC_SUCCESS) {
11504     return rc;
11505   }
11506   std::string new_auth_bytes;
11507   rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
11508   if (rc != TPM_RC_SUCCESS) {
11509     return rc;
11510   }
11511   if (authorization_delegate) {
11512     // Encrypt just the parameter data, not the size.
11513     std::string tmp = new_auth_bytes.substr(2);
11514     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11515       return TRUNKS_RC_ENCRYPTION_FAILED;
11516     }
11517     new_auth_bytes.replace(2, std::string::npos, tmp);
11518   }
11519   std::unique_ptr<crypto::SecureHash> hash(
11520       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11521   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11522   hash->Update(object_handle_name.data(), object_handle_name.size());
11523   handle_section_bytes += object_handle_bytes;
11524   command_size += object_handle_bytes.size();
11525   hash->Update(parent_handle_name.data(), parent_handle_name.size());
11526   handle_section_bytes += parent_handle_bytes;
11527   command_size += parent_handle_bytes.size();
11528   hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
11529   parameter_section_bytes += new_auth_bytes;
11530   command_size += new_auth_bytes.size();
11531   std::string command_hash(32, 0);
11532   hash->Finish(std::data(command_hash), command_hash.size());
11533   std::string authorization_section_bytes;
11534   std::string authorization_size_bytes;
11535   if (authorization_delegate) {
11536     if (!authorization_delegate->GetCommandAuthorization(
11537             command_hash, is_command_parameter_encryption_possible,
11538             is_response_parameter_encryption_possible,
11539             &authorization_section_bytes)) {
11540       return TRUNKS_RC_AUTHORIZATION_FAILED;
11541     }
11542     if (!authorization_section_bytes.empty()) {
11543       tag = TPM_ST_SESSIONS;
11544       std::string tmp;
11545       rc = Serialize_UINT32(authorization_section_bytes.size(),
11546                             &authorization_size_bytes);
11547       if (rc != TPM_RC_SUCCESS) {
11548         return rc;
11549       }
11550       command_size +=
11551           authorization_size_bytes.size() + authorization_section_bytes.size();
11552     }
11553   }
11554   std::string tag_bytes;
11555   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11556   if (rc != TPM_RC_SUCCESS) {
11557     return rc;
11558   }
11559   std::string command_size_bytes;
11560   rc = Serialize_UINT32(command_size, &command_size_bytes);
11561   if (rc != TPM_RC_SUCCESS) {
11562     return rc;
11563   }
11564   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11565                         handle_section_bytes + authorization_size_bytes +
11566                         authorization_section_bytes + parameter_section_bytes;
11567   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11568   VLOG(2) << "Command: "
11569           << base::HexEncode(serialized_command->data(),
11570                              serialized_command->size());
11571   return TPM_RC_SUCCESS;
11572 }
11573 
ParseResponse_ObjectChangeAuth(const std::string & response,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)11574 TPM_RC Tpm::ParseResponse_ObjectChangeAuth(
11575     const std::string& response,
11576     TPM2B_PRIVATE* out_private,
11577     AuthorizationDelegate* authorization_delegate) {
11578   VLOG(3) << __func__;
11579   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11580   TPM_RC rc = TPM_RC_SUCCESS;
11581   std::string buffer(response);
11582   TPM_ST tag;
11583   std::string tag_bytes;
11584   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11585   if (rc != TPM_RC_SUCCESS) {
11586     return rc;
11587   }
11588   UINT32 response_size;
11589   std::string response_size_bytes;
11590   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11591   if (rc != TPM_RC_SUCCESS) {
11592     return rc;
11593   }
11594   TPM_RC response_code;
11595   std::string response_code_bytes;
11596   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11597   if (rc != TPM_RC_SUCCESS) {
11598     return rc;
11599   }
11600   if (response_size != response.size()) {
11601     return TPM_RC_SIZE;
11602   }
11603   if (response_code != TPM_RC_SUCCESS) {
11604     return response_code;
11605   }
11606   TPM_CC command_code = TPM_CC_ObjectChangeAuth;
11607   std::string command_code_bytes;
11608   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11609   if (rc != TPM_RC_SUCCESS) {
11610     return rc;
11611   }
11612   std::string authorization_section_bytes;
11613   if (tag == TPM_ST_SESSIONS) {
11614     UINT32 parameter_section_size = buffer.size();
11615     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11616     if (rc != TPM_RC_SUCCESS) {
11617       return rc;
11618     }
11619     if (parameter_section_size > buffer.size()) {
11620       return TPM_RC_INSUFFICIENT;
11621     }
11622     authorization_section_bytes = buffer.substr(parameter_section_size);
11623     // Keep the parameter section in |buffer|.
11624     buffer.erase(parameter_section_size);
11625   }
11626   std::unique_ptr<crypto::SecureHash> hash(
11627       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11628   hash->Update(response_code_bytes.data(), response_code_bytes.size());
11629   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11630   hash->Update(buffer.data(), buffer.size());
11631   std::string response_hash(32, 0);
11632   hash->Finish(std::data(response_hash), response_hash.size());
11633   if (tag == TPM_ST_SESSIONS) {
11634     if (!authorization_delegate)
11635       return TRUNKS_RC_AUTHORIZATION_FAILED;
11636     if (!authorization_delegate->CheckResponseAuthorization(
11637             response_hash, authorization_section_bytes)) {
11638       return TRUNKS_RC_AUTHORIZATION_FAILED;
11639     }
11640   }
11641   if (tag == TPM_ST_SESSIONS) {
11642     if (!authorization_delegate)
11643       return TRUNKS_RC_AUTHORIZATION_FAILED;
11644 
11645     // Parse the encrypted parameter size.
11646     UINT16 size;
11647     std::string size_buffer = buffer.substr(0, 2);
11648     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11649       return result;
11650     }
11651     if (buffer.size() < 2 + size) {
11652       return TPM_RC_INSUFFICIENT;
11653     }
11654 
11655     // Decrypt just the parameter data, not the size.
11656     std::string decrypted_data = buffer.substr(2, size);
11657     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11658       return TRUNKS_RC_ENCRYPTION_FAILED;
11659     }
11660     buffer.replace(2, size, decrypted_data);
11661   }
11662   std::string out_private_bytes;
11663   rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
11664   if (rc != TPM_RC_SUCCESS) {
11665     return rc;
11666   }
11667   return TPM_RC_SUCCESS;
11668 }
11669 
ObjectChangeAuthErrorCallback(Tpm::ObjectChangeAuthResponse callback,TPM_RC response_code)11670 void ObjectChangeAuthErrorCallback(Tpm::ObjectChangeAuthResponse callback,
11671                                    TPM_RC response_code) {
11672   VLOG(1) << __func__;
11673   std::move(callback).Run(response_code, TPM2B_PRIVATE());
11674 }
11675 
ObjectChangeAuthResponseParser(Tpm::ObjectChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11676 void ObjectChangeAuthResponseParser(
11677     Tpm::ObjectChangeAuthResponse callback,
11678     AuthorizationDelegate* authorization_delegate,
11679     const std::string& response) {
11680   VLOG(1) << __func__;
11681   TPM2B_PRIVATE out_private;
11682   TPM_RC rc = Tpm::ParseResponse_ObjectChangeAuth(response, &out_private,
11683                                                   authorization_delegate);
11684   if (rc != TPM_RC_SUCCESS) {
11685     base::OnceCallback<void(TPM_RC)> error_reporter =
11686         base::BindOnce(ObjectChangeAuthErrorCallback, std::move(callback));
11687     std::move(error_reporter).Run(rc);
11688     return;
11689   }
11690   std::move(callback).Run(rc, out_private);
11691 }
11692 
ObjectChangeAuth(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate,ObjectChangeAuthResponse callback)11693 void Tpm::ObjectChangeAuth(const TPMI_DH_OBJECT& object_handle,
11694                            const std::string& object_handle_name,
11695                            const TPMI_DH_OBJECT& parent_handle,
11696                            const std::string& parent_handle_name,
11697                            const TPM2B_AUTH& new_auth,
11698                            AuthorizationDelegate* authorization_delegate,
11699                            ObjectChangeAuthResponse callback) {
11700   VLOG(1) << __func__;
11701   std::string command;
11702   TPM_RC rc = SerializeCommand_ObjectChangeAuth(
11703       object_handle, object_handle_name, parent_handle, parent_handle_name,
11704       new_auth, &command, authorization_delegate);
11705   if (rc != TPM_RC_SUCCESS) {
11706     base::OnceCallback<void(TPM_RC)> error_reporter =
11707         base::BindOnce(ObjectChangeAuthErrorCallback, std::move(callback));
11708     std::move(error_reporter).Run(rc);
11709     return;
11710   }
11711   base::OnceCallback<void(const std::string&)> parser =
11712       base::BindOnce(ObjectChangeAuthResponseParser, std::move(callback),
11713                      authorization_delegate);
11714   transceiver_->SendCommand(command, std::move(parser));
11715 }
11716 
ObjectChangeAuthSync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_AUTH & new_auth,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)11717 TPM_RC Tpm::ObjectChangeAuthSync(
11718     const TPMI_DH_OBJECT& object_handle,
11719     const std::string& object_handle_name,
11720     const TPMI_DH_OBJECT& parent_handle,
11721     const std::string& parent_handle_name,
11722     const TPM2B_AUTH& new_auth,
11723     TPM2B_PRIVATE* out_private,
11724     AuthorizationDelegate* authorization_delegate) {
11725   VLOG(1) << __func__;
11726   std::string command;
11727   TPM_RC rc = SerializeCommand_ObjectChangeAuth(
11728       object_handle, object_handle_name, parent_handle, parent_handle_name,
11729       new_auth, &command, authorization_delegate);
11730   if (rc != TPM_RC_SUCCESS) {
11731     return rc;
11732   }
11733   std::string response = transceiver_->SendCommandAndWait(command);
11734   rc = ParseResponse_ObjectChangeAuth(response, out_private,
11735                                       authorization_delegate);
11736   return rc;
11737 }
11738 
SerializeCommand_Duplicate(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & new_parent_handle,const std::string & new_parent_handle_name,const TPM2B_DATA & encryption_key_in,const TPMT_SYM_DEF_OBJECT & symmetric_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)11739 TPM_RC Tpm::SerializeCommand_Duplicate(
11740     const TPMI_DH_OBJECT& object_handle,
11741     const std::string& object_handle_name,
11742     const TPMI_DH_OBJECT& new_parent_handle,
11743     const std::string& new_parent_handle_name,
11744     const TPM2B_DATA& encryption_key_in,
11745     const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11746     std::string* serialized_command,
11747     AuthorizationDelegate* authorization_delegate) {
11748   VLOG(3) << __func__;
11749   TPM_RC rc = TPM_RC_SUCCESS;
11750   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11751   UINT32 command_size = 10;  // Header size.
11752   std::string handle_section_bytes;
11753   std::string parameter_section_bytes;
11754   TPM_CC command_code = TPM_CC_Duplicate;
11755   bool is_command_parameter_encryption_possible = true;
11756   bool is_response_parameter_encryption_possible = true;
11757   std::string command_code_bytes;
11758   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11759   if (rc != TPM_RC_SUCCESS) {
11760     return rc;
11761   }
11762   std::string object_handle_bytes;
11763   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
11764   if (rc != TPM_RC_SUCCESS) {
11765     return rc;
11766   }
11767   std::string new_parent_handle_bytes;
11768   rc = Serialize_TPMI_DH_OBJECT(new_parent_handle, &new_parent_handle_bytes);
11769   if (rc != TPM_RC_SUCCESS) {
11770     return rc;
11771   }
11772   std::string encryption_key_in_bytes;
11773   rc = Serialize_TPM2B_DATA(encryption_key_in, &encryption_key_in_bytes);
11774   if (rc != TPM_RC_SUCCESS) {
11775     return rc;
11776   }
11777   std::string symmetric_alg_bytes;
11778   rc = Serialize_TPMT_SYM_DEF_OBJECT(symmetric_alg, &symmetric_alg_bytes);
11779   if (rc != TPM_RC_SUCCESS) {
11780     return rc;
11781   }
11782   if (authorization_delegate) {
11783     // Encrypt just the parameter data, not the size.
11784     std::string tmp = encryption_key_in_bytes.substr(2);
11785     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11786       return TRUNKS_RC_ENCRYPTION_FAILED;
11787     }
11788     encryption_key_in_bytes.replace(2, std::string::npos, tmp);
11789   }
11790   std::unique_ptr<crypto::SecureHash> hash(
11791       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11792   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11793   hash->Update(object_handle_name.data(), object_handle_name.size());
11794   handle_section_bytes += object_handle_bytes;
11795   command_size += object_handle_bytes.size();
11796   hash->Update(new_parent_handle_name.data(), new_parent_handle_name.size());
11797   handle_section_bytes += new_parent_handle_bytes;
11798   command_size += new_parent_handle_bytes.size();
11799   hash->Update(encryption_key_in_bytes.data(), encryption_key_in_bytes.size());
11800   parameter_section_bytes += encryption_key_in_bytes;
11801   command_size += encryption_key_in_bytes.size();
11802   hash->Update(symmetric_alg_bytes.data(), symmetric_alg_bytes.size());
11803   parameter_section_bytes += symmetric_alg_bytes;
11804   command_size += symmetric_alg_bytes.size();
11805   std::string command_hash(32, 0);
11806   hash->Finish(std::data(command_hash), command_hash.size());
11807   std::string authorization_section_bytes;
11808   std::string authorization_size_bytes;
11809   if (authorization_delegate) {
11810     if (!authorization_delegate->GetCommandAuthorization(
11811             command_hash, is_command_parameter_encryption_possible,
11812             is_response_parameter_encryption_possible,
11813             &authorization_section_bytes)) {
11814       return TRUNKS_RC_AUTHORIZATION_FAILED;
11815     }
11816     if (!authorization_section_bytes.empty()) {
11817       tag = TPM_ST_SESSIONS;
11818       std::string tmp;
11819       rc = Serialize_UINT32(authorization_section_bytes.size(),
11820                             &authorization_size_bytes);
11821       if (rc != TPM_RC_SUCCESS) {
11822         return rc;
11823       }
11824       command_size +=
11825           authorization_size_bytes.size() + authorization_section_bytes.size();
11826     }
11827   }
11828   std::string tag_bytes;
11829   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11830   if (rc != TPM_RC_SUCCESS) {
11831     return rc;
11832   }
11833   std::string command_size_bytes;
11834   rc = Serialize_UINT32(command_size, &command_size_bytes);
11835   if (rc != TPM_RC_SUCCESS) {
11836     return rc;
11837   }
11838   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11839                         handle_section_bytes + authorization_size_bytes +
11840                         authorization_section_bytes + parameter_section_bytes;
11841   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11842   VLOG(2) << "Command: "
11843           << base::HexEncode(serialized_command->data(),
11844                              serialized_command->size());
11845   return TPM_RC_SUCCESS;
11846 }
11847 
ParseResponse_Duplicate(const std::string & response,TPM2B_DATA * encryption_key_out,TPM2B_PRIVATE * duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)11848 TPM_RC Tpm::ParseResponse_Duplicate(
11849     const std::string& response,
11850     TPM2B_DATA* encryption_key_out,
11851     TPM2B_PRIVATE* duplicate,
11852     TPM2B_ENCRYPTED_SECRET* out_sym_seed,
11853     AuthorizationDelegate* authorization_delegate) {
11854   VLOG(3) << __func__;
11855   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11856   TPM_RC rc = TPM_RC_SUCCESS;
11857   std::string buffer(response);
11858   TPM_ST tag;
11859   std::string tag_bytes;
11860   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11861   if (rc != TPM_RC_SUCCESS) {
11862     return rc;
11863   }
11864   UINT32 response_size;
11865   std::string response_size_bytes;
11866   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11867   if (rc != TPM_RC_SUCCESS) {
11868     return rc;
11869   }
11870   TPM_RC response_code;
11871   std::string response_code_bytes;
11872   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11873   if (rc != TPM_RC_SUCCESS) {
11874     return rc;
11875   }
11876   if (response_size != response.size()) {
11877     return TPM_RC_SIZE;
11878   }
11879   if (response_code != TPM_RC_SUCCESS) {
11880     return response_code;
11881   }
11882   TPM_CC command_code = TPM_CC_Duplicate;
11883   std::string command_code_bytes;
11884   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11885   if (rc != TPM_RC_SUCCESS) {
11886     return rc;
11887   }
11888   std::string authorization_section_bytes;
11889   if (tag == TPM_ST_SESSIONS) {
11890     UINT32 parameter_section_size = buffer.size();
11891     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11892     if (rc != TPM_RC_SUCCESS) {
11893       return rc;
11894     }
11895     if (parameter_section_size > buffer.size()) {
11896       return TPM_RC_INSUFFICIENT;
11897     }
11898     authorization_section_bytes = buffer.substr(parameter_section_size);
11899     // Keep the parameter section in |buffer|.
11900     buffer.erase(parameter_section_size);
11901   }
11902   std::unique_ptr<crypto::SecureHash> hash(
11903       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11904   hash->Update(response_code_bytes.data(), response_code_bytes.size());
11905   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11906   hash->Update(buffer.data(), buffer.size());
11907   std::string response_hash(32, 0);
11908   hash->Finish(std::data(response_hash), response_hash.size());
11909   if (tag == TPM_ST_SESSIONS) {
11910     if (!authorization_delegate)
11911       return TRUNKS_RC_AUTHORIZATION_FAILED;
11912     if (!authorization_delegate->CheckResponseAuthorization(
11913             response_hash, authorization_section_bytes)) {
11914       return TRUNKS_RC_AUTHORIZATION_FAILED;
11915     }
11916   }
11917   if (tag == TPM_ST_SESSIONS) {
11918     if (!authorization_delegate)
11919       return TRUNKS_RC_AUTHORIZATION_FAILED;
11920 
11921     // Parse the encrypted parameter size.
11922     UINT16 size;
11923     std::string size_buffer = buffer.substr(0, 2);
11924     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11925       return result;
11926     }
11927     if (buffer.size() < 2 + size) {
11928       return TPM_RC_INSUFFICIENT;
11929     }
11930 
11931     // Decrypt just the parameter data, not the size.
11932     std::string decrypted_data = buffer.substr(2, size);
11933     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11934       return TRUNKS_RC_ENCRYPTION_FAILED;
11935     }
11936     buffer.replace(2, size, decrypted_data);
11937   }
11938   std::string encryption_key_out_bytes;
11939   rc = Parse_TPM2B_DATA(&buffer, encryption_key_out, &encryption_key_out_bytes);
11940   if (rc != TPM_RC_SUCCESS) {
11941     return rc;
11942   }
11943   std::string duplicate_bytes;
11944   rc = Parse_TPM2B_PRIVATE(&buffer, duplicate, &duplicate_bytes);
11945   if (rc != TPM_RC_SUCCESS) {
11946     return rc;
11947   }
11948   std::string out_sym_seed_bytes;
11949   rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, out_sym_seed, &out_sym_seed_bytes);
11950   if (rc != TPM_RC_SUCCESS) {
11951     return rc;
11952   }
11953   return TPM_RC_SUCCESS;
11954 }
11955 
DuplicateErrorCallback(Tpm::DuplicateResponse callback,TPM_RC response_code)11956 void DuplicateErrorCallback(Tpm::DuplicateResponse callback,
11957                             TPM_RC response_code) {
11958   VLOG(1) << __func__;
11959   std::move(callback).Run(response_code, TPM2B_DATA(), TPM2B_PRIVATE(),
11960                           TPM2B_ENCRYPTED_SECRET());
11961 }
11962 
DuplicateResponseParser(Tpm::DuplicateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11963 void DuplicateResponseParser(Tpm::DuplicateResponse callback,
11964                              AuthorizationDelegate* authorization_delegate,
11965                              const std::string& response) {
11966   VLOG(1) << __func__;
11967   TPM2B_DATA encryption_key_out;
11968   TPM2B_PRIVATE duplicate;
11969   TPM2B_ENCRYPTED_SECRET out_sym_seed;
11970   TPM_RC rc =
11971       Tpm::ParseResponse_Duplicate(response, &encryption_key_out, &duplicate,
11972                                    &out_sym_seed, authorization_delegate);
11973   if (rc != TPM_RC_SUCCESS) {
11974     base::OnceCallback<void(TPM_RC)> error_reporter =
11975         base::BindOnce(DuplicateErrorCallback, std::move(callback));
11976     std::move(error_reporter).Run(rc);
11977     return;
11978   }
11979   std::move(callback).Run(rc, encryption_key_out, duplicate, out_sym_seed);
11980 }
11981 
Duplicate(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & new_parent_handle,const std::string & new_parent_handle_name,const TPM2B_DATA & encryption_key_in,const TPMT_SYM_DEF_OBJECT & symmetric_alg,AuthorizationDelegate * authorization_delegate,DuplicateResponse callback)11982 void Tpm::Duplicate(const TPMI_DH_OBJECT& object_handle,
11983                     const std::string& object_handle_name,
11984                     const TPMI_DH_OBJECT& new_parent_handle,
11985                     const std::string& new_parent_handle_name,
11986                     const TPM2B_DATA& encryption_key_in,
11987                     const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11988                     AuthorizationDelegate* authorization_delegate,
11989                     DuplicateResponse callback) {
11990   VLOG(1) << __func__;
11991   std::string command;
11992   TPM_RC rc = SerializeCommand_Duplicate(
11993       object_handle, object_handle_name, new_parent_handle,
11994       new_parent_handle_name, encryption_key_in, symmetric_alg, &command,
11995       authorization_delegate);
11996   if (rc != TPM_RC_SUCCESS) {
11997     base::OnceCallback<void(TPM_RC)> error_reporter =
11998         base::BindOnce(DuplicateErrorCallback, std::move(callback));
11999     std::move(error_reporter).Run(rc);
12000     return;
12001   }
12002   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12003       DuplicateResponseParser, std::move(callback), authorization_delegate);
12004   transceiver_->SendCommand(command, std::move(parser));
12005 }
12006 
DuplicateSync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & new_parent_handle,const std::string & new_parent_handle_name,const TPM2B_DATA & encryption_key_in,const TPMT_SYM_DEF_OBJECT & symmetric_alg,TPM2B_DATA * encryption_key_out,TPM2B_PRIVATE * duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)12007 TPM_RC Tpm::DuplicateSync(const TPMI_DH_OBJECT& object_handle,
12008                           const std::string& object_handle_name,
12009                           const TPMI_DH_OBJECT& new_parent_handle,
12010                           const std::string& new_parent_handle_name,
12011                           const TPM2B_DATA& encryption_key_in,
12012                           const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12013                           TPM2B_DATA* encryption_key_out,
12014                           TPM2B_PRIVATE* duplicate,
12015                           TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12016                           AuthorizationDelegate* authorization_delegate) {
12017   VLOG(1) << __func__;
12018   std::string command;
12019   TPM_RC rc = SerializeCommand_Duplicate(
12020       object_handle, object_handle_name, new_parent_handle,
12021       new_parent_handle_name, encryption_key_in, symmetric_alg, &command,
12022       authorization_delegate);
12023   if (rc != TPM_RC_SUCCESS) {
12024     return rc;
12025   }
12026   std::string response = transceiver_->SendCommandAndWait(command);
12027   rc = ParseResponse_Duplicate(response, encryption_key_out, duplicate,
12028                                out_sym_seed, authorization_delegate);
12029   return rc;
12030 }
12031 
SerializeCommand_Rewrap(const TPMI_DH_OBJECT & old_parent,const std::string & old_parent_name,const TPMI_DH_OBJECT & new_parent,const std::string & new_parent_name,const TPM2B_PRIVATE & in_duplicate,const TPM2B_NAME & name,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12032 TPM_RC Tpm::SerializeCommand_Rewrap(
12033     const TPMI_DH_OBJECT& old_parent,
12034     const std::string& old_parent_name,
12035     const TPMI_DH_OBJECT& new_parent,
12036     const std::string& new_parent_name,
12037     const TPM2B_PRIVATE& in_duplicate,
12038     const TPM2B_NAME& name,
12039     const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12040     std::string* serialized_command,
12041     AuthorizationDelegate* authorization_delegate) {
12042   VLOG(3) << __func__;
12043   TPM_RC rc = TPM_RC_SUCCESS;
12044   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12045   UINT32 command_size = 10;  // Header size.
12046   std::string handle_section_bytes;
12047   std::string parameter_section_bytes;
12048   TPM_CC command_code = TPM_CC_Rewrap;
12049   bool is_command_parameter_encryption_possible = true;
12050   bool is_response_parameter_encryption_possible = true;
12051   std::string command_code_bytes;
12052   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12053   if (rc != TPM_RC_SUCCESS) {
12054     return rc;
12055   }
12056   std::string old_parent_bytes;
12057   rc = Serialize_TPMI_DH_OBJECT(old_parent, &old_parent_bytes);
12058   if (rc != TPM_RC_SUCCESS) {
12059     return rc;
12060   }
12061   std::string new_parent_bytes;
12062   rc = Serialize_TPMI_DH_OBJECT(new_parent, &new_parent_bytes);
12063   if (rc != TPM_RC_SUCCESS) {
12064     return rc;
12065   }
12066   std::string in_duplicate_bytes;
12067   rc = Serialize_TPM2B_PRIVATE(in_duplicate, &in_duplicate_bytes);
12068   if (rc != TPM_RC_SUCCESS) {
12069     return rc;
12070   }
12071   std::string name_bytes;
12072   rc = Serialize_TPM2B_NAME(name, &name_bytes);
12073   if (rc != TPM_RC_SUCCESS) {
12074     return rc;
12075   }
12076   std::string in_sym_seed_bytes;
12077   rc = Serialize_TPM2B_ENCRYPTED_SECRET(in_sym_seed, &in_sym_seed_bytes);
12078   if (rc != TPM_RC_SUCCESS) {
12079     return rc;
12080   }
12081   if (authorization_delegate) {
12082     // Encrypt just the parameter data, not the size.
12083     std::string tmp = in_duplicate_bytes.substr(2);
12084     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12085       return TRUNKS_RC_ENCRYPTION_FAILED;
12086     }
12087     in_duplicate_bytes.replace(2, std::string::npos, tmp);
12088   }
12089   std::unique_ptr<crypto::SecureHash> hash(
12090       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12091   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12092   hash->Update(old_parent_name.data(), old_parent_name.size());
12093   handle_section_bytes += old_parent_bytes;
12094   command_size += old_parent_bytes.size();
12095   hash->Update(new_parent_name.data(), new_parent_name.size());
12096   handle_section_bytes += new_parent_bytes;
12097   command_size += new_parent_bytes.size();
12098   hash->Update(in_duplicate_bytes.data(), in_duplicate_bytes.size());
12099   parameter_section_bytes += in_duplicate_bytes;
12100   command_size += in_duplicate_bytes.size();
12101   hash->Update(name_bytes.data(), name_bytes.size());
12102   parameter_section_bytes += name_bytes;
12103   command_size += name_bytes.size();
12104   hash->Update(in_sym_seed_bytes.data(), in_sym_seed_bytes.size());
12105   parameter_section_bytes += in_sym_seed_bytes;
12106   command_size += in_sym_seed_bytes.size();
12107   std::string command_hash(32, 0);
12108   hash->Finish(std::data(command_hash), command_hash.size());
12109   std::string authorization_section_bytes;
12110   std::string authorization_size_bytes;
12111   if (authorization_delegate) {
12112     if (!authorization_delegate->GetCommandAuthorization(
12113             command_hash, is_command_parameter_encryption_possible,
12114             is_response_parameter_encryption_possible,
12115             &authorization_section_bytes)) {
12116       return TRUNKS_RC_AUTHORIZATION_FAILED;
12117     }
12118     if (!authorization_section_bytes.empty()) {
12119       tag = TPM_ST_SESSIONS;
12120       std::string tmp;
12121       rc = Serialize_UINT32(authorization_section_bytes.size(),
12122                             &authorization_size_bytes);
12123       if (rc != TPM_RC_SUCCESS) {
12124         return rc;
12125       }
12126       command_size +=
12127           authorization_size_bytes.size() + authorization_section_bytes.size();
12128     }
12129   }
12130   std::string tag_bytes;
12131   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12132   if (rc != TPM_RC_SUCCESS) {
12133     return rc;
12134   }
12135   std::string command_size_bytes;
12136   rc = Serialize_UINT32(command_size, &command_size_bytes);
12137   if (rc != TPM_RC_SUCCESS) {
12138     return rc;
12139   }
12140   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12141                         handle_section_bytes + authorization_size_bytes +
12142                         authorization_section_bytes + parameter_section_bytes;
12143   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12144   VLOG(2) << "Command: "
12145           << base::HexEncode(serialized_command->data(),
12146                              serialized_command->size());
12147   return TPM_RC_SUCCESS;
12148 }
12149 
ParseResponse_Rewrap(const std::string & response,TPM2B_PRIVATE * out_duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)12150 TPM_RC Tpm::ParseResponse_Rewrap(
12151     const std::string& response,
12152     TPM2B_PRIVATE* out_duplicate,
12153     TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12154     AuthorizationDelegate* authorization_delegate) {
12155   VLOG(3) << __func__;
12156   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12157   TPM_RC rc = TPM_RC_SUCCESS;
12158   std::string buffer(response);
12159   TPM_ST tag;
12160   std::string tag_bytes;
12161   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12162   if (rc != TPM_RC_SUCCESS) {
12163     return rc;
12164   }
12165   UINT32 response_size;
12166   std::string response_size_bytes;
12167   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12168   if (rc != TPM_RC_SUCCESS) {
12169     return rc;
12170   }
12171   TPM_RC response_code;
12172   std::string response_code_bytes;
12173   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12174   if (rc != TPM_RC_SUCCESS) {
12175     return rc;
12176   }
12177   if (response_size != response.size()) {
12178     return TPM_RC_SIZE;
12179   }
12180   if (response_code != TPM_RC_SUCCESS) {
12181     return response_code;
12182   }
12183   TPM_CC command_code = TPM_CC_Rewrap;
12184   std::string command_code_bytes;
12185   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12186   if (rc != TPM_RC_SUCCESS) {
12187     return rc;
12188   }
12189   std::string authorization_section_bytes;
12190   if (tag == TPM_ST_SESSIONS) {
12191     UINT32 parameter_section_size = buffer.size();
12192     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
12193     if (rc != TPM_RC_SUCCESS) {
12194       return rc;
12195     }
12196     if (parameter_section_size > buffer.size()) {
12197       return TPM_RC_INSUFFICIENT;
12198     }
12199     authorization_section_bytes = buffer.substr(parameter_section_size);
12200     // Keep the parameter section in |buffer|.
12201     buffer.erase(parameter_section_size);
12202   }
12203   std::unique_ptr<crypto::SecureHash> hash(
12204       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12205   hash->Update(response_code_bytes.data(), response_code_bytes.size());
12206   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12207   hash->Update(buffer.data(), buffer.size());
12208   std::string response_hash(32, 0);
12209   hash->Finish(std::data(response_hash), response_hash.size());
12210   if (tag == TPM_ST_SESSIONS) {
12211     if (!authorization_delegate)
12212       return TRUNKS_RC_AUTHORIZATION_FAILED;
12213     if (!authorization_delegate->CheckResponseAuthorization(
12214             response_hash, authorization_section_bytes)) {
12215       return TRUNKS_RC_AUTHORIZATION_FAILED;
12216     }
12217   }
12218   if (tag == TPM_ST_SESSIONS) {
12219     if (!authorization_delegate)
12220       return TRUNKS_RC_AUTHORIZATION_FAILED;
12221 
12222     // Parse the encrypted parameter size.
12223     UINT16 size;
12224     std::string size_buffer = buffer.substr(0, 2);
12225     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12226       return result;
12227     }
12228     if (buffer.size() < 2 + size) {
12229       return TPM_RC_INSUFFICIENT;
12230     }
12231 
12232     // Decrypt just the parameter data, not the size.
12233     std::string decrypted_data = buffer.substr(2, size);
12234     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12235       return TRUNKS_RC_ENCRYPTION_FAILED;
12236     }
12237     buffer.replace(2, size, decrypted_data);
12238   }
12239   std::string out_duplicate_bytes;
12240   rc = Parse_TPM2B_PRIVATE(&buffer, out_duplicate, &out_duplicate_bytes);
12241   if (rc != TPM_RC_SUCCESS) {
12242     return rc;
12243   }
12244   std::string out_sym_seed_bytes;
12245   rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, out_sym_seed, &out_sym_seed_bytes);
12246   if (rc != TPM_RC_SUCCESS) {
12247     return rc;
12248   }
12249   return TPM_RC_SUCCESS;
12250 }
12251 
RewrapErrorCallback(Tpm::RewrapResponse callback,TPM_RC response_code)12252 void RewrapErrorCallback(Tpm::RewrapResponse callback, TPM_RC response_code) {
12253   VLOG(1) << __func__;
12254   std::move(callback).Run(response_code, TPM2B_PRIVATE(),
12255                           TPM2B_ENCRYPTED_SECRET());
12256 }
12257 
RewrapResponseParser(Tpm::RewrapResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12258 void RewrapResponseParser(Tpm::RewrapResponse callback,
12259                           AuthorizationDelegate* authorization_delegate,
12260                           const std::string& response) {
12261   VLOG(1) << __func__;
12262   TPM2B_PRIVATE out_duplicate;
12263   TPM2B_ENCRYPTED_SECRET out_sym_seed;
12264   TPM_RC rc = Tpm::ParseResponse_Rewrap(response, &out_duplicate, &out_sym_seed,
12265                                         authorization_delegate);
12266   if (rc != TPM_RC_SUCCESS) {
12267     base::OnceCallback<void(TPM_RC)> error_reporter =
12268         base::BindOnce(RewrapErrorCallback, std::move(callback));
12269     std::move(error_reporter).Run(rc);
12270     return;
12271   }
12272   std::move(callback).Run(rc, out_duplicate, out_sym_seed);
12273 }
12274 
Rewrap(const TPMI_DH_OBJECT & old_parent,const std::string & old_parent_name,const TPMI_DH_OBJECT & new_parent,const std::string & new_parent_name,const TPM2B_PRIVATE & in_duplicate,const TPM2B_NAME & name,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,AuthorizationDelegate * authorization_delegate,RewrapResponse callback)12275 void Tpm::Rewrap(const TPMI_DH_OBJECT& old_parent,
12276                  const std::string& old_parent_name,
12277                  const TPMI_DH_OBJECT& new_parent,
12278                  const std::string& new_parent_name,
12279                  const TPM2B_PRIVATE& in_duplicate,
12280                  const TPM2B_NAME& name,
12281                  const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12282                  AuthorizationDelegate* authorization_delegate,
12283                  RewrapResponse callback) {
12284   VLOG(1) << __func__;
12285   std::string command;
12286   TPM_RC rc = SerializeCommand_Rewrap(
12287       old_parent, old_parent_name, new_parent, new_parent_name, in_duplicate,
12288       name, in_sym_seed, &command, authorization_delegate);
12289   if (rc != TPM_RC_SUCCESS) {
12290     base::OnceCallback<void(TPM_RC)> error_reporter =
12291         base::BindOnce(RewrapErrorCallback, std::move(callback));
12292     std::move(error_reporter).Run(rc);
12293     return;
12294   }
12295   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12296       RewrapResponseParser, std::move(callback), authorization_delegate);
12297   transceiver_->SendCommand(command, std::move(parser));
12298 }
12299 
RewrapSync(const TPMI_DH_OBJECT & old_parent,const std::string & old_parent_name,const TPMI_DH_OBJECT & new_parent,const std::string & new_parent_name,const TPM2B_PRIVATE & in_duplicate,const TPM2B_NAME & name,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,TPM2B_PRIVATE * out_duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)12300 TPM_RC Tpm::RewrapSync(const TPMI_DH_OBJECT& old_parent,
12301                        const std::string& old_parent_name,
12302                        const TPMI_DH_OBJECT& new_parent,
12303                        const std::string& new_parent_name,
12304                        const TPM2B_PRIVATE& in_duplicate,
12305                        const TPM2B_NAME& name,
12306                        const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12307                        TPM2B_PRIVATE* out_duplicate,
12308                        TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12309                        AuthorizationDelegate* authorization_delegate) {
12310   VLOG(1) << __func__;
12311   std::string command;
12312   TPM_RC rc = SerializeCommand_Rewrap(
12313       old_parent, old_parent_name, new_parent, new_parent_name, in_duplicate,
12314       name, in_sym_seed, &command, authorization_delegate);
12315   if (rc != TPM_RC_SUCCESS) {
12316     return rc;
12317   }
12318   std::string response = transceiver_->SendCommandAndWait(command);
12319   rc = ParseResponse_Rewrap(response, out_duplicate, out_sym_seed,
12320                             authorization_delegate);
12321   return rc;
12322 }
12323 
SerializeCommand_Import(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_DATA & encryption_key,const TPM2B_PUBLIC & object_public,const TPM2B_PRIVATE & duplicate,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,const TPMT_SYM_DEF_OBJECT & symmetric_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12324 TPM_RC Tpm::SerializeCommand_Import(
12325     const TPMI_DH_OBJECT& parent_handle,
12326     const std::string& parent_handle_name,
12327     const TPM2B_DATA& encryption_key,
12328     const TPM2B_PUBLIC& object_public,
12329     const TPM2B_PRIVATE& duplicate,
12330     const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12331     const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12332     std::string* serialized_command,
12333     AuthorizationDelegate* authorization_delegate) {
12334   VLOG(3) << __func__;
12335   TPM_RC rc = TPM_RC_SUCCESS;
12336   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12337   UINT32 command_size = 10;  // Header size.
12338   std::string handle_section_bytes;
12339   std::string parameter_section_bytes;
12340   TPM_CC command_code = TPM_CC_Import;
12341   bool is_command_parameter_encryption_possible = true;
12342   bool is_response_parameter_encryption_possible = true;
12343   std::string command_code_bytes;
12344   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12345   if (rc != TPM_RC_SUCCESS) {
12346     return rc;
12347   }
12348   std::string parent_handle_bytes;
12349   rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
12350   if (rc != TPM_RC_SUCCESS) {
12351     return rc;
12352   }
12353   std::string encryption_key_bytes;
12354   rc = Serialize_TPM2B_DATA(encryption_key, &encryption_key_bytes);
12355   if (rc != TPM_RC_SUCCESS) {
12356     return rc;
12357   }
12358   std::string object_public_bytes;
12359   rc = Serialize_TPM2B_PUBLIC(object_public, &object_public_bytes);
12360   if (rc != TPM_RC_SUCCESS) {
12361     return rc;
12362   }
12363   std::string duplicate_bytes;
12364   rc = Serialize_TPM2B_PRIVATE(duplicate, &duplicate_bytes);
12365   if (rc != TPM_RC_SUCCESS) {
12366     return rc;
12367   }
12368   std::string in_sym_seed_bytes;
12369   rc = Serialize_TPM2B_ENCRYPTED_SECRET(in_sym_seed, &in_sym_seed_bytes);
12370   if (rc != TPM_RC_SUCCESS) {
12371     return rc;
12372   }
12373   std::string symmetric_alg_bytes;
12374   rc = Serialize_TPMT_SYM_DEF_OBJECT(symmetric_alg, &symmetric_alg_bytes);
12375   if (rc != TPM_RC_SUCCESS) {
12376     return rc;
12377   }
12378   if (authorization_delegate) {
12379     // Encrypt just the parameter data, not the size.
12380     std::string tmp = encryption_key_bytes.substr(2);
12381     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12382       return TRUNKS_RC_ENCRYPTION_FAILED;
12383     }
12384     encryption_key_bytes.replace(2, std::string::npos, tmp);
12385   }
12386   std::unique_ptr<crypto::SecureHash> hash(
12387       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12388   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12389   hash->Update(parent_handle_name.data(), parent_handle_name.size());
12390   handle_section_bytes += parent_handle_bytes;
12391   command_size += parent_handle_bytes.size();
12392   hash->Update(encryption_key_bytes.data(), encryption_key_bytes.size());
12393   parameter_section_bytes += encryption_key_bytes;
12394   command_size += encryption_key_bytes.size();
12395   hash->Update(object_public_bytes.data(), object_public_bytes.size());
12396   parameter_section_bytes += object_public_bytes;
12397   command_size += object_public_bytes.size();
12398   hash->Update(duplicate_bytes.data(), duplicate_bytes.size());
12399   parameter_section_bytes += duplicate_bytes;
12400   command_size += duplicate_bytes.size();
12401   hash->Update(in_sym_seed_bytes.data(), in_sym_seed_bytes.size());
12402   parameter_section_bytes += in_sym_seed_bytes;
12403   command_size += in_sym_seed_bytes.size();
12404   hash->Update(symmetric_alg_bytes.data(), symmetric_alg_bytes.size());
12405   parameter_section_bytes += symmetric_alg_bytes;
12406   command_size += symmetric_alg_bytes.size();
12407   std::string command_hash(32, 0);
12408   hash->Finish(std::data(command_hash), command_hash.size());
12409   std::string authorization_section_bytes;
12410   std::string authorization_size_bytes;
12411   if (authorization_delegate) {
12412     if (!authorization_delegate->GetCommandAuthorization(
12413             command_hash, is_command_parameter_encryption_possible,
12414             is_response_parameter_encryption_possible,
12415             &authorization_section_bytes)) {
12416       return TRUNKS_RC_AUTHORIZATION_FAILED;
12417     }
12418     if (!authorization_section_bytes.empty()) {
12419       tag = TPM_ST_SESSIONS;
12420       std::string tmp;
12421       rc = Serialize_UINT32(authorization_section_bytes.size(),
12422                             &authorization_size_bytes);
12423       if (rc != TPM_RC_SUCCESS) {
12424         return rc;
12425       }
12426       command_size +=
12427           authorization_size_bytes.size() + authorization_section_bytes.size();
12428     }
12429   }
12430   std::string tag_bytes;
12431   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12432   if (rc != TPM_RC_SUCCESS) {
12433     return rc;
12434   }
12435   std::string command_size_bytes;
12436   rc = Serialize_UINT32(command_size, &command_size_bytes);
12437   if (rc != TPM_RC_SUCCESS) {
12438     return rc;
12439   }
12440   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12441                         handle_section_bytes + authorization_size_bytes +
12442                         authorization_section_bytes + parameter_section_bytes;
12443   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12444   VLOG(2) << "Command: "
12445           << base::HexEncode(serialized_command->data(),
12446                              serialized_command->size());
12447   return TPM_RC_SUCCESS;
12448 }
12449 
ParseResponse_Import(const std::string & response,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)12450 TPM_RC Tpm::ParseResponse_Import(
12451     const std::string& response,
12452     TPM2B_PRIVATE* out_private,
12453     AuthorizationDelegate* authorization_delegate) {
12454   VLOG(3) << __func__;
12455   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12456   TPM_RC rc = TPM_RC_SUCCESS;
12457   std::string buffer(response);
12458   TPM_ST tag;
12459   std::string tag_bytes;
12460   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12461   if (rc != TPM_RC_SUCCESS) {
12462     return rc;
12463   }
12464   UINT32 response_size;
12465   std::string response_size_bytes;
12466   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12467   if (rc != TPM_RC_SUCCESS) {
12468     return rc;
12469   }
12470   TPM_RC response_code;
12471   std::string response_code_bytes;
12472   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12473   if (rc != TPM_RC_SUCCESS) {
12474     return rc;
12475   }
12476   if (response_size != response.size()) {
12477     return TPM_RC_SIZE;
12478   }
12479   if (response_code != TPM_RC_SUCCESS) {
12480     return response_code;
12481   }
12482   TPM_CC command_code = TPM_CC_Import;
12483   std::string command_code_bytes;
12484   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12485   if (rc != TPM_RC_SUCCESS) {
12486     return rc;
12487   }
12488   std::string authorization_section_bytes;
12489   if (tag == TPM_ST_SESSIONS) {
12490     UINT32 parameter_section_size = buffer.size();
12491     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
12492     if (rc != TPM_RC_SUCCESS) {
12493       return rc;
12494     }
12495     if (parameter_section_size > buffer.size()) {
12496       return TPM_RC_INSUFFICIENT;
12497     }
12498     authorization_section_bytes = buffer.substr(parameter_section_size);
12499     // Keep the parameter section in |buffer|.
12500     buffer.erase(parameter_section_size);
12501   }
12502   std::unique_ptr<crypto::SecureHash> hash(
12503       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12504   hash->Update(response_code_bytes.data(), response_code_bytes.size());
12505   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12506   hash->Update(buffer.data(), buffer.size());
12507   std::string response_hash(32, 0);
12508   hash->Finish(std::data(response_hash), response_hash.size());
12509   if (tag == TPM_ST_SESSIONS) {
12510     if (!authorization_delegate)
12511       return TRUNKS_RC_AUTHORIZATION_FAILED;
12512     if (!authorization_delegate->CheckResponseAuthorization(
12513             response_hash, authorization_section_bytes)) {
12514       return TRUNKS_RC_AUTHORIZATION_FAILED;
12515     }
12516   }
12517   if (tag == TPM_ST_SESSIONS) {
12518     if (!authorization_delegate)
12519       return TRUNKS_RC_AUTHORIZATION_FAILED;
12520 
12521     // Parse the encrypted parameter size.
12522     UINT16 size;
12523     std::string size_buffer = buffer.substr(0, 2);
12524     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12525       return result;
12526     }
12527     if (buffer.size() < 2 + size) {
12528       return TPM_RC_INSUFFICIENT;
12529     }
12530 
12531     // Decrypt just the parameter data, not the size.
12532     std::string decrypted_data = buffer.substr(2, size);
12533     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12534       return TRUNKS_RC_ENCRYPTION_FAILED;
12535     }
12536     buffer.replace(2, size, decrypted_data);
12537   }
12538   std::string out_private_bytes;
12539   rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
12540   if (rc != TPM_RC_SUCCESS) {
12541     return rc;
12542   }
12543   return TPM_RC_SUCCESS;
12544 }
12545 
ImportErrorCallback(Tpm::ImportResponse callback,TPM_RC response_code)12546 void ImportErrorCallback(Tpm::ImportResponse callback, TPM_RC response_code) {
12547   VLOG(1) << __func__;
12548   std::move(callback).Run(response_code, TPM2B_PRIVATE());
12549 }
12550 
ImportResponseParser(Tpm::ImportResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12551 void ImportResponseParser(Tpm::ImportResponse callback,
12552                           AuthorizationDelegate* authorization_delegate,
12553                           const std::string& response) {
12554   VLOG(1) << __func__;
12555   TPM2B_PRIVATE out_private;
12556   TPM_RC rc =
12557       Tpm::ParseResponse_Import(response, &out_private, authorization_delegate);
12558   if (rc != TPM_RC_SUCCESS) {
12559     base::OnceCallback<void(TPM_RC)> error_reporter =
12560         base::BindOnce(ImportErrorCallback, std::move(callback));
12561     std::move(error_reporter).Run(rc);
12562     return;
12563   }
12564   std::move(callback).Run(rc, out_private);
12565 }
12566 
Import(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_DATA & encryption_key,const TPM2B_PUBLIC & object_public,const TPM2B_PRIVATE & duplicate,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,const TPMT_SYM_DEF_OBJECT & symmetric_alg,AuthorizationDelegate * authorization_delegate,ImportResponse callback)12567 void Tpm::Import(const TPMI_DH_OBJECT& parent_handle,
12568                  const std::string& parent_handle_name,
12569                  const TPM2B_DATA& encryption_key,
12570                  const TPM2B_PUBLIC& object_public,
12571                  const TPM2B_PRIVATE& duplicate,
12572                  const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12573                  const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12574                  AuthorizationDelegate* authorization_delegate,
12575                  ImportResponse callback) {
12576   VLOG(1) << __func__;
12577   std::string command;
12578   TPM_RC rc = SerializeCommand_Import(
12579       parent_handle, parent_handle_name, encryption_key, object_public,
12580       duplicate, in_sym_seed, symmetric_alg, &command, authorization_delegate);
12581   if (rc != TPM_RC_SUCCESS) {
12582     base::OnceCallback<void(TPM_RC)> error_reporter =
12583         base::BindOnce(ImportErrorCallback, std::move(callback));
12584     std::move(error_reporter).Run(rc);
12585     return;
12586   }
12587   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12588       ImportResponseParser, std::move(callback), authorization_delegate);
12589   transceiver_->SendCommand(command, std::move(parser));
12590 }
12591 
ImportSync(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_DATA & encryption_key,const TPM2B_PUBLIC & object_public,const TPM2B_PRIVATE & duplicate,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,const TPMT_SYM_DEF_OBJECT & symmetric_alg,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)12592 TPM_RC Tpm::ImportSync(const TPMI_DH_OBJECT& parent_handle,
12593                        const std::string& parent_handle_name,
12594                        const TPM2B_DATA& encryption_key,
12595                        const TPM2B_PUBLIC& object_public,
12596                        const TPM2B_PRIVATE& duplicate,
12597                        const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12598                        const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12599                        TPM2B_PRIVATE* out_private,
12600                        AuthorizationDelegate* authorization_delegate) {
12601   VLOG(1) << __func__;
12602   std::string command;
12603   TPM_RC rc = SerializeCommand_Import(
12604       parent_handle, parent_handle_name, encryption_key, object_public,
12605       duplicate, in_sym_seed, symmetric_alg, &command, authorization_delegate);
12606   if (rc != TPM_RC_SUCCESS) {
12607     return rc;
12608   }
12609   std::string response = transceiver_->SendCommandAndWait(command);
12610   rc = ParseResponse_Import(response, out_private, authorization_delegate);
12611   return rc;
12612 }
12613 
SerializeCommand_RSA_Encrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & message,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12614 TPM_RC Tpm::SerializeCommand_RSA_Encrypt(
12615     const TPMI_DH_OBJECT& key_handle,
12616     const std::string& key_handle_name,
12617     const TPM2B_PUBLIC_KEY_RSA& message,
12618     const TPMT_RSA_DECRYPT& in_scheme,
12619     const TPM2B_DATA& label,
12620     std::string* serialized_command,
12621     AuthorizationDelegate* authorization_delegate) {
12622   VLOG(3) << __func__;
12623   TPM_RC rc = TPM_RC_SUCCESS;
12624   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12625   UINT32 command_size = 10;  // Header size.
12626   std::string handle_section_bytes;
12627   std::string parameter_section_bytes;
12628   TPM_CC command_code = TPM_CC_RSA_Encrypt;
12629   bool is_command_parameter_encryption_possible = true;
12630   bool is_response_parameter_encryption_possible = true;
12631   std::string command_code_bytes;
12632   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12633   if (rc != TPM_RC_SUCCESS) {
12634     return rc;
12635   }
12636   std::string key_handle_bytes;
12637   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
12638   if (rc != TPM_RC_SUCCESS) {
12639     return rc;
12640   }
12641   std::string message_bytes;
12642   rc = Serialize_TPM2B_PUBLIC_KEY_RSA(message, &message_bytes);
12643   if (rc != TPM_RC_SUCCESS) {
12644     return rc;
12645   }
12646   std::string in_scheme_bytes;
12647   rc = Serialize_TPMT_RSA_DECRYPT(in_scheme, &in_scheme_bytes);
12648   if (rc != TPM_RC_SUCCESS) {
12649     return rc;
12650   }
12651   std::string label_bytes;
12652   rc = Serialize_TPM2B_DATA(label, &label_bytes);
12653   if (rc != TPM_RC_SUCCESS) {
12654     return rc;
12655   }
12656   if (authorization_delegate) {
12657     // Encrypt just the parameter data, not the size.
12658     std::string tmp = message_bytes.substr(2);
12659     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12660       return TRUNKS_RC_ENCRYPTION_FAILED;
12661     }
12662     message_bytes.replace(2, std::string::npos, tmp);
12663   }
12664   std::unique_ptr<crypto::SecureHash> hash(
12665       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12666   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12667   hash->Update(key_handle_name.data(), key_handle_name.size());
12668   handle_section_bytes += key_handle_bytes;
12669   command_size += key_handle_bytes.size();
12670   hash->Update(message_bytes.data(), message_bytes.size());
12671   parameter_section_bytes += message_bytes;
12672   command_size += message_bytes.size();
12673   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
12674   parameter_section_bytes += in_scheme_bytes;
12675   command_size += in_scheme_bytes.size();
12676   hash->Update(label_bytes.data(), label_bytes.size());
12677   parameter_section_bytes += label_bytes;
12678   command_size += label_bytes.size();
12679   std::string command_hash(32, 0);
12680   hash->Finish(std::data(command_hash), command_hash.size());
12681   std::string authorization_section_bytes;
12682   std::string authorization_size_bytes;
12683   if (authorization_delegate) {
12684     if (!authorization_delegate->GetCommandAuthorization(
12685             command_hash, is_command_parameter_encryption_possible,
12686             is_response_parameter_encryption_possible,
12687             &authorization_section_bytes)) {
12688       return TRUNKS_RC_AUTHORIZATION_FAILED;
12689     }
12690     if (!authorization_section_bytes.empty()) {
12691       tag = TPM_ST_SESSIONS;
12692       std::string tmp;
12693       rc = Serialize_UINT32(authorization_section_bytes.size(),
12694                             &authorization_size_bytes);
12695       if (rc != TPM_RC_SUCCESS) {
12696         return rc;
12697       }
12698       command_size +=
12699           authorization_size_bytes.size() + authorization_section_bytes.size();
12700     }
12701   }
12702   std::string tag_bytes;
12703   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12704   if (rc != TPM_RC_SUCCESS) {
12705     return rc;
12706   }
12707   std::string command_size_bytes;
12708   rc = Serialize_UINT32(command_size, &command_size_bytes);
12709   if (rc != TPM_RC_SUCCESS) {
12710     return rc;
12711   }
12712   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12713                         handle_section_bytes + authorization_size_bytes +
12714                         authorization_section_bytes + parameter_section_bytes;
12715   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12716   VLOG(2) << "Command: "
12717           << base::HexEncode(serialized_command->data(),
12718                              serialized_command->size());
12719   return TPM_RC_SUCCESS;
12720 }
12721 
ParseResponse_RSA_Encrypt(const std::string & response,TPM2B_PUBLIC_KEY_RSA * out_data,AuthorizationDelegate * authorization_delegate)12722 TPM_RC Tpm::ParseResponse_RSA_Encrypt(
12723     const std::string& response,
12724     TPM2B_PUBLIC_KEY_RSA* out_data,
12725     AuthorizationDelegate* authorization_delegate) {
12726   VLOG(3) << __func__;
12727   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12728   TPM_RC rc = TPM_RC_SUCCESS;
12729   std::string buffer(response);
12730   TPM_ST tag;
12731   std::string tag_bytes;
12732   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12733   if (rc != TPM_RC_SUCCESS) {
12734     return rc;
12735   }
12736   UINT32 response_size;
12737   std::string response_size_bytes;
12738   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12739   if (rc != TPM_RC_SUCCESS) {
12740     return rc;
12741   }
12742   TPM_RC response_code;
12743   std::string response_code_bytes;
12744   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12745   if (rc != TPM_RC_SUCCESS) {
12746     return rc;
12747   }
12748   if (response_size != response.size()) {
12749     return TPM_RC_SIZE;
12750   }
12751   if (response_code != TPM_RC_SUCCESS) {
12752     return response_code;
12753   }
12754   TPM_CC command_code = TPM_CC_RSA_Encrypt;
12755   std::string command_code_bytes;
12756   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12757   if (rc != TPM_RC_SUCCESS) {
12758     return rc;
12759   }
12760   std::string authorization_section_bytes;
12761   if (tag == TPM_ST_SESSIONS) {
12762     UINT32 parameter_section_size = buffer.size();
12763     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
12764     if (rc != TPM_RC_SUCCESS) {
12765       return rc;
12766     }
12767     if (parameter_section_size > buffer.size()) {
12768       return TPM_RC_INSUFFICIENT;
12769     }
12770     authorization_section_bytes = buffer.substr(parameter_section_size);
12771     // Keep the parameter section in |buffer|.
12772     buffer.erase(parameter_section_size);
12773   }
12774   std::unique_ptr<crypto::SecureHash> hash(
12775       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12776   hash->Update(response_code_bytes.data(), response_code_bytes.size());
12777   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12778   hash->Update(buffer.data(), buffer.size());
12779   std::string response_hash(32, 0);
12780   hash->Finish(std::data(response_hash), response_hash.size());
12781   if (tag == TPM_ST_SESSIONS) {
12782     if (!authorization_delegate)
12783       return TRUNKS_RC_AUTHORIZATION_FAILED;
12784     if (!authorization_delegate->CheckResponseAuthorization(
12785             response_hash, authorization_section_bytes)) {
12786       return TRUNKS_RC_AUTHORIZATION_FAILED;
12787     }
12788   }
12789   if (tag == TPM_ST_SESSIONS) {
12790     if (!authorization_delegate)
12791       return TRUNKS_RC_AUTHORIZATION_FAILED;
12792 
12793     // Parse the encrypted parameter size.
12794     UINT16 size;
12795     std::string size_buffer = buffer.substr(0, 2);
12796     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12797       return result;
12798     }
12799     if (buffer.size() < 2 + size) {
12800       return TPM_RC_INSUFFICIENT;
12801     }
12802 
12803     // Decrypt just the parameter data, not the size.
12804     std::string decrypted_data = buffer.substr(2, size);
12805     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12806       return TRUNKS_RC_ENCRYPTION_FAILED;
12807     }
12808     buffer.replace(2, size, decrypted_data);
12809   }
12810   std::string out_data_bytes;
12811   rc = Parse_TPM2B_PUBLIC_KEY_RSA(&buffer, out_data, &out_data_bytes);
12812   if (rc != TPM_RC_SUCCESS) {
12813     return rc;
12814   }
12815   return TPM_RC_SUCCESS;
12816 }
12817 
RSA_EncryptErrorCallback(Tpm::RSA_EncryptResponse callback,TPM_RC response_code)12818 void RSA_EncryptErrorCallback(Tpm::RSA_EncryptResponse callback,
12819                               TPM_RC response_code) {
12820   VLOG(1) << __func__;
12821   std::move(callback).Run(response_code, TPM2B_PUBLIC_KEY_RSA());
12822 }
12823 
RSA_EncryptResponseParser(Tpm::RSA_EncryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12824 void RSA_EncryptResponseParser(Tpm::RSA_EncryptResponse callback,
12825                                AuthorizationDelegate* authorization_delegate,
12826                                const std::string& response) {
12827   VLOG(1) << __func__;
12828   TPM2B_PUBLIC_KEY_RSA out_data;
12829   TPM_RC rc = Tpm::ParseResponse_RSA_Encrypt(response, &out_data,
12830                                              authorization_delegate);
12831   if (rc != TPM_RC_SUCCESS) {
12832     base::OnceCallback<void(TPM_RC)> error_reporter =
12833         base::BindOnce(RSA_EncryptErrorCallback, std::move(callback));
12834     std::move(error_reporter).Run(rc);
12835     return;
12836   }
12837   std::move(callback).Run(rc, out_data);
12838 }
12839 
RSA_Encrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & message,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,AuthorizationDelegate * authorization_delegate,RSA_EncryptResponse callback)12840 void Tpm::RSA_Encrypt(const TPMI_DH_OBJECT& key_handle,
12841                       const std::string& key_handle_name,
12842                       const TPM2B_PUBLIC_KEY_RSA& message,
12843                       const TPMT_RSA_DECRYPT& in_scheme,
12844                       const TPM2B_DATA& label,
12845                       AuthorizationDelegate* authorization_delegate,
12846                       RSA_EncryptResponse callback) {
12847   VLOG(1) << __func__;
12848   std::string command;
12849   TPM_RC rc = SerializeCommand_RSA_Encrypt(key_handle, key_handle_name, message,
12850                                            in_scheme, label, &command,
12851                                            authorization_delegate);
12852   if (rc != TPM_RC_SUCCESS) {
12853     base::OnceCallback<void(TPM_RC)> error_reporter =
12854         base::BindOnce(RSA_EncryptErrorCallback, std::move(callback));
12855     std::move(error_reporter).Run(rc);
12856     return;
12857   }
12858   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12859       RSA_EncryptResponseParser, std::move(callback), authorization_delegate);
12860   transceiver_->SendCommand(command, std::move(parser));
12861 }
12862 
RSA_EncryptSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & message,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,TPM2B_PUBLIC_KEY_RSA * out_data,AuthorizationDelegate * authorization_delegate)12863 TPM_RC Tpm::RSA_EncryptSync(const TPMI_DH_OBJECT& key_handle,
12864                             const std::string& key_handle_name,
12865                             const TPM2B_PUBLIC_KEY_RSA& message,
12866                             const TPMT_RSA_DECRYPT& in_scheme,
12867                             const TPM2B_DATA& label,
12868                             TPM2B_PUBLIC_KEY_RSA* out_data,
12869                             AuthorizationDelegate* authorization_delegate) {
12870   VLOG(1) << __func__;
12871   std::string command;
12872   TPM_RC rc = SerializeCommand_RSA_Encrypt(key_handle, key_handle_name, message,
12873                                            in_scheme, label, &command,
12874                                            authorization_delegate);
12875   if (rc != TPM_RC_SUCCESS) {
12876     return rc;
12877   }
12878   std::string response = transceiver_->SendCommandAndWait(command);
12879   rc = ParseResponse_RSA_Encrypt(response, out_data, authorization_delegate);
12880   return rc;
12881 }
12882 
SerializeCommand_RSA_Decrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & cipher_text,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12883 TPM_RC Tpm::SerializeCommand_RSA_Decrypt(
12884     const TPMI_DH_OBJECT& key_handle,
12885     const std::string& key_handle_name,
12886     const TPM2B_PUBLIC_KEY_RSA& cipher_text,
12887     const TPMT_RSA_DECRYPT& in_scheme,
12888     const TPM2B_DATA& label,
12889     std::string* serialized_command,
12890     AuthorizationDelegate* authorization_delegate) {
12891   VLOG(3) << __func__;
12892   TPM_RC rc = TPM_RC_SUCCESS;
12893   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12894   UINT32 command_size = 10;  // Header size.
12895   std::string handle_section_bytes;
12896   std::string parameter_section_bytes;
12897   TPM_CC command_code = TPM_CC_RSA_Decrypt;
12898   bool is_command_parameter_encryption_possible = true;
12899   bool is_response_parameter_encryption_possible = true;
12900   std::string command_code_bytes;
12901   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12902   if (rc != TPM_RC_SUCCESS) {
12903     return rc;
12904   }
12905   std::string key_handle_bytes;
12906   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
12907   if (rc != TPM_RC_SUCCESS) {
12908     return rc;
12909   }
12910   std::string cipher_text_bytes;
12911   rc = Serialize_TPM2B_PUBLIC_KEY_RSA(cipher_text, &cipher_text_bytes);
12912   if (rc != TPM_RC_SUCCESS) {
12913     return rc;
12914   }
12915   std::string in_scheme_bytes;
12916   rc = Serialize_TPMT_RSA_DECRYPT(in_scheme, &in_scheme_bytes);
12917   if (rc != TPM_RC_SUCCESS) {
12918     return rc;
12919   }
12920   std::string label_bytes;
12921   rc = Serialize_TPM2B_DATA(label, &label_bytes);
12922   if (rc != TPM_RC_SUCCESS) {
12923     return rc;
12924   }
12925   if (authorization_delegate) {
12926     // Encrypt just the parameter data, not the size.
12927     std::string tmp = cipher_text_bytes.substr(2);
12928     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12929       return TRUNKS_RC_ENCRYPTION_FAILED;
12930     }
12931     cipher_text_bytes.replace(2, std::string::npos, tmp);
12932   }
12933   std::unique_ptr<crypto::SecureHash> hash(
12934       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12935   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12936   hash->Update(key_handle_name.data(), key_handle_name.size());
12937   handle_section_bytes += key_handle_bytes;
12938   command_size += key_handle_bytes.size();
12939   hash->Update(cipher_text_bytes.data(), cipher_text_bytes.size());
12940   parameter_section_bytes += cipher_text_bytes;
12941   command_size += cipher_text_bytes.size();
12942   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
12943   parameter_section_bytes += in_scheme_bytes;
12944   command_size += in_scheme_bytes.size();
12945   hash->Update(label_bytes.data(), label_bytes.size());
12946   parameter_section_bytes += label_bytes;
12947   command_size += label_bytes.size();
12948   std::string command_hash(32, 0);
12949   hash->Finish(std::data(command_hash), command_hash.size());
12950   std::string authorization_section_bytes;
12951   std::string authorization_size_bytes;
12952   if (authorization_delegate) {
12953     if (!authorization_delegate->GetCommandAuthorization(
12954             command_hash, is_command_parameter_encryption_possible,
12955             is_response_parameter_encryption_possible,
12956             &authorization_section_bytes)) {
12957       return TRUNKS_RC_AUTHORIZATION_FAILED;
12958     }
12959     if (!authorization_section_bytes.empty()) {
12960       tag = TPM_ST_SESSIONS;
12961       std::string tmp;
12962       rc = Serialize_UINT32(authorization_section_bytes.size(),
12963                             &authorization_size_bytes);
12964       if (rc != TPM_RC_SUCCESS) {
12965         return rc;
12966       }
12967       command_size +=
12968           authorization_size_bytes.size() + authorization_section_bytes.size();
12969     }
12970   }
12971   std::string tag_bytes;
12972   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12973   if (rc != TPM_RC_SUCCESS) {
12974     return rc;
12975   }
12976   std::string command_size_bytes;
12977   rc = Serialize_UINT32(command_size, &command_size_bytes);
12978   if (rc != TPM_RC_SUCCESS) {
12979     return rc;
12980   }
12981   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12982                         handle_section_bytes + authorization_size_bytes +
12983                         authorization_section_bytes + parameter_section_bytes;
12984   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12985   VLOG(2) << "Command: "
12986           << base::HexEncode(serialized_command->data(),
12987                              serialized_command->size());
12988   return TPM_RC_SUCCESS;
12989 }
12990 
ParseResponse_RSA_Decrypt(const std::string & response,TPM2B_PUBLIC_KEY_RSA * message,AuthorizationDelegate * authorization_delegate)12991 TPM_RC Tpm::ParseResponse_RSA_Decrypt(
12992     const std::string& response,
12993     TPM2B_PUBLIC_KEY_RSA* message,
12994     AuthorizationDelegate* authorization_delegate) {
12995   VLOG(3) << __func__;
12996   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12997   TPM_RC rc = TPM_RC_SUCCESS;
12998   std::string buffer(response);
12999   TPM_ST tag;
13000   std::string tag_bytes;
13001   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13002   if (rc != TPM_RC_SUCCESS) {
13003     return rc;
13004   }
13005   UINT32 response_size;
13006   std::string response_size_bytes;
13007   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13008   if (rc != TPM_RC_SUCCESS) {
13009     return rc;
13010   }
13011   TPM_RC response_code;
13012   std::string response_code_bytes;
13013   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13014   if (rc != TPM_RC_SUCCESS) {
13015     return rc;
13016   }
13017   if (response_size != response.size()) {
13018     return TPM_RC_SIZE;
13019   }
13020   if (response_code != TPM_RC_SUCCESS) {
13021     return response_code;
13022   }
13023   TPM_CC command_code = TPM_CC_RSA_Decrypt;
13024   std::string command_code_bytes;
13025   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13026   if (rc != TPM_RC_SUCCESS) {
13027     return rc;
13028   }
13029   std::string authorization_section_bytes;
13030   if (tag == TPM_ST_SESSIONS) {
13031     UINT32 parameter_section_size = buffer.size();
13032     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13033     if (rc != TPM_RC_SUCCESS) {
13034       return rc;
13035     }
13036     if (parameter_section_size > buffer.size()) {
13037       return TPM_RC_INSUFFICIENT;
13038     }
13039     authorization_section_bytes = buffer.substr(parameter_section_size);
13040     // Keep the parameter section in |buffer|.
13041     buffer.erase(parameter_section_size);
13042   }
13043   std::unique_ptr<crypto::SecureHash> hash(
13044       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13045   hash->Update(response_code_bytes.data(), response_code_bytes.size());
13046   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13047   hash->Update(buffer.data(), buffer.size());
13048   std::string response_hash(32, 0);
13049   hash->Finish(std::data(response_hash), response_hash.size());
13050   if (tag == TPM_ST_SESSIONS) {
13051     if (!authorization_delegate)
13052       return TRUNKS_RC_AUTHORIZATION_FAILED;
13053     if (!authorization_delegate->CheckResponseAuthorization(
13054             response_hash, authorization_section_bytes)) {
13055       return TRUNKS_RC_AUTHORIZATION_FAILED;
13056     }
13057   }
13058   if (tag == TPM_ST_SESSIONS) {
13059     if (!authorization_delegate)
13060       return TRUNKS_RC_AUTHORIZATION_FAILED;
13061 
13062     // Parse the encrypted parameter size.
13063     UINT16 size;
13064     std::string size_buffer = buffer.substr(0, 2);
13065     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13066       return result;
13067     }
13068     if (buffer.size() < 2 + size) {
13069       return TPM_RC_INSUFFICIENT;
13070     }
13071 
13072     // Decrypt just the parameter data, not the size.
13073     std::string decrypted_data = buffer.substr(2, size);
13074     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13075       return TRUNKS_RC_ENCRYPTION_FAILED;
13076     }
13077     buffer.replace(2, size, decrypted_data);
13078   }
13079   std::string message_bytes;
13080   rc = Parse_TPM2B_PUBLIC_KEY_RSA(&buffer, message, &message_bytes);
13081   if (rc != TPM_RC_SUCCESS) {
13082     return rc;
13083   }
13084   return TPM_RC_SUCCESS;
13085 }
13086 
RSA_DecryptErrorCallback(Tpm::RSA_DecryptResponse callback,TPM_RC response_code)13087 void RSA_DecryptErrorCallback(Tpm::RSA_DecryptResponse callback,
13088                               TPM_RC response_code) {
13089   VLOG(1) << __func__;
13090   std::move(callback).Run(response_code, TPM2B_PUBLIC_KEY_RSA());
13091 }
13092 
RSA_DecryptResponseParser(Tpm::RSA_DecryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13093 void RSA_DecryptResponseParser(Tpm::RSA_DecryptResponse callback,
13094                                AuthorizationDelegate* authorization_delegate,
13095                                const std::string& response) {
13096   VLOG(1) << __func__;
13097   TPM2B_PUBLIC_KEY_RSA message;
13098   TPM_RC rc = Tpm::ParseResponse_RSA_Decrypt(response, &message,
13099                                              authorization_delegate);
13100   if (rc != TPM_RC_SUCCESS) {
13101     base::OnceCallback<void(TPM_RC)> error_reporter =
13102         base::BindOnce(RSA_DecryptErrorCallback, std::move(callback));
13103     std::move(error_reporter).Run(rc);
13104     return;
13105   }
13106   std::move(callback).Run(rc, message);
13107 }
13108 
RSA_Decrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & cipher_text,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,AuthorizationDelegate * authorization_delegate,RSA_DecryptResponse callback)13109 void Tpm::RSA_Decrypt(const TPMI_DH_OBJECT& key_handle,
13110                       const std::string& key_handle_name,
13111                       const TPM2B_PUBLIC_KEY_RSA& cipher_text,
13112                       const TPMT_RSA_DECRYPT& in_scheme,
13113                       const TPM2B_DATA& label,
13114                       AuthorizationDelegate* authorization_delegate,
13115                       RSA_DecryptResponse callback) {
13116   VLOG(1) << __func__;
13117   std::string command;
13118   TPM_RC rc = SerializeCommand_RSA_Decrypt(key_handle, key_handle_name,
13119                                            cipher_text, in_scheme, label,
13120                                            &command, authorization_delegate);
13121   if (rc != TPM_RC_SUCCESS) {
13122     base::OnceCallback<void(TPM_RC)> error_reporter =
13123         base::BindOnce(RSA_DecryptErrorCallback, std::move(callback));
13124     std::move(error_reporter).Run(rc);
13125     return;
13126   }
13127   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13128       RSA_DecryptResponseParser, std::move(callback), authorization_delegate);
13129   transceiver_->SendCommand(command, std::move(parser));
13130 }
13131 
RSA_DecryptSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & cipher_text,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,TPM2B_PUBLIC_KEY_RSA * message,AuthorizationDelegate * authorization_delegate)13132 TPM_RC Tpm::RSA_DecryptSync(const TPMI_DH_OBJECT& key_handle,
13133                             const std::string& key_handle_name,
13134                             const TPM2B_PUBLIC_KEY_RSA& cipher_text,
13135                             const TPMT_RSA_DECRYPT& in_scheme,
13136                             const TPM2B_DATA& label,
13137                             TPM2B_PUBLIC_KEY_RSA* message,
13138                             AuthorizationDelegate* authorization_delegate) {
13139   VLOG(1) << __func__;
13140   std::string command;
13141   TPM_RC rc = SerializeCommand_RSA_Decrypt(key_handle, key_handle_name,
13142                                            cipher_text, in_scheme, label,
13143                                            &command, authorization_delegate);
13144   if (rc != TPM_RC_SUCCESS) {
13145     return rc;
13146   }
13147   std::string response = transceiver_->SendCommandAndWait(command);
13148   rc = ParseResponse_RSA_Decrypt(response, message, authorization_delegate);
13149   return rc;
13150 }
13151 
SerializeCommand_ECDH_KeyGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13152 TPM_RC Tpm::SerializeCommand_ECDH_KeyGen(
13153     const TPMI_DH_OBJECT& key_handle,
13154     const std::string& key_handle_name,
13155     std::string* serialized_command,
13156     AuthorizationDelegate* authorization_delegate) {
13157   VLOG(3) << __func__;
13158   TPM_RC rc = TPM_RC_SUCCESS;
13159   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13160   UINT32 command_size = 10;  // Header size.
13161   std::string handle_section_bytes;
13162   std::string parameter_section_bytes;
13163   TPM_CC command_code = TPM_CC_ECDH_KeyGen;
13164   bool is_command_parameter_encryption_possible = false;
13165   bool is_response_parameter_encryption_possible = true;
13166   std::string command_code_bytes;
13167   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13168   if (rc != TPM_RC_SUCCESS) {
13169     return rc;
13170   }
13171   std::string key_handle_bytes;
13172   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13173   if (rc != TPM_RC_SUCCESS) {
13174     return rc;
13175   }
13176   std::unique_ptr<crypto::SecureHash> hash(
13177       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13178   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13179   hash->Update(key_handle_name.data(), key_handle_name.size());
13180   handle_section_bytes += key_handle_bytes;
13181   command_size += key_handle_bytes.size();
13182   std::string command_hash(32, 0);
13183   hash->Finish(std::data(command_hash), command_hash.size());
13184   std::string authorization_section_bytes;
13185   std::string authorization_size_bytes;
13186   if (authorization_delegate) {
13187     if (!authorization_delegate->GetCommandAuthorization(
13188             command_hash, is_command_parameter_encryption_possible,
13189             is_response_parameter_encryption_possible,
13190             &authorization_section_bytes)) {
13191       return TRUNKS_RC_AUTHORIZATION_FAILED;
13192     }
13193     if (!authorization_section_bytes.empty()) {
13194       tag = TPM_ST_SESSIONS;
13195       std::string tmp;
13196       rc = Serialize_UINT32(authorization_section_bytes.size(),
13197                             &authorization_size_bytes);
13198       if (rc != TPM_RC_SUCCESS) {
13199         return rc;
13200       }
13201       command_size +=
13202           authorization_size_bytes.size() + authorization_section_bytes.size();
13203     }
13204   }
13205   std::string tag_bytes;
13206   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13207   if (rc != TPM_RC_SUCCESS) {
13208     return rc;
13209   }
13210   std::string command_size_bytes;
13211   rc = Serialize_UINT32(command_size, &command_size_bytes);
13212   if (rc != TPM_RC_SUCCESS) {
13213     return rc;
13214   }
13215   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13216                         handle_section_bytes + authorization_size_bytes +
13217                         authorization_section_bytes + parameter_section_bytes;
13218   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13219   VLOG(2) << "Command: "
13220           << base::HexEncode(serialized_command->data(),
13221                              serialized_command->size());
13222   return TPM_RC_SUCCESS;
13223 }
13224 
ParseResponse_ECDH_KeyGen(const std::string & response,TPM2B_ECC_POINT * z_point,TPM2B_ECC_POINT * pub_point,AuthorizationDelegate * authorization_delegate)13225 TPM_RC Tpm::ParseResponse_ECDH_KeyGen(
13226     const std::string& response,
13227     TPM2B_ECC_POINT* z_point,
13228     TPM2B_ECC_POINT* pub_point,
13229     AuthorizationDelegate* authorization_delegate) {
13230   VLOG(3) << __func__;
13231   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13232   TPM_RC rc = TPM_RC_SUCCESS;
13233   std::string buffer(response);
13234   TPM_ST tag;
13235   std::string tag_bytes;
13236   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13237   if (rc != TPM_RC_SUCCESS) {
13238     return rc;
13239   }
13240   UINT32 response_size;
13241   std::string response_size_bytes;
13242   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13243   if (rc != TPM_RC_SUCCESS) {
13244     return rc;
13245   }
13246   TPM_RC response_code;
13247   std::string response_code_bytes;
13248   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13249   if (rc != TPM_RC_SUCCESS) {
13250     return rc;
13251   }
13252   if (response_size != response.size()) {
13253     return TPM_RC_SIZE;
13254   }
13255   if (response_code != TPM_RC_SUCCESS) {
13256     return response_code;
13257   }
13258   TPM_CC command_code = TPM_CC_ECDH_KeyGen;
13259   std::string command_code_bytes;
13260   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13261   if (rc != TPM_RC_SUCCESS) {
13262     return rc;
13263   }
13264   std::string authorization_section_bytes;
13265   if (tag == TPM_ST_SESSIONS) {
13266     UINT32 parameter_section_size = buffer.size();
13267     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13268     if (rc != TPM_RC_SUCCESS) {
13269       return rc;
13270     }
13271     if (parameter_section_size > buffer.size()) {
13272       return TPM_RC_INSUFFICIENT;
13273     }
13274     authorization_section_bytes = buffer.substr(parameter_section_size);
13275     // Keep the parameter section in |buffer|.
13276     buffer.erase(parameter_section_size);
13277   }
13278   std::unique_ptr<crypto::SecureHash> hash(
13279       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13280   hash->Update(response_code_bytes.data(), response_code_bytes.size());
13281   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13282   hash->Update(buffer.data(), buffer.size());
13283   std::string response_hash(32, 0);
13284   hash->Finish(std::data(response_hash), response_hash.size());
13285   if (tag == TPM_ST_SESSIONS) {
13286     if (!authorization_delegate)
13287       return TRUNKS_RC_AUTHORIZATION_FAILED;
13288     if (!authorization_delegate->CheckResponseAuthorization(
13289             response_hash, authorization_section_bytes)) {
13290       return TRUNKS_RC_AUTHORIZATION_FAILED;
13291     }
13292   }
13293   if (tag == TPM_ST_SESSIONS) {
13294     if (!authorization_delegate)
13295       return TRUNKS_RC_AUTHORIZATION_FAILED;
13296 
13297     // Parse the encrypted parameter size.
13298     UINT16 size;
13299     std::string size_buffer = buffer.substr(0, 2);
13300     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13301       return result;
13302     }
13303     if (buffer.size() < 2 + size) {
13304       return TPM_RC_INSUFFICIENT;
13305     }
13306 
13307     // Decrypt just the parameter data, not the size.
13308     std::string decrypted_data = buffer.substr(2, size);
13309     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13310       return TRUNKS_RC_ENCRYPTION_FAILED;
13311     }
13312     buffer.replace(2, size, decrypted_data);
13313   }
13314   std::string z_point_bytes;
13315   rc = Parse_TPM2B_ECC_POINT(&buffer, z_point, &z_point_bytes);
13316   if (rc != TPM_RC_SUCCESS) {
13317     return rc;
13318   }
13319   std::string pub_point_bytes;
13320   rc = Parse_TPM2B_ECC_POINT(&buffer, pub_point, &pub_point_bytes);
13321   if (rc != TPM_RC_SUCCESS) {
13322     return rc;
13323   }
13324   return TPM_RC_SUCCESS;
13325 }
13326 
ECDH_KeyGenErrorCallback(Tpm::ECDH_KeyGenResponse callback,TPM_RC response_code)13327 void ECDH_KeyGenErrorCallback(Tpm::ECDH_KeyGenResponse callback,
13328                               TPM_RC response_code) {
13329   VLOG(1) << __func__;
13330   std::move(callback).Run(response_code, TPM2B_ECC_POINT(), TPM2B_ECC_POINT());
13331 }
13332 
ECDH_KeyGenResponseParser(Tpm::ECDH_KeyGenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13333 void ECDH_KeyGenResponseParser(Tpm::ECDH_KeyGenResponse callback,
13334                                AuthorizationDelegate* authorization_delegate,
13335                                const std::string& response) {
13336   VLOG(1) << __func__;
13337   TPM2B_ECC_POINT z_point;
13338   TPM2B_ECC_POINT pub_point;
13339   TPM_RC rc = Tpm::ParseResponse_ECDH_KeyGen(response, &z_point, &pub_point,
13340                                              authorization_delegate);
13341   if (rc != TPM_RC_SUCCESS) {
13342     base::OnceCallback<void(TPM_RC)> error_reporter =
13343         base::BindOnce(ECDH_KeyGenErrorCallback, std::move(callback));
13344     std::move(error_reporter).Run(rc);
13345     return;
13346   }
13347   std::move(callback).Run(rc, z_point, pub_point);
13348 }
13349 
ECDH_KeyGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,AuthorizationDelegate * authorization_delegate,ECDH_KeyGenResponse callback)13350 void Tpm::ECDH_KeyGen(const TPMI_DH_OBJECT& key_handle,
13351                       const std::string& key_handle_name,
13352                       AuthorizationDelegate* authorization_delegate,
13353                       ECDH_KeyGenResponse callback) {
13354   VLOG(1) << __func__;
13355   std::string command;
13356   TPM_RC rc = SerializeCommand_ECDH_KeyGen(key_handle, key_handle_name,
13357                                            &command, authorization_delegate);
13358   if (rc != TPM_RC_SUCCESS) {
13359     base::OnceCallback<void(TPM_RC)> error_reporter =
13360         base::BindOnce(ECDH_KeyGenErrorCallback, std::move(callback));
13361     std::move(error_reporter).Run(rc);
13362     return;
13363   }
13364   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13365       ECDH_KeyGenResponseParser, std::move(callback), authorization_delegate);
13366   transceiver_->SendCommand(command, std::move(parser));
13367 }
13368 
ECDH_KeyGenSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,TPM2B_ECC_POINT * z_point,TPM2B_ECC_POINT * pub_point,AuthorizationDelegate * authorization_delegate)13369 TPM_RC Tpm::ECDH_KeyGenSync(const TPMI_DH_OBJECT& key_handle,
13370                             const std::string& key_handle_name,
13371                             TPM2B_ECC_POINT* z_point,
13372                             TPM2B_ECC_POINT* pub_point,
13373                             AuthorizationDelegate* authorization_delegate) {
13374   VLOG(1) << __func__;
13375   std::string command;
13376   TPM_RC rc = SerializeCommand_ECDH_KeyGen(key_handle, key_handle_name,
13377                                            &command, authorization_delegate);
13378   if (rc != TPM_RC_SUCCESS) {
13379     return rc;
13380   }
13381   std::string response = transceiver_->SendCommandAndWait(command);
13382   rc = ParseResponse_ECDH_KeyGen(response, z_point, pub_point,
13383                                  authorization_delegate);
13384   return rc;
13385 }
13386 
SerializeCommand_ECDH_ZGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ECC_POINT & in_point,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13387 TPM_RC Tpm::SerializeCommand_ECDH_ZGen(
13388     const TPMI_DH_OBJECT& key_handle,
13389     const std::string& key_handle_name,
13390     const TPM2B_ECC_POINT& in_point,
13391     std::string* serialized_command,
13392     AuthorizationDelegate* authorization_delegate) {
13393   VLOG(3) << __func__;
13394   TPM_RC rc = TPM_RC_SUCCESS;
13395   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13396   UINT32 command_size = 10;  // Header size.
13397   std::string handle_section_bytes;
13398   std::string parameter_section_bytes;
13399   TPM_CC command_code = TPM_CC_ECDH_ZGen;
13400   bool is_command_parameter_encryption_possible = true;
13401   bool is_response_parameter_encryption_possible = true;
13402   std::string command_code_bytes;
13403   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13404   if (rc != TPM_RC_SUCCESS) {
13405     return rc;
13406   }
13407   std::string key_handle_bytes;
13408   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13409   if (rc != TPM_RC_SUCCESS) {
13410     return rc;
13411   }
13412   std::string in_point_bytes;
13413   rc = Serialize_TPM2B_ECC_POINT(in_point, &in_point_bytes);
13414   if (rc != TPM_RC_SUCCESS) {
13415     return rc;
13416   }
13417   if (authorization_delegate) {
13418     // Encrypt just the parameter data, not the size.
13419     std::string tmp = in_point_bytes.substr(2);
13420     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
13421       return TRUNKS_RC_ENCRYPTION_FAILED;
13422     }
13423     in_point_bytes.replace(2, std::string::npos, tmp);
13424   }
13425   std::unique_ptr<crypto::SecureHash> hash(
13426       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13427   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13428   hash->Update(key_handle_name.data(), key_handle_name.size());
13429   handle_section_bytes += key_handle_bytes;
13430   command_size += key_handle_bytes.size();
13431   hash->Update(in_point_bytes.data(), in_point_bytes.size());
13432   parameter_section_bytes += in_point_bytes;
13433   command_size += in_point_bytes.size();
13434   std::string command_hash(32, 0);
13435   hash->Finish(std::data(command_hash), command_hash.size());
13436   std::string authorization_section_bytes;
13437   std::string authorization_size_bytes;
13438   if (authorization_delegate) {
13439     if (!authorization_delegate->GetCommandAuthorization(
13440             command_hash, is_command_parameter_encryption_possible,
13441             is_response_parameter_encryption_possible,
13442             &authorization_section_bytes)) {
13443       return TRUNKS_RC_AUTHORIZATION_FAILED;
13444     }
13445     if (!authorization_section_bytes.empty()) {
13446       tag = TPM_ST_SESSIONS;
13447       std::string tmp;
13448       rc = Serialize_UINT32(authorization_section_bytes.size(),
13449                             &authorization_size_bytes);
13450       if (rc != TPM_RC_SUCCESS) {
13451         return rc;
13452       }
13453       command_size +=
13454           authorization_size_bytes.size() + authorization_section_bytes.size();
13455     }
13456   }
13457   std::string tag_bytes;
13458   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13459   if (rc != TPM_RC_SUCCESS) {
13460     return rc;
13461   }
13462   std::string command_size_bytes;
13463   rc = Serialize_UINT32(command_size, &command_size_bytes);
13464   if (rc != TPM_RC_SUCCESS) {
13465     return rc;
13466   }
13467   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13468                         handle_section_bytes + authorization_size_bytes +
13469                         authorization_section_bytes + parameter_section_bytes;
13470   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13471   VLOG(2) << "Command: "
13472           << base::HexEncode(serialized_command->data(),
13473                              serialized_command->size());
13474   return TPM_RC_SUCCESS;
13475 }
13476 
ParseResponse_ECDH_ZGen(const std::string & response,TPM2B_ECC_POINT * out_point,AuthorizationDelegate * authorization_delegate)13477 TPM_RC Tpm::ParseResponse_ECDH_ZGen(
13478     const std::string& response,
13479     TPM2B_ECC_POINT* out_point,
13480     AuthorizationDelegate* authorization_delegate) {
13481   VLOG(3) << __func__;
13482   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13483   TPM_RC rc = TPM_RC_SUCCESS;
13484   std::string buffer(response);
13485   TPM_ST tag;
13486   std::string tag_bytes;
13487   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13488   if (rc != TPM_RC_SUCCESS) {
13489     return rc;
13490   }
13491   UINT32 response_size;
13492   std::string response_size_bytes;
13493   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13494   if (rc != TPM_RC_SUCCESS) {
13495     return rc;
13496   }
13497   TPM_RC response_code;
13498   std::string response_code_bytes;
13499   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13500   if (rc != TPM_RC_SUCCESS) {
13501     return rc;
13502   }
13503   if (response_size != response.size()) {
13504     return TPM_RC_SIZE;
13505   }
13506   if (response_code != TPM_RC_SUCCESS) {
13507     return response_code;
13508   }
13509   TPM_CC command_code = TPM_CC_ECDH_ZGen;
13510   std::string command_code_bytes;
13511   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13512   if (rc != TPM_RC_SUCCESS) {
13513     return rc;
13514   }
13515   std::string authorization_section_bytes;
13516   if (tag == TPM_ST_SESSIONS) {
13517     UINT32 parameter_section_size = buffer.size();
13518     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13519     if (rc != TPM_RC_SUCCESS) {
13520       return rc;
13521     }
13522     if (parameter_section_size > buffer.size()) {
13523       return TPM_RC_INSUFFICIENT;
13524     }
13525     authorization_section_bytes = buffer.substr(parameter_section_size);
13526     // Keep the parameter section in |buffer|.
13527     buffer.erase(parameter_section_size);
13528   }
13529   std::unique_ptr<crypto::SecureHash> hash(
13530       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13531   hash->Update(response_code_bytes.data(), response_code_bytes.size());
13532   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13533   hash->Update(buffer.data(), buffer.size());
13534   std::string response_hash(32, 0);
13535   hash->Finish(std::data(response_hash), response_hash.size());
13536   if (tag == TPM_ST_SESSIONS) {
13537     if (!authorization_delegate)
13538       return TRUNKS_RC_AUTHORIZATION_FAILED;
13539     if (!authorization_delegate->CheckResponseAuthorization(
13540             response_hash, authorization_section_bytes)) {
13541       return TRUNKS_RC_AUTHORIZATION_FAILED;
13542     }
13543   }
13544   if (tag == TPM_ST_SESSIONS) {
13545     if (!authorization_delegate)
13546       return TRUNKS_RC_AUTHORIZATION_FAILED;
13547 
13548     // Parse the encrypted parameter size.
13549     UINT16 size;
13550     std::string size_buffer = buffer.substr(0, 2);
13551     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13552       return result;
13553     }
13554     if (buffer.size() < 2 + size) {
13555       return TPM_RC_INSUFFICIENT;
13556     }
13557 
13558     // Decrypt just the parameter data, not the size.
13559     std::string decrypted_data = buffer.substr(2, size);
13560     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13561       return TRUNKS_RC_ENCRYPTION_FAILED;
13562     }
13563     buffer.replace(2, size, decrypted_data);
13564   }
13565   std::string out_point_bytes;
13566   rc = Parse_TPM2B_ECC_POINT(&buffer, out_point, &out_point_bytes);
13567   if (rc != TPM_RC_SUCCESS) {
13568     return rc;
13569   }
13570   return TPM_RC_SUCCESS;
13571 }
13572 
ECDH_ZGenErrorCallback(Tpm::ECDH_ZGenResponse callback,TPM_RC response_code)13573 void ECDH_ZGenErrorCallback(Tpm::ECDH_ZGenResponse callback,
13574                             TPM_RC response_code) {
13575   VLOG(1) << __func__;
13576   std::move(callback).Run(response_code, TPM2B_ECC_POINT());
13577 }
13578 
ECDH_ZGenResponseParser(Tpm::ECDH_ZGenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13579 void ECDH_ZGenResponseParser(Tpm::ECDH_ZGenResponse callback,
13580                              AuthorizationDelegate* authorization_delegate,
13581                              const std::string& response) {
13582   VLOG(1) << __func__;
13583   TPM2B_ECC_POINT out_point;
13584   TPM_RC rc = Tpm::ParseResponse_ECDH_ZGen(response, &out_point,
13585                                            authorization_delegate);
13586   if (rc != TPM_RC_SUCCESS) {
13587     base::OnceCallback<void(TPM_RC)> error_reporter =
13588         base::BindOnce(ECDH_ZGenErrorCallback, std::move(callback));
13589     std::move(error_reporter).Run(rc);
13590     return;
13591   }
13592   std::move(callback).Run(rc, out_point);
13593 }
13594 
ECDH_ZGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ECC_POINT & in_point,AuthorizationDelegate * authorization_delegate,ECDH_ZGenResponse callback)13595 void Tpm::ECDH_ZGen(const TPMI_DH_OBJECT& key_handle,
13596                     const std::string& key_handle_name,
13597                     const TPM2B_ECC_POINT& in_point,
13598                     AuthorizationDelegate* authorization_delegate,
13599                     ECDH_ZGenResponse callback) {
13600   VLOG(1) << __func__;
13601   std::string command;
13602   TPM_RC rc = SerializeCommand_ECDH_ZGen(key_handle, key_handle_name, in_point,
13603                                          &command, authorization_delegate);
13604   if (rc != TPM_RC_SUCCESS) {
13605     base::OnceCallback<void(TPM_RC)> error_reporter =
13606         base::BindOnce(ECDH_ZGenErrorCallback, std::move(callback));
13607     std::move(error_reporter).Run(rc);
13608     return;
13609   }
13610   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13611       ECDH_ZGenResponseParser, std::move(callback), authorization_delegate);
13612   transceiver_->SendCommand(command, std::move(parser));
13613 }
13614 
ECDH_ZGenSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ECC_POINT & in_point,TPM2B_ECC_POINT * out_point,AuthorizationDelegate * authorization_delegate)13615 TPM_RC Tpm::ECDH_ZGenSync(const TPMI_DH_OBJECT& key_handle,
13616                           const std::string& key_handle_name,
13617                           const TPM2B_ECC_POINT& in_point,
13618                           TPM2B_ECC_POINT* out_point,
13619                           AuthorizationDelegate* authorization_delegate) {
13620   VLOG(1) << __func__;
13621   std::string command;
13622   TPM_RC rc = SerializeCommand_ECDH_ZGen(key_handle, key_handle_name, in_point,
13623                                          &command, authorization_delegate);
13624   if (rc != TPM_RC_SUCCESS) {
13625     return rc;
13626   }
13627   std::string response = transceiver_->SendCommandAndWait(command);
13628   rc = ParseResponse_ECDH_ZGen(response, out_point, authorization_delegate);
13629   return rc;
13630 }
13631 
SerializeCommand_ECC_Parameters(const TPMI_ECC_CURVE & curve_id,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13632 TPM_RC Tpm::SerializeCommand_ECC_Parameters(
13633     const TPMI_ECC_CURVE& curve_id,
13634     std::string* serialized_command,
13635     AuthorizationDelegate* authorization_delegate) {
13636   VLOG(3) << __func__;
13637   TPM_RC rc = TPM_RC_SUCCESS;
13638   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13639   UINT32 command_size = 10;  // Header size.
13640   std::string handle_section_bytes;
13641   std::string parameter_section_bytes;
13642   TPM_CC command_code = TPM_CC_ECC_Parameters;
13643   bool is_command_parameter_encryption_possible = false;
13644   bool is_response_parameter_encryption_possible = false;
13645   std::string command_code_bytes;
13646   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13647   if (rc != TPM_RC_SUCCESS) {
13648     return rc;
13649   }
13650   std::string curve_id_bytes;
13651   rc = Serialize_TPMI_ECC_CURVE(curve_id, &curve_id_bytes);
13652   if (rc != TPM_RC_SUCCESS) {
13653     return rc;
13654   }
13655   std::unique_ptr<crypto::SecureHash> hash(
13656       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13657   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13658   hash->Update(curve_id_bytes.data(), curve_id_bytes.size());
13659   parameter_section_bytes += curve_id_bytes;
13660   command_size += curve_id_bytes.size();
13661   std::string command_hash(32, 0);
13662   hash->Finish(std::data(command_hash), command_hash.size());
13663   std::string authorization_section_bytes;
13664   std::string authorization_size_bytes;
13665   if (authorization_delegate) {
13666     if (!authorization_delegate->GetCommandAuthorization(
13667             command_hash, is_command_parameter_encryption_possible,
13668             is_response_parameter_encryption_possible,
13669             &authorization_section_bytes)) {
13670       return TRUNKS_RC_AUTHORIZATION_FAILED;
13671     }
13672     if (!authorization_section_bytes.empty()) {
13673       tag = TPM_ST_SESSIONS;
13674       std::string tmp;
13675       rc = Serialize_UINT32(authorization_section_bytes.size(),
13676                             &authorization_size_bytes);
13677       if (rc != TPM_RC_SUCCESS) {
13678         return rc;
13679       }
13680       command_size +=
13681           authorization_size_bytes.size() + authorization_section_bytes.size();
13682     }
13683   }
13684   std::string tag_bytes;
13685   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13686   if (rc != TPM_RC_SUCCESS) {
13687     return rc;
13688   }
13689   std::string command_size_bytes;
13690   rc = Serialize_UINT32(command_size, &command_size_bytes);
13691   if (rc != TPM_RC_SUCCESS) {
13692     return rc;
13693   }
13694   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13695                         handle_section_bytes + authorization_size_bytes +
13696                         authorization_section_bytes + parameter_section_bytes;
13697   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13698   VLOG(2) << "Command: "
13699           << base::HexEncode(serialized_command->data(),
13700                              serialized_command->size());
13701   return TPM_RC_SUCCESS;
13702 }
13703 
ParseResponse_ECC_Parameters(const std::string & response,TPMS_ALGORITHM_DETAIL_ECC * parameters,AuthorizationDelegate * authorization_delegate)13704 TPM_RC Tpm::ParseResponse_ECC_Parameters(
13705     const std::string& response,
13706     TPMS_ALGORITHM_DETAIL_ECC* parameters,
13707     AuthorizationDelegate* authorization_delegate) {
13708   VLOG(3) << __func__;
13709   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13710   TPM_RC rc = TPM_RC_SUCCESS;
13711   std::string buffer(response);
13712   TPM_ST tag;
13713   std::string tag_bytes;
13714   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13715   if (rc != TPM_RC_SUCCESS) {
13716     return rc;
13717   }
13718   UINT32 response_size;
13719   std::string response_size_bytes;
13720   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13721   if (rc != TPM_RC_SUCCESS) {
13722     return rc;
13723   }
13724   TPM_RC response_code;
13725   std::string response_code_bytes;
13726   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13727   if (rc != TPM_RC_SUCCESS) {
13728     return rc;
13729   }
13730   if (response_size != response.size()) {
13731     return TPM_RC_SIZE;
13732   }
13733   if (response_code != TPM_RC_SUCCESS) {
13734     return response_code;
13735   }
13736   TPM_CC command_code = TPM_CC_ECC_Parameters;
13737   std::string command_code_bytes;
13738   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13739   if (rc != TPM_RC_SUCCESS) {
13740     return rc;
13741   }
13742   std::string authorization_section_bytes;
13743   if (tag == TPM_ST_SESSIONS) {
13744     UINT32 parameter_section_size = buffer.size();
13745     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13746     if (rc != TPM_RC_SUCCESS) {
13747       return rc;
13748     }
13749     if (parameter_section_size > buffer.size()) {
13750       return TPM_RC_INSUFFICIENT;
13751     }
13752     authorization_section_bytes = buffer.substr(parameter_section_size);
13753     // Keep the parameter section in |buffer|.
13754     buffer.erase(parameter_section_size);
13755   }
13756   std::unique_ptr<crypto::SecureHash> hash(
13757       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13758   hash->Update(response_code_bytes.data(), response_code_bytes.size());
13759   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13760   hash->Update(buffer.data(), buffer.size());
13761   std::string response_hash(32, 0);
13762   hash->Finish(std::data(response_hash), response_hash.size());
13763   if (tag == TPM_ST_SESSIONS) {
13764     if (!authorization_delegate)
13765       return TRUNKS_RC_AUTHORIZATION_FAILED;
13766     if (!authorization_delegate->CheckResponseAuthorization(
13767             response_hash, authorization_section_bytes)) {
13768       return TRUNKS_RC_AUTHORIZATION_FAILED;
13769     }
13770   }
13771   std::string parameters_bytes;
13772   rc = Parse_TPMS_ALGORITHM_DETAIL_ECC(&buffer, parameters, &parameters_bytes);
13773   if (rc != TPM_RC_SUCCESS) {
13774     return rc;
13775   }
13776   return TPM_RC_SUCCESS;
13777 }
13778 
ECC_ParametersErrorCallback(Tpm::ECC_ParametersResponse callback,TPM_RC response_code)13779 void ECC_ParametersErrorCallback(Tpm::ECC_ParametersResponse callback,
13780                                  TPM_RC response_code) {
13781   VLOG(1) << __func__;
13782   std::move(callback).Run(response_code, TPMS_ALGORITHM_DETAIL_ECC());
13783 }
13784 
ECC_ParametersResponseParser(Tpm::ECC_ParametersResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13785 void ECC_ParametersResponseParser(Tpm::ECC_ParametersResponse callback,
13786                                   AuthorizationDelegate* authorization_delegate,
13787                                   const std::string& response) {
13788   VLOG(1) << __func__;
13789   TPMS_ALGORITHM_DETAIL_ECC parameters;
13790   TPM_RC rc = Tpm::ParseResponse_ECC_Parameters(response, &parameters,
13791                                                 authorization_delegate);
13792   if (rc != TPM_RC_SUCCESS) {
13793     base::OnceCallback<void(TPM_RC)> error_reporter =
13794         base::BindOnce(ECC_ParametersErrorCallback, std::move(callback));
13795     std::move(error_reporter).Run(rc);
13796     return;
13797   }
13798   std::move(callback).Run(rc, parameters);
13799 }
13800 
ECC_Parameters(const TPMI_ECC_CURVE & curve_id,AuthorizationDelegate * authorization_delegate,ECC_ParametersResponse callback)13801 void Tpm::ECC_Parameters(const TPMI_ECC_CURVE& curve_id,
13802                          AuthorizationDelegate* authorization_delegate,
13803                          ECC_ParametersResponse callback) {
13804   VLOG(1) << __func__;
13805   std::string command;
13806   TPM_RC rc = SerializeCommand_ECC_Parameters(curve_id, &command,
13807                                               authorization_delegate);
13808   if (rc != TPM_RC_SUCCESS) {
13809     base::OnceCallback<void(TPM_RC)> error_reporter =
13810         base::BindOnce(ECC_ParametersErrorCallback, std::move(callback));
13811     std::move(error_reporter).Run(rc);
13812     return;
13813   }
13814   base::OnceCallback<void(const std::string&)> parser =
13815       base::BindOnce(ECC_ParametersResponseParser, std::move(callback),
13816                      authorization_delegate);
13817   transceiver_->SendCommand(command, std::move(parser));
13818 }
13819 
ECC_ParametersSync(const TPMI_ECC_CURVE & curve_id,TPMS_ALGORITHM_DETAIL_ECC * parameters,AuthorizationDelegate * authorization_delegate)13820 TPM_RC Tpm::ECC_ParametersSync(const TPMI_ECC_CURVE& curve_id,
13821                                TPMS_ALGORITHM_DETAIL_ECC* parameters,
13822                                AuthorizationDelegate* authorization_delegate) {
13823   VLOG(1) << __func__;
13824   std::string command;
13825   TPM_RC rc = SerializeCommand_ECC_Parameters(curve_id, &command,
13826                                               authorization_delegate);
13827   if (rc != TPM_RC_SUCCESS) {
13828     return rc;
13829   }
13830   std::string response = transceiver_->SendCommandAndWait(command);
13831   rc = ParseResponse_ECC_Parameters(response, parameters,
13832                                     authorization_delegate);
13833   return rc;
13834 }
13835 
SerializeCommand_ZGen_2Phase(const TPMI_DH_OBJECT & key_a,const std::string & key_a_name,const TPM2B_ECC_POINT & in_qs_b,const TPM2B_ECC_POINT & in_qe_b,const TPMI_ECC_KEY_EXCHANGE & in_scheme,const UINT16 & counter,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13836 TPM_RC Tpm::SerializeCommand_ZGen_2Phase(
13837     const TPMI_DH_OBJECT& key_a,
13838     const std::string& key_a_name,
13839     const TPM2B_ECC_POINT& in_qs_b,
13840     const TPM2B_ECC_POINT& in_qe_b,
13841     const TPMI_ECC_KEY_EXCHANGE& in_scheme,
13842     const UINT16& counter,
13843     std::string* serialized_command,
13844     AuthorizationDelegate* authorization_delegate) {
13845   VLOG(3) << __func__;
13846   TPM_RC rc = TPM_RC_SUCCESS;
13847   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13848   UINT32 command_size = 10;  // Header size.
13849   std::string handle_section_bytes;
13850   std::string parameter_section_bytes;
13851   TPM_CC command_code = TPM_CC_ZGen_2Phase;
13852   bool is_command_parameter_encryption_possible = true;
13853   bool is_response_parameter_encryption_possible = true;
13854   std::string command_code_bytes;
13855   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13856   if (rc != TPM_RC_SUCCESS) {
13857     return rc;
13858   }
13859   std::string key_a_bytes;
13860   rc = Serialize_TPMI_DH_OBJECT(key_a, &key_a_bytes);
13861   if (rc != TPM_RC_SUCCESS) {
13862     return rc;
13863   }
13864   std::string in_qs_b_bytes;
13865   rc = Serialize_TPM2B_ECC_POINT(in_qs_b, &in_qs_b_bytes);
13866   if (rc != TPM_RC_SUCCESS) {
13867     return rc;
13868   }
13869   std::string in_qe_b_bytes;
13870   rc = Serialize_TPM2B_ECC_POINT(in_qe_b, &in_qe_b_bytes);
13871   if (rc != TPM_RC_SUCCESS) {
13872     return rc;
13873   }
13874   std::string in_scheme_bytes;
13875   rc = Serialize_TPMI_ECC_KEY_EXCHANGE(in_scheme, &in_scheme_bytes);
13876   if (rc != TPM_RC_SUCCESS) {
13877     return rc;
13878   }
13879   std::string counter_bytes;
13880   rc = Serialize_UINT16(counter, &counter_bytes);
13881   if (rc != TPM_RC_SUCCESS) {
13882     return rc;
13883   }
13884   if (authorization_delegate) {
13885     // Encrypt just the parameter data, not the size.
13886     std::string tmp = in_qs_b_bytes.substr(2);
13887     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
13888       return TRUNKS_RC_ENCRYPTION_FAILED;
13889     }
13890     in_qs_b_bytes.replace(2, std::string::npos, tmp);
13891   }
13892   std::unique_ptr<crypto::SecureHash> hash(
13893       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13894   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13895   hash->Update(key_a_name.data(), key_a_name.size());
13896   handle_section_bytes += key_a_bytes;
13897   command_size += key_a_bytes.size();
13898   hash->Update(in_qs_b_bytes.data(), in_qs_b_bytes.size());
13899   parameter_section_bytes += in_qs_b_bytes;
13900   command_size += in_qs_b_bytes.size();
13901   hash->Update(in_qe_b_bytes.data(), in_qe_b_bytes.size());
13902   parameter_section_bytes += in_qe_b_bytes;
13903   command_size += in_qe_b_bytes.size();
13904   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
13905   parameter_section_bytes += in_scheme_bytes;
13906   command_size += in_scheme_bytes.size();
13907   hash->Update(counter_bytes.data(), counter_bytes.size());
13908   parameter_section_bytes += counter_bytes;
13909   command_size += counter_bytes.size();
13910   std::string command_hash(32, 0);
13911   hash->Finish(std::data(command_hash), command_hash.size());
13912   std::string authorization_section_bytes;
13913   std::string authorization_size_bytes;
13914   if (authorization_delegate) {
13915     if (!authorization_delegate->GetCommandAuthorization(
13916             command_hash, is_command_parameter_encryption_possible,
13917             is_response_parameter_encryption_possible,
13918             &authorization_section_bytes)) {
13919       return TRUNKS_RC_AUTHORIZATION_FAILED;
13920     }
13921     if (!authorization_section_bytes.empty()) {
13922       tag = TPM_ST_SESSIONS;
13923       std::string tmp;
13924       rc = Serialize_UINT32(authorization_section_bytes.size(),
13925                             &authorization_size_bytes);
13926       if (rc != TPM_RC_SUCCESS) {
13927         return rc;
13928       }
13929       command_size +=
13930           authorization_size_bytes.size() + authorization_section_bytes.size();
13931     }
13932   }
13933   std::string tag_bytes;
13934   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13935   if (rc != TPM_RC_SUCCESS) {
13936     return rc;
13937   }
13938   std::string command_size_bytes;
13939   rc = Serialize_UINT32(command_size, &command_size_bytes);
13940   if (rc != TPM_RC_SUCCESS) {
13941     return rc;
13942   }
13943   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13944                         handle_section_bytes + authorization_size_bytes +
13945                         authorization_section_bytes + parameter_section_bytes;
13946   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13947   VLOG(2) << "Command: "
13948           << base::HexEncode(serialized_command->data(),
13949                              serialized_command->size());
13950   return TPM_RC_SUCCESS;
13951 }
13952 
ParseResponse_ZGen_2Phase(const std::string & response,TPM2B_ECC_POINT * out_z1,TPM2B_ECC_POINT * out_z2,AuthorizationDelegate * authorization_delegate)13953 TPM_RC Tpm::ParseResponse_ZGen_2Phase(
13954     const std::string& response,
13955     TPM2B_ECC_POINT* out_z1,
13956     TPM2B_ECC_POINT* out_z2,
13957     AuthorizationDelegate* authorization_delegate) {
13958   VLOG(3) << __func__;
13959   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13960   TPM_RC rc = TPM_RC_SUCCESS;
13961   std::string buffer(response);
13962   TPM_ST tag;
13963   std::string tag_bytes;
13964   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13965   if (rc != TPM_RC_SUCCESS) {
13966     return rc;
13967   }
13968   UINT32 response_size;
13969   std::string response_size_bytes;
13970   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13971   if (rc != TPM_RC_SUCCESS) {
13972     return rc;
13973   }
13974   TPM_RC response_code;
13975   std::string response_code_bytes;
13976   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13977   if (rc != TPM_RC_SUCCESS) {
13978     return rc;
13979   }
13980   if (response_size != response.size()) {
13981     return TPM_RC_SIZE;
13982   }
13983   if (response_code != TPM_RC_SUCCESS) {
13984     return response_code;
13985   }
13986   TPM_CC command_code = TPM_CC_ZGen_2Phase;
13987   std::string command_code_bytes;
13988   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13989   if (rc != TPM_RC_SUCCESS) {
13990     return rc;
13991   }
13992   std::string authorization_section_bytes;
13993   if (tag == TPM_ST_SESSIONS) {
13994     UINT32 parameter_section_size = buffer.size();
13995     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13996     if (rc != TPM_RC_SUCCESS) {
13997       return rc;
13998     }
13999     if (parameter_section_size > buffer.size()) {
14000       return TPM_RC_INSUFFICIENT;
14001     }
14002     authorization_section_bytes = buffer.substr(parameter_section_size);
14003     // Keep the parameter section in |buffer|.
14004     buffer.erase(parameter_section_size);
14005   }
14006   std::unique_ptr<crypto::SecureHash> hash(
14007       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14008   hash->Update(response_code_bytes.data(), response_code_bytes.size());
14009   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14010   hash->Update(buffer.data(), buffer.size());
14011   std::string response_hash(32, 0);
14012   hash->Finish(std::data(response_hash), response_hash.size());
14013   if (tag == TPM_ST_SESSIONS) {
14014     if (!authorization_delegate)
14015       return TRUNKS_RC_AUTHORIZATION_FAILED;
14016     if (!authorization_delegate->CheckResponseAuthorization(
14017             response_hash, authorization_section_bytes)) {
14018       return TRUNKS_RC_AUTHORIZATION_FAILED;
14019     }
14020   }
14021   if (tag == TPM_ST_SESSIONS) {
14022     if (!authorization_delegate)
14023       return TRUNKS_RC_AUTHORIZATION_FAILED;
14024 
14025     // Parse the encrypted parameter size.
14026     UINT16 size;
14027     std::string size_buffer = buffer.substr(0, 2);
14028     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14029       return result;
14030     }
14031     if (buffer.size() < 2 + size) {
14032       return TPM_RC_INSUFFICIENT;
14033     }
14034 
14035     // Decrypt just the parameter data, not the size.
14036     std::string decrypted_data = buffer.substr(2, size);
14037     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14038       return TRUNKS_RC_ENCRYPTION_FAILED;
14039     }
14040     buffer.replace(2, size, decrypted_data);
14041   }
14042   std::string out_z1_bytes;
14043   rc = Parse_TPM2B_ECC_POINT(&buffer, out_z1, &out_z1_bytes);
14044   if (rc != TPM_RC_SUCCESS) {
14045     return rc;
14046   }
14047   std::string out_z2_bytes;
14048   rc = Parse_TPM2B_ECC_POINT(&buffer, out_z2, &out_z2_bytes);
14049   if (rc != TPM_RC_SUCCESS) {
14050     return rc;
14051   }
14052   return TPM_RC_SUCCESS;
14053 }
14054 
ZGen_2PhaseErrorCallback(Tpm::ZGen_2PhaseResponse callback,TPM_RC response_code)14055 void ZGen_2PhaseErrorCallback(Tpm::ZGen_2PhaseResponse callback,
14056                               TPM_RC response_code) {
14057   VLOG(1) << __func__;
14058   std::move(callback).Run(response_code, TPM2B_ECC_POINT(), TPM2B_ECC_POINT());
14059 }
14060 
ZGen_2PhaseResponseParser(Tpm::ZGen_2PhaseResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14061 void ZGen_2PhaseResponseParser(Tpm::ZGen_2PhaseResponse callback,
14062                                AuthorizationDelegate* authorization_delegate,
14063                                const std::string& response) {
14064   VLOG(1) << __func__;
14065   TPM2B_ECC_POINT out_z1;
14066   TPM2B_ECC_POINT out_z2;
14067   TPM_RC rc = Tpm::ParseResponse_ZGen_2Phase(response, &out_z1, &out_z2,
14068                                              authorization_delegate);
14069   if (rc != TPM_RC_SUCCESS) {
14070     base::OnceCallback<void(TPM_RC)> error_reporter =
14071         base::BindOnce(ZGen_2PhaseErrorCallback, std::move(callback));
14072     std::move(error_reporter).Run(rc);
14073     return;
14074   }
14075   std::move(callback).Run(rc, out_z1, out_z2);
14076 }
14077 
ZGen_2Phase(const TPMI_DH_OBJECT & key_a,const std::string & key_a_name,const TPM2B_ECC_POINT & in_qs_b,const TPM2B_ECC_POINT & in_qe_b,const TPMI_ECC_KEY_EXCHANGE & in_scheme,const UINT16 & counter,AuthorizationDelegate * authorization_delegate,ZGen_2PhaseResponse callback)14078 void Tpm::ZGen_2Phase(const TPMI_DH_OBJECT& key_a,
14079                       const std::string& key_a_name,
14080                       const TPM2B_ECC_POINT& in_qs_b,
14081                       const TPM2B_ECC_POINT& in_qe_b,
14082                       const TPMI_ECC_KEY_EXCHANGE& in_scheme,
14083                       const UINT16& counter,
14084                       AuthorizationDelegate* authorization_delegate,
14085                       ZGen_2PhaseResponse callback) {
14086   VLOG(1) << __func__;
14087   std::string command;
14088   TPM_RC rc = SerializeCommand_ZGen_2Phase(key_a, key_a_name, in_qs_b, in_qe_b,
14089                                            in_scheme, counter, &command,
14090                                            authorization_delegate);
14091   if (rc != TPM_RC_SUCCESS) {
14092     base::OnceCallback<void(TPM_RC)> error_reporter =
14093         base::BindOnce(ZGen_2PhaseErrorCallback, std::move(callback));
14094     std::move(error_reporter).Run(rc);
14095     return;
14096   }
14097   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14098       ZGen_2PhaseResponseParser, std::move(callback), authorization_delegate);
14099   transceiver_->SendCommand(command, std::move(parser));
14100 }
14101 
ZGen_2PhaseSync(const TPMI_DH_OBJECT & key_a,const std::string & key_a_name,const TPM2B_ECC_POINT & in_qs_b,const TPM2B_ECC_POINT & in_qe_b,const TPMI_ECC_KEY_EXCHANGE & in_scheme,const UINT16 & counter,TPM2B_ECC_POINT * out_z1,TPM2B_ECC_POINT * out_z2,AuthorizationDelegate * authorization_delegate)14102 TPM_RC Tpm::ZGen_2PhaseSync(const TPMI_DH_OBJECT& key_a,
14103                             const std::string& key_a_name,
14104                             const TPM2B_ECC_POINT& in_qs_b,
14105                             const TPM2B_ECC_POINT& in_qe_b,
14106                             const TPMI_ECC_KEY_EXCHANGE& in_scheme,
14107                             const UINT16& counter,
14108                             TPM2B_ECC_POINT* out_z1,
14109                             TPM2B_ECC_POINT* out_z2,
14110                             AuthorizationDelegate* authorization_delegate) {
14111   VLOG(1) << __func__;
14112   std::string command;
14113   TPM_RC rc = SerializeCommand_ZGen_2Phase(key_a, key_a_name, in_qs_b, in_qe_b,
14114                                            in_scheme, counter, &command,
14115                                            authorization_delegate);
14116   if (rc != TPM_RC_SUCCESS) {
14117     return rc;
14118   }
14119   std::string response = transceiver_->SendCommandAndWait(command);
14120   rc = ParseResponse_ZGen_2Phase(response, out_z1, out_z2,
14121                                  authorization_delegate);
14122   return rc;
14123 }
14124 
SerializeCommand_EncryptDecrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPMI_YES_NO & decrypt,const TPMI_ALG_SYM_MODE & mode,const TPM2B_IV & iv_in,const TPM2B_MAX_BUFFER & in_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14125 TPM_RC Tpm::SerializeCommand_EncryptDecrypt(
14126     const TPMI_DH_OBJECT& key_handle,
14127     const std::string& key_handle_name,
14128     const TPMI_YES_NO& decrypt,
14129     const TPMI_ALG_SYM_MODE& mode,
14130     const TPM2B_IV& iv_in,
14131     const TPM2B_MAX_BUFFER& in_data,
14132     std::string* serialized_command,
14133     AuthorizationDelegate* authorization_delegate) {
14134   VLOG(3) << __func__;
14135   TPM_RC rc = TPM_RC_SUCCESS;
14136   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14137   UINT32 command_size = 10;  // Header size.
14138   std::string handle_section_bytes;
14139   std::string parameter_section_bytes;
14140   TPM_CC command_code = TPM_CC_EncryptDecrypt;
14141   bool is_command_parameter_encryption_possible = false;
14142   bool is_response_parameter_encryption_possible = true;
14143   std::string command_code_bytes;
14144   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14145   if (rc != TPM_RC_SUCCESS) {
14146     return rc;
14147   }
14148   std::string key_handle_bytes;
14149   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
14150   if (rc != TPM_RC_SUCCESS) {
14151     return rc;
14152   }
14153   std::string decrypt_bytes;
14154   rc = Serialize_TPMI_YES_NO(decrypt, &decrypt_bytes);
14155   if (rc != TPM_RC_SUCCESS) {
14156     return rc;
14157   }
14158   std::string mode_bytes;
14159   rc = Serialize_TPMI_ALG_SYM_MODE(mode, &mode_bytes);
14160   if (rc != TPM_RC_SUCCESS) {
14161     return rc;
14162   }
14163   std::string iv_in_bytes;
14164   rc = Serialize_TPM2B_IV(iv_in, &iv_in_bytes);
14165   if (rc != TPM_RC_SUCCESS) {
14166     return rc;
14167   }
14168   std::string in_data_bytes;
14169   rc = Serialize_TPM2B_MAX_BUFFER(in_data, &in_data_bytes);
14170   if (rc != TPM_RC_SUCCESS) {
14171     return rc;
14172   }
14173   std::unique_ptr<crypto::SecureHash> hash(
14174       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14175   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14176   hash->Update(key_handle_name.data(), key_handle_name.size());
14177   handle_section_bytes += key_handle_bytes;
14178   command_size += key_handle_bytes.size();
14179   hash->Update(decrypt_bytes.data(), decrypt_bytes.size());
14180   parameter_section_bytes += decrypt_bytes;
14181   command_size += decrypt_bytes.size();
14182   hash->Update(mode_bytes.data(), mode_bytes.size());
14183   parameter_section_bytes += mode_bytes;
14184   command_size += mode_bytes.size();
14185   hash->Update(iv_in_bytes.data(), iv_in_bytes.size());
14186   parameter_section_bytes += iv_in_bytes;
14187   command_size += iv_in_bytes.size();
14188   hash->Update(in_data_bytes.data(), in_data_bytes.size());
14189   parameter_section_bytes += in_data_bytes;
14190   command_size += in_data_bytes.size();
14191   std::string command_hash(32, 0);
14192   hash->Finish(std::data(command_hash), command_hash.size());
14193   std::string authorization_section_bytes;
14194   std::string authorization_size_bytes;
14195   if (authorization_delegate) {
14196     if (!authorization_delegate->GetCommandAuthorization(
14197             command_hash, is_command_parameter_encryption_possible,
14198             is_response_parameter_encryption_possible,
14199             &authorization_section_bytes)) {
14200       return TRUNKS_RC_AUTHORIZATION_FAILED;
14201     }
14202     if (!authorization_section_bytes.empty()) {
14203       tag = TPM_ST_SESSIONS;
14204       std::string tmp;
14205       rc = Serialize_UINT32(authorization_section_bytes.size(),
14206                             &authorization_size_bytes);
14207       if (rc != TPM_RC_SUCCESS) {
14208         return rc;
14209       }
14210       command_size +=
14211           authorization_size_bytes.size() + authorization_section_bytes.size();
14212     }
14213   }
14214   std::string tag_bytes;
14215   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14216   if (rc != TPM_RC_SUCCESS) {
14217     return rc;
14218   }
14219   std::string command_size_bytes;
14220   rc = Serialize_UINT32(command_size, &command_size_bytes);
14221   if (rc != TPM_RC_SUCCESS) {
14222     return rc;
14223   }
14224   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14225                         handle_section_bytes + authorization_size_bytes +
14226                         authorization_section_bytes + parameter_section_bytes;
14227   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14228   VLOG(2) << "Command: "
14229           << base::HexEncode(serialized_command->data(),
14230                              serialized_command->size());
14231   return TPM_RC_SUCCESS;
14232 }
14233 
ParseResponse_EncryptDecrypt(const std::string & response,TPM2B_MAX_BUFFER * out_data,TPM2B_IV * iv_out,AuthorizationDelegate * authorization_delegate)14234 TPM_RC Tpm::ParseResponse_EncryptDecrypt(
14235     const std::string& response,
14236     TPM2B_MAX_BUFFER* out_data,
14237     TPM2B_IV* iv_out,
14238     AuthorizationDelegate* authorization_delegate) {
14239   VLOG(3) << __func__;
14240   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14241   TPM_RC rc = TPM_RC_SUCCESS;
14242   std::string buffer(response);
14243   TPM_ST tag;
14244   std::string tag_bytes;
14245   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14246   if (rc != TPM_RC_SUCCESS) {
14247     return rc;
14248   }
14249   UINT32 response_size;
14250   std::string response_size_bytes;
14251   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14252   if (rc != TPM_RC_SUCCESS) {
14253     return rc;
14254   }
14255   TPM_RC response_code;
14256   std::string response_code_bytes;
14257   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14258   if (rc != TPM_RC_SUCCESS) {
14259     return rc;
14260   }
14261   if (response_size != response.size()) {
14262     return TPM_RC_SIZE;
14263   }
14264   if (response_code != TPM_RC_SUCCESS) {
14265     return response_code;
14266   }
14267   TPM_CC command_code = TPM_CC_EncryptDecrypt;
14268   std::string command_code_bytes;
14269   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14270   if (rc != TPM_RC_SUCCESS) {
14271     return rc;
14272   }
14273   std::string authorization_section_bytes;
14274   if (tag == TPM_ST_SESSIONS) {
14275     UINT32 parameter_section_size = buffer.size();
14276     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14277     if (rc != TPM_RC_SUCCESS) {
14278       return rc;
14279     }
14280     if (parameter_section_size > buffer.size()) {
14281       return TPM_RC_INSUFFICIENT;
14282     }
14283     authorization_section_bytes = buffer.substr(parameter_section_size);
14284     // Keep the parameter section in |buffer|.
14285     buffer.erase(parameter_section_size);
14286   }
14287   std::unique_ptr<crypto::SecureHash> hash(
14288       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14289   hash->Update(response_code_bytes.data(), response_code_bytes.size());
14290   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14291   hash->Update(buffer.data(), buffer.size());
14292   std::string response_hash(32, 0);
14293   hash->Finish(std::data(response_hash), response_hash.size());
14294   if (tag == TPM_ST_SESSIONS) {
14295     if (!authorization_delegate)
14296       return TRUNKS_RC_AUTHORIZATION_FAILED;
14297     if (!authorization_delegate->CheckResponseAuthorization(
14298             response_hash, authorization_section_bytes)) {
14299       return TRUNKS_RC_AUTHORIZATION_FAILED;
14300     }
14301   }
14302   if (tag == TPM_ST_SESSIONS) {
14303     if (!authorization_delegate)
14304       return TRUNKS_RC_AUTHORIZATION_FAILED;
14305 
14306     // Parse the encrypted parameter size.
14307     UINT16 size;
14308     std::string size_buffer = buffer.substr(0, 2);
14309     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14310       return result;
14311     }
14312     if (buffer.size() < 2 + size) {
14313       return TPM_RC_INSUFFICIENT;
14314     }
14315 
14316     // Decrypt just the parameter data, not the size.
14317     std::string decrypted_data = buffer.substr(2, size);
14318     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14319       return TRUNKS_RC_ENCRYPTION_FAILED;
14320     }
14321     buffer.replace(2, size, decrypted_data);
14322   }
14323   std::string out_data_bytes;
14324   rc = Parse_TPM2B_MAX_BUFFER(&buffer, out_data, &out_data_bytes);
14325   if (rc != TPM_RC_SUCCESS) {
14326     return rc;
14327   }
14328   std::string iv_out_bytes;
14329   rc = Parse_TPM2B_IV(&buffer, iv_out, &iv_out_bytes);
14330   if (rc != TPM_RC_SUCCESS) {
14331     return rc;
14332   }
14333   return TPM_RC_SUCCESS;
14334 }
14335 
EncryptDecryptErrorCallback(Tpm::EncryptDecryptResponse callback,TPM_RC response_code)14336 void EncryptDecryptErrorCallback(Tpm::EncryptDecryptResponse callback,
14337                                  TPM_RC response_code) {
14338   VLOG(1) << __func__;
14339   std::move(callback).Run(response_code, TPM2B_MAX_BUFFER(), TPM2B_IV());
14340 }
14341 
EncryptDecryptResponseParser(Tpm::EncryptDecryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14342 void EncryptDecryptResponseParser(Tpm::EncryptDecryptResponse callback,
14343                                   AuthorizationDelegate* authorization_delegate,
14344                                   const std::string& response) {
14345   VLOG(1) << __func__;
14346   TPM2B_MAX_BUFFER out_data;
14347   TPM2B_IV iv_out;
14348   TPM_RC rc = Tpm::ParseResponse_EncryptDecrypt(response, &out_data, &iv_out,
14349                                                 authorization_delegate);
14350   if (rc != TPM_RC_SUCCESS) {
14351     base::OnceCallback<void(TPM_RC)> error_reporter =
14352         base::BindOnce(EncryptDecryptErrorCallback, std::move(callback));
14353     std::move(error_reporter).Run(rc);
14354     return;
14355   }
14356   std::move(callback).Run(rc, out_data, iv_out);
14357 }
14358 
EncryptDecrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPMI_YES_NO & decrypt,const TPMI_ALG_SYM_MODE & mode,const TPM2B_IV & iv_in,const TPM2B_MAX_BUFFER & in_data,AuthorizationDelegate * authorization_delegate,EncryptDecryptResponse callback)14359 void Tpm::EncryptDecrypt(const TPMI_DH_OBJECT& key_handle,
14360                          const std::string& key_handle_name,
14361                          const TPMI_YES_NO& decrypt,
14362                          const TPMI_ALG_SYM_MODE& mode,
14363                          const TPM2B_IV& iv_in,
14364                          const TPM2B_MAX_BUFFER& in_data,
14365                          AuthorizationDelegate* authorization_delegate,
14366                          EncryptDecryptResponse callback) {
14367   VLOG(1) << __func__;
14368   std::string command;
14369   TPM_RC rc = SerializeCommand_EncryptDecrypt(key_handle, key_handle_name,
14370                                               decrypt, mode, iv_in, in_data,
14371                                               &command, authorization_delegate);
14372   if (rc != TPM_RC_SUCCESS) {
14373     base::OnceCallback<void(TPM_RC)> error_reporter =
14374         base::BindOnce(EncryptDecryptErrorCallback, std::move(callback));
14375     std::move(error_reporter).Run(rc);
14376     return;
14377   }
14378   base::OnceCallback<void(const std::string&)> parser =
14379       base::BindOnce(EncryptDecryptResponseParser, std::move(callback),
14380                      authorization_delegate);
14381   transceiver_->SendCommand(command, std::move(parser));
14382 }
14383 
EncryptDecryptSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPMI_YES_NO & decrypt,const TPMI_ALG_SYM_MODE & mode,const TPM2B_IV & iv_in,const TPM2B_MAX_BUFFER & in_data,TPM2B_MAX_BUFFER * out_data,TPM2B_IV * iv_out,AuthorizationDelegate * authorization_delegate)14384 TPM_RC Tpm::EncryptDecryptSync(const TPMI_DH_OBJECT& key_handle,
14385                                const std::string& key_handle_name,
14386                                const TPMI_YES_NO& decrypt,
14387                                const TPMI_ALG_SYM_MODE& mode,
14388                                const TPM2B_IV& iv_in,
14389                                const TPM2B_MAX_BUFFER& in_data,
14390                                TPM2B_MAX_BUFFER* out_data,
14391                                TPM2B_IV* iv_out,
14392                                AuthorizationDelegate* authorization_delegate) {
14393   VLOG(1) << __func__;
14394   std::string command;
14395   TPM_RC rc = SerializeCommand_EncryptDecrypt(key_handle, key_handle_name,
14396                                               decrypt, mode, iv_in, in_data,
14397                                               &command, authorization_delegate);
14398   if (rc != TPM_RC_SUCCESS) {
14399     return rc;
14400   }
14401   std::string response = transceiver_->SendCommandAndWait(command);
14402   rc = ParseResponse_EncryptDecrypt(response, out_data, iv_out,
14403                                     authorization_delegate);
14404   return rc;
14405 }
14406 
SerializeCommand_Hash(const TPM2B_MAX_BUFFER & data,const TPMI_ALG_HASH & hash_alg,const TPMI_RH_HIERARCHY & hierarchy,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14407 TPM_RC Tpm::SerializeCommand_Hash(
14408     const TPM2B_MAX_BUFFER& data,
14409     const TPMI_ALG_HASH& hash_alg,
14410     const TPMI_RH_HIERARCHY& hierarchy,
14411     std::string* serialized_command,
14412     AuthorizationDelegate* authorization_delegate) {
14413   VLOG(3) << __func__;
14414   TPM_RC rc = TPM_RC_SUCCESS;
14415   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14416   UINT32 command_size = 10;  // Header size.
14417   std::string handle_section_bytes;
14418   std::string parameter_section_bytes;
14419   TPM_CC command_code = TPM_CC_Hash;
14420   bool is_command_parameter_encryption_possible = true;
14421   bool is_response_parameter_encryption_possible = true;
14422   std::string command_code_bytes;
14423   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14424   if (rc != TPM_RC_SUCCESS) {
14425     return rc;
14426   }
14427   std::string data_bytes;
14428   rc = Serialize_TPM2B_MAX_BUFFER(data, &data_bytes);
14429   if (rc != TPM_RC_SUCCESS) {
14430     return rc;
14431   }
14432   std::string hash_alg_bytes;
14433   rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
14434   if (rc != TPM_RC_SUCCESS) {
14435     return rc;
14436   }
14437   std::string hierarchy_bytes;
14438   rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
14439   if (rc != TPM_RC_SUCCESS) {
14440     return rc;
14441   }
14442   if (authorization_delegate) {
14443     // Encrypt just the parameter data, not the size.
14444     std::string tmp = data_bytes.substr(2);
14445     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14446       return TRUNKS_RC_ENCRYPTION_FAILED;
14447     }
14448     data_bytes.replace(2, std::string::npos, tmp);
14449   }
14450   std::unique_ptr<crypto::SecureHash> hash(
14451       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14452   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14453   hash->Update(data_bytes.data(), data_bytes.size());
14454   parameter_section_bytes += data_bytes;
14455   command_size += data_bytes.size();
14456   hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
14457   parameter_section_bytes += hash_alg_bytes;
14458   command_size += hash_alg_bytes.size();
14459   hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
14460   parameter_section_bytes += hierarchy_bytes;
14461   command_size += hierarchy_bytes.size();
14462   std::string command_hash(32, 0);
14463   hash->Finish(std::data(command_hash), command_hash.size());
14464   std::string authorization_section_bytes;
14465   std::string authorization_size_bytes;
14466   if (authorization_delegate) {
14467     if (!authorization_delegate->GetCommandAuthorization(
14468             command_hash, is_command_parameter_encryption_possible,
14469             is_response_parameter_encryption_possible,
14470             &authorization_section_bytes)) {
14471       return TRUNKS_RC_AUTHORIZATION_FAILED;
14472     }
14473     if (!authorization_section_bytes.empty()) {
14474       tag = TPM_ST_SESSIONS;
14475       std::string tmp;
14476       rc = Serialize_UINT32(authorization_section_bytes.size(),
14477                             &authorization_size_bytes);
14478       if (rc != TPM_RC_SUCCESS) {
14479         return rc;
14480       }
14481       command_size +=
14482           authorization_size_bytes.size() + authorization_section_bytes.size();
14483     }
14484   }
14485   std::string tag_bytes;
14486   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14487   if (rc != TPM_RC_SUCCESS) {
14488     return rc;
14489   }
14490   std::string command_size_bytes;
14491   rc = Serialize_UINT32(command_size, &command_size_bytes);
14492   if (rc != TPM_RC_SUCCESS) {
14493     return rc;
14494   }
14495   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14496                         handle_section_bytes + authorization_size_bytes +
14497                         authorization_section_bytes + parameter_section_bytes;
14498   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14499   VLOG(2) << "Command: "
14500           << base::HexEncode(serialized_command->data(),
14501                              serialized_command->size());
14502   return TPM_RC_SUCCESS;
14503 }
14504 
ParseResponse_Hash(const std::string & response,TPM2B_DIGEST * out_hash,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)14505 TPM_RC Tpm::ParseResponse_Hash(const std::string& response,
14506                                TPM2B_DIGEST* out_hash,
14507                                TPMT_TK_HASHCHECK* validation,
14508                                AuthorizationDelegate* authorization_delegate) {
14509   VLOG(3) << __func__;
14510   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14511   TPM_RC rc = TPM_RC_SUCCESS;
14512   std::string buffer(response);
14513   TPM_ST tag;
14514   std::string tag_bytes;
14515   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14516   if (rc != TPM_RC_SUCCESS) {
14517     return rc;
14518   }
14519   UINT32 response_size;
14520   std::string response_size_bytes;
14521   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14522   if (rc != TPM_RC_SUCCESS) {
14523     return rc;
14524   }
14525   TPM_RC response_code;
14526   std::string response_code_bytes;
14527   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14528   if (rc != TPM_RC_SUCCESS) {
14529     return rc;
14530   }
14531   if (response_size != response.size()) {
14532     return TPM_RC_SIZE;
14533   }
14534   if (response_code != TPM_RC_SUCCESS) {
14535     return response_code;
14536   }
14537   TPM_CC command_code = TPM_CC_Hash;
14538   std::string command_code_bytes;
14539   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14540   if (rc != TPM_RC_SUCCESS) {
14541     return rc;
14542   }
14543   std::string authorization_section_bytes;
14544   if (tag == TPM_ST_SESSIONS) {
14545     UINT32 parameter_section_size = buffer.size();
14546     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14547     if (rc != TPM_RC_SUCCESS) {
14548       return rc;
14549     }
14550     if (parameter_section_size > buffer.size()) {
14551       return TPM_RC_INSUFFICIENT;
14552     }
14553     authorization_section_bytes = buffer.substr(parameter_section_size);
14554     // Keep the parameter section in |buffer|.
14555     buffer.erase(parameter_section_size);
14556   }
14557   std::unique_ptr<crypto::SecureHash> hash(
14558       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14559   hash->Update(response_code_bytes.data(), response_code_bytes.size());
14560   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14561   hash->Update(buffer.data(), buffer.size());
14562   std::string response_hash(32, 0);
14563   hash->Finish(std::data(response_hash), response_hash.size());
14564   if (tag == TPM_ST_SESSIONS) {
14565     if (!authorization_delegate)
14566       return TRUNKS_RC_AUTHORIZATION_FAILED;
14567     if (!authorization_delegate->CheckResponseAuthorization(
14568             response_hash, authorization_section_bytes)) {
14569       return TRUNKS_RC_AUTHORIZATION_FAILED;
14570     }
14571   }
14572   if (tag == TPM_ST_SESSIONS) {
14573     if (!authorization_delegate)
14574       return TRUNKS_RC_AUTHORIZATION_FAILED;
14575 
14576     // Parse the encrypted parameter size.
14577     UINT16 size;
14578     std::string size_buffer = buffer.substr(0, 2);
14579     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14580       return result;
14581     }
14582     if (buffer.size() < 2 + size) {
14583       return TPM_RC_INSUFFICIENT;
14584     }
14585 
14586     // Decrypt just the parameter data, not the size.
14587     std::string decrypted_data = buffer.substr(2, size);
14588     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14589       return TRUNKS_RC_ENCRYPTION_FAILED;
14590     }
14591     buffer.replace(2, size, decrypted_data);
14592   }
14593   std::string out_hash_bytes;
14594   rc = Parse_TPM2B_DIGEST(&buffer, out_hash, &out_hash_bytes);
14595   if (rc != TPM_RC_SUCCESS) {
14596     return rc;
14597   }
14598   std::string validation_bytes;
14599   rc = Parse_TPMT_TK_HASHCHECK(&buffer, validation, &validation_bytes);
14600   if (rc != TPM_RC_SUCCESS) {
14601     return rc;
14602   }
14603   return TPM_RC_SUCCESS;
14604 }
14605 
HashErrorCallback(Tpm::HashResponse callback,TPM_RC response_code)14606 void HashErrorCallback(Tpm::HashResponse callback, TPM_RC response_code) {
14607   VLOG(1) << __func__;
14608   std::move(callback).Run(response_code, TPM2B_DIGEST(), TPMT_TK_HASHCHECK());
14609 }
14610 
HashResponseParser(Tpm::HashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14611 void HashResponseParser(Tpm::HashResponse callback,
14612                         AuthorizationDelegate* authorization_delegate,
14613                         const std::string& response) {
14614   VLOG(1) << __func__;
14615   TPM2B_DIGEST out_hash;
14616   TPMT_TK_HASHCHECK validation;
14617   TPM_RC rc = Tpm::ParseResponse_Hash(response, &out_hash, &validation,
14618                                       authorization_delegate);
14619   if (rc != TPM_RC_SUCCESS) {
14620     base::OnceCallback<void(TPM_RC)> error_reporter =
14621         base::BindOnce(HashErrorCallback, std::move(callback));
14622     std::move(error_reporter).Run(rc);
14623     return;
14624   }
14625   std::move(callback).Run(rc, out_hash, validation);
14626 }
14627 
Hash(const TPM2B_MAX_BUFFER & data,const TPMI_ALG_HASH & hash_alg,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,HashResponse callback)14628 void Tpm::Hash(const TPM2B_MAX_BUFFER& data,
14629                const TPMI_ALG_HASH& hash_alg,
14630                const TPMI_RH_HIERARCHY& hierarchy,
14631                AuthorizationDelegate* authorization_delegate,
14632                HashResponse callback) {
14633   VLOG(1) << __func__;
14634   std::string command;
14635   TPM_RC rc = SerializeCommand_Hash(data, hash_alg, hierarchy, &command,
14636                                     authorization_delegate);
14637   if (rc != TPM_RC_SUCCESS) {
14638     base::OnceCallback<void(TPM_RC)> error_reporter =
14639         base::BindOnce(HashErrorCallback, std::move(callback));
14640     std::move(error_reporter).Run(rc);
14641     return;
14642   }
14643   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14644       HashResponseParser, std::move(callback), authorization_delegate);
14645   transceiver_->SendCommand(command, std::move(parser));
14646 }
14647 
HashSync(const TPM2B_MAX_BUFFER & data,const TPMI_ALG_HASH & hash_alg,const TPMI_RH_HIERARCHY & hierarchy,TPM2B_DIGEST * out_hash,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)14648 TPM_RC Tpm::HashSync(const TPM2B_MAX_BUFFER& data,
14649                      const TPMI_ALG_HASH& hash_alg,
14650                      const TPMI_RH_HIERARCHY& hierarchy,
14651                      TPM2B_DIGEST* out_hash,
14652                      TPMT_TK_HASHCHECK* validation,
14653                      AuthorizationDelegate* authorization_delegate) {
14654   VLOG(1) << __func__;
14655   std::string command;
14656   TPM_RC rc = SerializeCommand_Hash(data, hash_alg, hierarchy, &command,
14657                                     authorization_delegate);
14658   if (rc != TPM_RC_SUCCESS) {
14659     return rc;
14660   }
14661   std::string response = transceiver_->SendCommandAndWait(command);
14662   rc = ParseResponse_Hash(response, out_hash, validation,
14663                           authorization_delegate);
14664   return rc;
14665 }
14666 
SerializeCommand_HMAC(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14667 TPM_RC Tpm::SerializeCommand_HMAC(
14668     const TPMI_DH_OBJECT& handle,
14669     const std::string& handle_name,
14670     const TPM2B_MAX_BUFFER& buffer,
14671     const TPMI_ALG_HASH& hash_alg,
14672     std::string* serialized_command,
14673     AuthorizationDelegate* authorization_delegate) {
14674   VLOG(3) << __func__;
14675   TPM_RC rc = TPM_RC_SUCCESS;
14676   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14677   UINT32 command_size = 10;  // Header size.
14678   std::string handle_section_bytes;
14679   std::string parameter_section_bytes;
14680   TPM_CC command_code = TPM_CC_HMAC;
14681   bool is_command_parameter_encryption_possible = true;
14682   bool is_response_parameter_encryption_possible = true;
14683   std::string command_code_bytes;
14684   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14685   if (rc != TPM_RC_SUCCESS) {
14686     return rc;
14687   }
14688   std::string handle_bytes;
14689   rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
14690   if (rc != TPM_RC_SUCCESS) {
14691     return rc;
14692   }
14693   std::string buffer_bytes;
14694   rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
14695   if (rc != TPM_RC_SUCCESS) {
14696     return rc;
14697   }
14698   std::string hash_alg_bytes;
14699   rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
14700   if (rc != TPM_RC_SUCCESS) {
14701     return rc;
14702   }
14703   if (authorization_delegate) {
14704     // Encrypt just the parameter data, not the size.
14705     std::string tmp = buffer_bytes.substr(2);
14706     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14707       return TRUNKS_RC_ENCRYPTION_FAILED;
14708     }
14709     buffer_bytes.replace(2, std::string::npos, tmp);
14710   }
14711   std::unique_ptr<crypto::SecureHash> hash(
14712       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14713   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14714   hash->Update(handle_name.data(), handle_name.size());
14715   handle_section_bytes += handle_bytes;
14716   command_size += handle_bytes.size();
14717   hash->Update(buffer_bytes.data(), buffer_bytes.size());
14718   parameter_section_bytes += buffer_bytes;
14719   command_size += buffer_bytes.size();
14720   hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
14721   parameter_section_bytes += hash_alg_bytes;
14722   command_size += hash_alg_bytes.size();
14723   std::string command_hash(32, 0);
14724   hash->Finish(std::data(command_hash), command_hash.size());
14725   std::string authorization_section_bytes;
14726   std::string authorization_size_bytes;
14727   if (authorization_delegate) {
14728     if (!authorization_delegate->GetCommandAuthorization(
14729             command_hash, is_command_parameter_encryption_possible,
14730             is_response_parameter_encryption_possible,
14731             &authorization_section_bytes)) {
14732       return TRUNKS_RC_AUTHORIZATION_FAILED;
14733     }
14734     if (!authorization_section_bytes.empty()) {
14735       tag = TPM_ST_SESSIONS;
14736       std::string tmp;
14737       rc = Serialize_UINT32(authorization_section_bytes.size(),
14738                             &authorization_size_bytes);
14739       if (rc != TPM_RC_SUCCESS) {
14740         return rc;
14741       }
14742       command_size +=
14743           authorization_size_bytes.size() + authorization_section_bytes.size();
14744     }
14745   }
14746   std::string tag_bytes;
14747   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14748   if (rc != TPM_RC_SUCCESS) {
14749     return rc;
14750   }
14751   std::string command_size_bytes;
14752   rc = Serialize_UINT32(command_size, &command_size_bytes);
14753   if (rc != TPM_RC_SUCCESS) {
14754     return rc;
14755   }
14756   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14757                         handle_section_bytes + authorization_size_bytes +
14758                         authorization_section_bytes + parameter_section_bytes;
14759   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14760   VLOG(2) << "Command: "
14761           << base::HexEncode(serialized_command->data(),
14762                              serialized_command->size());
14763   return TPM_RC_SUCCESS;
14764 }
14765 
ParseResponse_HMAC(const std::string & response,TPM2B_DIGEST * out_hmac,AuthorizationDelegate * authorization_delegate)14766 TPM_RC Tpm::ParseResponse_HMAC(const std::string& response,
14767                                TPM2B_DIGEST* out_hmac,
14768                                AuthorizationDelegate* authorization_delegate) {
14769   VLOG(3) << __func__;
14770   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14771   TPM_RC rc = TPM_RC_SUCCESS;
14772   std::string buffer(response);
14773   TPM_ST tag;
14774   std::string tag_bytes;
14775   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14776   if (rc != TPM_RC_SUCCESS) {
14777     return rc;
14778   }
14779   UINT32 response_size;
14780   std::string response_size_bytes;
14781   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14782   if (rc != TPM_RC_SUCCESS) {
14783     return rc;
14784   }
14785   TPM_RC response_code;
14786   std::string response_code_bytes;
14787   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14788   if (rc != TPM_RC_SUCCESS) {
14789     return rc;
14790   }
14791   if (response_size != response.size()) {
14792     return TPM_RC_SIZE;
14793   }
14794   if (response_code != TPM_RC_SUCCESS) {
14795     return response_code;
14796   }
14797   TPM_CC command_code = TPM_CC_HMAC;
14798   std::string command_code_bytes;
14799   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14800   if (rc != TPM_RC_SUCCESS) {
14801     return rc;
14802   }
14803   std::string authorization_section_bytes;
14804   if (tag == TPM_ST_SESSIONS) {
14805     UINT32 parameter_section_size = buffer.size();
14806     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14807     if (rc != TPM_RC_SUCCESS) {
14808       return rc;
14809     }
14810     if (parameter_section_size > buffer.size()) {
14811       return TPM_RC_INSUFFICIENT;
14812     }
14813     authorization_section_bytes = buffer.substr(parameter_section_size);
14814     // Keep the parameter section in |buffer|.
14815     buffer.erase(parameter_section_size);
14816   }
14817   std::unique_ptr<crypto::SecureHash> hash(
14818       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14819   hash->Update(response_code_bytes.data(), response_code_bytes.size());
14820   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14821   hash->Update(buffer.data(), buffer.size());
14822   std::string response_hash(32, 0);
14823   hash->Finish(std::data(response_hash), response_hash.size());
14824   if (tag == TPM_ST_SESSIONS) {
14825     if (!authorization_delegate)
14826       return TRUNKS_RC_AUTHORIZATION_FAILED;
14827     if (!authorization_delegate->CheckResponseAuthorization(
14828             response_hash, authorization_section_bytes)) {
14829       return TRUNKS_RC_AUTHORIZATION_FAILED;
14830     }
14831   }
14832   if (tag == TPM_ST_SESSIONS) {
14833     if (!authorization_delegate)
14834       return TRUNKS_RC_AUTHORIZATION_FAILED;
14835 
14836     // Parse the encrypted parameter size.
14837     UINT16 size;
14838     std::string size_buffer = buffer.substr(0, 2);
14839     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14840       return result;
14841     }
14842     if (buffer.size() < 2 + size) {
14843       return TPM_RC_INSUFFICIENT;
14844     }
14845 
14846     // Decrypt just the parameter data, not the size.
14847     std::string decrypted_data = buffer.substr(2, size);
14848     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14849       return TRUNKS_RC_ENCRYPTION_FAILED;
14850     }
14851     buffer.replace(2, size, decrypted_data);
14852   }
14853   std::string out_hmac_bytes;
14854   rc = Parse_TPM2B_DIGEST(&buffer, out_hmac, &out_hmac_bytes);
14855   if (rc != TPM_RC_SUCCESS) {
14856     return rc;
14857   }
14858   return TPM_RC_SUCCESS;
14859 }
14860 
HMACErrorCallback(Tpm::HMACResponse callback,TPM_RC response_code)14861 void HMACErrorCallback(Tpm::HMACResponse callback, TPM_RC response_code) {
14862   VLOG(1) << __func__;
14863   std::move(callback).Run(response_code, TPM2B_DIGEST());
14864 }
14865 
HMACResponseParser(Tpm::HMACResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14866 void HMACResponseParser(Tpm::HMACResponse callback,
14867                         AuthorizationDelegate* authorization_delegate,
14868                         const std::string& response) {
14869   VLOG(1) << __func__;
14870   TPM2B_DIGEST out_hmac;
14871   TPM_RC rc =
14872       Tpm::ParseResponse_HMAC(response, &out_hmac, authorization_delegate);
14873   if (rc != TPM_RC_SUCCESS) {
14874     base::OnceCallback<void(TPM_RC)> error_reporter =
14875         base::BindOnce(HMACErrorCallback, std::move(callback));
14876     std::move(error_reporter).Run(rc);
14877     return;
14878   }
14879   std::move(callback).Run(rc, out_hmac);
14880 }
14881 
HMAC(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,HMACResponse callback)14882 void Tpm::HMAC(const TPMI_DH_OBJECT& handle,
14883                const std::string& handle_name,
14884                const TPM2B_MAX_BUFFER& buffer,
14885                const TPMI_ALG_HASH& hash_alg,
14886                AuthorizationDelegate* authorization_delegate,
14887                HMACResponse callback) {
14888   VLOG(1) << __func__;
14889   std::string command;
14890   TPM_RC rc = SerializeCommand_HMAC(handle, handle_name, buffer, hash_alg,
14891                                     &command, authorization_delegate);
14892   if (rc != TPM_RC_SUCCESS) {
14893     base::OnceCallback<void(TPM_RC)> error_reporter =
14894         base::BindOnce(HMACErrorCallback, std::move(callback));
14895     std::move(error_reporter).Run(rc);
14896     return;
14897   }
14898   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14899       HMACResponseParser, std::move(callback), authorization_delegate);
14900   transceiver_->SendCommand(command, std::move(parser));
14901 }
14902 
HMACSync(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_ALG_HASH & hash_alg,TPM2B_DIGEST * out_hmac,AuthorizationDelegate * authorization_delegate)14903 TPM_RC Tpm::HMACSync(const TPMI_DH_OBJECT& handle,
14904                      const std::string& handle_name,
14905                      const TPM2B_MAX_BUFFER& buffer,
14906                      const TPMI_ALG_HASH& hash_alg,
14907                      TPM2B_DIGEST* out_hmac,
14908                      AuthorizationDelegate* authorization_delegate) {
14909   VLOG(1) << __func__;
14910   std::string command;
14911   TPM_RC rc = SerializeCommand_HMAC(handle, handle_name, buffer, hash_alg,
14912                                     &command, authorization_delegate);
14913   if (rc != TPM_RC_SUCCESS) {
14914     return rc;
14915   }
14916   std::string response = transceiver_->SendCommandAndWait(command);
14917   rc = ParseResponse_HMAC(response, out_hmac, authorization_delegate);
14918   return rc;
14919 }
14920 
SerializeCommand_GetRandom(const UINT16 & bytes_requested,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14921 TPM_RC Tpm::SerializeCommand_GetRandom(
14922     const UINT16& bytes_requested,
14923     std::string* serialized_command,
14924     AuthorizationDelegate* authorization_delegate) {
14925   VLOG(3) << __func__;
14926   TPM_RC rc = TPM_RC_SUCCESS;
14927   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14928   UINT32 command_size = 10;  // Header size.
14929   std::string handle_section_bytes;
14930   std::string parameter_section_bytes;
14931   TPM_CC command_code = TPM_CC_GetRandom;
14932   bool is_command_parameter_encryption_possible = false;
14933   bool is_response_parameter_encryption_possible = true;
14934   std::string command_code_bytes;
14935   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14936   if (rc != TPM_RC_SUCCESS) {
14937     return rc;
14938   }
14939   std::string bytes_requested_bytes;
14940   rc = Serialize_UINT16(bytes_requested, &bytes_requested_bytes);
14941   if (rc != TPM_RC_SUCCESS) {
14942     return rc;
14943   }
14944   std::unique_ptr<crypto::SecureHash> hash(
14945       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14946   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14947   hash->Update(bytes_requested_bytes.data(), bytes_requested_bytes.size());
14948   parameter_section_bytes += bytes_requested_bytes;
14949   command_size += bytes_requested_bytes.size();
14950   std::string command_hash(32, 0);
14951   hash->Finish(std::data(command_hash), command_hash.size());
14952   std::string authorization_section_bytes;
14953   std::string authorization_size_bytes;
14954   if (authorization_delegate) {
14955     if (!authorization_delegate->GetCommandAuthorization(
14956             command_hash, is_command_parameter_encryption_possible,
14957             is_response_parameter_encryption_possible,
14958             &authorization_section_bytes)) {
14959       return TRUNKS_RC_AUTHORIZATION_FAILED;
14960     }
14961     if (!authorization_section_bytes.empty()) {
14962       tag = TPM_ST_SESSIONS;
14963       std::string tmp;
14964       rc = Serialize_UINT32(authorization_section_bytes.size(),
14965                             &authorization_size_bytes);
14966       if (rc != TPM_RC_SUCCESS) {
14967         return rc;
14968       }
14969       command_size +=
14970           authorization_size_bytes.size() + authorization_section_bytes.size();
14971     }
14972   }
14973   std::string tag_bytes;
14974   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14975   if (rc != TPM_RC_SUCCESS) {
14976     return rc;
14977   }
14978   std::string command_size_bytes;
14979   rc = Serialize_UINT32(command_size, &command_size_bytes);
14980   if (rc != TPM_RC_SUCCESS) {
14981     return rc;
14982   }
14983   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14984                         handle_section_bytes + authorization_size_bytes +
14985                         authorization_section_bytes + parameter_section_bytes;
14986   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14987   VLOG(2) << "Command: "
14988           << base::HexEncode(serialized_command->data(),
14989                              serialized_command->size());
14990   return TPM_RC_SUCCESS;
14991 }
14992 
ParseResponse_GetRandom(const std::string & response,TPM2B_DIGEST * random_bytes,AuthorizationDelegate * authorization_delegate)14993 TPM_RC Tpm::ParseResponse_GetRandom(
14994     const std::string& response,
14995     TPM2B_DIGEST* random_bytes,
14996     AuthorizationDelegate* authorization_delegate) {
14997   VLOG(3) << __func__;
14998   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14999   TPM_RC rc = TPM_RC_SUCCESS;
15000   std::string buffer(response);
15001   TPM_ST tag;
15002   std::string tag_bytes;
15003   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15004   if (rc != TPM_RC_SUCCESS) {
15005     return rc;
15006   }
15007   UINT32 response_size;
15008   std::string response_size_bytes;
15009   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15010   if (rc != TPM_RC_SUCCESS) {
15011     return rc;
15012   }
15013   TPM_RC response_code;
15014   std::string response_code_bytes;
15015   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15016   if (rc != TPM_RC_SUCCESS) {
15017     return rc;
15018   }
15019   if (response_size != response.size()) {
15020     return TPM_RC_SIZE;
15021   }
15022   if (response_code != TPM_RC_SUCCESS) {
15023     return response_code;
15024   }
15025   TPM_CC command_code = TPM_CC_GetRandom;
15026   std::string command_code_bytes;
15027   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15028   if (rc != TPM_RC_SUCCESS) {
15029     return rc;
15030   }
15031   std::string authorization_section_bytes;
15032   if (tag == TPM_ST_SESSIONS) {
15033     UINT32 parameter_section_size = buffer.size();
15034     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15035     if (rc != TPM_RC_SUCCESS) {
15036       return rc;
15037     }
15038     if (parameter_section_size > buffer.size()) {
15039       return TPM_RC_INSUFFICIENT;
15040     }
15041     authorization_section_bytes = buffer.substr(parameter_section_size);
15042     // Keep the parameter section in |buffer|.
15043     buffer.erase(parameter_section_size);
15044   }
15045   std::unique_ptr<crypto::SecureHash> hash(
15046       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15047   hash->Update(response_code_bytes.data(), response_code_bytes.size());
15048   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15049   hash->Update(buffer.data(), buffer.size());
15050   std::string response_hash(32, 0);
15051   hash->Finish(std::data(response_hash), response_hash.size());
15052   if (tag == TPM_ST_SESSIONS) {
15053     if (!authorization_delegate)
15054       return TRUNKS_RC_AUTHORIZATION_FAILED;
15055     if (!authorization_delegate->CheckResponseAuthorization(
15056             response_hash, authorization_section_bytes)) {
15057       return TRUNKS_RC_AUTHORIZATION_FAILED;
15058     }
15059   }
15060   if (tag == TPM_ST_SESSIONS) {
15061     if (!authorization_delegate)
15062       return TRUNKS_RC_AUTHORIZATION_FAILED;
15063 
15064     // Parse the encrypted parameter size.
15065     UINT16 size;
15066     std::string size_buffer = buffer.substr(0, 2);
15067     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
15068       return result;
15069     }
15070     if (buffer.size() < 2 + size) {
15071       return TPM_RC_INSUFFICIENT;
15072     }
15073 
15074     // Decrypt just the parameter data, not the size.
15075     std::string decrypted_data = buffer.substr(2, size);
15076     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
15077       return TRUNKS_RC_ENCRYPTION_FAILED;
15078     }
15079     buffer.replace(2, size, decrypted_data);
15080   }
15081   std::string random_bytes_bytes;
15082   rc = Parse_TPM2B_DIGEST(&buffer, random_bytes, &random_bytes_bytes);
15083   if (rc != TPM_RC_SUCCESS) {
15084     return rc;
15085   }
15086   return TPM_RC_SUCCESS;
15087 }
15088 
GetRandomErrorCallback(Tpm::GetRandomResponse callback,TPM_RC response_code)15089 void GetRandomErrorCallback(Tpm::GetRandomResponse callback,
15090                             TPM_RC response_code) {
15091   VLOG(1) << __func__;
15092   std::move(callback).Run(response_code, TPM2B_DIGEST());
15093 }
15094 
GetRandomResponseParser(Tpm::GetRandomResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15095 void GetRandomResponseParser(Tpm::GetRandomResponse callback,
15096                              AuthorizationDelegate* authorization_delegate,
15097                              const std::string& response) {
15098   VLOG(1) << __func__;
15099   TPM2B_DIGEST random_bytes;
15100   TPM_RC rc = Tpm::ParseResponse_GetRandom(response, &random_bytes,
15101                                            authorization_delegate);
15102   if (rc != TPM_RC_SUCCESS) {
15103     base::OnceCallback<void(TPM_RC)> error_reporter =
15104         base::BindOnce(GetRandomErrorCallback, std::move(callback));
15105     std::move(error_reporter).Run(rc);
15106     return;
15107   }
15108   std::move(callback).Run(rc, random_bytes);
15109 }
15110 
GetRandom(const UINT16 & bytes_requested,AuthorizationDelegate * authorization_delegate,GetRandomResponse callback)15111 void Tpm::GetRandom(const UINT16& bytes_requested,
15112                     AuthorizationDelegate* authorization_delegate,
15113                     GetRandomResponse callback) {
15114   VLOG(1) << __func__;
15115   std::string command;
15116   TPM_RC rc = SerializeCommand_GetRandom(bytes_requested, &command,
15117                                          authorization_delegate);
15118   if (rc != TPM_RC_SUCCESS) {
15119     base::OnceCallback<void(TPM_RC)> error_reporter =
15120         base::BindOnce(GetRandomErrorCallback, std::move(callback));
15121     std::move(error_reporter).Run(rc);
15122     return;
15123   }
15124   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15125       GetRandomResponseParser, std::move(callback), authorization_delegate);
15126   transceiver_->SendCommand(command, std::move(parser));
15127 }
15128 
GetRandomSync(const UINT16 & bytes_requested,TPM2B_DIGEST * random_bytes,AuthorizationDelegate * authorization_delegate)15129 TPM_RC Tpm::GetRandomSync(const UINT16& bytes_requested,
15130                           TPM2B_DIGEST* random_bytes,
15131                           AuthorizationDelegate* authorization_delegate) {
15132   VLOG(1) << __func__;
15133   std::string command;
15134   TPM_RC rc = SerializeCommand_GetRandom(bytes_requested, &command,
15135                                          authorization_delegate);
15136   if (rc != TPM_RC_SUCCESS) {
15137     return rc;
15138   }
15139   std::string response = transceiver_->SendCommandAndWait(command);
15140   rc = ParseResponse_GetRandom(response, random_bytes, authorization_delegate);
15141   return rc;
15142 }
15143 
SerializeCommand_StirRandom(const TPM2B_SENSITIVE_DATA & in_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15144 TPM_RC Tpm::SerializeCommand_StirRandom(
15145     const TPM2B_SENSITIVE_DATA& in_data,
15146     std::string* serialized_command,
15147     AuthorizationDelegate* authorization_delegate) {
15148   VLOG(3) << __func__;
15149   TPM_RC rc = TPM_RC_SUCCESS;
15150   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15151   UINT32 command_size = 10;  // Header size.
15152   std::string handle_section_bytes;
15153   std::string parameter_section_bytes;
15154   TPM_CC command_code = TPM_CC_StirRandom;
15155   bool is_command_parameter_encryption_possible = true;
15156   bool is_response_parameter_encryption_possible = false;
15157   std::string command_code_bytes;
15158   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15159   if (rc != TPM_RC_SUCCESS) {
15160     return rc;
15161   }
15162   std::string in_data_bytes;
15163   rc = Serialize_TPM2B_SENSITIVE_DATA(in_data, &in_data_bytes);
15164   if (rc != TPM_RC_SUCCESS) {
15165     return rc;
15166   }
15167   if (authorization_delegate) {
15168     // Encrypt just the parameter data, not the size.
15169     std::string tmp = in_data_bytes.substr(2);
15170     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15171       return TRUNKS_RC_ENCRYPTION_FAILED;
15172     }
15173     in_data_bytes.replace(2, std::string::npos, tmp);
15174   }
15175   std::unique_ptr<crypto::SecureHash> hash(
15176       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15177   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15178   hash->Update(in_data_bytes.data(), in_data_bytes.size());
15179   parameter_section_bytes += in_data_bytes;
15180   command_size += in_data_bytes.size();
15181   std::string command_hash(32, 0);
15182   hash->Finish(std::data(command_hash), command_hash.size());
15183   std::string authorization_section_bytes;
15184   std::string authorization_size_bytes;
15185   if (authorization_delegate) {
15186     if (!authorization_delegate->GetCommandAuthorization(
15187             command_hash, is_command_parameter_encryption_possible,
15188             is_response_parameter_encryption_possible,
15189             &authorization_section_bytes)) {
15190       return TRUNKS_RC_AUTHORIZATION_FAILED;
15191     }
15192     if (!authorization_section_bytes.empty()) {
15193       tag = TPM_ST_SESSIONS;
15194       std::string tmp;
15195       rc = Serialize_UINT32(authorization_section_bytes.size(),
15196                             &authorization_size_bytes);
15197       if (rc != TPM_RC_SUCCESS) {
15198         return rc;
15199       }
15200       command_size +=
15201           authorization_size_bytes.size() + authorization_section_bytes.size();
15202     }
15203   }
15204   std::string tag_bytes;
15205   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15206   if (rc != TPM_RC_SUCCESS) {
15207     return rc;
15208   }
15209   std::string command_size_bytes;
15210   rc = Serialize_UINT32(command_size, &command_size_bytes);
15211   if (rc != TPM_RC_SUCCESS) {
15212     return rc;
15213   }
15214   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15215                         handle_section_bytes + authorization_size_bytes +
15216                         authorization_section_bytes + parameter_section_bytes;
15217   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15218   VLOG(2) << "Command: "
15219           << base::HexEncode(serialized_command->data(),
15220                              serialized_command->size());
15221   return TPM_RC_SUCCESS;
15222 }
15223 
ParseResponse_StirRandom(const std::string & response,AuthorizationDelegate * authorization_delegate)15224 TPM_RC Tpm::ParseResponse_StirRandom(
15225     const std::string& response,
15226     AuthorizationDelegate* authorization_delegate) {
15227   VLOG(3) << __func__;
15228   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15229   TPM_RC rc = TPM_RC_SUCCESS;
15230   std::string buffer(response);
15231   TPM_ST tag;
15232   std::string tag_bytes;
15233   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15234   if (rc != TPM_RC_SUCCESS) {
15235     return rc;
15236   }
15237   UINT32 response_size;
15238   std::string response_size_bytes;
15239   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15240   if (rc != TPM_RC_SUCCESS) {
15241     return rc;
15242   }
15243   TPM_RC response_code;
15244   std::string response_code_bytes;
15245   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15246   if (rc != TPM_RC_SUCCESS) {
15247     return rc;
15248   }
15249   if (response_size != response.size()) {
15250     return TPM_RC_SIZE;
15251   }
15252   if (response_code != TPM_RC_SUCCESS) {
15253     return response_code;
15254   }
15255   TPM_CC command_code = TPM_CC_StirRandom;
15256   std::string command_code_bytes;
15257   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15258   if (rc != TPM_RC_SUCCESS) {
15259     return rc;
15260   }
15261   std::string authorization_section_bytes;
15262   if (tag == TPM_ST_SESSIONS) {
15263     UINT32 parameter_section_size = buffer.size();
15264     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15265     if (rc != TPM_RC_SUCCESS) {
15266       return rc;
15267     }
15268     if (parameter_section_size > buffer.size()) {
15269       return TPM_RC_INSUFFICIENT;
15270     }
15271     authorization_section_bytes = buffer.substr(parameter_section_size);
15272     // Keep the parameter section in |buffer|.
15273     buffer.erase(parameter_section_size);
15274   }
15275   std::unique_ptr<crypto::SecureHash> hash(
15276       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15277   hash->Update(response_code_bytes.data(), response_code_bytes.size());
15278   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15279   hash->Update(buffer.data(), buffer.size());
15280   std::string response_hash(32, 0);
15281   hash->Finish(std::data(response_hash), response_hash.size());
15282   if (tag == TPM_ST_SESSIONS) {
15283     if (!authorization_delegate)
15284       return TRUNKS_RC_AUTHORIZATION_FAILED;
15285     if (!authorization_delegate->CheckResponseAuthorization(
15286             response_hash, authorization_section_bytes)) {
15287       return TRUNKS_RC_AUTHORIZATION_FAILED;
15288     }
15289   }
15290   return TPM_RC_SUCCESS;
15291 }
15292 
StirRandomErrorCallback(Tpm::StirRandomResponse callback,TPM_RC response_code)15293 void StirRandomErrorCallback(Tpm::StirRandomResponse callback,
15294                              TPM_RC response_code) {
15295   VLOG(1) << __func__;
15296   std::move(callback).Run(response_code);
15297 }
15298 
StirRandomResponseParser(Tpm::StirRandomResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15299 void StirRandomResponseParser(Tpm::StirRandomResponse callback,
15300                               AuthorizationDelegate* authorization_delegate,
15301                               const std::string& response) {
15302   VLOG(1) << __func__;
15303   TPM_RC rc = Tpm::ParseResponse_StirRandom(response, authorization_delegate);
15304   if (rc != TPM_RC_SUCCESS) {
15305     base::OnceCallback<void(TPM_RC)> error_reporter =
15306         base::BindOnce(StirRandomErrorCallback, std::move(callback));
15307     std::move(error_reporter).Run(rc);
15308     return;
15309   }
15310   std::move(callback).Run(rc);
15311 }
15312 
StirRandom(const TPM2B_SENSITIVE_DATA & in_data,AuthorizationDelegate * authorization_delegate,StirRandomResponse callback)15313 void Tpm::StirRandom(const TPM2B_SENSITIVE_DATA& in_data,
15314                      AuthorizationDelegate* authorization_delegate,
15315                      StirRandomResponse callback) {
15316   VLOG(1) << __func__;
15317   std::string command;
15318   TPM_RC rc =
15319       SerializeCommand_StirRandom(in_data, &command, authorization_delegate);
15320   if (rc != TPM_RC_SUCCESS) {
15321     base::OnceCallback<void(TPM_RC)> error_reporter =
15322         base::BindOnce(StirRandomErrorCallback, std::move(callback));
15323     std::move(error_reporter).Run(rc);
15324     return;
15325   }
15326   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15327       StirRandomResponseParser, std::move(callback), authorization_delegate);
15328   transceiver_->SendCommand(command, std::move(parser));
15329 }
15330 
StirRandomSync(const TPM2B_SENSITIVE_DATA & in_data,AuthorizationDelegate * authorization_delegate)15331 TPM_RC Tpm::StirRandomSync(const TPM2B_SENSITIVE_DATA& in_data,
15332                            AuthorizationDelegate* authorization_delegate) {
15333   VLOG(1) << __func__;
15334   std::string command;
15335   TPM_RC rc =
15336       SerializeCommand_StirRandom(in_data, &command, authorization_delegate);
15337   if (rc != TPM_RC_SUCCESS) {
15338     return rc;
15339   }
15340   std::string response = transceiver_->SendCommandAndWait(command);
15341   rc = ParseResponse_StirRandom(response, authorization_delegate);
15342   return rc;
15343 }
15344 
SerializeCommand_HMAC_Start(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15345 TPM_RC Tpm::SerializeCommand_HMAC_Start(
15346     const TPMI_DH_OBJECT& handle,
15347     const std::string& handle_name,
15348     const TPM2B_AUTH& auth,
15349     const TPMI_ALG_HASH& hash_alg,
15350     std::string* serialized_command,
15351     AuthorizationDelegate* authorization_delegate) {
15352   VLOG(3) << __func__;
15353   TPM_RC rc = TPM_RC_SUCCESS;
15354   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15355   UINT32 command_size = 10;  // Header size.
15356   std::string handle_section_bytes;
15357   std::string parameter_section_bytes;
15358   TPM_CC command_code = TPM_CC_HMAC_Start;
15359   bool is_command_parameter_encryption_possible = true;
15360   bool is_response_parameter_encryption_possible = false;
15361   std::string command_code_bytes;
15362   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15363   if (rc != TPM_RC_SUCCESS) {
15364     return rc;
15365   }
15366   std::string handle_bytes;
15367   rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
15368   if (rc != TPM_RC_SUCCESS) {
15369     return rc;
15370   }
15371   std::string auth_bytes;
15372   rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
15373   if (rc != TPM_RC_SUCCESS) {
15374     return rc;
15375   }
15376   std::string hash_alg_bytes;
15377   rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
15378   if (rc != TPM_RC_SUCCESS) {
15379     return rc;
15380   }
15381   if (authorization_delegate) {
15382     // Encrypt just the parameter data, not the size.
15383     std::string tmp = auth_bytes.substr(2);
15384     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15385       return TRUNKS_RC_ENCRYPTION_FAILED;
15386     }
15387     auth_bytes.replace(2, std::string::npos, tmp);
15388   }
15389   std::unique_ptr<crypto::SecureHash> hash(
15390       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15391   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15392   hash->Update(handle_name.data(), handle_name.size());
15393   handle_section_bytes += handle_bytes;
15394   command_size += handle_bytes.size();
15395   hash->Update(auth_bytes.data(), auth_bytes.size());
15396   parameter_section_bytes += auth_bytes;
15397   command_size += auth_bytes.size();
15398   hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
15399   parameter_section_bytes += hash_alg_bytes;
15400   command_size += hash_alg_bytes.size();
15401   std::string command_hash(32, 0);
15402   hash->Finish(std::data(command_hash), command_hash.size());
15403   std::string authorization_section_bytes;
15404   std::string authorization_size_bytes;
15405   if (authorization_delegate) {
15406     if (!authorization_delegate->GetCommandAuthorization(
15407             command_hash, is_command_parameter_encryption_possible,
15408             is_response_parameter_encryption_possible,
15409             &authorization_section_bytes)) {
15410       return TRUNKS_RC_AUTHORIZATION_FAILED;
15411     }
15412     if (!authorization_section_bytes.empty()) {
15413       tag = TPM_ST_SESSIONS;
15414       std::string tmp;
15415       rc = Serialize_UINT32(authorization_section_bytes.size(),
15416                             &authorization_size_bytes);
15417       if (rc != TPM_RC_SUCCESS) {
15418         return rc;
15419       }
15420       command_size +=
15421           authorization_size_bytes.size() + authorization_section_bytes.size();
15422     }
15423   }
15424   std::string tag_bytes;
15425   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15426   if (rc != TPM_RC_SUCCESS) {
15427     return rc;
15428   }
15429   std::string command_size_bytes;
15430   rc = Serialize_UINT32(command_size, &command_size_bytes);
15431   if (rc != TPM_RC_SUCCESS) {
15432     return rc;
15433   }
15434   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15435                         handle_section_bytes + authorization_size_bytes +
15436                         authorization_section_bytes + parameter_section_bytes;
15437   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15438   VLOG(2) << "Command: "
15439           << base::HexEncode(serialized_command->data(),
15440                              serialized_command->size());
15441   return TPM_RC_SUCCESS;
15442 }
15443 
ParseResponse_HMAC_Start(const std::string & response,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15444 TPM_RC Tpm::ParseResponse_HMAC_Start(
15445     const std::string& response,
15446     TPMI_DH_OBJECT* sequence_handle,
15447     AuthorizationDelegate* authorization_delegate) {
15448   VLOG(3) << __func__;
15449   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15450   TPM_RC rc = TPM_RC_SUCCESS;
15451   std::string buffer(response);
15452   TPM_ST tag;
15453   std::string tag_bytes;
15454   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15455   if (rc != TPM_RC_SUCCESS) {
15456     return rc;
15457   }
15458   UINT32 response_size;
15459   std::string response_size_bytes;
15460   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15461   if (rc != TPM_RC_SUCCESS) {
15462     return rc;
15463   }
15464   TPM_RC response_code;
15465   std::string response_code_bytes;
15466   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15467   if (rc != TPM_RC_SUCCESS) {
15468     return rc;
15469   }
15470   if (response_size != response.size()) {
15471     return TPM_RC_SIZE;
15472   }
15473   if (response_code != TPM_RC_SUCCESS) {
15474     return response_code;
15475   }
15476   std::string sequence_handle_bytes;
15477   rc = Parse_TPMI_DH_OBJECT(&buffer, sequence_handle, &sequence_handle_bytes);
15478   if (rc != TPM_RC_SUCCESS) {
15479     return rc;
15480   }
15481   TPM_CC command_code = TPM_CC_HMAC_Start;
15482   std::string command_code_bytes;
15483   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15484   if (rc != TPM_RC_SUCCESS) {
15485     return rc;
15486   }
15487   std::string authorization_section_bytes;
15488   if (tag == TPM_ST_SESSIONS) {
15489     UINT32 parameter_section_size = buffer.size();
15490     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15491     if (rc != TPM_RC_SUCCESS) {
15492       return rc;
15493     }
15494     if (parameter_section_size > buffer.size()) {
15495       return TPM_RC_INSUFFICIENT;
15496     }
15497     authorization_section_bytes = buffer.substr(parameter_section_size);
15498     // Keep the parameter section in |buffer|.
15499     buffer.erase(parameter_section_size);
15500   }
15501   std::unique_ptr<crypto::SecureHash> hash(
15502       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15503   hash->Update(response_code_bytes.data(), response_code_bytes.size());
15504   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15505   hash->Update(buffer.data(), buffer.size());
15506   std::string response_hash(32, 0);
15507   hash->Finish(std::data(response_hash), response_hash.size());
15508   if (tag == TPM_ST_SESSIONS) {
15509     if (!authorization_delegate)
15510       return TRUNKS_RC_AUTHORIZATION_FAILED;
15511     if (!authorization_delegate->CheckResponseAuthorization(
15512             response_hash, authorization_section_bytes)) {
15513       return TRUNKS_RC_AUTHORIZATION_FAILED;
15514     }
15515   }
15516   return TPM_RC_SUCCESS;
15517 }
15518 
HMAC_StartErrorCallback(Tpm::HMAC_StartResponse callback,TPM_RC response_code)15519 void HMAC_StartErrorCallback(Tpm::HMAC_StartResponse callback,
15520                              TPM_RC response_code) {
15521   VLOG(1) << __func__;
15522   std::move(callback).Run(response_code, TPMI_DH_OBJECT());
15523 }
15524 
HMAC_StartResponseParser(Tpm::HMAC_StartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15525 void HMAC_StartResponseParser(Tpm::HMAC_StartResponse callback,
15526                               AuthorizationDelegate* authorization_delegate,
15527                               const std::string& response) {
15528   VLOG(1) << __func__;
15529   TPMI_DH_OBJECT sequence_handle;
15530   TPM_RC rc = Tpm::ParseResponse_HMAC_Start(response, &sequence_handle,
15531                                             authorization_delegate);
15532   if (rc != TPM_RC_SUCCESS) {
15533     base::OnceCallback<void(TPM_RC)> error_reporter =
15534         base::BindOnce(HMAC_StartErrorCallback, std::move(callback));
15535     std::move(error_reporter).Run(rc);
15536     return;
15537   }
15538   std::move(callback).Run(rc, sequence_handle);
15539 }
15540 
HMAC_Start(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,HMAC_StartResponse callback)15541 void Tpm::HMAC_Start(const TPMI_DH_OBJECT& handle,
15542                      const std::string& handle_name,
15543                      const TPM2B_AUTH& auth,
15544                      const TPMI_ALG_HASH& hash_alg,
15545                      AuthorizationDelegate* authorization_delegate,
15546                      HMAC_StartResponse callback) {
15547   VLOG(1) << __func__;
15548   std::string command;
15549   TPM_RC rc = SerializeCommand_HMAC_Start(handle, handle_name, auth, hash_alg,
15550                                           &command, authorization_delegate);
15551   if (rc != TPM_RC_SUCCESS) {
15552     base::OnceCallback<void(TPM_RC)> error_reporter =
15553         base::BindOnce(HMAC_StartErrorCallback, std::move(callback));
15554     std::move(error_reporter).Run(rc);
15555     return;
15556   }
15557   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15558       HMAC_StartResponseParser, std::move(callback), authorization_delegate);
15559   transceiver_->SendCommand(command, std::move(parser));
15560 }
15561 
HMAC_StartSync(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15562 TPM_RC Tpm::HMAC_StartSync(const TPMI_DH_OBJECT& handle,
15563                            const std::string& handle_name,
15564                            const TPM2B_AUTH& auth,
15565                            const TPMI_ALG_HASH& hash_alg,
15566                            TPMI_DH_OBJECT* sequence_handle,
15567                            AuthorizationDelegate* authorization_delegate) {
15568   VLOG(1) << __func__;
15569   std::string command;
15570   TPM_RC rc = SerializeCommand_HMAC_Start(handle, handle_name, auth, hash_alg,
15571                                           &command, authorization_delegate);
15572   if (rc != TPM_RC_SUCCESS) {
15573     return rc;
15574   }
15575   std::string response = transceiver_->SendCommandAndWait(command);
15576   rc = ParseResponse_HMAC_Start(response, sequence_handle,
15577                                 authorization_delegate);
15578   return rc;
15579 }
15580 
SerializeCommand_HashSequenceStart(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15581 TPM_RC Tpm::SerializeCommand_HashSequenceStart(
15582     const TPM2B_AUTH& auth,
15583     const TPMI_ALG_HASH& hash_alg,
15584     std::string* serialized_command,
15585     AuthorizationDelegate* authorization_delegate) {
15586   VLOG(3) << __func__;
15587   TPM_RC rc = TPM_RC_SUCCESS;
15588   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15589   UINT32 command_size = 10;  // Header size.
15590   std::string handle_section_bytes;
15591   std::string parameter_section_bytes;
15592   TPM_CC command_code = TPM_CC_HashSequenceStart;
15593   bool is_command_parameter_encryption_possible = true;
15594   bool is_response_parameter_encryption_possible = false;
15595   std::string command_code_bytes;
15596   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15597   if (rc != TPM_RC_SUCCESS) {
15598     return rc;
15599   }
15600   std::string auth_bytes;
15601   rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
15602   if (rc != TPM_RC_SUCCESS) {
15603     return rc;
15604   }
15605   std::string hash_alg_bytes;
15606   rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
15607   if (rc != TPM_RC_SUCCESS) {
15608     return rc;
15609   }
15610   if (authorization_delegate) {
15611     // Encrypt just the parameter data, not the size.
15612     std::string tmp = auth_bytes.substr(2);
15613     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15614       return TRUNKS_RC_ENCRYPTION_FAILED;
15615     }
15616     auth_bytes.replace(2, std::string::npos, tmp);
15617   }
15618   std::unique_ptr<crypto::SecureHash> hash(
15619       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15620   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15621   hash->Update(auth_bytes.data(), auth_bytes.size());
15622   parameter_section_bytes += auth_bytes;
15623   command_size += auth_bytes.size();
15624   hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
15625   parameter_section_bytes += hash_alg_bytes;
15626   command_size += hash_alg_bytes.size();
15627   std::string command_hash(32, 0);
15628   hash->Finish(std::data(command_hash), command_hash.size());
15629   std::string authorization_section_bytes;
15630   std::string authorization_size_bytes;
15631   if (authorization_delegate) {
15632     if (!authorization_delegate->GetCommandAuthorization(
15633             command_hash, is_command_parameter_encryption_possible,
15634             is_response_parameter_encryption_possible,
15635             &authorization_section_bytes)) {
15636       return TRUNKS_RC_AUTHORIZATION_FAILED;
15637     }
15638     if (!authorization_section_bytes.empty()) {
15639       tag = TPM_ST_SESSIONS;
15640       std::string tmp;
15641       rc = Serialize_UINT32(authorization_section_bytes.size(),
15642                             &authorization_size_bytes);
15643       if (rc != TPM_RC_SUCCESS) {
15644         return rc;
15645       }
15646       command_size +=
15647           authorization_size_bytes.size() + authorization_section_bytes.size();
15648     }
15649   }
15650   std::string tag_bytes;
15651   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15652   if (rc != TPM_RC_SUCCESS) {
15653     return rc;
15654   }
15655   std::string command_size_bytes;
15656   rc = Serialize_UINT32(command_size, &command_size_bytes);
15657   if (rc != TPM_RC_SUCCESS) {
15658     return rc;
15659   }
15660   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15661                         handle_section_bytes + authorization_size_bytes +
15662                         authorization_section_bytes + parameter_section_bytes;
15663   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15664   VLOG(2) << "Command: "
15665           << base::HexEncode(serialized_command->data(),
15666                              serialized_command->size());
15667   return TPM_RC_SUCCESS;
15668 }
15669 
ParseResponse_HashSequenceStart(const std::string & response,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15670 TPM_RC Tpm::ParseResponse_HashSequenceStart(
15671     const std::string& response,
15672     TPMI_DH_OBJECT* sequence_handle,
15673     AuthorizationDelegate* authorization_delegate) {
15674   VLOG(3) << __func__;
15675   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15676   TPM_RC rc = TPM_RC_SUCCESS;
15677   std::string buffer(response);
15678   TPM_ST tag;
15679   std::string tag_bytes;
15680   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15681   if (rc != TPM_RC_SUCCESS) {
15682     return rc;
15683   }
15684   UINT32 response_size;
15685   std::string response_size_bytes;
15686   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15687   if (rc != TPM_RC_SUCCESS) {
15688     return rc;
15689   }
15690   TPM_RC response_code;
15691   std::string response_code_bytes;
15692   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15693   if (rc != TPM_RC_SUCCESS) {
15694     return rc;
15695   }
15696   if (response_size != response.size()) {
15697     return TPM_RC_SIZE;
15698   }
15699   if (response_code != TPM_RC_SUCCESS) {
15700     return response_code;
15701   }
15702   std::string sequence_handle_bytes;
15703   rc = Parse_TPMI_DH_OBJECT(&buffer, sequence_handle, &sequence_handle_bytes);
15704   if (rc != TPM_RC_SUCCESS) {
15705     return rc;
15706   }
15707   TPM_CC command_code = TPM_CC_HashSequenceStart;
15708   std::string command_code_bytes;
15709   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15710   if (rc != TPM_RC_SUCCESS) {
15711     return rc;
15712   }
15713   std::string authorization_section_bytes;
15714   if (tag == TPM_ST_SESSIONS) {
15715     UINT32 parameter_section_size = buffer.size();
15716     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15717     if (rc != TPM_RC_SUCCESS) {
15718       return rc;
15719     }
15720     if (parameter_section_size > buffer.size()) {
15721       return TPM_RC_INSUFFICIENT;
15722     }
15723     authorization_section_bytes = buffer.substr(parameter_section_size);
15724     // Keep the parameter section in |buffer|.
15725     buffer.erase(parameter_section_size);
15726   }
15727   std::unique_ptr<crypto::SecureHash> hash(
15728       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15729   hash->Update(response_code_bytes.data(), response_code_bytes.size());
15730   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15731   hash->Update(buffer.data(), buffer.size());
15732   std::string response_hash(32, 0);
15733   hash->Finish(std::data(response_hash), response_hash.size());
15734   if (tag == TPM_ST_SESSIONS) {
15735     if (!authorization_delegate)
15736       return TRUNKS_RC_AUTHORIZATION_FAILED;
15737     if (!authorization_delegate->CheckResponseAuthorization(
15738             response_hash, authorization_section_bytes)) {
15739       return TRUNKS_RC_AUTHORIZATION_FAILED;
15740     }
15741   }
15742   return TPM_RC_SUCCESS;
15743 }
15744 
HashSequenceStartErrorCallback(Tpm::HashSequenceStartResponse callback,TPM_RC response_code)15745 void HashSequenceStartErrorCallback(Tpm::HashSequenceStartResponse callback,
15746                                     TPM_RC response_code) {
15747   VLOG(1) << __func__;
15748   std::move(callback).Run(response_code, TPMI_DH_OBJECT());
15749 }
15750 
HashSequenceStartResponseParser(Tpm::HashSequenceStartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15751 void HashSequenceStartResponseParser(
15752     Tpm::HashSequenceStartResponse callback,
15753     AuthorizationDelegate* authorization_delegate,
15754     const std::string& response) {
15755   VLOG(1) << __func__;
15756   TPMI_DH_OBJECT sequence_handle;
15757   TPM_RC rc = Tpm::ParseResponse_HashSequenceStart(response, &sequence_handle,
15758                                                    authorization_delegate);
15759   if (rc != TPM_RC_SUCCESS) {
15760     base::OnceCallback<void(TPM_RC)> error_reporter =
15761         base::BindOnce(HashSequenceStartErrorCallback, std::move(callback));
15762     std::move(error_reporter).Run(rc);
15763     return;
15764   }
15765   std::move(callback).Run(rc, sequence_handle);
15766 }
15767 
HashSequenceStart(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,HashSequenceStartResponse callback)15768 void Tpm::HashSequenceStart(const TPM2B_AUTH& auth,
15769                             const TPMI_ALG_HASH& hash_alg,
15770                             AuthorizationDelegate* authorization_delegate,
15771                             HashSequenceStartResponse callback) {
15772   VLOG(1) << __func__;
15773   std::string command;
15774   TPM_RC rc = SerializeCommand_HashSequenceStart(auth, hash_alg, &command,
15775                                                  authorization_delegate);
15776   if (rc != TPM_RC_SUCCESS) {
15777     base::OnceCallback<void(TPM_RC)> error_reporter =
15778         base::BindOnce(HashSequenceStartErrorCallback, std::move(callback));
15779     std::move(error_reporter).Run(rc);
15780     return;
15781   }
15782   base::OnceCallback<void(const std::string&)> parser =
15783       base::BindOnce(HashSequenceStartResponseParser, std::move(callback),
15784                      authorization_delegate);
15785   transceiver_->SendCommand(command, std::move(parser));
15786 }
15787 
HashSequenceStartSync(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15788 TPM_RC Tpm::HashSequenceStartSync(
15789     const TPM2B_AUTH& auth,
15790     const TPMI_ALG_HASH& hash_alg,
15791     TPMI_DH_OBJECT* sequence_handle,
15792     AuthorizationDelegate* authorization_delegate) {
15793   VLOG(1) << __func__;
15794   std::string command;
15795   TPM_RC rc = SerializeCommand_HashSequenceStart(auth, hash_alg, &command,
15796                                                  authorization_delegate);
15797   if (rc != TPM_RC_SUCCESS) {
15798     return rc;
15799   }
15800   std::string response = transceiver_->SendCommandAndWait(command);
15801   rc = ParseResponse_HashSequenceStart(response, sequence_handle,
15802                                        authorization_delegate);
15803   return rc;
15804 }
15805 
SerializeCommand_SequenceUpdate(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15806 TPM_RC Tpm::SerializeCommand_SequenceUpdate(
15807     const TPMI_DH_OBJECT& sequence_handle,
15808     const std::string& sequence_handle_name,
15809     const TPM2B_MAX_BUFFER& buffer,
15810     std::string* serialized_command,
15811     AuthorizationDelegate* authorization_delegate) {
15812   VLOG(3) << __func__;
15813   TPM_RC rc = TPM_RC_SUCCESS;
15814   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15815   UINT32 command_size = 10;  // Header size.
15816   std::string handle_section_bytes;
15817   std::string parameter_section_bytes;
15818   TPM_CC command_code = TPM_CC_SequenceUpdate;
15819   bool is_command_parameter_encryption_possible = true;
15820   bool is_response_parameter_encryption_possible = false;
15821   std::string command_code_bytes;
15822   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15823   if (rc != TPM_RC_SUCCESS) {
15824     return rc;
15825   }
15826   std::string sequence_handle_bytes;
15827   rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
15828   if (rc != TPM_RC_SUCCESS) {
15829     return rc;
15830   }
15831   std::string buffer_bytes;
15832   rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
15833   if (rc != TPM_RC_SUCCESS) {
15834     return rc;
15835   }
15836   if (authorization_delegate) {
15837     // Encrypt just the parameter data, not the size.
15838     std::string tmp = buffer_bytes.substr(2);
15839     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15840       return TRUNKS_RC_ENCRYPTION_FAILED;
15841     }
15842     buffer_bytes.replace(2, std::string::npos, tmp);
15843   }
15844   std::unique_ptr<crypto::SecureHash> hash(
15845       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15846   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15847   hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
15848   handle_section_bytes += sequence_handle_bytes;
15849   command_size += sequence_handle_bytes.size();
15850   hash->Update(buffer_bytes.data(), buffer_bytes.size());
15851   parameter_section_bytes += buffer_bytes;
15852   command_size += buffer_bytes.size();
15853   std::string command_hash(32, 0);
15854   hash->Finish(std::data(command_hash), command_hash.size());
15855   std::string authorization_section_bytes;
15856   std::string authorization_size_bytes;
15857   if (authorization_delegate) {
15858     if (!authorization_delegate->GetCommandAuthorization(
15859             command_hash, is_command_parameter_encryption_possible,
15860             is_response_parameter_encryption_possible,
15861             &authorization_section_bytes)) {
15862       return TRUNKS_RC_AUTHORIZATION_FAILED;
15863     }
15864     if (!authorization_section_bytes.empty()) {
15865       tag = TPM_ST_SESSIONS;
15866       std::string tmp;
15867       rc = Serialize_UINT32(authorization_section_bytes.size(),
15868                             &authorization_size_bytes);
15869       if (rc != TPM_RC_SUCCESS) {
15870         return rc;
15871       }
15872       command_size +=
15873           authorization_size_bytes.size() + authorization_section_bytes.size();
15874     }
15875   }
15876   std::string tag_bytes;
15877   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15878   if (rc != TPM_RC_SUCCESS) {
15879     return rc;
15880   }
15881   std::string command_size_bytes;
15882   rc = Serialize_UINT32(command_size, &command_size_bytes);
15883   if (rc != TPM_RC_SUCCESS) {
15884     return rc;
15885   }
15886   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15887                         handle_section_bytes + authorization_size_bytes +
15888                         authorization_section_bytes + parameter_section_bytes;
15889   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15890   VLOG(2) << "Command: "
15891           << base::HexEncode(serialized_command->data(),
15892                              serialized_command->size());
15893   return TPM_RC_SUCCESS;
15894 }
15895 
ParseResponse_SequenceUpdate(const std::string & response,AuthorizationDelegate * authorization_delegate)15896 TPM_RC Tpm::ParseResponse_SequenceUpdate(
15897     const std::string& response,
15898     AuthorizationDelegate* authorization_delegate) {
15899   VLOG(3) << __func__;
15900   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15901   TPM_RC rc = TPM_RC_SUCCESS;
15902   std::string buffer(response);
15903   TPM_ST tag;
15904   std::string tag_bytes;
15905   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15906   if (rc != TPM_RC_SUCCESS) {
15907     return rc;
15908   }
15909   UINT32 response_size;
15910   std::string response_size_bytes;
15911   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15912   if (rc != TPM_RC_SUCCESS) {
15913     return rc;
15914   }
15915   TPM_RC response_code;
15916   std::string response_code_bytes;
15917   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15918   if (rc != TPM_RC_SUCCESS) {
15919     return rc;
15920   }
15921   if (response_size != response.size()) {
15922     return TPM_RC_SIZE;
15923   }
15924   if (response_code != TPM_RC_SUCCESS) {
15925     return response_code;
15926   }
15927   TPM_CC command_code = TPM_CC_SequenceUpdate;
15928   std::string command_code_bytes;
15929   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15930   if (rc != TPM_RC_SUCCESS) {
15931     return rc;
15932   }
15933   std::string authorization_section_bytes;
15934   if (tag == TPM_ST_SESSIONS) {
15935     UINT32 parameter_section_size = buffer.size();
15936     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15937     if (rc != TPM_RC_SUCCESS) {
15938       return rc;
15939     }
15940     if (parameter_section_size > buffer.size()) {
15941       return TPM_RC_INSUFFICIENT;
15942     }
15943     authorization_section_bytes = buffer.substr(parameter_section_size);
15944     // Keep the parameter section in |buffer|.
15945     buffer.erase(parameter_section_size);
15946   }
15947   std::unique_ptr<crypto::SecureHash> hash(
15948       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15949   hash->Update(response_code_bytes.data(), response_code_bytes.size());
15950   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15951   hash->Update(buffer.data(), buffer.size());
15952   std::string response_hash(32, 0);
15953   hash->Finish(std::data(response_hash), response_hash.size());
15954   if (tag == TPM_ST_SESSIONS) {
15955     if (!authorization_delegate)
15956       return TRUNKS_RC_AUTHORIZATION_FAILED;
15957     if (!authorization_delegate->CheckResponseAuthorization(
15958             response_hash, authorization_section_bytes)) {
15959       return TRUNKS_RC_AUTHORIZATION_FAILED;
15960     }
15961   }
15962   return TPM_RC_SUCCESS;
15963 }
15964 
SequenceUpdateErrorCallback(Tpm::SequenceUpdateResponse callback,TPM_RC response_code)15965 void SequenceUpdateErrorCallback(Tpm::SequenceUpdateResponse callback,
15966                                  TPM_RC response_code) {
15967   VLOG(1) << __func__;
15968   std::move(callback).Run(response_code);
15969 }
15970 
SequenceUpdateResponseParser(Tpm::SequenceUpdateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15971 void SequenceUpdateResponseParser(Tpm::SequenceUpdateResponse callback,
15972                                   AuthorizationDelegate* authorization_delegate,
15973                                   const std::string& response) {
15974   VLOG(1) << __func__;
15975   TPM_RC rc =
15976       Tpm::ParseResponse_SequenceUpdate(response, authorization_delegate);
15977   if (rc != TPM_RC_SUCCESS) {
15978     base::OnceCallback<void(TPM_RC)> error_reporter =
15979         base::BindOnce(SequenceUpdateErrorCallback, std::move(callback));
15980     std::move(error_reporter).Run(rc);
15981     return;
15982   }
15983   std::move(callback).Run(rc);
15984 }
15985 
SequenceUpdate(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate,SequenceUpdateResponse callback)15986 void Tpm::SequenceUpdate(const TPMI_DH_OBJECT& sequence_handle,
15987                          const std::string& sequence_handle_name,
15988                          const TPM2B_MAX_BUFFER& buffer,
15989                          AuthorizationDelegate* authorization_delegate,
15990                          SequenceUpdateResponse callback) {
15991   VLOG(1) << __func__;
15992   std::string command;
15993   TPM_RC rc =
15994       SerializeCommand_SequenceUpdate(sequence_handle, sequence_handle_name,
15995                                       buffer, &command, authorization_delegate);
15996   if (rc != TPM_RC_SUCCESS) {
15997     base::OnceCallback<void(TPM_RC)> error_reporter =
15998         base::BindOnce(SequenceUpdateErrorCallback, std::move(callback));
15999     std::move(error_reporter).Run(rc);
16000     return;
16001   }
16002   base::OnceCallback<void(const std::string&)> parser =
16003       base::BindOnce(SequenceUpdateResponseParser, std::move(callback),
16004                      authorization_delegate);
16005   transceiver_->SendCommand(command, std::move(parser));
16006 }
16007 
SequenceUpdateSync(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate)16008 TPM_RC Tpm::SequenceUpdateSync(const TPMI_DH_OBJECT& sequence_handle,
16009                                const std::string& sequence_handle_name,
16010                                const TPM2B_MAX_BUFFER& buffer,
16011                                AuthorizationDelegate* authorization_delegate) {
16012   VLOG(1) << __func__;
16013   std::string command;
16014   TPM_RC rc =
16015       SerializeCommand_SequenceUpdate(sequence_handle, sequence_handle_name,
16016                                       buffer, &command, authorization_delegate);
16017   if (rc != TPM_RC_SUCCESS) {
16018     return rc;
16019   }
16020   std::string response = transceiver_->SendCommandAndWait(command);
16021   rc = ParseResponse_SequenceUpdate(response, authorization_delegate);
16022   return rc;
16023 }
16024 
SerializeCommand_SequenceComplete(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_RH_HIERARCHY & hierarchy,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16025 TPM_RC Tpm::SerializeCommand_SequenceComplete(
16026     const TPMI_DH_OBJECT& sequence_handle,
16027     const std::string& sequence_handle_name,
16028     const TPM2B_MAX_BUFFER& buffer,
16029     const TPMI_RH_HIERARCHY& hierarchy,
16030     std::string* serialized_command,
16031     AuthorizationDelegate* authorization_delegate) {
16032   VLOG(3) << __func__;
16033   TPM_RC rc = TPM_RC_SUCCESS;
16034   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16035   UINT32 command_size = 10;  // Header size.
16036   std::string handle_section_bytes;
16037   std::string parameter_section_bytes;
16038   TPM_CC command_code = TPM_CC_SequenceComplete;
16039   bool is_command_parameter_encryption_possible = true;
16040   bool is_response_parameter_encryption_possible = true;
16041   std::string command_code_bytes;
16042   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16043   if (rc != TPM_RC_SUCCESS) {
16044     return rc;
16045   }
16046   std::string sequence_handle_bytes;
16047   rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
16048   if (rc != TPM_RC_SUCCESS) {
16049     return rc;
16050   }
16051   std::string buffer_bytes;
16052   rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
16053   if (rc != TPM_RC_SUCCESS) {
16054     return rc;
16055   }
16056   std::string hierarchy_bytes;
16057   rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
16058   if (rc != TPM_RC_SUCCESS) {
16059     return rc;
16060   }
16061   if (authorization_delegate) {
16062     // Encrypt just the parameter data, not the size.
16063     std::string tmp = buffer_bytes.substr(2);
16064     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16065       return TRUNKS_RC_ENCRYPTION_FAILED;
16066     }
16067     buffer_bytes.replace(2, std::string::npos, tmp);
16068   }
16069   std::unique_ptr<crypto::SecureHash> hash(
16070       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16071   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16072   hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
16073   handle_section_bytes += sequence_handle_bytes;
16074   command_size += sequence_handle_bytes.size();
16075   hash->Update(buffer_bytes.data(), buffer_bytes.size());
16076   parameter_section_bytes += buffer_bytes;
16077   command_size += buffer_bytes.size();
16078   hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
16079   parameter_section_bytes += hierarchy_bytes;
16080   command_size += hierarchy_bytes.size();
16081   std::string command_hash(32, 0);
16082   hash->Finish(std::data(command_hash), command_hash.size());
16083   std::string authorization_section_bytes;
16084   std::string authorization_size_bytes;
16085   if (authorization_delegate) {
16086     if (!authorization_delegate->GetCommandAuthorization(
16087             command_hash, is_command_parameter_encryption_possible,
16088             is_response_parameter_encryption_possible,
16089             &authorization_section_bytes)) {
16090       return TRUNKS_RC_AUTHORIZATION_FAILED;
16091     }
16092     if (!authorization_section_bytes.empty()) {
16093       tag = TPM_ST_SESSIONS;
16094       std::string tmp;
16095       rc = Serialize_UINT32(authorization_section_bytes.size(),
16096                             &authorization_size_bytes);
16097       if (rc != TPM_RC_SUCCESS) {
16098         return rc;
16099       }
16100       command_size +=
16101           authorization_size_bytes.size() + authorization_section_bytes.size();
16102     }
16103   }
16104   std::string tag_bytes;
16105   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16106   if (rc != TPM_RC_SUCCESS) {
16107     return rc;
16108   }
16109   std::string command_size_bytes;
16110   rc = Serialize_UINT32(command_size, &command_size_bytes);
16111   if (rc != TPM_RC_SUCCESS) {
16112     return rc;
16113   }
16114   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16115                         handle_section_bytes + authorization_size_bytes +
16116                         authorization_section_bytes + parameter_section_bytes;
16117   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16118   VLOG(2) << "Command: "
16119           << base::HexEncode(serialized_command->data(),
16120                              serialized_command->size());
16121   return TPM_RC_SUCCESS;
16122 }
16123 
ParseResponse_SequenceComplete(const std::string & response,TPM2B_DIGEST * result,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)16124 TPM_RC Tpm::ParseResponse_SequenceComplete(
16125     const std::string& response,
16126     TPM2B_DIGEST* result,
16127     TPMT_TK_HASHCHECK* validation,
16128     AuthorizationDelegate* authorization_delegate) {
16129   VLOG(3) << __func__;
16130   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16131   TPM_RC rc = TPM_RC_SUCCESS;
16132   std::string buffer(response);
16133   TPM_ST tag;
16134   std::string tag_bytes;
16135   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16136   if (rc != TPM_RC_SUCCESS) {
16137     return rc;
16138   }
16139   UINT32 response_size;
16140   std::string response_size_bytes;
16141   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16142   if (rc != TPM_RC_SUCCESS) {
16143     return rc;
16144   }
16145   TPM_RC response_code;
16146   std::string response_code_bytes;
16147   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16148   if (rc != TPM_RC_SUCCESS) {
16149     return rc;
16150   }
16151   if (response_size != response.size()) {
16152     return TPM_RC_SIZE;
16153   }
16154   if (response_code != TPM_RC_SUCCESS) {
16155     return response_code;
16156   }
16157   TPM_CC command_code = TPM_CC_SequenceComplete;
16158   std::string command_code_bytes;
16159   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16160   if (rc != TPM_RC_SUCCESS) {
16161     return rc;
16162   }
16163   std::string authorization_section_bytes;
16164   if (tag == TPM_ST_SESSIONS) {
16165     UINT32 parameter_section_size = buffer.size();
16166     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16167     if (rc != TPM_RC_SUCCESS) {
16168       return rc;
16169     }
16170     if (parameter_section_size > buffer.size()) {
16171       return TPM_RC_INSUFFICIENT;
16172     }
16173     authorization_section_bytes = buffer.substr(parameter_section_size);
16174     // Keep the parameter section in |buffer|.
16175     buffer.erase(parameter_section_size);
16176   }
16177   std::unique_ptr<crypto::SecureHash> hash(
16178       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16179   hash->Update(response_code_bytes.data(), response_code_bytes.size());
16180   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16181   hash->Update(buffer.data(), buffer.size());
16182   std::string response_hash(32, 0);
16183   hash->Finish(std::data(response_hash), response_hash.size());
16184   if (tag == TPM_ST_SESSIONS) {
16185     if (!authorization_delegate)
16186       return TRUNKS_RC_AUTHORIZATION_FAILED;
16187     if (!authorization_delegate->CheckResponseAuthorization(
16188             response_hash, authorization_section_bytes)) {
16189       return TRUNKS_RC_AUTHORIZATION_FAILED;
16190     }
16191   }
16192   if (tag == TPM_ST_SESSIONS) {
16193     if (!authorization_delegate)
16194       return TRUNKS_RC_AUTHORIZATION_FAILED;
16195 
16196     // Parse the encrypted parameter size.
16197     UINT16 size;
16198     std::string size_buffer = buffer.substr(0, 2);
16199     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
16200       return result;
16201     }
16202     if (buffer.size() < 2 + size) {
16203       return TPM_RC_INSUFFICIENT;
16204     }
16205 
16206     // Decrypt just the parameter data, not the size.
16207     std::string decrypted_data = buffer.substr(2, size);
16208     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
16209       return TRUNKS_RC_ENCRYPTION_FAILED;
16210     }
16211     buffer.replace(2, size, decrypted_data);
16212   }
16213   std::string result_bytes;
16214   rc = Parse_TPM2B_DIGEST(&buffer, result, &result_bytes);
16215   if (rc != TPM_RC_SUCCESS) {
16216     return rc;
16217   }
16218   std::string validation_bytes;
16219   rc = Parse_TPMT_TK_HASHCHECK(&buffer, validation, &validation_bytes);
16220   if (rc != TPM_RC_SUCCESS) {
16221     return rc;
16222   }
16223   return TPM_RC_SUCCESS;
16224 }
16225 
SequenceCompleteErrorCallback(Tpm::SequenceCompleteResponse callback,TPM_RC response_code)16226 void SequenceCompleteErrorCallback(Tpm::SequenceCompleteResponse callback,
16227                                    TPM_RC response_code) {
16228   VLOG(1) << __func__;
16229   std::move(callback).Run(response_code, TPM2B_DIGEST(), TPMT_TK_HASHCHECK());
16230 }
16231 
SequenceCompleteResponseParser(Tpm::SequenceCompleteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16232 void SequenceCompleteResponseParser(
16233     Tpm::SequenceCompleteResponse callback,
16234     AuthorizationDelegate* authorization_delegate,
16235     const std::string& response) {
16236   VLOG(1) << __func__;
16237   TPM2B_DIGEST result;
16238   TPMT_TK_HASHCHECK validation;
16239   TPM_RC rc = Tpm::ParseResponse_SequenceComplete(
16240       response, &result, &validation, authorization_delegate);
16241   if (rc != TPM_RC_SUCCESS) {
16242     base::OnceCallback<void(TPM_RC)> error_reporter =
16243         base::BindOnce(SequenceCompleteErrorCallback, std::move(callback));
16244     std::move(error_reporter).Run(rc);
16245     return;
16246   }
16247   std::move(callback).Run(rc, result, validation);
16248 }
16249 
SequenceComplete(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,SequenceCompleteResponse callback)16250 void Tpm::SequenceComplete(const TPMI_DH_OBJECT& sequence_handle,
16251                            const std::string& sequence_handle_name,
16252                            const TPM2B_MAX_BUFFER& buffer,
16253                            const TPMI_RH_HIERARCHY& hierarchy,
16254                            AuthorizationDelegate* authorization_delegate,
16255                            SequenceCompleteResponse callback) {
16256   VLOG(1) << __func__;
16257   std::string command;
16258   TPM_RC rc = SerializeCommand_SequenceComplete(
16259       sequence_handle, sequence_handle_name, buffer, hierarchy, &command,
16260       authorization_delegate);
16261   if (rc != TPM_RC_SUCCESS) {
16262     base::OnceCallback<void(TPM_RC)> error_reporter =
16263         base::BindOnce(SequenceCompleteErrorCallback, std::move(callback));
16264     std::move(error_reporter).Run(rc);
16265     return;
16266   }
16267   base::OnceCallback<void(const std::string&)> parser =
16268       base::BindOnce(SequenceCompleteResponseParser, std::move(callback),
16269                      authorization_delegate);
16270   transceiver_->SendCommand(command, std::move(parser));
16271 }
16272 
SequenceCompleteSync(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_RH_HIERARCHY & hierarchy,TPM2B_DIGEST * result,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)16273 TPM_RC Tpm::SequenceCompleteSync(
16274     const TPMI_DH_OBJECT& sequence_handle,
16275     const std::string& sequence_handle_name,
16276     const TPM2B_MAX_BUFFER& buffer,
16277     const TPMI_RH_HIERARCHY& hierarchy,
16278     TPM2B_DIGEST* result,
16279     TPMT_TK_HASHCHECK* validation,
16280     AuthorizationDelegate* authorization_delegate) {
16281   VLOG(1) << __func__;
16282   std::string command;
16283   TPM_RC rc = SerializeCommand_SequenceComplete(
16284       sequence_handle, sequence_handle_name, buffer, hierarchy, &command,
16285       authorization_delegate);
16286   if (rc != TPM_RC_SUCCESS) {
16287     return rc;
16288   }
16289   std::string response = transceiver_->SendCommandAndWait(command);
16290   rc = ParseResponse_SequenceComplete(response, result, validation,
16291                                       authorization_delegate);
16292   return rc;
16293 }
16294 
SerializeCommand_EventSequenceComplete(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16295 TPM_RC Tpm::SerializeCommand_EventSequenceComplete(
16296     const TPMI_DH_PCR& pcr_handle,
16297     const std::string& pcr_handle_name,
16298     const TPMI_DH_OBJECT& sequence_handle,
16299     const std::string& sequence_handle_name,
16300     const TPM2B_MAX_BUFFER& buffer,
16301     std::string* serialized_command,
16302     AuthorizationDelegate* authorization_delegate) {
16303   VLOG(3) << __func__;
16304   TPM_RC rc = TPM_RC_SUCCESS;
16305   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16306   UINT32 command_size = 10;  // Header size.
16307   std::string handle_section_bytes;
16308   std::string parameter_section_bytes;
16309   TPM_CC command_code = TPM_CC_EventSequenceComplete;
16310   bool is_command_parameter_encryption_possible = true;
16311   bool is_response_parameter_encryption_possible = false;
16312   std::string command_code_bytes;
16313   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16314   if (rc != TPM_RC_SUCCESS) {
16315     return rc;
16316   }
16317   std::string pcr_handle_bytes;
16318   rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
16319   if (rc != TPM_RC_SUCCESS) {
16320     return rc;
16321   }
16322   std::string sequence_handle_bytes;
16323   rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
16324   if (rc != TPM_RC_SUCCESS) {
16325     return rc;
16326   }
16327   std::string buffer_bytes;
16328   rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
16329   if (rc != TPM_RC_SUCCESS) {
16330     return rc;
16331   }
16332   if (authorization_delegate) {
16333     // Encrypt just the parameter data, not the size.
16334     std::string tmp = buffer_bytes.substr(2);
16335     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16336       return TRUNKS_RC_ENCRYPTION_FAILED;
16337     }
16338     buffer_bytes.replace(2, std::string::npos, tmp);
16339   }
16340   std::unique_ptr<crypto::SecureHash> hash(
16341       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16342   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16343   hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
16344   handle_section_bytes += pcr_handle_bytes;
16345   command_size += pcr_handle_bytes.size();
16346   hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
16347   handle_section_bytes += sequence_handle_bytes;
16348   command_size += sequence_handle_bytes.size();
16349   hash->Update(buffer_bytes.data(), buffer_bytes.size());
16350   parameter_section_bytes += buffer_bytes;
16351   command_size += buffer_bytes.size();
16352   std::string command_hash(32, 0);
16353   hash->Finish(std::data(command_hash), command_hash.size());
16354   std::string authorization_section_bytes;
16355   std::string authorization_size_bytes;
16356   if (authorization_delegate) {
16357     if (!authorization_delegate->GetCommandAuthorization(
16358             command_hash, is_command_parameter_encryption_possible,
16359             is_response_parameter_encryption_possible,
16360             &authorization_section_bytes)) {
16361       return TRUNKS_RC_AUTHORIZATION_FAILED;
16362     }
16363     if (!authorization_section_bytes.empty()) {
16364       tag = TPM_ST_SESSIONS;
16365       std::string tmp;
16366       rc = Serialize_UINT32(authorization_section_bytes.size(),
16367                             &authorization_size_bytes);
16368       if (rc != TPM_RC_SUCCESS) {
16369         return rc;
16370       }
16371       command_size +=
16372           authorization_size_bytes.size() + authorization_section_bytes.size();
16373     }
16374   }
16375   std::string tag_bytes;
16376   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16377   if (rc != TPM_RC_SUCCESS) {
16378     return rc;
16379   }
16380   std::string command_size_bytes;
16381   rc = Serialize_UINT32(command_size, &command_size_bytes);
16382   if (rc != TPM_RC_SUCCESS) {
16383     return rc;
16384   }
16385   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16386                         handle_section_bytes + authorization_size_bytes +
16387                         authorization_section_bytes + parameter_section_bytes;
16388   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16389   VLOG(2) << "Command: "
16390           << base::HexEncode(serialized_command->data(),
16391                              serialized_command->size());
16392   return TPM_RC_SUCCESS;
16393 }
16394 
ParseResponse_EventSequenceComplete(const std::string & response,TPML_DIGEST_VALUES * results,AuthorizationDelegate * authorization_delegate)16395 TPM_RC Tpm::ParseResponse_EventSequenceComplete(
16396     const std::string& response,
16397     TPML_DIGEST_VALUES* results,
16398     AuthorizationDelegate* authorization_delegate) {
16399   VLOG(3) << __func__;
16400   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16401   TPM_RC rc = TPM_RC_SUCCESS;
16402   std::string buffer(response);
16403   TPM_ST tag;
16404   std::string tag_bytes;
16405   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16406   if (rc != TPM_RC_SUCCESS) {
16407     return rc;
16408   }
16409   UINT32 response_size;
16410   std::string response_size_bytes;
16411   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16412   if (rc != TPM_RC_SUCCESS) {
16413     return rc;
16414   }
16415   TPM_RC response_code;
16416   std::string response_code_bytes;
16417   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16418   if (rc != TPM_RC_SUCCESS) {
16419     return rc;
16420   }
16421   if (response_size != response.size()) {
16422     return TPM_RC_SIZE;
16423   }
16424   if (response_code != TPM_RC_SUCCESS) {
16425     return response_code;
16426   }
16427   TPM_CC command_code = TPM_CC_EventSequenceComplete;
16428   std::string command_code_bytes;
16429   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16430   if (rc != TPM_RC_SUCCESS) {
16431     return rc;
16432   }
16433   std::string authorization_section_bytes;
16434   if (tag == TPM_ST_SESSIONS) {
16435     UINT32 parameter_section_size = buffer.size();
16436     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16437     if (rc != TPM_RC_SUCCESS) {
16438       return rc;
16439     }
16440     if (parameter_section_size > buffer.size()) {
16441       return TPM_RC_INSUFFICIENT;
16442     }
16443     authorization_section_bytes = buffer.substr(parameter_section_size);
16444     // Keep the parameter section in |buffer|.
16445     buffer.erase(parameter_section_size);
16446   }
16447   std::unique_ptr<crypto::SecureHash> hash(
16448       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16449   hash->Update(response_code_bytes.data(), response_code_bytes.size());
16450   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16451   hash->Update(buffer.data(), buffer.size());
16452   std::string response_hash(32, 0);
16453   hash->Finish(std::data(response_hash), response_hash.size());
16454   if (tag == TPM_ST_SESSIONS) {
16455     if (!authorization_delegate)
16456       return TRUNKS_RC_AUTHORIZATION_FAILED;
16457     if (!authorization_delegate->CheckResponseAuthorization(
16458             response_hash, authorization_section_bytes)) {
16459       return TRUNKS_RC_AUTHORIZATION_FAILED;
16460     }
16461   }
16462   std::string results_bytes;
16463   rc = Parse_TPML_DIGEST_VALUES(&buffer, results, &results_bytes);
16464   if (rc != TPM_RC_SUCCESS) {
16465     return rc;
16466   }
16467   return TPM_RC_SUCCESS;
16468 }
16469 
EventSequenceCompleteErrorCallback(Tpm::EventSequenceCompleteResponse callback,TPM_RC response_code)16470 void EventSequenceCompleteErrorCallback(
16471     Tpm::EventSequenceCompleteResponse callback, TPM_RC response_code) {
16472   VLOG(1) << __func__;
16473   std::move(callback).Run(response_code, TPML_DIGEST_VALUES());
16474 }
16475 
EventSequenceCompleteResponseParser(Tpm::EventSequenceCompleteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16476 void EventSequenceCompleteResponseParser(
16477     Tpm::EventSequenceCompleteResponse callback,
16478     AuthorizationDelegate* authorization_delegate,
16479     const std::string& response) {
16480   VLOG(1) << __func__;
16481   TPML_DIGEST_VALUES results;
16482   TPM_RC rc = Tpm::ParseResponse_EventSequenceComplete(response, &results,
16483                                                        authorization_delegate);
16484   if (rc != TPM_RC_SUCCESS) {
16485     base::OnceCallback<void(TPM_RC)> error_reporter =
16486         base::BindOnce(EventSequenceCompleteErrorCallback, std::move(callback));
16487     std::move(error_reporter).Run(rc);
16488     return;
16489   }
16490   std::move(callback).Run(rc, results);
16491 }
16492 
EventSequenceComplete(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate,EventSequenceCompleteResponse callback)16493 void Tpm::EventSequenceComplete(const TPMI_DH_PCR& pcr_handle,
16494                                 const std::string& pcr_handle_name,
16495                                 const TPMI_DH_OBJECT& sequence_handle,
16496                                 const std::string& sequence_handle_name,
16497                                 const TPM2B_MAX_BUFFER& buffer,
16498                                 AuthorizationDelegate* authorization_delegate,
16499                                 EventSequenceCompleteResponse callback) {
16500   VLOG(1) << __func__;
16501   std::string command;
16502   TPM_RC rc = SerializeCommand_EventSequenceComplete(
16503       pcr_handle, pcr_handle_name, sequence_handle, sequence_handle_name,
16504       buffer, &command, authorization_delegate);
16505   if (rc != TPM_RC_SUCCESS) {
16506     base::OnceCallback<void(TPM_RC)> error_reporter =
16507         base::BindOnce(EventSequenceCompleteErrorCallback, std::move(callback));
16508     std::move(error_reporter).Run(rc);
16509     return;
16510   }
16511   base::OnceCallback<void(const std::string&)> parser =
16512       base::BindOnce(EventSequenceCompleteResponseParser, std::move(callback),
16513                      authorization_delegate);
16514   transceiver_->SendCommand(command, std::move(parser));
16515 }
16516 
EventSequenceCompleteSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,TPML_DIGEST_VALUES * results,AuthorizationDelegate * authorization_delegate)16517 TPM_RC Tpm::EventSequenceCompleteSync(
16518     const TPMI_DH_PCR& pcr_handle,
16519     const std::string& pcr_handle_name,
16520     const TPMI_DH_OBJECT& sequence_handle,
16521     const std::string& sequence_handle_name,
16522     const TPM2B_MAX_BUFFER& buffer,
16523     TPML_DIGEST_VALUES* results,
16524     AuthorizationDelegate* authorization_delegate) {
16525   VLOG(1) << __func__;
16526   std::string command;
16527   TPM_RC rc = SerializeCommand_EventSequenceComplete(
16528       pcr_handle, pcr_handle_name, sequence_handle, sequence_handle_name,
16529       buffer, &command, authorization_delegate);
16530   if (rc != TPM_RC_SUCCESS) {
16531     return rc;
16532   }
16533   std::string response = transceiver_->SendCommandAndWait(command);
16534   rc = ParseResponse_EventSequenceComplete(response, results,
16535                                            authorization_delegate);
16536   return rc;
16537 }
16538 
SerializeCommand_Certify(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16539 TPM_RC Tpm::SerializeCommand_Certify(
16540     const TPMI_DH_OBJECT& object_handle,
16541     const std::string& object_handle_name,
16542     const TPMI_DH_OBJECT& sign_handle,
16543     const std::string& sign_handle_name,
16544     const TPM2B_DATA& qualifying_data,
16545     const TPMT_SIG_SCHEME& in_scheme,
16546     std::string* serialized_command,
16547     AuthorizationDelegate* authorization_delegate) {
16548   VLOG(3) << __func__;
16549   TPM_RC rc = TPM_RC_SUCCESS;
16550   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16551   UINT32 command_size = 10;  // Header size.
16552   std::string handle_section_bytes;
16553   std::string parameter_section_bytes;
16554   TPM_CC command_code = TPM_CC_Certify;
16555   bool is_command_parameter_encryption_possible = true;
16556   bool is_response_parameter_encryption_possible = true;
16557   std::string command_code_bytes;
16558   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16559   if (rc != TPM_RC_SUCCESS) {
16560     return rc;
16561   }
16562   std::string object_handle_bytes;
16563   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
16564   if (rc != TPM_RC_SUCCESS) {
16565     return rc;
16566   }
16567   std::string sign_handle_bytes;
16568   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16569   if (rc != TPM_RC_SUCCESS) {
16570     return rc;
16571   }
16572   std::string qualifying_data_bytes;
16573   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16574   if (rc != TPM_RC_SUCCESS) {
16575     return rc;
16576   }
16577   std::string in_scheme_bytes;
16578   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16579   if (rc != TPM_RC_SUCCESS) {
16580     return rc;
16581   }
16582   if (authorization_delegate) {
16583     // Encrypt just the parameter data, not the size.
16584     std::string tmp = qualifying_data_bytes.substr(2);
16585     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16586       return TRUNKS_RC_ENCRYPTION_FAILED;
16587     }
16588     qualifying_data_bytes.replace(2, std::string::npos, tmp);
16589   }
16590   std::unique_ptr<crypto::SecureHash> hash(
16591       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16592   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16593   hash->Update(object_handle_name.data(), object_handle_name.size());
16594   handle_section_bytes += object_handle_bytes;
16595   command_size += object_handle_bytes.size();
16596   hash->Update(sign_handle_name.data(), sign_handle_name.size());
16597   handle_section_bytes += sign_handle_bytes;
16598   command_size += sign_handle_bytes.size();
16599   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16600   parameter_section_bytes += qualifying_data_bytes;
16601   command_size += qualifying_data_bytes.size();
16602   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16603   parameter_section_bytes += in_scheme_bytes;
16604   command_size += in_scheme_bytes.size();
16605   std::string command_hash(32, 0);
16606   hash->Finish(std::data(command_hash), command_hash.size());
16607   std::string authorization_section_bytes;
16608   std::string authorization_size_bytes;
16609   if (authorization_delegate) {
16610     if (!authorization_delegate->GetCommandAuthorization(
16611             command_hash, is_command_parameter_encryption_possible,
16612             is_response_parameter_encryption_possible,
16613             &authorization_section_bytes)) {
16614       return TRUNKS_RC_AUTHORIZATION_FAILED;
16615     }
16616     if (!authorization_section_bytes.empty()) {
16617       tag = TPM_ST_SESSIONS;
16618       std::string tmp;
16619       rc = Serialize_UINT32(authorization_section_bytes.size(),
16620                             &authorization_size_bytes);
16621       if (rc != TPM_RC_SUCCESS) {
16622         return rc;
16623       }
16624       command_size +=
16625           authorization_size_bytes.size() + authorization_section_bytes.size();
16626     }
16627   }
16628   std::string tag_bytes;
16629   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16630   if (rc != TPM_RC_SUCCESS) {
16631     return rc;
16632   }
16633   std::string command_size_bytes;
16634   rc = Serialize_UINT32(command_size, &command_size_bytes);
16635   if (rc != TPM_RC_SUCCESS) {
16636     return rc;
16637   }
16638   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16639                         handle_section_bytes + authorization_size_bytes +
16640                         authorization_section_bytes + parameter_section_bytes;
16641   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16642   VLOG(2) << "Command: "
16643           << base::HexEncode(serialized_command->data(),
16644                              serialized_command->size());
16645   return TPM_RC_SUCCESS;
16646 }
16647 
ParseResponse_Certify(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16648 TPM_RC Tpm::ParseResponse_Certify(
16649     const std::string& response,
16650     TPM2B_ATTEST* certify_info,
16651     TPMT_SIGNATURE* signature,
16652     AuthorizationDelegate* authorization_delegate) {
16653   VLOG(3) << __func__;
16654   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16655   TPM_RC rc = TPM_RC_SUCCESS;
16656   std::string buffer(response);
16657   TPM_ST tag;
16658   std::string tag_bytes;
16659   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16660   if (rc != TPM_RC_SUCCESS) {
16661     return rc;
16662   }
16663   UINT32 response_size;
16664   std::string response_size_bytes;
16665   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16666   if (rc != TPM_RC_SUCCESS) {
16667     return rc;
16668   }
16669   TPM_RC response_code;
16670   std::string response_code_bytes;
16671   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16672   if (rc != TPM_RC_SUCCESS) {
16673     return rc;
16674   }
16675   if (response_size != response.size()) {
16676     return TPM_RC_SIZE;
16677   }
16678   if (response_code != TPM_RC_SUCCESS) {
16679     return response_code;
16680   }
16681   TPM_CC command_code = TPM_CC_Certify;
16682   std::string command_code_bytes;
16683   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16684   if (rc != TPM_RC_SUCCESS) {
16685     return rc;
16686   }
16687   std::string authorization_section_bytes;
16688   if (tag == TPM_ST_SESSIONS) {
16689     UINT32 parameter_section_size = buffer.size();
16690     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16691     if (rc != TPM_RC_SUCCESS) {
16692       return rc;
16693     }
16694     if (parameter_section_size > buffer.size()) {
16695       return TPM_RC_INSUFFICIENT;
16696     }
16697     authorization_section_bytes = buffer.substr(parameter_section_size);
16698     // Keep the parameter section in |buffer|.
16699     buffer.erase(parameter_section_size);
16700   }
16701   std::unique_ptr<crypto::SecureHash> hash(
16702       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16703   hash->Update(response_code_bytes.data(), response_code_bytes.size());
16704   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16705   hash->Update(buffer.data(), buffer.size());
16706   std::string response_hash(32, 0);
16707   hash->Finish(std::data(response_hash), response_hash.size());
16708   if (tag == TPM_ST_SESSIONS) {
16709     if (!authorization_delegate)
16710       return TRUNKS_RC_AUTHORIZATION_FAILED;
16711     if (!authorization_delegate->CheckResponseAuthorization(
16712             response_hash, authorization_section_bytes)) {
16713       return TRUNKS_RC_AUTHORIZATION_FAILED;
16714     }
16715   }
16716   if (tag == TPM_ST_SESSIONS) {
16717     if (!authorization_delegate)
16718       return TRUNKS_RC_AUTHORIZATION_FAILED;
16719 
16720     // Parse the encrypted parameter size.
16721     UINT16 size;
16722     std::string size_buffer = buffer.substr(0, 2);
16723     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
16724       return result;
16725     }
16726     if (buffer.size() < 2 + size) {
16727       return TPM_RC_INSUFFICIENT;
16728     }
16729 
16730     // Decrypt just the parameter data, not the size.
16731     std::string decrypted_data = buffer.substr(2, size);
16732     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
16733       return TRUNKS_RC_ENCRYPTION_FAILED;
16734     }
16735     buffer.replace(2, size, decrypted_data);
16736   }
16737   std::string certify_info_bytes;
16738   rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
16739   if (rc != TPM_RC_SUCCESS) {
16740     return rc;
16741   }
16742   std::string signature_bytes;
16743   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
16744   if (rc != TPM_RC_SUCCESS) {
16745     return rc;
16746   }
16747   return TPM_RC_SUCCESS;
16748 }
16749 
CertifyErrorCallback(Tpm::CertifyResponse callback,TPM_RC response_code)16750 void CertifyErrorCallback(Tpm::CertifyResponse callback, TPM_RC response_code) {
16751   VLOG(1) << __func__;
16752   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
16753 }
16754 
CertifyResponseParser(Tpm::CertifyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16755 void CertifyResponseParser(Tpm::CertifyResponse callback,
16756                            AuthorizationDelegate* authorization_delegate,
16757                            const std::string& response) {
16758   VLOG(1) << __func__;
16759   TPM2B_ATTEST certify_info;
16760   TPMT_SIGNATURE signature;
16761   TPM_RC rc = Tpm::ParseResponse_Certify(response, &certify_info, &signature,
16762                                          authorization_delegate);
16763   if (rc != TPM_RC_SUCCESS) {
16764     base::OnceCallback<void(TPM_RC)> error_reporter =
16765         base::BindOnce(CertifyErrorCallback, std::move(callback));
16766     std::move(error_reporter).Run(rc);
16767     return;
16768   }
16769   std::move(callback).Run(rc, certify_info, signature);
16770 }
16771 
Certify(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,CertifyResponse callback)16772 void Tpm::Certify(const TPMI_DH_OBJECT& object_handle,
16773                   const std::string& object_handle_name,
16774                   const TPMI_DH_OBJECT& sign_handle,
16775                   const std::string& sign_handle_name,
16776                   const TPM2B_DATA& qualifying_data,
16777                   const TPMT_SIG_SCHEME& in_scheme,
16778                   AuthorizationDelegate* authorization_delegate,
16779                   CertifyResponse callback) {
16780   VLOG(1) << __func__;
16781   std::string command;
16782   TPM_RC rc = SerializeCommand_Certify(
16783       object_handle, object_handle_name, sign_handle, sign_handle_name,
16784       qualifying_data, in_scheme, &command, authorization_delegate);
16785   if (rc != TPM_RC_SUCCESS) {
16786     base::OnceCallback<void(TPM_RC)> error_reporter =
16787         base::BindOnce(CertifyErrorCallback, std::move(callback));
16788     std::move(error_reporter).Run(rc);
16789     return;
16790   }
16791   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
16792       CertifyResponseParser, std::move(callback), authorization_delegate);
16793   transceiver_->SendCommand(command, std::move(parser));
16794 }
16795 
CertifySync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16796 TPM_RC Tpm::CertifySync(const TPMI_DH_OBJECT& object_handle,
16797                         const std::string& object_handle_name,
16798                         const TPMI_DH_OBJECT& sign_handle,
16799                         const std::string& sign_handle_name,
16800                         const TPM2B_DATA& qualifying_data,
16801                         const TPMT_SIG_SCHEME& in_scheme,
16802                         TPM2B_ATTEST* certify_info,
16803                         TPMT_SIGNATURE* signature,
16804                         AuthorizationDelegate* authorization_delegate) {
16805   VLOG(1) << __func__;
16806   std::string command;
16807   TPM_RC rc = SerializeCommand_Certify(
16808       object_handle, object_handle_name, sign_handle, sign_handle_name,
16809       qualifying_data, in_scheme, &command, authorization_delegate);
16810   if (rc != TPM_RC_SUCCESS) {
16811     return rc;
16812   }
16813   std::string response = transceiver_->SendCommandAndWait(command);
16814   rc = ParseResponse_Certify(response, certify_info, signature,
16815                              authorization_delegate);
16816   return rc;
16817 }
16818 
SerializeCommand_CertifyCreation(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPM2B_DATA & qualifying_data,const TPM2B_DIGEST & creation_hash,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_CREATION & creation_ticket,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16819 TPM_RC Tpm::SerializeCommand_CertifyCreation(
16820     const TPMI_DH_OBJECT& sign_handle,
16821     const std::string& sign_handle_name,
16822     const TPMI_DH_OBJECT& object_handle,
16823     const std::string& object_handle_name,
16824     const TPM2B_DATA& qualifying_data,
16825     const TPM2B_DIGEST& creation_hash,
16826     const TPMT_SIG_SCHEME& in_scheme,
16827     const TPMT_TK_CREATION& creation_ticket,
16828     std::string* serialized_command,
16829     AuthorizationDelegate* authorization_delegate) {
16830   VLOG(3) << __func__;
16831   TPM_RC rc = TPM_RC_SUCCESS;
16832   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16833   UINT32 command_size = 10;  // Header size.
16834   std::string handle_section_bytes;
16835   std::string parameter_section_bytes;
16836   TPM_CC command_code = TPM_CC_CertifyCreation;
16837   bool is_command_parameter_encryption_possible = true;
16838   bool is_response_parameter_encryption_possible = true;
16839   std::string command_code_bytes;
16840   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16841   if (rc != TPM_RC_SUCCESS) {
16842     return rc;
16843   }
16844   std::string sign_handle_bytes;
16845   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16846   if (rc != TPM_RC_SUCCESS) {
16847     return rc;
16848   }
16849   std::string object_handle_bytes;
16850   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
16851   if (rc != TPM_RC_SUCCESS) {
16852     return rc;
16853   }
16854   std::string qualifying_data_bytes;
16855   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16856   if (rc != TPM_RC_SUCCESS) {
16857     return rc;
16858   }
16859   std::string creation_hash_bytes;
16860   rc = Serialize_TPM2B_DIGEST(creation_hash, &creation_hash_bytes);
16861   if (rc != TPM_RC_SUCCESS) {
16862     return rc;
16863   }
16864   std::string in_scheme_bytes;
16865   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16866   if (rc != TPM_RC_SUCCESS) {
16867     return rc;
16868   }
16869   std::string creation_ticket_bytes;
16870   rc = Serialize_TPMT_TK_CREATION(creation_ticket, &creation_ticket_bytes);
16871   if (rc != TPM_RC_SUCCESS) {
16872     return rc;
16873   }
16874   if (authorization_delegate) {
16875     // Encrypt just the parameter data, not the size.
16876     std::string tmp = qualifying_data_bytes.substr(2);
16877     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16878       return TRUNKS_RC_ENCRYPTION_FAILED;
16879     }
16880     qualifying_data_bytes.replace(2, std::string::npos, tmp);
16881   }
16882   std::unique_ptr<crypto::SecureHash> hash(
16883       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16884   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16885   hash->Update(sign_handle_name.data(), sign_handle_name.size());
16886   handle_section_bytes += sign_handle_bytes;
16887   command_size += sign_handle_bytes.size();
16888   hash->Update(object_handle_name.data(), object_handle_name.size());
16889   handle_section_bytes += object_handle_bytes;
16890   command_size += object_handle_bytes.size();
16891   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16892   parameter_section_bytes += qualifying_data_bytes;
16893   command_size += qualifying_data_bytes.size();
16894   hash->Update(creation_hash_bytes.data(), creation_hash_bytes.size());
16895   parameter_section_bytes += creation_hash_bytes;
16896   command_size += creation_hash_bytes.size();
16897   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16898   parameter_section_bytes += in_scheme_bytes;
16899   command_size += in_scheme_bytes.size();
16900   hash->Update(creation_ticket_bytes.data(), creation_ticket_bytes.size());
16901   parameter_section_bytes += creation_ticket_bytes;
16902   command_size += creation_ticket_bytes.size();
16903   std::string command_hash(32, 0);
16904   hash->Finish(std::data(command_hash), command_hash.size());
16905   std::string authorization_section_bytes;
16906   std::string authorization_size_bytes;
16907   if (authorization_delegate) {
16908     if (!authorization_delegate->GetCommandAuthorization(
16909             command_hash, is_command_parameter_encryption_possible,
16910             is_response_parameter_encryption_possible,
16911             &authorization_section_bytes)) {
16912       return TRUNKS_RC_AUTHORIZATION_FAILED;
16913     }
16914     if (!authorization_section_bytes.empty()) {
16915       tag = TPM_ST_SESSIONS;
16916       std::string tmp;
16917       rc = Serialize_UINT32(authorization_section_bytes.size(),
16918                             &authorization_size_bytes);
16919       if (rc != TPM_RC_SUCCESS) {
16920         return rc;
16921       }
16922       command_size +=
16923           authorization_size_bytes.size() + authorization_section_bytes.size();
16924     }
16925   }
16926   std::string tag_bytes;
16927   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16928   if (rc != TPM_RC_SUCCESS) {
16929     return rc;
16930   }
16931   std::string command_size_bytes;
16932   rc = Serialize_UINT32(command_size, &command_size_bytes);
16933   if (rc != TPM_RC_SUCCESS) {
16934     return rc;
16935   }
16936   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16937                         handle_section_bytes + authorization_size_bytes +
16938                         authorization_section_bytes + parameter_section_bytes;
16939   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16940   VLOG(2) << "Command: "
16941           << base::HexEncode(serialized_command->data(),
16942                              serialized_command->size());
16943   return TPM_RC_SUCCESS;
16944 }
16945 
ParseResponse_CertifyCreation(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16946 TPM_RC Tpm::ParseResponse_CertifyCreation(
16947     const std::string& response,
16948     TPM2B_ATTEST* certify_info,
16949     TPMT_SIGNATURE* signature,
16950     AuthorizationDelegate* authorization_delegate) {
16951   VLOG(3) << __func__;
16952   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16953   TPM_RC rc = TPM_RC_SUCCESS;
16954   std::string buffer(response);
16955   TPM_ST tag;
16956   std::string tag_bytes;
16957   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16958   if (rc != TPM_RC_SUCCESS) {
16959     return rc;
16960   }
16961   UINT32 response_size;
16962   std::string response_size_bytes;
16963   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16964   if (rc != TPM_RC_SUCCESS) {
16965     return rc;
16966   }
16967   TPM_RC response_code;
16968   std::string response_code_bytes;
16969   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16970   if (rc != TPM_RC_SUCCESS) {
16971     return rc;
16972   }
16973   if (response_size != response.size()) {
16974     return TPM_RC_SIZE;
16975   }
16976   if (response_code != TPM_RC_SUCCESS) {
16977     return response_code;
16978   }
16979   TPM_CC command_code = TPM_CC_CertifyCreation;
16980   std::string command_code_bytes;
16981   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16982   if (rc != TPM_RC_SUCCESS) {
16983     return rc;
16984   }
16985   std::string authorization_section_bytes;
16986   if (tag == TPM_ST_SESSIONS) {
16987     UINT32 parameter_section_size = buffer.size();
16988     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16989     if (rc != TPM_RC_SUCCESS) {
16990       return rc;
16991     }
16992     if (parameter_section_size > buffer.size()) {
16993       return TPM_RC_INSUFFICIENT;
16994     }
16995     authorization_section_bytes = buffer.substr(parameter_section_size);
16996     // Keep the parameter section in |buffer|.
16997     buffer.erase(parameter_section_size);
16998   }
16999   std::unique_ptr<crypto::SecureHash> hash(
17000       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17001   hash->Update(response_code_bytes.data(), response_code_bytes.size());
17002   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17003   hash->Update(buffer.data(), buffer.size());
17004   std::string response_hash(32, 0);
17005   hash->Finish(std::data(response_hash), response_hash.size());
17006   if (tag == TPM_ST_SESSIONS) {
17007     if (!authorization_delegate)
17008       return TRUNKS_RC_AUTHORIZATION_FAILED;
17009     if (!authorization_delegate->CheckResponseAuthorization(
17010             response_hash, authorization_section_bytes)) {
17011       return TRUNKS_RC_AUTHORIZATION_FAILED;
17012     }
17013   }
17014   if (tag == TPM_ST_SESSIONS) {
17015     if (!authorization_delegate)
17016       return TRUNKS_RC_AUTHORIZATION_FAILED;
17017 
17018     // Parse the encrypted parameter size.
17019     UINT16 size;
17020     std::string size_buffer = buffer.substr(0, 2);
17021     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17022       return result;
17023     }
17024     if (buffer.size() < 2 + size) {
17025       return TPM_RC_INSUFFICIENT;
17026     }
17027 
17028     // Decrypt just the parameter data, not the size.
17029     std::string decrypted_data = buffer.substr(2, size);
17030     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17031       return TRUNKS_RC_ENCRYPTION_FAILED;
17032     }
17033     buffer.replace(2, size, decrypted_data);
17034   }
17035   std::string certify_info_bytes;
17036   rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
17037   if (rc != TPM_RC_SUCCESS) {
17038     return rc;
17039   }
17040   std::string signature_bytes;
17041   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17042   if (rc != TPM_RC_SUCCESS) {
17043     return rc;
17044   }
17045   return TPM_RC_SUCCESS;
17046 }
17047 
CertifyCreationErrorCallback(Tpm::CertifyCreationResponse callback,TPM_RC response_code)17048 void CertifyCreationErrorCallback(Tpm::CertifyCreationResponse callback,
17049                                   TPM_RC response_code) {
17050   VLOG(1) << __func__;
17051   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17052 }
17053 
CertifyCreationResponseParser(Tpm::CertifyCreationResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17054 void CertifyCreationResponseParser(
17055     Tpm::CertifyCreationResponse callback,
17056     AuthorizationDelegate* authorization_delegate,
17057     const std::string& response) {
17058   VLOG(1) << __func__;
17059   TPM2B_ATTEST certify_info;
17060   TPMT_SIGNATURE signature;
17061   TPM_RC rc = Tpm::ParseResponse_CertifyCreation(
17062       response, &certify_info, &signature, authorization_delegate);
17063   if (rc != TPM_RC_SUCCESS) {
17064     base::OnceCallback<void(TPM_RC)> error_reporter =
17065         base::BindOnce(CertifyCreationErrorCallback, std::move(callback));
17066     std::move(error_reporter).Run(rc);
17067     return;
17068   }
17069   std::move(callback).Run(rc, certify_info, signature);
17070 }
17071 
CertifyCreation(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPM2B_DATA & qualifying_data,const TPM2B_DIGEST & creation_hash,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_CREATION & creation_ticket,AuthorizationDelegate * authorization_delegate,CertifyCreationResponse callback)17072 void Tpm::CertifyCreation(const TPMI_DH_OBJECT& sign_handle,
17073                           const std::string& sign_handle_name,
17074                           const TPMI_DH_OBJECT& object_handle,
17075                           const std::string& object_handle_name,
17076                           const TPM2B_DATA& qualifying_data,
17077                           const TPM2B_DIGEST& creation_hash,
17078                           const TPMT_SIG_SCHEME& in_scheme,
17079                           const TPMT_TK_CREATION& creation_ticket,
17080                           AuthorizationDelegate* authorization_delegate,
17081                           CertifyCreationResponse callback) {
17082   VLOG(1) << __func__;
17083   std::string command;
17084   TPM_RC rc = SerializeCommand_CertifyCreation(
17085       sign_handle, sign_handle_name, object_handle, object_handle_name,
17086       qualifying_data, creation_hash, in_scheme, creation_ticket, &command,
17087       authorization_delegate);
17088   if (rc != TPM_RC_SUCCESS) {
17089     base::OnceCallback<void(TPM_RC)> error_reporter =
17090         base::BindOnce(CertifyCreationErrorCallback, std::move(callback));
17091     std::move(error_reporter).Run(rc);
17092     return;
17093   }
17094   base::OnceCallback<void(const std::string&)> parser =
17095       base::BindOnce(CertifyCreationResponseParser, std::move(callback),
17096                      authorization_delegate);
17097   transceiver_->SendCommand(command, std::move(parser));
17098 }
17099 
CertifyCreationSync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPM2B_DATA & qualifying_data,const TPM2B_DIGEST & creation_hash,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_CREATION & creation_ticket,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17100 TPM_RC Tpm::CertifyCreationSync(const TPMI_DH_OBJECT& sign_handle,
17101                                 const std::string& sign_handle_name,
17102                                 const TPMI_DH_OBJECT& object_handle,
17103                                 const std::string& object_handle_name,
17104                                 const TPM2B_DATA& qualifying_data,
17105                                 const TPM2B_DIGEST& creation_hash,
17106                                 const TPMT_SIG_SCHEME& in_scheme,
17107                                 const TPMT_TK_CREATION& creation_ticket,
17108                                 TPM2B_ATTEST* certify_info,
17109                                 TPMT_SIGNATURE* signature,
17110                                 AuthorizationDelegate* authorization_delegate) {
17111   VLOG(1) << __func__;
17112   std::string command;
17113   TPM_RC rc = SerializeCommand_CertifyCreation(
17114       sign_handle, sign_handle_name, object_handle, object_handle_name,
17115       qualifying_data, creation_hash, in_scheme, creation_ticket, &command,
17116       authorization_delegate);
17117   if (rc != TPM_RC_SUCCESS) {
17118     return rc;
17119   }
17120   std::string response = transceiver_->SendCommandAndWait(command);
17121   rc = ParseResponse_CertifyCreation(response, certify_info, signature,
17122                                      authorization_delegate);
17123   return rc;
17124 }
17125 
SerializeCommand_Quote(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const TPML_PCR_SELECTION & pcrselect,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17126 TPM_RC Tpm::SerializeCommand_Quote(
17127     const TPMI_DH_OBJECT& sign_handle,
17128     const std::string& sign_handle_name,
17129     const TPM2B_DATA& qualifying_data,
17130     const TPMT_SIG_SCHEME& in_scheme,
17131     const TPML_PCR_SELECTION& pcrselect,
17132     std::string* serialized_command,
17133     AuthorizationDelegate* authorization_delegate) {
17134   VLOG(3) << __func__;
17135   TPM_RC rc = TPM_RC_SUCCESS;
17136   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17137   UINT32 command_size = 10;  // Header size.
17138   std::string handle_section_bytes;
17139   std::string parameter_section_bytes;
17140   TPM_CC command_code = TPM_CC_Quote;
17141   bool is_command_parameter_encryption_possible = true;
17142   bool is_response_parameter_encryption_possible = true;
17143   std::string command_code_bytes;
17144   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17145   if (rc != TPM_RC_SUCCESS) {
17146     return rc;
17147   }
17148   std::string sign_handle_bytes;
17149   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17150   if (rc != TPM_RC_SUCCESS) {
17151     return rc;
17152   }
17153   std::string qualifying_data_bytes;
17154   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17155   if (rc != TPM_RC_SUCCESS) {
17156     return rc;
17157   }
17158   std::string in_scheme_bytes;
17159   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17160   if (rc != TPM_RC_SUCCESS) {
17161     return rc;
17162   }
17163   std::string pcrselect_bytes;
17164   rc = Serialize_TPML_PCR_SELECTION(pcrselect, &pcrselect_bytes);
17165   if (rc != TPM_RC_SUCCESS) {
17166     return rc;
17167   }
17168   if (authorization_delegate) {
17169     // Encrypt just the parameter data, not the size.
17170     std::string tmp = qualifying_data_bytes.substr(2);
17171     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17172       return TRUNKS_RC_ENCRYPTION_FAILED;
17173     }
17174     qualifying_data_bytes.replace(2, std::string::npos, tmp);
17175   }
17176   std::unique_ptr<crypto::SecureHash> hash(
17177       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17178   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17179   hash->Update(sign_handle_name.data(), sign_handle_name.size());
17180   handle_section_bytes += sign_handle_bytes;
17181   command_size += sign_handle_bytes.size();
17182   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17183   parameter_section_bytes += qualifying_data_bytes;
17184   command_size += qualifying_data_bytes.size();
17185   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17186   parameter_section_bytes += in_scheme_bytes;
17187   command_size += in_scheme_bytes.size();
17188   hash->Update(pcrselect_bytes.data(), pcrselect_bytes.size());
17189   parameter_section_bytes += pcrselect_bytes;
17190   command_size += pcrselect_bytes.size();
17191   std::string command_hash(32, 0);
17192   hash->Finish(std::data(command_hash), command_hash.size());
17193   std::string authorization_section_bytes;
17194   std::string authorization_size_bytes;
17195   if (authorization_delegate) {
17196     if (!authorization_delegate->GetCommandAuthorization(
17197             command_hash, is_command_parameter_encryption_possible,
17198             is_response_parameter_encryption_possible,
17199             &authorization_section_bytes)) {
17200       return TRUNKS_RC_AUTHORIZATION_FAILED;
17201     }
17202     if (!authorization_section_bytes.empty()) {
17203       tag = TPM_ST_SESSIONS;
17204       std::string tmp;
17205       rc = Serialize_UINT32(authorization_section_bytes.size(),
17206                             &authorization_size_bytes);
17207       if (rc != TPM_RC_SUCCESS) {
17208         return rc;
17209       }
17210       command_size +=
17211           authorization_size_bytes.size() + authorization_section_bytes.size();
17212     }
17213   }
17214   std::string tag_bytes;
17215   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17216   if (rc != TPM_RC_SUCCESS) {
17217     return rc;
17218   }
17219   std::string command_size_bytes;
17220   rc = Serialize_UINT32(command_size, &command_size_bytes);
17221   if (rc != TPM_RC_SUCCESS) {
17222     return rc;
17223   }
17224   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17225                         handle_section_bytes + authorization_size_bytes +
17226                         authorization_section_bytes + parameter_section_bytes;
17227   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17228   VLOG(2) << "Command: "
17229           << base::HexEncode(serialized_command->data(),
17230                              serialized_command->size());
17231   return TPM_RC_SUCCESS;
17232 }
17233 
ParseResponse_Quote(const std::string & response,TPM2B_ATTEST * quoted,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17234 TPM_RC Tpm::ParseResponse_Quote(const std::string& response,
17235                                 TPM2B_ATTEST* quoted,
17236                                 TPMT_SIGNATURE* signature,
17237                                 AuthorizationDelegate* authorization_delegate) {
17238   VLOG(3) << __func__;
17239   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17240   TPM_RC rc = TPM_RC_SUCCESS;
17241   std::string buffer(response);
17242   TPM_ST tag;
17243   std::string tag_bytes;
17244   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17245   if (rc != TPM_RC_SUCCESS) {
17246     return rc;
17247   }
17248   UINT32 response_size;
17249   std::string response_size_bytes;
17250   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17251   if (rc != TPM_RC_SUCCESS) {
17252     return rc;
17253   }
17254   TPM_RC response_code;
17255   std::string response_code_bytes;
17256   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17257   if (rc != TPM_RC_SUCCESS) {
17258     return rc;
17259   }
17260   if (response_size != response.size()) {
17261     return TPM_RC_SIZE;
17262   }
17263   if (response_code != TPM_RC_SUCCESS) {
17264     return response_code;
17265   }
17266   TPM_CC command_code = TPM_CC_Quote;
17267   std::string command_code_bytes;
17268   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17269   if (rc != TPM_RC_SUCCESS) {
17270     return rc;
17271   }
17272   std::string authorization_section_bytes;
17273   if (tag == TPM_ST_SESSIONS) {
17274     UINT32 parameter_section_size = buffer.size();
17275     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
17276     if (rc != TPM_RC_SUCCESS) {
17277       return rc;
17278     }
17279     if (parameter_section_size > buffer.size()) {
17280       return TPM_RC_INSUFFICIENT;
17281     }
17282     authorization_section_bytes = buffer.substr(parameter_section_size);
17283     // Keep the parameter section in |buffer|.
17284     buffer.erase(parameter_section_size);
17285   }
17286   std::unique_ptr<crypto::SecureHash> hash(
17287       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17288   hash->Update(response_code_bytes.data(), response_code_bytes.size());
17289   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17290   hash->Update(buffer.data(), buffer.size());
17291   std::string response_hash(32, 0);
17292   hash->Finish(std::data(response_hash), response_hash.size());
17293   if (tag == TPM_ST_SESSIONS) {
17294     if (!authorization_delegate)
17295       return TRUNKS_RC_AUTHORIZATION_FAILED;
17296     if (!authorization_delegate->CheckResponseAuthorization(
17297             response_hash, authorization_section_bytes)) {
17298       return TRUNKS_RC_AUTHORIZATION_FAILED;
17299     }
17300   }
17301   if (tag == TPM_ST_SESSIONS) {
17302     if (!authorization_delegate)
17303       return TRUNKS_RC_AUTHORIZATION_FAILED;
17304 
17305     // Parse the encrypted parameter size.
17306     UINT16 size;
17307     std::string size_buffer = buffer.substr(0, 2);
17308     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17309       return result;
17310     }
17311     if (buffer.size() < 2 + size) {
17312       return TPM_RC_INSUFFICIENT;
17313     }
17314 
17315     // Decrypt just the parameter data, not the size.
17316     std::string decrypted_data = buffer.substr(2, size);
17317     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17318       return TRUNKS_RC_ENCRYPTION_FAILED;
17319     }
17320     buffer.replace(2, size, decrypted_data);
17321   }
17322   std::string quoted_bytes;
17323   rc = Parse_TPM2B_ATTEST(&buffer, quoted, &quoted_bytes);
17324   if (rc != TPM_RC_SUCCESS) {
17325     return rc;
17326   }
17327   std::string signature_bytes;
17328   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17329   if (rc != TPM_RC_SUCCESS) {
17330     return rc;
17331   }
17332   return TPM_RC_SUCCESS;
17333 }
17334 
QuoteErrorCallback(Tpm::QuoteResponse callback,TPM_RC response_code)17335 void QuoteErrorCallback(Tpm::QuoteResponse callback, TPM_RC response_code) {
17336   VLOG(1) << __func__;
17337   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17338 }
17339 
QuoteResponseParser(Tpm::QuoteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17340 void QuoteResponseParser(Tpm::QuoteResponse callback,
17341                          AuthorizationDelegate* authorization_delegate,
17342                          const std::string& response) {
17343   VLOG(1) << __func__;
17344   TPM2B_ATTEST quoted;
17345   TPMT_SIGNATURE signature;
17346   TPM_RC rc = Tpm::ParseResponse_Quote(response, &quoted, &signature,
17347                                        authorization_delegate);
17348   if (rc != TPM_RC_SUCCESS) {
17349     base::OnceCallback<void(TPM_RC)> error_reporter =
17350         base::BindOnce(QuoteErrorCallback, std::move(callback));
17351     std::move(error_reporter).Run(rc);
17352     return;
17353   }
17354   std::move(callback).Run(rc, quoted, signature);
17355 }
17356 
Quote(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const TPML_PCR_SELECTION & pcrselect,AuthorizationDelegate * authorization_delegate,QuoteResponse callback)17357 void Tpm::Quote(const TPMI_DH_OBJECT& sign_handle,
17358                 const std::string& sign_handle_name,
17359                 const TPM2B_DATA& qualifying_data,
17360                 const TPMT_SIG_SCHEME& in_scheme,
17361                 const TPML_PCR_SELECTION& pcrselect,
17362                 AuthorizationDelegate* authorization_delegate,
17363                 QuoteResponse callback) {
17364   VLOG(1) << __func__;
17365   std::string command;
17366   TPM_RC rc = SerializeCommand_Quote(sign_handle, sign_handle_name,
17367                                      qualifying_data, in_scheme, pcrselect,
17368                                      &command, authorization_delegate);
17369   if (rc != TPM_RC_SUCCESS) {
17370     base::OnceCallback<void(TPM_RC)> error_reporter =
17371         base::BindOnce(QuoteErrorCallback, std::move(callback));
17372     std::move(error_reporter).Run(rc);
17373     return;
17374   }
17375   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
17376       QuoteResponseParser, std::move(callback), authorization_delegate);
17377   transceiver_->SendCommand(command, std::move(parser));
17378 }
17379 
QuoteSync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const TPML_PCR_SELECTION & pcrselect,TPM2B_ATTEST * quoted,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17380 TPM_RC Tpm::QuoteSync(const TPMI_DH_OBJECT& sign_handle,
17381                       const std::string& sign_handle_name,
17382                       const TPM2B_DATA& qualifying_data,
17383                       const TPMT_SIG_SCHEME& in_scheme,
17384                       const TPML_PCR_SELECTION& pcrselect,
17385                       TPM2B_ATTEST* quoted,
17386                       TPMT_SIGNATURE* signature,
17387                       AuthorizationDelegate* authorization_delegate) {
17388   VLOG(1) << __func__;
17389   std::string command;
17390   TPM_RC rc = SerializeCommand_Quote(sign_handle, sign_handle_name,
17391                                      qualifying_data, in_scheme, pcrselect,
17392                                      &command, authorization_delegate);
17393   if (rc != TPM_RC_SUCCESS) {
17394     return rc;
17395   }
17396   std::string response = transceiver_->SendCommandAndWait(command);
17397   rc = ParseResponse_Quote(response, quoted, signature, authorization_delegate);
17398   return rc;
17399 }
17400 
SerializeCommand_GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_SH_HMAC & session_handle,const std::string & session_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17401 TPM_RC Tpm::SerializeCommand_GetSessionAuditDigest(
17402     const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17403     const std::string& privacy_admin_handle_name,
17404     const TPMI_DH_OBJECT& sign_handle,
17405     const std::string& sign_handle_name,
17406     const TPMI_SH_HMAC& session_handle,
17407     const std::string& session_handle_name,
17408     const TPM2B_DATA& qualifying_data,
17409     const TPMT_SIG_SCHEME& in_scheme,
17410     std::string* serialized_command,
17411     AuthorizationDelegate* authorization_delegate) {
17412   VLOG(3) << __func__;
17413   TPM_RC rc = TPM_RC_SUCCESS;
17414   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17415   UINT32 command_size = 10;  // Header size.
17416   std::string handle_section_bytes;
17417   std::string parameter_section_bytes;
17418   TPM_CC command_code = TPM_CC_GetSessionAuditDigest;
17419   bool is_command_parameter_encryption_possible = true;
17420   bool is_response_parameter_encryption_possible = true;
17421   std::string command_code_bytes;
17422   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17423   if (rc != TPM_RC_SUCCESS) {
17424     return rc;
17425   }
17426   std::string privacy_admin_handle_bytes;
17427   rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_admin_handle,
17428                                      &privacy_admin_handle_bytes);
17429   if (rc != TPM_RC_SUCCESS) {
17430     return rc;
17431   }
17432   std::string sign_handle_bytes;
17433   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17434   if (rc != TPM_RC_SUCCESS) {
17435     return rc;
17436   }
17437   std::string session_handle_bytes;
17438   rc = Serialize_TPMI_SH_HMAC(session_handle, &session_handle_bytes);
17439   if (rc != TPM_RC_SUCCESS) {
17440     return rc;
17441   }
17442   std::string qualifying_data_bytes;
17443   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17444   if (rc != TPM_RC_SUCCESS) {
17445     return rc;
17446   }
17447   std::string in_scheme_bytes;
17448   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17449   if (rc != TPM_RC_SUCCESS) {
17450     return rc;
17451   }
17452   if (authorization_delegate) {
17453     // Encrypt just the parameter data, not the size.
17454     std::string tmp = qualifying_data_bytes.substr(2);
17455     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17456       return TRUNKS_RC_ENCRYPTION_FAILED;
17457     }
17458     qualifying_data_bytes.replace(2, std::string::npos, tmp);
17459   }
17460   std::unique_ptr<crypto::SecureHash> hash(
17461       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17462   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17463   hash->Update(privacy_admin_handle_name.data(),
17464                privacy_admin_handle_name.size());
17465   handle_section_bytes += privacy_admin_handle_bytes;
17466   command_size += privacy_admin_handle_bytes.size();
17467   hash->Update(sign_handle_name.data(), sign_handle_name.size());
17468   handle_section_bytes += sign_handle_bytes;
17469   command_size += sign_handle_bytes.size();
17470   hash->Update(session_handle_name.data(), session_handle_name.size());
17471   handle_section_bytes += session_handle_bytes;
17472   command_size += session_handle_bytes.size();
17473   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17474   parameter_section_bytes += qualifying_data_bytes;
17475   command_size += qualifying_data_bytes.size();
17476   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17477   parameter_section_bytes += in_scheme_bytes;
17478   command_size += in_scheme_bytes.size();
17479   std::string command_hash(32, 0);
17480   hash->Finish(std::data(command_hash), command_hash.size());
17481   std::string authorization_section_bytes;
17482   std::string authorization_size_bytes;
17483   if (authorization_delegate) {
17484     if (!authorization_delegate->GetCommandAuthorization(
17485             command_hash, is_command_parameter_encryption_possible,
17486             is_response_parameter_encryption_possible,
17487             &authorization_section_bytes)) {
17488       return TRUNKS_RC_AUTHORIZATION_FAILED;
17489     }
17490     if (!authorization_section_bytes.empty()) {
17491       tag = TPM_ST_SESSIONS;
17492       std::string tmp;
17493       rc = Serialize_UINT32(authorization_section_bytes.size(),
17494                             &authorization_size_bytes);
17495       if (rc != TPM_RC_SUCCESS) {
17496         return rc;
17497       }
17498       command_size +=
17499           authorization_size_bytes.size() + authorization_section_bytes.size();
17500     }
17501   }
17502   std::string tag_bytes;
17503   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17504   if (rc != TPM_RC_SUCCESS) {
17505     return rc;
17506   }
17507   std::string command_size_bytes;
17508   rc = Serialize_UINT32(command_size, &command_size_bytes);
17509   if (rc != TPM_RC_SUCCESS) {
17510     return rc;
17511   }
17512   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17513                         handle_section_bytes + authorization_size_bytes +
17514                         authorization_section_bytes + parameter_section_bytes;
17515   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17516   VLOG(2) << "Command: "
17517           << base::HexEncode(serialized_command->data(),
17518                              serialized_command->size());
17519   return TPM_RC_SUCCESS;
17520 }
17521 
ParseResponse_GetSessionAuditDigest(const std::string & response,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17522 TPM_RC Tpm::ParseResponse_GetSessionAuditDigest(
17523     const std::string& response,
17524     TPM2B_ATTEST* audit_info,
17525     TPMT_SIGNATURE* signature,
17526     AuthorizationDelegate* authorization_delegate) {
17527   VLOG(3) << __func__;
17528   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17529   TPM_RC rc = TPM_RC_SUCCESS;
17530   std::string buffer(response);
17531   TPM_ST tag;
17532   std::string tag_bytes;
17533   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17534   if (rc != TPM_RC_SUCCESS) {
17535     return rc;
17536   }
17537   UINT32 response_size;
17538   std::string response_size_bytes;
17539   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17540   if (rc != TPM_RC_SUCCESS) {
17541     return rc;
17542   }
17543   TPM_RC response_code;
17544   std::string response_code_bytes;
17545   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17546   if (rc != TPM_RC_SUCCESS) {
17547     return rc;
17548   }
17549   if (response_size != response.size()) {
17550     return TPM_RC_SIZE;
17551   }
17552   if (response_code != TPM_RC_SUCCESS) {
17553     return response_code;
17554   }
17555   TPM_CC command_code = TPM_CC_GetSessionAuditDigest;
17556   std::string command_code_bytes;
17557   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17558   if (rc != TPM_RC_SUCCESS) {
17559     return rc;
17560   }
17561   std::string authorization_section_bytes;
17562   if (tag == TPM_ST_SESSIONS) {
17563     UINT32 parameter_section_size = buffer.size();
17564     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
17565     if (rc != TPM_RC_SUCCESS) {
17566       return rc;
17567     }
17568     if (parameter_section_size > buffer.size()) {
17569       return TPM_RC_INSUFFICIENT;
17570     }
17571     authorization_section_bytes = buffer.substr(parameter_section_size);
17572     // Keep the parameter section in |buffer|.
17573     buffer.erase(parameter_section_size);
17574   }
17575   std::unique_ptr<crypto::SecureHash> hash(
17576       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17577   hash->Update(response_code_bytes.data(), response_code_bytes.size());
17578   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17579   hash->Update(buffer.data(), buffer.size());
17580   std::string response_hash(32, 0);
17581   hash->Finish(std::data(response_hash), response_hash.size());
17582   if (tag == TPM_ST_SESSIONS) {
17583     if (!authorization_delegate)
17584       return TRUNKS_RC_AUTHORIZATION_FAILED;
17585     if (!authorization_delegate->CheckResponseAuthorization(
17586             response_hash, authorization_section_bytes)) {
17587       return TRUNKS_RC_AUTHORIZATION_FAILED;
17588     }
17589   }
17590   if (tag == TPM_ST_SESSIONS) {
17591     if (!authorization_delegate)
17592       return TRUNKS_RC_AUTHORIZATION_FAILED;
17593 
17594     // Parse the encrypted parameter size.
17595     UINT16 size;
17596     std::string size_buffer = buffer.substr(0, 2);
17597     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17598       return result;
17599     }
17600     if (buffer.size() < 2 + size) {
17601       return TPM_RC_INSUFFICIENT;
17602     }
17603 
17604     // Decrypt just the parameter data, not the size.
17605     std::string decrypted_data = buffer.substr(2, size);
17606     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17607       return TRUNKS_RC_ENCRYPTION_FAILED;
17608     }
17609     buffer.replace(2, size, decrypted_data);
17610   }
17611   std::string audit_info_bytes;
17612   rc = Parse_TPM2B_ATTEST(&buffer, audit_info, &audit_info_bytes);
17613   if (rc != TPM_RC_SUCCESS) {
17614     return rc;
17615   }
17616   std::string signature_bytes;
17617   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17618   if (rc != TPM_RC_SUCCESS) {
17619     return rc;
17620   }
17621   return TPM_RC_SUCCESS;
17622 }
17623 
GetSessionAuditDigestErrorCallback(Tpm::GetSessionAuditDigestResponse callback,TPM_RC response_code)17624 void GetSessionAuditDigestErrorCallback(
17625     Tpm::GetSessionAuditDigestResponse callback, TPM_RC response_code) {
17626   VLOG(1) << __func__;
17627   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17628 }
17629 
GetSessionAuditDigestResponseParser(Tpm::GetSessionAuditDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17630 void GetSessionAuditDigestResponseParser(
17631     Tpm::GetSessionAuditDigestResponse callback,
17632     AuthorizationDelegate* authorization_delegate,
17633     const std::string& response) {
17634   VLOG(1) << __func__;
17635   TPM2B_ATTEST audit_info;
17636   TPMT_SIGNATURE signature;
17637   TPM_RC rc = Tpm::ParseResponse_GetSessionAuditDigest(
17638       response, &audit_info, &signature, authorization_delegate);
17639   if (rc != TPM_RC_SUCCESS) {
17640     base::OnceCallback<void(TPM_RC)> error_reporter =
17641         base::BindOnce(GetSessionAuditDigestErrorCallback, std::move(callback));
17642     std::move(error_reporter).Run(rc);
17643     return;
17644   }
17645   std::move(callback).Run(rc, audit_info, signature);
17646 }
17647 
GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_SH_HMAC & session_handle,const std::string & session_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,GetSessionAuditDigestResponse callback)17648 void Tpm::GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17649                                 const std::string& privacy_admin_handle_name,
17650                                 const TPMI_DH_OBJECT& sign_handle,
17651                                 const std::string& sign_handle_name,
17652                                 const TPMI_SH_HMAC& session_handle,
17653                                 const std::string& session_handle_name,
17654                                 const TPM2B_DATA& qualifying_data,
17655                                 const TPMT_SIG_SCHEME& in_scheme,
17656                                 AuthorizationDelegate* authorization_delegate,
17657                                 GetSessionAuditDigestResponse callback) {
17658   VLOG(1) << __func__;
17659   std::string command;
17660   TPM_RC rc = SerializeCommand_GetSessionAuditDigest(
17661       privacy_admin_handle, privacy_admin_handle_name, sign_handle,
17662       sign_handle_name, session_handle, session_handle_name, qualifying_data,
17663       in_scheme, &command, authorization_delegate);
17664   if (rc != TPM_RC_SUCCESS) {
17665     base::OnceCallback<void(TPM_RC)> error_reporter =
17666         base::BindOnce(GetSessionAuditDigestErrorCallback, std::move(callback));
17667     std::move(error_reporter).Run(rc);
17668     return;
17669   }
17670   base::OnceCallback<void(const std::string&)> parser =
17671       base::BindOnce(GetSessionAuditDigestResponseParser, std::move(callback),
17672                      authorization_delegate);
17673   transceiver_->SendCommand(command, std::move(parser));
17674 }
17675 
GetSessionAuditDigestSync(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_SH_HMAC & session_handle,const std::string & session_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17676 TPM_RC Tpm::GetSessionAuditDigestSync(
17677     const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17678     const std::string& privacy_admin_handle_name,
17679     const TPMI_DH_OBJECT& sign_handle,
17680     const std::string& sign_handle_name,
17681     const TPMI_SH_HMAC& session_handle,
17682     const std::string& session_handle_name,
17683     const TPM2B_DATA& qualifying_data,
17684     const TPMT_SIG_SCHEME& in_scheme,
17685     TPM2B_ATTEST* audit_info,
17686     TPMT_SIGNATURE* signature,
17687     AuthorizationDelegate* authorization_delegate) {
17688   VLOG(1) << __func__;
17689   std::string command;
17690   TPM_RC rc = SerializeCommand_GetSessionAuditDigest(
17691       privacy_admin_handle, privacy_admin_handle_name, sign_handle,
17692       sign_handle_name, session_handle, session_handle_name, qualifying_data,
17693       in_scheme, &command, authorization_delegate);
17694   if (rc != TPM_RC_SUCCESS) {
17695     return rc;
17696   }
17697   std::string response = transceiver_->SendCommandAndWait(command);
17698   rc = ParseResponse_GetSessionAuditDigest(response, audit_info, signature,
17699                                            authorization_delegate);
17700   return rc;
17701 }
17702 
SerializeCommand_GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_handle,const std::string & privacy_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17703 TPM_RC Tpm::SerializeCommand_GetCommandAuditDigest(
17704     const TPMI_RH_ENDORSEMENT& privacy_handle,
17705     const std::string& privacy_handle_name,
17706     const TPMI_DH_OBJECT& sign_handle,
17707     const std::string& sign_handle_name,
17708     const TPM2B_DATA& qualifying_data,
17709     const TPMT_SIG_SCHEME& in_scheme,
17710     std::string* serialized_command,
17711     AuthorizationDelegate* authorization_delegate) {
17712   VLOG(3) << __func__;
17713   TPM_RC rc = TPM_RC_SUCCESS;
17714   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17715   UINT32 command_size = 10;  // Header size.
17716   std::string handle_section_bytes;
17717   std::string parameter_section_bytes;
17718   TPM_CC command_code = TPM_CC_GetCommandAuditDigest;
17719   bool is_command_parameter_encryption_possible = true;
17720   bool is_response_parameter_encryption_possible = true;
17721   std::string command_code_bytes;
17722   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17723   if (rc != TPM_RC_SUCCESS) {
17724     return rc;
17725   }
17726   std::string privacy_handle_bytes;
17727   rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_handle, &privacy_handle_bytes);
17728   if (rc != TPM_RC_SUCCESS) {
17729     return rc;
17730   }
17731   std::string sign_handle_bytes;
17732   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17733   if (rc != TPM_RC_SUCCESS) {
17734     return rc;
17735   }
17736   std::string qualifying_data_bytes;
17737   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17738   if (rc != TPM_RC_SUCCESS) {
17739     return rc;
17740   }
17741   std::string in_scheme_bytes;
17742   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17743   if (rc != TPM_RC_SUCCESS) {
17744     return rc;
17745   }
17746   if (authorization_delegate) {
17747     // Encrypt just the parameter data, not the size.
17748     std::string tmp = qualifying_data_bytes.substr(2);
17749     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17750       return TRUNKS_RC_ENCRYPTION_FAILED;
17751     }
17752     qualifying_data_bytes.replace(2, std::string::npos, tmp);
17753   }
17754   std::unique_ptr<crypto::SecureHash> hash(
17755       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17756   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17757   hash->Update(privacy_handle_name.data(), privacy_handle_name.size());
17758   handle_section_bytes += privacy_handle_bytes;
17759   command_size += privacy_handle_bytes.size();
17760   hash->Update(sign_handle_name.data(), sign_handle_name.size());
17761   handle_section_bytes += sign_handle_bytes;
17762   command_size += sign_handle_bytes.size();
17763   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17764   parameter_section_bytes += qualifying_data_bytes;
17765   command_size += qualifying_data_bytes.size();
17766   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17767   parameter_section_bytes += in_scheme_bytes;
17768   command_size += in_scheme_bytes.size();
17769   std::string command_hash(32, 0);
17770   hash->Finish(std::data(command_hash), command_hash.size());
17771   std::string authorization_section_bytes;
17772   std::string authorization_size_bytes;
17773   if (authorization_delegate) {
17774     if (!authorization_delegate->GetCommandAuthorization(
17775             command_hash, is_command_parameter_encryption_possible,
17776             is_response_parameter_encryption_possible,
17777             &authorization_section_bytes)) {
17778       return TRUNKS_RC_AUTHORIZATION_FAILED;
17779     }
17780     if (!authorization_section_bytes.empty()) {
17781       tag = TPM_ST_SESSIONS;
17782       std::string tmp;
17783       rc = Serialize_UINT32(authorization_section_bytes.size(),
17784                             &authorization_size_bytes);
17785       if (rc != TPM_RC_SUCCESS) {
17786         return rc;
17787       }
17788       command_size +=
17789           authorization_size_bytes.size() + authorization_section_bytes.size();
17790     }
17791   }
17792   std::string tag_bytes;
17793   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17794   if (rc != TPM_RC_SUCCESS) {
17795     return rc;
17796   }
17797   std::string command_size_bytes;
17798   rc = Serialize_UINT32(command_size, &command_size_bytes);
17799   if (rc != TPM_RC_SUCCESS) {
17800     return rc;
17801   }
17802   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17803                         handle_section_bytes + authorization_size_bytes +
17804                         authorization_section_bytes + parameter_section_bytes;
17805   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17806   VLOG(2) << "Command: "
17807           << base::HexEncode(serialized_command->data(),
17808                              serialized_command->size());
17809   return TPM_RC_SUCCESS;
17810 }
17811 
ParseResponse_GetCommandAuditDigest(const std::string & response,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17812 TPM_RC Tpm::ParseResponse_GetCommandAuditDigest(
17813     const std::string& response,
17814     TPM2B_ATTEST* audit_info,
17815     TPMT_SIGNATURE* signature,
17816     AuthorizationDelegate* authorization_delegate) {
17817   VLOG(3) << __func__;
17818   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17819   TPM_RC rc = TPM_RC_SUCCESS;
17820   std::string buffer(response);
17821   TPM_ST tag;
17822   std::string tag_bytes;
17823   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17824   if (rc != TPM_RC_SUCCESS) {
17825     return rc;
17826   }
17827   UINT32 response_size;
17828   std::string response_size_bytes;
17829   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17830   if (rc != TPM_RC_SUCCESS) {
17831     return rc;
17832   }
17833   TPM_RC response_code;
17834   std::string response_code_bytes;
17835   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17836   if (rc != TPM_RC_SUCCESS) {
17837     return rc;
17838   }
17839   if (response_size != response.size()) {
17840     return TPM_RC_SIZE;
17841   }
17842   if (response_code != TPM_RC_SUCCESS) {
17843     return response_code;
17844   }
17845   TPM_CC command_code = TPM_CC_GetCommandAuditDigest;
17846   std::string command_code_bytes;
17847   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17848   if (rc != TPM_RC_SUCCESS) {
17849     return rc;
17850   }
17851   std::string authorization_section_bytes;
17852   if (tag == TPM_ST_SESSIONS) {
17853     UINT32 parameter_section_size = buffer.size();
17854     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
17855     if (rc != TPM_RC_SUCCESS) {
17856       return rc;
17857     }
17858     if (parameter_section_size > buffer.size()) {
17859       return TPM_RC_INSUFFICIENT;
17860     }
17861     authorization_section_bytes = buffer.substr(parameter_section_size);
17862     // Keep the parameter section in |buffer|.
17863     buffer.erase(parameter_section_size);
17864   }
17865   std::unique_ptr<crypto::SecureHash> hash(
17866       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17867   hash->Update(response_code_bytes.data(), response_code_bytes.size());
17868   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17869   hash->Update(buffer.data(), buffer.size());
17870   std::string response_hash(32, 0);
17871   hash->Finish(std::data(response_hash), response_hash.size());
17872   if (tag == TPM_ST_SESSIONS) {
17873     if (!authorization_delegate)
17874       return TRUNKS_RC_AUTHORIZATION_FAILED;
17875     if (!authorization_delegate->CheckResponseAuthorization(
17876             response_hash, authorization_section_bytes)) {
17877       return TRUNKS_RC_AUTHORIZATION_FAILED;
17878     }
17879   }
17880   if (tag == TPM_ST_SESSIONS) {
17881     if (!authorization_delegate)
17882       return TRUNKS_RC_AUTHORIZATION_FAILED;
17883 
17884     // Parse the encrypted parameter size.
17885     UINT16 size;
17886     std::string size_buffer = buffer.substr(0, 2);
17887     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17888       return result;
17889     }
17890     if (buffer.size() < 2 + size) {
17891       return TPM_RC_INSUFFICIENT;
17892     }
17893 
17894     // Decrypt just the parameter data, not the size.
17895     std::string decrypted_data = buffer.substr(2, size);
17896     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17897       return TRUNKS_RC_ENCRYPTION_FAILED;
17898     }
17899     buffer.replace(2, size, decrypted_data);
17900   }
17901   std::string audit_info_bytes;
17902   rc = Parse_TPM2B_ATTEST(&buffer, audit_info, &audit_info_bytes);
17903   if (rc != TPM_RC_SUCCESS) {
17904     return rc;
17905   }
17906   std::string signature_bytes;
17907   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17908   if (rc != TPM_RC_SUCCESS) {
17909     return rc;
17910   }
17911   return TPM_RC_SUCCESS;
17912 }
17913 
GetCommandAuditDigestErrorCallback(Tpm::GetCommandAuditDigestResponse callback,TPM_RC response_code)17914 void GetCommandAuditDigestErrorCallback(
17915     Tpm::GetCommandAuditDigestResponse callback, TPM_RC response_code) {
17916   VLOG(1) << __func__;
17917   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17918 }
17919 
GetCommandAuditDigestResponseParser(Tpm::GetCommandAuditDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17920 void GetCommandAuditDigestResponseParser(
17921     Tpm::GetCommandAuditDigestResponse callback,
17922     AuthorizationDelegate* authorization_delegate,
17923     const std::string& response) {
17924   VLOG(1) << __func__;
17925   TPM2B_ATTEST audit_info;
17926   TPMT_SIGNATURE signature;
17927   TPM_RC rc = Tpm::ParseResponse_GetCommandAuditDigest(
17928       response, &audit_info, &signature, authorization_delegate);
17929   if (rc != TPM_RC_SUCCESS) {
17930     base::OnceCallback<void(TPM_RC)> error_reporter =
17931         base::BindOnce(GetCommandAuditDigestErrorCallback, std::move(callback));
17932     std::move(error_reporter).Run(rc);
17933     return;
17934   }
17935   std::move(callback).Run(rc, audit_info, signature);
17936 }
17937 
GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_handle,const std::string & privacy_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,GetCommandAuditDigestResponse callback)17938 void Tpm::GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT& privacy_handle,
17939                                 const std::string& privacy_handle_name,
17940                                 const TPMI_DH_OBJECT& sign_handle,
17941                                 const std::string& sign_handle_name,
17942                                 const TPM2B_DATA& qualifying_data,
17943                                 const TPMT_SIG_SCHEME& in_scheme,
17944                                 AuthorizationDelegate* authorization_delegate,
17945                                 GetCommandAuditDigestResponse callback) {
17946   VLOG(1) << __func__;
17947   std::string command;
17948   TPM_RC rc = SerializeCommand_GetCommandAuditDigest(
17949       privacy_handle, privacy_handle_name, sign_handle, sign_handle_name,
17950       qualifying_data, in_scheme, &command, authorization_delegate);
17951   if (rc != TPM_RC_SUCCESS) {
17952     base::OnceCallback<void(TPM_RC)> error_reporter =
17953         base::BindOnce(GetCommandAuditDigestErrorCallback, std::move(callback));
17954     std::move(error_reporter).Run(rc);
17955     return;
17956   }
17957   base::OnceCallback<void(const std::string&)> parser =
17958       base::BindOnce(GetCommandAuditDigestResponseParser, std::move(callback),
17959                      authorization_delegate);
17960   transceiver_->SendCommand(command, std::move(parser));
17961 }
17962 
GetCommandAuditDigestSync(const TPMI_RH_ENDORSEMENT & privacy_handle,const std::string & privacy_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17963 TPM_RC Tpm::GetCommandAuditDigestSync(
17964     const TPMI_RH_ENDORSEMENT& privacy_handle,
17965     const std::string& privacy_handle_name,
17966     const TPMI_DH_OBJECT& sign_handle,
17967     const std::string& sign_handle_name,
17968     const TPM2B_DATA& qualifying_data,
17969     const TPMT_SIG_SCHEME& in_scheme,
17970     TPM2B_ATTEST* audit_info,
17971     TPMT_SIGNATURE* signature,
17972     AuthorizationDelegate* authorization_delegate) {
17973   VLOG(1) << __func__;
17974   std::string command;
17975   TPM_RC rc = SerializeCommand_GetCommandAuditDigest(
17976       privacy_handle, privacy_handle_name, sign_handle, sign_handle_name,
17977       qualifying_data, in_scheme, &command, authorization_delegate);
17978   if (rc != TPM_RC_SUCCESS) {
17979     return rc;
17980   }
17981   std::string response = transceiver_->SendCommandAndWait(command);
17982   rc = ParseResponse_GetCommandAuditDigest(response, audit_info, signature,
17983                                            authorization_delegate);
17984   return rc;
17985 }
17986 
SerializeCommand_GetTime(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17987 TPM_RC Tpm::SerializeCommand_GetTime(
17988     const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17989     const std::string& privacy_admin_handle_name,
17990     const TPMI_DH_OBJECT& sign_handle,
17991     const std::string& sign_handle_name,
17992     const TPM2B_DATA& qualifying_data,
17993     const TPMT_SIG_SCHEME& in_scheme,
17994     std::string* serialized_command,
17995     AuthorizationDelegate* authorization_delegate) {
17996   VLOG(3) << __func__;
17997   TPM_RC rc = TPM_RC_SUCCESS;
17998   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17999   UINT32 command_size = 10;  // Header size.
18000   std::string handle_section_bytes;
18001   std::string parameter_section_bytes;
18002   TPM_CC command_code = TPM_CC_GetTime;
18003   bool is_command_parameter_encryption_possible = true;
18004   bool is_response_parameter_encryption_possible = true;
18005   std::string command_code_bytes;
18006   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18007   if (rc != TPM_RC_SUCCESS) {
18008     return rc;
18009   }
18010   std::string privacy_admin_handle_bytes;
18011   rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_admin_handle,
18012                                      &privacy_admin_handle_bytes);
18013   if (rc != TPM_RC_SUCCESS) {
18014     return rc;
18015   }
18016   std::string sign_handle_bytes;
18017   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
18018   if (rc != TPM_RC_SUCCESS) {
18019     return rc;
18020   }
18021   std::string qualifying_data_bytes;
18022   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
18023   if (rc != TPM_RC_SUCCESS) {
18024     return rc;
18025   }
18026   std::string in_scheme_bytes;
18027   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
18028   if (rc != TPM_RC_SUCCESS) {
18029     return rc;
18030   }
18031   if (authorization_delegate) {
18032     // Encrypt just the parameter data, not the size.
18033     std::string tmp = qualifying_data_bytes.substr(2);
18034     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
18035       return TRUNKS_RC_ENCRYPTION_FAILED;
18036     }
18037     qualifying_data_bytes.replace(2, std::string::npos, tmp);
18038   }
18039   std::unique_ptr<crypto::SecureHash> hash(
18040       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18041   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18042   hash->Update(privacy_admin_handle_name.data(),
18043                privacy_admin_handle_name.size());
18044   handle_section_bytes += privacy_admin_handle_bytes;
18045   command_size += privacy_admin_handle_bytes.size();
18046   hash->Update(sign_handle_name.data(), sign_handle_name.size());
18047   handle_section_bytes += sign_handle_bytes;
18048   command_size += sign_handle_bytes.size();
18049   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
18050   parameter_section_bytes += qualifying_data_bytes;
18051   command_size += qualifying_data_bytes.size();
18052   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
18053   parameter_section_bytes += in_scheme_bytes;
18054   command_size += in_scheme_bytes.size();
18055   std::string command_hash(32, 0);
18056   hash->Finish(std::data(command_hash), command_hash.size());
18057   std::string authorization_section_bytes;
18058   std::string authorization_size_bytes;
18059   if (authorization_delegate) {
18060     if (!authorization_delegate->GetCommandAuthorization(
18061             command_hash, is_command_parameter_encryption_possible,
18062             is_response_parameter_encryption_possible,
18063             &authorization_section_bytes)) {
18064       return TRUNKS_RC_AUTHORIZATION_FAILED;
18065     }
18066     if (!authorization_section_bytes.empty()) {
18067       tag = TPM_ST_SESSIONS;
18068       std::string tmp;
18069       rc = Serialize_UINT32(authorization_section_bytes.size(),
18070                             &authorization_size_bytes);
18071       if (rc != TPM_RC_SUCCESS) {
18072         return rc;
18073       }
18074       command_size +=
18075           authorization_size_bytes.size() + authorization_section_bytes.size();
18076     }
18077   }
18078   std::string tag_bytes;
18079   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18080   if (rc != TPM_RC_SUCCESS) {
18081     return rc;
18082   }
18083   std::string command_size_bytes;
18084   rc = Serialize_UINT32(command_size, &command_size_bytes);
18085   if (rc != TPM_RC_SUCCESS) {
18086     return rc;
18087   }
18088   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18089                         handle_section_bytes + authorization_size_bytes +
18090                         authorization_section_bytes + parameter_section_bytes;
18091   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18092   VLOG(2) << "Command: "
18093           << base::HexEncode(serialized_command->data(),
18094                              serialized_command->size());
18095   return TPM_RC_SUCCESS;
18096 }
18097 
ParseResponse_GetTime(const std::string & response,TPM2B_ATTEST * time_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)18098 TPM_RC Tpm::ParseResponse_GetTime(
18099     const std::string& response,
18100     TPM2B_ATTEST* time_info,
18101     TPMT_SIGNATURE* signature,
18102     AuthorizationDelegate* authorization_delegate) {
18103   VLOG(3) << __func__;
18104   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18105   TPM_RC rc = TPM_RC_SUCCESS;
18106   std::string buffer(response);
18107   TPM_ST tag;
18108   std::string tag_bytes;
18109   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18110   if (rc != TPM_RC_SUCCESS) {
18111     return rc;
18112   }
18113   UINT32 response_size;
18114   std::string response_size_bytes;
18115   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18116   if (rc != TPM_RC_SUCCESS) {
18117     return rc;
18118   }
18119   TPM_RC response_code;
18120   std::string response_code_bytes;
18121   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18122   if (rc != TPM_RC_SUCCESS) {
18123     return rc;
18124   }
18125   if (response_size != response.size()) {
18126     return TPM_RC_SIZE;
18127   }
18128   if (response_code != TPM_RC_SUCCESS) {
18129     return response_code;
18130   }
18131   TPM_CC command_code = TPM_CC_GetTime;
18132   std::string command_code_bytes;
18133   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18134   if (rc != TPM_RC_SUCCESS) {
18135     return rc;
18136   }
18137   std::string authorization_section_bytes;
18138   if (tag == TPM_ST_SESSIONS) {
18139     UINT32 parameter_section_size = buffer.size();
18140     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18141     if (rc != TPM_RC_SUCCESS) {
18142       return rc;
18143     }
18144     if (parameter_section_size > buffer.size()) {
18145       return TPM_RC_INSUFFICIENT;
18146     }
18147     authorization_section_bytes = buffer.substr(parameter_section_size);
18148     // Keep the parameter section in |buffer|.
18149     buffer.erase(parameter_section_size);
18150   }
18151   std::unique_ptr<crypto::SecureHash> hash(
18152       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18153   hash->Update(response_code_bytes.data(), response_code_bytes.size());
18154   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18155   hash->Update(buffer.data(), buffer.size());
18156   std::string response_hash(32, 0);
18157   hash->Finish(std::data(response_hash), response_hash.size());
18158   if (tag == TPM_ST_SESSIONS) {
18159     if (!authorization_delegate)
18160       return TRUNKS_RC_AUTHORIZATION_FAILED;
18161     if (!authorization_delegate->CheckResponseAuthorization(
18162             response_hash, authorization_section_bytes)) {
18163       return TRUNKS_RC_AUTHORIZATION_FAILED;
18164     }
18165   }
18166   if (tag == TPM_ST_SESSIONS) {
18167     if (!authorization_delegate)
18168       return TRUNKS_RC_AUTHORIZATION_FAILED;
18169 
18170     // Parse the encrypted parameter size.
18171     UINT16 size;
18172     std::string size_buffer = buffer.substr(0, 2);
18173     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
18174       return result;
18175     }
18176     if (buffer.size() < 2 + size) {
18177       return TPM_RC_INSUFFICIENT;
18178     }
18179 
18180     // Decrypt just the parameter data, not the size.
18181     std::string decrypted_data = buffer.substr(2, size);
18182     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
18183       return TRUNKS_RC_ENCRYPTION_FAILED;
18184     }
18185     buffer.replace(2, size, decrypted_data);
18186   }
18187   std::string time_info_bytes;
18188   rc = Parse_TPM2B_ATTEST(&buffer, time_info, &time_info_bytes);
18189   if (rc != TPM_RC_SUCCESS) {
18190     return rc;
18191   }
18192   std::string signature_bytes;
18193   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
18194   if (rc != TPM_RC_SUCCESS) {
18195     return rc;
18196   }
18197   return TPM_RC_SUCCESS;
18198 }
18199 
GetTimeErrorCallback(Tpm::GetTimeResponse callback,TPM_RC response_code)18200 void GetTimeErrorCallback(Tpm::GetTimeResponse callback, TPM_RC response_code) {
18201   VLOG(1) << __func__;
18202   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
18203 }
18204 
GetTimeResponseParser(Tpm::GetTimeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18205 void GetTimeResponseParser(Tpm::GetTimeResponse callback,
18206                            AuthorizationDelegate* authorization_delegate,
18207                            const std::string& response) {
18208   VLOG(1) << __func__;
18209   TPM2B_ATTEST time_info;
18210   TPMT_SIGNATURE signature;
18211   TPM_RC rc = Tpm::ParseResponse_GetTime(response, &time_info, &signature,
18212                                          authorization_delegate);
18213   if (rc != TPM_RC_SUCCESS) {
18214     base::OnceCallback<void(TPM_RC)> error_reporter =
18215         base::BindOnce(GetTimeErrorCallback, std::move(callback));
18216     std::move(error_reporter).Run(rc);
18217     return;
18218   }
18219   std::move(callback).Run(rc, time_info, signature);
18220 }
18221 
GetTime(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,GetTimeResponse callback)18222 void Tpm::GetTime(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
18223                   const std::string& privacy_admin_handle_name,
18224                   const TPMI_DH_OBJECT& sign_handle,
18225                   const std::string& sign_handle_name,
18226                   const TPM2B_DATA& qualifying_data,
18227                   const TPMT_SIG_SCHEME& in_scheme,
18228                   AuthorizationDelegate* authorization_delegate,
18229                   GetTimeResponse callback) {
18230   VLOG(1) << __func__;
18231   std::string command;
18232   TPM_RC rc =
18233       SerializeCommand_GetTime(privacy_admin_handle, privacy_admin_handle_name,
18234                                sign_handle, sign_handle_name, qualifying_data,
18235                                in_scheme, &command, authorization_delegate);
18236   if (rc != TPM_RC_SUCCESS) {
18237     base::OnceCallback<void(TPM_RC)> error_reporter =
18238         base::BindOnce(GetTimeErrorCallback, std::move(callback));
18239     std::move(error_reporter).Run(rc);
18240     return;
18241   }
18242   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18243       GetTimeResponseParser, std::move(callback), authorization_delegate);
18244   transceiver_->SendCommand(command, std::move(parser));
18245 }
18246 
GetTimeSync(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * time_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)18247 TPM_RC Tpm::GetTimeSync(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
18248                         const std::string& privacy_admin_handle_name,
18249                         const TPMI_DH_OBJECT& sign_handle,
18250                         const std::string& sign_handle_name,
18251                         const TPM2B_DATA& qualifying_data,
18252                         const TPMT_SIG_SCHEME& in_scheme,
18253                         TPM2B_ATTEST* time_info,
18254                         TPMT_SIGNATURE* signature,
18255                         AuthorizationDelegate* authorization_delegate) {
18256   VLOG(1) << __func__;
18257   std::string command;
18258   TPM_RC rc =
18259       SerializeCommand_GetTime(privacy_admin_handle, privacy_admin_handle_name,
18260                                sign_handle, sign_handle_name, qualifying_data,
18261                                in_scheme, &command, authorization_delegate);
18262   if (rc != TPM_RC_SUCCESS) {
18263     return rc;
18264   }
18265   std::string response = transceiver_->SendCommandAndWait(command);
18266   rc = ParseResponse_GetTime(response, time_info, signature,
18267                              authorization_delegate);
18268   return rc;
18269 }
18270 
SerializeCommand_Commit(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const UINT32 & param_size,const TPM2B_ECC_POINT & p1,const TPM2B_SENSITIVE_DATA & s2,const TPM2B_ECC_PARAMETER & y2,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)18271 TPM_RC Tpm::SerializeCommand_Commit(
18272     const TPMI_DH_OBJECT& sign_handle,
18273     const std::string& sign_handle_name,
18274     const UINT32& param_size,
18275     const TPM2B_ECC_POINT& p1,
18276     const TPM2B_SENSITIVE_DATA& s2,
18277     const TPM2B_ECC_PARAMETER& y2,
18278     std::string* serialized_command,
18279     AuthorizationDelegate* authorization_delegate) {
18280   VLOG(3) << __func__;
18281   TPM_RC rc = TPM_RC_SUCCESS;
18282   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18283   UINT32 command_size = 10;  // Header size.
18284   std::string handle_section_bytes;
18285   std::string parameter_section_bytes;
18286   TPM_CC command_code = TPM_CC_Commit;
18287   bool is_command_parameter_encryption_possible = false;
18288   bool is_response_parameter_encryption_possible = false;
18289   std::string command_code_bytes;
18290   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18291   if (rc != TPM_RC_SUCCESS) {
18292     return rc;
18293   }
18294   std::string param_size_bytes;
18295   rc = Serialize_UINT32(param_size, &param_size_bytes);
18296   if (rc != TPM_RC_SUCCESS) {
18297     return rc;
18298   }
18299   std::string sign_handle_bytes;
18300   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
18301   if (rc != TPM_RC_SUCCESS) {
18302     return rc;
18303   }
18304   std::string p1_bytes;
18305   rc = Serialize_TPM2B_ECC_POINT(p1, &p1_bytes);
18306   if (rc != TPM_RC_SUCCESS) {
18307     return rc;
18308   }
18309   std::string s2_bytes;
18310   rc = Serialize_TPM2B_SENSITIVE_DATA(s2, &s2_bytes);
18311   if (rc != TPM_RC_SUCCESS) {
18312     return rc;
18313   }
18314   std::string y2_bytes;
18315   rc = Serialize_TPM2B_ECC_PARAMETER(y2, &y2_bytes);
18316   if (rc != TPM_RC_SUCCESS) {
18317     return rc;
18318   }
18319   std::unique_ptr<crypto::SecureHash> hash(
18320       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18321   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18322   hash->Update(sign_handle_name.data(), sign_handle_name.size());
18323   handle_section_bytes += sign_handle_bytes;
18324   command_size += sign_handle_bytes.size();
18325   hash->Update(param_size_bytes.data(), param_size_bytes.size());
18326   parameter_section_bytes += param_size_bytes;
18327   command_size += param_size_bytes.size();
18328   hash->Update(p1_bytes.data(), p1_bytes.size());
18329   parameter_section_bytes += p1_bytes;
18330   command_size += p1_bytes.size();
18331   hash->Update(s2_bytes.data(), s2_bytes.size());
18332   parameter_section_bytes += s2_bytes;
18333   command_size += s2_bytes.size();
18334   hash->Update(y2_bytes.data(), y2_bytes.size());
18335   parameter_section_bytes += y2_bytes;
18336   command_size += y2_bytes.size();
18337   std::string command_hash(32, 0);
18338   hash->Finish(std::data(command_hash), command_hash.size());
18339   std::string authorization_section_bytes;
18340   std::string authorization_size_bytes;
18341   if (authorization_delegate) {
18342     if (!authorization_delegate->GetCommandAuthorization(
18343             command_hash, is_command_parameter_encryption_possible,
18344             is_response_parameter_encryption_possible,
18345             &authorization_section_bytes)) {
18346       return TRUNKS_RC_AUTHORIZATION_FAILED;
18347     }
18348     if (!authorization_section_bytes.empty()) {
18349       tag = TPM_ST_SESSIONS;
18350       std::string tmp;
18351       rc = Serialize_UINT32(authorization_section_bytes.size(),
18352                             &authorization_size_bytes);
18353       if (rc != TPM_RC_SUCCESS) {
18354         return rc;
18355       }
18356       command_size +=
18357           authorization_size_bytes.size() + authorization_section_bytes.size();
18358     }
18359   }
18360   std::string tag_bytes;
18361   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18362   if (rc != TPM_RC_SUCCESS) {
18363     return rc;
18364   }
18365   std::string command_size_bytes;
18366   rc = Serialize_UINT32(command_size, &command_size_bytes);
18367   if (rc != TPM_RC_SUCCESS) {
18368     return rc;
18369   }
18370   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18371                         handle_section_bytes + authorization_size_bytes +
18372                         authorization_section_bytes + parameter_section_bytes;
18373   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18374   VLOG(2) << "Command: "
18375           << base::HexEncode(serialized_command->data(),
18376                              serialized_command->size());
18377   return TPM_RC_SUCCESS;
18378 }
18379 
ParseResponse_Commit(const std::string & response,UINT32 * param_size_out,TPM2B_ECC_POINT * k,TPM2B_ECC_POINT * l,TPM2B_ECC_POINT * e,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18380 TPM_RC Tpm::ParseResponse_Commit(
18381     const std::string& response,
18382     UINT32* param_size_out,
18383     TPM2B_ECC_POINT* k,
18384     TPM2B_ECC_POINT* l,
18385     TPM2B_ECC_POINT* e,
18386     UINT16* counter,
18387     AuthorizationDelegate* authorization_delegate) {
18388   VLOG(3) << __func__;
18389   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18390   TPM_RC rc = TPM_RC_SUCCESS;
18391   std::string buffer(response);
18392   TPM_ST tag;
18393   std::string tag_bytes;
18394   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18395   if (rc != TPM_RC_SUCCESS) {
18396     return rc;
18397   }
18398   UINT32 response_size;
18399   std::string response_size_bytes;
18400   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18401   if (rc != TPM_RC_SUCCESS) {
18402     return rc;
18403   }
18404   TPM_RC response_code;
18405   std::string response_code_bytes;
18406   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18407   if (rc != TPM_RC_SUCCESS) {
18408     return rc;
18409   }
18410   if (response_size != response.size()) {
18411     return TPM_RC_SIZE;
18412   }
18413   if (response_code != TPM_RC_SUCCESS) {
18414     return response_code;
18415   }
18416   TPM_CC command_code = TPM_CC_Commit;
18417   std::string command_code_bytes;
18418   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18419   if (rc != TPM_RC_SUCCESS) {
18420     return rc;
18421   }
18422   std::string authorization_section_bytes;
18423   if (tag == TPM_ST_SESSIONS) {
18424     UINT32 parameter_section_size = buffer.size();
18425     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18426     if (rc != TPM_RC_SUCCESS) {
18427       return rc;
18428     }
18429     if (parameter_section_size > buffer.size()) {
18430       return TPM_RC_INSUFFICIENT;
18431     }
18432     authorization_section_bytes = buffer.substr(parameter_section_size);
18433     // Keep the parameter section in |buffer|.
18434     buffer.erase(parameter_section_size);
18435   }
18436   std::unique_ptr<crypto::SecureHash> hash(
18437       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18438   hash->Update(response_code_bytes.data(), response_code_bytes.size());
18439   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18440   hash->Update(buffer.data(), buffer.size());
18441   std::string response_hash(32, 0);
18442   hash->Finish(std::data(response_hash), response_hash.size());
18443   if (tag == TPM_ST_SESSIONS) {
18444     if (!authorization_delegate)
18445       return TRUNKS_RC_AUTHORIZATION_FAILED;
18446     if (!authorization_delegate->CheckResponseAuthorization(
18447             response_hash, authorization_section_bytes)) {
18448       return TRUNKS_RC_AUTHORIZATION_FAILED;
18449     }
18450   }
18451   std::string param_size_out_bytes;
18452   rc = Parse_UINT32(&buffer, param_size_out, &param_size_out_bytes);
18453   if (rc != TPM_RC_SUCCESS) {
18454     return rc;
18455   }
18456   std::string k_bytes;
18457   rc = Parse_TPM2B_ECC_POINT(&buffer, k, &k_bytes);
18458   if (rc != TPM_RC_SUCCESS) {
18459     return rc;
18460   }
18461   std::string l_bytes;
18462   rc = Parse_TPM2B_ECC_POINT(&buffer, l, &l_bytes);
18463   if (rc != TPM_RC_SUCCESS) {
18464     return rc;
18465   }
18466   std::string e_bytes;
18467   rc = Parse_TPM2B_ECC_POINT(&buffer, e, &e_bytes);
18468   if (rc != TPM_RC_SUCCESS) {
18469     return rc;
18470   }
18471   std::string counter_bytes;
18472   rc = Parse_UINT16(&buffer, counter, &counter_bytes);
18473   if (rc != TPM_RC_SUCCESS) {
18474     return rc;
18475   }
18476   return TPM_RC_SUCCESS;
18477 }
18478 
CommitErrorCallback(Tpm::CommitResponse callback,TPM_RC response_code)18479 void CommitErrorCallback(Tpm::CommitResponse callback, TPM_RC response_code) {
18480   VLOG(1) << __func__;
18481   std::move(callback).Run(response_code, UINT32(), TPM2B_ECC_POINT(),
18482                           TPM2B_ECC_POINT(), TPM2B_ECC_POINT(), UINT16());
18483 }
18484 
CommitResponseParser(Tpm::CommitResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18485 void CommitResponseParser(Tpm::CommitResponse callback,
18486                           AuthorizationDelegate* authorization_delegate,
18487                           const std::string& response) {
18488   VLOG(1) << __func__;
18489   UINT32 param_size_out;
18490   TPM2B_ECC_POINT k;
18491   TPM2B_ECC_POINT l;
18492   TPM2B_ECC_POINT e;
18493   UINT16 counter;
18494   TPM_RC rc = Tpm::ParseResponse_Commit(response, &param_size_out, &k, &l, &e,
18495                                         &counter, authorization_delegate);
18496   if (rc != TPM_RC_SUCCESS) {
18497     base::OnceCallback<void(TPM_RC)> error_reporter =
18498         base::BindOnce(CommitErrorCallback, std::move(callback));
18499     std::move(error_reporter).Run(rc);
18500     return;
18501   }
18502   std::move(callback).Run(rc, param_size_out, k, l, e, counter);
18503 }
18504 
Commit(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const UINT32 & param_size,const TPM2B_ECC_POINT & p1,const TPM2B_SENSITIVE_DATA & s2,const TPM2B_ECC_PARAMETER & y2,AuthorizationDelegate * authorization_delegate,CommitResponse callback)18505 void Tpm::Commit(const TPMI_DH_OBJECT& sign_handle,
18506                  const std::string& sign_handle_name,
18507                  const UINT32& param_size,
18508                  const TPM2B_ECC_POINT& p1,
18509                  const TPM2B_SENSITIVE_DATA& s2,
18510                  const TPM2B_ECC_PARAMETER& y2,
18511                  AuthorizationDelegate* authorization_delegate,
18512                  CommitResponse callback) {
18513   VLOG(1) << __func__;
18514   std::string command;
18515   TPM_RC rc =
18516       SerializeCommand_Commit(sign_handle, sign_handle_name, param_size, p1, s2,
18517                               y2, &command, authorization_delegate);
18518   if (rc != TPM_RC_SUCCESS) {
18519     base::OnceCallback<void(TPM_RC)> error_reporter =
18520         base::BindOnce(CommitErrorCallback, std::move(callback));
18521     std::move(error_reporter).Run(rc);
18522     return;
18523   }
18524   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18525       CommitResponseParser, std::move(callback), authorization_delegate);
18526   transceiver_->SendCommand(command, std::move(parser));
18527 }
18528 
CommitSync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const UINT32 & param_size,const TPM2B_ECC_POINT & p1,const TPM2B_SENSITIVE_DATA & s2,const TPM2B_ECC_PARAMETER & y2,UINT32 * param_size_out,TPM2B_ECC_POINT * k,TPM2B_ECC_POINT * l,TPM2B_ECC_POINT * e,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18529 TPM_RC Tpm::CommitSync(const TPMI_DH_OBJECT& sign_handle,
18530                        const std::string& sign_handle_name,
18531                        const UINT32& param_size,
18532                        const TPM2B_ECC_POINT& p1,
18533                        const TPM2B_SENSITIVE_DATA& s2,
18534                        const TPM2B_ECC_PARAMETER& y2,
18535                        UINT32* param_size_out,
18536                        TPM2B_ECC_POINT* k,
18537                        TPM2B_ECC_POINT* l,
18538                        TPM2B_ECC_POINT* e,
18539                        UINT16* counter,
18540                        AuthorizationDelegate* authorization_delegate) {
18541   VLOG(1) << __func__;
18542   std::string command;
18543   TPM_RC rc =
18544       SerializeCommand_Commit(sign_handle, sign_handle_name, param_size, p1, s2,
18545                               y2, &command, authorization_delegate);
18546   if (rc != TPM_RC_SUCCESS) {
18547     return rc;
18548   }
18549   std::string response = transceiver_->SendCommandAndWait(command);
18550   rc = ParseResponse_Commit(response, param_size_out, k, l, e, counter,
18551                             authorization_delegate);
18552   return rc;
18553 }
18554 
SerializeCommand_EC_Ephemeral(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)18555 TPM_RC Tpm::SerializeCommand_EC_Ephemeral(
18556     const UINT32& param_size,
18557     const TPMI_ECC_CURVE& curve_id,
18558     std::string* serialized_command,
18559     AuthorizationDelegate* authorization_delegate) {
18560   VLOG(3) << __func__;
18561   TPM_RC rc = TPM_RC_SUCCESS;
18562   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18563   UINT32 command_size = 10;  // Header size.
18564   std::string handle_section_bytes;
18565   std::string parameter_section_bytes;
18566   TPM_CC command_code = TPM_CC_EC_Ephemeral;
18567   bool is_command_parameter_encryption_possible = false;
18568   bool is_response_parameter_encryption_possible = false;
18569   std::string command_code_bytes;
18570   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18571   if (rc != TPM_RC_SUCCESS) {
18572     return rc;
18573   }
18574   std::string param_size_bytes;
18575   rc = Serialize_UINT32(param_size, &param_size_bytes);
18576   if (rc != TPM_RC_SUCCESS) {
18577     return rc;
18578   }
18579   std::string curve_id_bytes;
18580   rc = Serialize_TPMI_ECC_CURVE(curve_id, &curve_id_bytes);
18581   if (rc != TPM_RC_SUCCESS) {
18582     return rc;
18583   }
18584   std::unique_ptr<crypto::SecureHash> hash(
18585       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18586   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18587   hash->Update(param_size_bytes.data(), param_size_bytes.size());
18588   parameter_section_bytes += param_size_bytes;
18589   command_size += param_size_bytes.size();
18590   hash->Update(curve_id_bytes.data(), curve_id_bytes.size());
18591   parameter_section_bytes += curve_id_bytes;
18592   command_size += curve_id_bytes.size();
18593   std::string command_hash(32, 0);
18594   hash->Finish(std::data(command_hash), command_hash.size());
18595   std::string authorization_section_bytes;
18596   std::string authorization_size_bytes;
18597   if (authorization_delegate) {
18598     if (!authorization_delegate->GetCommandAuthorization(
18599             command_hash, is_command_parameter_encryption_possible,
18600             is_response_parameter_encryption_possible,
18601             &authorization_section_bytes)) {
18602       return TRUNKS_RC_AUTHORIZATION_FAILED;
18603     }
18604     if (!authorization_section_bytes.empty()) {
18605       tag = TPM_ST_SESSIONS;
18606       std::string tmp;
18607       rc = Serialize_UINT32(authorization_section_bytes.size(),
18608                             &authorization_size_bytes);
18609       if (rc != TPM_RC_SUCCESS) {
18610         return rc;
18611       }
18612       command_size +=
18613           authorization_size_bytes.size() + authorization_section_bytes.size();
18614     }
18615   }
18616   std::string tag_bytes;
18617   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18618   if (rc != TPM_RC_SUCCESS) {
18619     return rc;
18620   }
18621   std::string command_size_bytes;
18622   rc = Serialize_UINT32(command_size, &command_size_bytes);
18623   if (rc != TPM_RC_SUCCESS) {
18624     return rc;
18625   }
18626   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18627                         handle_section_bytes + authorization_size_bytes +
18628                         authorization_section_bytes + parameter_section_bytes;
18629   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18630   VLOG(2) << "Command: "
18631           << base::HexEncode(serialized_command->data(),
18632                              serialized_command->size());
18633   return TPM_RC_SUCCESS;
18634 }
18635 
ParseResponse_EC_Ephemeral(const std::string & response,UINT32 * param_size_out,TPM2B_ECC_POINT * q,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18636 TPM_RC Tpm::ParseResponse_EC_Ephemeral(
18637     const std::string& response,
18638     UINT32* param_size_out,
18639     TPM2B_ECC_POINT* q,
18640     UINT16* counter,
18641     AuthorizationDelegate* authorization_delegate) {
18642   VLOG(3) << __func__;
18643   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18644   TPM_RC rc = TPM_RC_SUCCESS;
18645   std::string buffer(response);
18646   TPM_ST tag;
18647   std::string tag_bytes;
18648   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18649   if (rc != TPM_RC_SUCCESS) {
18650     return rc;
18651   }
18652   UINT32 response_size;
18653   std::string response_size_bytes;
18654   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18655   if (rc != TPM_RC_SUCCESS) {
18656     return rc;
18657   }
18658   TPM_RC response_code;
18659   std::string response_code_bytes;
18660   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18661   if (rc != TPM_RC_SUCCESS) {
18662     return rc;
18663   }
18664   if (response_size != response.size()) {
18665     return TPM_RC_SIZE;
18666   }
18667   if (response_code != TPM_RC_SUCCESS) {
18668     return response_code;
18669   }
18670   TPM_CC command_code = TPM_CC_EC_Ephemeral;
18671   std::string command_code_bytes;
18672   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18673   if (rc != TPM_RC_SUCCESS) {
18674     return rc;
18675   }
18676   std::string authorization_section_bytes;
18677   if (tag == TPM_ST_SESSIONS) {
18678     UINT32 parameter_section_size = buffer.size();
18679     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18680     if (rc != TPM_RC_SUCCESS) {
18681       return rc;
18682     }
18683     if (parameter_section_size > buffer.size()) {
18684       return TPM_RC_INSUFFICIENT;
18685     }
18686     authorization_section_bytes = buffer.substr(parameter_section_size);
18687     // Keep the parameter section in |buffer|.
18688     buffer.erase(parameter_section_size);
18689   }
18690   std::unique_ptr<crypto::SecureHash> hash(
18691       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18692   hash->Update(response_code_bytes.data(), response_code_bytes.size());
18693   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18694   hash->Update(buffer.data(), buffer.size());
18695   std::string response_hash(32, 0);
18696   hash->Finish(std::data(response_hash), response_hash.size());
18697   if (tag == TPM_ST_SESSIONS) {
18698     if (!authorization_delegate)
18699       return TRUNKS_RC_AUTHORIZATION_FAILED;
18700     if (!authorization_delegate->CheckResponseAuthorization(
18701             response_hash, authorization_section_bytes)) {
18702       return TRUNKS_RC_AUTHORIZATION_FAILED;
18703     }
18704   }
18705   std::string param_size_out_bytes;
18706   rc = Parse_UINT32(&buffer, param_size_out, &param_size_out_bytes);
18707   if (rc != TPM_RC_SUCCESS) {
18708     return rc;
18709   }
18710   std::string q_bytes;
18711   rc = Parse_TPM2B_ECC_POINT(&buffer, q, &q_bytes);
18712   if (rc != TPM_RC_SUCCESS) {
18713     return rc;
18714   }
18715   std::string counter_bytes;
18716   rc = Parse_UINT16(&buffer, counter, &counter_bytes);
18717   if (rc != TPM_RC_SUCCESS) {
18718     return rc;
18719   }
18720   return TPM_RC_SUCCESS;
18721 }
18722 
EC_EphemeralErrorCallback(Tpm::EC_EphemeralResponse callback,TPM_RC response_code)18723 void EC_EphemeralErrorCallback(Tpm::EC_EphemeralResponse callback,
18724                                TPM_RC response_code) {
18725   VLOG(1) << __func__;
18726   std::move(callback).Run(response_code, UINT32(), TPM2B_ECC_POINT(), UINT16());
18727 }
18728 
EC_EphemeralResponseParser(Tpm::EC_EphemeralResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18729 void EC_EphemeralResponseParser(Tpm::EC_EphemeralResponse callback,
18730                                 AuthorizationDelegate* authorization_delegate,
18731                                 const std::string& response) {
18732   VLOG(1) << __func__;
18733   UINT32 param_size_out;
18734   TPM2B_ECC_POINT q;
18735   UINT16 counter;
18736   TPM_RC rc = Tpm::ParseResponse_EC_Ephemeral(response, &param_size_out, &q,
18737                                               &counter, authorization_delegate);
18738   if (rc != TPM_RC_SUCCESS) {
18739     base::OnceCallback<void(TPM_RC)> error_reporter =
18740         base::BindOnce(EC_EphemeralErrorCallback, std::move(callback));
18741     std::move(error_reporter).Run(rc);
18742     return;
18743   }
18744   std::move(callback).Run(rc, param_size_out, q, counter);
18745 }
18746 
EC_Ephemeral(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,AuthorizationDelegate * authorization_delegate,EC_EphemeralResponse callback)18747 void Tpm::EC_Ephemeral(const UINT32& param_size,
18748                        const TPMI_ECC_CURVE& curve_id,
18749                        AuthorizationDelegate* authorization_delegate,
18750                        EC_EphemeralResponse callback) {
18751   VLOG(1) << __func__;
18752   std::string command;
18753   TPM_RC rc = SerializeCommand_EC_Ephemeral(param_size, curve_id, &command,
18754                                             authorization_delegate);
18755   if (rc != TPM_RC_SUCCESS) {
18756     base::OnceCallback<void(TPM_RC)> error_reporter =
18757         base::BindOnce(EC_EphemeralErrorCallback, std::move(callback));
18758     std::move(error_reporter).Run(rc);
18759     return;
18760   }
18761   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18762       EC_EphemeralResponseParser, std::move(callback), authorization_delegate);
18763   transceiver_->SendCommand(command, std::move(parser));
18764 }
18765 
EC_EphemeralSync(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,UINT32 * param_size_out,TPM2B_ECC_POINT * q,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18766 TPM_RC Tpm::EC_EphemeralSync(const UINT32& param_size,
18767                              const TPMI_ECC_CURVE& curve_id,
18768                              UINT32* param_size_out,
18769                              TPM2B_ECC_POINT* q,
18770                              UINT16* counter,
18771                              AuthorizationDelegate* authorization_delegate) {
18772   VLOG(1) << __func__;
18773   std::string command;
18774   TPM_RC rc = SerializeCommand_EC_Ephemeral(param_size, curve_id, &command,
18775                                             authorization_delegate);
18776   if (rc != TPM_RC_SUCCESS) {
18777     return rc;
18778   }
18779   std::string response = transceiver_->SendCommandAndWait(command);
18780   rc = ParseResponse_EC_Ephemeral(response, param_size_out, q, counter,
18781                                   authorization_delegate);
18782   return rc;
18783 }
18784 
SerializeCommand_VerifySignature(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIGNATURE & signature,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)18785 TPM_RC Tpm::SerializeCommand_VerifySignature(
18786     const TPMI_DH_OBJECT& key_handle,
18787     const std::string& key_handle_name,
18788     const TPM2B_DIGEST& digest,
18789     const TPMT_SIGNATURE& signature,
18790     std::string* serialized_command,
18791     AuthorizationDelegate* authorization_delegate) {
18792   VLOG(3) << __func__;
18793   TPM_RC rc = TPM_RC_SUCCESS;
18794   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18795   UINT32 command_size = 10;  // Header size.
18796   std::string handle_section_bytes;
18797   std::string parameter_section_bytes;
18798   TPM_CC command_code = TPM_CC_VerifySignature;
18799   bool is_command_parameter_encryption_possible = true;
18800   bool is_response_parameter_encryption_possible = false;
18801   std::string command_code_bytes;
18802   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18803   if (rc != TPM_RC_SUCCESS) {
18804     return rc;
18805   }
18806   std::string key_handle_bytes;
18807   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
18808   if (rc != TPM_RC_SUCCESS) {
18809     return rc;
18810   }
18811   std::string digest_bytes;
18812   rc = Serialize_TPM2B_DIGEST(digest, &digest_bytes);
18813   if (rc != TPM_RC_SUCCESS) {
18814     return rc;
18815   }
18816   std::string signature_bytes;
18817   rc = Serialize_TPMT_SIGNATURE(signature, &signature_bytes);
18818   if (rc != TPM_RC_SUCCESS) {
18819     return rc;
18820   }
18821   if (authorization_delegate) {
18822     // Encrypt just the parameter data, not the size.
18823     std::string tmp = digest_bytes.substr(2);
18824     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
18825       return TRUNKS_RC_ENCRYPTION_FAILED;
18826     }
18827     digest_bytes.replace(2, std::string::npos, tmp);
18828   }
18829   std::unique_ptr<crypto::SecureHash> hash(
18830       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18831   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18832   hash->Update(key_handle_name.data(), key_handle_name.size());
18833   handle_section_bytes += key_handle_bytes;
18834   command_size += key_handle_bytes.size();
18835   hash->Update(digest_bytes.data(), digest_bytes.size());
18836   parameter_section_bytes += digest_bytes;
18837   command_size += digest_bytes.size();
18838   hash->Update(signature_bytes.data(), signature_bytes.size());
18839   parameter_section_bytes += signature_bytes;
18840   command_size += signature_bytes.size();
18841   std::string command_hash(32, 0);
18842   hash->Finish(std::data(command_hash), command_hash.size());
18843   std::string authorization_section_bytes;
18844   std::string authorization_size_bytes;
18845   if (authorization_delegate) {
18846     if (!authorization_delegate->GetCommandAuthorization(
18847             command_hash, is_command_parameter_encryption_possible,
18848             is_response_parameter_encryption_possible,
18849             &authorization_section_bytes)) {
18850       return TRUNKS_RC_AUTHORIZATION_FAILED;
18851     }
18852     if (!authorization_section_bytes.empty()) {
18853       tag = TPM_ST_SESSIONS;
18854       std::string tmp;
18855       rc = Serialize_UINT32(authorization_section_bytes.size(),
18856                             &authorization_size_bytes);
18857       if (rc != TPM_RC_SUCCESS) {
18858         return rc;
18859       }
18860       command_size +=
18861           authorization_size_bytes.size() + authorization_section_bytes.size();
18862     }
18863   }
18864   std::string tag_bytes;
18865   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18866   if (rc != TPM_RC_SUCCESS) {
18867     return rc;
18868   }
18869   std::string command_size_bytes;
18870   rc = Serialize_UINT32(command_size, &command_size_bytes);
18871   if (rc != TPM_RC_SUCCESS) {
18872     return rc;
18873   }
18874   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18875                         handle_section_bytes + authorization_size_bytes +
18876                         authorization_section_bytes + parameter_section_bytes;
18877   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18878   VLOG(2) << "Command: "
18879           << base::HexEncode(serialized_command->data(),
18880                              serialized_command->size());
18881   return TPM_RC_SUCCESS;
18882 }
18883 
ParseResponse_VerifySignature(const std::string & response,TPMT_TK_VERIFIED * validation,AuthorizationDelegate * authorization_delegate)18884 TPM_RC Tpm::ParseResponse_VerifySignature(
18885     const std::string& response,
18886     TPMT_TK_VERIFIED* validation,
18887     AuthorizationDelegate* authorization_delegate) {
18888   VLOG(3) << __func__;
18889   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18890   TPM_RC rc = TPM_RC_SUCCESS;
18891   std::string buffer(response);
18892   TPM_ST tag;
18893   std::string tag_bytes;
18894   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18895   if (rc != TPM_RC_SUCCESS) {
18896     return rc;
18897   }
18898   UINT32 response_size;
18899   std::string response_size_bytes;
18900   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18901   if (rc != TPM_RC_SUCCESS) {
18902     return rc;
18903   }
18904   TPM_RC response_code;
18905   std::string response_code_bytes;
18906   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18907   if (rc != TPM_RC_SUCCESS) {
18908     return rc;
18909   }
18910   if (response_size != response.size()) {
18911     return TPM_RC_SIZE;
18912   }
18913   if (response_code != TPM_RC_SUCCESS) {
18914     return response_code;
18915   }
18916   TPM_CC command_code = TPM_CC_VerifySignature;
18917   std::string command_code_bytes;
18918   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18919   if (rc != TPM_RC_SUCCESS) {
18920     return rc;
18921   }
18922   std::string authorization_section_bytes;
18923   if (tag == TPM_ST_SESSIONS) {
18924     UINT32 parameter_section_size = buffer.size();
18925     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18926     if (rc != TPM_RC_SUCCESS) {
18927       return rc;
18928     }
18929     if (parameter_section_size > buffer.size()) {
18930       return TPM_RC_INSUFFICIENT;
18931     }
18932     authorization_section_bytes = buffer.substr(parameter_section_size);
18933     // Keep the parameter section in |buffer|.
18934     buffer.erase(parameter_section_size);
18935   }
18936   std::unique_ptr<crypto::SecureHash> hash(
18937       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18938   hash->Update(response_code_bytes.data(), response_code_bytes.size());
18939   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18940   hash->Update(buffer.data(), buffer.size());
18941   std::string response_hash(32, 0);
18942   hash->Finish(std::data(response_hash), response_hash.size());
18943   if (tag == TPM_ST_SESSIONS) {
18944     if (!authorization_delegate)
18945       return TRUNKS_RC_AUTHORIZATION_FAILED;
18946     if (!authorization_delegate->CheckResponseAuthorization(
18947             response_hash, authorization_section_bytes)) {
18948       return TRUNKS_RC_AUTHORIZATION_FAILED;
18949     }
18950   }
18951   std::string validation_bytes;
18952   rc = Parse_TPMT_TK_VERIFIED(&buffer, validation, &validation_bytes);
18953   if (rc != TPM_RC_SUCCESS) {
18954     return rc;
18955   }
18956   return TPM_RC_SUCCESS;
18957 }
18958 
VerifySignatureErrorCallback(Tpm::VerifySignatureResponse callback,TPM_RC response_code)18959 void VerifySignatureErrorCallback(Tpm::VerifySignatureResponse callback,
18960                                   TPM_RC response_code) {
18961   VLOG(1) << __func__;
18962   std::move(callback).Run(response_code, TPMT_TK_VERIFIED());
18963 }
18964 
VerifySignatureResponseParser(Tpm::VerifySignatureResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18965 void VerifySignatureResponseParser(
18966     Tpm::VerifySignatureResponse callback,
18967     AuthorizationDelegate* authorization_delegate,
18968     const std::string& response) {
18969   VLOG(1) << __func__;
18970   TPMT_TK_VERIFIED validation;
18971   TPM_RC rc = Tpm::ParseResponse_VerifySignature(response, &validation,
18972                                                  authorization_delegate);
18973   if (rc != TPM_RC_SUCCESS) {
18974     base::OnceCallback<void(TPM_RC)> error_reporter =
18975         base::BindOnce(VerifySignatureErrorCallback, std::move(callback));
18976     std::move(error_reporter).Run(rc);
18977     return;
18978   }
18979   std::move(callback).Run(rc, validation);
18980 }
18981 
VerifySignature(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIGNATURE & signature,AuthorizationDelegate * authorization_delegate,VerifySignatureResponse callback)18982 void Tpm::VerifySignature(const TPMI_DH_OBJECT& key_handle,
18983                           const std::string& key_handle_name,
18984                           const TPM2B_DIGEST& digest,
18985                           const TPMT_SIGNATURE& signature,
18986                           AuthorizationDelegate* authorization_delegate,
18987                           VerifySignatureResponse callback) {
18988   VLOG(1) << __func__;
18989   std::string command;
18990   TPM_RC rc = SerializeCommand_VerifySignature(key_handle, key_handle_name,
18991                                                digest, signature, &command,
18992                                                authorization_delegate);
18993   if (rc != TPM_RC_SUCCESS) {
18994     base::OnceCallback<void(TPM_RC)> error_reporter =
18995         base::BindOnce(VerifySignatureErrorCallback, std::move(callback));
18996     std::move(error_reporter).Run(rc);
18997     return;
18998   }
18999   base::OnceCallback<void(const std::string&)> parser =
19000       base::BindOnce(VerifySignatureResponseParser, std::move(callback),
19001                      authorization_delegate);
19002   transceiver_->SendCommand(command, std::move(parser));
19003 }
19004 
VerifySignatureSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIGNATURE & signature,TPMT_TK_VERIFIED * validation,AuthorizationDelegate * authorization_delegate)19005 TPM_RC Tpm::VerifySignatureSync(const TPMI_DH_OBJECT& key_handle,
19006                                 const std::string& key_handle_name,
19007                                 const TPM2B_DIGEST& digest,
19008                                 const TPMT_SIGNATURE& signature,
19009                                 TPMT_TK_VERIFIED* validation,
19010                                 AuthorizationDelegate* authorization_delegate) {
19011   VLOG(1) << __func__;
19012   std::string command;
19013   TPM_RC rc = SerializeCommand_VerifySignature(key_handle, key_handle_name,
19014                                                digest, signature, &command,
19015                                                authorization_delegate);
19016   if (rc != TPM_RC_SUCCESS) {
19017     return rc;
19018   }
19019   std::string response = transceiver_->SendCommandAndWait(command);
19020   rc = ParseResponse_VerifySignature(response, validation,
19021                                      authorization_delegate);
19022   return rc;
19023 }
19024 
SerializeCommand_Sign(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_HASHCHECK & validation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19025 TPM_RC Tpm::SerializeCommand_Sign(
19026     const TPMI_DH_OBJECT& key_handle,
19027     const std::string& key_handle_name,
19028     const TPM2B_DIGEST& digest,
19029     const TPMT_SIG_SCHEME& in_scheme,
19030     const TPMT_TK_HASHCHECK& validation,
19031     std::string* serialized_command,
19032     AuthorizationDelegate* authorization_delegate) {
19033   VLOG(3) << __func__;
19034   TPM_RC rc = TPM_RC_SUCCESS;
19035   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19036   UINT32 command_size = 10;  // Header size.
19037   std::string handle_section_bytes;
19038   std::string parameter_section_bytes;
19039   TPM_CC command_code = TPM_CC_Sign;
19040   bool is_command_parameter_encryption_possible = true;
19041   bool is_response_parameter_encryption_possible = false;
19042   std::string command_code_bytes;
19043   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19044   if (rc != TPM_RC_SUCCESS) {
19045     return rc;
19046   }
19047   std::string key_handle_bytes;
19048   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
19049   if (rc != TPM_RC_SUCCESS) {
19050     return rc;
19051   }
19052   std::string digest_bytes;
19053   rc = Serialize_TPM2B_DIGEST(digest, &digest_bytes);
19054   if (rc != TPM_RC_SUCCESS) {
19055     return rc;
19056   }
19057   std::string in_scheme_bytes;
19058   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
19059   if (rc != TPM_RC_SUCCESS) {
19060     return rc;
19061   }
19062   std::string validation_bytes;
19063   rc = Serialize_TPMT_TK_HASHCHECK(validation, &validation_bytes);
19064   if (rc != TPM_RC_SUCCESS) {
19065     return rc;
19066   }
19067   if (authorization_delegate) {
19068     // Encrypt just the parameter data, not the size.
19069     std::string tmp = digest_bytes.substr(2);
19070     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
19071       return TRUNKS_RC_ENCRYPTION_FAILED;
19072     }
19073     digest_bytes.replace(2, std::string::npos, tmp);
19074   }
19075   std::unique_ptr<crypto::SecureHash> hash(
19076       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19077   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19078   hash->Update(key_handle_name.data(), key_handle_name.size());
19079   handle_section_bytes += key_handle_bytes;
19080   command_size += key_handle_bytes.size();
19081   hash->Update(digest_bytes.data(), digest_bytes.size());
19082   parameter_section_bytes += digest_bytes;
19083   command_size += digest_bytes.size();
19084   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
19085   parameter_section_bytes += in_scheme_bytes;
19086   command_size += in_scheme_bytes.size();
19087   hash->Update(validation_bytes.data(), validation_bytes.size());
19088   parameter_section_bytes += validation_bytes;
19089   command_size += validation_bytes.size();
19090   std::string command_hash(32, 0);
19091   hash->Finish(std::data(command_hash), command_hash.size());
19092   std::string authorization_section_bytes;
19093   std::string authorization_size_bytes;
19094   if (authorization_delegate) {
19095     if (!authorization_delegate->GetCommandAuthorization(
19096             command_hash, is_command_parameter_encryption_possible,
19097             is_response_parameter_encryption_possible,
19098             &authorization_section_bytes)) {
19099       return TRUNKS_RC_AUTHORIZATION_FAILED;
19100     }
19101     if (!authorization_section_bytes.empty()) {
19102       tag = TPM_ST_SESSIONS;
19103       std::string tmp;
19104       rc = Serialize_UINT32(authorization_section_bytes.size(),
19105                             &authorization_size_bytes);
19106       if (rc != TPM_RC_SUCCESS) {
19107         return rc;
19108       }
19109       command_size +=
19110           authorization_size_bytes.size() + authorization_section_bytes.size();
19111     }
19112   }
19113   std::string tag_bytes;
19114   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19115   if (rc != TPM_RC_SUCCESS) {
19116     return rc;
19117   }
19118   std::string command_size_bytes;
19119   rc = Serialize_UINT32(command_size, &command_size_bytes);
19120   if (rc != TPM_RC_SUCCESS) {
19121     return rc;
19122   }
19123   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19124                         handle_section_bytes + authorization_size_bytes +
19125                         authorization_section_bytes + parameter_section_bytes;
19126   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19127   VLOG(2) << "Command: "
19128           << base::HexEncode(serialized_command->data(),
19129                              serialized_command->size());
19130   return TPM_RC_SUCCESS;
19131 }
19132 
ParseResponse_Sign(const std::string & response,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)19133 TPM_RC Tpm::ParseResponse_Sign(const std::string& response,
19134                                TPMT_SIGNATURE* signature,
19135                                AuthorizationDelegate* authorization_delegate) {
19136   VLOG(3) << __func__;
19137   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19138   TPM_RC rc = TPM_RC_SUCCESS;
19139   std::string buffer(response);
19140   TPM_ST tag;
19141   std::string tag_bytes;
19142   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19143   if (rc != TPM_RC_SUCCESS) {
19144     return rc;
19145   }
19146   UINT32 response_size;
19147   std::string response_size_bytes;
19148   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19149   if (rc != TPM_RC_SUCCESS) {
19150     return rc;
19151   }
19152   TPM_RC response_code;
19153   std::string response_code_bytes;
19154   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19155   if (rc != TPM_RC_SUCCESS) {
19156     return rc;
19157   }
19158   if (response_size != response.size()) {
19159     return TPM_RC_SIZE;
19160   }
19161   if (response_code != TPM_RC_SUCCESS) {
19162     return response_code;
19163   }
19164   TPM_CC command_code = TPM_CC_Sign;
19165   std::string command_code_bytes;
19166   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19167   if (rc != TPM_RC_SUCCESS) {
19168     return rc;
19169   }
19170   std::string authorization_section_bytes;
19171   if (tag == TPM_ST_SESSIONS) {
19172     UINT32 parameter_section_size = buffer.size();
19173     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19174     if (rc != TPM_RC_SUCCESS) {
19175       return rc;
19176     }
19177     if (parameter_section_size > buffer.size()) {
19178       return TPM_RC_INSUFFICIENT;
19179     }
19180     authorization_section_bytes = buffer.substr(parameter_section_size);
19181     // Keep the parameter section in |buffer|.
19182     buffer.erase(parameter_section_size);
19183   }
19184   std::unique_ptr<crypto::SecureHash> hash(
19185       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19186   hash->Update(response_code_bytes.data(), response_code_bytes.size());
19187   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19188   hash->Update(buffer.data(), buffer.size());
19189   std::string response_hash(32, 0);
19190   hash->Finish(std::data(response_hash), response_hash.size());
19191   if (tag == TPM_ST_SESSIONS) {
19192     if (!authorization_delegate)
19193       return TRUNKS_RC_AUTHORIZATION_FAILED;
19194     if (!authorization_delegate->CheckResponseAuthorization(
19195             response_hash, authorization_section_bytes)) {
19196       return TRUNKS_RC_AUTHORIZATION_FAILED;
19197     }
19198   }
19199   std::string signature_bytes;
19200   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
19201   if (rc != TPM_RC_SUCCESS) {
19202     return rc;
19203   }
19204   return TPM_RC_SUCCESS;
19205 }
19206 
SignErrorCallback(Tpm::SignResponse callback,TPM_RC response_code)19207 void SignErrorCallback(Tpm::SignResponse callback, TPM_RC response_code) {
19208   VLOG(1) << __func__;
19209   std::move(callback).Run(response_code, TPMT_SIGNATURE());
19210 }
19211 
SignResponseParser(Tpm::SignResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19212 void SignResponseParser(Tpm::SignResponse callback,
19213                         AuthorizationDelegate* authorization_delegate,
19214                         const std::string& response) {
19215   VLOG(1) << __func__;
19216   TPMT_SIGNATURE signature;
19217   TPM_RC rc =
19218       Tpm::ParseResponse_Sign(response, &signature, authorization_delegate);
19219   if (rc != TPM_RC_SUCCESS) {
19220     base::OnceCallback<void(TPM_RC)> error_reporter =
19221         base::BindOnce(SignErrorCallback, std::move(callback));
19222     std::move(error_reporter).Run(rc);
19223     return;
19224   }
19225   std::move(callback).Run(rc, signature);
19226 }
19227 
Sign(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_HASHCHECK & validation,AuthorizationDelegate * authorization_delegate,SignResponse callback)19228 void Tpm::Sign(const TPMI_DH_OBJECT& key_handle,
19229                const std::string& key_handle_name,
19230                const TPM2B_DIGEST& digest,
19231                const TPMT_SIG_SCHEME& in_scheme,
19232                const TPMT_TK_HASHCHECK& validation,
19233                AuthorizationDelegate* authorization_delegate,
19234                SignResponse callback) {
19235   VLOG(1) << __func__;
19236   std::string command;
19237   TPM_RC rc =
19238       SerializeCommand_Sign(key_handle, key_handle_name, digest, in_scheme,
19239                             validation, &command, authorization_delegate);
19240   if (rc != TPM_RC_SUCCESS) {
19241     base::OnceCallback<void(TPM_RC)> error_reporter =
19242         base::BindOnce(SignErrorCallback, std::move(callback));
19243     std::move(error_reporter).Run(rc);
19244     return;
19245   }
19246   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19247       SignResponseParser, std::move(callback), authorization_delegate);
19248   transceiver_->SendCommand(command, std::move(parser));
19249 }
19250 
SignSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_HASHCHECK & validation,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)19251 TPM_RC Tpm::SignSync(const TPMI_DH_OBJECT& key_handle,
19252                      const std::string& key_handle_name,
19253                      const TPM2B_DIGEST& digest,
19254                      const TPMT_SIG_SCHEME& in_scheme,
19255                      const TPMT_TK_HASHCHECK& validation,
19256                      TPMT_SIGNATURE* signature,
19257                      AuthorizationDelegate* authorization_delegate) {
19258   VLOG(1) << __func__;
19259   std::string command;
19260   TPM_RC rc =
19261       SerializeCommand_Sign(key_handle, key_handle_name, digest, in_scheme,
19262                             validation, &command, authorization_delegate);
19263   if (rc != TPM_RC_SUCCESS) {
19264     return rc;
19265   }
19266   std::string response = transceiver_->SendCommandAndWait(command);
19267   rc = ParseResponse_Sign(response, signature, authorization_delegate);
19268   return rc;
19269 }
19270 
SerializeCommand_SetCommandCodeAuditStatus(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_ALG_HASH & audit_alg,const TPML_CC & set_list,const TPML_CC & clear_list,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19271 TPM_RC Tpm::SerializeCommand_SetCommandCodeAuditStatus(
19272     const TPMI_RH_PROVISION& auth,
19273     const std::string& auth_name,
19274     const TPMI_ALG_HASH& audit_alg,
19275     const TPML_CC& set_list,
19276     const TPML_CC& clear_list,
19277     std::string* serialized_command,
19278     AuthorizationDelegate* authorization_delegate) {
19279   VLOG(3) << __func__;
19280   TPM_RC rc = TPM_RC_SUCCESS;
19281   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19282   UINT32 command_size = 10;  // Header size.
19283   std::string handle_section_bytes;
19284   std::string parameter_section_bytes;
19285   TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus;
19286   bool is_command_parameter_encryption_possible = false;
19287   bool is_response_parameter_encryption_possible = false;
19288   std::string command_code_bytes;
19289   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19290   if (rc != TPM_RC_SUCCESS) {
19291     return rc;
19292   }
19293   std::string auth_bytes;
19294   rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
19295   if (rc != TPM_RC_SUCCESS) {
19296     return rc;
19297   }
19298   std::string audit_alg_bytes;
19299   rc = Serialize_TPMI_ALG_HASH(audit_alg, &audit_alg_bytes);
19300   if (rc != TPM_RC_SUCCESS) {
19301     return rc;
19302   }
19303   std::string set_list_bytes;
19304   rc = Serialize_TPML_CC(set_list, &set_list_bytes);
19305   if (rc != TPM_RC_SUCCESS) {
19306     return rc;
19307   }
19308   std::string clear_list_bytes;
19309   rc = Serialize_TPML_CC(clear_list, &clear_list_bytes);
19310   if (rc != TPM_RC_SUCCESS) {
19311     return rc;
19312   }
19313   std::unique_ptr<crypto::SecureHash> hash(
19314       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19315   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19316   hash->Update(auth_name.data(), auth_name.size());
19317   handle_section_bytes += auth_bytes;
19318   command_size += auth_bytes.size();
19319   hash->Update(audit_alg_bytes.data(), audit_alg_bytes.size());
19320   parameter_section_bytes += audit_alg_bytes;
19321   command_size += audit_alg_bytes.size();
19322   hash->Update(set_list_bytes.data(), set_list_bytes.size());
19323   parameter_section_bytes += set_list_bytes;
19324   command_size += set_list_bytes.size();
19325   hash->Update(clear_list_bytes.data(), clear_list_bytes.size());
19326   parameter_section_bytes += clear_list_bytes;
19327   command_size += clear_list_bytes.size();
19328   std::string command_hash(32, 0);
19329   hash->Finish(std::data(command_hash), command_hash.size());
19330   std::string authorization_section_bytes;
19331   std::string authorization_size_bytes;
19332   if (authorization_delegate) {
19333     if (!authorization_delegate->GetCommandAuthorization(
19334             command_hash, is_command_parameter_encryption_possible,
19335             is_response_parameter_encryption_possible,
19336             &authorization_section_bytes)) {
19337       return TRUNKS_RC_AUTHORIZATION_FAILED;
19338     }
19339     if (!authorization_section_bytes.empty()) {
19340       tag = TPM_ST_SESSIONS;
19341       std::string tmp;
19342       rc = Serialize_UINT32(authorization_section_bytes.size(),
19343                             &authorization_size_bytes);
19344       if (rc != TPM_RC_SUCCESS) {
19345         return rc;
19346       }
19347       command_size +=
19348           authorization_size_bytes.size() + authorization_section_bytes.size();
19349     }
19350   }
19351   std::string tag_bytes;
19352   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19353   if (rc != TPM_RC_SUCCESS) {
19354     return rc;
19355   }
19356   std::string command_size_bytes;
19357   rc = Serialize_UINT32(command_size, &command_size_bytes);
19358   if (rc != TPM_RC_SUCCESS) {
19359     return rc;
19360   }
19361   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19362                         handle_section_bytes + authorization_size_bytes +
19363                         authorization_section_bytes + parameter_section_bytes;
19364   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19365   VLOG(2) << "Command: "
19366           << base::HexEncode(serialized_command->data(),
19367                              serialized_command->size());
19368   return TPM_RC_SUCCESS;
19369 }
19370 
ParseResponse_SetCommandCodeAuditStatus(const std::string & response,AuthorizationDelegate * authorization_delegate)19371 TPM_RC Tpm::ParseResponse_SetCommandCodeAuditStatus(
19372     const std::string& response,
19373     AuthorizationDelegate* authorization_delegate) {
19374   VLOG(3) << __func__;
19375   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19376   TPM_RC rc = TPM_RC_SUCCESS;
19377   std::string buffer(response);
19378   TPM_ST tag;
19379   std::string tag_bytes;
19380   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19381   if (rc != TPM_RC_SUCCESS) {
19382     return rc;
19383   }
19384   UINT32 response_size;
19385   std::string response_size_bytes;
19386   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19387   if (rc != TPM_RC_SUCCESS) {
19388     return rc;
19389   }
19390   TPM_RC response_code;
19391   std::string response_code_bytes;
19392   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19393   if (rc != TPM_RC_SUCCESS) {
19394     return rc;
19395   }
19396   if (response_size != response.size()) {
19397     return TPM_RC_SIZE;
19398   }
19399   if (response_code != TPM_RC_SUCCESS) {
19400     return response_code;
19401   }
19402   TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus;
19403   std::string command_code_bytes;
19404   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19405   if (rc != TPM_RC_SUCCESS) {
19406     return rc;
19407   }
19408   std::string authorization_section_bytes;
19409   if (tag == TPM_ST_SESSIONS) {
19410     UINT32 parameter_section_size = buffer.size();
19411     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19412     if (rc != TPM_RC_SUCCESS) {
19413       return rc;
19414     }
19415     if (parameter_section_size > buffer.size()) {
19416       return TPM_RC_INSUFFICIENT;
19417     }
19418     authorization_section_bytes = buffer.substr(parameter_section_size);
19419     // Keep the parameter section in |buffer|.
19420     buffer.erase(parameter_section_size);
19421   }
19422   std::unique_ptr<crypto::SecureHash> hash(
19423       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19424   hash->Update(response_code_bytes.data(), response_code_bytes.size());
19425   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19426   hash->Update(buffer.data(), buffer.size());
19427   std::string response_hash(32, 0);
19428   hash->Finish(std::data(response_hash), response_hash.size());
19429   if (tag == TPM_ST_SESSIONS) {
19430     if (!authorization_delegate)
19431       return TRUNKS_RC_AUTHORIZATION_FAILED;
19432     if (!authorization_delegate->CheckResponseAuthorization(
19433             response_hash, authorization_section_bytes)) {
19434       return TRUNKS_RC_AUTHORIZATION_FAILED;
19435     }
19436   }
19437   return TPM_RC_SUCCESS;
19438 }
19439 
SetCommandCodeAuditStatusErrorCallback(Tpm::SetCommandCodeAuditStatusResponse callback,TPM_RC response_code)19440 void SetCommandCodeAuditStatusErrorCallback(
19441     Tpm::SetCommandCodeAuditStatusResponse callback, TPM_RC response_code) {
19442   VLOG(1) << __func__;
19443   std::move(callback).Run(response_code);
19444 }
19445 
SetCommandCodeAuditStatusResponseParser(Tpm::SetCommandCodeAuditStatusResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19446 void SetCommandCodeAuditStatusResponseParser(
19447     Tpm::SetCommandCodeAuditStatusResponse callback,
19448     AuthorizationDelegate* authorization_delegate,
19449     const std::string& response) {
19450   VLOG(1) << __func__;
19451   TPM_RC rc = Tpm::ParseResponse_SetCommandCodeAuditStatus(
19452       response, authorization_delegate);
19453   if (rc != TPM_RC_SUCCESS) {
19454     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
19455         SetCommandCodeAuditStatusErrorCallback, std::move(callback));
19456     std::move(error_reporter).Run(rc);
19457     return;
19458   }
19459   std::move(callback).Run(rc);
19460 }
19461 
SetCommandCodeAuditStatus(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_ALG_HASH & audit_alg,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate,SetCommandCodeAuditStatusResponse callback)19462 void Tpm::SetCommandCodeAuditStatus(
19463     const TPMI_RH_PROVISION& auth,
19464     const std::string& auth_name,
19465     const TPMI_ALG_HASH& audit_alg,
19466     const TPML_CC& set_list,
19467     const TPML_CC& clear_list,
19468     AuthorizationDelegate* authorization_delegate,
19469     SetCommandCodeAuditStatusResponse callback) {
19470   VLOG(1) << __func__;
19471   std::string command;
19472   TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus(
19473       auth, auth_name, audit_alg, set_list, clear_list, &command,
19474       authorization_delegate);
19475   if (rc != TPM_RC_SUCCESS) {
19476     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
19477         SetCommandCodeAuditStatusErrorCallback, std::move(callback));
19478     std::move(error_reporter).Run(rc);
19479     return;
19480   }
19481   base::OnceCallback<void(const std::string&)> parser =
19482       base::BindOnce(SetCommandCodeAuditStatusResponseParser,
19483                      std::move(callback), authorization_delegate);
19484   transceiver_->SendCommand(command, std::move(parser));
19485 }
19486 
SetCommandCodeAuditStatusSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_ALG_HASH & audit_alg,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate)19487 TPM_RC Tpm::SetCommandCodeAuditStatusSync(
19488     const TPMI_RH_PROVISION& auth,
19489     const std::string& auth_name,
19490     const TPMI_ALG_HASH& audit_alg,
19491     const TPML_CC& set_list,
19492     const TPML_CC& clear_list,
19493     AuthorizationDelegate* authorization_delegate) {
19494   VLOG(1) << __func__;
19495   std::string command;
19496   TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus(
19497       auth, auth_name, audit_alg, set_list, clear_list, &command,
19498       authorization_delegate);
19499   if (rc != TPM_RC_SUCCESS) {
19500     return rc;
19501   }
19502   std::string response = transceiver_->SendCommandAndWait(command);
19503   rc =
19504       ParseResponse_SetCommandCodeAuditStatus(response, authorization_delegate);
19505   return rc;
19506 }
19507 
SerializeCommand_PCR_Extend(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPML_DIGEST_VALUES & digests,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19508 TPM_RC Tpm::SerializeCommand_PCR_Extend(
19509     const TPMI_DH_PCR& pcr_handle,
19510     const std::string& pcr_handle_name,
19511     const TPML_DIGEST_VALUES& digests,
19512     std::string* serialized_command,
19513     AuthorizationDelegate* authorization_delegate) {
19514   VLOG(3) << __func__;
19515   TPM_RC rc = TPM_RC_SUCCESS;
19516   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19517   UINT32 command_size = 10;  // Header size.
19518   std::string handle_section_bytes;
19519   std::string parameter_section_bytes;
19520   TPM_CC command_code = TPM_CC_PCR_Extend;
19521   bool is_command_parameter_encryption_possible = false;
19522   bool is_response_parameter_encryption_possible = false;
19523   std::string command_code_bytes;
19524   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19525   if (rc != TPM_RC_SUCCESS) {
19526     return rc;
19527   }
19528   std::string pcr_handle_bytes;
19529   rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
19530   if (rc != TPM_RC_SUCCESS) {
19531     return rc;
19532   }
19533   std::string digests_bytes;
19534   rc = Serialize_TPML_DIGEST_VALUES(digests, &digests_bytes);
19535   if (rc != TPM_RC_SUCCESS) {
19536     return rc;
19537   }
19538   std::unique_ptr<crypto::SecureHash> hash(
19539       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19540   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19541   hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
19542   handle_section_bytes += pcr_handle_bytes;
19543   command_size += pcr_handle_bytes.size();
19544   hash->Update(digests_bytes.data(), digests_bytes.size());
19545   parameter_section_bytes += digests_bytes;
19546   command_size += digests_bytes.size();
19547   std::string command_hash(32, 0);
19548   hash->Finish(std::data(command_hash), command_hash.size());
19549   std::string authorization_section_bytes;
19550   std::string authorization_size_bytes;
19551   if (authorization_delegate) {
19552     if (!authorization_delegate->GetCommandAuthorization(
19553             command_hash, is_command_parameter_encryption_possible,
19554             is_response_parameter_encryption_possible,
19555             &authorization_section_bytes)) {
19556       return TRUNKS_RC_AUTHORIZATION_FAILED;
19557     }
19558     if (!authorization_section_bytes.empty()) {
19559       tag = TPM_ST_SESSIONS;
19560       std::string tmp;
19561       rc = Serialize_UINT32(authorization_section_bytes.size(),
19562                             &authorization_size_bytes);
19563       if (rc != TPM_RC_SUCCESS) {
19564         return rc;
19565       }
19566       command_size +=
19567           authorization_size_bytes.size() + authorization_section_bytes.size();
19568     }
19569   }
19570   std::string tag_bytes;
19571   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19572   if (rc != TPM_RC_SUCCESS) {
19573     return rc;
19574   }
19575   std::string command_size_bytes;
19576   rc = Serialize_UINT32(command_size, &command_size_bytes);
19577   if (rc != TPM_RC_SUCCESS) {
19578     return rc;
19579   }
19580   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19581                         handle_section_bytes + authorization_size_bytes +
19582                         authorization_section_bytes + parameter_section_bytes;
19583   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19584   VLOG(2) << "Command: "
19585           << base::HexEncode(serialized_command->data(),
19586                              serialized_command->size());
19587   return TPM_RC_SUCCESS;
19588 }
19589 
ParseResponse_PCR_Extend(const std::string & response,AuthorizationDelegate * authorization_delegate)19590 TPM_RC Tpm::ParseResponse_PCR_Extend(
19591     const std::string& response,
19592     AuthorizationDelegate* authorization_delegate) {
19593   VLOG(3) << __func__;
19594   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19595   TPM_RC rc = TPM_RC_SUCCESS;
19596   std::string buffer(response);
19597   TPM_ST tag;
19598   std::string tag_bytes;
19599   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19600   if (rc != TPM_RC_SUCCESS) {
19601     return rc;
19602   }
19603   UINT32 response_size;
19604   std::string response_size_bytes;
19605   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19606   if (rc != TPM_RC_SUCCESS) {
19607     return rc;
19608   }
19609   TPM_RC response_code;
19610   std::string response_code_bytes;
19611   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19612   if (rc != TPM_RC_SUCCESS) {
19613     return rc;
19614   }
19615   if (response_size != response.size()) {
19616     return TPM_RC_SIZE;
19617   }
19618   if (response_code != TPM_RC_SUCCESS) {
19619     return response_code;
19620   }
19621   TPM_CC command_code = TPM_CC_PCR_Extend;
19622   std::string command_code_bytes;
19623   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19624   if (rc != TPM_RC_SUCCESS) {
19625     return rc;
19626   }
19627   std::string authorization_section_bytes;
19628   if (tag == TPM_ST_SESSIONS) {
19629     UINT32 parameter_section_size = buffer.size();
19630     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19631     if (rc != TPM_RC_SUCCESS) {
19632       return rc;
19633     }
19634     if (parameter_section_size > buffer.size()) {
19635       return TPM_RC_INSUFFICIENT;
19636     }
19637     authorization_section_bytes = buffer.substr(parameter_section_size);
19638     // Keep the parameter section in |buffer|.
19639     buffer.erase(parameter_section_size);
19640   }
19641   std::unique_ptr<crypto::SecureHash> hash(
19642       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19643   hash->Update(response_code_bytes.data(), response_code_bytes.size());
19644   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19645   hash->Update(buffer.data(), buffer.size());
19646   std::string response_hash(32, 0);
19647   hash->Finish(std::data(response_hash), response_hash.size());
19648   if (tag == TPM_ST_SESSIONS) {
19649     if (!authorization_delegate)
19650       return TRUNKS_RC_AUTHORIZATION_FAILED;
19651     if (!authorization_delegate->CheckResponseAuthorization(
19652             response_hash, authorization_section_bytes)) {
19653       return TRUNKS_RC_AUTHORIZATION_FAILED;
19654     }
19655   }
19656   return TPM_RC_SUCCESS;
19657 }
19658 
PCR_ExtendErrorCallback(Tpm::PCR_ExtendResponse callback,TPM_RC response_code)19659 void PCR_ExtendErrorCallback(Tpm::PCR_ExtendResponse callback,
19660                              TPM_RC response_code) {
19661   VLOG(1) << __func__;
19662   std::move(callback).Run(response_code);
19663 }
19664 
PCR_ExtendResponseParser(Tpm::PCR_ExtendResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19665 void PCR_ExtendResponseParser(Tpm::PCR_ExtendResponse callback,
19666                               AuthorizationDelegate* authorization_delegate,
19667                               const std::string& response) {
19668   VLOG(1) << __func__;
19669   TPM_RC rc = Tpm::ParseResponse_PCR_Extend(response, authorization_delegate);
19670   if (rc != TPM_RC_SUCCESS) {
19671     base::OnceCallback<void(TPM_RC)> error_reporter =
19672         base::BindOnce(PCR_ExtendErrorCallback, std::move(callback));
19673     std::move(error_reporter).Run(rc);
19674     return;
19675   }
19676   std::move(callback).Run(rc);
19677 }
19678 
PCR_Extend(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPML_DIGEST_VALUES & digests,AuthorizationDelegate * authorization_delegate,PCR_ExtendResponse callback)19679 void Tpm::PCR_Extend(const TPMI_DH_PCR& pcr_handle,
19680                      const std::string& pcr_handle_name,
19681                      const TPML_DIGEST_VALUES& digests,
19682                      AuthorizationDelegate* authorization_delegate,
19683                      PCR_ExtendResponse callback) {
19684   VLOG(1) << __func__;
19685   std::string command;
19686   TPM_RC rc = SerializeCommand_PCR_Extend(pcr_handle, pcr_handle_name, digests,
19687                                           &command, authorization_delegate);
19688   if (rc != TPM_RC_SUCCESS) {
19689     base::OnceCallback<void(TPM_RC)> error_reporter =
19690         base::BindOnce(PCR_ExtendErrorCallback, std::move(callback));
19691     std::move(error_reporter).Run(rc);
19692     return;
19693   }
19694   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19695       PCR_ExtendResponseParser, std::move(callback), authorization_delegate);
19696   transceiver_->SendCommand(command, std::move(parser));
19697 }
19698 
PCR_ExtendSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPML_DIGEST_VALUES & digests,AuthorizationDelegate * authorization_delegate)19699 TPM_RC Tpm::PCR_ExtendSync(const TPMI_DH_PCR& pcr_handle,
19700                            const std::string& pcr_handle_name,
19701                            const TPML_DIGEST_VALUES& digests,
19702                            AuthorizationDelegate* authorization_delegate) {
19703   VLOG(1) << __func__;
19704   std::string command;
19705   TPM_RC rc = SerializeCommand_PCR_Extend(pcr_handle, pcr_handle_name, digests,
19706                                           &command, authorization_delegate);
19707   if (rc != TPM_RC_SUCCESS) {
19708     return rc;
19709   }
19710   std::string response = transceiver_->SendCommandAndWait(command);
19711   rc = ParseResponse_PCR_Extend(response, authorization_delegate);
19712   return rc;
19713 }
19714 
SerializeCommand_PCR_Event(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_EVENT & event_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19715 TPM_RC Tpm::SerializeCommand_PCR_Event(
19716     const TPMI_DH_PCR& pcr_handle,
19717     const std::string& pcr_handle_name,
19718     const TPM2B_EVENT& event_data,
19719     std::string* serialized_command,
19720     AuthorizationDelegate* authorization_delegate) {
19721   VLOG(3) << __func__;
19722   TPM_RC rc = TPM_RC_SUCCESS;
19723   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19724   UINT32 command_size = 10;  // Header size.
19725   std::string handle_section_bytes;
19726   std::string parameter_section_bytes;
19727   TPM_CC command_code = TPM_CC_PCR_Event;
19728   bool is_command_parameter_encryption_possible = true;
19729   bool is_response_parameter_encryption_possible = false;
19730   std::string command_code_bytes;
19731   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19732   if (rc != TPM_RC_SUCCESS) {
19733     return rc;
19734   }
19735   std::string pcr_handle_bytes;
19736   rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
19737   if (rc != TPM_RC_SUCCESS) {
19738     return rc;
19739   }
19740   std::string event_data_bytes;
19741   rc = Serialize_TPM2B_EVENT(event_data, &event_data_bytes);
19742   if (rc != TPM_RC_SUCCESS) {
19743     return rc;
19744   }
19745   if (authorization_delegate) {
19746     // Encrypt just the parameter data, not the size.
19747     std::string tmp = event_data_bytes.substr(2);
19748     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
19749       return TRUNKS_RC_ENCRYPTION_FAILED;
19750     }
19751     event_data_bytes.replace(2, std::string::npos, tmp);
19752   }
19753   std::unique_ptr<crypto::SecureHash> hash(
19754       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19755   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19756   hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
19757   handle_section_bytes += pcr_handle_bytes;
19758   command_size += pcr_handle_bytes.size();
19759   hash->Update(event_data_bytes.data(), event_data_bytes.size());
19760   parameter_section_bytes += event_data_bytes;
19761   command_size += event_data_bytes.size();
19762   std::string command_hash(32, 0);
19763   hash->Finish(std::data(command_hash), command_hash.size());
19764   std::string authorization_section_bytes;
19765   std::string authorization_size_bytes;
19766   if (authorization_delegate) {
19767     if (!authorization_delegate->GetCommandAuthorization(
19768             command_hash, is_command_parameter_encryption_possible,
19769             is_response_parameter_encryption_possible,
19770             &authorization_section_bytes)) {
19771       return TRUNKS_RC_AUTHORIZATION_FAILED;
19772     }
19773     if (!authorization_section_bytes.empty()) {
19774       tag = TPM_ST_SESSIONS;
19775       std::string tmp;
19776       rc = Serialize_UINT32(authorization_section_bytes.size(),
19777                             &authorization_size_bytes);
19778       if (rc != TPM_RC_SUCCESS) {
19779         return rc;
19780       }
19781       command_size +=
19782           authorization_size_bytes.size() + authorization_section_bytes.size();
19783     }
19784   }
19785   std::string tag_bytes;
19786   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19787   if (rc != TPM_RC_SUCCESS) {
19788     return rc;
19789   }
19790   std::string command_size_bytes;
19791   rc = Serialize_UINT32(command_size, &command_size_bytes);
19792   if (rc != TPM_RC_SUCCESS) {
19793     return rc;
19794   }
19795   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19796                         handle_section_bytes + authorization_size_bytes +
19797                         authorization_section_bytes + parameter_section_bytes;
19798   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19799   VLOG(2) << "Command: "
19800           << base::HexEncode(serialized_command->data(),
19801                              serialized_command->size());
19802   return TPM_RC_SUCCESS;
19803 }
19804 
ParseResponse_PCR_Event(const std::string & response,TPML_DIGEST_VALUES * digests,AuthorizationDelegate * authorization_delegate)19805 TPM_RC Tpm::ParseResponse_PCR_Event(
19806     const std::string& response,
19807     TPML_DIGEST_VALUES* digests,
19808     AuthorizationDelegate* authorization_delegate) {
19809   VLOG(3) << __func__;
19810   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19811   TPM_RC rc = TPM_RC_SUCCESS;
19812   std::string buffer(response);
19813   TPM_ST tag;
19814   std::string tag_bytes;
19815   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19816   if (rc != TPM_RC_SUCCESS) {
19817     return rc;
19818   }
19819   UINT32 response_size;
19820   std::string response_size_bytes;
19821   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19822   if (rc != TPM_RC_SUCCESS) {
19823     return rc;
19824   }
19825   TPM_RC response_code;
19826   std::string response_code_bytes;
19827   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19828   if (rc != TPM_RC_SUCCESS) {
19829     return rc;
19830   }
19831   if (response_size != response.size()) {
19832     return TPM_RC_SIZE;
19833   }
19834   if (response_code != TPM_RC_SUCCESS) {
19835     return response_code;
19836   }
19837   TPM_CC command_code = TPM_CC_PCR_Event;
19838   std::string command_code_bytes;
19839   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19840   if (rc != TPM_RC_SUCCESS) {
19841     return rc;
19842   }
19843   std::string authorization_section_bytes;
19844   if (tag == TPM_ST_SESSIONS) {
19845     UINT32 parameter_section_size = buffer.size();
19846     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19847     if (rc != TPM_RC_SUCCESS) {
19848       return rc;
19849     }
19850     if (parameter_section_size > buffer.size()) {
19851       return TPM_RC_INSUFFICIENT;
19852     }
19853     authorization_section_bytes = buffer.substr(parameter_section_size);
19854     // Keep the parameter section in |buffer|.
19855     buffer.erase(parameter_section_size);
19856   }
19857   std::unique_ptr<crypto::SecureHash> hash(
19858       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19859   hash->Update(response_code_bytes.data(), response_code_bytes.size());
19860   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19861   hash->Update(buffer.data(), buffer.size());
19862   std::string response_hash(32, 0);
19863   hash->Finish(std::data(response_hash), response_hash.size());
19864   if (tag == TPM_ST_SESSIONS) {
19865     if (!authorization_delegate)
19866       return TRUNKS_RC_AUTHORIZATION_FAILED;
19867     if (!authorization_delegate->CheckResponseAuthorization(
19868             response_hash, authorization_section_bytes)) {
19869       return TRUNKS_RC_AUTHORIZATION_FAILED;
19870     }
19871   }
19872   std::string digests_bytes;
19873   rc = Parse_TPML_DIGEST_VALUES(&buffer, digests, &digests_bytes);
19874   if (rc != TPM_RC_SUCCESS) {
19875     return rc;
19876   }
19877   return TPM_RC_SUCCESS;
19878 }
19879 
PCR_EventErrorCallback(Tpm::PCR_EventResponse callback,TPM_RC response_code)19880 void PCR_EventErrorCallback(Tpm::PCR_EventResponse callback,
19881                             TPM_RC response_code) {
19882   VLOG(1) << __func__;
19883   std::move(callback).Run(response_code, TPML_DIGEST_VALUES());
19884 }
19885 
PCR_EventResponseParser(Tpm::PCR_EventResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19886 void PCR_EventResponseParser(Tpm::PCR_EventResponse callback,
19887                              AuthorizationDelegate* authorization_delegate,
19888                              const std::string& response) {
19889   VLOG(1) << __func__;
19890   TPML_DIGEST_VALUES digests;
19891   TPM_RC rc =
19892       Tpm::ParseResponse_PCR_Event(response, &digests, authorization_delegate);
19893   if (rc != TPM_RC_SUCCESS) {
19894     base::OnceCallback<void(TPM_RC)> error_reporter =
19895         base::BindOnce(PCR_EventErrorCallback, std::move(callback));
19896     std::move(error_reporter).Run(rc);
19897     return;
19898   }
19899   std::move(callback).Run(rc, digests);
19900 }
19901 
PCR_Event(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_EVENT & event_data,AuthorizationDelegate * authorization_delegate,PCR_EventResponse callback)19902 void Tpm::PCR_Event(const TPMI_DH_PCR& pcr_handle,
19903                     const std::string& pcr_handle_name,
19904                     const TPM2B_EVENT& event_data,
19905                     AuthorizationDelegate* authorization_delegate,
19906                     PCR_EventResponse callback) {
19907   VLOG(1) << __func__;
19908   std::string command;
19909   TPM_RC rc =
19910       SerializeCommand_PCR_Event(pcr_handle, pcr_handle_name, event_data,
19911                                  &command, authorization_delegate);
19912   if (rc != TPM_RC_SUCCESS) {
19913     base::OnceCallback<void(TPM_RC)> error_reporter =
19914         base::BindOnce(PCR_EventErrorCallback, std::move(callback));
19915     std::move(error_reporter).Run(rc);
19916     return;
19917   }
19918   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19919       PCR_EventResponseParser, std::move(callback), authorization_delegate);
19920   transceiver_->SendCommand(command, std::move(parser));
19921 }
19922 
PCR_EventSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_EVENT & event_data,TPML_DIGEST_VALUES * digests,AuthorizationDelegate * authorization_delegate)19923 TPM_RC Tpm::PCR_EventSync(const TPMI_DH_PCR& pcr_handle,
19924                           const std::string& pcr_handle_name,
19925                           const TPM2B_EVENT& event_data,
19926                           TPML_DIGEST_VALUES* digests,
19927                           AuthorizationDelegate* authorization_delegate) {
19928   VLOG(1) << __func__;
19929   std::string command;
19930   TPM_RC rc =
19931       SerializeCommand_PCR_Event(pcr_handle, pcr_handle_name, event_data,
19932                                  &command, authorization_delegate);
19933   if (rc != TPM_RC_SUCCESS) {
19934     return rc;
19935   }
19936   std::string response = transceiver_->SendCommandAndWait(command);
19937   rc = ParseResponse_PCR_Event(response, digests, authorization_delegate);
19938   return rc;
19939 }
19940 
SerializeCommand_PCR_Read(const TPML_PCR_SELECTION & pcr_selection_in,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19941 TPM_RC Tpm::SerializeCommand_PCR_Read(
19942     const TPML_PCR_SELECTION& pcr_selection_in,
19943     std::string* serialized_command,
19944     AuthorizationDelegate* authorization_delegate) {
19945   VLOG(3) << __func__;
19946   TPM_RC rc = TPM_RC_SUCCESS;
19947   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19948   UINT32 command_size = 10;  // Header size.
19949   std::string handle_section_bytes;
19950   std::string parameter_section_bytes;
19951   TPM_CC command_code = TPM_CC_PCR_Read;
19952   bool is_command_parameter_encryption_possible = false;
19953   bool is_response_parameter_encryption_possible = false;
19954   std::string command_code_bytes;
19955   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19956   if (rc != TPM_RC_SUCCESS) {
19957     return rc;
19958   }
19959   std::string pcr_selection_in_bytes;
19960   rc = Serialize_TPML_PCR_SELECTION(pcr_selection_in, &pcr_selection_in_bytes);
19961   if (rc != TPM_RC_SUCCESS) {
19962     return rc;
19963   }
19964   std::unique_ptr<crypto::SecureHash> hash(
19965       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19966   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19967   hash->Update(pcr_selection_in_bytes.data(), pcr_selection_in_bytes.size());
19968   parameter_section_bytes += pcr_selection_in_bytes;
19969   command_size += pcr_selection_in_bytes.size();
19970   std::string command_hash(32, 0);
19971   hash->Finish(std::data(command_hash), command_hash.size());
19972   std::string authorization_section_bytes;
19973   std::string authorization_size_bytes;
19974   if (authorization_delegate) {
19975     if (!authorization_delegate->GetCommandAuthorization(
19976             command_hash, is_command_parameter_encryption_possible,
19977             is_response_parameter_encryption_possible,
19978             &authorization_section_bytes)) {
19979       return TRUNKS_RC_AUTHORIZATION_FAILED;
19980     }
19981     if (!authorization_section_bytes.empty()) {
19982       tag = TPM_ST_SESSIONS;
19983       std::string tmp;
19984       rc = Serialize_UINT32(authorization_section_bytes.size(),
19985                             &authorization_size_bytes);
19986       if (rc != TPM_RC_SUCCESS) {
19987         return rc;
19988       }
19989       command_size +=
19990           authorization_size_bytes.size() + authorization_section_bytes.size();
19991     }
19992   }
19993   std::string tag_bytes;
19994   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19995   if (rc != TPM_RC_SUCCESS) {
19996     return rc;
19997   }
19998   std::string command_size_bytes;
19999   rc = Serialize_UINT32(command_size, &command_size_bytes);
20000   if (rc != TPM_RC_SUCCESS) {
20001     return rc;
20002   }
20003   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20004                         handle_section_bytes + authorization_size_bytes +
20005                         authorization_section_bytes + parameter_section_bytes;
20006   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20007   VLOG(2) << "Command: "
20008           << base::HexEncode(serialized_command->data(),
20009                              serialized_command->size());
20010   return TPM_RC_SUCCESS;
20011 }
20012 
ParseResponse_PCR_Read(const std::string & response,UINT32 * pcr_update_counter,TPML_PCR_SELECTION * pcr_selection_out,TPML_DIGEST * pcr_values,AuthorizationDelegate * authorization_delegate)20013 TPM_RC Tpm::ParseResponse_PCR_Read(
20014     const std::string& response,
20015     UINT32* pcr_update_counter,
20016     TPML_PCR_SELECTION* pcr_selection_out,
20017     TPML_DIGEST* pcr_values,
20018     AuthorizationDelegate* authorization_delegate) {
20019   VLOG(3) << __func__;
20020   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20021   TPM_RC rc = TPM_RC_SUCCESS;
20022   std::string buffer(response);
20023   TPM_ST tag;
20024   std::string tag_bytes;
20025   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20026   if (rc != TPM_RC_SUCCESS) {
20027     return rc;
20028   }
20029   UINT32 response_size;
20030   std::string response_size_bytes;
20031   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20032   if (rc != TPM_RC_SUCCESS) {
20033     return rc;
20034   }
20035   TPM_RC response_code;
20036   std::string response_code_bytes;
20037   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20038   if (rc != TPM_RC_SUCCESS) {
20039     return rc;
20040   }
20041   if (response_size != response.size()) {
20042     return TPM_RC_SIZE;
20043   }
20044   if (response_code != TPM_RC_SUCCESS) {
20045     return response_code;
20046   }
20047   TPM_CC command_code = TPM_CC_PCR_Read;
20048   std::string command_code_bytes;
20049   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20050   if (rc != TPM_RC_SUCCESS) {
20051     return rc;
20052   }
20053   std::string authorization_section_bytes;
20054   if (tag == TPM_ST_SESSIONS) {
20055     UINT32 parameter_section_size = buffer.size();
20056     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20057     if (rc != TPM_RC_SUCCESS) {
20058       return rc;
20059     }
20060     if (parameter_section_size > buffer.size()) {
20061       return TPM_RC_INSUFFICIENT;
20062     }
20063     authorization_section_bytes = buffer.substr(parameter_section_size);
20064     // Keep the parameter section in |buffer|.
20065     buffer.erase(parameter_section_size);
20066   }
20067   std::unique_ptr<crypto::SecureHash> hash(
20068       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20069   hash->Update(response_code_bytes.data(), response_code_bytes.size());
20070   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20071   hash->Update(buffer.data(), buffer.size());
20072   std::string response_hash(32, 0);
20073   hash->Finish(std::data(response_hash), response_hash.size());
20074   if (tag == TPM_ST_SESSIONS) {
20075     if (!authorization_delegate)
20076       return TRUNKS_RC_AUTHORIZATION_FAILED;
20077     if (!authorization_delegate->CheckResponseAuthorization(
20078             response_hash, authorization_section_bytes)) {
20079       return TRUNKS_RC_AUTHORIZATION_FAILED;
20080     }
20081   }
20082   std::string pcr_update_counter_bytes;
20083   rc = Parse_UINT32(&buffer, pcr_update_counter, &pcr_update_counter_bytes);
20084   if (rc != TPM_RC_SUCCESS) {
20085     return rc;
20086   }
20087   std::string pcr_selection_out_bytes;
20088   rc = Parse_TPML_PCR_SELECTION(&buffer, pcr_selection_out,
20089                                 &pcr_selection_out_bytes);
20090   if (rc != TPM_RC_SUCCESS) {
20091     return rc;
20092   }
20093   std::string pcr_values_bytes;
20094   rc = Parse_TPML_DIGEST(&buffer, pcr_values, &pcr_values_bytes);
20095   if (rc != TPM_RC_SUCCESS) {
20096     return rc;
20097   }
20098   return TPM_RC_SUCCESS;
20099 }
20100 
PCR_ReadErrorCallback(Tpm::PCR_ReadResponse callback,TPM_RC response_code)20101 void PCR_ReadErrorCallback(Tpm::PCR_ReadResponse callback,
20102                            TPM_RC response_code) {
20103   VLOG(1) << __func__;
20104   std::move(callback).Run(response_code, UINT32(), TPML_PCR_SELECTION(),
20105                           TPML_DIGEST());
20106 }
20107 
PCR_ReadResponseParser(Tpm::PCR_ReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20108 void PCR_ReadResponseParser(Tpm::PCR_ReadResponse callback,
20109                             AuthorizationDelegate* authorization_delegate,
20110                             const std::string& response) {
20111   VLOG(1) << __func__;
20112   UINT32 pcr_update_counter;
20113   TPML_PCR_SELECTION pcr_selection_out;
20114   TPML_DIGEST pcr_values;
20115   TPM_RC rc = Tpm::ParseResponse_PCR_Read(response, &pcr_update_counter,
20116                                           &pcr_selection_out, &pcr_values,
20117                                           authorization_delegate);
20118   if (rc != TPM_RC_SUCCESS) {
20119     base::OnceCallback<void(TPM_RC)> error_reporter =
20120         base::BindOnce(PCR_ReadErrorCallback, std::move(callback));
20121     std::move(error_reporter).Run(rc);
20122     return;
20123   }
20124   std::move(callback).Run(rc, pcr_update_counter, pcr_selection_out,
20125                           pcr_values);
20126 }
20127 
PCR_Read(const TPML_PCR_SELECTION & pcr_selection_in,AuthorizationDelegate * authorization_delegate,PCR_ReadResponse callback)20128 void Tpm::PCR_Read(const TPML_PCR_SELECTION& pcr_selection_in,
20129                    AuthorizationDelegate* authorization_delegate,
20130                    PCR_ReadResponse callback) {
20131   VLOG(1) << __func__;
20132   std::string command;
20133   TPM_RC rc = SerializeCommand_PCR_Read(pcr_selection_in, &command,
20134                                         authorization_delegate);
20135   if (rc != TPM_RC_SUCCESS) {
20136     base::OnceCallback<void(TPM_RC)> error_reporter =
20137         base::BindOnce(PCR_ReadErrorCallback, std::move(callback));
20138     std::move(error_reporter).Run(rc);
20139     return;
20140   }
20141   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
20142       PCR_ReadResponseParser, std::move(callback), authorization_delegate);
20143   transceiver_->SendCommand(command, std::move(parser));
20144 }
20145 
PCR_ReadSync(const TPML_PCR_SELECTION & pcr_selection_in,UINT32 * pcr_update_counter,TPML_PCR_SELECTION * pcr_selection_out,TPML_DIGEST * pcr_values,AuthorizationDelegate * authorization_delegate)20146 TPM_RC Tpm::PCR_ReadSync(const TPML_PCR_SELECTION& pcr_selection_in,
20147                          UINT32* pcr_update_counter,
20148                          TPML_PCR_SELECTION* pcr_selection_out,
20149                          TPML_DIGEST* pcr_values,
20150                          AuthorizationDelegate* authorization_delegate) {
20151   VLOG(1) << __func__;
20152   std::string command;
20153   TPM_RC rc = SerializeCommand_PCR_Read(pcr_selection_in, &command,
20154                                         authorization_delegate);
20155   if (rc != TPM_RC_SUCCESS) {
20156     return rc;
20157   }
20158   std::string response = transceiver_->SendCommandAndWait(command);
20159   rc = ParseResponse_PCR_Read(response, pcr_update_counter, pcr_selection_out,
20160                               pcr_values, authorization_delegate);
20161   return rc;
20162 }
20163 
SerializeCommand_PCR_Allocate(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPML_PCR_SELECTION & pcr_allocation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20164 TPM_RC Tpm::SerializeCommand_PCR_Allocate(
20165     const TPMI_RH_PLATFORM& auth_handle,
20166     const std::string& auth_handle_name,
20167     const TPML_PCR_SELECTION& pcr_allocation,
20168     std::string* serialized_command,
20169     AuthorizationDelegate* authorization_delegate) {
20170   VLOG(3) << __func__;
20171   TPM_RC rc = TPM_RC_SUCCESS;
20172   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20173   UINT32 command_size = 10;  // Header size.
20174   std::string handle_section_bytes;
20175   std::string parameter_section_bytes;
20176   TPM_CC command_code = TPM_CC_PCR_Allocate;
20177   bool is_command_parameter_encryption_possible = false;
20178   bool is_response_parameter_encryption_possible = false;
20179   std::string command_code_bytes;
20180   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20181   if (rc != TPM_RC_SUCCESS) {
20182     return rc;
20183   }
20184   std::string auth_handle_bytes;
20185   rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
20186   if (rc != TPM_RC_SUCCESS) {
20187     return rc;
20188   }
20189   std::string pcr_allocation_bytes;
20190   rc = Serialize_TPML_PCR_SELECTION(pcr_allocation, &pcr_allocation_bytes);
20191   if (rc != TPM_RC_SUCCESS) {
20192     return rc;
20193   }
20194   std::unique_ptr<crypto::SecureHash> hash(
20195       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20196   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20197   hash->Update(auth_handle_name.data(), auth_handle_name.size());
20198   handle_section_bytes += auth_handle_bytes;
20199   command_size += auth_handle_bytes.size();
20200   hash->Update(pcr_allocation_bytes.data(), pcr_allocation_bytes.size());
20201   parameter_section_bytes += pcr_allocation_bytes;
20202   command_size += pcr_allocation_bytes.size();
20203   std::string command_hash(32, 0);
20204   hash->Finish(std::data(command_hash), command_hash.size());
20205   std::string authorization_section_bytes;
20206   std::string authorization_size_bytes;
20207   if (authorization_delegate) {
20208     if (!authorization_delegate->GetCommandAuthorization(
20209             command_hash, is_command_parameter_encryption_possible,
20210             is_response_parameter_encryption_possible,
20211             &authorization_section_bytes)) {
20212       return TRUNKS_RC_AUTHORIZATION_FAILED;
20213     }
20214     if (!authorization_section_bytes.empty()) {
20215       tag = TPM_ST_SESSIONS;
20216       std::string tmp;
20217       rc = Serialize_UINT32(authorization_section_bytes.size(),
20218                             &authorization_size_bytes);
20219       if (rc != TPM_RC_SUCCESS) {
20220         return rc;
20221       }
20222       command_size +=
20223           authorization_size_bytes.size() + authorization_section_bytes.size();
20224     }
20225   }
20226   std::string tag_bytes;
20227   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20228   if (rc != TPM_RC_SUCCESS) {
20229     return rc;
20230   }
20231   std::string command_size_bytes;
20232   rc = Serialize_UINT32(command_size, &command_size_bytes);
20233   if (rc != TPM_RC_SUCCESS) {
20234     return rc;
20235   }
20236   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20237                         handle_section_bytes + authorization_size_bytes +
20238                         authorization_section_bytes + parameter_section_bytes;
20239   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20240   VLOG(2) << "Command: "
20241           << base::HexEncode(serialized_command->data(),
20242                              serialized_command->size());
20243   return TPM_RC_SUCCESS;
20244 }
20245 
ParseResponse_PCR_Allocate(const std::string & response,TPMI_YES_NO * allocation_success,UINT32 * max_pcr,UINT32 * size_needed,UINT32 * size_available,AuthorizationDelegate * authorization_delegate)20246 TPM_RC Tpm::ParseResponse_PCR_Allocate(
20247     const std::string& response,
20248     TPMI_YES_NO* allocation_success,
20249     UINT32* max_pcr,
20250     UINT32* size_needed,
20251     UINT32* size_available,
20252     AuthorizationDelegate* authorization_delegate) {
20253   VLOG(3) << __func__;
20254   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20255   TPM_RC rc = TPM_RC_SUCCESS;
20256   std::string buffer(response);
20257   TPM_ST tag;
20258   std::string tag_bytes;
20259   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20260   if (rc != TPM_RC_SUCCESS) {
20261     return rc;
20262   }
20263   UINT32 response_size;
20264   std::string response_size_bytes;
20265   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20266   if (rc != TPM_RC_SUCCESS) {
20267     return rc;
20268   }
20269   TPM_RC response_code;
20270   std::string response_code_bytes;
20271   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20272   if (rc != TPM_RC_SUCCESS) {
20273     return rc;
20274   }
20275   if (response_size != response.size()) {
20276     return TPM_RC_SIZE;
20277   }
20278   if (response_code != TPM_RC_SUCCESS) {
20279     return response_code;
20280   }
20281   TPM_CC command_code = TPM_CC_PCR_Allocate;
20282   std::string command_code_bytes;
20283   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20284   if (rc != TPM_RC_SUCCESS) {
20285     return rc;
20286   }
20287   std::string authorization_section_bytes;
20288   if (tag == TPM_ST_SESSIONS) {
20289     UINT32 parameter_section_size = buffer.size();
20290     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20291     if (rc != TPM_RC_SUCCESS) {
20292       return rc;
20293     }
20294     if (parameter_section_size > buffer.size()) {
20295       return TPM_RC_INSUFFICIENT;
20296     }
20297     authorization_section_bytes = buffer.substr(parameter_section_size);
20298     // Keep the parameter section in |buffer|.
20299     buffer.erase(parameter_section_size);
20300   }
20301   std::unique_ptr<crypto::SecureHash> hash(
20302       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20303   hash->Update(response_code_bytes.data(), response_code_bytes.size());
20304   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20305   hash->Update(buffer.data(), buffer.size());
20306   std::string response_hash(32, 0);
20307   hash->Finish(std::data(response_hash), response_hash.size());
20308   if (tag == TPM_ST_SESSIONS) {
20309     if (!authorization_delegate)
20310       return TRUNKS_RC_AUTHORIZATION_FAILED;
20311     if (!authorization_delegate->CheckResponseAuthorization(
20312             response_hash, authorization_section_bytes)) {
20313       return TRUNKS_RC_AUTHORIZATION_FAILED;
20314     }
20315   }
20316   std::string allocation_success_bytes;
20317   rc =
20318       Parse_TPMI_YES_NO(&buffer, allocation_success, &allocation_success_bytes);
20319   if (rc != TPM_RC_SUCCESS) {
20320     return rc;
20321   }
20322   std::string max_pcr_bytes;
20323   rc = Parse_UINT32(&buffer, max_pcr, &max_pcr_bytes);
20324   if (rc != TPM_RC_SUCCESS) {
20325     return rc;
20326   }
20327   std::string size_needed_bytes;
20328   rc = Parse_UINT32(&buffer, size_needed, &size_needed_bytes);
20329   if (rc != TPM_RC_SUCCESS) {
20330     return rc;
20331   }
20332   std::string size_available_bytes;
20333   rc = Parse_UINT32(&buffer, size_available, &size_available_bytes);
20334   if (rc != TPM_RC_SUCCESS) {
20335     return rc;
20336   }
20337   return TPM_RC_SUCCESS;
20338 }
20339 
PCR_AllocateErrorCallback(Tpm::PCR_AllocateResponse callback,TPM_RC response_code)20340 void PCR_AllocateErrorCallback(Tpm::PCR_AllocateResponse callback,
20341                                TPM_RC response_code) {
20342   VLOG(1) << __func__;
20343   std::move(callback).Run(response_code, TPMI_YES_NO(), UINT32(), UINT32(),
20344                           UINT32());
20345 }
20346 
PCR_AllocateResponseParser(Tpm::PCR_AllocateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20347 void PCR_AllocateResponseParser(Tpm::PCR_AllocateResponse callback,
20348                                 AuthorizationDelegate* authorization_delegate,
20349                                 const std::string& response) {
20350   VLOG(1) << __func__;
20351   TPMI_YES_NO allocation_success;
20352   UINT32 max_pcr;
20353   UINT32 size_needed;
20354   UINT32 size_available;
20355   TPM_RC rc = Tpm::ParseResponse_PCR_Allocate(
20356       response, &allocation_success, &max_pcr, &size_needed, &size_available,
20357       authorization_delegate);
20358   if (rc != TPM_RC_SUCCESS) {
20359     base::OnceCallback<void(TPM_RC)> error_reporter =
20360         base::BindOnce(PCR_AllocateErrorCallback, std::move(callback));
20361     std::move(error_reporter).Run(rc);
20362     return;
20363   }
20364   std::move(callback).Run(rc, allocation_success, max_pcr, size_needed,
20365                           size_available);
20366 }
20367 
PCR_Allocate(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPML_PCR_SELECTION & pcr_allocation,AuthorizationDelegate * authorization_delegate,PCR_AllocateResponse callback)20368 void Tpm::PCR_Allocate(const TPMI_RH_PLATFORM& auth_handle,
20369                        const std::string& auth_handle_name,
20370                        const TPML_PCR_SELECTION& pcr_allocation,
20371                        AuthorizationDelegate* authorization_delegate,
20372                        PCR_AllocateResponse callback) {
20373   VLOG(1) << __func__;
20374   std::string command;
20375   TPM_RC rc = SerializeCommand_PCR_Allocate(auth_handle, auth_handle_name,
20376                                             pcr_allocation, &command,
20377                                             authorization_delegate);
20378   if (rc != TPM_RC_SUCCESS) {
20379     base::OnceCallback<void(TPM_RC)> error_reporter =
20380         base::BindOnce(PCR_AllocateErrorCallback, std::move(callback));
20381     std::move(error_reporter).Run(rc);
20382     return;
20383   }
20384   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
20385       PCR_AllocateResponseParser, std::move(callback), authorization_delegate);
20386   transceiver_->SendCommand(command, std::move(parser));
20387 }
20388 
PCR_AllocateSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPML_PCR_SELECTION & pcr_allocation,TPMI_YES_NO * allocation_success,UINT32 * max_pcr,UINT32 * size_needed,UINT32 * size_available,AuthorizationDelegate * authorization_delegate)20389 TPM_RC Tpm::PCR_AllocateSync(const TPMI_RH_PLATFORM& auth_handle,
20390                              const std::string& auth_handle_name,
20391                              const TPML_PCR_SELECTION& pcr_allocation,
20392                              TPMI_YES_NO* allocation_success,
20393                              UINT32* max_pcr,
20394                              UINT32* size_needed,
20395                              UINT32* size_available,
20396                              AuthorizationDelegate* authorization_delegate) {
20397   VLOG(1) << __func__;
20398   std::string command;
20399   TPM_RC rc = SerializeCommand_PCR_Allocate(auth_handle, auth_handle_name,
20400                                             pcr_allocation, &command,
20401                                             authorization_delegate);
20402   if (rc != TPM_RC_SUCCESS) {
20403     return rc;
20404   }
20405   std::string response = transceiver_->SendCommandAndWait(command);
20406   rc = ParseResponse_PCR_Allocate(response, allocation_success, max_pcr,
20407                                   size_needed, size_available,
20408                                   authorization_delegate);
20409   return rc;
20410 }
20411 
SerializeCommand_PCR_SetAuthPolicy(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPMI_DH_PCR & pcr_num,const std::string & pcr_num_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & policy_digest,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20412 TPM_RC Tpm::SerializeCommand_PCR_SetAuthPolicy(
20413     const TPMI_RH_PLATFORM& auth_handle,
20414     const std::string& auth_handle_name,
20415     const TPMI_DH_PCR& pcr_num,
20416     const std::string& pcr_num_name,
20417     const TPM2B_DIGEST& auth_policy,
20418     const TPMI_ALG_HASH& policy_digest,
20419     std::string* serialized_command,
20420     AuthorizationDelegate* authorization_delegate) {
20421   VLOG(3) << __func__;
20422   TPM_RC rc = TPM_RC_SUCCESS;
20423   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20424   UINT32 command_size = 10;  // Header size.
20425   std::string handle_section_bytes;
20426   std::string parameter_section_bytes;
20427   TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy;
20428   bool is_command_parameter_encryption_possible = true;
20429   bool is_response_parameter_encryption_possible = false;
20430   std::string command_code_bytes;
20431   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20432   if (rc != TPM_RC_SUCCESS) {
20433     return rc;
20434   }
20435   std::string auth_handle_bytes;
20436   rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
20437   if (rc != TPM_RC_SUCCESS) {
20438     return rc;
20439   }
20440   std::string auth_policy_bytes;
20441   rc = Serialize_TPM2B_DIGEST(auth_policy, &auth_policy_bytes);
20442   if (rc != TPM_RC_SUCCESS) {
20443     return rc;
20444   }
20445   std::string policy_digest_bytes;
20446   rc = Serialize_TPMI_ALG_HASH(policy_digest, &policy_digest_bytes);
20447   if (rc != TPM_RC_SUCCESS) {
20448     return rc;
20449   }
20450   std::string pcr_num_bytes;
20451   rc = Serialize_TPMI_DH_PCR(pcr_num, &pcr_num_bytes);
20452   if (rc != TPM_RC_SUCCESS) {
20453     return rc;
20454   }
20455   if (authorization_delegate) {
20456     // Encrypt just the parameter data, not the size.
20457     std::string tmp = auth_policy_bytes.substr(2);
20458     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20459       return TRUNKS_RC_ENCRYPTION_FAILED;
20460     }
20461     auth_policy_bytes.replace(2, std::string::npos, tmp);
20462   }
20463   std::unique_ptr<crypto::SecureHash> hash(
20464       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20465   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20466   hash->Update(auth_handle_name.data(), auth_handle_name.size());
20467   handle_section_bytes += auth_handle_bytes;
20468   command_size += auth_handle_bytes.size();
20469   hash->Update(pcr_num_name.data(), pcr_num_name.size());
20470   handle_section_bytes += pcr_num_bytes;
20471   command_size += pcr_num_bytes.size();
20472   hash->Update(auth_policy_bytes.data(), auth_policy_bytes.size());
20473   parameter_section_bytes += auth_policy_bytes;
20474   command_size += auth_policy_bytes.size();
20475   hash->Update(policy_digest_bytes.data(), policy_digest_bytes.size());
20476   parameter_section_bytes += policy_digest_bytes;
20477   command_size += policy_digest_bytes.size();
20478   std::string command_hash(32, 0);
20479   hash->Finish(std::data(command_hash), command_hash.size());
20480   std::string authorization_section_bytes;
20481   std::string authorization_size_bytes;
20482   if (authorization_delegate) {
20483     if (!authorization_delegate->GetCommandAuthorization(
20484             command_hash, is_command_parameter_encryption_possible,
20485             is_response_parameter_encryption_possible,
20486             &authorization_section_bytes)) {
20487       return TRUNKS_RC_AUTHORIZATION_FAILED;
20488     }
20489     if (!authorization_section_bytes.empty()) {
20490       tag = TPM_ST_SESSIONS;
20491       std::string tmp;
20492       rc = Serialize_UINT32(authorization_section_bytes.size(),
20493                             &authorization_size_bytes);
20494       if (rc != TPM_RC_SUCCESS) {
20495         return rc;
20496       }
20497       command_size +=
20498           authorization_size_bytes.size() + authorization_section_bytes.size();
20499     }
20500   }
20501   std::string tag_bytes;
20502   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20503   if (rc != TPM_RC_SUCCESS) {
20504     return rc;
20505   }
20506   std::string command_size_bytes;
20507   rc = Serialize_UINT32(command_size, &command_size_bytes);
20508   if (rc != TPM_RC_SUCCESS) {
20509     return rc;
20510   }
20511   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20512                         handle_section_bytes + authorization_size_bytes +
20513                         authorization_section_bytes + parameter_section_bytes;
20514   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20515   VLOG(2) << "Command: "
20516           << base::HexEncode(serialized_command->data(),
20517                              serialized_command->size());
20518   return TPM_RC_SUCCESS;
20519 }
20520 
ParseResponse_PCR_SetAuthPolicy(const std::string & response,AuthorizationDelegate * authorization_delegate)20521 TPM_RC Tpm::ParseResponse_PCR_SetAuthPolicy(
20522     const std::string& response,
20523     AuthorizationDelegate* authorization_delegate) {
20524   VLOG(3) << __func__;
20525   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20526   TPM_RC rc = TPM_RC_SUCCESS;
20527   std::string buffer(response);
20528   TPM_ST tag;
20529   std::string tag_bytes;
20530   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20531   if (rc != TPM_RC_SUCCESS) {
20532     return rc;
20533   }
20534   UINT32 response_size;
20535   std::string response_size_bytes;
20536   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20537   if (rc != TPM_RC_SUCCESS) {
20538     return rc;
20539   }
20540   TPM_RC response_code;
20541   std::string response_code_bytes;
20542   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20543   if (rc != TPM_RC_SUCCESS) {
20544     return rc;
20545   }
20546   if (response_size != response.size()) {
20547     return TPM_RC_SIZE;
20548   }
20549   if (response_code != TPM_RC_SUCCESS) {
20550     return response_code;
20551   }
20552   TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy;
20553   std::string command_code_bytes;
20554   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20555   if (rc != TPM_RC_SUCCESS) {
20556     return rc;
20557   }
20558   std::string authorization_section_bytes;
20559   if (tag == TPM_ST_SESSIONS) {
20560     UINT32 parameter_section_size = buffer.size();
20561     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20562     if (rc != TPM_RC_SUCCESS) {
20563       return rc;
20564     }
20565     if (parameter_section_size > buffer.size()) {
20566       return TPM_RC_INSUFFICIENT;
20567     }
20568     authorization_section_bytes = buffer.substr(parameter_section_size);
20569     // Keep the parameter section in |buffer|.
20570     buffer.erase(parameter_section_size);
20571   }
20572   std::unique_ptr<crypto::SecureHash> hash(
20573       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20574   hash->Update(response_code_bytes.data(), response_code_bytes.size());
20575   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20576   hash->Update(buffer.data(), buffer.size());
20577   std::string response_hash(32, 0);
20578   hash->Finish(std::data(response_hash), response_hash.size());
20579   if (tag == TPM_ST_SESSIONS) {
20580     if (!authorization_delegate)
20581       return TRUNKS_RC_AUTHORIZATION_FAILED;
20582     if (!authorization_delegate->CheckResponseAuthorization(
20583             response_hash, authorization_section_bytes)) {
20584       return TRUNKS_RC_AUTHORIZATION_FAILED;
20585     }
20586   }
20587   return TPM_RC_SUCCESS;
20588 }
20589 
PCR_SetAuthPolicyErrorCallback(Tpm::PCR_SetAuthPolicyResponse callback,TPM_RC response_code)20590 void PCR_SetAuthPolicyErrorCallback(Tpm::PCR_SetAuthPolicyResponse callback,
20591                                     TPM_RC response_code) {
20592   VLOG(1) << __func__;
20593   std::move(callback).Run(response_code);
20594 }
20595 
PCR_SetAuthPolicyResponseParser(Tpm::PCR_SetAuthPolicyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20596 void PCR_SetAuthPolicyResponseParser(
20597     Tpm::PCR_SetAuthPolicyResponse callback,
20598     AuthorizationDelegate* authorization_delegate,
20599     const std::string& response) {
20600   VLOG(1) << __func__;
20601   TPM_RC rc =
20602       Tpm::ParseResponse_PCR_SetAuthPolicy(response, authorization_delegate);
20603   if (rc != TPM_RC_SUCCESS) {
20604     base::OnceCallback<void(TPM_RC)> error_reporter =
20605         base::BindOnce(PCR_SetAuthPolicyErrorCallback, std::move(callback));
20606     std::move(error_reporter).Run(rc);
20607     return;
20608   }
20609   std::move(callback).Run(rc);
20610 }
20611 
PCR_SetAuthPolicy(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPMI_DH_PCR & pcr_num,const std::string & pcr_num_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & policy_digest,AuthorizationDelegate * authorization_delegate,PCR_SetAuthPolicyResponse callback)20612 void Tpm::PCR_SetAuthPolicy(const TPMI_RH_PLATFORM& auth_handle,
20613                             const std::string& auth_handle_name,
20614                             const TPMI_DH_PCR& pcr_num,
20615                             const std::string& pcr_num_name,
20616                             const TPM2B_DIGEST& auth_policy,
20617                             const TPMI_ALG_HASH& policy_digest,
20618                             AuthorizationDelegate* authorization_delegate,
20619                             PCR_SetAuthPolicyResponse callback) {
20620   VLOG(1) << __func__;
20621   std::string command;
20622   TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy(
20623       auth_handle, auth_handle_name, pcr_num, pcr_num_name, auth_policy,
20624       policy_digest, &command, authorization_delegate);
20625   if (rc != TPM_RC_SUCCESS) {
20626     base::OnceCallback<void(TPM_RC)> error_reporter =
20627         base::BindOnce(PCR_SetAuthPolicyErrorCallback, std::move(callback));
20628     std::move(error_reporter).Run(rc);
20629     return;
20630   }
20631   base::OnceCallback<void(const std::string&)> parser =
20632       base::BindOnce(PCR_SetAuthPolicyResponseParser, std::move(callback),
20633                      authorization_delegate);
20634   transceiver_->SendCommand(command, std::move(parser));
20635 }
20636 
PCR_SetAuthPolicySync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPMI_DH_PCR & pcr_num,const std::string & pcr_num_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & policy_digest,AuthorizationDelegate * authorization_delegate)20637 TPM_RC Tpm::PCR_SetAuthPolicySync(
20638     const TPMI_RH_PLATFORM& auth_handle,
20639     const std::string& auth_handle_name,
20640     const TPMI_DH_PCR& pcr_num,
20641     const std::string& pcr_num_name,
20642     const TPM2B_DIGEST& auth_policy,
20643     const TPMI_ALG_HASH& policy_digest,
20644     AuthorizationDelegate* authorization_delegate) {
20645   VLOG(1) << __func__;
20646   std::string command;
20647   TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy(
20648       auth_handle, auth_handle_name, pcr_num, pcr_num_name, auth_policy,
20649       policy_digest, &command, authorization_delegate);
20650   if (rc != TPM_RC_SUCCESS) {
20651     return rc;
20652   }
20653   std::string response = transceiver_->SendCommandAndWait(command);
20654   rc = ParseResponse_PCR_SetAuthPolicy(response, authorization_delegate);
20655   return rc;
20656 }
20657 
SerializeCommand_PCR_SetAuthValue(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20658 TPM_RC Tpm::SerializeCommand_PCR_SetAuthValue(
20659     const TPMI_DH_PCR& pcr_handle,
20660     const std::string& pcr_handle_name,
20661     const TPM2B_DIGEST& auth,
20662     std::string* serialized_command,
20663     AuthorizationDelegate* authorization_delegate) {
20664   VLOG(3) << __func__;
20665   TPM_RC rc = TPM_RC_SUCCESS;
20666   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20667   UINT32 command_size = 10;  // Header size.
20668   std::string handle_section_bytes;
20669   std::string parameter_section_bytes;
20670   TPM_CC command_code = TPM_CC_PCR_SetAuthValue;
20671   bool is_command_parameter_encryption_possible = true;
20672   bool is_response_parameter_encryption_possible = false;
20673   std::string command_code_bytes;
20674   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20675   if (rc != TPM_RC_SUCCESS) {
20676     return rc;
20677   }
20678   std::string pcr_handle_bytes;
20679   rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
20680   if (rc != TPM_RC_SUCCESS) {
20681     return rc;
20682   }
20683   std::string auth_bytes;
20684   rc = Serialize_TPM2B_DIGEST(auth, &auth_bytes);
20685   if (rc != TPM_RC_SUCCESS) {
20686     return rc;
20687   }
20688   if (authorization_delegate) {
20689     // Encrypt just the parameter data, not the size.
20690     std::string tmp = auth_bytes.substr(2);
20691     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20692       return TRUNKS_RC_ENCRYPTION_FAILED;
20693     }
20694     auth_bytes.replace(2, std::string::npos, tmp);
20695   }
20696   std::unique_ptr<crypto::SecureHash> hash(
20697       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20698   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20699   hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
20700   handle_section_bytes += pcr_handle_bytes;
20701   command_size += pcr_handle_bytes.size();
20702   hash->Update(auth_bytes.data(), auth_bytes.size());
20703   parameter_section_bytes += auth_bytes;
20704   command_size += auth_bytes.size();
20705   std::string command_hash(32, 0);
20706   hash->Finish(std::data(command_hash), command_hash.size());
20707   std::string authorization_section_bytes;
20708   std::string authorization_size_bytes;
20709   if (authorization_delegate) {
20710     if (!authorization_delegate->GetCommandAuthorization(
20711             command_hash, is_command_parameter_encryption_possible,
20712             is_response_parameter_encryption_possible,
20713             &authorization_section_bytes)) {
20714       return TRUNKS_RC_AUTHORIZATION_FAILED;
20715     }
20716     if (!authorization_section_bytes.empty()) {
20717       tag = TPM_ST_SESSIONS;
20718       std::string tmp;
20719       rc = Serialize_UINT32(authorization_section_bytes.size(),
20720                             &authorization_size_bytes);
20721       if (rc != TPM_RC_SUCCESS) {
20722         return rc;
20723       }
20724       command_size +=
20725           authorization_size_bytes.size() + authorization_section_bytes.size();
20726     }
20727   }
20728   std::string tag_bytes;
20729   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20730   if (rc != TPM_RC_SUCCESS) {
20731     return rc;
20732   }
20733   std::string command_size_bytes;
20734   rc = Serialize_UINT32(command_size, &command_size_bytes);
20735   if (rc != TPM_RC_SUCCESS) {
20736     return rc;
20737   }
20738   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20739                         handle_section_bytes + authorization_size_bytes +
20740                         authorization_section_bytes + parameter_section_bytes;
20741   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20742   VLOG(2) << "Command: "
20743           << base::HexEncode(serialized_command->data(),
20744                              serialized_command->size());
20745   return TPM_RC_SUCCESS;
20746 }
20747 
ParseResponse_PCR_SetAuthValue(const std::string & response,AuthorizationDelegate * authorization_delegate)20748 TPM_RC Tpm::ParseResponse_PCR_SetAuthValue(
20749     const std::string& response,
20750     AuthorizationDelegate* authorization_delegate) {
20751   VLOG(3) << __func__;
20752   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20753   TPM_RC rc = TPM_RC_SUCCESS;
20754   std::string buffer(response);
20755   TPM_ST tag;
20756   std::string tag_bytes;
20757   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20758   if (rc != TPM_RC_SUCCESS) {
20759     return rc;
20760   }
20761   UINT32 response_size;
20762   std::string response_size_bytes;
20763   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20764   if (rc != TPM_RC_SUCCESS) {
20765     return rc;
20766   }
20767   TPM_RC response_code;
20768   std::string response_code_bytes;
20769   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20770   if (rc != TPM_RC_SUCCESS) {
20771     return rc;
20772   }
20773   if (response_size != response.size()) {
20774     return TPM_RC_SIZE;
20775   }
20776   if (response_code != TPM_RC_SUCCESS) {
20777     return response_code;
20778   }
20779   TPM_CC command_code = TPM_CC_PCR_SetAuthValue;
20780   std::string command_code_bytes;
20781   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20782   if (rc != TPM_RC_SUCCESS) {
20783     return rc;
20784   }
20785   std::string authorization_section_bytes;
20786   if (tag == TPM_ST_SESSIONS) {
20787     UINT32 parameter_section_size = buffer.size();
20788     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20789     if (rc != TPM_RC_SUCCESS) {
20790       return rc;
20791     }
20792     if (parameter_section_size > buffer.size()) {
20793       return TPM_RC_INSUFFICIENT;
20794     }
20795     authorization_section_bytes = buffer.substr(parameter_section_size);
20796     // Keep the parameter section in |buffer|.
20797     buffer.erase(parameter_section_size);
20798   }
20799   std::unique_ptr<crypto::SecureHash> hash(
20800       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20801   hash->Update(response_code_bytes.data(), response_code_bytes.size());
20802   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20803   hash->Update(buffer.data(), buffer.size());
20804   std::string response_hash(32, 0);
20805   hash->Finish(std::data(response_hash), response_hash.size());
20806   if (tag == TPM_ST_SESSIONS) {
20807     if (!authorization_delegate)
20808       return TRUNKS_RC_AUTHORIZATION_FAILED;
20809     if (!authorization_delegate->CheckResponseAuthorization(
20810             response_hash, authorization_section_bytes)) {
20811       return TRUNKS_RC_AUTHORIZATION_FAILED;
20812     }
20813   }
20814   return TPM_RC_SUCCESS;
20815 }
20816 
PCR_SetAuthValueErrorCallback(Tpm::PCR_SetAuthValueResponse callback,TPM_RC response_code)20817 void PCR_SetAuthValueErrorCallback(Tpm::PCR_SetAuthValueResponse callback,
20818                                    TPM_RC response_code) {
20819   VLOG(1) << __func__;
20820   std::move(callback).Run(response_code);
20821 }
20822 
PCR_SetAuthValueResponseParser(Tpm::PCR_SetAuthValueResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20823 void PCR_SetAuthValueResponseParser(
20824     Tpm::PCR_SetAuthValueResponse callback,
20825     AuthorizationDelegate* authorization_delegate,
20826     const std::string& response) {
20827   VLOG(1) << __func__;
20828   TPM_RC rc =
20829       Tpm::ParseResponse_PCR_SetAuthValue(response, authorization_delegate);
20830   if (rc != TPM_RC_SUCCESS) {
20831     base::OnceCallback<void(TPM_RC)> error_reporter =
20832         base::BindOnce(PCR_SetAuthValueErrorCallback, std::move(callback));
20833     std::move(error_reporter).Run(rc);
20834     return;
20835   }
20836   std::move(callback).Run(rc);
20837 }
20838 
PCR_SetAuthValue(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,AuthorizationDelegate * authorization_delegate,PCR_SetAuthValueResponse callback)20839 void Tpm::PCR_SetAuthValue(const TPMI_DH_PCR& pcr_handle,
20840                            const std::string& pcr_handle_name,
20841                            const TPM2B_DIGEST& auth,
20842                            AuthorizationDelegate* authorization_delegate,
20843                            PCR_SetAuthValueResponse callback) {
20844   VLOG(1) << __func__;
20845   std::string command;
20846   TPM_RC rc = SerializeCommand_PCR_SetAuthValue(
20847       pcr_handle, pcr_handle_name, auth, &command, authorization_delegate);
20848   if (rc != TPM_RC_SUCCESS) {
20849     base::OnceCallback<void(TPM_RC)> error_reporter =
20850         base::BindOnce(PCR_SetAuthValueErrorCallback, std::move(callback));
20851     std::move(error_reporter).Run(rc);
20852     return;
20853   }
20854   base::OnceCallback<void(const std::string&)> parser =
20855       base::BindOnce(PCR_SetAuthValueResponseParser, std::move(callback),
20856                      authorization_delegate);
20857   transceiver_->SendCommand(command, std::move(parser));
20858 }
20859 
PCR_SetAuthValueSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,AuthorizationDelegate * authorization_delegate)20860 TPM_RC Tpm::PCR_SetAuthValueSync(
20861     const TPMI_DH_PCR& pcr_handle,
20862     const std::string& pcr_handle_name,
20863     const TPM2B_DIGEST& auth,
20864     AuthorizationDelegate* authorization_delegate) {
20865   VLOG(1) << __func__;
20866   std::string command;
20867   TPM_RC rc = SerializeCommand_PCR_SetAuthValue(
20868       pcr_handle, pcr_handle_name, auth, &command, authorization_delegate);
20869   if (rc != TPM_RC_SUCCESS) {
20870     return rc;
20871   }
20872   std::string response = transceiver_->SendCommandAndWait(command);
20873   rc = ParseResponse_PCR_SetAuthValue(response, authorization_delegate);
20874   return rc;
20875 }
20876 
SerializeCommand_PCR_Reset(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20877 TPM_RC Tpm::SerializeCommand_PCR_Reset(
20878     const TPMI_DH_PCR& pcr_handle,
20879     const std::string& pcr_handle_name,
20880     std::string* serialized_command,
20881     AuthorizationDelegate* authorization_delegate) {
20882   VLOG(3) << __func__;
20883   TPM_RC rc = TPM_RC_SUCCESS;
20884   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20885   UINT32 command_size = 10;  // Header size.
20886   std::string handle_section_bytes;
20887   std::string parameter_section_bytes;
20888   TPM_CC command_code = TPM_CC_PCR_Reset;
20889   bool is_command_parameter_encryption_possible = false;
20890   bool is_response_parameter_encryption_possible = false;
20891   std::string command_code_bytes;
20892   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20893   if (rc != TPM_RC_SUCCESS) {
20894     return rc;
20895   }
20896   std::string pcr_handle_bytes;
20897   rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
20898   if (rc != TPM_RC_SUCCESS) {
20899     return rc;
20900   }
20901   std::unique_ptr<crypto::SecureHash> hash(
20902       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20903   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20904   hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
20905   handle_section_bytes += pcr_handle_bytes;
20906   command_size += pcr_handle_bytes.size();
20907   std::string command_hash(32, 0);
20908   hash->Finish(std::data(command_hash), command_hash.size());
20909   std::string authorization_section_bytes;
20910   std::string authorization_size_bytes;
20911   if (authorization_delegate) {
20912     if (!authorization_delegate->GetCommandAuthorization(
20913             command_hash, is_command_parameter_encryption_possible,
20914             is_response_parameter_encryption_possible,
20915             &authorization_section_bytes)) {
20916       return TRUNKS_RC_AUTHORIZATION_FAILED;
20917     }
20918     if (!authorization_section_bytes.empty()) {
20919       tag = TPM_ST_SESSIONS;
20920       std::string tmp;
20921       rc = Serialize_UINT32(authorization_section_bytes.size(),
20922                             &authorization_size_bytes);
20923       if (rc != TPM_RC_SUCCESS) {
20924         return rc;
20925       }
20926       command_size +=
20927           authorization_size_bytes.size() + authorization_section_bytes.size();
20928     }
20929   }
20930   std::string tag_bytes;
20931   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20932   if (rc != TPM_RC_SUCCESS) {
20933     return rc;
20934   }
20935   std::string command_size_bytes;
20936   rc = Serialize_UINT32(command_size, &command_size_bytes);
20937   if (rc != TPM_RC_SUCCESS) {
20938     return rc;
20939   }
20940   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20941                         handle_section_bytes + authorization_size_bytes +
20942                         authorization_section_bytes + parameter_section_bytes;
20943   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20944   VLOG(2) << "Command: "
20945           << base::HexEncode(serialized_command->data(),
20946                              serialized_command->size());
20947   return TPM_RC_SUCCESS;
20948 }
20949 
ParseResponse_PCR_Reset(const std::string & response,AuthorizationDelegate * authorization_delegate)20950 TPM_RC Tpm::ParseResponse_PCR_Reset(
20951     const std::string& response,
20952     AuthorizationDelegate* authorization_delegate) {
20953   VLOG(3) << __func__;
20954   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20955   TPM_RC rc = TPM_RC_SUCCESS;
20956   std::string buffer(response);
20957   TPM_ST tag;
20958   std::string tag_bytes;
20959   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20960   if (rc != TPM_RC_SUCCESS) {
20961     return rc;
20962   }
20963   UINT32 response_size;
20964   std::string response_size_bytes;
20965   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20966   if (rc != TPM_RC_SUCCESS) {
20967     return rc;
20968   }
20969   TPM_RC response_code;
20970   std::string response_code_bytes;
20971   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20972   if (rc != TPM_RC_SUCCESS) {
20973     return rc;
20974   }
20975   if (response_size != response.size()) {
20976     return TPM_RC_SIZE;
20977   }
20978   if (response_code != TPM_RC_SUCCESS) {
20979     return response_code;
20980   }
20981   TPM_CC command_code = TPM_CC_PCR_Reset;
20982   std::string command_code_bytes;
20983   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20984   if (rc != TPM_RC_SUCCESS) {
20985     return rc;
20986   }
20987   std::string authorization_section_bytes;
20988   if (tag == TPM_ST_SESSIONS) {
20989     UINT32 parameter_section_size = buffer.size();
20990     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20991     if (rc != TPM_RC_SUCCESS) {
20992       return rc;
20993     }
20994     if (parameter_section_size > buffer.size()) {
20995       return TPM_RC_INSUFFICIENT;
20996     }
20997     authorization_section_bytes = buffer.substr(parameter_section_size);
20998     // Keep the parameter section in |buffer|.
20999     buffer.erase(parameter_section_size);
21000   }
21001   std::unique_ptr<crypto::SecureHash> hash(
21002       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21003   hash->Update(response_code_bytes.data(), response_code_bytes.size());
21004   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21005   hash->Update(buffer.data(), buffer.size());
21006   std::string response_hash(32, 0);
21007   hash->Finish(std::data(response_hash), response_hash.size());
21008   if (tag == TPM_ST_SESSIONS) {
21009     if (!authorization_delegate)
21010       return TRUNKS_RC_AUTHORIZATION_FAILED;
21011     if (!authorization_delegate->CheckResponseAuthorization(
21012             response_hash, authorization_section_bytes)) {
21013       return TRUNKS_RC_AUTHORIZATION_FAILED;
21014     }
21015   }
21016   return TPM_RC_SUCCESS;
21017 }
21018 
PCR_ResetErrorCallback(Tpm::PCR_ResetResponse callback,TPM_RC response_code)21019 void PCR_ResetErrorCallback(Tpm::PCR_ResetResponse callback,
21020                             TPM_RC response_code) {
21021   VLOG(1) << __func__;
21022   std::move(callback).Run(response_code);
21023 }
21024 
PCR_ResetResponseParser(Tpm::PCR_ResetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21025 void PCR_ResetResponseParser(Tpm::PCR_ResetResponse callback,
21026                              AuthorizationDelegate* authorization_delegate,
21027                              const std::string& response) {
21028   VLOG(1) << __func__;
21029   TPM_RC rc = Tpm::ParseResponse_PCR_Reset(response, authorization_delegate);
21030   if (rc != TPM_RC_SUCCESS) {
21031     base::OnceCallback<void(TPM_RC)> error_reporter =
21032         base::BindOnce(PCR_ResetErrorCallback, std::move(callback));
21033     std::move(error_reporter).Run(rc);
21034     return;
21035   }
21036   std::move(callback).Run(rc);
21037 }
21038 
PCR_Reset(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,AuthorizationDelegate * authorization_delegate,PCR_ResetResponse callback)21039 void Tpm::PCR_Reset(const TPMI_DH_PCR& pcr_handle,
21040                     const std::string& pcr_handle_name,
21041                     AuthorizationDelegate* authorization_delegate,
21042                     PCR_ResetResponse callback) {
21043   VLOG(1) << __func__;
21044   std::string command;
21045   TPM_RC rc = SerializeCommand_PCR_Reset(pcr_handle, pcr_handle_name, &command,
21046                                          authorization_delegate);
21047   if (rc != TPM_RC_SUCCESS) {
21048     base::OnceCallback<void(TPM_RC)> error_reporter =
21049         base::BindOnce(PCR_ResetErrorCallback, std::move(callback));
21050     std::move(error_reporter).Run(rc);
21051     return;
21052   }
21053   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21054       PCR_ResetResponseParser, std::move(callback), authorization_delegate);
21055   transceiver_->SendCommand(command, std::move(parser));
21056 }
21057 
PCR_ResetSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,AuthorizationDelegate * authorization_delegate)21058 TPM_RC Tpm::PCR_ResetSync(const TPMI_DH_PCR& pcr_handle,
21059                           const std::string& pcr_handle_name,
21060                           AuthorizationDelegate* authorization_delegate) {
21061   VLOG(1) << __func__;
21062   std::string command;
21063   TPM_RC rc = SerializeCommand_PCR_Reset(pcr_handle, pcr_handle_name, &command,
21064                                          authorization_delegate);
21065   if (rc != TPM_RC_SUCCESS) {
21066     return rc;
21067   }
21068   std::string response = transceiver_->SendCommandAndWait(command);
21069   rc = ParseResponse_PCR_Reset(response, authorization_delegate);
21070   return rc;
21071 }
21072 
SerializeCommand_PolicySigned(const TPMI_DH_OBJECT & auth_object,const std::string & auth_object_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,const TPMT_SIGNATURE & auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21073 TPM_RC Tpm::SerializeCommand_PolicySigned(
21074     const TPMI_DH_OBJECT& auth_object,
21075     const std::string& auth_object_name,
21076     const TPMI_SH_POLICY& policy_session,
21077     const std::string& policy_session_name,
21078     const TPM2B_NONCE& nonce_tpm,
21079     const TPM2B_DIGEST& cp_hash_a,
21080     const TPM2B_NONCE& policy_ref,
21081     const INT32& expiration,
21082     const TPMT_SIGNATURE& auth,
21083     std::string* serialized_command,
21084     AuthorizationDelegate* authorization_delegate) {
21085   VLOG(3) << __func__;
21086   TPM_RC rc = TPM_RC_SUCCESS;
21087   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21088   UINT32 command_size = 10;  // Header size.
21089   std::string handle_section_bytes;
21090   std::string parameter_section_bytes;
21091   TPM_CC command_code = TPM_CC_PolicySigned;
21092   bool is_command_parameter_encryption_possible = true;
21093   bool is_response_parameter_encryption_possible = true;
21094   std::string command_code_bytes;
21095   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21096   if (rc != TPM_RC_SUCCESS) {
21097     return rc;
21098   }
21099   std::string auth_object_bytes;
21100   rc = Serialize_TPMI_DH_OBJECT(auth_object, &auth_object_bytes);
21101   if (rc != TPM_RC_SUCCESS) {
21102     return rc;
21103   }
21104   std::string policy_session_bytes;
21105   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21106   if (rc != TPM_RC_SUCCESS) {
21107     return rc;
21108   }
21109   std::string nonce_tpm_bytes;
21110   rc = Serialize_TPM2B_NONCE(nonce_tpm, &nonce_tpm_bytes);
21111   if (rc != TPM_RC_SUCCESS) {
21112     return rc;
21113   }
21114   std::string cp_hash_a_bytes;
21115   rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21116   if (rc != TPM_RC_SUCCESS) {
21117     return rc;
21118   }
21119   std::string policy_ref_bytes;
21120   rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21121   if (rc != TPM_RC_SUCCESS) {
21122     return rc;
21123   }
21124   std::string expiration_bytes;
21125   rc = Serialize_INT32(expiration, &expiration_bytes);
21126   if (rc != TPM_RC_SUCCESS) {
21127     return rc;
21128   }
21129   std::string auth_bytes;
21130   rc = Serialize_TPMT_SIGNATURE(auth, &auth_bytes);
21131   if (rc != TPM_RC_SUCCESS) {
21132     return rc;
21133   }
21134   if (authorization_delegate) {
21135     // Encrypt just the parameter data, not the size.
21136     std::string tmp = nonce_tpm_bytes.substr(2);
21137     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21138       return TRUNKS_RC_ENCRYPTION_FAILED;
21139     }
21140     nonce_tpm_bytes.replace(2, std::string::npos, tmp);
21141   }
21142   std::unique_ptr<crypto::SecureHash> hash(
21143       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21144   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21145   hash->Update(auth_object_name.data(), auth_object_name.size());
21146   handle_section_bytes += auth_object_bytes;
21147   command_size += auth_object_bytes.size();
21148   hash->Update(policy_session_name.data(), policy_session_name.size());
21149   handle_section_bytes += policy_session_bytes;
21150   command_size += policy_session_bytes.size();
21151   hash->Update(nonce_tpm_bytes.data(), nonce_tpm_bytes.size());
21152   parameter_section_bytes += nonce_tpm_bytes;
21153   command_size += nonce_tpm_bytes.size();
21154   hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21155   parameter_section_bytes += cp_hash_a_bytes;
21156   command_size += cp_hash_a_bytes.size();
21157   hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21158   parameter_section_bytes += policy_ref_bytes;
21159   command_size += policy_ref_bytes.size();
21160   hash->Update(expiration_bytes.data(), expiration_bytes.size());
21161   parameter_section_bytes += expiration_bytes;
21162   command_size += expiration_bytes.size();
21163   hash->Update(auth_bytes.data(), auth_bytes.size());
21164   parameter_section_bytes += auth_bytes;
21165   command_size += auth_bytes.size();
21166   std::string command_hash(32, 0);
21167   hash->Finish(std::data(command_hash), command_hash.size());
21168   std::string authorization_section_bytes;
21169   std::string authorization_size_bytes;
21170   if (authorization_delegate) {
21171     if (!authorization_delegate->GetCommandAuthorization(
21172             command_hash, is_command_parameter_encryption_possible,
21173             is_response_parameter_encryption_possible,
21174             &authorization_section_bytes)) {
21175       return TRUNKS_RC_AUTHORIZATION_FAILED;
21176     }
21177     if (!authorization_section_bytes.empty()) {
21178       tag = TPM_ST_SESSIONS;
21179       std::string tmp;
21180       rc = Serialize_UINT32(authorization_section_bytes.size(),
21181                             &authorization_size_bytes);
21182       if (rc != TPM_RC_SUCCESS) {
21183         return rc;
21184       }
21185       command_size +=
21186           authorization_size_bytes.size() + authorization_section_bytes.size();
21187     }
21188   }
21189   std::string tag_bytes;
21190   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21191   if (rc != TPM_RC_SUCCESS) {
21192     return rc;
21193   }
21194   std::string command_size_bytes;
21195   rc = Serialize_UINT32(command_size, &command_size_bytes);
21196   if (rc != TPM_RC_SUCCESS) {
21197     return rc;
21198   }
21199   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21200                         handle_section_bytes + authorization_size_bytes +
21201                         authorization_section_bytes + parameter_section_bytes;
21202   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21203   VLOG(2) << "Command: "
21204           << base::HexEncode(serialized_command->data(),
21205                              serialized_command->size());
21206   return TPM_RC_SUCCESS;
21207 }
21208 
ParseResponse_PolicySigned(const std::string & response,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21209 TPM_RC Tpm::ParseResponse_PolicySigned(
21210     const std::string& response,
21211     TPM2B_TIMEOUT* timeout,
21212     TPMT_TK_AUTH* policy_ticket,
21213     AuthorizationDelegate* authorization_delegate) {
21214   VLOG(3) << __func__;
21215   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21216   TPM_RC rc = TPM_RC_SUCCESS;
21217   std::string buffer(response);
21218   TPM_ST tag;
21219   std::string tag_bytes;
21220   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21221   if (rc != TPM_RC_SUCCESS) {
21222     return rc;
21223   }
21224   UINT32 response_size;
21225   std::string response_size_bytes;
21226   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21227   if (rc != TPM_RC_SUCCESS) {
21228     return rc;
21229   }
21230   TPM_RC response_code;
21231   std::string response_code_bytes;
21232   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21233   if (rc != TPM_RC_SUCCESS) {
21234     return rc;
21235   }
21236   if (response_size != response.size()) {
21237     return TPM_RC_SIZE;
21238   }
21239   if (response_code != TPM_RC_SUCCESS) {
21240     return response_code;
21241   }
21242   TPM_CC command_code = TPM_CC_PolicySigned;
21243   std::string command_code_bytes;
21244   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21245   if (rc != TPM_RC_SUCCESS) {
21246     return rc;
21247   }
21248   std::string authorization_section_bytes;
21249   if (tag == TPM_ST_SESSIONS) {
21250     UINT32 parameter_section_size = buffer.size();
21251     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
21252     if (rc != TPM_RC_SUCCESS) {
21253       return rc;
21254     }
21255     if (parameter_section_size > buffer.size()) {
21256       return TPM_RC_INSUFFICIENT;
21257     }
21258     authorization_section_bytes = buffer.substr(parameter_section_size);
21259     // Keep the parameter section in |buffer|.
21260     buffer.erase(parameter_section_size);
21261   }
21262   std::unique_ptr<crypto::SecureHash> hash(
21263       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21264   hash->Update(response_code_bytes.data(), response_code_bytes.size());
21265   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21266   hash->Update(buffer.data(), buffer.size());
21267   std::string response_hash(32, 0);
21268   hash->Finish(std::data(response_hash), response_hash.size());
21269   if (tag == TPM_ST_SESSIONS) {
21270     if (!authorization_delegate)
21271       return TRUNKS_RC_AUTHORIZATION_FAILED;
21272     if (!authorization_delegate->CheckResponseAuthorization(
21273             response_hash, authorization_section_bytes)) {
21274       return TRUNKS_RC_AUTHORIZATION_FAILED;
21275     }
21276   }
21277   if (tag == TPM_ST_SESSIONS) {
21278     if (!authorization_delegate)
21279       return TRUNKS_RC_AUTHORIZATION_FAILED;
21280 
21281     // Parse the encrypted parameter size.
21282     UINT16 size;
21283     std::string size_buffer = buffer.substr(0, 2);
21284     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
21285       return result;
21286     }
21287     if (buffer.size() < 2 + size) {
21288       return TPM_RC_INSUFFICIENT;
21289     }
21290 
21291     // Decrypt just the parameter data, not the size.
21292     std::string decrypted_data = buffer.substr(2, size);
21293     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
21294       return TRUNKS_RC_ENCRYPTION_FAILED;
21295     }
21296     buffer.replace(2, size, decrypted_data);
21297   }
21298   std::string timeout_bytes;
21299   rc = Parse_TPM2B_TIMEOUT(&buffer, timeout, &timeout_bytes);
21300   if (rc != TPM_RC_SUCCESS) {
21301     return rc;
21302   }
21303   std::string policy_ticket_bytes;
21304   rc = Parse_TPMT_TK_AUTH(&buffer, policy_ticket, &policy_ticket_bytes);
21305   if (rc != TPM_RC_SUCCESS) {
21306     return rc;
21307   }
21308   return TPM_RC_SUCCESS;
21309 }
21310 
PolicySignedErrorCallback(Tpm::PolicySignedResponse callback,TPM_RC response_code)21311 void PolicySignedErrorCallback(Tpm::PolicySignedResponse callback,
21312                                TPM_RC response_code) {
21313   VLOG(1) << __func__;
21314   std::move(callback).Run(response_code, TPM2B_TIMEOUT(), TPMT_TK_AUTH());
21315 }
21316 
PolicySignedResponseParser(Tpm::PolicySignedResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21317 void PolicySignedResponseParser(Tpm::PolicySignedResponse callback,
21318                                 AuthorizationDelegate* authorization_delegate,
21319                                 const std::string& response) {
21320   VLOG(1) << __func__;
21321   TPM2B_TIMEOUT timeout;
21322   TPMT_TK_AUTH policy_ticket;
21323   TPM_RC rc = Tpm::ParseResponse_PolicySigned(
21324       response, &timeout, &policy_ticket, authorization_delegate);
21325   if (rc != TPM_RC_SUCCESS) {
21326     base::OnceCallback<void(TPM_RC)> error_reporter =
21327         base::BindOnce(PolicySignedErrorCallback, std::move(callback));
21328     std::move(error_reporter).Run(rc);
21329     return;
21330   }
21331   std::move(callback).Run(rc, timeout, policy_ticket);
21332 }
21333 
PolicySigned(const TPMI_DH_OBJECT & auth_object,const std::string & auth_object_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,const TPMT_SIGNATURE & auth,AuthorizationDelegate * authorization_delegate,PolicySignedResponse callback)21334 void Tpm::PolicySigned(const TPMI_DH_OBJECT& auth_object,
21335                        const std::string& auth_object_name,
21336                        const TPMI_SH_POLICY& policy_session,
21337                        const std::string& policy_session_name,
21338                        const TPM2B_NONCE& nonce_tpm,
21339                        const TPM2B_DIGEST& cp_hash_a,
21340                        const TPM2B_NONCE& policy_ref,
21341                        const INT32& expiration,
21342                        const TPMT_SIGNATURE& auth,
21343                        AuthorizationDelegate* authorization_delegate,
21344                        PolicySignedResponse callback) {
21345   VLOG(1) << __func__;
21346   std::string command;
21347   TPM_RC rc = SerializeCommand_PolicySigned(
21348       auth_object, auth_object_name, policy_session, policy_session_name,
21349       nonce_tpm, cp_hash_a, policy_ref, expiration, auth, &command,
21350       authorization_delegate);
21351   if (rc != TPM_RC_SUCCESS) {
21352     base::OnceCallback<void(TPM_RC)> error_reporter =
21353         base::BindOnce(PolicySignedErrorCallback, std::move(callback));
21354     std::move(error_reporter).Run(rc);
21355     return;
21356   }
21357   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21358       PolicySignedResponseParser, std::move(callback), authorization_delegate);
21359   transceiver_->SendCommand(command, std::move(parser));
21360 }
21361 
PolicySignedSync(const TPMI_DH_OBJECT & auth_object,const std::string & auth_object_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,const TPMT_SIGNATURE & auth,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21362 TPM_RC Tpm::PolicySignedSync(const TPMI_DH_OBJECT& auth_object,
21363                              const std::string& auth_object_name,
21364                              const TPMI_SH_POLICY& policy_session,
21365                              const std::string& policy_session_name,
21366                              const TPM2B_NONCE& nonce_tpm,
21367                              const TPM2B_DIGEST& cp_hash_a,
21368                              const TPM2B_NONCE& policy_ref,
21369                              const INT32& expiration,
21370                              const TPMT_SIGNATURE& auth,
21371                              TPM2B_TIMEOUT* timeout,
21372                              TPMT_TK_AUTH* policy_ticket,
21373                              AuthorizationDelegate* authorization_delegate) {
21374   VLOG(1) << __func__;
21375   std::string command;
21376   TPM_RC rc = SerializeCommand_PolicySigned(
21377       auth_object, auth_object_name, policy_session, policy_session_name,
21378       nonce_tpm, cp_hash_a, policy_ref, expiration, auth, &command,
21379       authorization_delegate);
21380   if (rc != TPM_RC_SUCCESS) {
21381     return rc;
21382   }
21383   std::string response = transceiver_->SendCommandAndWait(command);
21384   rc = ParseResponse_PolicySigned(response, timeout, policy_ticket,
21385                                   authorization_delegate);
21386   return rc;
21387 }
21388 
SerializeCommand_PolicySecret(const TPMI_DH_ENTITY & auth_handle,const std::string & auth_handle_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21389 TPM_RC Tpm::SerializeCommand_PolicySecret(
21390     const TPMI_DH_ENTITY& auth_handle,
21391     const std::string& auth_handle_name,
21392     const TPMI_SH_POLICY& policy_session,
21393     const std::string& policy_session_name,
21394     const TPM2B_NONCE& nonce_tpm,
21395     const TPM2B_DIGEST& cp_hash_a,
21396     const TPM2B_NONCE& policy_ref,
21397     const INT32& expiration,
21398     std::string* serialized_command,
21399     AuthorizationDelegate* authorization_delegate) {
21400   VLOG(3) << __func__;
21401   TPM_RC rc = TPM_RC_SUCCESS;
21402   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21403   UINT32 command_size = 10;  // Header size.
21404   std::string handle_section_bytes;
21405   std::string parameter_section_bytes;
21406   TPM_CC command_code = TPM_CC_PolicySecret;
21407   bool is_command_parameter_encryption_possible = true;
21408   bool is_response_parameter_encryption_possible = true;
21409   std::string command_code_bytes;
21410   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21411   if (rc != TPM_RC_SUCCESS) {
21412     return rc;
21413   }
21414   std::string auth_handle_bytes;
21415   rc = Serialize_TPMI_DH_ENTITY(auth_handle, &auth_handle_bytes);
21416   if (rc != TPM_RC_SUCCESS) {
21417     return rc;
21418   }
21419   std::string policy_session_bytes;
21420   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21421   if (rc != TPM_RC_SUCCESS) {
21422     return rc;
21423   }
21424   std::string nonce_tpm_bytes;
21425   rc = Serialize_TPM2B_NONCE(nonce_tpm, &nonce_tpm_bytes);
21426   if (rc != TPM_RC_SUCCESS) {
21427     return rc;
21428   }
21429   std::string cp_hash_a_bytes;
21430   rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21431   if (rc != TPM_RC_SUCCESS) {
21432     return rc;
21433   }
21434   std::string policy_ref_bytes;
21435   rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21436   if (rc != TPM_RC_SUCCESS) {
21437     return rc;
21438   }
21439   std::string expiration_bytes;
21440   rc = Serialize_INT32(expiration, &expiration_bytes);
21441   if (rc != TPM_RC_SUCCESS) {
21442     return rc;
21443   }
21444   if (authorization_delegate) {
21445     // Encrypt just the parameter data, not the size.
21446     std::string tmp = nonce_tpm_bytes.substr(2);
21447     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21448       return TRUNKS_RC_ENCRYPTION_FAILED;
21449     }
21450     nonce_tpm_bytes.replace(2, std::string::npos, tmp);
21451   }
21452   std::unique_ptr<crypto::SecureHash> hash(
21453       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21454   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21455   hash->Update(auth_handle_name.data(), auth_handle_name.size());
21456   handle_section_bytes += auth_handle_bytes;
21457   command_size += auth_handle_bytes.size();
21458   hash->Update(policy_session_name.data(), policy_session_name.size());
21459   handle_section_bytes += policy_session_bytes;
21460   command_size += policy_session_bytes.size();
21461   hash->Update(nonce_tpm_bytes.data(), nonce_tpm_bytes.size());
21462   parameter_section_bytes += nonce_tpm_bytes;
21463   command_size += nonce_tpm_bytes.size();
21464   hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21465   parameter_section_bytes += cp_hash_a_bytes;
21466   command_size += cp_hash_a_bytes.size();
21467   hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21468   parameter_section_bytes += policy_ref_bytes;
21469   command_size += policy_ref_bytes.size();
21470   hash->Update(expiration_bytes.data(), expiration_bytes.size());
21471   parameter_section_bytes += expiration_bytes;
21472   command_size += expiration_bytes.size();
21473   std::string command_hash(32, 0);
21474   hash->Finish(std::data(command_hash), command_hash.size());
21475   std::string authorization_section_bytes;
21476   std::string authorization_size_bytes;
21477   if (authorization_delegate) {
21478     if (!authorization_delegate->GetCommandAuthorization(
21479             command_hash, is_command_parameter_encryption_possible,
21480             is_response_parameter_encryption_possible,
21481             &authorization_section_bytes)) {
21482       return TRUNKS_RC_AUTHORIZATION_FAILED;
21483     }
21484     if (!authorization_section_bytes.empty()) {
21485       tag = TPM_ST_SESSIONS;
21486       std::string tmp;
21487       rc = Serialize_UINT32(authorization_section_bytes.size(),
21488                             &authorization_size_bytes);
21489       if (rc != TPM_RC_SUCCESS) {
21490         return rc;
21491       }
21492       command_size +=
21493           authorization_size_bytes.size() + authorization_section_bytes.size();
21494     }
21495   }
21496   std::string tag_bytes;
21497   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21498   if (rc != TPM_RC_SUCCESS) {
21499     return rc;
21500   }
21501   std::string command_size_bytes;
21502   rc = Serialize_UINT32(command_size, &command_size_bytes);
21503   if (rc != TPM_RC_SUCCESS) {
21504     return rc;
21505   }
21506   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21507                         handle_section_bytes + authorization_size_bytes +
21508                         authorization_section_bytes + parameter_section_bytes;
21509   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21510   VLOG(2) << "Command: "
21511           << base::HexEncode(serialized_command->data(),
21512                              serialized_command->size());
21513   return TPM_RC_SUCCESS;
21514 }
21515 
ParseResponse_PolicySecret(const std::string & response,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21516 TPM_RC Tpm::ParseResponse_PolicySecret(
21517     const std::string& response,
21518     TPM2B_TIMEOUT* timeout,
21519     TPMT_TK_AUTH* policy_ticket,
21520     AuthorizationDelegate* authorization_delegate) {
21521   VLOG(3) << __func__;
21522   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21523   TPM_RC rc = TPM_RC_SUCCESS;
21524   std::string buffer(response);
21525   TPM_ST tag;
21526   std::string tag_bytes;
21527   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21528   if (rc != TPM_RC_SUCCESS) {
21529     return rc;
21530   }
21531   UINT32 response_size;
21532   std::string response_size_bytes;
21533   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21534   if (rc != TPM_RC_SUCCESS) {
21535     return rc;
21536   }
21537   TPM_RC response_code;
21538   std::string response_code_bytes;
21539   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21540   if (rc != TPM_RC_SUCCESS) {
21541     return rc;
21542   }
21543   if (response_size != response.size()) {
21544     return TPM_RC_SIZE;
21545   }
21546   if (response_code != TPM_RC_SUCCESS) {
21547     return response_code;
21548   }
21549   TPM_CC command_code = TPM_CC_PolicySecret;
21550   std::string command_code_bytes;
21551   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21552   if (rc != TPM_RC_SUCCESS) {
21553     return rc;
21554   }
21555   std::string authorization_section_bytes;
21556   if (tag == TPM_ST_SESSIONS) {
21557     UINT32 parameter_section_size = buffer.size();
21558     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
21559     if (rc != TPM_RC_SUCCESS) {
21560       return rc;
21561     }
21562     if (parameter_section_size > buffer.size()) {
21563       return TPM_RC_INSUFFICIENT;
21564     }
21565     authorization_section_bytes = buffer.substr(parameter_section_size);
21566     // Keep the parameter section in |buffer|.
21567     buffer.erase(parameter_section_size);
21568   }
21569   std::unique_ptr<crypto::SecureHash> hash(
21570       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21571   hash->Update(response_code_bytes.data(), response_code_bytes.size());
21572   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21573   hash->Update(buffer.data(), buffer.size());
21574   std::string response_hash(32, 0);
21575   hash->Finish(std::data(response_hash), response_hash.size());
21576   if (tag == TPM_ST_SESSIONS) {
21577     if (!authorization_delegate)
21578       return TRUNKS_RC_AUTHORIZATION_FAILED;
21579     if (!authorization_delegate->CheckResponseAuthorization(
21580             response_hash, authorization_section_bytes)) {
21581       return TRUNKS_RC_AUTHORIZATION_FAILED;
21582     }
21583   }
21584   if (tag == TPM_ST_SESSIONS) {
21585     if (!authorization_delegate)
21586       return TRUNKS_RC_AUTHORIZATION_FAILED;
21587 
21588     // Parse the encrypted parameter size.
21589     UINT16 size;
21590     std::string size_buffer = buffer.substr(0, 2);
21591     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
21592       return result;
21593     }
21594     if (buffer.size() < 2 + size) {
21595       return TPM_RC_INSUFFICIENT;
21596     }
21597 
21598     // Decrypt just the parameter data, not the size.
21599     std::string decrypted_data = buffer.substr(2, size);
21600     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
21601       return TRUNKS_RC_ENCRYPTION_FAILED;
21602     }
21603     buffer.replace(2, size, decrypted_data);
21604   }
21605   std::string timeout_bytes;
21606   rc = Parse_TPM2B_TIMEOUT(&buffer, timeout, &timeout_bytes);
21607   if (rc != TPM_RC_SUCCESS) {
21608     return rc;
21609   }
21610   std::string policy_ticket_bytes;
21611   rc = Parse_TPMT_TK_AUTH(&buffer, policy_ticket, &policy_ticket_bytes);
21612   if (rc != TPM_RC_SUCCESS) {
21613     return rc;
21614   }
21615   return TPM_RC_SUCCESS;
21616 }
21617 
PolicySecretErrorCallback(Tpm::PolicySecretResponse callback,TPM_RC response_code)21618 void PolicySecretErrorCallback(Tpm::PolicySecretResponse callback,
21619                                TPM_RC response_code) {
21620   VLOG(1) << __func__;
21621   std::move(callback).Run(response_code, TPM2B_TIMEOUT(), TPMT_TK_AUTH());
21622 }
21623 
PolicySecretResponseParser(Tpm::PolicySecretResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21624 void PolicySecretResponseParser(Tpm::PolicySecretResponse callback,
21625                                 AuthorizationDelegate* authorization_delegate,
21626                                 const std::string& response) {
21627   VLOG(1) << __func__;
21628   TPM2B_TIMEOUT timeout;
21629   TPMT_TK_AUTH policy_ticket;
21630   TPM_RC rc = Tpm::ParseResponse_PolicySecret(
21631       response, &timeout, &policy_ticket, authorization_delegate);
21632   if (rc != TPM_RC_SUCCESS) {
21633     base::OnceCallback<void(TPM_RC)> error_reporter =
21634         base::BindOnce(PolicySecretErrorCallback, std::move(callback));
21635     std::move(error_reporter).Run(rc);
21636     return;
21637   }
21638   std::move(callback).Run(rc, timeout, policy_ticket);
21639 }
21640 
PolicySecret(const TPMI_DH_ENTITY & auth_handle,const std::string & auth_handle_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,AuthorizationDelegate * authorization_delegate,PolicySecretResponse callback)21641 void Tpm::PolicySecret(const TPMI_DH_ENTITY& auth_handle,
21642                        const std::string& auth_handle_name,
21643                        const TPMI_SH_POLICY& policy_session,
21644                        const std::string& policy_session_name,
21645                        const TPM2B_NONCE& nonce_tpm,
21646                        const TPM2B_DIGEST& cp_hash_a,
21647                        const TPM2B_NONCE& policy_ref,
21648                        const INT32& expiration,
21649                        AuthorizationDelegate* authorization_delegate,
21650                        PolicySecretResponse callback) {
21651   VLOG(1) << __func__;
21652   std::string command;
21653   TPM_RC rc = SerializeCommand_PolicySecret(
21654       auth_handle, auth_handle_name, policy_session, policy_session_name,
21655       nonce_tpm, cp_hash_a, policy_ref, expiration, &command,
21656       authorization_delegate);
21657   if (rc != TPM_RC_SUCCESS) {
21658     base::OnceCallback<void(TPM_RC)> error_reporter =
21659         base::BindOnce(PolicySecretErrorCallback, std::move(callback));
21660     std::move(error_reporter).Run(rc);
21661     return;
21662   }
21663   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21664       PolicySecretResponseParser, std::move(callback), authorization_delegate);
21665   transceiver_->SendCommand(command, std::move(parser));
21666 }
21667 
PolicySecretSync(const TPMI_DH_ENTITY & auth_handle,const std::string & auth_handle_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21668 TPM_RC Tpm::PolicySecretSync(const TPMI_DH_ENTITY& auth_handle,
21669                              const std::string& auth_handle_name,
21670                              const TPMI_SH_POLICY& policy_session,
21671                              const std::string& policy_session_name,
21672                              const TPM2B_NONCE& nonce_tpm,
21673                              const TPM2B_DIGEST& cp_hash_a,
21674                              const TPM2B_NONCE& policy_ref,
21675                              const INT32& expiration,
21676                              TPM2B_TIMEOUT* timeout,
21677                              TPMT_TK_AUTH* policy_ticket,
21678                              AuthorizationDelegate* authorization_delegate) {
21679   VLOG(1) << __func__;
21680   std::string command;
21681   TPM_RC rc = SerializeCommand_PolicySecret(
21682       auth_handle, auth_handle_name, policy_session, policy_session_name,
21683       nonce_tpm, cp_hash_a, policy_ref, expiration, &command,
21684       authorization_delegate);
21685   if (rc != TPM_RC_SUCCESS) {
21686     return rc;
21687   }
21688   std::string response = transceiver_->SendCommandAndWait(command);
21689   rc = ParseResponse_PolicySecret(response, timeout, policy_ticket,
21690                                   authorization_delegate);
21691   return rc;
21692 }
21693 
SerializeCommand_PolicyTicket(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_TIMEOUT & timeout,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & auth_name,const TPMT_TK_AUTH & ticket,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21694 TPM_RC Tpm::SerializeCommand_PolicyTicket(
21695     const TPMI_SH_POLICY& policy_session,
21696     const std::string& policy_session_name,
21697     const TPM2B_TIMEOUT& timeout,
21698     const TPM2B_DIGEST& cp_hash_a,
21699     const TPM2B_NONCE& policy_ref,
21700     const TPM2B_NAME& auth_name,
21701     const TPMT_TK_AUTH& ticket,
21702     std::string* serialized_command,
21703     AuthorizationDelegate* authorization_delegate) {
21704   VLOG(3) << __func__;
21705   TPM_RC rc = TPM_RC_SUCCESS;
21706   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21707   UINT32 command_size = 10;  // Header size.
21708   std::string handle_section_bytes;
21709   std::string parameter_section_bytes;
21710   TPM_CC command_code = TPM_CC_PolicyTicket;
21711   bool is_command_parameter_encryption_possible = true;
21712   bool is_response_parameter_encryption_possible = false;
21713   std::string command_code_bytes;
21714   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21715   if (rc != TPM_RC_SUCCESS) {
21716     return rc;
21717   }
21718   std::string policy_session_bytes;
21719   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21720   if (rc != TPM_RC_SUCCESS) {
21721     return rc;
21722   }
21723   std::string timeout_bytes;
21724   rc = Serialize_TPM2B_TIMEOUT(timeout, &timeout_bytes);
21725   if (rc != TPM_RC_SUCCESS) {
21726     return rc;
21727   }
21728   std::string cp_hash_a_bytes;
21729   rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21730   if (rc != TPM_RC_SUCCESS) {
21731     return rc;
21732   }
21733   std::string policy_ref_bytes;
21734   rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21735   if (rc != TPM_RC_SUCCESS) {
21736     return rc;
21737   }
21738   std::string auth_name_bytes;
21739   rc = Serialize_TPM2B_NAME(auth_name, &auth_name_bytes);
21740   if (rc != TPM_RC_SUCCESS) {
21741     return rc;
21742   }
21743   std::string ticket_bytes;
21744   rc = Serialize_TPMT_TK_AUTH(ticket, &ticket_bytes);
21745   if (rc != TPM_RC_SUCCESS) {
21746     return rc;
21747   }
21748   if (authorization_delegate) {
21749     // Encrypt just the parameter data, not the size.
21750     std::string tmp = timeout_bytes.substr(2);
21751     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21752       return TRUNKS_RC_ENCRYPTION_FAILED;
21753     }
21754     timeout_bytes.replace(2, std::string::npos, tmp);
21755   }
21756   std::unique_ptr<crypto::SecureHash> hash(
21757       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21758   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21759   hash->Update(policy_session_name.data(), policy_session_name.size());
21760   handle_section_bytes += policy_session_bytes;
21761   command_size += policy_session_bytes.size();
21762   hash->Update(timeout_bytes.data(), timeout_bytes.size());
21763   parameter_section_bytes += timeout_bytes;
21764   command_size += timeout_bytes.size();
21765   hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21766   parameter_section_bytes += cp_hash_a_bytes;
21767   command_size += cp_hash_a_bytes.size();
21768   hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21769   parameter_section_bytes += policy_ref_bytes;
21770   command_size += policy_ref_bytes.size();
21771   hash->Update(auth_name_bytes.data(), auth_name_bytes.size());
21772   parameter_section_bytes += auth_name_bytes;
21773   command_size += auth_name_bytes.size();
21774   hash->Update(ticket_bytes.data(), ticket_bytes.size());
21775   parameter_section_bytes += ticket_bytes;
21776   command_size += ticket_bytes.size();
21777   std::string command_hash(32, 0);
21778   hash->Finish(std::data(command_hash), command_hash.size());
21779   std::string authorization_section_bytes;
21780   std::string authorization_size_bytes;
21781   if (authorization_delegate) {
21782     if (!authorization_delegate->GetCommandAuthorization(
21783             command_hash, is_command_parameter_encryption_possible,
21784             is_response_parameter_encryption_possible,
21785             &authorization_section_bytes)) {
21786       return TRUNKS_RC_AUTHORIZATION_FAILED;
21787     }
21788     if (!authorization_section_bytes.empty()) {
21789       tag = TPM_ST_SESSIONS;
21790       std::string tmp;
21791       rc = Serialize_UINT32(authorization_section_bytes.size(),
21792                             &authorization_size_bytes);
21793       if (rc != TPM_RC_SUCCESS) {
21794         return rc;
21795       }
21796       command_size +=
21797           authorization_size_bytes.size() + authorization_section_bytes.size();
21798     }
21799   }
21800   std::string tag_bytes;
21801   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21802   if (rc != TPM_RC_SUCCESS) {
21803     return rc;
21804   }
21805   std::string command_size_bytes;
21806   rc = Serialize_UINT32(command_size, &command_size_bytes);
21807   if (rc != TPM_RC_SUCCESS) {
21808     return rc;
21809   }
21810   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21811                         handle_section_bytes + authorization_size_bytes +
21812                         authorization_section_bytes + parameter_section_bytes;
21813   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21814   VLOG(2) << "Command: "
21815           << base::HexEncode(serialized_command->data(),
21816                              serialized_command->size());
21817   return TPM_RC_SUCCESS;
21818 }
21819 
ParseResponse_PolicyTicket(const std::string & response,AuthorizationDelegate * authorization_delegate)21820 TPM_RC Tpm::ParseResponse_PolicyTicket(
21821     const std::string& response,
21822     AuthorizationDelegate* authorization_delegate) {
21823   VLOG(3) << __func__;
21824   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21825   TPM_RC rc = TPM_RC_SUCCESS;
21826   std::string buffer(response);
21827   TPM_ST tag;
21828   std::string tag_bytes;
21829   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21830   if (rc != TPM_RC_SUCCESS) {
21831     return rc;
21832   }
21833   UINT32 response_size;
21834   std::string response_size_bytes;
21835   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21836   if (rc != TPM_RC_SUCCESS) {
21837     return rc;
21838   }
21839   TPM_RC response_code;
21840   std::string response_code_bytes;
21841   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21842   if (rc != TPM_RC_SUCCESS) {
21843     return rc;
21844   }
21845   if (response_size != response.size()) {
21846     return TPM_RC_SIZE;
21847   }
21848   if (response_code != TPM_RC_SUCCESS) {
21849     return response_code;
21850   }
21851   TPM_CC command_code = TPM_CC_PolicyTicket;
21852   std::string command_code_bytes;
21853   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21854   if (rc != TPM_RC_SUCCESS) {
21855     return rc;
21856   }
21857   std::string authorization_section_bytes;
21858   if (tag == TPM_ST_SESSIONS) {
21859     UINT32 parameter_section_size = buffer.size();
21860     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
21861     if (rc != TPM_RC_SUCCESS) {
21862       return rc;
21863     }
21864     if (parameter_section_size > buffer.size()) {
21865       return TPM_RC_INSUFFICIENT;
21866     }
21867     authorization_section_bytes = buffer.substr(parameter_section_size);
21868     // Keep the parameter section in |buffer|.
21869     buffer.erase(parameter_section_size);
21870   }
21871   std::unique_ptr<crypto::SecureHash> hash(
21872       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21873   hash->Update(response_code_bytes.data(), response_code_bytes.size());
21874   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21875   hash->Update(buffer.data(), buffer.size());
21876   std::string response_hash(32, 0);
21877   hash->Finish(std::data(response_hash), response_hash.size());
21878   if (tag == TPM_ST_SESSIONS) {
21879     if (!authorization_delegate)
21880       return TRUNKS_RC_AUTHORIZATION_FAILED;
21881     if (!authorization_delegate->CheckResponseAuthorization(
21882             response_hash, authorization_section_bytes)) {
21883       return TRUNKS_RC_AUTHORIZATION_FAILED;
21884     }
21885   }
21886   return TPM_RC_SUCCESS;
21887 }
21888 
PolicyTicketErrorCallback(Tpm::PolicyTicketResponse callback,TPM_RC response_code)21889 void PolicyTicketErrorCallback(Tpm::PolicyTicketResponse callback,
21890                                TPM_RC response_code) {
21891   VLOG(1) << __func__;
21892   std::move(callback).Run(response_code);
21893 }
21894 
PolicyTicketResponseParser(Tpm::PolicyTicketResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21895 void PolicyTicketResponseParser(Tpm::PolicyTicketResponse callback,
21896                                 AuthorizationDelegate* authorization_delegate,
21897                                 const std::string& response) {
21898   VLOG(1) << __func__;
21899   TPM_RC rc = Tpm::ParseResponse_PolicyTicket(response, authorization_delegate);
21900   if (rc != TPM_RC_SUCCESS) {
21901     base::OnceCallback<void(TPM_RC)> error_reporter =
21902         base::BindOnce(PolicyTicketErrorCallback, std::move(callback));
21903     std::move(error_reporter).Run(rc);
21904     return;
21905   }
21906   std::move(callback).Run(rc);
21907 }
21908 
PolicyTicket(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_TIMEOUT & timeout,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & auth_name,const TPMT_TK_AUTH & ticket,AuthorizationDelegate * authorization_delegate,PolicyTicketResponse callback)21909 void Tpm::PolicyTicket(const TPMI_SH_POLICY& policy_session,
21910                        const std::string& policy_session_name,
21911                        const TPM2B_TIMEOUT& timeout,
21912                        const TPM2B_DIGEST& cp_hash_a,
21913                        const TPM2B_NONCE& policy_ref,
21914                        const TPM2B_NAME& auth_name,
21915                        const TPMT_TK_AUTH& ticket,
21916                        AuthorizationDelegate* authorization_delegate,
21917                        PolicyTicketResponse callback) {
21918   VLOG(1) << __func__;
21919   std::string command;
21920   TPM_RC rc = SerializeCommand_PolicyTicket(
21921       policy_session, policy_session_name, timeout, cp_hash_a, policy_ref,
21922       auth_name, ticket, &command, authorization_delegate);
21923   if (rc != TPM_RC_SUCCESS) {
21924     base::OnceCallback<void(TPM_RC)> error_reporter =
21925         base::BindOnce(PolicyTicketErrorCallback, std::move(callback));
21926     std::move(error_reporter).Run(rc);
21927     return;
21928   }
21929   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21930       PolicyTicketResponseParser, std::move(callback), authorization_delegate);
21931   transceiver_->SendCommand(command, std::move(parser));
21932 }
21933 
PolicyTicketSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_TIMEOUT & timeout,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & auth_name,const TPMT_TK_AUTH & ticket,AuthorizationDelegate * authorization_delegate)21934 TPM_RC Tpm::PolicyTicketSync(const TPMI_SH_POLICY& policy_session,
21935                              const std::string& policy_session_name,
21936                              const TPM2B_TIMEOUT& timeout,
21937                              const TPM2B_DIGEST& cp_hash_a,
21938                              const TPM2B_NONCE& policy_ref,
21939                              const TPM2B_NAME& auth_name,
21940                              const TPMT_TK_AUTH& ticket,
21941                              AuthorizationDelegate* authorization_delegate) {
21942   VLOG(1) << __func__;
21943   std::string command;
21944   TPM_RC rc = SerializeCommand_PolicyTicket(
21945       policy_session, policy_session_name, timeout, cp_hash_a, policy_ref,
21946       auth_name, ticket, &command, authorization_delegate);
21947   if (rc != TPM_RC_SUCCESS) {
21948     return rc;
21949   }
21950   std::string response = transceiver_->SendCommandAndWait(command);
21951   rc = ParseResponse_PolicyTicket(response, authorization_delegate);
21952   return rc;
21953 }
21954 
SerializeCommand_PolicyOR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21955 TPM_RC Tpm::SerializeCommand_PolicyOR(
21956     const TPMI_SH_POLICY& policy_session,
21957     const std::string& policy_session_name,
21958     const TPML_DIGEST& p_hash_list,
21959     std::string* serialized_command,
21960     AuthorizationDelegate* authorization_delegate) {
21961   VLOG(3) << __func__;
21962   TPM_RC rc = TPM_RC_SUCCESS;
21963   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21964   UINT32 command_size = 10;  // Header size.
21965   std::string handle_section_bytes;
21966   std::string parameter_section_bytes;
21967   TPM_CC command_code = TPM_CC_PolicyOR;
21968   bool is_command_parameter_encryption_possible = false;
21969   bool is_response_parameter_encryption_possible = false;
21970   std::string command_code_bytes;
21971   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21972   if (rc != TPM_RC_SUCCESS) {
21973     return rc;
21974   }
21975   std::string policy_session_bytes;
21976   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21977   if (rc != TPM_RC_SUCCESS) {
21978     return rc;
21979   }
21980   std::string p_hash_list_bytes;
21981   rc = Serialize_TPML_DIGEST(p_hash_list, &p_hash_list_bytes);
21982   if (rc != TPM_RC_SUCCESS) {
21983     return rc;
21984   }
21985   std::unique_ptr<crypto::SecureHash> hash(
21986       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21987   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21988   hash->Update(policy_session_name.data(), policy_session_name.size());
21989   handle_section_bytes += policy_session_bytes;
21990   command_size += policy_session_bytes.size();
21991   hash->Update(p_hash_list_bytes.data(), p_hash_list_bytes.size());
21992   parameter_section_bytes += p_hash_list_bytes;
21993   command_size += p_hash_list_bytes.size();
21994   std::string command_hash(32, 0);
21995   hash->Finish(std::data(command_hash), command_hash.size());
21996   std::string authorization_section_bytes;
21997   std::string authorization_size_bytes;
21998   if (authorization_delegate) {
21999     if (!authorization_delegate->GetCommandAuthorization(
22000             command_hash, is_command_parameter_encryption_possible,
22001             is_response_parameter_encryption_possible,
22002             &authorization_section_bytes)) {
22003       return TRUNKS_RC_AUTHORIZATION_FAILED;
22004     }
22005     if (!authorization_section_bytes.empty()) {
22006       tag = TPM_ST_SESSIONS;
22007       std::string tmp;
22008       rc = Serialize_UINT32(authorization_section_bytes.size(),
22009                             &authorization_size_bytes);
22010       if (rc != TPM_RC_SUCCESS) {
22011         return rc;
22012       }
22013       command_size +=
22014           authorization_size_bytes.size() + authorization_section_bytes.size();
22015     }
22016   }
22017   std::string tag_bytes;
22018   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22019   if (rc != TPM_RC_SUCCESS) {
22020     return rc;
22021   }
22022   std::string command_size_bytes;
22023   rc = Serialize_UINT32(command_size, &command_size_bytes);
22024   if (rc != TPM_RC_SUCCESS) {
22025     return rc;
22026   }
22027   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22028                         handle_section_bytes + authorization_size_bytes +
22029                         authorization_section_bytes + parameter_section_bytes;
22030   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22031   VLOG(2) << "Command: "
22032           << base::HexEncode(serialized_command->data(),
22033                              serialized_command->size());
22034   return TPM_RC_SUCCESS;
22035 }
22036 
ParseResponse_PolicyOR(const std::string & response,AuthorizationDelegate * authorization_delegate)22037 TPM_RC Tpm::ParseResponse_PolicyOR(
22038     const std::string& response,
22039     AuthorizationDelegate* authorization_delegate) {
22040   VLOG(3) << __func__;
22041   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22042   TPM_RC rc = TPM_RC_SUCCESS;
22043   std::string buffer(response);
22044   TPM_ST tag;
22045   std::string tag_bytes;
22046   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22047   if (rc != TPM_RC_SUCCESS) {
22048     return rc;
22049   }
22050   UINT32 response_size;
22051   std::string response_size_bytes;
22052   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22053   if (rc != TPM_RC_SUCCESS) {
22054     return rc;
22055   }
22056   TPM_RC response_code;
22057   std::string response_code_bytes;
22058   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22059   if (rc != TPM_RC_SUCCESS) {
22060     return rc;
22061   }
22062   if (response_size != response.size()) {
22063     return TPM_RC_SIZE;
22064   }
22065   if (response_code != TPM_RC_SUCCESS) {
22066     return response_code;
22067   }
22068   TPM_CC command_code = TPM_CC_PolicyOR;
22069   std::string command_code_bytes;
22070   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22071   if (rc != TPM_RC_SUCCESS) {
22072     return rc;
22073   }
22074   std::string authorization_section_bytes;
22075   if (tag == TPM_ST_SESSIONS) {
22076     UINT32 parameter_section_size = buffer.size();
22077     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22078     if (rc != TPM_RC_SUCCESS) {
22079       return rc;
22080     }
22081     if (parameter_section_size > buffer.size()) {
22082       return TPM_RC_INSUFFICIENT;
22083     }
22084     authorization_section_bytes = buffer.substr(parameter_section_size);
22085     // Keep the parameter section in |buffer|.
22086     buffer.erase(parameter_section_size);
22087   }
22088   std::unique_ptr<crypto::SecureHash> hash(
22089       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22090   hash->Update(response_code_bytes.data(), response_code_bytes.size());
22091   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22092   hash->Update(buffer.data(), buffer.size());
22093   std::string response_hash(32, 0);
22094   hash->Finish(std::data(response_hash), response_hash.size());
22095   if (tag == TPM_ST_SESSIONS) {
22096     if (!authorization_delegate)
22097       return TRUNKS_RC_AUTHORIZATION_FAILED;
22098     if (!authorization_delegate->CheckResponseAuthorization(
22099             response_hash, authorization_section_bytes)) {
22100       return TRUNKS_RC_AUTHORIZATION_FAILED;
22101     }
22102   }
22103   return TPM_RC_SUCCESS;
22104 }
22105 
PolicyORErrorCallback(Tpm::PolicyORResponse callback,TPM_RC response_code)22106 void PolicyORErrorCallback(Tpm::PolicyORResponse callback,
22107                            TPM_RC response_code) {
22108   VLOG(1) << __func__;
22109   std::move(callback).Run(response_code);
22110 }
22111 
PolicyORResponseParser(Tpm::PolicyORResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22112 void PolicyORResponseParser(Tpm::PolicyORResponse callback,
22113                             AuthorizationDelegate* authorization_delegate,
22114                             const std::string& response) {
22115   VLOG(1) << __func__;
22116   TPM_RC rc = Tpm::ParseResponse_PolicyOR(response, authorization_delegate);
22117   if (rc != TPM_RC_SUCCESS) {
22118     base::OnceCallback<void(TPM_RC)> error_reporter =
22119         base::BindOnce(PolicyORErrorCallback, std::move(callback));
22120     std::move(error_reporter).Run(rc);
22121     return;
22122   }
22123   std::move(callback).Run(rc);
22124 }
22125 
PolicyOR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,AuthorizationDelegate * authorization_delegate,PolicyORResponse callback)22126 void Tpm::PolicyOR(const TPMI_SH_POLICY& policy_session,
22127                    const std::string& policy_session_name,
22128                    const TPML_DIGEST& p_hash_list,
22129                    AuthorizationDelegate* authorization_delegate,
22130                    PolicyORResponse callback) {
22131   VLOG(1) << __func__;
22132   std::string command;
22133   TPM_RC rc =
22134       SerializeCommand_PolicyOR(policy_session, policy_session_name,
22135                                 p_hash_list, &command, authorization_delegate);
22136   if (rc != TPM_RC_SUCCESS) {
22137     base::OnceCallback<void(TPM_RC)> error_reporter =
22138         base::BindOnce(PolicyORErrorCallback, std::move(callback));
22139     std::move(error_reporter).Run(rc);
22140     return;
22141   }
22142   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22143       PolicyORResponseParser, std::move(callback), authorization_delegate);
22144   transceiver_->SendCommand(command, std::move(parser));
22145 }
22146 
PolicyORSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,AuthorizationDelegate * authorization_delegate)22147 TPM_RC Tpm::PolicyORSync(const TPMI_SH_POLICY& policy_session,
22148                          const std::string& policy_session_name,
22149                          const TPML_DIGEST& p_hash_list,
22150                          AuthorizationDelegate* authorization_delegate) {
22151   VLOG(1) << __func__;
22152   std::string command;
22153   TPM_RC rc =
22154       SerializeCommand_PolicyOR(policy_session, policy_session_name,
22155                                 p_hash_list, &command, authorization_delegate);
22156   if (rc != TPM_RC_SUCCESS) {
22157     return rc;
22158   }
22159   std::string response = transceiver_->SendCommandAndWait(command);
22160   rc = ParseResponse_PolicyOR(response, authorization_delegate);
22161   return rc;
22162 }
22163 
SerializeCommand_PolicyPCR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & pcr_digest,const TPML_PCR_SELECTION & pcrs,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22164 TPM_RC Tpm::SerializeCommand_PolicyPCR(
22165     const TPMI_SH_POLICY& policy_session,
22166     const std::string& policy_session_name,
22167     const TPM2B_DIGEST& pcr_digest,
22168     const TPML_PCR_SELECTION& pcrs,
22169     std::string* serialized_command,
22170     AuthorizationDelegate* authorization_delegate) {
22171   VLOG(3) << __func__;
22172   TPM_RC rc = TPM_RC_SUCCESS;
22173   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22174   UINT32 command_size = 10;  // Header size.
22175   std::string handle_section_bytes;
22176   std::string parameter_section_bytes;
22177   TPM_CC command_code = TPM_CC_PolicyPCR;
22178   bool is_command_parameter_encryption_possible = true;
22179   bool is_response_parameter_encryption_possible = false;
22180   std::string command_code_bytes;
22181   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22182   if (rc != TPM_RC_SUCCESS) {
22183     return rc;
22184   }
22185   std::string policy_session_bytes;
22186   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22187   if (rc != TPM_RC_SUCCESS) {
22188     return rc;
22189   }
22190   std::string pcr_digest_bytes;
22191   rc = Serialize_TPM2B_DIGEST(pcr_digest, &pcr_digest_bytes);
22192   if (rc != TPM_RC_SUCCESS) {
22193     return rc;
22194   }
22195   std::string pcrs_bytes;
22196   rc = Serialize_TPML_PCR_SELECTION(pcrs, &pcrs_bytes);
22197   if (rc != TPM_RC_SUCCESS) {
22198     return rc;
22199   }
22200   if (authorization_delegate) {
22201     // Encrypt just the parameter data, not the size.
22202     std::string tmp = pcr_digest_bytes.substr(2);
22203     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22204       return TRUNKS_RC_ENCRYPTION_FAILED;
22205     }
22206     pcr_digest_bytes.replace(2, std::string::npos, tmp);
22207   }
22208   std::unique_ptr<crypto::SecureHash> hash(
22209       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22210   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22211   hash->Update(policy_session_name.data(), policy_session_name.size());
22212   handle_section_bytes += policy_session_bytes;
22213   command_size += policy_session_bytes.size();
22214   hash->Update(pcr_digest_bytes.data(), pcr_digest_bytes.size());
22215   parameter_section_bytes += pcr_digest_bytes;
22216   command_size += pcr_digest_bytes.size();
22217   hash->Update(pcrs_bytes.data(), pcrs_bytes.size());
22218   parameter_section_bytes += pcrs_bytes;
22219   command_size += pcrs_bytes.size();
22220   std::string command_hash(32, 0);
22221   hash->Finish(std::data(command_hash), command_hash.size());
22222   std::string authorization_section_bytes;
22223   std::string authorization_size_bytes;
22224   if (authorization_delegate) {
22225     if (!authorization_delegate->GetCommandAuthorization(
22226             command_hash, is_command_parameter_encryption_possible,
22227             is_response_parameter_encryption_possible,
22228             &authorization_section_bytes)) {
22229       return TRUNKS_RC_AUTHORIZATION_FAILED;
22230     }
22231     if (!authorization_section_bytes.empty()) {
22232       tag = TPM_ST_SESSIONS;
22233       std::string tmp;
22234       rc = Serialize_UINT32(authorization_section_bytes.size(),
22235                             &authorization_size_bytes);
22236       if (rc != TPM_RC_SUCCESS) {
22237         return rc;
22238       }
22239       command_size +=
22240           authorization_size_bytes.size() + authorization_section_bytes.size();
22241     }
22242   }
22243   std::string tag_bytes;
22244   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22245   if (rc != TPM_RC_SUCCESS) {
22246     return rc;
22247   }
22248   std::string command_size_bytes;
22249   rc = Serialize_UINT32(command_size, &command_size_bytes);
22250   if (rc != TPM_RC_SUCCESS) {
22251     return rc;
22252   }
22253   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22254                         handle_section_bytes + authorization_size_bytes +
22255                         authorization_section_bytes + parameter_section_bytes;
22256   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22257   VLOG(2) << "Command: "
22258           << base::HexEncode(serialized_command->data(),
22259                              serialized_command->size());
22260   return TPM_RC_SUCCESS;
22261 }
22262 
ParseResponse_PolicyPCR(const std::string & response,AuthorizationDelegate * authorization_delegate)22263 TPM_RC Tpm::ParseResponse_PolicyPCR(
22264     const std::string& response,
22265     AuthorizationDelegate* authorization_delegate) {
22266   VLOG(3) << __func__;
22267   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22268   TPM_RC rc = TPM_RC_SUCCESS;
22269   std::string buffer(response);
22270   TPM_ST tag;
22271   std::string tag_bytes;
22272   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22273   if (rc != TPM_RC_SUCCESS) {
22274     return rc;
22275   }
22276   UINT32 response_size;
22277   std::string response_size_bytes;
22278   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22279   if (rc != TPM_RC_SUCCESS) {
22280     return rc;
22281   }
22282   TPM_RC response_code;
22283   std::string response_code_bytes;
22284   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22285   if (rc != TPM_RC_SUCCESS) {
22286     return rc;
22287   }
22288   if (response_size != response.size()) {
22289     return TPM_RC_SIZE;
22290   }
22291   if (response_code != TPM_RC_SUCCESS) {
22292     return response_code;
22293   }
22294   TPM_CC command_code = TPM_CC_PolicyPCR;
22295   std::string command_code_bytes;
22296   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22297   if (rc != TPM_RC_SUCCESS) {
22298     return rc;
22299   }
22300   std::string authorization_section_bytes;
22301   if (tag == TPM_ST_SESSIONS) {
22302     UINT32 parameter_section_size = buffer.size();
22303     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22304     if (rc != TPM_RC_SUCCESS) {
22305       return rc;
22306     }
22307     if (parameter_section_size > buffer.size()) {
22308       return TPM_RC_INSUFFICIENT;
22309     }
22310     authorization_section_bytes = buffer.substr(parameter_section_size);
22311     // Keep the parameter section in |buffer|.
22312     buffer.erase(parameter_section_size);
22313   }
22314   std::unique_ptr<crypto::SecureHash> hash(
22315       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22316   hash->Update(response_code_bytes.data(), response_code_bytes.size());
22317   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22318   hash->Update(buffer.data(), buffer.size());
22319   std::string response_hash(32, 0);
22320   hash->Finish(std::data(response_hash), response_hash.size());
22321   if (tag == TPM_ST_SESSIONS) {
22322     if (!authorization_delegate)
22323       return TRUNKS_RC_AUTHORIZATION_FAILED;
22324     if (!authorization_delegate->CheckResponseAuthorization(
22325             response_hash, authorization_section_bytes)) {
22326       return TRUNKS_RC_AUTHORIZATION_FAILED;
22327     }
22328   }
22329   return TPM_RC_SUCCESS;
22330 }
22331 
PolicyPCRErrorCallback(Tpm::PolicyPCRResponse callback,TPM_RC response_code)22332 void PolicyPCRErrorCallback(Tpm::PolicyPCRResponse callback,
22333                             TPM_RC response_code) {
22334   VLOG(1) << __func__;
22335   std::move(callback).Run(response_code);
22336 }
22337 
PolicyPCRResponseParser(Tpm::PolicyPCRResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22338 void PolicyPCRResponseParser(Tpm::PolicyPCRResponse callback,
22339                              AuthorizationDelegate* authorization_delegate,
22340                              const std::string& response) {
22341   VLOG(1) << __func__;
22342   TPM_RC rc = Tpm::ParseResponse_PolicyPCR(response, authorization_delegate);
22343   if (rc != TPM_RC_SUCCESS) {
22344     base::OnceCallback<void(TPM_RC)> error_reporter =
22345         base::BindOnce(PolicyPCRErrorCallback, std::move(callback));
22346     std::move(error_reporter).Run(rc);
22347     return;
22348   }
22349   std::move(callback).Run(rc);
22350 }
22351 
PolicyPCR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & pcr_digest,const TPML_PCR_SELECTION & pcrs,AuthorizationDelegate * authorization_delegate,PolicyPCRResponse callback)22352 void Tpm::PolicyPCR(const TPMI_SH_POLICY& policy_session,
22353                     const std::string& policy_session_name,
22354                     const TPM2B_DIGEST& pcr_digest,
22355                     const TPML_PCR_SELECTION& pcrs,
22356                     AuthorizationDelegate* authorization_delegate,
22357                     PolicyPCRResponse callback) {
22358   VLOG(1) << __func__;
22359   std::string command;
22360   TPM_RC rc = SerializeCommand_PolicyPCR(policy_session, policy_session_name,
22361                                          pcr_digest, pcrs, &command,
22362                                          authorization_delegate);
22363   if (rc != TPM_RC_SUCCESS) {
22364     base::OnceCallback<void(TPM_RC)> error_reporter =
22365         base::BindOnce(PolicyPCRErrorCallback, std::move(callback));
22366     std::move(error_reporter).Run(rc);
22367     return;
22368   }
22369   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22370       PolicyPCRResponseParser, std::move(callback), authorization_delegate);
22371   transceiver_->SendCommand(command, std::move(parser));
22372 }
22373 
PolicyPCRSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & pcr_digest,const TPML_PCR_SELECTION & pcrs,AuthorizationDelegate * authorization_delegate)22374 TPM_RC Tpm::PolicyPCRSync(const TPMI_SH_POLICY& policy_session,
22375                           const std::string& policy_session_name,
22376                           const TPM2B_DIGEST& pcr_digest,
22377                           const TPML_PCR_SELECTION& pcrs,
22378                           AuthorizationDelegate* authorization_delegate) {
22379   VLOG(1) << __func__;
22380   std::string command;
22381   TPM_RC rc = SerializeCommand_PolicyPCR(policy_session, policy_session_name,
22382                                          pcr_digest, pcrs, &command,
22383                                          authorization_delegate);
22384   if (rc != TPM_RC_SUCCESS) {
22385     return rc;
22386   }
22387   std::string response = transceiver_->SendCommandAndWait(command);
22388   rc = ParseResponse_PolicyPCR(response, authorization_delegate);
22389   return rc;
22390 }
22391 
SerializeCommand_PolicyLocality(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22392 TPM_RC Tpm::SerializeCommand_PolicyLocality(
22393     const TPMI_SH_POLICY& policy_session,
22394     const std::string& policy_session_name,
22395     const TPMA_LOCALITY& locality,
22396     std::string* serialized_command,
22397     AuthorizationDelegate* authorization_delegate) {
22398   VLOG(3) << __func__;
22399   TPM_RC rc = TPM_RC_SUCCESS;
22400   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22401   UINT32 command_size = 10;  // Header size.
22402   std::string handle_section_bytes;
22403   std::string parameter_section_bytes;
22404   TPM_CC command_code = TPM_CC_PolicyLocality;
22405   bool is_command_parameter_encryption_possible = false;
22406   bool is_response_parameter_encryption_possible = false;
22407   std::string command_code_bytes;
22408   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22409   if (rc != TPM_RC_SUCCESS) {
22410     return rc;
22411   }
22412   std::string policy_session_bytes;
22413   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22414   if (rc != TPM_RC_SUCCESS) {
22415     return rc;
22416   }
22417   std::string locality_bytes;
22418   rc = Serialize_TPMA_LOCALITY(locality, &locality_bytes);
22419   if (rc != TPM_RC_SUCCESS) {
22420     return rc;
22421   }
22422   std::unique_ptr<crypto::SecureHash> hash(
22423       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22424   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22425   hash->Update(policy_session_name.data(), policy_session_name.size());
22426   handle_section_bytes += policy_session_bytes;
22427   command_size += policy_session_bytes.size();
22428   hash->Update(locality_bytes.data(), locality_bytes.size());
22429   parameter_section_bytes += locality_bytes;
22430   command_size += locality_bytes.size();
22431   std::string command_hash(32, 0);
22432   hash->Finish(std::data(command_hash), command_hash.size());
22433   std::string authorization_section_bytes;
22434   std::string authorization_size_bytes;
22435   if (authorization_delegate) {
22436     if (!authorization_delegate->GetCommandAuthorization(
22437             command_hash, is_command_parameter_encryption_possible,
22438             is_response_parameter_encryption_possible,
22439             &authorization_section_bytes)) {
22440       return TRUNKS_RC_AUTHORIZATION_FAILED;
22441     }
22442     if (!authorization_section_bytes.empty()) {
22443       tag = TPM_ST_SESSIONS;
22444       std::string tmp;
22445       rc = Serialize_UINT32(authorization_section_bytes.size(),
22446                             &authorization_size_bytes);
22447       if (rc != TPM_RC_SUCCESS) {
22448         return rc;
22449       }
22450       command_size +=
22451           authorization_size_bytes.size() + authorization_section_bytes.size();
22452     }
22453   }
22454   std::string tag_bytes;
22455   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22456   if (rc != TPM_RC_SUCCESS) {
22457     return rc;
22458   }
22459   std::string command_size_bytes;
22460   rc = Serialize_UINT32(command_size, &command_size_bytes);
22461   if (rc != TPM_RC_SUCCESS) {
22462     return rc;
22463   }
22464   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22465                         handle_section_bytes + authorization_size_bytes +
22466                         authorization_section_bytes + parameter_section_bytes;
22467   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22468   VLOG(2) << "Command: "
22469           << base::HexEncode(serialized_command->data(),
22470                              serialized_command->size());
22471   return TPM_RC_SUCCESS;
22472 }
22473 
ParseResponse_PolicyLocality(const std::string & response,AuthorizationDelegate * authorization_delegate)22474 TPM_RC Tpm::ParseResponse_PolicyLocality(
22475     const std::string& response,
22476     AuthorizationDelegate* authorization_delegate) {
22477   VLOG(3) << __func__;
22478   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22479   TPM_RC rc = TPM_RC_SUCCESS;
22480   std::string buffer(response);
22481   TPM_ST tag;
22482   std::string tag_bytes;
22483   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22484   if (rc != TPM_RC_SUCCESS) {
22485     return rc;
22486   }
22487   UINT32 response_size;
22488   std::string response_size_bytes;
22489   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22490   if (rc != TPM_RC_SUCCESS) {
22491     return rc;
22492   }
22493   TPM_RC response_code;
22494   std::string response_code_bytes;
22495   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22496   if (rc != TPM_RC_SUCCESS) {
22497     return rc;
22498   }
22499   if (response_size != response.size()) {
22500     return TPM_RC_SIZE;
22501   }
22502   if (response_code != TPM_RC_SUCCESS) {
22503     return response_code;
22504   }
22505   TPM_CC command_code = TPM_CC_PolicyLocality;
22506   std::string command_code_bytes;
22507   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22508   if (rc != TPM_RC_SUCCESS) {
22509     return rc;
22510   }
22511   std::string authorization_section_bytes;
22512   if (tag == TPM_ST_SESSIONS) {
22513     UINT32 parameter_section_size = buffer.size();
22514     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22515     if (rc != TPM_RC_SUCCESS) {
22516       return rc;
22517     }
22518     if (parameter_section_size > buffer.size()) {
22519       return TPM_RC_INSUFFICIENT;
22520     }
22521     authorization_section_bytes = buffer.substr(parameter_section_size);
22522     // Keep the parameter section in |buffer|.
22523     buffer.erase(parameter_section_size);
22524   }
22525   std::unique_ptr<crypto::SecureHash> hash(
22526       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22527   hash->Update(response_code_bytes.data(), response_code_bytes.size());
22528   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22529   hash->Update(buffer.data(), buffer.size());
22530   std::string response_hash(32, 0);
22531   hash->Finish(std::data(response_hash), response_hash.size());
22532   if (tag == TPM_ST_SESSIONS) {
22533     if (!authorization_delegate)
22534       return TRUNKS_RC_AUTHORIZATION_FAILED;
22535     if (!authorization_delegate->CheckResponseAuthorization(
22536             response_hash, authorization_section_bytes)) {
22537       return TRUNKS_RC_AUTHORIZATION_FAILED;
22538     }
22539   }
22540   return TPM_RC_SUCCESS;
22541 }
22542 
PolicyLocalityErrorCallback(Tpm::PolicyLocalityResponse callback,TPM_RC response_code)22543 void PolicyLocalityErrorCallback(Tpm::PolicyLocalityResponse callback,
22544                                  TPM_RC response_code) {
22545   VLOG(1) << __func__;
22546   std::move(callback).Run(response_code);
22547 }
22548 
PolicyLocalityResponseParser(Tpm::PolicyLocalityResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22549 void PolicyLocalityResponseParser(Tpm::PolicyLocalityResponse callback,
22550                                   AuthorizationDelegate* authorization_delegate,
22551                                   const std::string& response) {
22552   VLOG(1) << __func__;
22553   TPM_RC rc =
22554       Tpm::ParseResponse_PolicyLocality(response, authorization_delegate);
22555   if (rc != TPM_RC_SUCCESS) {
22556     base::OnceCallback<void(TPM_RC)> error_reporter =
22557         base::BindOnce(PolicyLocalityErrorCallback, std::move(callback));
22558     std::move(error_reporter).Run(rc);
22559     return;
22560   }
22561   std::move(callback).Run(rc);
22562 }
22563 
PolicyLocality(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,AuthorizationDelegate * authorization_delegate,PolicyLocalityResponse callback)22564 void Tpm::PolicyLocality(const TPMI_SH_POLICY& policy_session,
22565                          const std::string& policy_session_name,
22566                          const TPMA_LOCALITY& locality,
22567                          AuthorizationDelegate* authorization_delegate,
22568                          PolicyLocalityResponse callback) {
22569   VLOG(1) << __func__;
22570   std::string command;
22571   TPM_RC rc = SerializeCommand_PolicyLocality(policy_session,
22572                                               policy_session_name, locality,
22573                                               &command, authorization_delegate);
22574   if (rc != TPM_RC_SUCCESS) {
22575     base::OnceCallback<void(TPM_RC)> error_reporter =
22576         base::BindOnce(PolicyLocalityErrorCallback, std::move(callback));
22577     std::move(error_reporter).Run(rc);
22578     return;
22579   }
22580   base::OnceCallback<void(const std::string&)> parser =
22581       base::BindOnce(PolicyLocalityResponseParser, std::move(callback),
22582                      authorization_delegate);
22583   transceiver_->SendCommand(command, std::move(parser));
22584 }
22585 
PolicyLocalitySync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,AuthorizationDelegate * authorization_delegate)22586 TPM_RC Tpm::PolicyLocalitySync(const TPMI_SH_POLICY& policy_session,
22587                                const std::string& policy_session_name,
22588                                const TPMA_LOCALITY& locality,
22589                                AuthorizationDelegate* authorization_delegate) {
22590   VLOG(1) << __func__;
22591   std::string command;
22592   TPM_RC rc = SerializeCommand_PolicyLocality(policy_session,
22593                                               policy_session_name, locality,
22594                                               &command, authorization_delegate);
22595   if (rc != TPM_RC_SUCCESS) {
22596     return rc;
22597   }
22598   std::string response = transceiver_->SendCommandAndWait(command);
22599   rc = ParseResponse_PolicyLocality(response, authorization_delegate);
22600   return rc;
22601 }
22602 
SerializeCommand_PolicyNV(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22603 TPM_RC Tpm::SerializeCommand_PolicyNV(
22604     const TPMI_RH_NV_AUTH& auth_handle,
22605     const std::string& auth_handle_name,
22606     const TPMI_RH_NV_INDEX& nv_index,
22607     const std::string& nv_index_name,
22608     const TPMI_SH_POLICY& policy_session,
22609     const std::string& policy_session_name,
22610     const TPM2B_OPERAND& operand_b,
22611     const UINT16& offset,
22612     const TPM_EO& operation,
22613     std::string* serialized_command,
22614     AuthorizationDelegate* authorization_delegate) {
22615   VLOG(3) << __func__;
22616   TPM_RC rc = TPM_RC_SUCCESS;
22617   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22618   UINT32 command_size = 10;  // Header size.
22619   std::string handle_section_bytes;
22620   std::string parameter_section_bytes;
22621   TPM_CC command_code = TPM_CC_PolicyNV;
22622   bool is_command_parameter_encryption_possible = true;
22623   bool is_response_parameter_encryption_possible = false;
22624   std::string command_code_bytes;
22625   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22626   if (rc != TPM_RC_SUCCESS) {
22627     return rc;
22628   }
22629   std::string auth_handle_bytes;
22630   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
22631   if (rc != TPM_RC_SUCCESS) {
22632     return rc;
22633   }
22634   std::string nv_index_bytes;
22635   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
22636   if (rc != TPM_RC_SUCCESS) {
22637     return rc;
22638   }
22639   std::string policy_session_bytes;
22640   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22641   if (rc != TPM_RC_SUCCESS) {
22642     return rc;
22643   }
22644   std::string operand_b_bytes;
22645   rc = Serialize_TPM2B_OPERAND(operand_b, &operand_b_bytes);
22646   if (rc != TPM_RC_SUCCESS) {
22647     return rc;
22648   }
22649   std::string offset_bytes;
22650   rc = Serialize_UINT16(offset, &offset_bytes);
22651   if (rc != TPM_RC_SUCCESS) {
22652     return rc;
22653   }
22654   std::string operation_bytes;
22655   rc = Serialize_TPM_EO(operation, &operation_bytes);
22656   if (rc != TPM_RC_SUCCESS) {
22657     return rc;
22658   }
22659   if (authorization_delegate) {
22660     // Encrypt just the parameter data, not the size.
22661     std::string tmp = operand_b_bytes.substr(2);
22662     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22663       return TRUNKS_RC_ENCRYPTION_FAILED;
22664     }
22665     operand_b_bytes.replace(2, std::string::npos, tmp);
22666   }
22667   std::unique_ptr<crypto::SecureHash> hash(
22668       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22669   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22670   hash->Update(auth_handle_name.data(), auth_handle_name.size());
22671   handle_section_bytes += auth_handle_bytes;
22672   command_size += auth_handle_bytes.size();
22673   hash->Update(nv_index_name.data(), nv_index_name.size());
22674   handle_section_bytes += nv_index_bytes;
22675   command_size += nv_index_bytes.size();
22676   hash->Update(policy_session_name.data(), policy_session_name.size());
22677   handle_section_bytes += policy_session_bytes;
22678   command_size += policy_session_bytes.size();
22679   hash->Update(operand_b_bytes.data(), operand_b_bytes.size());
22680   parameter_section_bytes += operand_b_bytes;
22681   command_size += operand_b_bytes.size();
22682   hash->Update(offset_bytes.data(), offset_bytes.size());
22683   parameter_section_bytes += offset_bytes;
22684   command_size += offset_bytes.size();
22685   hash->Update(operation_bytes.data(), operation_bytes.size());
22686   parameter_section_bytes += operation_bytes;
22687   command_size += operation_bytes.size();
22688   std::string command_hash(32, 0);
22689   hash->Finish(std::data(command_hash), command_hash.size());
22690   std::string authorization_section_bytes;
22691   std::string authorization_size_bytes;
22692   if (authorization_delegate) {
22693     if (!authorization_delegate->GetCommandAuthorization(
22694             command_hash, is_command_parameter_encryption_possible,
22695             is_response_parameter_encryption_possible,
22696             &authorization_section_bytes)) {
22697       return TRUNKS_RC_AUTHORIZATION_FAILED;
22698     }
22699     if (!authorization_section_bytes.empty()) {
22700       tag = TPM_ST_SESSIONS;
22701       std::string tmp;
22702       rc = Serialize_UINT32(authorization_section_bytes.size(),
22703                             &authorization_size_bytes);
22704       if (rc != TPM_RC_SUCCESS) {
22705         return rc;
22706       }
22707       command_size +=
22708           authorization_size_bytes.size() + authorization_section_bytes.size();
22709     }
22710   }
22711   std::string tag_bytes;
22712   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22713   if (rc != TPM_RC_SUCCESS) {
22714     return rc;
22715   }
22716   std::string command_size_bytes;
22717   rc = Serialize_UINT32(command_size, &command_size_bytes);
22718   if (rc != TPM_RC_SUCCESS) {
22719     return rc;
22720   }
22721   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22722                         handle_section_bytes + authorization_size_bytes +
22723                         authorization_section_bytes + parameter_section_bytes;
22724   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22725   VLOG(2) << "Command: "
22726           << base::HexEncode(serialized_command->data(),
22727                              serialized_command->size());
22728   return TPM_RC_SUCCESS;
22729 }
22730 
ParseResponse_PolicyNV(const std::string & response,AuthorizationDelegate * authorization_delegate)22731 TPM_RC Tpm::ParseResponse_PolicyNV(
22732     const std::string& response,
22733     AuthorizationDelegate* authorization_delegate) {
22734   VLOG(3) << __func__;
22735   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22736   TPM_RC rc = TPM_RC_SUCCESS;
22737   std::string buffer(response);
22738   TPM_ST tag;
22739   std::string tag_bytes;
22740   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22741   if (rc != TPM_RC_SUCCESS) {
22742     return rc;
22743   }
22744   UINT32 response_size;
22745   std::string response_size_bytes;
22746   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22747   if (rc != TPM_RC_SUCCESS) {
22748     return rc;
22749   }
22750   TPM_RC response_code;
22751   std::string response_code_bytes;
22752   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22753   if (rc != TPM_RC_SUCCESS) {
22754     return rc;
22755   }
22756   if (response_size != response.size()) {
22757     return TPM_RC_SIZE;
22758   }
22759   if (response_code != TPM_RC_SUCCESS) {
22760     return response_code;
22761   }
22762   TPM_CC command_code = TPM_CC_PolicyNV;
22763   std::string command_code_bytes;
22764   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22765   if (rc != TPM_RC_SUCCESS) {
22766     return rc;
22767   }
22768   std::string authorization_section_bytes;
22769   if (tag == TPM_ST_SESSIONS) {
22770     UINT32 parameter_section_size = buffer.size();
22771     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22772     if (rc != TPM_RC_SUCCESS) {
22773       return rc;
22774     }
22775     if (parameter_section_size > buffer.size()) {
22776       return TPM_RC_INSUFFICIENT;
22777     }
22778     authorization_section_bytes = buffer.substr(parameter_section_size);
22779     // Keep the parameter section in |buffer|.
22780     buffer.erase(parameter_section_size);
22781   }
22782   std::unique_ptr<crypto::SecureHash> hash(
22783       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22784   hash->Update(response_code_bytes.data(), response_code_bytes.size());
22785   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22786   hash->Update(buffer.data(), buffer.size());
22787   std::string response_hash(32, 0);
22788   hash->Finish(std::data(response_hash), response_hash.size());
22789   if (tag == TPM_ST_SESSIONS) {
22790     if (!authorization_delegate)
22791       return TRUNKS_RC_AUTHORIZATION_FAILED;
22792     if (!authorization_delegate->CheckResponseAuthorization(
22793             response_hash, authorization_section_bytes)) {
22794       return TRUNKS_RC_AUTHORIZATION_FAILED;
22795     }
22796   }
22797   return TPM_RC_SUCCESS;
22798 }
22799 
PolicyNVErrorCallback(Tpm::PolicyNVResponse callback,TPM_RC response_code)22800 void PolicyNVErrorCallback(Tpm::PolicyNVResponse callback,
22801                            TPM_RC response_code) {
22802   VLOG(1) << __func__;
22803   std::move(callback).Run(response_code);
22804 }
22805 
PolicyNVResponseParser(Tpm::PolicyNVResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22806 void PolicyNVResponseParser(Tpm::PolicyNVResponse callback,
22807                             AuthorizationDelegate* authorization_delegate,
22808                             const std::string& response) {
22809   VLOG(1) << __func__;
22810   TPM_RC rc = Tpm::ParseResponse_PolicyNV(response, authorization_delegate);
22811   if (rc != TPM_RC_SUCCESS) {
22812     base::OnceCallback<void(TPM_RC)> error_reporter =
22813         base::BindOnce(PolicyNVErrorCallback, std::move(callback));
22814     std::move(error_reporter).Run(rc);
22815     return;
22816   }
22817   std::move(callback).Run(rc);
22818 }
22819 
PolicyNV(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate,PolicyNVResponse callback)22820 void Tpm::PolicyNV(const TPMI_RH_NV_AUTH& auth_handle,
22821                    const std::string& auth_handle_name,
22822                    const TPMI_RH_NV_INDEX& nv_index,
22823                    const std::string& nv_index_name,
22824                    const TPMI_SH_POLICY& policy_session,
22825                    const std::string& policy_session_name,
22826                    const TPM2B_OPERAND& operand_b,
22827                    const UINT16& offset,
22828                    const TPM_EO& operation,
22829                    AuthorizationDelegate* authorization_delegate,
22830                    PolicyNVResponse callback) {
22831   VLOG(1) << __func__;
22832   std::string command;
22833   TPM_RC rc = SerializeCommand_PolicyNV(
22834       auth_handle, auth_handle_name, nv_index, nv_index_name, policy_session,
22835       policy_session_name, operand_b, offset, operation, &command,
22836       authorization_delegate);
22837   if (rc != TPM_RC_SUCCESS) {
22838     base::OnceCallback<void(TPM_RC)> error_reporter =
22839         base::BindOnce(PolicyNVErrorCallback, std::move(callback));
22840     std::move(error_reporter).Run(rc);
22841     return;
22842   }
22843   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22844       PolicyNVResponseParser, std::move(callback), authorization_delegate);
22845   transceiver_->SendCommand(command, std::move(parser));
22846 }
22847 
PolicyNVSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate)22848 TPM_RC Tpm::PolicyNVSync(const TPMI_RH_NV_AUTH& auth_handle,
22849                          const std::string& auth_handle_name,
22850                          const TPMI_RH_NV_INDEX& nv_index,
22851                          const std::string& nv_index_name,
22852                          const TPMI_SH_POLICY& policy_session,
22853                          const std::string& policy_session_name,
22854                          const TPM2B_OPERAND& operand_b,
22855                          const UINT16& offset,
22856                          const TPM_EO& operation,
22857                          AuthorizationDelegate* authorization_delegate) {
22858   VLOG(1) << __func__;
22859   std::string command;
22860   TPM_RC rc = SerializeCommand_PolicyNV(
22861       auth_handle, auth_handle_name, nv_index, nv_index_name, policy_session,
22862       policy_session_name, operand_b, offset, operation, &command,
22863       authorization_delegate);
22864   if (rc != TPM_RC_SUCCESS) {
22865     return rc;
22866   }
22867   std::string response = transceiver_->SendCommandAndWait(command);
22868   rc = ParseResponse_PolicyNV(response, authorization_delegate);
22869   return rc;
22870 }
22871 
SerializeCommand_PolicyCounterTimer(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22872 TPM_RC Tpm::SerializeCommand_PolicyCounterTimer(
22873     const TPMI_SH_POLICY& policy_session,
22874     const std::string& policy_session_name,
22875     const TPM2B_OPERAND& operand_b,
22876     const UINT16& offset,
22877     const TPM_EO& operation,
22878     std::string* serialized_command,
22879     AuthorizationDelegate* authorization_delegate) {
22880   VLOG(3) << __func__;
22881   TPM_RC rc = TPM_RC_SUCCESS;
22882   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22883   UINT32 command_size = 10;  // Header size.
22884   std::string handle_section_bytes;
22885   std::string parameter_section_bytes;
22886   TPM_CC command_code = TPM_CC_PolicyCounterTimer;
22887   bool is_command_parameter_encryption_possible = true;
22888   bool is_response_parameter_encryption_possible = false;
22889   std::string command_code_bytes;
22890   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22891   if (rc != TPM_RC_SUCCESS) {
22892     return rc;
22893   }
22894   std::string policy_session_bytes;
22895   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22896   if (rc != TPM_RC_SUCCESS) {
22897     return rc;
22898   }
22899   std::string operand_b_bytes;
22900   rc = Serialize_TPM2B_OPERAND(operand_b, &operand_b_bytes);
22901   if (rc != TPM_RC_SUCCESS) {
22902     return rc;
22903   }
22904   std::string offset_bytes;
22905   rc = Serialize_UINT16(offset, &offset_bytes);
22906   if (rc != TPM_RC_SUCCESS) {
22907     return rc;
22908   }
22909   std::string operation_bytes;
22910   rc = Serialize_TPM_EO(operation, &operation_bytes);
22911   if (rc != TPM_RC_SUCCESS) {
22912     return rc;
22913   }
22914   if (authorization_delegate) {
22915     // Encrypt just the parameter data, not the size.
22916     std::string tmp = operand_b_bytes.substr(2);
22917     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22918       return TRUNKS_RC_ENCRYPTION_FAILED;
22919     }
22920     operand_b_bytes.replace(2, std::string::npos, tmp);
22921   }
22922   std::unique_ptr<crypto::SecureHash> hash(
22923       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22924   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22925   hash->Update(policy_session_name.data(), policy_session_name.size());
22926   handle_section_bytes += policy_session_bytes;
22927   command_size += policy_session_bytes.size();
22928   hash->Update(operand_b_bytes.data(), operand_b_bytes.size());
22929   parameter_section_bytes += operand_b_bytes;
22930   command_size += operand_b_bytes.size();
22931   hash->Update(offset_bytes.data(), offset_bytes.size());
22932   parameter_section_bytes += offset_bytes;
22933   command_size += offset_bytes.size();
22934   hash->Update(operation_bytes.data(), operation_bytes.size());
22935   parameter_section_bytes += operation_bytes;
22936   command_size += operation_bytes.size();
22937   std::string command_hash(32, 0);
22938   hash->Finish(std::data(command_hash), command_hash.size());
22939   std::string authorization_section_bytes;
22940   std::string authorization_size_bytes;
22941   if (authorization_delegate) {
22942     if (!authorization_delegate->GetCommandAuthorization(
22943             command_hash, is_command_parameter_encryption_possible,
22944             is_response_parameter_encryption_possible,
22945             &authorization_section_bytes)) {
22946       return TRUNKS_RC_AUTHORIZATION_FAILED;
22947     }
22948     if (!authorization_section_bytes.empty()) {
22949       tag = TPM_ST_SESSIONS;
22950       std::string tmp;
22951       rc = Serialize_UINT32(authorization_section_bytes.size(),
22952                             &authorization_size_bytes);
22953       if (rc != TPM_RC_SUCCESS) {
22954         return rc;
22955       }
22956       command_size +=
22957           authorization_size_bytes.size() + authorization_section_bytes.size();
22958     }
22959   }
22960   std::string tag_bytes;
22961   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22962   if (rc != TPM_RC_SUCCESS) {
22963     return rc;
22964   }
22965   std::string command_size_bytes;
22966   rc = Serialize_UINT32(command_size, &command_size_bytes);
22967   if (rc != TPM_RC_SUCCESS) {
22968     return rc;
22969   }
22970   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22971                         handle_section_bytes + authorization_size_bytes +
22972                         authorization_section_bytes + parameter_section_bytes;
22973   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22974   VLOG(2) << "Command: "
22975           << base::HexEncode(serialized_command->data(),
22976                              serialized_command->size());
22977   return TPM_RC_SUCCESS;
22978 }
22979 
ParseResponse_PolicyCounterTimer(const std::string & response,AuthorizationDelegate * authorization_delegate)22980 TPM_RC Tpm::ParseResponse_PolicyCounterTimer(
22981     const std::string& response,
22982     AuthorizationDelegate* authorization_delegate) {
22983   VLOG(3) << __func__;
22984   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22985   TPM_RC rc = TPM_RC_SUCCESS;
22986   std::string buffer(response);
22987   TPM_ST tag;
22988   std::string tag_bytes;
22989   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22990   if (rc != TPM_RC_SUCCESS) {
22991     return rc;
22992   }
22993   UINT32 response_size;
22994   std::string response_size_bytes;
22995   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22996   if (rc != TPM_RC_SUCCESS) {
22997     return rc;
22998   }
22999   TPM_RC response_code;
23000   std::string response_code_bytes;
23001   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23002   if (rc != TPM_RC_SUCCESS) {
23003     return rc;
23004   }
23005   if (response_size != response.size()) {
23006     return TPM_RC_SIZE;
23007   }
23008   if (response_code != TPM_RC_SUCCESS) {
23009     return response_code;
23010   }
23011   TPM_CC command_code = TPM_CC_PolicyCounterTimer;
23012   std::string command_code_bytes;
23013   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23014   if (rc != TPM_RC_SUCCESS) {
23015     return rc;
23016   }
23017   std::string authorization_section_bytes;
23018   if (tag == TPM_ST_SESSIONS) {
23019     UINT32 parameter_section_size = buffer.size();
23020     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23021     if (rc != TPM_RC_SUCCESS) {
23022       return rc;
23023     }
23024     if (parameter_section_size > buffer.size()) {
23025       return TPM_RC_INSUFFICIENT;
23026     }
23027     authorization_section_bytes = buffer.substr(parameter_section_size);
23028     // Keep the parameter section in |buffer|.
23029     buffer.erase(parameter_section_size);
23030   }
23031   std::unique_ptr<crypto::SecureHash> hash(
23032       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23033   hash->Update(response_code_bytes.data(), response_code_bytes.size());
23034   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23035   hash->Update(buffer.data(), buffer.size());
23036   std::string response_hash(32, 0);
23037   hash->Finish(std::data(response_hash), response_hash.size());
23038   if (tag == TPM_ST_SESSIONS) {
23039     if (!authorization_delegate)
23040       return TRUNKS_RC_AUTHORIZATION_FAILED;
23041     if (!authorization_delegate->CheckResponseAuthorization(
23042             response_hash, authorization_section_bytes)) {
23043       return TRUNKS_RC_AUTHORIZATION_FAILED;
23044     }
23045   }
23046   return TPM_RC_SUCCESS;
23047 }
23048 
PolicyCounterTimerErrorCallback(Tpm::PolicyCounterTimerResponse callback,TPM_RC response_code)23049 void PolicyCounterTimerErrorCallback(Tpm::PolicyCounterTimerResponse callback,
23050                                      TPM_RC response_code) {
23051   VLOG(1) << __func__;
23052   std::move(callback).Run(response_code);
23053 }
23054 
PolicyCounterTimerResponseParser(Tpm::PolicyCounterTimerResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23055 void PolicyCounterTimerResponseParser(
23056     Tpm::PolicyCounterTimerResponse callback,
23057     AuthorizationDelegate* authorization_delegate,
23058     const std::string& response) {
23059   VLOG(1) << __func__;
23060   TPM_RC rc =
23061       Tpm::ParseResponse_PolicyCounterTimer(response, authorization_delegate);
23062   if (rc != TPM_RC_SUCCESS) {
23063     base::OnceCallback<void(TPM_RC)> error_reporter =
23064         base::BindOnce(PolicyCounterTimerErrorCallback, std::move(callback));
23065     std::move(error_reporter).Run(rc);
23066     return;
23067   }
23068   std::move(callback).Run(rc);
23069 }
23070 
PolicyCounterTimer(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate,PolicyCounterTimerResponse callback)23071 void Tpm::PolicyCounterTimer(const TPMI_SH_POLICY& policy_session,
23072                              const std::string& policy_session_name,
23073                              const TPM2B_OPERAND& operand_b,
23074                              const UINT16& offset,
23075                              const TPM_EO& operation,
23076                              AuthorizationDelegate* authorization_delegate,
23077                              PolicyCounterTimerResponse callback) {
23078   VLOG(1) << __func__;
23079   std::string command;
23080   TPM_RC rc = SerializeCommand_PolicyCounterTimer(
23081       policy_session, policy_session_name, operand_b, offset, operation,
23082       &command, authorization_delegate);
23083   if (rc != TPM_RC_SUCCESS) {
23084     base::OnceCallback<void(TPM_RC)> error_reporter =
23085         base::BindOnce(PolicyCounterTimerErrorCallback, std::move(callback));
23086     std::move(error_reporter).Run(rc);
23087     return;
23088   }
23089   base::OnceCallback<void(const std::string&)> parser =
23090       base::BindOnce(PolicyCounterTimerResponseParser, std::move(callback),
23091                      authorization_delegate);
23092   transceiver_->SendCommand(command, std::move(parser));
23093 }
23094 
PolicyCounterTimerSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate)23095 TPM_RC Tpm::PolicyCounterTimerSync(
23096     const TPMI_SH_POLICY& policy_session,
23097     const std::string& policy_session_name,
23098     const TPM2B_OPERAND& operand_b,
23099     const UINT16& offset,
23100     const TPM_EO& operation,
23101     AuthorizationDelegate* authorization_delegate) {
23102   VLOG(1) << __func__;
23103   std::string command;
23104   TPM_RC rc = SerializeCommand_PolicyCounterTimer(
23105       policy_session, policy_session_name, operand_b, offset, operation,
23106       &command, authorization_delegate);
23107   if (rc != TPM_RC_SUCCESS) {
23108     return rc;
23109   }
23110   std::string response = transceiver_->SendCommandAndWait(command);
23111   rc = ParseResponse_PolicyCounterTimer(response, authorization_delegate);
23112   return rc;
23113 }
23114 
SerializeCommand_PolicyCommandCode(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23115 TPM_RC Tpm::SerializeCommand_PolicyCommandCode(
23116     const TPMI_SH_POLICY& policy_session,
23117     const std::string& policy_session_name,
23118     const TPM_CC& code,
23119     std::string* serialized_command,
23120     AuthorizationDelegate* authorization_delegate) {
23121   VLOG(3) << __func__;
23122   TPM_RC rc = TPM_RC_SUCCESS;
23123   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23124   UINT32 command_size = 10;  // Header size.
23125   std::string handle_section_bytes;
23126   std::string parameter_section_bytes;
23127   TPM_CC command_code = TPM_CC_PolicyCommandCode;
23128   bool is_command_parameter_encryption_possible = false;
23129   bool is_response_parameter_encryption_possible = false;
23130   std::string command_code_bytes;
23131   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23132   if (rc != TPM_RC_SUCCESS) {
23133     return rc;
23134   }
23135   std::string policy_session_bytes;
23136   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23137   if (rc != TPM_RC_SUCCESS) {
23138     return rc;
23139   }
23140   std::string code_bytes;
23141   rc = Serialize_TPM_CC(code, &code_bytes);
23142   if (rc != TPM_RC_SUCCESS) {
23143     return rc;
23144   }
23145   std::unique_ptr<crypto::SecureHash> hash(
23146       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23147   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23148   hash->Update(policy_session_name.data(), policy_session_name.size());
23149   handle_section_bytes += policy_session_bytes;
23150   command_size += policy_session_bytes.size();
23151   hash->Update(code_bytes.data(), code_bytes.size());
23152   parameter_section_bytes += code_bytes;
23153   command_size += code_bytes.size();
23154   std::string command_hash(32, 0);
23155   hash->Finish(std::data(command_hash), command_hash.size());
23156   std::string authorization_section_bytes;
23157   std::string authorization_size_bytes;
23158   if (authorization_delegate) {
23159     if (!authorization_delegate->GetCommandAuthorization(
23160             command_hash, is_command_parameter_encryption_possible,
23161             is_response_parameter_encryption_possible,
23162             &authorization_section_bytes)) {
23163       return TRUNKS_RC_AUTHORIZATION_FAILED;
23164     }
23165     if (!authorization_section_bytes.empty()) {
23166       tag = TPM_ST_SESSIONS;
23167       std::string tmp;
23168       rc = Serialize_UINT32(authorization_section_bytes.size(),
23169                             &authorization_size_bytes);
23170       if (rc != TPM_RC_SUCCESS) {
23171         return rc;
23172       }
23173       command_size +=
23174           authorization_size_bytes.size() + authorization_section_bytes.size();
23175     }
23176   }
23177   std::string tag_bytes;
23178   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23179   if (rc != TPM_RC_SUCCESS) {
23180     return rc;
23181   }
23182   std::string command_size_bytes;
23183   rc = Serialize_UINT32(command_size, &command_size_bytes);
23184   if (rc != TPM_RC_SUCCESS) {
23185     return rc;
23186   }
23187   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23188                         handle_section_bytes + authorization_size_bytes +
23189                         authorization_section_bytes + parameter_section_bytes;
23190   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23191   VLOG(2) << "Command: "
23192           << base::HexEncode(serialized_command->data(),
23193                              serialized_command->size());
23194   return TPM_RC_SUCCESS;
23195 }
23196 
ParseResponse_PolicyCommandCode(const std::string & response,AuthorizationDelegate * authorization_delegate)23197 TPM_RC Tpm::ParseResponse_PolicyCommandCode(
23198     const std::string& response,
23199     AuthorizationDelegate* authorization_delegate) {
23200   VLOG(3) << __func__;
23201   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23202   TPM_RC rc = TPM_RC_SUCCESS;
23203   std::string buffer(response);
23204   TPM_ST tag;
23205   std::string tag_bytes;
23206   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23207   if (rc != TPM_RC_SUCCESS) {
23208     return rc;
23209   }
23210   UINT32 response_size;
23211   std::string response_size_bytes;
23212   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23213   if (rc != TPM_RC_SUCCESS) {
23214     return rc;
23215   }
23216   TPM_RC response_code;
23217   std::string response_code_bytes;
23218   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23219   if (rc != TPM_RC_SUCCESS) {
23220     return rc;
23221   }
23222   if (response_size != response.size()) {
23223     return TPM_RC_SIZE;
23224   }
23225   if (response_code != TPM_RC_SUCCESS) {
23226     return response_code;
23227   }
23228   TPM_CC command_code = TPM_CC_PolicyCommandCode;
23229   std::string command_code_bytes;
23230   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23231   if (rc != TPM_RC_SUCCESS) {
23232     return rc;
23233   }
23234   std::string authorization_section_bytes;
23235   if (tag == TPM_ST_SESSIONS) {
23236     UINT32 parameter_section_size = buffer.size();
23237     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23238     if (rc != TPM_RC_SUCCESS) {
23239       return rc;
23240     }
23241     if (parameter_section_size > buffer.size()) {
23242       return TPM_RC_INSUFFICIENT;
23243     }
23244     authorization_section_bytes = buffer.substr(parameter_section_size);
23245     // Keep the parameter section in |buffer|.
23246     buffer.erase(parameter_section_size);
23247   }
23248   std::unique_ptr<crypto::SecureHash> hash(
23249       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23250   hash->Update(response_code_bytes.data(), response_code_bytes.size());
23251   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23252   hash->Update(buffer.data(), buffer.size());
23253   std::string response_hash(32, 0);
23254   hash->Finish(std::data(response_hash), response_hash.size());
23255   if (tag == TPM_ST_SESSIONS) {
23256     if (!authorization_delegate)
23257       return TRUNKS_RC_AUTHORIZATION_FAILED;
23258     if (!authorization_delegate->CheckResponseAuthorization(
23259             response_hash, authorization_section_bytes)) {
23260       return TRUNKS_RC_AUTHORIZATION_FAILED;
23261     }
23262   }
23263   return TPM_RC_SUCCESS;
23264 }
23265 
PolicyCommandCodeErrorCallback(Tpm::PolicyCommandCodeResponse callback,TPM_RC response_code)23266 void PolicyCommandCodeErrorCallback(Tpm::PolicyCommandCodeResponse callback,
23267                                     TPM_RC response_code) {
23268   VLOG(1) << __func__;
23269   std::move(callback).Run(response_code);
23270 }
23271 
PolicyCommandCodeResponseParser(Tpm::PolicyCommandCodeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23272 void PolicyCommandCodeResponseParser(
23273     Tpm::PolicyCommandCodeResponse callback,
23274     AuthorizationDelegate* authorization_delegate,
23275     const std::string& response) {
23276   VLOG(1) << __func__;
23277   TPM_RC rc =
23278       Tpm::ParseResponse_PolicyCommandCode(response, authorization_delegate);
23279   if (rc != TPM_RC_SUCCESS) {
23280     base::OnceCallback<void(TPM_RC)> error_reporter =
23281         base::BindOnce(PolicyCommandCodeErrorCallback, std::move(callback));
23282     std::move(error_reporter).Run(rc);
23283     return;
23284   }
23285   std::move(callback).Run(rc);
23286 }
23287 
PolicyCommandCode(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,AuthorizationDelegate * authorization_delegate,PolicyCommandCodeResponse callback)23288 void Tpm::PolicyCommandCode(const TPMI_SH_POLICY& policy_session,
23289                             const std::string& policy_session_name,
23290                             const TPM_CC& code,
23291                             AuthorizationDelegate* authorization_delegate,
23292                             PolicyCommandCodeResponse callback) {
23293   VLOG(1) << __func__;
23294   std::string command;
23295   TPM_RC rc = SerializeCommand_PolicyCommandCode(
23296       policy_session, policy_session_name, code, &command,
23297       authorization_delegate);
23298   if (rc != TPM_RC_SUCCESS) {
23299     base::OnceCallback<void(TPM_RC)> error_reporter =
23300         base::BindOnce(PolicyCommandCodeErrorCallback, std::move(callback));
23301     std::move(error_reporter).Run(rc);
23302     return;
23303   }
23304   base::OnceCallback<void(const std::string&)> parser =
23305       base::BindOnce(PolicyCommandCodeResponseParser, std::move(callback),
23306                      authorization_delegate);
23307   transceiver_->SendCommand(command, std::move(parser));
23308 }
23309 
PolicyCommandCodeSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,AuthorizationDelegate * authorization_delegate)23310 TPM_RC Tpm::PolicyCommandCodeSync(
23311     const TPMI_SH_POLICY& policy_session,
23312     const std::string& policy_session_name,
23313     const TPM_CC& code,
23314     AuthorizationDelegate* authorization_delegate) {
23315   VLOG(1) << __func__;
23316   std::string command;
23317   TPM_RC rc = SerializeCommand_PolicyCommandCode(
23318       policy_session, policy_session_name, code, &command,
23319       authorization_delegate);
23320   if (rc != TPM_RC_SUCCESS) {
23321     return rc;
23322   }
23323   std::string response = transceiver_->SendCommandAndWait(command);
23324   rc = ParseResponse_PolicyCommandCode(response, authorization_delegate);
23325   return rc;
23326 }
23327 
SerializeCommand_PolicyPhysicalPresence(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23328 TPM_RC Tpm::SerializeCommand_PolicyPhysicalPresence(
23329     const TPMI_SH_POLICY& policy_session,
23330     const std::string& policy_session_name,
23331     std::string* serialized_command,
23332     AuthorizationDelegate* authorization_delegate) {
23333   VLOG(3) << __func__;
23334   TPM_RC rc = TPM_RC_SUCCESS;
23335   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23336   UINT32 command_size = 10;  // Header size.
23337   std::string handle_section_bytes;
23338   std::string parameter_section_bytes;
23339   TPM_CC command_code = TPM_CC_PolicyPhysicalPresence;
23340   bool is_command_parameter_encryption_possible = false;
23341   bool is_response_parameter_encryption_possible = false;
23342   std::string command_code_bytes;
23343   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23344   if (rc != TPM_RC_SUCCESS) {
23345     return rc;
23346   }
23347   std::string policy_session_bytes;
23348   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23349   if (rc != TPM_RC_SUCCESS) {
23350     return rc;
23351   }
23352   std::unique_ptr<crypto::SecureHash> hash(
23353       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23354   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23355   hash->Update(policy_session_name.data(), policy_session_name.size());
23356   handle_section_bytes += policy_session_bytes;
23357   command_size += policy_session_bytes.size();
23358   std::string command_hash(32, 0);
23359   hash->Finish(std::data(command_hash), command_hash.size());
23360   std::string authorization_section_bytes;
23361   std::string authorization_size_bytes;
23362   if (authorization_delegate) {
23363     if (!authorization_delegate->GetCommandAuthorization(
23364             command_hash, is_command_parameter_encryption_possible,
23365             is_response_parameter_encryption_possible,
23366             &authorization_section_bytes)) {
23367       return TRUNKS_RC_AUTHORIZATION_FAILED;
23368     }
23369     if (!authorization_section_bytes.empty()) {
23370       tag = TPM_ST_SESSIONS;
23371       std::string tmp;
23372       rc = Serialize_UINT32(authorization_section_bytes.size(),
23373                             &authorization_size_bytes);
23374       if (rc != TPM_RC_SUCCESS) {
23375         return rc;
23376       }
23377       command_size +=
23378           authorization_size_bytes.size() + authorization_section_bytes.size();
23379     }
23380   }
23381   std::string tag_bytes;
23382   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23383   if (rc != TPM_RC_SUCCESS) {
23384     return rc;
23385   }
23386   std::string command_size_bytes;
23387   rc = Serialize_UINT32(command_size, &command_size_bytes);
23388   if (rc != TPM_RC_SUCCESS) {
23389     return rc;
23390   }
23391   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23392                         handle_section_bytes + authorization_size_bytes +
23393                         authorization_section_bytes + parameter_section_bytes;
23394   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23395   VLOG(2) << "Command: "
23396           << base::HexEncode(serialized_command->data(),
23397                              serialized_command->size());
23398   return TPM_RC_SUCCESS;
23399 }
23400 
ParseResponse_PolicyPhysicalPresence(const std::string & response,AuthorizationDelegate * authorization_delegate)23401 TPM_RC Tpm::ParseResponse_PolicyPhysicalPresence(
23402     const std::string& response,
23403     AuthorizationDelegate* authorization_delegate) {
23404   VLOG(3) << __func__;
23405   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23406   TPM_RC rc = TPM_RC_SUCCESS;
23407   std::string buffer(response);
23408   TPM_ST tag;
23409   std::string tag_bytes;
23410   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23411   if (rc != TPM_RC_SUCCESS) {
23412     return rc;
23413   }
23414   UINT32 response_size;
23415   std::string response_size_bytes;
23416   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23417   if (rc != TPM_RC_SUCCESS) {
23418     return rc;
23419   }
23420   TPM_RC response_code;
23421   std::string response_code_bytes;
23422   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23423   if (rc != TPM_RC_SUCCESS) {
23424     return rc;
23425   }
23426   if (response_size != response.size()) {
23427     return TPM_RC_SIZE;
23428   }
23429   if (response_code != TPM_RC_SUCCESS) {
23430     return response_code;
23431   }
23432   TPM_CC command_code = TPM_CC_PolicyPhysicalPresence;
23433   std::string command_code_bytes;
23434   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23435   if (rc != TPM_RC_SUCCESS) {
23436     return rc;
23437   }
23438   std::string authorization_section_bytes;
23439   if (tag == TPM_ST_SESSIONS) {
23440     UINT32 parameter_section_size = buffer.size();
23441     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23442     if (rc != TPM_RC_SUCCESS) {
23443       return rc;
23444     }
23445     if (parameter_section_size > buffer.size()) {
23446       return TPM_RC_INSUFFICIENT;
23447     }
23448     authorization_section_bytes = buffer.substr(parameter_section_size);
23449     // Keep the parameter section in |buffer|.
23450     buffer.erase(parameter_section_size);
23451   }
23452   std::unique_ptr<crypto::SecureHash> hash(
23453       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23454   hash->Update(response_code_bytes.data(), response_code_bytes.size());
23455   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23456   hash->Update(buffer.data(), buffer.size());
23457   std::string response_hash(32, 0);
23458   hash->Finish(std::data(response_hash), response_hash.size());
23459   if (tag == TPM_ST_SESSIONS) {
23460     if (!authorization_delegate)
23461       return TRUNKS_RC_AUTHORIZATION_FAILED;
23462     if (!authorization_delegate->CheckResponseAuthorization(
23463             response_hash, authorization_section_bytes)) {
23464       return TRUNKS_RC_AUTHORIZATION_FAILED;
23465     }
23466   }
23467   return TPM_RC_SUCCESS;
23468 }
23469 
PolicyPhysicalPresenceErrorCallback(Tpm::PolicyPhysicalPresenceResponse callback,TPM_RC response_code)23470 void PolicyPhysicalPresenceErrorCallback(
23471     Tpm::PolicyPhysicalPresenceResponse callback, TPM_RC response_code) {
23472   VLOG(1) << __func__;
23473   std::move(callback).Run(response_code);
23474 }
23475 
PolicyPhysicalPresenceResponseParser(Tpm::PolicyPhysicalPresenceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23476 void PolicyPhysicalPresenceResponseParser(
23477     Tpm::PolicyPhysicalPresenceResponse callback,
23478     AuthorizationDelegate* authorization_delegate,
23479     const std::string& response) {
23480   VLOG(1) << __func__;
23481   TPM_RC rc = Tpm::ParseResponse_PolicyPhysicalPresence(response,
23482                                                         authorization_delegate);
23483   if (rc != TPM_RC_SUCCESS) {
23484     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
23485         PolicyPhysicalPresenceErrorCallback, std::move(callback));
23486     std::move(error_reporter).Run(rc);
23487     return;
23488   }
23489   std::move(callback).Run(rc);
23490 }
23491 
PolicyPhysicalPresence(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyPhysicalPresenceResponse callback)23492 void Tpm::PolicyPhysicalPresence(const TPMI_SH_POLICY& policy_session,
23493                                  const std::string& policy_session_name,
23494                                  AuthorizationDelegate* authorization_delegate,
23495                                  PolicyPhysicalPresenceResponse callback) {
23496   VLOG(1) << __func__;
23497   std::string command;
23498   TPM_RC rc = SerializeCommand_PolicyPhysicalPresence(
23499       policy_session, policy_session_name, &command, authorization_delegate);
23500   if (rc != TPM_RC_SUCCESS) {
23501     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
23502         PolicyPhysicalPresenceErrorCallback, std::move(callback));
23503     std::move(error_reporter).Run(rc);
23504     return;
23505   }
23506   base::OnceCallback<void(const std::string&)> parser =
23507       base::BindOnce(PolicyPhysicalPresenceResponseParser, std::move(callback),
23508                      authorization_delegate);
23509   transceiver_->SendCommand(command, std::move(parser));
23510 }
23511 
PolicyPhysicalPresenceSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)23512 TPM_RC Tpm::PolicyPhysicalPresenceSync(
23513     const TPMI_SH_POLICY& policy_session,
23514     const std::string& policy_session_name,
23515     AuthorizationDelegate* authorization_delegate) {
23516   VLOG(1) << __func__;
23517   std::string command;
23518   TPM_RC rc = SerializeCommand_PolicyPhysicalPresence(
23519       policy_session, policy_session_name, &command, authorization_delegate);
23520   if (rc != TPM_RC_SUCCESS) {
23521     return rc;
23522   }
23523   std::string response = transceiver_->SendCommandAndWait(command);
23524   rc = ParseResponse_PolicyPhysicalPresence(response, authorization_delegate);
23525   return rc;
23526 }
23527 
SerializeCommand_PolicyCpHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23528 TPM_RC Tpm::SerializeCommand_PolicyCpHash(
23529     const TPMI_SH_POLICY& policy_session,
23530     const std::string& policy_session_name,
23531     const TPM2B_DIGEST& cp_hash_a,
23532     std::string* serialized_command,
23533     AuthorizationDelegate* authorization_delegate) {
23534   VLOG(3) << __func__;
23535   TPM_RC rc = TPM_RC_SUCCESS;
23536   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23537   UINT32 command_size = 10;  // Header size.
23538   std::string handle_section_bytes;
23539   std::string parameter_section_bytes;
23540   TPM_CC command_code = TPM_CC_PolicyCpHash;
23541   bool is_command_parameter_encryption_possible = true;
23542   bool is_response_parameter_encryption_possible = false;
23543   std::string command_code_bytes;
23544   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23545   if (rc != TPM_RC_SUCCESS) {
23546     return rc;
23547   }
23548   std::string policy_session_bytes;
23549   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23550   if (rc != TPM_RC_SUCCESS) {
23551     return rc;
23552   }
23553   std::string cp_hash_a_bytes;
23554   rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
23555   if (rc != TPM_RC_SUCCESS) {
23556     return rc;
23557   }
23558   if (authorization_delegate) {
23559     // Encrypt just the parameter data, not the size.
23560     std::string tmp = cp_hash_a_bytes.substr(2);
23561     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23562       return TRUNKS_RC_ENCRYPTION_FAILED;
23563     }
23564     cp_hash_a_bytes.replace(2, std::string::npos, tmp);
23565   }
23566   std::unique_ptr<crypto::SecureHash> hash(
23567       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23568   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23569   hash->Update(policy_session_name.data(), policy_session_name.size());
23570   handle_section_bytes += policy_session_bytes;
23571   command_size += policy_session_bytes.size();
23572   hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
23573   parameter_section_bytes += cp_hash_a_bytes;
23574   command_size += cp_hash_a_bytes.size();
23575   std::string command_hash(32, 0);
23576   hash->Finish(std::data(command_hash), command_hash.size());
23577   std::string authorization_section_bytes;
23578   std::string authorization_size_bytes;
23579   if (authorization_delegate) {
23580     if (!authorization_delegate->GetCommandAuthorization(
23581             command_hash, is_command_parameter_encryption_possible,
23582             is_response_parameter_encryption_possible,
23583             &authorization_section_bytes)) {
23584       return TRUNKS_RC_AUTHORIZATION_FAILED;
23585     }
23586     if (!authorization_section_bytes.empty()) {
23587       tag = TPM_ST_SESSIONS;
23588       std::string tmp;
23589       rc = Serialize_UINT32(authorization_section_bytes.size(),
23590                             &authorization_size_bytes);
23591       if (rc != TPM_RC_SUCCESS) {
23592         return rc;
23593       }
23594       command_size +=
23595           authorization_size_bytes.size() + authorization_section_bytes.size();
23596     }
23597   }
23598   std::string tag_bytes;
23599   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23600   if (rc != TPM_RC_SUCCESS) {
23601     return rc;
23602   }
23603   std::string command_size_bytes;
23604   rc = Serialize_UINT32(command_size, &command_size_bytes);
23605   if (rc != TPM_RC_SUCCESS) {
23606     return rc;
23607   }
23608   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23609                         handle_section_bytes + authorization_size_bytes +
23610                         authorization_section_bytes + parameter_section_bytes;
23611   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23612   VLOG(2) << "Command: "
23613           << base::HexEncode(serialized_command->data(),
23614                              serialized_command->size());
23615   return TPM_RC_SUCCESS;
23616 }
23617 
ParseResponse_PolicyCpHash(const std::string & response,AuthorizationDelegate * authorization_delegate)23618 TPM_RC Tpm::ParseResponse_PolicyCpHash(
23619     const std::string& response,
23620     AuthorizationDelegate* authorization_delegate) {
23621   VLOG(3) << __func__;
23622   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23623   TPM_RC rc = TPM_RC_SUCCESS;
23624   std::string buffer(response);
23625   TPM_ST tag;
23626   std::string tag_bytes;
23627   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23628   if (rc != TPM_RC_SUCCESS) {
23629     return rc;
23630   }
23631   UINT32 response_size;
23632   std::string response_size_bytes;
23633   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23634   if (rc != TPM_RC_SUCCESS) {
23635     return rc;
23636   }
23637   TPM_RC response_code;
23638   std::string response_code_bytes;
23639   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23640   if (rc != TPM_RC_SUCCESS) {
23641     return rc;
23642   }
23643   if (response_size != response.size()) {
23644     return TPM_RC_SIZE;
23645   }
23646   if (response_code != TPM_RC_SUCCESS) {
23647     return response_code;
23648   }
23649   TPM_CC command_code = TPM_CC_PolicyCpHash;
23650   std::string command_code_bytes;
23651   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23652   if (rc != TPM_RC_SUCCESS) {
23653     return rc;
23654   }
23655   std::string authorization_section_bytes;
23656   if (tag == TPM_ST_SESSIONS) {
23657     UINT32 parameter_section_size = buffer.size();
23658     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23659     if (rc != TPM_RC_SUCCESS) {
23660       return rc;
23661     }
23662     if (parameter_section_size > buffer.size()) {
23663       return TPM_RC_INSUFFICIENT;
23664     }
23665     authorization_section_bytes = buffer.substr(parameter_section_size);
23666     // Keep the parameter section in |buffer|.
23667     buffer.erase(parameter_section_size);
23668   }
23669   std::unique_ptr<crypto::SecureHash> hash(
23670       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23671   hash->Update(response_code_bytes.data(), response_code_bytes.size());
23672   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23673   hash->Update(buffer.data(), buffer.size());
23674   std::string response_hash(32, 0);
23675   hash->Finish(std::data(response_hash), response_hash.size());
23676   if (tag == TPM_ST_SESSIONS) {
23677     if (!authorization_delegate)
23678       return TRUNKS_RC_AUTHORIZATION_FAILED;
23679     if (!authorization_delegate->CheckResponseAuthorization(
23680             response_hash, authorization_section_bytes)) {
23681       return TRUNKS_RC_AUTHORIZATION_FAILED;
23682     }
23683   }
23684   return TPM_RC_SUCCESS;
23685 }
23686 
PolicyCpHashErrorCallback(Tpm::PolicyCpHashResponse callback,TPM_RC response_code)23687 void PolicyCpHashErrorCallback(Tpm::PolicyCpHashResponse callback,
23688                                TPM_RC response_code) {
23689   VLOG(1) << __func__;
23690   std::move(callback).Run(response_code);
23691 }
23692 
PolicyCpHashResponseParser(Tpm::PolicyCpHashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23693 void PolicyCpHashResponseParser(Tpm::PolicyCpHashResponse callback,
23694                                 AuthorizationDelegate* authorization_delegate,
23695                                 const std::string& response) {
23696   VLOG(1) << __func__;
23697   TPM_RC rc = Tpm::ParseResponse_PolicyCpHash(response, authorization_delegate);
23698   if (rc != TPM_RC_SUCCESS) {
23699     base::OnceCallback<void(TPM_RC)> error_reporter =
23700         base::BindOnce(PolicyCpHashErrorCallback, std::move(callback));
23701     std::move(error_reporter).Run(rc);
23702     return;
23703   }
23704   std::move(callback).Run(rc);
23705 }
23706 
PolicyCpHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,AuthorizationDelegate * authorization_delegate,PolicyCpHashResponse callback)23707 void Tpm::PolicyCpHash(const TPMI_SH_POLICY& policy_session,
23708                        const std::string& policy_session_name,
23709                        const TPM2B_DIGEST& cp_hash_a,
23710                        AuthorizationDelegate* authorization_delegate,
23711                        PolicyCpHashResponse callback) {
23712   VLOG(1) << __func__;
23713   std::string command;
23714   TPM_RC rc = SerializeCommand_PolicyCpHash(policy_session, policy_session_name,
23715                                             cp_hash_a, &command,
23716                                             authorization_delegate);
23717   if (rc != TPM_RC_SUCCESS) {
23718     base::OnceCallback<void(TPM_RC)> error_reporter =
23719         base::BindOnce(PolicyCpHashErrorCallback, std::move(callback));
23720     std::move(error_reporter).Run(rc);
23721     return;
23722   }
23723   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
23724       PolicyCpHashResponseParser, std::move(callback), authorization_delegate);
23725   transceiver_->SendCommand(command, std::move(parser));
23726 }
23727 
PolicyCpHashSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,AuthorizationDelegate * authorization_delegate)23728 TPM_RC Tpm::PolicyCpHashSync(const TPMI_SH_POLICY& policy_session,
23729                              const std::string& policy_session_name,
23730                              const TPM2B_DIGEST& cp_hash_a,
23731                              AuthorizationDelegate* authorization_delegate) {
23732   VLOG(1) << __func__;
23733   std::string command;
23734   TPM_RC rc = SerializeCommand_PolicyCpHash(policy_session, policy_session_name,
23735                                             cp_hash_a, &command,
23736                                             authorization_delegate);
23737   if (rc != TPM_RC_SUCCESS) {
23738     return rc;
23739   }
23740   std::string response = transceiver_->SendCommandAndWait(command);
23741   rc = ParseResponse_PolicyCpHash(response, authorization_delegate);
23742   return rc;
23743 }
23744 
SerializeCommand_PolicyNameHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23745 TPM_RC Tpm::SerializeCommand_PolicyNameHash(
23746     const TPMI_SH_POLICY& policy_session,
23747     const std::string& policy_session_name,
23748     const TPM2B_DIGEST& name_hash,
23749     std::string* serialized_command,
23750     AuthorizationDelegate* authorization_delegate) {
23751   VLOG(3) << __func__;
23752   TPM_RC rc = TPM_RC_SUCCESS;
23753   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23754   UINT32 command_size = 10;  // Header size.
23755   std::string handle_section_bytes;
23756   std::string parameter_section_bytes;
23757   TPM_CC command_code = TPM_CC_PolicyNameHash;
23758   bool is_command_parameter_encryption_possible = true;
23759   bool is_response_parameter_encryption_possible = false;
23760   std::string command_code_bytes;
23761   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23762   if (rc != TPM_RC_SUCCESS) {
23763     return rc;
23764   }
23765   std::string policy_session_bytes;
23766   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23767   if (rc != TPM_RC_SUCCESS) {
23768     return rc;
23769   }
23770   std::string name_hash_bytes;
23771   rc = Serialize_TPM2B_DIGEST(name_hash, &name_hash_bytes);
23772   if (rc != TPM_RC_SUCCESS) {
23773     return rc;
23774   }
23775   if (authorization_delegate) {
23776     // Encrypt just the parameter data, not the size.
23777     std::string tmp = name_hash_bytes.substr(2);
23778     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23779       return TRUNKS_RC_ENCRYPTION_FAILED;
23780     }
23781     name_hash_bytes.replace(2, std::string::npos, tmp);
23782   }
23783   std::unique_ptr<crypto::SecureHash> hash(
23784       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23785   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23786   hash->Update(policy_session_name.data(), policy_session_name.size());
23787   handle_section_bytes += policy_session_bytes;
23788   command_size += policy_session_bytes.size();
23789   hash->Update(name_hash_bytes.data(), name_hash_bytes.size());
23790   parameter_section_bytes += name_hash_bytes;
23791   command_size += name_hash_bytes.size();
23792   std::string command_hash(32, 0);
23793   hash->Finish(std::data(command_hash), command_hash.size());
23794   std::string authorization_section_bytes;
23795   std::string authorization_size_bytes;
23796   if (authorization_delegate) {
23797     if (!authorization_delegate->GetCommandAuthorization(
23798             command_hash, is_command_parameter_encryption_possible,
23799             is_response_parameter_encryption_possible,
23800             &authorization_section_bytes)) {
23801       return TRUNKS_RC_AUTHORIZATION_FAILED;
23802     }
23803     if (!authorization_section_bytes.empty()) {
23804       tag = TPM_ST_SESSIONS;
23805       std::string tmp;
23806       rc = Serialize_UINT32(authorization_section_bytes.size(),
23807                             &authorization_size_bytes);
23808       if (rc != TPM_RC_SUCCESS) {
23809         return rc;
23810       }
23811       command_size +=
23812           authorization_size_bytes.size() + authorization_section_bytes.size();
23813     }
23814   }
23815   std::string tag_bytes;
23816   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23817   if (rc != TPM_RC_SUCCESS) {
23818     return rc;
23819   }
23820   std::string command_size_bytes;
23821   rc = Serialize_UINT32(command_size, &command_size_bytes);
23822   if (rc != TPM_RC_SUCCESS) {
23823     return rc;
23824   }
23825   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23826                         handle_section_bytes + authorization_size_bytes +
23827                         authorization_section_bytes + parameter_section_bytes;
23828   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23829   VLOG(2) << "Command: "
23830           << base::HexEncode(serialized_command->data(),
23831                              serialized_command->size());
23832   return TPM_RC_SUCCESS;
23833 }
23834 
ParseResponse_PolicyNameHash(const std::string & response,AuthorizationDelegate * authorization_delegate)23835 TPM_RC Tpm::ParseResponse_PolicyNameHash(
23836     const std::string& response,
23837     AuthorizationDelegate* authorization_delegate) {
23838   VLOG(3) << __func__;
23839   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23840   TPM_RC rc = TPM_RC_SUCCESS;
23841   std::string buffer(response);
23842   TPM_ST tag;
23843   std::string tag_bytes;
23844   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23845   if (rc != TPM_RC_SUCCESS) {
23846     return rc;
23847   }
23848   UINT32 response_size;
23849   std::string response_size_bytes;
23850   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23851   if (rc != TPM_RC_SUCCESS) {
23852     return rc;
23853   }
23854   TPM_RC response_code;
23855   std::string response_code_bytes;
23856   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23857   if (rc != TPM_RC_SUCCESS) {
23858     return rc;
23859   }
23860   if (response_size != response.size()) {
23861     return TPM_RC_SIZE;
23862   }
23863   if (response_code != TPM_RC_SUCCESS) {
23864     return response_code;
23865   }
23866   TPM_CC command_code = TPM_CC_PolicyNameHash;
23867   std::string command_code_bytes;
23868   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23869   if (rc != TPM_RC_SUCCESS) {
23870     return rc;
23871   }
23872   std::string authorization_section_bytes;
23873   if (tag == TPM_ST_SESSIONS) {
23874     UINT32 parameter_section_size = buffer.size();
23875     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23876     if (rc != TPM_RC_SUCCESS) {
23877       return rc;
23878     }
23879     if (parameter_section_size > buffer.size()) {
23880       return TPM_RC_INSUFFICIENT;
23881     }
23882     authorization_section_bytes = buffer.substr(parameter_section_size);
23883     // Keep the parameter section in |buffer|.
23884     buffer.erase(parameter_section_size);
23885   }
23886   std::unique_ptr<crypto::SecureHash> hash(
23887       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23888   hash->Update(response_code_bytes.data(), response_code_bytes.size());
23889   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23890   hash->Update(buffer.data(), buffer.size());
23891   std::string response_hash(32, 0);
23892   hash->Finish(std::data(response_hash), response_hash.size());
23893   if (tag == TPM_ST_SESSIONS) {
23894     if (!authorization_delegate)
23895       return TRUNKS_RC_AUTHORIZATION_FAILED;
23896     if (!authorization_delegate->CheckResponseAuthorization(
23897             response_hash, authorization_section_bytes)) {
23898       return TRUNKS_RC_AUTHORIZATION_FAILED;
23899     }
23900   }
23901   return TPM_RC_SUCCESS;
23902 }
23903 
PolicyNameHashErrorCallback(Tpm::PolicyNameHashResponse callback,TPM_RC response_code)23904 void PolicyNameHashErrorCallback(Tpm::PolicyNameHashResponse callback,
23905                                  TPM_RC response_code) {
23906   VLOG(1) << __func__;
23907   std::move(callback).Run(response_code);
23908 }
23909 
PolicyNameHashResponseParser(Tpm::PolicyNameHashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23910 void PolicyNameHashResponseParser(Tpm::PolicyNameHashResponse callback,
23911                                   AuthorizationDelegate* authorization_delegate,
23912                                   const std::string& response) {
23913   VLOG(1) << __func__;
23914   TPM_RC rc =
23915       Tpm::ParseResponse_PolicyNameHash(response, authorization_delegate);
23916   if (rc != TPM_RC_SUCCESS) {
23917     base::OnceCallback<void(TPM_RC)> error_reporter =
23918         base::BindOnce(PolicyNameHashErrorCallback, std::move(callback));
23919     std::move(error_reporter).Run(rc);
23920     return;
23921   }
23922   std::move(callback).Run(rc);
23923 }
23924 
PolicyNameHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,AuthorizationDelegate * authorization_delegate,PolicyNameHashResponse callback)23925 void Tpm::PolicyNameHash(const TPMI_SH_POLICY& policy_session,
23926                          const std::string& policy_session_name,
23927                          const TPM2B_DIGEST& name_hash,
23928                          AuthorizationDelegate* authorization_delegate,
23929                          PolicyNameHashResponse callback) {
23930   VLOG(1) << __func__;
23931   std::string command;
23932   TPM_RC rc = SerializeCommand_PolicyNameHash(policy_session,
23933                                               policy_session_name, name_hash,
23934                                               &command, authorization_delegate);
23935   if (rc != TPM_RC_SUCCESS) {
23936     base::OnceCallback<void(TPM_RC)> error_reporter =
23937         base::BindOnce(PolicyNameHashErrorCallback, std::move(callback));
23938     std::move(error_reporter).Run(rc);
23939     return;
23940   }
23941   base::OnceCallback<void(const std::string&)> parser =
23942       base::BindOnce(PolicyNameHashResponseParser, std::move(callback),
23943                      authorization_delegate);
23944   transceiver_->SendCommand(command, std::move(parser));
23945 }
23946 
PolicyNameHashSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,AuthorizationDelegate * authorization_delegate)23947 TPM_RC Tpm::PolicyNameHashSync(const TPMI_SH_POLICY& policy_session,
23948                                const std::string& policy_session_name,
23949                                const TPM2B_DIGEST& name_hash,
23950                                AuthorizationDelegate* authorization_delegate) {
23951   VLOG(1) << __func__;
23952   std::string command;
23953   TPM_RC rc = SerializeCommand_PolicyNameHash(policy_session,
23954                                               policy_session_name, name_hash,
23955                                               &command, authorization_delegate);
23956   if (rc != TPM_RC_SUCCESS) {
23957     return rc;
23958   }
23959   std::string response = transceiver_->SendCommandAndWait(command);
23960   rc = ParseResponse_PolicyNameHash(response, authorization_delegate);
23961   return rc;
23962 }
23963 
SerializeCommand_PolicyDuplicationSelect(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NAME & object_name,const TPM2B_NAME & new_parent_name,const TPMI_YES_NO & include_object,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23964 TPM_RC Tpm::SerializeCommand_PolicyDuplicationSelect(
23965     const TPMI_SH_POLICY& policy_session,
23966     const std::string& policy_session_name,
23967     const TPM2B_NAME& object_name,
23968     const TPM2B_NAME& new_parent_name,
23969     const TPMI_YES_NO& include_object,
23970     std::string* serialized_command,
23971     AuthorizationDelegate* authorization_delegate) {
23972   VLOG(3) << __func__;
23973   TPM_RC rc = TPM_RC_SUCCESS;
23974   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23975   UINT32 command_size = 10;  // Header size.
23976   std::string handle_section_bytes;
23977   std::string parameter_section_bytes;
23978   TPM_CC command_code = TPM_CC_PolicyDuplicationSelect;
23979   bool is_command_parameter_encryption_possible = true;
23980   bool is_response_parameter_encryption_possible = false;
23981   std::string command_code_bytes;
23982   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23983   if (rc != TPM_RC_SUCCESS) {
23984     return rc;
23985   }
23986   std::string policy_session_bytes;
23987   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23988   if (rc != TPM_RC_SUCCESS) {
23989     return rc;
23990   }
23991   std::string object_name_bytes;
23992   rc = Serialize_TPM2B_NAME(object_name, &object_name_bytes);
23993   if (rc != TPM_RC_SUCCESS) {
23994     return rc;
23995   }
23996   std::string new_parent_name_bytes;
23997   rc = Serialize_TPM2B_NAME(new_parent_name, &new_parent_name_bytes);
23998   if (rc != TPM_RC_SUCCESS) {
23999     return rc;
24000   }
24001   std::string include_object_bytes;
24002   rc = Serialize_TPMI_YES_NO(include_object, &include_object_bytes);
24003   if (rc != TPM_RC_SUCCESS) {
24004     return rc;
24005   }
24006   if (authorization_delegate) {
24007     // Encrypt just the parameter data, not the size.
24008     std::string tmp = object_name_bytes.substr(2);
24009     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
24010       return TRUNKS_RC_ENCRYPTION_FAILED;
24011     }
24012     object_name_bytes.replace(2, std::string::npos, tmp);
24013   }
24014   std::unique_ptr<crypto::SecureHash> hash(
24015       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24016   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24017   hash->Update(policy_session_name.data(), policy_session_name.size());
24018   handle_section_bytes += policy_session_bytes;
24019   command_size += policy_session_bytes.size();
24020   hash->Update(object_name_bytes.data(), object_name_bytes.size());
24021   parameter_section_bytes += object_name_bytes;
24022   command_size += object_name_bytes.size();
24023   hash->Update(new_parent_name_bytes.data(), new_parent_name_bytes.size());
24024   parameter_section_bytes += new_parent_name_bytes;
24025   command_size += new_parent_name_bytes.size();
24026   hash->Update(include_object_bytes.data(), include_object_bytes.size());
24027   parameter_section_bytes += include_object_bytes;
24028   command_size += include_object_bytes.size();
24029   std::string command_hash(32, 0);
24030   hash->Finish(std::data(command_hash), command_hash.size());
24031   std::string authorization_section_bytes;
24032   std::string authorization_size_bytes;
24033   if (authorization_delegate) {
24034     if (!authorization_delegate->GetCommandAuthorization(
24035             command_hash, is_command_parameter_encryption_possible,
24036             is_response_parameter_encryption_possible,
24037             &authorization_section_bytes)) {
24038       return TRUNKS_RC_AUTHORIZATION_FAILED;
24039     }
24040     if (!authorization_section_bytes.empty()) {
24041       tag = TPM_ST_SESSIONS;
24042       std::string tmp;
24043       rc = Serialize_UINT32(authorization_section_bytes.size(),
24044                             &authorization_size_bytes);
24045       if (rc != TPM_RC_SUCCESS) {
24046         return rc;
24047       }
24048       command_size +=
24049           authorization_size_bytes.size() + authorization_section_bytes.size();
24050     }
24051   }
24052   std::string tag_bytes;
24053   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24054   if (rc != TPM_RC_SUCCESS) {
24055     return rc;
24056   }
24057   std::string command_size_bytes;
24058   rc = Serialize_UINT32(command_size, &command_size_bytes);
24059   if (rc != TPM_RC_SUCCESS) {
24060     return rc;
24061   }
24062   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24063                         handle_section_bytes + authorization_size_bytes +
24064                         authorization_section_bytes + parameter_section_bytes;
24065   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24066   VLOG(2) << "Command: "
24067           << base::HexEncode(serialized_command->data(),
24068                              serialized_command->size());
24069   return TPM_RC_SUCCESS;
24070 }
24071 
ParseResponse_PolicyDuplicationSelect(const std::string & response,AuthorizationDelegate * authorization_delegate)24072 TPM_RC Tpm::ParseResponse_PolicyDuplicationSelect(
24073     const std::string& response,
24074     AuthorizationDelegate* authorization_delegate) {
24075   VLOG(3) << __func__;
24076   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24077   TPM_RC rc = TPM_RC_SUCCESS;
24078   std::string buffer(response);
24079   TPM_ST tag;
24080   std::string tag_bytes;
24081   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24082   if (rc != TPM_RC_SUCCESS) {
24083     return rc;
24084   }
24085   UINT32 response_size;
24086   std::string response_size_bytes;
24087   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24088   if (rc != TPM_RC_SUCCESS) {
24089     return rc;
24090   }
24091   TPM_RC response_code;
24092   std::string response_code_bytes;
24093   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24094   if (rc != TPM_RC_SUCCESS) {
24095     return rc;
24096   }
24097   if (response_size != response.size()) {
24098     return TPM_RC_SIZE;
24099   }
24100   if (response_code != TPM_RC_SUCCESS) {
24101     return response_code;
24102   }
24103   TPM_CC command_code = TPM_CC_PolicyDuplicationSelect;
24104   std::string command_code_bytes;
24105   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24106   if (rc != TPM_RC_SUCCESS) {
24107     return rc;
24108   }
24109   std::string authorization_section_bytes;
24110   if (tag == TPM_ST_SESSIONS) {
24111     UINT32 parameter_section_size = buffer.size();
24112     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24113     if (rc != TPM_RC_SUCCESS) {
24114       return rc;
24115     }
24116     if (parameter_section_size > buffer.size()) {
24117       return TPM_RC_INSUFFICIENT;
24118     }
24119     authorization_section_bytes = buffer.substr(parameter_section_size);
24120     // Keep the parameter section in |buffer|.
24121     buffer.erase(parameter_section_size);
24122   }
24123   std::unique_ptr<crypto::SecureHash> hash(
24124       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24125   hash->Update(response_code_bytes.data(), response_code_bytes.size());
24126   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24127   hash->Update(buffer.data(), buffer.size());
24128   std::string response_hash(32, 0);
24129   hash->Finish(std::data(response_hash), response_hash.size());
24130   if (tag == TPM_ST_SESSIONS) {
24131     if (!authorization_delegate)
24132       return TRUNKS_RC_AUTHORIZATION_FAILED;
24133     if (!authorization_delegate->CheckResponseAuthorization(
24134             response_hash, authorization_section_bytes)) {
24135       return TRUNKS_RC_AUTHORIZATION_FAILED;
24136     }
24137   }
24138   return TPM_RC_SUCCESS;
24139 }
24140 
PolicyDuplicationSelectErrorCallback(Tpm::PolicyDuplicationSelectResponse callback,TPM_RC response_code)24141 void PolicyDuplicationSelectErrorCallback(
24142     Tpm::PolicyDuplicationSelectResponse callback, TPM_RC response_code) {
24143   VLOG(1) << __func__;
24144   std::move(callback).Run(response_code);
24145 }
24146 
PolicyDuplicationSelectResponseParser(Tpm::PolicyDuplicationSelectResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24147 void PolicyDuplicationSelectResponseParser(
24148     Tpm::PolicyDuplicationSelectResponse callback,
24149     AuthorizationDelegate* authorization_delegate,
24150     const std::string& response) {
24151   VLOG(1) << __func__;
24152   TPM_RC rc = Tpm::ParseResponse_PolicyDuplicationSelect(
24153       response, authorization_delegate);
24154   if (rc != TPM_RC_SUCCESS) {
24155     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
24156         PolicyDuplicationSelectErrorCallback, std::move(callback));
24157     std::move(error_reporter).Run(rc);
24158     return;
24159   }
24160   std::move(callback).Run(rc);
24161 }
24162 
PolicyDuplicationSelect(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NAME & object_name,const TPM2B_NAME & new_parent_name,const TPMI_YES_NO & include_object,AuthorizationDelegate * authorization_delegate,PolicyDuplicationSelectResponse callback)24163 void Tpm::PolicyDuplicationSelect(const TPMI_SH_POLICY& policy_session,
24164                                   const std::string& policy_session_name,
24165                                   const TPM2B_NAME& object_name,
24166                                   const TPM2B_NAME& new_parent_name,
24167                                   const TPMI_YES_NO& include_object,
24168                                   AuthorizationDelegate* authorization_delegate,
24169                                   PolicyDuplicationSelectResponse callback) {
24170   VLOG(1) << __func__;
24171   std::string command;
24172   TPM_RC rc = SerializeCommand_PolicyDuplicationSelect(
24173       policy_session, policy_session_name, object_name, new_parent_name,
24174       include_object, &command, authorization_delegate);
24175   if (rc != TPM_RC_SUCCESS) {
24176     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
24177         PolicyDuplicationSelectErrorCallback, std::move(callback));
24178     std::move(error_reporter).Run(rc);
24179     return;
24180   }
24181   base::OnceCallback<void(const std::string&)> parser =
24182       base::BindOnce(PolicyDuplicationSelectResponseParser, std::move(callback),
24183                      authorization_delegate);
24184   transceiver_->SendCommand(command, std::move(parser));
24185 }
24186 
PolicyDuplicationSelectSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NAME & object_name,const TPM2B_NAME & new_parent_name,const TPMI_YES_NO & include_object,AuthorizationDelegate * authorization_delegate)24187 TPM_RC Tpm::PolicyDuplicationSelectSync(
24188     const TPMI_SH_POLICY& policy_session,
24189     const std::string& policy_session_name,
24190     const TPM2B_NAME& object_name,
24191     const TPM2B_NAME& new_parent_name,
24192     const TPMI_YES_NO& include_object,
24193     AuthorizationDelegate* authorization_delegate) {
24194   VLOG(1) << __func__;
24195   std::string command;
24196   TPM_RC rc = SerializeCommand_PolicyDuplicationSelect(
24197       policy_session, policy_session_name, object_name, new_parent_name,
24198       include_object, &command, authorization_delegate);
24199   if (rc != TPM_RC_SUCCESS) {
24200     return rc;
24201   }
24202   std::string response = transceiver_->SendCommandAndWait(command);
24203   rc = ParseResponse_PolicyDuplicationSelect(response, authorization_delegate);
24204   return rc;
24205 }
24206 
SerializeCommand_PolicyAuthorize(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & approved_policy,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & key_sign,const TPMT_TK_VERIFIED & check_ticket,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24207 TPM_RC Tpm::SerializeCommand_PolicyAuthorize(
24208     const TPMI_SH_POLICY& policy_session,
24209     const std::string& policy_session_name,
24210     const TPM2B_DIGEST& approved_policy,
24211     const TPM2B_NONCE& policy_ref,
24212     const TPM2B_NAME& key_sign,
24213     const TPMT_TK_VERIFIED& check_ticket,
24214     std::string* serialized_command,
24215     AuthorizationDelegate* authorization_delegate) {
24216   VLOG(3) << __func__;
24217   TPM_RC rc = TPM_RC_SUCCESS;
24218   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24219   UINT32 command_size = 10;  // Header size.
24220   std::string handle_section_bytes;
24221   std::string parameter_section_bytes;
24222   TPM_CC command_code = TPM_CC_PolicyAuthorize;
24223   bool is_command_parameter_encryption_possible = true;
24224   bool is_response_parameter_encryption_possible = false;
24225   std::string command_code_bytes;
24226   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24227   if (rc != TPM_RC_SUCCESS) {
24228     return rc;
24229   }
24230   std::string policy_session_bytes;
24231   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24232   if (rc != TPM_RC_SUCCESS) {
24233     return rc;
24234   }
24235   std::string approved_policy_bytes;
24236   rc = Serialize_TPM2B_DIGEST(approved_policy, &approved_policy_bytes);
24237   if (rc != TPM_RC_SUCCESS) {
24238     return rc;
24239   }
24240   std::string policy_ref_bytes;
24241   rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
24242   if (rc != TPM_RC_SUCCESS) {
24243     return rc;
24244   }
24245   std::string key_sign_bytes;
24246   rc = Serialize_TPM2B_NAME(key_sign, &key_sign_bytes);
24247   if (rc != TPM_RC_SUCCESS) {
24248     return rc;
24249   }
24250   std::string check_ticket_bytes;
24251   rc = Serialize_TPMT_TK_VERIFIED(check_ticket, &check_ticket_bytes);
24252   if (rc != TPM_RC_SUCCESS) {
24253     return rc;
24254   }
24255   if (authorization_delegate) {
24256     // Encrypt just the parameter data, not the size.
24257     std::string tmp = approved_policy_bytes.substr(2);
24258     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
24259       return TRUNKS_RC_ENCRYPTION_FAILED;
24260     }
24261     approved_policy_bytes.replace(2, std::string::npos, tmp);
24262   }
24263   std::unique_ptr<crypto::SecureHash> hash(
24264       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24265   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24266   hash->Update(policy_session_name.data(), policy_session_name.size());
24267   handle_section_bytes += policy_session_bytes;
24268   command_size += policy_session_bytes.size();
24269   hash->Update(approved_policy_bytes.data(), approved_policy_bytes.size());
24270   parameter_section_bytes += approved_policy_bytes;
24271   command_size += approved_policy_bytes.size();
24272   hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
24273   parameter_section_bytes += policy_ref_bytes;
24274   command_size += policy_ref_bytes.size();
24275   hash->Update(key_sign_bytes.data(), key_sign_bytes.size());
24276   parameter_section_bytes += key_sign_bytes;
24277   command_size += key_sign_bytes.size();
24278   hash->Update(check_ticket_bytes.data(), check_ticket_bytes.size());
24279   parameter_section_bytes += check_ticket_bytes;
24280   command_size += check_ticket_bytes.size();
24281   std::string command_hash(32, 0);
24282   hash->Finish(std::data(command_hash), command_hash.size());
24283   std::string authorization_section_bytes;
24284   std::string authorization_size_bytes;
24285   if (authorization_delegate) {
24286     if (!authorization_delegate->GetCommandAuthorization(
24287             command_hash, is_command_parameter_encryption_possible,
24288             is_response_parameter_encryption_possible,
24289             &authorization_section_bytes)) {
24290       return TRUNKS_RC_AUTHORIZATION_FAILED;
24291     }
24292     if (!authorization_section_bytes.empty()) {
24293       tag = TPM_ST_SESSIONS;
24294       std::string tmp;
24295       rc = Serialize_UINT32(authorization_section_bytes.size(),
24296                             &authorization_size_bytes);
24297       if (rc != TPM_RC_SUCCESS) {
24298         return rc;
24299       }
24300       command_size +=
24301           authorization_size_bytes.size() + authorization_section_bytes.size();
24302     }
24303   }
24304   std::string tag_bytes;
24305   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24306   if (rc != TPM_RC_SUCCESS) {
24307     return rc;
24308   }
24309   std::string command_size_bytes;
24310   rc = Serialize_UINT32(command_size, &command_size_bytes);
24311   if (rc != TPM_RC_SUCCESS) {
24312     return rc;
24313   }
24314   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24315                         handle_section_bytes + authorization_size_bytes +
24316                         authorization_section_bytes + parameter_section_bytes;
24317   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24318   VLOG(2) << "Command: "
24319           << base::HexEncode(serialized_command->data(),
24320                              serialized_command->size());
24321   return TPM_RC_SUCCESS;
24322 }
24323 
ParseResponse_PolicyAuthorize(const std::string & response,AuthorizationDelegate * authorization_delegate)24324 TPM_RC Tpm::ParseResponse_PolicyAuthorize(
24325     const std::string& response,
24326     AuthorizationDelegate* authorization_delegate) {
24327   VLOG(3) << __func__;
24328   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24329   TPM_RC rc = TPM_RC_SUCCESS;
24330   std::string buffer(response);
24331   TPM_ST tag;
24332   std::string tag_bytes;
24333   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24334   if (rc != TPM_RC_SUCCESS) {
24335     return rc;
24336   }
24337   UINT32 response_size;
24338   std::string response_size_bytes;
24339   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24340   if (rc != TPM_RC_SUCCESS) {
24341     return rc;
24342   }
24343   TPM_RC response_code;
24344   std::string response_code_bytes;
24345   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24346   if (rc != TPM_RC_SUCCESS) {
24347     return rc;
24348   }
24349   if (response_size != response.size()) {
24350     return TPM_RC_SIZE;
24351   }
24352   if (response_code != TPM_RC_SUCCESS) {
24353     return response_code;
24354   }
24355   TPM_CC command_code = TPM_CC_PolicyAuthorize;
24356   std::string command_code_bytes;
24357   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24358   if (rc != TPM_RC_SUCCESS) {
24359     return rc;
24360   }
24361   std::string authorization_section_bytes;
24362   if (tag == TPM_ST_SESSIONS) {
24363     UINT32 parameter_section_size = buffer.size();
24364     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24365     if (rc != TPM_RC_SUCCESS) {
24366       return rc;
24367     }
24368     if (parameter_section_size > buffer.size()) {
24369       return TPM_RC_INSUFFICIENT;
24370     }
24371     authorization_section_bytes = buffer.substr(parameter_section_size);
24372     // Keep the parameter section in |buffer|.
24373     buffer.erase(parameter_section_size);
24374   }
24375   std::unique_ptr<crypto::SecureHash> hash(
24376       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24377   hash->Update(response_code_bytes.data(), response_code_bytes.size());
24378   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24379   hash->Update(buffer.data(), buffer.size());
24380   std::string response_hash(32, 0);
24381   hash->Finish(std::data(response_hash), response_hash.size());
24382   if (tag == TPM_ST_SESSIONS) {
24383     if (!authorization_delegate)
24384       return TRUNKS_RC_AUTHORIZATION_FAILED;
24385     if (!authorization_delegate->CheckResponseAuthorization(
24386             response_hash, authorization_section_bytes)) {
24387       return TRUNKS_RC_AUTHORIZATION_FAILED;
24388     }
24389   }
24390   return TPM_RC_SUCCESS;
24391 }
24392 
PolicyAuthorizeErrorCallback(Tpm::PolicyAuthorizeResponse callback,TPM_RC response_code)24393 void PolicyAuthorizeErrorCallback(Tpm::PolicyAuthorizeResponse callback,
24394                                   TPM_RC response_code) {
24395   VLOG(1) << __func__;
24396   std::move(callback).Run(response_code);
24397 }
24398 
PolicyAuthorizeResponseParser(Tpm::PolicyAuthorizeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24399 void PolicyAuthorizeResponseParser(
24400     Tpm::PolicyAuthorizeResponse callback,
24401     AuthorizationDelegate* authorization_delegate,
24402     const std::string& response) {
24403   VLOG(1) << __func__;
24404   TPM_RC rc =
24405       Tpm::ParseResponse_PolicyAuthorize(response, authorization_delegate);
24406   if (rc != TPM_RC_SUCCESS) {
24407     base::OnceCallback<void(TPM_RC)> error_reporter =
24408         base::BindOnce(PolicyAuthorizeErrorCallback, std::move(callback));
24409     std::move(error_reporter).Run(rc);
24410     return;
24411   }
24412   std::move(callback).Run(rc);
24413 }
24414 
PolicyAuthorize(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & approved_policy,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & key_sign,const TPMT_TK_VERIFIED & check_ticket,AuthorizationDelegate * authorization_delegate,PolicyAuthorizeResponse callback)24415 void Tpm::PolicyAuthorize(const TPMI_SH_POLICY& policy_session,
24416                           const std::string& policy_session_name,
24417                           const TPM2B_DIGEST& approved_policy,
24418                           const TPM2B_NONCE& policy_ref,
24419                           const TPM2B_NAME& key_sign,
24420                           const TPMT_TK_VERIFIED& check_ticket,
24421                           AuthorizationDelegate* authorization_delegate,
24422                           PolicyAuthorizeResponse callback) {
24423   VLOG(1) << __func__;
24424   std::string command;
24425   TPM_RC rc = SerializeCommand_PolicyAuthorize(
24426       policy_session, policy_session_name, approved_policy, policy_ref,
24427       key_sign, check_ticket, &command, authorization_delegate);
24428   if (rc != TPM_RC_SUCCESS) {
24429     base::OnceCallback<void(TPM_RC)> error_reporter =
24430         base::BindOnce(PolicyAuthorizeErrorCallback, std::move(callback));
24431     std::move(error_reporter).Run(rc);
24432     return;
24433   }
24434   base::OnceCallback<void(const std::string&)> parser =
24435       base::BindOnce(PolicyAuthorizeResponseParser, std::move(callback),
24436                      authorization_delegate);
24437   transceiver_->SendCommand(command, std::move(parser));
24438 }
24439 
PolicyAuthorizeSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & approved_policy,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & key_sign,const TPMT_TK_VERIFIED & check_ticket,AuthorizationDelegate * authorization_delegate)24440 TPM_RC Tpm::PolicyAuthorizeSync(const TPMI_SH_POLICY& policy_session,
24441                                 const std::string& policy_session_name,
24442                                 const TPM2B_DIGEST& approved_policy,
24443                                 const TPM2B_NONCE& policy_ref,
24444                                 const TPM2B_NAME& key_sign,
24445                                 const TPMT_TK_VERIFIED& check_ticket,
24446                                 AuthorizationDelegate* authorization_delegate) {
24447   VLOG(1) << __func__;
24448   std::string command;
24449   TPM_RC rc = SerializeCommand_PolicyAuthorize(
24450       policy_session, policy_session_name, approved_policy, policy_ref,
24451       key_sign, check_ticket, &command, authorization_delegate);
24452   if (rc != TPM_RC_SUCCESS) {
24453     return rc;
24454   }
24455   std::string response = transceiver_->SendCommandAndWait(command);
24456   rc = ParseResponse_PolicyAuthorize(response, authorization_delegate);
24457   return rc;
24458 }
24459 
SerializeCommand_PolicyAuthValue(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24460 TPM_RC Tpm::SerializeCommand_PolicyAuthValue(
24461     const TPMI_SH_POLICY& policy_session,
24462     const std::string& policy_session_name,
24463     std::string* serialized_command,
24464     AuthorizationDelegate* authorization_delegate) {
24465   VLOG(3) << __func__;
24466   TPM_RC rc = TPM_RC_SUCCESS;
24467   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24468   UINT32 command_size = 10;  // Header size.
24469   std::string handle_section_bytes;
24470   std::string parameter_section_bytes;
24471   TPM_CC command_code = TPM_CC_PolicyAuthValue;
24472   bool is_command_parameter_encryption_possible = false;
24473   bool is_response_parameter_encryption_possible = false;
24474   std::string command_code_bytes;
24475   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24476   if (rc != TPM_RC_SUCCESS) {
24477     return rc;
24478   }
24479   std::string policy_session_bytes;
24480   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24481   if (rc != TPM_RC_SUCCESS) {
24482     return rc;
24483   }
24484   std::unique_ptr<crypto::SecureHash> hash(
24485       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24486   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24487   hash->Update(policy_session_name.data(), policy_session_name.size());
24488   handle_section_bytes += policy_session_bytes;
24489   command_size += policy_session_bytes.size();
24490   std::string command_hash(32, 0);
24491   hash->Finish(std::data(command_hash), command_hash.size());
24492   std::string authorization_section_bytes;
24493   std::string authorization_size_bytes;
24494   if (authorization_delegate) {
24495     if (!authorization_delegate->GetCommandAuthorization(
24496             command_hash, is_command_parameter_encryption_possible,
24497             is_response_parameter_encryption_possible,
24498             &authorization_section_bytes)) {
24499       return TRUNKS_RC_AUTHORIZATION_FAILED;
24500     }
24501     if (!authorization_section_bytes.empty()) {
24502       tag = TPM_ST_SESSIONS;
24503       std::string tmp;
24504       rc = Serialize_UINT32(authorization_section_bytes.size(),
24505                             &authorization_size_bytes);
24506       if (rc != TPM_RC_SUCCESS) {
24507         return rc;
24508       }
24509       command_size +=
24510           authorization_size_bytes.size() + authorization_section_bytes.size();
24511     }
24512   }
24513   std::string tag_bytes;
24514   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24515   if (rc != TPM_RC_SUCCESS) {
24516     return rc;
24517   }
24518   std::string command_size_bytes;
24519   rc = Serialize_UINT32(command_size, &command_size_bytes);
24520   if (rc != TPM_RC_SUCCESS) {
24521     return rc;
24522   }
24523   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24524                         handle_section_bytes + authorization_size_bytes +
24525                         authorization_section_bytes + parameter_section_bytes;
24526   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24527   VLOG(2) << "Command: "
24528           << base::HexEncode(serialized_command->data(),
24529                              serialized_command->size());
24530   return TPM_RC_SUCCESS;
24531 }
24532 
ParseResponse_PolicyAuthValue(const std::string & response,AuthorizationDelegate * authorization_delegate)24533 TPM_RC Tpm::ParseResponse_PolicyAuthValue(
24534     const std::string& response,
24535     AuthorizationDelegate* authorization_delegate) {
24536   VLOG(3) << __func__;
24537   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24538   TPM_RC rc = TPM_RC_SUCCESS;
24539   std::string buffer(response);
24540   TPM_ST tag;
24541   std::string tag_bytes;
24542   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24543   if (rc != TPM_RC_SUCCESS) {
24544     return rc;
24545   }
24546   UINT32 response_size;
24547   std::string response_size_bytes;
24548   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24549   if (rc != TPM_RC_SUCCESS) {
24550     return rc;
24551   }
24552   TPM_RC response_code;
24553   std::string response_code_bytes;
24554   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24555   if (rc != TPM_RC_SUCCESS) {
24556     return rc;
24557   }
24558   if (response_size != response.size()) {
24559     return TPM_RC_SIZE;
24560   }
24561   if (response_code != TPM_RC_SUCCESS) {
24562     return response_code;
24563   }
24564   TPM_CC command_code = TPM_CC_PolicyAuthValue;
24565   std::string command_code_bytes;
24566   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24567   if (rc != TPM_RC_SUCCESS) {
24568     return rc;
24569   }
24570   std::string authorization_section_bytes;
24571   if (tag == TPM_ST_SESSIONS) {
24572     UINT32 parameter_section_size = buffer.size();
24573     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24574     if (rc != TPM_RC_SUCCESS) {
24575       return rc;
24576     }
24577     if (parameter_section_size > buffer.size()) {
24578       return TPM_RC_INSUFFICIENT;
24579     }
24580     authorization_section_bytes = buffer.substr(parameter_section_size);
24581     // Keep the parameter section in |buffer|.
24582     buffer.erase(parameter_section_size);
24583   }
24584   std::unique_ptr<crypto::SecureHash> hash(
24585       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24586   hash->Update(response_code_bytes.data(), response_code_bytes.size());
24587   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24588   hash->Update(buffer.data(), buffer.size());
24589   std::string response_hash(32, 0);
24590   hash->Finish(std::data(response_hash), response_hash.size());
24591   if (tag == TPM_ST_SESSIONS) {
24592     if (!authorization_delegate)
24593       return TRUNKS_RC_AUTHORIZATION_FAILED;
24594     if (!authorization_delegate->CheckResponseAuthorization(
24595             response_hash, authorization_section_bytes)) {
24596       return TRUNKS_RC_AUTHORIZATION_FAILED;
24597     }
24598   }
24599   return TPM_RC_SUCCESS;
24600 }
24601 
PolicyAuthValueErrorCallback(Tpm::PolicyAuthValueResponse callback,TPM_RC response_code)24602 void PolicyAuthValueErrorCallback(Tpm::PolicyAuthValueResponse callback,
24603                                   TPM_RC response_code) {
24604   VLOG(1) << __func__;
24605   std::move(callback).Run(response_code);
24606 }
24607 
PolicyAuthValueResponseParser(Tpm::PolicyAuthValueResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24608 void PolicyAuthValueResponseParser(
24609     Tpm::PolicyAuthValueResponse callback,
24610     AuthorizationDelegate* authorization_delegate,
24611     const std::string& response) {
24612   VLOG(1) << __func__;
24613   TPM_RC rc =
24614       Tpm::ParseResponse_PolicyAuthValue(response, authorization_delegate);
24615   if (rc != TPM_RC_SUCCESS) {
24616     base::OnceCallback<void(TPM_RC)> error_reporter =
24617         base::BindOnce(PolicyAuthValueErrorCallback, std::move(callback));
24618     std::move(error_reporter).Run(rc);
24619     return;
24620   }
24621   std::move(callback).Run(rc);
24622 }
24623 
PolicyAuthValue(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyAuthValueResponse callback)24624 void Tpm::PolicyAuthValue(const TPMI_SH_POLICY& policy_session,
24625                           const std::string& policy_session_name,
24626                           AuthorizationDelegate* authorization_delegate,
24627                           PolicyAuthValueResponse callback) {
24628   VLOG(1) << __func__;
24629   std::string command;
24630   TPM_RC rc = SerializeCommand_PolicyAuthValue(
24631       policy_session, policy_session_name, &command, authorization_delegate);
24632   if (rc != TPM_RC_SUCCESS) {
24633     base::OnceCallback<void(TPM_RC)> error_reporter =
24634         base::BindOnce(PolicyAuthValueErrorCallback, std::move(callback));
24635     std::move(error_reporter).Run(rc);
24636     return;
24637   }
24638   base::OnceCallback<void(const std::string&)> parser =
24639       base::BindOnce(PolicyAuthValueResponseParser, std::move(callback),
24640                      authorization_delegate);
24641   transceiver_->SendCommand(command, std::move(parser));
24642 }
24643 
PolicyAuthValueSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)24644 TPM_RC Tpm::PolicyAuthValueSync(const TPMI_SH_POLICY& policy_session,
24645                                 const std::string& policy_session_name,
24646                                 AuthorizationDelegate* authorization_delegate) {
24647   VLOG(1) << __func__;
24648   std::string command;
24649   TPM_RC rc = SerializeCommand_PolicyAuthValue(
24650       policy_session, policy_session_name, &command, authorization_delegate);
24651   if (rc != TPM_RC_SUCCESS) {
24652     return rc;
24653   }
24654   std::string response = transceiver_->SendCommandAndWait(command);
24655   rc = ParseResponse_PolicyAuthValue(response, authorization_delegate);
24656   return rc;
24657 }
24658 
SerializeCommand_PolicyPassword(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24659 TPM_RC Tpm::SerializeCommand_PolicyPassword(
24660     const TPMI_SH_POLICY& policy_session,
24661     const std::string& policy_session_name,
24662     std::string* serialized_command,
24663     AuthorizationDelegate* authorization_delegate) {
24664   VLOG(3) << __func__;
24665   TPM_RC rc = TPM_RC_SUCCESS;
24666   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24667   UINT32 command_size = 10;  // Header size.
24668   std::string handle_section_bytes;
24669   std::string parameter_section_bytes;
24670   TPM_CC command_code = TPM_CC_PolicyPassword;
24671   bool is_command_parameter_encryption_possible = false;
24672   bool is_response_parameter_encryption_possible = false;
24673   std::string command_code_bytes;
24674   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24675   if (rc != TPM_RC_SUCCESS) {
24676     return rc;
24677   }
24678   std::string policy_session_bytes;
24679   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24680   if (rc != TPM_RC_SUCCESS) {
24681     return rc;
24682   }
24683   std::unique_ptr<crypto::SecureHash> hash(
24684       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24685   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24686   hash->Update(policy_session_name.data(), policy_session_name.size());
24687   handle_section_bytes += policy_session_bytes;
24688   command_size += policy_session_bytes.size();
24689   std::string command_hash(32, 0);
24690   hash->Finish(std::data(command_hash), command_hash.size());
24691   std::string authorization_section_bytes;
24692   std::string authorization_size_bytes;
24693   if (authorization_delegate) {
24694     if (!authorization_delegate->GetCommandAuthorization(
24695             command_hash, is_command_parameter_encryption_possible,
24696             is_response_parameter_encryption_possible,
24697             &authorization_section_bytes)) {
24698       return TRUNKS_RC_AUTHORIZATION_FAILED;
24699     }
24700     if (!authorization_section_bytes.empty()) {
24701       tag = TPM_ST_SESSIONS;
24702       std::string tmp;
24703       rc = Serialize_UINT32(authorization_section_bytes.size(),
24704                             &authorization_size_bytes);
24705       if (rc != TPM_RC_SUCCESS) {
24706         return rc;
24707       }
24708       command_size +=
24709           authorization_size_bytes.size() + authorization_section_bytes.size();
24710     }
24711   }
24712   std::string tag_bytes;
24713   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24714   if (rc != TPM_RC_SUCCESS) {
24715     return rc;
24716   }
24717   std::string command_size_bytes;
24718   rc = Serialize_UINT32(command_size, &command_size_bytes);
24719   if (rc != TPM_RC_SUCCESS) {
24720     return rc;
24721   }
24722   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24723                         handle_section_bytes + authorization_size_bytes +
24724                         authorization_section_bytes + parameter_section_bytes;
24725   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24726   VLOG(2) << "Command: "
24727           << base::HexEncode(serialized_command->data(),
24728                              serialized_command->size());
24729   return TPM_RC_SUCCESS;
24730 }
24731 
ParseResponse_PolicyPassword(const std::string & response,AuthorizationDelegate * authorization_delegate)24732 TPM_RC Tpm::ParseResponse_PolicyPassword(
24733     const std::string& response,
24734     AuthorizationDelegate* authorization_delegate) {
24735   VLOG(3) << __func__;
24736   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24737   TPM_RC rc = TPM_RC_SUCCESS;
24738   std::string buffer(response);
24739   TPM_ST tag;
24740   std::string tag_bytes;
24741   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24742   if (rc != TPM_RC_SUCCESS) {
24743     return rc;
24744   }
24745   UINT32 response_size;
24746   std::string response_size_bytes;
24747   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24748   if (rc != TPM_RC_SUCCESS) {
24749     return rc;
24750   }
24751   TPM_RC response_code;
24752   std::string response_code_bytes;
24753   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24754   if (rc != TPM_RC_SUCCESS) {
24755     return rc;
24756   }
24757   if (response_size != response.size()) {
24758     return TPM_RC_SIZE;
24759   }
24760   if (response_code != TPM_RC_SUCCESS) {
24761     return response_code;
24762   }
24763   TPM_CC command_code = TPM_CC_PolicyPassword;
24764   std::string command_code_bytes;
24765   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24766   if (rc != TPM_RC_SUCCESS) {
24767     return rc;
24768   }
24769   std::string authorization_section_bytes;
24770   if (tag == TPM_ST_SESSIONS) {
24771     UINT32 parameter_section_size = buffer.size();
24772     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24773     if (rc != TPM_RC_SUCCESS) {
24774       return rc;
24775     }
24776     if (parameter_section_size > buffer.size()) {
24777       return TPM_RC_INSUFFICIENT;
24778     }
24779     authorization_section_bytes = buffer.substr(parameter_section_size);
24780     // Keep the parameter section in |buffer|.
24781     buffer.erase(parameter_section_size);
24782   }
24783   std::unique_ptr<crypto::SecureHash> hash(
24784       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24785   hash->Update(response_code_bytes.data(), response_code_bytes.size());
24786   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24787   hash->Update(buffer.data(), buffer.size());
24788   std::string response_hash(32, 0);
24789   hash->Finish(std::data(response_hash), response_hash.size());
24790   if (tag == TPM_ST_SESSIONS) {
24791     if (!authorization_delegate)
24792       return TRUNKS_RC_AUTHORIZATION_FAILED;
24793     if (!authorization_delegate->CheckResponseAuthorization(
24794             response_hash, authorization_section_bytes)) {
24795       return TRUNKS_RC_AUTHORIZATION_FAILED;
24796     }
24797   }
24798   return TPM_RC_SUCCESS;
24799 }
24800 
PolicyPasswordErrorCallback(Tpm::PolicyPasswordResponse callback,TPM_RC response_code)24801 void PolicyPasswordErrorCallback(Tpm::PolicyPasswordResponse callback,
24802                                  TPM_RC response_code) {
24803   VLOG(1) << __func__;
24804   std::move(callback).Run(response_code);
24805 }
24806 
PolicyPasswordResponseParser(Tpm::PolicyPasswordResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24807 void PolicyPasswordResponseParser(Tpm::PolicyPasswordResponse callback,
24808                                   AuthorizationDelegate* authorization_delegate,
24809                                   const std::string& response) {
24810   VLOG(1) << __func__;
24811   TPM_RC rc =
24812       Tpm::ParseResponse_PolicyPassword(response, authorization_delegate);
24813   if (rc != TPM_RC_SUCCESS) {
24814     base::OnceCallback<void(TPM_RC)> error_reporter =
24815         base::BindOnce(PolicyPasswordErrorCallback, std::move(callback));
24816     std::move(error_reporter).Run(rc);
24817     return;
24818   }
24819   std::move(callback).Run(rc);
24820 }
24821 
PolicyPassword(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyPasswordResponse callback)24822 void Tpm::PolicyPassword(const TPMI_SH_POLICY& policy_session,
24823                          const std::string& policy_session_name,
24824                          AuthorizationDelegate* authorization_delegate,
24825                          PolicyPasswordResponse callback) {
24826   VLOG(1) << __func__;
24827   std::string command;
24828   TPM_RC rc = SerializeCommand_PolicyPassword(
24829       policy_session, policy_session_name, &command, authorization_delegate);
24830   if (rc != TPM_RC_SUCCESS) {
24831     base::OnceCallback<void(TPM_RC)> error_reporter =
24832         base::BindOnce(PolicyPasswordErrorCallback, std::move(callback));
24833     std::move(error_reporter).Run(rc);
24834     return;
24835   }
24836   base::OnceCallback<void(const std::string&)> parser =
24837       base::BindOnce(PolicyPasswordResponseParser, std::move(callback),
24838                      authorization_delegate);
24839   transceiver_->SendCommand(command, std::move(parser));
24840 }
24841 
PolicyPasswordSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)24842 TPM_RC Tpm::PolicyPasswordSync(const TPMI_SH_POLICY& policy_session,
24843                                const std::string& policy_session_name,
24844                                AuthorizationDelegate* authorization_delegate) {
24845   VLOG(1) << __func__;
24846   std::string command;
24847   TPM_RC rc = SerializeCommand_PolicyPassword(
24848       policy_session, policy_session_name, &command, authorization_delegate);
24849   if (rc != TPM_RC_SUCCESS) {
24850     return rc;
24851   }
24852   std::string response = transceiver_->SendCommandAndWait(command);
24853   rc = ParseResponse_PolicyPassword(response, authorization_delegate);
24854   return rc;
24855 }
24856 
SerializeCommand_PolicyGetDigest(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24857 TPM_RC Tpm::SerializeCommand_PolicyGetDigest(
24858     const TPMI_SH_POLICY& policy_session,
24859     const std::string& policy_session_name,
24860     std::string* serialized_command,
24861     AuthorizationDelegate* authorization_delegate) {
24862   VLOG(3) << __func__;
24863   TPM_RC rc = TPM_RC_SUCCESS;
24864   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24865   UINT32 command_size = 10;  // Header size.
24866   std::string handle_section_bytes;
24867   std::string parameter_section_bytes;
24868   TPM_CC command_code = TPM_CC_PolicyGetDigest;
24869   bool is_command_parameter_encryption_possible = false;
24870   bool is_response_parameter_encryption_possible = true;
24871   std::string command_code_bytes;
24872   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24873   if (rc != TPM_RC_SUCCESS) {
24874     return rc;
24875   }
24876   std::string policy_session_bytes;
24877   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24878   if (rc != TPM_RC_SUCCESS) {
24879     return rc;
24880   }
24881   std::unique_ptr<crypto::SecureHash> hash(
24882       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24883   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24884   hash->Update(policy_session_name.data(), policy_session_name.size());
24885   handle_section_bytes += policy_session_bytes;
24886   command_size += policy_session_bytes.size();
24887   std::string command_hash(32, 0);
24888   hash->Finish(std::data(command_hash), command_hash.size());
24889   std::string authorization_section_bytes;
24890   std::string authorization_size_bytes;
24891   if (authorization_delegate) {
24892     if (!authorization_delegate->GetCommandAuthorization(
24893             command_hash, is_command_parameter_encryption_possible,
24894             is_response_parameter_encryption_possible,
24895             &authorization_section_bytes)) {
24896       return TRUNKS_RC_AUTHORIZATION_FAILED;
24897     }
24898     if (!authorization_section_bytes.empty()) {
24899       tag = TPM_ST_SESSIONS;
24900       std::string tmp;
24901       rc = Serialize_UINT32(authorization_section_bytes.size(),
24902                             &authorization_size_bytes);
24903       if (rc != TPM_RC_SUCCESS) {
24904         return rc;
24905       }
24906       command_size +=
24907           authorization_size_bytes.size() + authorization_section_bytes.size();
24908     }
24909   }
24910   std::string tag_bytes;
24911   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24912   if (rc != TPM_RC_SUCCESS) {
24913     return rc;
24914   }
24915   std::string command_size_bytes;
24916   rc = Serialize_UINT32(command_size, &command_size_bytes);
24917   if (rc != TPM_RC_SUCCESS) {
24918     return rc;
24919   }
24920   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24921                         handle_section_bytes + authorization_size_bytes +
24922                         authorization_section_bytes + parameter_section_bytes;
24923   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24924   VLOG(2) << "Command: "
24925           << base::HexEncode(serialized_command->data(),
24926                              serialized_command->size());
24927   return TPM_RC_SUCCESS;
24928 }
24929 
ParseResponse_PolicyGetDigest(const std::string & response,TPM2B_DIGEST * policy_digest,AuthorizationDelegate * authorization_delegate)24930 TPM_RC Tpm::ParseResponse_PolicyGetDigest(
24931     const std::string& response,
24932     TPM2B_DIGEST* policy_digest,
24933     AuthorizationDelegate* authorization_delegate) {
24934   VLOG(3) << __func__;
24935   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24936   TPM_RC rc = TPM_RC_SUCCESS;
24937   std::string buffer(response);
24938   TPM_ST tag;
24939   std::string tag_bytes;
24940   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24941   if (rc != TPM_RC_SUCCESS) {
24942     return rc;
24943   }
24944   UINT32 response_size;
24945   std::string response_size_bytes;
24946   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24947   if (rc != TPM_RC_SUCCESS) {
24948     return rc;
24949   }
24950   TPM_RC response_code;
24951   std::string response_code_bytes;
24952   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24953   if (rc != TPM_RC_SUCCESS) {
24954     return rc;
24955   }
24956   if (response_size != response.size()) {
24957     return TPM_RC_SIZE;
24958   }
24959   if (response_code != TPM_RC_SUCCESS) {
24960     return response_code;
24961   }
24962   TPM_CC command_code = TPM_CC_PolicyGetDigest;
24963   std::string command_code_bytes;
24964   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24965   if (rc != TPM_RC_SUCCESS) {
24966     return rc;
24967   }
24968   std::string authorization_section_bytes;
24969   if (tag == TPM_ST_SESSIONS) {
24970     UINT32 parameter_section_size = buffer.size();
24971     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24972     if (rc != TPM_RC_SUCCESS) {
24973       return rc;
24974     }
24975     if (parameter_section_size > buffer.size()) {
24976       return TPM_RC_INSUFFICIENT;
24977     }
24978     authorization_section_bytes = buffer.substr(parameter_section_size);
24979     // Keep the parameter section in |buffer|.
24980     buffer.erase(parameter_section_size);
24981   }
24982   std::unique_ptr<crypto::SecureHash> hash(
24983       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24984   hash->Update(response_code_bytes.data(), response_code_bytes.size());
24985   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24986   hash->Update(buffer.data(), buffer.size());
24987   std::string response_hash(32, 0);
24988   hash->Finish(std::data(response_hash), response_hash.size());
24989   if (tag == TPM_ST_SESSIONS) {
24990     if (!authorization_delegate)
24991       return TRUNKS_RC_AUTHORIZATION_FAILED;
24992     if (!authorization_delegate->CheckResponseAuthorization(
24993             response_hash, authorization_section_bytes)) {
24994       return TRUNKS_RC_AUTHORIZATION_FAILED;
24995     }
24996   }
24997   if (tag == TPM_ST_SESSIONS) {
24998     if (!authorization_delegate)
24999       return TRUNKS_RC_AUTHORIZATION_FAILED;
25000 
25001     // Parse the encrypted parameter size.
25002     UINT16 size;
25003     std::string size_buffer = buffer.substr(0, 2);
25004     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
25005       return result;
25006     }
25007     if (buffer.size() < 2 + size) {
25008       return TPM_RC_INSUFFICIENT;
25009     }
25010 
25011     // Decrypt just the parameter data, not the size.
25012     std::string decrypted_data = buffer.substr(2, size);
25013     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
25014       return TRUNKS_RC_ENCRYPTION_FAILED;
25015     }
25016     buffer.replace(2, size, decrypted_data);
25017   }
25018   std::string policy_digest_bytes;
25019   rc = Parse_TPM2B_DIGEST(&buffer, policy_digest, &policy_digest_bytes);
25020   if (rc != TPM_RC_SUCCESS) {
25021     return rc;
25022   }
25023   return TPM_RC_SUCCESS;
25024 }
25025 
PolicyGetDigestErrorCallback(Tpm::PolicyGetDigestResponse callback,TPM_RC response_code)25026 void PolicyGetDigestErrorCallback(Tpm::PolicyGetDigestResponse callback,
25027                                   TPM_RC response_code) {
25028   VLOG(1) << __func__;
25029   std::move(callback).Run(response_code, TPM2B_DIGEST());
25030 }
25031 
PolicyGetDigestResponseParser(Tpm::PolicyGetDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25032 void PolicyGetDigestResponseParser(
25033     Tpm::PolicyGetDigestResponse callback,
25034     AuthorizationDelegate* authorization_delegate,
25035     const std::string& response) {
25036   VLOG(1) << __func__;
25037   TPM2B_DIGEST policy_digest;
25038   TPM_RC rc = Tpm::ParseResponse_PolicyGetDigest(response, &policy_digest,
25039                                                  authorization_delegate);
25040   if (rc != TPM_RC_SUCCESS) {
25041     base::OnceCallback<void(TPM_RC)> error_reporter =
25042         base::BindOnce(PolicyGetDigestErrorCallback, std::move(callback));
25043     std::move(error_reporter).Run(rc);
25044     return;
25045   }
25046   std::move(callback).Run(rc, policy_digest);
25047 }
25048 
PolicyGetDigest(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyGetDigestResponse callback)25049 void Tpm::PolicyGetDigest(const TPMI_SH_POLICY& policy_session,
25050                           const std::string& policy_session_name,
25051                           AuthorizationDelegate* authorization_delegate,
25052                           PolicyGetDigestResponse callback) {
25053   VLOG(1) << __func__;
25054   std::string command;
25055   TPM_RC rc = SerializeCommand_PolicyGetDigest(
25056       policy_session, policy_session_name, &command, authorization_delegate);
25057   if (rc != TPM_RC_SUCCESS) {
25058     base::OnceCallback<void(TPM_RC)> error_reporter =
25059         base::BindOnce(PolicyGetDigestErrorCallback, std::move(callback));
25060     std::move(error_reporter).Run(rc);
25061     return;
25062   }
25063   base::OnceCallback<void(const std::string&)> parser =
25064       base::BindOnce(PolicyGetDigestResponseParser, std::move(callback),
25065                      authorization_delegate);
25066   transceiver_->SendCommand(command, std::move(parser));
25067 }
25068 
PolicyGetDigestSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,TPM2B_DIGEST * policy_digest,AuthorizationDelegate * authorization_delegate)25069 TPM_RC Tpm::PolicyGetDigestSync(const TPMI_SH_POLICY& policy_session,
25070                                 const std::string& policy_session_name,
25071                                 TPM2B_DIGEST* policy_digest,
25072                                 AuthorizationDelegate* authorization_delegate) {
25073   VLOG(1) << __func__;
25074   std::string command;
25075   TPM_RC rc = SerializeCommand_PolicyGetDigest(
25076       policy_session, policy_session_name, &command, authorization_delegate);
25077   if (rc != TPM_RC_SUCCESS) {
25078     return rc;
25079   }
25080   std::string response = transceiver_->SendCommandAndWait(command);
25081   rc = ParseResponse_PolicyGetDigest(response, policy_digest,
25082                                      authorization_delegate);
25083   return rc;
25084 }
25085 
SerializeCommand_PolicyNvWritten(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25086 TPM_RC Tpm::SerializeCommand_PolicyNvWritten(
25087     const TPMI_SH_POLICY& policy_session,
25088     const std::string& policy_session_name,
25089     const TPMI_YES_NO& written_set,
25090     std::string* serialized_command,
25091     AuthorizationDelegate* authorization_delegate) {
25092   VLOG(3) << __func__;
25093   TPM_RC rc = TPM_RC_SUCCESS;
25094   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25095   UINT32 command_size = 10;  // Header size.
25096   std::string handle_section_bytes;
25097   std::string parameter_section_bytes;
25098   TPM_CC command_code = TPM_CC_PolicyNvWritten;
25099   bool is_command_parameter_encryption_possible = false;
25100   bool is_response_parameter_encryption_possible = false;
25101   std::string command_code_bytes;
25102   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25103   if (rc != TPM_RC_SUCCESS) {
25104     return rc;
25105   }
25106   std::string policy_session_bytes;
25107   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
25108   if (rc != TPM_RC_SUCCESS) {
25109     return rc;
25110   }
25111   std::string written_set_bytes;
25112   rc = Serialize_TPMI_YES_NO(written_set, &written_set_bytes);
25113   if (rc != TPM_RC_SUCCESS) {
25114     return rc;
25115   }
25116   std::unique_ptr<crypto::SecureHash> hash(
25117       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25118   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25119   hash->Update(policy_session_name.data(), policy_session_name.size());
25120   handle_section_bytes += policy_session_bytes;
25121   command_size += policy_session_bytes.size();
25122   hash->Update(written_set_bytes.data(), written_set_bytes.size());
25123   parameter_section_bytes += written_set_bytes;
25124   command_size += written_set_bytes.size();
25125   std::string command_hash(32, 0);
25126   hash->Finish(std::data(command_hash), command_hash.size());
25127   std::string authorization_section_bytes;
25128   std::string authorization_size_bytes;
25129   if (authorization_delegate) {
25130     if (!authorization_delegate->GetCommandAuthorization(
25131             command_hash, is_command_parameter_encryption_possible,
25132             is_response_parameter_encryption_possible,
25133             &authorization_section_bytes)) {
25134       return TRUNKS_RC_AUTHORIZATION_FAILED;
25135     }
25136     if (!authorization_section_bytes.empty()) {
25137       tag = TPM_ST_SESSIONS;
25138       std::string tmp;
25139       rc = Serialize_UINT32(authorization_section_bytes.size(),
25140                             &authorization_size_bytes);
25141       if (rc != TPM_RC_SUCCESS) {
25142         return rc;
25143       }
25144       command_size +=
25145           authorization_size_bytes.size() + authorization_section_bytes.size();
25146     }
25147   }
25148   std::string tag_bytes;
25149   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25150   if (rc != TPM_RC_SUCCESS) {
25151     return rc;
25152   }
25153   std::string command_size_bytes;
25154   rc = Serialize_UINT32(command_size, &command_size_bytes);
25155   if (rc != TPM_RC_SUCCESS) {
25156     return rc;
25157   }
25158   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25159                         handle_section_bytes + authorization_size_bytes +
25160                         authorization_section_bytes + parameter_section_bytes;
25161   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25162   VLOG(2) << "Command: "
25163           << base::HexEncode(serialized_command->data(),
25164                              serialized_command->size());
25165   return TPM_RC_SUCCESS;
25166 }
25167 
ParseResponse_PolicyNvWritten(const std::string & response,AuthorizationDelegate * authorization_delegate)25168 TPM_RC Tpm::ParseResponse_PolicyNvWritten(
25169     const std::string& response,
25170     AuthorizationDelegate* authorization_delegate) {
25171   VLOG(3) << __func__;
25172   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25173   TPM_RC rc = TPM_RC_SUCCESS;
25174   std::string buffer(response);
25175   TPM_ST tag;
25176   std::string tag_bytes;
25177   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25178   if (rc != TPM_RC_SUCCESS) {
25179     return rc;
25180   }
25181   UINT32 response_size;
25182   std::string response_size_bytes;
25183   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25184   if (rc != TPM_RC_SUCCESS) {
25185     return rc;
25186   }
25187   TPM_RC response_code;
25188   std::string response_code_bytes;
25189   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25190   if (rc != TPM_RC_SUCCESS) {
25191     return rc;
25192   }
25193   if (response_size != response.size()) {
25194     return TPM_RC_SIZE;
25195   }
25196   if (response_code != TPM_RC_SUCCESS) {
25197     return response_code;
25198   }
25199   TPM_CC command_code = TPM_CC_PolicyNvWritten;
25200   std::string command_code_bytes;
25201   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25202   if (rc != TPM_RC_SUCCESS) {
25203     return rc;
25204   }
25205   std::string authorization_section_bytes;
25206   if (tag == TPM_ST_SESSIONS) {
25207     UINT32 parameter_section_size = buffer.size();
25208     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25209     if (rc != TPM_RC_SUCCESS) {
25210       return rc;
25211     }
25212     if (parameter_section_size > buffer.size()) {
25213       return TPM_RC_INSUFFICIENT;
25214     }
25215     authorization_section_bytes = buffer.substr(parameter_section_size);
25216     // Keep the parameter section in |buffer|.
25217     buffer.erase(parameter_section_size);
25218   }
25219   std::unique_ptr<crypto::SecureHash> hash(
25220       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25221   hash->Update(response_code_bytes.data(), response_code_bytes.size());
25222   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25223   hash->Update(buffer.data(), buffer.size());
25224   std::string response_hash(32, 0);
25225   hash->Finish(std::data(response_hash), response_hash.size());
25226   if (tag == TPM_ST_SESSIONS) {
25227     if (!authorization_delegate)
25228       return TRUNKS_RC_AUTHORIZATION_FAILED;
25229     if (!authorization_delegate->CheckResponseAuthorization(
25230             response_hash, authorization_section_bytes)) {
25231       return TRUNKS_RC_AUTHORIZATION_FAILED;
25232     }
25233   }
25234   return TPM_RC_SUCCESS;
25235 }
25236 
PolicyNvWrittenErrorCallback(Tpm::PolicyNvWrittenResponse callback,TPM_RC response_code)25237 void PolicyNvWrittenErrorCallback(Tpm::PolicyNvWrittenResponse callback,
25238                                   TPM_RC response_code) {
25239   VLOG(1) << __func__;
25240   std::move(callback).Run(response_code);
25241 }
25242 
PolicyNvWrittenResponseParser(Tpm::PolicyNvWrittenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25243 void PolicyNvWrittenResponseParser(
25244     Tpm::PolicyNvWrittenResponse callback,
25245     AuthorizationDelegate* authorization_delegate,
25246     const std::string& response) {
25247   VLOG(1) << __func__;
25248   TPM_RC rc =
25249       Tpm::ParseResponse_PolicyNvWritten(response, authorization_delegate);
25250   if (rc != TPM_RC_SUCCESS) {
25251     base::OnceCallback<void(TPM_RC)> error_reporter =
25252         base::BindOnce(PolicyNvWrittenErrorCallback, std::move(callback));
25253     std::move(error_reporter).Run(rc);
25254     return;
25255   }
25256   std::move(callback).Run(rc);
25257 }
25258 
PolicyNvWritten(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,AuthorizationDelegate * authorization_delegate,PolicyNvWrittenResponse callback)25259 void Tpm::PolicyNvWritten(const TPMI_SH_POLICY& policy_session,
25260                           const std::string& policy_session_name,
25261                           const TPMI_YES_NO& written_set,
25262                           AuthorizationDelegate* authorization_delegate,
25263                           PolicyNvWrittenResponse callback) {
25264   VLOG(1) << __func__;
25265   std::string command;
25266   TPM_RC rc = SerializeCommand_PolicyNvWritten(
25267       policy_session, policy_session_name, written_set, &command,
25268       authorization_delegate);
25269   if (rc != TPM_RC_SUCCESS) {
25270     base::OnceCallback<void(TPM_RC)> error_reporter =
25271         base::BindOnce(PolicyNvWrittenErrorCallback, std::move(callback));
25272     std::move(error_reporter).Run(rc);
25273     return;
25274   }
25275   base::OnceCallback<void(const std::string&)> parser =
25276       base::BindOnce(PolicyNvWrittenResponseParser, std::move(callback),
25277                      authorization_delegate);
25278   transceiver_->SendCommand(command, std::move(parser));
25279 }
25280 
PolicyNvWrittenSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,AuthorizationDelegate * authorization_delegate)25281 TPM_RC Tpm::PolicyNvWrittenSync(const TPMI_SH_POLICY& policy_session,
25282                                 const std::string& policy_session_name,
25283                                 const TPMI_YES_NO& written_set,
25284                                 AuthorizationDelegate* authorization_delegate) {
25285   VLOG(1) << __func__;
25286   std::string command;
25287   TPM_RC rc = SerializeCommand_PolicyNvWritten(
25288       policy_session, policy_session_name, written_set, &command,
25289       authorization_delegate);
25290   if (rc != TPM_RC_SUCCESS) {
25291     return rc;
25292   }
25293   std::string response = transceiver_->SendCommandAndWait(command);
25294   rc = ParseResponse_PolicyNvWritten(response, authorization_delegate);
25295   return rc;
25296 }
25297 
SerializeCommand_CreatePrimary(const TPMI_RH_HIERARCHY & primary_handle,const std::string & primary_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25298 TPM_RC Tpm::SerializeCommand_CreatePrimary(
25299     const TPMI_RH_HIERARCHY& primary_handle,
25300     const std::string& primary_handle_name,
25301     const TPM2B_SENSITIVE_CREATE& in_sensitive,
25302     const TPM2B_PUBLIC& in_public,
25303     const TPM2B_DATA& outside_info,
25304     const TPML_PCR_SELECTION& creation_pcr,
25305     std::string* serialized_command,
25306     AuthorizationDelegate* authorization_delegate) {
25307   VLOG(3) << __func__;
25308   TPM_RC rc = TPM_RC_SUCCESS;
25309   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25310   UINT32 command_size = 10;  // Header size.
25311   std::string handle_section_bytes;
25312   std::string parameter_section_bytes;
25313   TPM_CC command_code = TPM_CC_CreatePrimary;
25314   bool is_command_parameter_encryption_possible = true;
25315   bool is_response_parameter_encryption_possible = true;
25316   std::string command_code_bytes;
25317   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25318   if (rc != TPM_RC_SUCCESS) {
25319     return rc;
25320   }
25321   std::string primary_handle_bytes;
25322   rc = Serialize_TPMI_RH_HIERARCHY(primary_handle, &primary_handle_bytes);
25323   if (rc != TPM_RC_SUCCESS) {
25324     return rc;
25325   }
25326   std::string in_sensitive_bytes;
25327   rc = Serialize_TPM2B_SENSITIVE_CREATE(in_sensitive, &in_sensitive_bytes);
25328   if (rc != TPM_RC_SUCCESS) {
25329     return rc;
25330   }
25331   std::string in_public_bytes;
25332   rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
25333   if (rc != TPM_RC_SUCCESS) {
25334     return rc;
25335   }
25336   std::string outside_info_bytes;
25337   rc = Serialize_TPM2B_DATA(outside_info, &outside_info_bytes);
25338   if (rc != TPM_RC_SUCCESS) {
25339     return rc;
25340   }
25341   std::string creation_pcr_bytes;
25342   rc = Serialize_TPML_PCR_SELECTION(creation_pcr, &creation_pcr_bytes);
25343   if (rc != TPM_RC_SUCCESS) {
25344     return rc;
25345   }
25346   if (authorization_delegate) {
25347     // Encrypt just the parameter data, not the size.
25348     std::string tmp = in_sensitive_bytes.substr(2);
25349     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
25350       return TRUNKS_RC_ENCRYPTION_FAILED;
25351     }
25352     in_sensitive_bytes.replace(2, std::string::npos, tmp);
25353   }
25354   std::unique_ptr<crypto::SecureHash> hash(
25355       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25356   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25357   hash->Update(primary_handle_name.data(), primary_handle_name.size());
25358   handle_section_bytes += primary_handle_bytes;
25359   command_size += primary_handle_bytes.size();
25360   hash->Update(in_sensitive_bytes.data(), in_sensitive_bytes.size());
25361   parameter_section_bytes += in_sensitive_bytes;
25362   command_size += in_sensitive_bytes.size();
25363   hash->Update(in_public_bytes.data(), in_public_bytes.size());
25364   parameter_section_bytes += in_public_bytes;
25365   command_size += in_public_bytes.size();
25366   hash->Update(outside_info_bytes.data(), outside_info_bytes.size());
25367   parameter_section_bytes += outside_info_bytes;
25368   command_size += outside_info_bytes.size();
25369   hash->Update(creation_pcr_bytes.data(), creation_pcr_bytes.size());
25370   parameter_section_bytes += creation_pcr_bytes;
25371   command_size += creation_pcr_bytes.size();
25372   std::string command_hash(32, 0);
25373   hash->Finish(std::data(command_hash), command_hash.size());
25374   std::string authorization_section_bytes;
25375   std::string authorization_size_bytes;
25376   if (authorization_delegate) {
25377     if (!authorization_delegate->GetCommandAuthorization(
25378             command_hash, is_command_parameter_encryption_possible,
25379             is_response_parameter_encryption_possible,
25380             &authorization_section_bytes)) {
25381       return TRUNKS_RC_AUTHORIZATION_FAILED;
25382     }
25383     if (!authorization_section_bytes.empty()) {
25384       tag = TPM_ST_SESSIONS;
25385       std::string tmp;
25386       rc = Serialize_UINT32(authorization_section_bytes.size(),
25387                             &authorization_size_bytes);
25388       if (rc != TPM_RC_SUCCESS) {
25389         return rc;
25390       }
25391       command_size +=
25392           authorization_size_bytes.size() + authorization_section_bytes.size();
25393     }
25394   }
25395   std::string tag_bytes;
25396   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25397   if (rc != TPM_RC_SUCCESS) {
25398     return rc;
25399   }
25400   std::string command_size_bytes;
25401   rc = Serialize_UINT32(command_size, &command_size_bytes);
25402   if (rc != TPM_RC_SUCCESS) {
25403     return rc;
25404   }
25405   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25406                         handle_section_bytes + authorization_size_bytes +
25407                         authorization_section_bytes + parameter_section_bytes;
25408   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25409   VLOG(2) << "Command: "
25410           << base::HexEncode(serialized_command->data(),
25411                              serialized_command->size());
25412   return TPM_RC_SUCCESS;
25413 }
25414 
ParseResponse_CreatePrimary(const std::string & response,TPM_HANDLE * object_handle,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)25415 TPM_RC Tpm::ParseResponse_CreatePrimary(
25416     const std::string& response,
25417     TPM_HANDLE* object_handle,
25418     TPM2B_PUBLIC* out_public,
25419     TPM2B_CREATION_DATA* creation_data,
25420     TPM2B_DIGEST* creation_hash,
25421     TPMT_TK_CREATION* creation_ticket,
25422     TPM2B_NAME* name,
25423     AuthorizationDelegate* authorization_delegate) {
25424   VLOG(3) << __func__;
25425   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25426   TPM_RC rc = TPM_RC_SUCCESS;
25427   std::string buffer(response);
25428   TPM_ST tag;
25429   std::string tag_bytes;
25430   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25431   if (rc != TPM_RC_SUCCESS) {
25432     return rc;
25433   }
25434   UINT32 response_size;
25435   std::string response_size_bytes;
25436   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25437   if (rc != TPM_RC_SUCCESS) {
25438     return rc;
25439   }
25440   TPM_RC response_code;
25441   std::string response_code_bytes;
25442   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25443   if (rc != TPM_RC_SUCCESS) {
25444     return rc;
25445   }
25446   if (response_size != response.size()) {
25447     return TPM_RC_SIZE;
25448   }
25449   if (response_code != TPM_RC_SUCCESS) {
25450     return response_code;
25451   }
25452   std::string object_handle_bytes;
25453   rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
25454   if (rc != TPM_RC_SUCCESS) {
25455     return rc;
25456   }
25457   TPM_CC command_code = TPM_CC_CreatePrimary;
25458   std::string command_code_bytes;
25459   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25460   if (rc != TPM_RC_SUCCESS) {
25461     return rc;
25462   }
25463   std::string authorization_section_bytes;
25464   if (tag == TPM_ST_SESSIONS) {
25465     UINT32 parameter_section_size = buffer.size();
25466     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25467     if (rc != TPM_RC_SUCCESS) {
25468       return rc;
25469     }
25470     if (parameter_section_size > buffer.size()) {
25471       return TPM_RC_INSUFFICIENT;
25472     }
25473     authorization_section_bytes = buffer.substr(parameter_section_size);
25474     // Keep the parameter section in |buffer|.
25475     buffer.erase(parameter_section_size);
25476   }
25477   std::unique_ptr<crypto::SecureHash> hash(
25478       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25479   hash->Update(response_code_bytes.data(), response_code_bytes.size());
25480   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25481   hash->Update(buffer.data(), buffer.size());
25482   std::string response_hash(32, 0);
25483   hash->Finish(std::data(response_hash), response_hash.size());
25484   if (tag == TPM_ST_SESSIONS) {
25485     if (!authorization_delegate)
25486       return TRUNKS_RC_AUTHORIZATION_FAILED;
25487     if (!authorization_delegate->CheckResponseAuthorization(
25488             response_hash, authorization_section_bytes)) {
25489       return TRUNKS_RC_AUTHORIZATION_FAILED;
25490     }
25491   }
25492   if (tag == TPM_ST_SESSIONS) {
25493     if (!authorization_delegate)
25494       return TRUNKS_RC_AUTHORIZATION_FAILED;
25495 
25496     // Parse the encrypted parameter size.
25497     UINT16 size;
25498     std::string size_buffer = buffer.substr(0, 2);
25499     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
25500       return result;
25501     }
25502     if (buffer.size() < 2 + size) {
25503       return TPM_RC_INSUFFICIENT;
25504     }
25505 
25506     // Decrypt just the parameter data, not the size.
25507     std::string decrypted_data = buffer.substr(2, size);
25508     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
25509       return TRUNKS_RC_ENCRYPTION_FAILED;
25510     }
25511     buffer.replace(2, size, decrypted_data);
25512   }
25513   std::string out_public_bytes;
25514   rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
25515   if (rc != TPM_RC_SUCCESS) {
25516     return rc;
25517   }
25518   std::string creation_data_bytes;
25519   rc = Parse_TPM2B_CREATION_DATA(&buffer, creation_data, &creation_data_bytes);
25520   if (rc != TPM_RC_SUCCESS) {
25521     return rc;
25522   }
25523   std::string creation_hash_bytes;
25524   rc = Parse_TPM2B_DIGEST(&buffer, creation_hash, &creation_hash_bytes);
25525   if (rc != TPM_RC_SUCCESS) {
25526     return rc;
25527   }
25528   std::string creation_ticket_bytes;
25529   rc = Parse_TPMT_TK_CREATION(&buffer, creation_ticket, &creation_ticket_bytes);
25530   if (rc != TPM_RC_SUCCESS) {
25531     return rc;
25532   }
25533   std::string name_bytes;
25534   rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
25535   if (rc != TPM_RC_SUCCESS) {
25536     return rc;
25537   }
25538   return TPM_RC_SUCCESS;
25539 }
25540 
CreatePrimaryErrorCallback(Tpm::CreatePrimaryResponse callback,TPM_RC response_code)25541 void CreatePrimaryErrorCallback(Tpm::CreatePrimaryResponse callback,
25542                                 TPM_RC response_code) {
25543   VLOG(1) << __func__;
25544   std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_PUBLIC(),
25545                           TPM2B_CREATION_DATA(), TPM2B_DIGEST(),
25546                           TPMT_TK_CREATION(), TPM2B_NAME());
25547 }
25548 
CreatePrimaryResponseParser(Tpm::CreatePrimaryResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25549 void CreatePrimaryResponseParser(Tpm::CreatePrimaryResponse callback,
25550                                  AuthorizationDelegate* authorization_delegate,
25551                                  const std::string& response) {
25552   VLOG(1) << __func__;
25553   TPM_HANDLE object_handle;
25554   TPM2B_PUBLIC out_public;
25555   TPM2B_CREATION_DATA creation_data;
25556   TPM2B_DIGEST creation_hash;
25557   TPMT_TK_CREATION creation_ticket;
25558   TPM2B_NAME name;
25559   TPM_RC rc = Tpm::ParseResponse_CreatePrimary(
25560       response, &object_handle, &out_public, &creation_data, &creation_hash,
25561       &creation_ticket, &name, authorization_delegate);
25562   if (rc != TPM_RC_SUCCESS) {
25563     base::OnceCallback<void(TPM_RC)> error_reporter =
25564         base::BindOnce(CreatePrimaryErrorCallback, std::move(callback));
25565     std::move(error_reporter).Run(rc);
25566     return;
25567   }
25568   std::move(callback).Run(rc, object_handle, out_public, creation_data,
25569                           creation_hash, creation_ticket, name);
25570 }
25571 
CreatePrimary(const TPMI_RH_HIERARCHY & primary_handle,const std::string & primary_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,AuthorizationDelegate * authorization_delegate,CreatePrimaryResponse callback)25572 void Tpm::CreatePrimary(const TPMI_RH_HIERARCHY& primary_handle,
25573                         const std::string& primary_handle_name,
25574                         const TPM2B_SENSITIVE_CREATE& in_sensitive,
25575                         const TPM2B_PUBLIC& in_public,
25576                         const TPM2B_DATA& outside_info,
25577                         const TPML_PCR_SELECTION& creation_pcr,
25578                         AuthorizationDelegate* authorization_delegate,
25579                         CreatePrimaryResponse callback) {
25580   VLOG(1) << __func__;
25581   std::string command;
25582   TPM_RC rc = SerializeCommand_CreatePrimary(
25583       primary_handle, primary_handle_name, in_sensitive, in_public,
25584       outside_info, creation_pcr, &command, authorization_delegate);
25585   if (rc != TPM_RC_SUCCESS) {
25586     base::OnceCallback<void(TPM_RC)> error_reporter =
25587         base::BindOnce(CreatePrimaryErrorCallback, std::move(callback));
25588     std::move(error_reporter).Run(rc);
25589     return;
25590   }
25591   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
25592       CreatePrimaryResponseParser, std::move(callback), authorization_delegate);
25593   transceiver_->SendCommand(command, std::move(parser));
25594 }
25595 
CreatePrimarySync(const TPMI_RH_HIERARCHY & primary_handle,const std::string & primary_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,TPM_HANDLE * object_handle,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)25596 TPM_RC Tpm::CreatePrimarySync(const TPMI_RH_HIERARCHY& primary_handle,
25597                               const std::string& primary_handle_name,
25598                               const TPM2B_SENSITIVE_CREATE& in_sensitive,
25599                               const TPM2B_PUBLIC& in_public,
25600                               const TPM2B_DATA& outside_info,
25601                               const TPML_PCR_SELECTION& creation_pcr,
25602                               TPM_HANDLE* object_handle,
25603                               TPM2B_PUBLIC* out_public,
25604                               TPM2B_CREATION_DATA* creation_data,
25605                               TPM2B_DIGEST* creation_hash,
25606                               TPMT_TK_CREATION* creation_ticket,
25607                               TPM2B_NAME* name,
25608                               AuthorizationDelegate* authorization_delegate) {
25609   VLOG(1) << __func__;
25610   std::string command;
25611   TPM_RC rc = SerializeCommand_CreatePrimary(
25612       primary_handle, primary_handle_name, in_sensitive, in_public,
25613       outside_info, creation_pcr, &command, authorization_delegate);
25614   if (rc != TPM_RC_SUCCESS) {
25615     return rc;
25616   }
25617   std::string response = transceiver_->SendCommandAndWait(command);
25618   rc = ParseResponse_CreatePrimary(
25619       response, object_handle, out_public, creation_data, creation_hash,
25620       creation_ticket, name, authorization_delegate);
25621   return rc;
25622 }
25623 
SerializeCommand_HierarchyControl(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPMI_RH_ENABLES & enable,const TPMI_YES_NO & state,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25624 TPM_RC Tpm::SerializeCommand_HierarchyControl(
25625     const TPMI_RH_HIERARCHY& auth_handle,
25626     const std::string& auth_handle_name,
25627     const TPMI_RH_ENABLES& enable,
25628     const TPMI_YES_NO& state,
25629     std::string* serialized_command,
25630     AuthorizationDelegate* authorization_delegate) {
25631   VLOG(3) << __func__;
25632   TPM_RC rc = TPM_RC_SUCCESS;
25633   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25634   UINT32 command_size = 10;  // Header size.
25635   std::string handle_section_bytes;
25636   std::string parameter_section_bytes;
25637   TPM_CC command_code = TPM_CC_HierarchyControl;
25638   bool is_command_parameter_encryption_possible = false;
25639   bool is_response_parameter_encryption_possible = false;
25640   std::string command_code_bytes;
25641   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25642   if (rc != TPM_RC_SUCCESS) {
25643     return rc;
25644   }
25645   std::string auth_handle_bytes;
25646   rc = Serialize_TPMI_RH_HIERARCHY(auth_handle, &auth_handle_bytes);
25647   if (rc != TPM_RC_SUCCESS) {
25648     return rc;
25649   }
25650   std::string enable_bytes;
25651   rc = Serialize_TPMI_RH_ENABLES(enable, &enable_bytes);
25652   if (rc != TPM_RC_SUCCESS) {
25653     return rc;
25654   }
25655   std::string state_bytes;
25656   rc = Serialize_TPMI_YES_NO(state, &state_bytes);
25657   if (rc != TPM_RC_SUCCESS) {
25658     return rc;
25659   }
25660   std::unique_ptr<crypto::SecureHash> hash(
25661       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25662   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25663   hash->Update(auth_handle_name.data(), auth_handle_name.size());
25664   handle_section_bytes += auth_handle_bytes;
25665   command_size += auth_handle_bytes.size();
25666   hash->Update(enable_bytes.data(), enable_bytes.size());
25667   parameter_section_bytes += enable_bytes;
25668   command_size += enable_bytes.size();
25669   hash->Update(state_bytes.data(), state_bytes.size());
25670   parameter_section_bytes += state_bytes;
25671   command_size += state_bytes.size();
25672   std::string command_hash(32, 0);
25673   hash->Finish(std::data(command_hash), command_hash.size());
25674   std::string authorization_section_bytes;
25675   std::string authorization_size_bytes;
25676   if (authorization_delegate) {
25677     if (!authorization_delegate->GetCommandAuthorization(
25678             command_hash, is_command_parameter_encryption_possible,
25679             is_response_parameter_encryption_possible,
25680             &authorization_section_bytes)) {
25681       return TRUNKS_RC_AUTHORIZATION_FAILED;
25682     }
25683     if (!authorization_section_bytes.empty()) {
25684       tag = TPM_ST_SESSIONS;
25685       std::string tmp;
25686       rc = Serialize_UINT32(authorization_section_bytes.size(),
25687                             &authorization_size_bytes);
25688       if (rc != TPM_RC_SUCCESS) {
25689         return rc;
25690       }
25691       command_size +=
25692           authorization_size_bytes.size() + authorization_section_bytes.size();
25693     }
25694   }
25695   std::string tag_bytes;
25696   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25697   if (rc != TPM_RC_SUCCESS) {
25698     return rc;
25699   }
25700   std::string command_size_bytes;
25701   rc = Serialize_UINT32(command_size, &command_size_bytes);
25702   if (rc != TPM_RC_SUCCESS) {
25703     return rc;
25704   }
25705   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25706                         handle_section_bytes + authorization_size_bytes +
25707                         authorization_section_bytes + parameter_section_bytes;
25708   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25709   VLOG(2) << "Command: "
25710           << base::HexEncode(serialized_command->data(),
25711                              serialized_command->size());
25712   return TPM_RC_SUCCESS;
25713 }
25714 
ParseResponse_HierarchyControl(const std::string & response,AuthorizationDelegate * authorization_delegate)25715 TPM_RC Tpm::ParseResponse_HierarchyControl(
25716     const std::string& response,
25717     AuthorizationDelegate* authorization_delegate) {
25718   VLOG(3) << __func__;
25719   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25720   TPM_RC rc = TPM_RC_SUCCESS;
25721   std::string buffer(response);
25722   TPM_ST tag;
25723   std::string tag_bytes;
25724   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25725   if (rc != TPM_RC_SUCCESS) {
25726     return rc;
25727   }
25728   UINT32 response_size;
25729   std::string response_size_bytes;
25730   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25731   if (rc != TPM_RC_SUCCESS) {
25732     return rc;
25733   }
25734   TPM_RC response_code;
25735   std::string response_code_bytes;
25736   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25737   if (rc != TPM_RC_SUCCESS) {
25738     return rc;
25739   }
25740   if (response_size != response.size()) {
25741     return TPM_RC_SIZE;
25742   }
25743   if (response_code != TPM_RC_SUCCESS) {
25744     return response_code;
25745   }
25746   TPM_CC command_code = TPM_CC_HierarchyControl;
25747   std::string command_code_bytes;
25748   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25749   if (rc != TPM_RC_SUCCESS) {
25750     return rc;
25751   }
25752   std::string authorization_section_bytes;
25753   if (tag == TPM_ST_SESSIONS) {
25754     UINT32 parameter_section_size = buffer.size();
25755     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25756     if (rc != TPM_RC_SUCCESS) {
25757       return rc;
25758     }
25759     if (parameter_section_size > buffer.size()) {
25760       return TPM_RC_INSUFFICIENT;
25761     }
25762     authorization_section_bytes = buffer.substr(parameter_section_size);
25763     // Keep the parameter section in |buffer|.
25764     buffer.erase(parameter_section_size);
25765   }
25766   std::unique_ptr<crypto::SecureHash> hash(
25767       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25768   hash->Update(response_code_bytes.data(), response_code_bytes.size());
25769   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25770   hash->Update(buffer.data(), buffer.size());
25771   std::string response_hash(32, 0);
25772   hash->Finish(std::data(response_hash), response_hash.size());
25773   if (tag == TPM_ST_SESSIONS) {
25774     if (!authorization_delegate)
25775       return TRUNKS_RC_AUTHORIZATION_FAILED;
25776     if (!authorization_delegate->CheckResponseAuthorization(
25777             response_hash, authorization_section_bytes)) {
25778       return TRUNKS_RC_AUTHORIZATION_FAILED;
25779     }
25780   }
25781   return TPM_RC_SUCCESS;
25782 }
25783 
HierarchyControlErrorCallback(Tpm::HierarchyControlResponse callback,TPM_RC response_code)25784 void HierarchyControlErrorCallback(Tpm::HierarchyControlResponse callback,
25785                                    TPM_RC response_code) {
25786   VLOG(1) << __func__;
25787   std::move(callback).Run(response_code);
25788 }
25789 
HierarchyControlResponseParser(Tpm::HierarchyControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25790 void HierarchyControlResponseParser(
25791     Tpm::HierarchyControlResponse callback,
25792     AuthorizationDelegate* authorization_delegate,
25793     const std::string& response) {
25794   VLOG(1) << __func__;
25795   TPM_RC rc =
25796       Tpm::ParseResponse_HierarchyControl(response, authorization_delegate);
25797   if (rc != TPM_RC_SUCCESS) {
25798     base::OnceCallback<void(TPM_RC)> error_reporter =
25799         base::BindOnce(HierarchyControlErrorCallback, std::move(callback));
25800     std::move(error_reporter).Run(rc);
25801     return;
25802   }
25803   std::move(callback).Run(rc);
25804 }
25805 
HierarchyControl(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPMI_RH_ENABLES & enable,const TPMI_YES_NO & state,AuthorizationDelegate * authorization_delegate,HierarchyControlResponse callback)25806 void Tpm::HierarchyControl(const TPMI_RH_HIERARCHY& auth_handle,
25807                            const std::string& auth_handle_name,
25808                            const TPMI_RH_ENABLES& enable,
25809                            const TPMI_YES_NO& state,
25810                            AuthorizationDelegate* authorization_delegate,
25811                            HierarchyControlResponse callback) {
25812   VLOG(1) << __func__;
25813   std::string command;
25814   TPM_RC rc = SerializeCommand_HierarchyControl(auth_handle, auth_handle_name,
25815                                                 enable, state, &command,
25816                                                 authorization_delegate);
25817   if (rc != TPM_RC_SUCCESS) {
25818     base::OnceCallback<void(TPM_RC)> error_reporter =
25819         base::BindOnce(HierarchyControlErrorCallback, std::move(callback));
25820     std::move(error_reporter).Run(rc);
25821     return;
25822   }
25823   base::OnceCallback<void(const std::string&)> parser =
25824       base::BindOnce(HierarchyControlResponseParser, std::move(callback),
25825                      authorization_delegate);
25826   transceiver_->SendCommand(command, std::move(parser));
25827 }
25828 
HierarchyControlSync(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPMI_RH_ENABLES & enable,const TPMI_YES_NO & state,AuthorizationDelegate * authorization_delegate)25829 TPM_RC Tpm::HierarchyControlSync(
25830     const TPMI_RH_HIERARCHY& auth_handle,
25831     const std::string& auth_handle_name,
25832     const TPMI_RH_ENABLES& enable,
25833     const TPMI_YES_NO& state,
25834     AuthorizationDelegate* authorization_delegate) {
25835   VLOG(1) << __func__;
25836   std::string command;
25837   TPM_RC rc = SerializeCommand_HierarchyControl(auth_handle, auth_handle_name,
25838                                                 enable, state, &command,
25839                                                 authorization_delegate);
25840   if (rc != TPM_RC_SUCCESS) {
25841     return rc;
25842   }
25843   std::string response = transceiver_->SendCommandAndWait(command);
25844   rc = ParseResponse_HierarchyControl(response, authorization_delegate);
25845   return rc;
25846 }
25847 
SerializeCommand_SetPrimaryPolicy(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25848 TPM_RC Tpm::SerializeCommand_SetPrimaryPolicy(
25849     const TPMI_RH_HIERARCHY& auth_handle,
25850     const std::string& auth_handle_name,
25851     const TPM2B_DIGEST& auth_policy,
25852     const TPMI_ALG_HASH& hash_alg,
25853     std::string* serialized_command,
25854     AuthorizationDelegate* authorization_delegate) {
25855   VLOG(3) << __func__;
25856   TPM_RC rc = TPM_RC_SUCCESS;
25857   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25858   UINT32 command_size = 10;  // Header size.
25859   std::string handle_section_bytes;
25860   std::string parameter_section_bytes;
25861   TPM_CC command_code = TPM_CC_SetPrimaryPolicy;
25862   bool is_command_parameter_encryption_possible = true;
25863   bool is_response_parameter_encryption_possible = false;
25864   std::string command_code_bytes;
25865   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25866   if (rc != TPM_RC_SUCCESS) {
25867     return rc;
25868   }
25869   std::string auth_handle_bytes;
25870   rc = Serialize_TPMI_RH_HIERARCHY(auth_handle, &auth_handle_bytes);
25871   if (rc != TPM_RC_SUCCESS) {
25872     return rc;
25873   }
25874   std::string auth_policy_bytes;
25875   rc = Serialize_TPM2B_DIGEST(auth_policy, &auth_policy_bytes);
25876   if (rc != TPM_RC_SUCCESS) {
25877     return rc;
25878   }
25879   std::string hash_alg_bytes;
25880   rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
25881   if (rc != TPM_RC_SUCCESS) {
25882     return rc;
25883   }
25884   if (authorization_delegate) {
25885     // Encrypt just the parameter data, not the size.
25886     std::string tmp = auth_policy_bytes.substr(2);
25887     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
25888       return TRUNKS_RC_ENCRYPTION_FAILED;
25889     }
25890     auth_policy_bytes.replace(2, std::string::npos, tmp);
25891   }
25892   std::unique_ptr<crypto::SecureHash> hash(
25893       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25894   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25895   hash->Update(auth_handle_name.data(), auth_handle_name.size());
25896   handle_section_bytes += auth_handle_bytes;
25897   command_size += auth_handle_bytes.size();
25898   hash->Update(auth_policy_bytes.data(), auth_policy_bytes.size());
25899   parameter_section_bytes += auth_policy_bytes;
25900   command_size += auth_policy_bytes.size();
25901   hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
25902   parameter_section_bytes += hash_alg_bytes;
25903   command_size += hash_alg_bytes.size();
25904   std::string command_hash(32, 0);
25905   hash->Finish(std::data(command_hash), command_hash.size());
25906   std::string authorization_section_bytes;
25907   std::string authorization_size_bytes;
25908   if (authorization_delegate) {
25909     if (!authorization_delegate->GetCommandAuthorization(
25910             command_hash, is_command_parameter_encryption_possible,
25911             is_response_parameter_encryption_possible,
25912             &authorization_section_bytes)) {
25913       return TRUNKS_RC_AUTHORIZATION_FAILED;
25914     }
25915     if (!authorization_section_bytes.empty()) {
25916       tag = TPM_ST_SESSIONS;
25917       std::string tmp;
25918       rc = Serialize_UINT32(authorization_section_bytes.size(),
25919                             &authorization_size_bytes);
25920       if (rc != TPM_RC_SUCCESS) {
25921         return rc;
25922       }
25923       command_size +=
25924           authorization_size_bytes.size() + authorization_section_bytes.size();
25925     }
25926   }
25927   std::string tag_bytes;
25928   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25929   if (rc != TPM_RC_SUCCESS) {
25930     return rc;
25931   }
25932   std::string command_size_bytes;
25933   rc = Serialize_UINT32(command_size, &command_size_bytes);
25934   if (rc != TPM_RC_SUCCESS) {
25935     return rc;
25936   }
25937   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25938                         handle_section_bytes + authorization_size_bytes +
25939                         authorization_section_bytes + parameter_section_bytes;
25940   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25941   VLOG(2) << "Command: "
25942           << base::HexEncode(serialized_command->data(),
25943                              serialized_command->size());
25944   return TPM_RC_SUCCESS;
25945 }
25946 
ParseResponse_SetPrimaryPolicy(const std::string & response,AuthorizationDelegate * authorization_delegate)25947 TPM_RC Tpm::ParseResponse_SetPrimaryPolicy(
25948     const std::string& response,
25949     AuthorizationDelegate* authorization_delegate) {
25950   VLOG(3) << __func__;
25951   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25952   TPM_RC rc = TPM_RC_SUCCESS;
25953   std::string buffer(response);
25954   TPM_ST tag;
25955   std::string tag_bytes;
25956   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25957   if (rc != TPM_RC_SUCCESS) {
25958     return rc;
25959   }
25960   UINT32 response_size;
25961   std::string response_size_bytes;
25962   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25963   if (rc != TPM_RC_SUCCESS) {
25964     return rc;
25965   }
25966   TPM_RC response_code;
25967   std::string response_code_bytes;
25968   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25969   if (rc != TPM_RC_SUCCESS) {
25970     return rc;
25971   }
25972   if (response_size != response.size()) {
25973     return TPM_RC_SIZE;
25974   }
25975   if (response_code != TPM_RC_SUCCESS) {
25976     return response_code;
25977   }
25978   TPM_CC command_code = TPM_CC_SetPrimaryPolicy;
25979   std::string command_code_bytes;
25980   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25981   if (rc != TPM_RC_SUCCESS) {
25982     return rc;
25983   }
25984   std::string authorization_section_bytes;
25985   if (tag == TPM_ST_SESSIONS) {
25986     UINT32 parameter_section_size = buffer.size();
25987     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25988     if (rc != TPM_RC_SUCCESS) {
25989       return rc;
25990     }
25991     if (parameter_section_size > buffer.size()) {
25992       return TPM_RC_INSUFFICIENT;
25993     }
25994     authorization_section_bytes = buffer.substr(parameter_section_size);
25995     // Keep the parameter section in |buffer|.
25996     buffer.erase(parameter_section_size);
25997   }
25998   std::unique_ptr<crypto::SecureHash> hash(
25999       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26000   hash->Update(response_code_bytes.data(), response_code_bytes.size());
26001   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26002   hash->Update(buffer.data(), buffer.size());
26003   std::string response_hash(32, 0);
26004   hash->Finish(std::data(response_hash), response_hash.size());
26005   if (tag == TPM_ST_SESSIONS) {
26006     if (!authorization_delegate)
26007       return TRUNKS_RC_AUTHORIZATION_FAILED;
26008     if (!authorization_delegate->CheckResponseAuthorization(
26009             response_hash, authorization_section_bytes)) {
26010       return TRUNKS_RC_AUTHORIZATION_FAILED;
26011     }
26012   }
26013   return TPM_RC_SUCCESS;
26014 }
26015 
SetPrimaryPolicyErrorCallback(Tpm::SetPrimaryPolicyResponse callback,TPM_RC response_code)26016 void SetPrimaryPolicyErrorCallback(Tpm::SetPrimaryPolicyResponse callback,
26017                                    TPM_RC response_code) {
26018   VLOG(1) << __func__;
26019   std::move(callback).Run(response_code);
26020 }
26021 
SetPrimaryPolicyResponseParser(Tpm::SetPrimaryPolicyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26022 void SetPrimaryPolicyResponseParser(
26023     Tpm::SetPrimaryPolicyResponse callback,
26024     AuthorizationDelegate* authorization_delegate,
26025     const std::string& response) {
26026   VLOG(1) << __func__;
26027   TPM_RC rc =
26028       Tpm::ParseResponse_SetPrimaryPolicy(response, authorization_delegate);
26029   if (rc != TPM_RC_SUCCESS) {
26030     base::OnceCallback<void(TPM_RC)> error_reporter =
26031         base::BindOnce(SetPrimaryPolicyErrorCallback, std::move(callback));
26032     std::move(error_reporter).Run(rc);
26033     return;
26034   }
26035   std::move(callback).Run(rc);
26036 }
26037 
SetPrimaryPolicy(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,SetPrimaryPolicyResponse callback)26038 void Tpm::SetPrimaryPolicy(const TPMI_RH_HIERARCHY& auth_handle,
26039                            const std::string& auth_handle_name,
26040                            const TPM2B_DIGEST& auth_policy,
26041                            const TPMI_ALG_HASH& hash_alg,
26042                            AuthorizationDelegate* authorization_delegate,
26043                            SetPrimaryPolicyResponse callback) {
26044   VLOG(1) << __func__;
26045   std::string command;
26046   TPM_RC rc = SerializeCommand_SetPrimaryPolicy(auth_handle, auth_handle_name,
26047                                                 auth_policy, hash_alg, &command,
26048                                                 authorization_delegate);
26049   if (rc != TPM_RC_SUCCESS) {
26050     base::OnceCallback<void(TPM_RC)> error_reporter =
26051         base::BindOnce(SetPrimaryPolicyErrorCallback, std::move(callback));
26052     std::move(error_reporter).Run(rc);
26053     return;
26054   }
26055   base::OnceCallback<void(const std::string&)> parser =
26056       base::BindOnce(SetPrimaryPolicyResponseParser, std::move(callback),
26057                      authorization_delegate);
26058   transceiver_->SendCommand(command, std::move(parser));
26059 }
26060 
SetPrimaryPolicySync(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate)26061 TPM_RC Tpm::SetPrimaryPolicySync(
26062     const TPMI_RH_HIERARCHY& auth_handle,
26063     const std::string& auth_handle_name,
26064     const TPM2B_DIGEST& auth_policy,
26065     const TPMI_ALG_HASH& hash_alg,
26066     AuthorizationDelegate* authorization_delegate) {
26067   VLOG(1) << __func__;
26068   std::string command;
26069   TPM_RC rc = SerializeCommand_SetPrimaryPolicy(auth_handle, auth_handle_name,
26070                                                 auth_policy, hash_alg, &command,
26071                                                 authorization_delegate);
26072   if (rc != TPM_RC_SUCCESS) {
26073     return rc;
26074   }
26075   std::string response = transceiver_->SendCommandAndWait(command);
26076   rc = ParseResponse_SetPrimaryPolicy(response, authorization_delegate);
26077   return rc;
26078 }
26079 
SerializeCommand_ChangePPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26080 TPM_RC Tpm::SerializeCommand_ChangePPS(
26081     const TPMI_RH_PLATFORM& auth_handle,
26082     const std::string& auth_handle_name,
26083     std::string* serialized_command,
26084     AuthorizationDelegate* authorization_delegate) {
26085   VLOG(3) << __func__;
26086   TPM_RC rc = TPM_RC_SUCCESS;
26087   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26088   UINT32 command_size = 10;  // Header size.
26089   std::string handle_section_bytes;
26090   std::string parameter_section_bytes;
26091   TPM_CC command_code = TPM_CC_ChangePPS;
26092   bool is_command_parameter_encryption_possible = false;
26093   bool is_response_parameter_encryption_possible = false;
26094   std::string command_code_bytes;
26095   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26096   if (rc != TPM_RC_SUCCESS) {
26097     return rc;
26098   }
26099   std::string auth_handle_bytes;
26100   rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
26101   if (rc != TPM_RC_SUCCESS) {
26102     return rc;
26103   }
26104   std::unique_ptr<crypto::SecureHash> hash(
26105       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26106   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26107   hash->Update(auth_handle_name.data(), auth_handle_name.size());
26108   handle_section_bytes += auth_handle_bytes;
26109   command_size += auth_handle_bytes.size();
26110   std::string command_hash(32, 0);
26111   hash->Finish(std::data(command_hash), command_hash.size());
26112   std::string authorization_section_bytes;
26113   std::string authorization_size_bytes;
26114   if (authorization_delegate) {
26115     if (!authorization_delegate->GetCommandAuthorization(
26116             command_hash, is_command_parameter_encryption_possible,
26117             is_response_parameter_encryption_possible,
26118             &authorization_section_bytes)) {
26119       return TRUNKS_RC_AUTHORIZATION_FAILED;
26120     }
26121     if (!authorization_section_bytes.empty()) {
26122       tag = TPM_ST_SESSIONS;
26123       std::string tmp;
26124       rc = Serialize_UINT32(authorization_section_bytes.size(),
26125                             &authorization_size_bytes);
26126       if (rc != TPM_RC_SUCCESS) {
26127         return rc;
26128       }
26129       command_size +=
26130           authorization_size_bytes.size() + authorization_section_bytes.size();
26131     }
26132   }
26133   std::string tag_bytes;
26134   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26135   if (rc != TPM_RC_SUCCESS) {
26136     return rc;
26137   }
26138   std::string command_size_bytes;
26139   rc = Serialize_UINT32(command_size, &command_size_bytes);
26140   if (rc != TPM_RC_SUCCESS) {
26141     return rc;
26142   }
26143   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26144                         handle_section_bytes + authorization_size_bytes +
26145                         authorization_section_bytes + parameter_section_bytes;
26146   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26147   VLOG(2) << "Command: "
26148           << base::HexEncode(serialized_command->data(),
26149                              serialized_command->size());
26150   return TPM_RC_SUCCESS;
26151 }
26152 
ParseResponse_ChangePPS(const std::string & response,AuthorizationDelegate * authorization_delegate)26153 TPM_RC Tpm::ParseResponse_ChangePPS(
26154     const std::string& response,
26155     AuthorizationDelegate* authorization_delegate) {
26156   VLOG(3) << __func__;
26157   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26158   TPM_RC rc = TPM_RC_SUCCESS;
26159   std::string buffer(response);
26160   TPM_ST tag;
26161   std::string tag_bytes;
26162   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26163   if (rc != TPM_RC_SUCCESS) {
26164     return rc;
26165   }
26166   UINT32 response_size;
26167   std::string response_size_bytes;
26168   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26169   if (rc != TPM_RC_SUCCESS) {
26170     return rc;
26171   }
26172   TPM_RC response_code;
26173   std::string response_code_bytes;
26174   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26175   if (rc != TPM_RC_SUCCESS) {
26176     return rc;
26177   }
26178   if (response_size != response.size()) {
26179     return TPM_RC_SIZE;
26180   }
26181   if (response_code != TPM_RC_SUCCESS) {
26182     return response_code;
26183   }
26184   TPM_CC command_code = TPM_CC_ChangePPS;
26185   std::string command_code_bytes;
26186   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26187   if (rc != TPM_RC_SUCCESS) {
26188     return rc;
26189   }
26190   std::string authorization_section_bytes;
26191   if (tag == TPM_ST_SESSIONS) {
26192     UINT32 parameter_section_size = buffer.size();
26193     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26194     if (rc != TPM_RC_SUCCESS) {
26195       return rc;
26196     }
26197     if (parameter_section_size > buffer.size()) {
26198       return TPM_RC_INSUFFICIENT;
26199     }
26200     authorization_section_bytes = buffer.substr(parameter_section_size);
26201     // Keep the parameter section in |buffer|.
26202     buffer.erase(parameter_section_size);
26203   }
26204   std::unique_ptr<crypto::SecureHash> hash(
26205       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26206   hash->Update(response_code_bytes.data(), response_code_bytes.size());
26207   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26208   hash->Update(buffer.data(), buffer.size());
26209   std::string response_hash(32, 0);
26210   hash->Finish(std::data(response_hash), response_hash.size());
26211   if (tag == TPM_ST_SESSIONS) {
26212     if (!authorization_delegate)
26213       return TRUNKS_RC_AUTHORIZATION_FAILED;
26214     if (!authorization_delegate->CheckResponseAuthorization(
26215             response_hash, authorization_section_bytes)) {
26216       return TRUNKS_RC_AUTHORIZATION_FAILED;
26217     }
26218   }
26219   return TPM_RC_SUCCESS;
26220 }
26221 
ChangePPSErrorCallback(Tpm::ChangePPSResponse callback,TPM_RC response_code)26222 void ChangePPSErrorCallback(Tpm::ChangePPSResponse callback,
26223                             TPM_RC response_code) {
26224   VLOG(1) << __func__;
26225   std::move(callback).Run(response_code);
26226 }
26227 
ChangePPSResponseParser(Tpm::ChangePPSResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26228 void ChangePPSResponseParser(Tpm::ChangePPSResponse callback,
26229                              AuthorizationDelegate* authorization_delegate,
26230                              const std::string& response) {
26231   VLOG(1) << __func__;
26232   TPM_RC rc = Tpm::ParseResponse_ChangePPS(response, authorization_delegate);
26233   if (rc != TPM_RC_SUCCESS) {
26234     base::OnceCallback<void(TPM_RC)> error_reporter =
26235         base::BindOnce(ChangePPSErrorCallback, std::move(callback));
26236     std::move(error_reporter).Run(rc);
26237     return;
26238   }
26239   std::move(callback).Run(rc);
26240 }
26241 
ChangePPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ChangePPSResponse callback)26242 void Tpm::ChangePPS(const TPMI_RH_PLATFORM& auth_handle,
26243                     const std::string& auth_handle_name,
26244                     AuthorizationDelegate* authorization_delegate,
26245                     ChangePPSResponse callback) {
26246   VLOG(1) << __func__;
26247   std::string command;
26248   TPM_RC rc = SerializeCommand_ChangePPS(auth_handle, auth_handle_name,
26249                                          &command, authorization_delegate);
26250   if (rc != TPM_RC_SUCCESS) {
26251     base::OnceCallback<void(TPM_RC)> error_reporter =
26252         base::BindOnce(ChangePPSErrorCallback, std::move(callback));
26253     std::move(error_reporter).Run(rc);
26254     return;
26255   }
26256   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26257       ChangePPSResponseParser, std::move(callback), authorization_delegate);
26258   transceiver_->SendCommand(command, std::move(parser));
26259 }
26260 
ChangePPSSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26261 TPM_RC Tpm::ChangePPSSync(const TPMI_RH_PLATFORM& auth_handle,
26262                           const std::string& auth_handle_name,
26263                           AuthorizationDelegate* authorization_delegate) {
26264   VLOG(1) << __func__;
26265   std::string command;
26266   TPM_RC rc = SerializeCommand_ChangePPS(auth_handle, auth_handle_name,
26267                                          &command, authorization_delegate);
26268   if (rc != TPM_RC_SUCCESS) {
26269     return rc;
26270   }
26271   std::string response = transceiver_->SendCommandAndWait(command);
26272   rc = ParseResponse_ChangePPS(response, authorization_delegate);
26273   return rc;
26274 }
26275 
SerializeCommand_ChangeEPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26276 TPM_RC Tpm::SerializeCommand_ChangeEPS(
26277     const TPMI_RH_PLATFORM& auth_handle,
26278     const std::string& auth_handle_name,
26279     std::string* serialized_command,
26280     AuthorizationDelegate* authorization_delegate) {
26281   VLOG(3) << __func__;
26282   TPM_RC rc = TPM_RC_SUCCESS;
26283   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26284   UINT32 command_size = 10;  // Header size.
26285   std::string handle_section_bytes;
26286   std::string parameter_section_bytes;
26287   TPM_CC command_code = TPM_CC_ChangeEPS;
26288   bool is_command_parameter_encryption_possible = false;
26289   bool is_response_parameter_encryption_possible = false;
26290   std::string command_code_bytes;
26291   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26292   if (rc != TPM_RC_SUCCESS) {
26293     return rc;
26294   }
26295   std::string auth_handle_bytes;
26296   rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
26297   if (rc != TPM_RC_SUCCESS) {
26298     return rc;
26299   }
26300   std::unique_ptr<crypto::SecureHash> hash(
26301       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26302   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26303   hash->Update(auth_handle_name.data(), auth_handle_name.size());
26304   handle_section_bytes += auth_handle_bytes;
26305   command_size += auth_handle_bytes.size();
26306   std::string command_hash(32, 0);
26307   hash->Finish(std::data(command_hash), command_hash.size());
26308   std::string authorization_section_bytes;
26309   std::string authorization_size_bytes;
26310   if (authorization_delegate) {
26311     if (!authorization_delegate->GetCommandAuthorization(
26312             command_hash, is_command_parameter_encryption_possible,
26313             is_response_parameter_encryption_possible,
26314             &authorization_section_bytes)) {
26315       return TRUNKS_RC_AUTHORIZATION_FAILED;
26316     }
26317     if (!authorization_section_bytes.empty()) {
26318       tag = TPM_ST_SESSIONS;
26319       std::string tmp;
26320       rc = Serialize_UINT32(authorization_section_bytes.size(),
26321                             &authorization_size_bytes);
26322       if (rc != TPM_RC_SUCCESS) {
26323         return rc;
26324       }
26325       command_size +=
26326           authorization_size_bytes.size() + authorization_section_bytes.size();
26327     }
26328   }
26329   std::string tag_bytes;
26330   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26331   if (rc != TPM_RC_SUCCESS) {
26332     return rc;
26333   }
26334   std::string command_size_bytes;
26335   rc = Serialize_UINT32(command_size, &command_size_bytes);
26336   if (rc != TPM_RC_SUCCESS) {
26337     return rc;
26338   }
26339   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26340                         handle_section_bytes + authorization_size_bytes +
26341                         authorization_section_bytes + parameter_section_bytes;
26342   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26343   VLOG(2) << "Command: "
26344           << base::HexEncode(serialized_command->data(),
26345                              serialized_command->size());
26346   return TPM_RC_SUCCESS;
26347 }
26348 
ParseResponse_ChangeEPS(const std::string & response,AuthorizationDelegate * authorization_delegate)26349 TPM_RC Tpm::ParseResponse_ChangeEPS(
26350     const std::string& response,
26351     AuthorizationDelegate* authorization_delegate) {
26352   VLOG(3) << __func__;
26353   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26354   TPM_RC rc = TPM_RC_SUCCESS;
26355   std::string buffer(response);
26356   TPM_ST tag;
26357   std::string tag_bytes;
26358   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26359   if (rc != TPM_RC_SUCCESS) {
26360     return rc;
26361   }
26362   UINT32 response_size;
26363   std::string response_size_bytes;
26364   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26365   if (rc != TPM_RC_SUCCESS) {
26366     return rc;
26367   }
26368   TPM_RC response_code;
26369   std::string response_code_bytes;
26370   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26371   if (rc != TPM_RC_SUCCESS) {
26372     return rc;
26373   }
26374   if (response_size != response.size()) {
26375     return TPM_RC_SIZE;
26376   }
26377   if (response_code != TPM_RC_SUCCESS) {
26378     return response_code;
26379   }
26380   TPM_CC command_code = TPM_CC_ChangeEPS;
26381   std::string command_code_bytes;
26382   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26383   if (rc != TPM_RC_SUCCESS) {
26384     return rc;
26385   }
26386   std::string authorization_section_bytes;
26387   if (tag == TPM_ST_SESSIONS) {
26388     UINT32 parameter_section_size = buffer.size();
26389     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26390     if (rc != TPM_RC_SUCCESS) {
26391       return rc;
26392     }
26393     if (parameter_section_size > buffer.size()) {
26394       return TPM_RC_INSUFFICIENT;
26395     }
26396     authorization_section_bytes = buffer.substr(parameter_section_size);
26397     // Keep the parameter section in |buffer|.
26398     buffer.erase(parameter_section_size);
26399   }
26400   std::unique_ptr<crypto::SecureHash> hash(
26401       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26402   hash->Update(response_code_bytes.data(), response_code_bytes.size());
26403   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26404   hash->Update(buffer.data(), buffer.size());
26405   std::string response_hash(32, 0);
26406   hash->Finish(std::data(response_hash), response_hash.size());
26407   if (tag == TPM_ST_SESSIONS) {
26408     if (!authorization_delegate)
26409       return TRUNKS_RC_AUTHORIZATION_FAILED;
26410     if (!authorization_delegate->CheckResponseAuthorization(
26411             response_hash, authorization_section_bytes)) {
26412       return TRUNKS_RC_AUTHORIZATION_FAILED;
26413     }
26414   }
26415   return TPM_RC_SUCCESS;
26416 }
26417 
ChangeEPSErrorCallback(Tpm::ChangeEPSResponse callback,TPM_RC response_code)26418 void ChangeEPSErrorCallback(Tpm::ChangeEPSResponse callback,
26419                             TPM_RC response_code) {
26420   VLOG(1) << __func__;
26421   std::move(callback).Run(response_code);
26422 }
26423 
ChangeEPSResponseParser(Tpm::ChangeEPSResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26424 void ChangeEPSResponseParser(Tpm::ChangeEPSResponse callback,
26425                              AuthorizationDelegate* authorization_delegate,
26426                              const std::string& response) {
26427   VLOG(1) << __func__;
26428   TPM_RC rc = Tpm::ParseResponse_ChangeEPS(response, authorization_delegate);
26429   if (rc != TPM_RC_SUCCESS) {
26430     base::OnceCallback<void(TPM_RC)> error_reporter =
26431         base::BindOnce(ChangeEPSErrorCallback, std::move(callback));
26432     std::move(error_reporter).Run(rc);
26433     return;
26434   }
26435   std::move(callback).Run(rc);
26436 }
26437 
ChangeEPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ChangeEPSResponse callback)26438 void Tpm::ChangeEPS(const TPMI_RH_PLATFORM& auth_handle,
26439                     const std::string& auth_handle_name,
26440                     AuthorizationDelegate* authorization_delegate,
26441                     ChangeEPSResponse callback) {
26442   VLOG(1) << __func__;
26443   std::string command;
26444   TPM_RC rc = SerializeCommand_ChangeEPS(auth_handle, auth_handle_name,
26445                                          &command, authorization_delegate);
26446   if (rc != TPM_RC_SUCCESS) {
26447     base::OnceCallback<void(TPM_RC)> error_reporter =
26448         base::BindOnce(ChangeEPSErrorCallback, std::move(callback));
26449     std::move(error_reporter).Run(rc);
26450     return;
26451   }
26452   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26453       ChangeEPSResponseParser, std::move(callback), authorization_delegate);
26454   transceiver_->SendCommand(command, std::move(parser));
26455 }
26456 
ChangeEPSSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26457 TPM_RC Tpm::ChangeEPSSync(const TPMI_RH_PLATFORM& auth_handle,
26458                           const std::string& auth_handle_name,
26459                           AuthorizationDelegate* authorization_delegate) {
26460   VLOG(1) << __func__;
26461   std::string command;
26462   TPM_RC rc = SerializeCommand_ChangeEPS(auth_handle, auth_handle_name,
26463                                          &command, authorization_delegate);
26464   if (rc != TPM_RC_SUCCESS) {
26465     return rc;
26466   }
26467   std::string response = transceiver_->SendCommandAndWait(command);
26468   rc = ParseResponse_ChangeEPS(response, authorization_delegate);
26469   return rc;
26470 }
26471 
SerializeCommand_Clear(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26472 TPM_RC Tpm::SerializeCommand_Clear(
26473     const TPMI_RH_CLEAR& auth_handle,
26474     const std::string& auth_handle_name,
26475     std::string* serialized_command,
26476     AuthorizationDelegate* authorization_delegate) {
26477   VLOG(3) << __func__;
26478   TPM_RC rc = TPM_RC_SUCCESS;
26479   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26480   UINT32 command_size = 10;  // Header size.
26481   std::string handle_section_bytes;
26482   std::string parameter_section_bytes;
26483   TPM_CC command_code = TPM_CC_Clear;
26484   bool is_command_parameter_encryption_possible = false;
26485   bool is_response_parameter_encryption_possible = false;
26486   std::string command_code_bytes;
26487   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26488   if (rc != TPM_RC_SUCCESS) {
26489     return rc;
26490   }
26491   std::string auth_handle_bytes;
26492   rc = Serialize_TPMI_RH_CLEAR(auth_handle, &auth_handle_bytes);
26493   if (rc != TPM_RC_SUCCESS) {
26494     return rc;
26495   }
26496   std::unique_ptr<crypto::SecureHash> hash(
26497       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26498   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26499   hash->Update(auth_handle_name.data(), auth_handle_name.size());
26500   handle_section_bytes += auth_handle_bytes;
26501   command_size += auth_handle_bytes.size();
26502   std::string command_hash(32, 0);
26503   hash->Finish(std::data(command_hash), command_hash.size());
26504   std::string authorization_section_bytes;
26505   std::string authorization_size_bytes;
26506   if (authorization_delegate) {
26507     if (!authorization_delegate->GetCommandAuthorization(
26508             command_hash, is_command_parameter_encryption_possible,
26509             is_response_parameter_encryption_possible,
26510             &authorization_section_bytes)) {
26511       return TRUNKS_RC_AUTHORIZATION_FAILED;
26512     }
26513     if (!authorization_section_bytes.empty()) {
26514       tag = TPM_ST_SESSIONS;
26515       std::string tmp;
26516       rc = Serialize_UINT32(authorization_section_bytes.size(),
26517                             &authorization_size_bytes);
26518       if (rc != TPM_RC_SUCCESS) {
26519         return rc;
26520       }
26521       command_size +=
26522           authorization_size_bytes.size() + authorization_section_bytes.size();
26523     }
26524   }
26525   std::string tag_bytes;
26526   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26527   if (rc != TPM_RC_SUCCESS) {
26528     return rc;
26529   }
26530   std::string command_size_bytes;
26531   rc = Serialize_UINT32(command_size, &command_size_bytes);
26532   if (rc != TPM_RC_SUCCESS) {
26533     return rc;
26534   }
26535   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26536                         handle_section_bytes + authorization_size_bytes +
26537                         authorization_section_bytes + parameter_section_bytes;
26538   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26539   VLOG(2) << "Command: "
26540           << base::HexEncode(serialized_command->data(),
26541                              serialized_command->size());
26542   return TPM_RC_SUCCESS;
26543 }
26544 
ParseResponse_Clear(const std::string & response,AuthorizationDelegate * authorization_delegate)26545 TPM_RC Tpm::ParseResponse_Clear(const std::string& response,
26546                                 AuthorizationDelegate* authorization_delegate) {
26547   VLOG(3) << __func__;
26548   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26549   TPM_RC rc = TPM_RC_SUCCESS;
26550   std::string buffer(response);
26551   TPM_ST tag;
26552   std::string tag_bytes;
26553   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26554   if (rc != TPM_RC_SUCCESS) {
26555     return rc;
26556   }
26557   UINT32 response_size;
26558   std::string response_size_bytes;
26559   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26560   if (rc != TPM_RC_SUCCESS) {
26561     return rc;
26562   }
26563   TPM_RC response_code;
26564   std::string response_code_bytes;
26565   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26566   if (rc != TPM_RC_SUCCESS) {
26567     return rc;
26568   }
26569   if (response_size != response.size()) {
26570     return TPM_RC_SIZE;
26571   }
26572   if (response_code != TPM_RC_SUCCESS) {
26573     return response_code;
26574   }
26575   TPM_CC command_code = TPM_CC_Clear;
26576   std::string command_code_bytes;
26577   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26578   if (rc != TPM_RC_SUCCESS) {
26579     return rc;
26580   }
26581   std::string authorization_section_bytes;
26582   if (tag == TPM_ST_SESSIONS) {
26583     UINT32 parameter_section_size = buffer.size();
26584     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26585     if (rc != TPM_RC_SUCCESS) {
26586       return rc;
26587     }
26588     if (parameter_section_size > buffer.size()) {
26589       return TPM_RC_INSUFFICIENT;
26590     }
26591     authorization_section_bytes = buffer.substr(parameter_section_size);
26592     // Keep the parameter section in |buffer|.
26593     buffer.erase(parameter_section_size);
26594   }
26595   std::unique_ptr<crypto::SecureHash> hash(
26596       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26597   hash->Update(response_code_bytes.data(), response_code_bytes.size());
26598   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26599   hash->Update(buffer.data(), buffer.size());
26600   std::string response_hash(32, 0);
26601   hash->Finish(std::data(response_hash), response_hash.size());
26602   if (tag == TPM_ST_SESSIONS) {
26603     if (!authorization_delegate)
26604       return TRUNKS_RC_AUTHORIZATION_FAILED;
26605     if (!authorization_delegate->CheckResponseAuthorization(
26606             response_hash, authorization_section_bytes)) {
26607       return TRUNKS_RC_AUTHORIZATION_FAILED;
26608     }
26609   }
26610   return TPM_RC_SUCCESS;
26611 }
26612 
ClearErrorCallback(Tpm::ClearResponse callback,TPM_RC response_code)26613 void ClearErrorCallback(Tpm::ClearResponse callback, TPM_RC response_code) {
26614   VLOG(1) << __func__;
26615   std::move(callback).Run(response_code);
26616 }
26617 
ClearResponseParser(Tpm::ClearResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26618 void ClearResponseParser(Tpm::ClearResponse callback,
26619                          AuthorizationDelegate* authorization_delegate,
26620                          const std::string& response) {
26621   VLOG(1) << __func__;
26622   TPM_RC rc = Tpm::ParseResponse_Clear(response, authorization_delegate);
26623   if (rc != TPM_RC_SUCCESS) {
26624     base::OnceCallback<void(TPM_RC)> error_reporter =
26625         base::BindOnce(ClearErrorCallback, std::move(callback));
26626     std::move(error_reporter).Run(rc);
26627     return;
26628   }
26629   std::move(callback).Run(rc);
26630 }
26631 
Clear(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ClearResponse callback)26632 void Tpm::Clear(const TPMI_RH_CLEAR& auth_handle,
26633                 const std::string& auth_handle_name,
26634                 AuthorizationDelegate* authorization_delegate,
26635                 ClearResponse callback) {
26636   VLOG(1) << __func__;
26637   std::string command;
26638   TPM_RC rc = SerializeCommand_Clear(auth_handle, auth_handle_name, &command,
26639                                      authorization_delegate);
26640   if (rc != TPM_RC_SUCCESS) {
26641     base::OnceCallback<void(TPM_RC)> error_reporter =
26642         base::BindOnce(ClearErrorCallback, std::move(callback));
26643     std::move(error_reporter).Run(rc);
26644     return;
26645   }
26646   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26647       ClearResponseParser, std::move(callback), authorization_delegate);
26648   transceiver_->SendCommand(command, std::move(parser));
26649 }
26650 
ClearSync(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26651 TPM_RC Tpm::ClearSync(const TPMI_RH_CLEAR& auth_handle,
26652                       const std::string& auth_handle_name,
26653                       AuthorizationDelegate* authorization_delegate) {
26654   VLOG(1) << __func__;
26655   std::string command;
26656   TPM_RC rc = SerializeCommand_Clear(auth_handle, auth_handle_name, &command,
26657                                      authorization_delegate);
26658   if (rc != TPM_RC_SUCCESS) {
26659     return rc;
26660   }
26661   std::string response = transceiver_->SendCommandAndWait(command);
26662   rc = ParseResponse_Clear(response, authorization_delegate);
26663   return rc;
26664 }
26665 
SerializeCommand_ClearControl(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26666 TPM_RC Tpm::SerializeCommand_ClearControl(
26667     const TPMI_RH_CLEAR& auth,
26668     const std::string& auth_name,
26669     const TPMI_YES_NO& disable,
26670     std::string* serialized_command,
26671     AuthorizationDelegate* authorization_delegate) {
26672   VLOG(3) << __func__;
26673   TPM_RC rc = TPM_RC_SUCCESS;
26674   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26675   UINT32 command_size = 10;  // Header size.
26676   std::string handle_section_bytes;
26677   std::string parameter_section_bytes;
26678   TPM_CC command_code = TPM_CC_ClearControl;
26679   bool is_command_parameter_encryption_possible = false;
26680   bool is_response_parameter_encryption_possible = false;
26681   std::string command_code_bytes;
26682   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26683   if (rc != TPM_RC_SUCCESS) {
26684     return rc;
26685   }
26686   std::string auth_bytes;
26687   rc = Serialize_TPMI_RH_CLEAR(auth, &auth_bytes);
26688   if (rc != TPM_RC_SUCCESS) {
26689     return rc;
26690   }
26691   std::string disable_bytes;
26692   rc = Serialize_TPMI_YES_NO(disable, &disable_bytes);
26693   if (rc != TPM_RC_SUCCESS) {
26694     return rc;
26695   }
26696   std::unique_ptr<crypto::SecureHash> hash(
26697       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26698   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26699   hash->Update(auth_name.data(), auth_name.size());
26700   handle_section_bytes += auth_bytes;
26701   command_size += auth_bytes.size();
26702   hash->Update(disable_bytes.data(), disable_bytes.size());
26703   parameter_section_bytes += disable_bytes;
26704   command_size += disable_bytes.size();
26705   std::string command_hash(32, 0);
26706   hash->Finish(std::data(command_hash), command_hash.size());
26707   std::string authorization_section_bytes;
26708   std::string authorization_size_bytes;
26709   if (authorization_delegate) {
26710     if (!authorization_delegate->GetCommandAuthorization(
26711             command_hash, is_command_parameter_encryption_possible,
26712             is_response_parameter_encryption_possible,
26713             &authorization_section_bytes)) {
26714       return TRUNKS_RC_AUTHORIZATION_FAILED;
26715     }
26716     if (!authorization_section_bytes.empty()) {
26717       tag = TPM_ST_SESSIONS;
26718       std::string tmp;
26719       rc = Serialize_UINT32(authorization_section_bytes.size(),
26720                             &authorization_size_bytes);
26721       if (rc != TPM_RC_SUCCESS) {
26722         return rc;
26723       }
26724       command_size +=
26725           authorization_size_bytes.size() + authorization_section_bytes.size();
26726     }
26727   }
26728   std::string tag_bytes;
26729   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26730   if (rc != TPM_RC_SUCCESS) {
26731     return rc;
26732   }
26733   std::string command_size_bytes;
26734   rc = Serialize_UINT32(command_size, &command_size_bytes);
26735   if (rc != TPM_RC_SUCCESS) {
26736     return rc;
26737   }
26738   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26739                         handle_section_bytes + authorization_size_bytes +
26740                         authorization_section_bytes + parameter_section_bytes;
26741   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26742   VLOG(2) << "Command: "
26743           << base::HexEncode(serialized_command->data(),
26744                              serialized_command->size());
26745   return TPM_RC_SUCCESS;
26746 }
26747 
ParseResponse_ClearControl(const std::string & response,AuthorizationDelegate * authorization_delegate)26748 TPM_RC Tpm::ParseResponse_ClearControl(
26749     const std::string& response,
26750     AuthorizationDelegate* authorization_delegate) {
26751   VLOG(3) << __func__;
26752   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26753   TPM_RC rc = TPM_RC_SUCCESS;
26754   std::string buffer(response);
26755   TPM_ST tag;
26756   std::string tag_bytes;
26757   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26758   if (rc != TPM_RC_SUCCESS) {
26759     return rc;
26760   }
26761   UINT32 response_size;
26762   std::string response_size_bytes;
26763   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26764   if (rc != TPM_RC_SUCCESS) {
26765     return rc;
26766   }
26767   TPM_RC response_code;
26768   std::string response_code_bytes;
26769   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26770   if (rc != TPM_RC_SUCCESS) {
26771     return rc;
26772   }
26773   if (response_size != response.size()) {
26774     return TPM_RC_SIZE;
26775   }
26776   if (response_code != TPM_RC_SUCCESS) {
26777     return response_code;
26778   }
26779   TPM_CC command_code = TPM_CC_ClearControl;
26780   std::string command_code_bytes;
26781   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26782   if (rc != TPM_RC_SUCCESS) {
26783     return rc;
26784   }
26785   std::string authorization_section_bytes;
26786   if (tag == TPM_ST_SESSIONS) {
26787     UINT32 parameter_section_size = buffer.size();
26788     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26789     if (rc != TPM_RC_SUCCESS) {
26790       return rc;
26791     }
26792     if (parameter_section_size > buffer.size()) {
26793       return TPM_RC_INSUFFICIENT;
26794     }
26795     authorization_section_bytes = buffer.substr(parameter_section_size);
26796     // Keep the parameter section in |buffer|.
26797     buffer.erase(parameter_section_size);
26798   }
26799   std::unique_ptr<crypto::SecureHash> hash(
26800       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26801   hash->Update(response_code_bytes.data(), response_code_bytes.size());
26802   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26803   hash->Update(buffer.data(), buffer.size());
26804   std::string response_hash(32, 0);
26805   hash->Finish(std::data(response_hash), response_hash.size());
26806   if (tag == TPM_ST_SESSIONS) {
26807     if (!authorization_delegate)
26808       return TRUNKS_RC_AUTHORIZATION_FAILED;
26809     if (!authorization_delegate->CheckResponseAuthorization(
26810             response_hash, authorization_section_bytes)) {
26811       return TRUNKS_RC_AUTHORIZATION_FAILED;
26812     }
26813   }
26814   return TPM_RC_SUCCESS;
26815 }
26816 
ClearControlErrorCallback(Tpm::ClearControlResponse callback,TPM_RC response_code)26817 void ClearControlErrorCallback(Tpm::ClearControlResponse callback,
26818                                TPM_RC response_code) {
26819   VLOG(1) << __func__;
26820   std::move(callback).Run(response_code);
26821 }
26822 
ClearControlResponseParser(Tpm::ClearControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26823 void ClearControlResponseParser(Tpm::ClearControlResponse callback,
26824                                 AuthorizationDelegate* authorization_delegate,
26825                                 const std::string& response) {
26826   VLOG(1) << __func__;
26827   TPM_RC rc = Tpm::ParseResponse_ClearControl(response, authorization_delegate);
26828   if (rc != TPM_RC_SUCCESS) {
26829     base::OnceCallback<void(TPM_RC)> error_reporter =
26830         base::BindOnce(ClearControlErrorCallback, std::move(callback));
26831     std::move(error_reporter).Run(rc);
26832     return;
26833   }
26834   std::move(callback).Run(rc);
26835 }
26836 
ClearControl(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,AuthorizationDelegate * authorization_delegate,ClearControlResponse callback)26837 void Tpm::ClearControl(const TPMI_RH_CLEAR& auth,
26838                        const std::string& auth_name,
26839                        const TPMI_YES_NO& disable,
26840                        AuthorizationDelegate* authorization_delegate,
26841                        ClearControlResponse callback) {
26842   VLOG(1) << __func__;
26843   std::string command;
26844   TPM_RC rc = SerializeCommand_ClearControl(auth, auth_name, disable, &command,
26845                                             authorization_delegate);
26846   if (rc != TPM_RC_SUCCESS) {
26847     base::OnceCallback<void(TPM_RC)> error_reporter =
26848         base::BindOnce(ClearControlErrorCallback, std::move(callback));
26849     std::move(error_reporter).Run(rc);
26850     return;
26851   }
26852   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26853       ClearControlResponseParser, std::move(callback), authorization_delegate);
26854   transceiver_->SendCommand(command, std::move(parser));
26855 }
26856 
ClearControlSync(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,AuthorizationDelegate * authorization_delegate)26857 TPM_RC Tpm::ClearControlSync(const TPMI_RH_CLEAR& auth,
26858                              const std::string& auth_name,
26859                              const TPMI_YES_NO& disable,
26860                              AuthorizationDelegate* authorization_delegate) {
26861   VLOG(1) << __func__;
26862   std::string command;
26863   TPM_RC rc = SerializeCommand_ClearControl(auth, auth_name, disable, &command,
26864                                             authorization_delegate);
26865   if (rc != TPM_RC_SUCCESS) {
26866     return rc;
26867   }
26868   std::string response = transceiver_->SendCommandAndWait(command);
26869   rc = ParseResponse_ClearControl(response, authorization_delegate);
26870   return rc;
26871 }
26872 
SerializeCommand_HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26873 TPM_RC Tpm::SerializeCommand_HierarchyChangeAuth(
26874     const TPMI_RH_HIERARCHY_AUTH& auth_handle,
26875     const std::string& auth_handle_name,
26876     const TPM2B_AUTH& new_auth,
26877     std::string* serialized_command,
26878     AuthorizationDelegate* authorization_delegate) {
26879   VLOG(3) << __func__;
26880   TPM_RC rc = TPM_RC_SUCCESS;
26881   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26882   UINT32 command_size = 10;  // Header size.
26883   std::string handle_section_bytes;
26884   std::string parameter_section_bytes;
26885   TPM_CC command_code = TPM_CC_HierarchyChangeAuth;
26886   bool is_command_parameter_encryption_possible = true;
26887   bool is_response_parameter_encryption_possible = false;
26888   std::string command_code_bytes;
26889   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26890   if (rc != TPM_RC_SUCCESS) {
26891     return rc;
26892   }
26893   std::string auth_handle_bytes;
26894   rc = Serialize_TPMI_RH_HIERARCHY_AUTH(auth_handle, &auth_handle_bytes);
26895   if (rc != TPM_RC_SUCCESS) {
26896     return rc;
26897   }
26898   std::string new_auth_bytes;
26899   rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
26900   if (rc != TPM_RC_SUCCESS) {
26901     return rc;
26902   }
26903   if (authorization_delegate) {
26904     // Encrypt just the parameter data, not the size.
26905     std::string tmp = new_auth_bytes.substr(2);
26906     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
26907       return TRUNKS_RC_ENCRYPTION_FAILED;
26908     }
26909     new_auth_bytes.replace(2, std::string::npos, tmp);
26910   }
26911   std::unique_ptr<crypto::SecureHash> hash(
26912       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26913   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26914   hash->Update(auth_handle_name.data(), auth_handle_name.size());
26915   handle_section_bytes += auth_handle_bytes;
26916   command_size += auth_handle_bytes.size();
26917   hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
26918   parameter_section_bytes += new_auth_bytes;
26919   command_size += new_auth_bytes.size();
26920   std::string command_hash(32, 0);
26921   hash->Finish(std::data(command_hash), command_hash.size());
26922   std::string authorization_section_bytes;
26923   std::string authorization_size_bytes;
26924   if (authorization_delegate) {
26925     if (!authorization_delegate->GetCommandAuthorization(
26926             command_hash, is_command_parameter_encryption_possible,
26927             is_response_parameter_encryption_possible,
26928             &authorization_section_bytes)) {
26929       return TRUNKS_RC_AUTHORIZATION_FAILED;
26930     }
26931     if (!authorization_section_bytes.empty()) {
26932       tag = TPM_ST_SESSIONS;
26933       std::string tmp;
26934       rc = Serialize_UINT32(authorization_section_bytes.size(),
26935                             &authorization_size_bytes);
26936       if (rc != TPM_RC_SUCCESS) {
26937         return rc;
26938       }
26939       command_size +=
26940           authorization_size_bytes.size() + authorization_section_bytes.size();
26941     }
26942   }
26943   std::string tag_bytes;
26944   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26945   if (rc != TPM_RC_SUCCESS) {
26946     return rc;
26947   }
26948   std::string command_size_bytes;
26949   rc = Serialize_UINT32(command_size, &command_size_bytes);
26950   if (rc != TPM_RC_SUCCESS) {
26951     return rc;
26952   }
26953   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26954                         handle_section_bytes + authorization_size_bytes +
26955                         authorization_section_bytes + parameter_section_bytes;
26956   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26957   VLOG(2) << "Command: "
26958           << base::HexEncode(serialized_command->data(),
26959                              serialized_command->size());
26960   return TPM_RC_SUCCESS;
26961 }
26962 
ParseResponse_HierarchyChangeAuth(const std::string & response,AuthorizationDelegate * authorization_delegate)26963 TPM_RC Tpm::ParseResponse_HierarchyChangeAuth(
26964     const std::string& response,
26965     AuthorizationDelegate* authorization_delegate) {
26966   VLOG(3) << __func__;
26967   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26968   TPM_RC rc = TPM_RC_SUCCESS;
26969   std::string buffer(response);
26970   TPM_ST tag;
26971   std::string tag_bytes;
26972   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26973   if (rc != TPM_RC_SUCCESS) {
26974     return rc;
26975   }
26976   UINT32 response_size;
26977   std::string response_size_bytes;
26978   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26979   if (rc != TPM_RC_SUCCESS) {
26980     return rc;
26981   }
26982   TPM_RC response_code;
26983   std::string response_code_bytes;
26984   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26985   if (rc != TPM_RC_SUCCESS) {
26986     return rc;
26987   }
26988   if (response_size != response.size()) {
26989     return TPM_RC_SIZE;
26990   }
26991   if (response_code != TPM_RC_SUCCESS) {
26992     return response_code;
26993   }
26994   TPM_CC command_code = TPM_CC_HierarchyChangeAuth;
26995   std::string command_code_bytes;
26996   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26997   if (rc != TPM_RC_SUCCESS) {
26998     return rc;
26999   }
27000   std::string authorization_section_bytes;
27001   if (tag == TPM_ST_SESSIONS) {
27002     UINT32 parameter_section_size = buffer.size();
27003     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27004     if (rc != TPM_RC_SUCCESS) {
27005       return rc;
27006     }
27007     if (parameter_section_size > buffer.size()) {
27008       return TPM_RC_INSUFFICIENT;
27009     }
27010     authorization_section_bytes = buffer.substr(parameter_section_size);
27011     // Keep the parameter section in |buffer|.
27012     buffer.erase(parameter_section_size);
27013   }
27014   std::unique_ptr<crypto::SecureHash> hash(
27015       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27016   hash->Update(response_code_bytes.data(), response_code_bytes.size());
27017   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27018   hash->Update(buffer.data(), buffer.size());
27019   std::string response_hash(32, 0);
27020   hash->Finish(std::data(response_hash), response_hash.size());
27021   if (tag == TPM_ST_SESSIONS) {
27022     if (!authorization_delegate)
27023       return TRUNKS_RC_AUTHORIZATION_FAILED;
27024     if (!authorization_delegate->CheckResponseAuthorization(
27025             response_hash, authorization_section_bytes)) {
27026       return TRUNKS_RC_AUTHORIZATION_FAILED;
27027     }
27028   }
27029   return TPM_RC_SUCCESS;
27030 }
27031 
HierarchyChangeAuthErrorCallback(Tpm::HierarchyChangeAuthResponse callback,TPM_RC response_code)27032 void HierarchyChangeAuthErrorCallback(Tpm::HierarchyChangeAuthResponse callback,
27033                                       TPM_RC response_code) {
27034   VLOG(1) << __func__;
27035   std::move(callback).Run(response_code);
27036 }
27037 
HierarchyChangeAuthResponseParser(Tpm::HierarchyChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27038 void HierarchyChangeAuthResponseParser(
27039     Tpm::HierarchyChangeAuthResponse callback,
27040     AuthorizationDelegate* authorization_delegate,
27041     const std::string& response) {
27042   VLOG(1) << __func__;
27043   TPM_RC rc =
27044       Tpm::ParseResponse_HierarchyChangeAuth(response, authorization_delegate);
27045   if (rc != TPM_RC_SUCCESS) {
27046     base::OnceCallback<void(TPM_RC)> error_reporter =
27047         base::BindOnce(HierarchyChangeAuthErrorCallback, std::move(callback));
27048     std::move(error_reporter).Run(rc);
27049     return;
27050   }
27051   std::move(callback).Run(rc);
27052 }
27053 
HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate,HierarchyChangeAuthResponse callback)27054 void Tpm::HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH& auth_handle,
27055                               const std::string& auth_handle_name,
27056                               const TPM2B_AUTH& new_auth,
27057                               AuthorizationDelegate* authorization_delegate,
27058                               HierarchyChangeAuthResponse callback) {
27059   VLOG(1) << __func__;
27060   std::string command;
27061   TPM_RC rc = SerializeCommand_HierarchyChangeAuth(
27062       auth_handle, auth_handle_name, new_auth, &command,
27063       authorization_delegate);
27064   if (rc != TPM_RC_SUCCESS) {
27065     base::OnceCallback<void(TPM_RC)> error_reporter =
27066         base::BindOnce(HierarchyChangeAuthErrorCallback, std::move(callback));
27067     std::move(error_reporter).Run(rc);
27068     return;
27069   }
27070   base::OnceCallback<void(const std::string&)> parser =
27071       base::BindOnce(HierarchyChangeAuthResponseParser, std::move(callback),
27072                      authorization_delegate);
27073   transceiver_->SendCommand(command, std::move(parser));
27074 }
27075 
HierarchyChangeAuthSync(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate)27076 TPM_RC Tpm::HierarchyChangeAuthSync(
27077     const TPMI_RH_HIERARCHY_AUTH& auth_handle,
27078     const std::string& auth_handle_name,
27079     const TPM2B_AUTH& new_auth,
27080     AuthorizationDelegate* authorization_delegate) {
27081   VLOG(1) << __func__;
27082   std::string command;
27083   TPM_RC rc = SerializeCommand_HierarchyChangeAuth(
27084       auth_handle, auth_handle_name, new_auth, &command,
27085       authorization_delegate);
27086   if (rc != TPM_RC_SUCCESS) {
27087     return rc;
27088   }
27089   std::string response = transceiver_->SendCommandAndWait(command);
27090   rc = ParseResponse_HierarchyChangeAuth(response, authorization_delegate);
27091   return rc;
27092 }
27093 
SerializeCommand_DictionaryAttackLockReset(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27094 TPM_RC Tpm::SerializeCommand_DictionaryAttackLockReset(
27095     const TPMI_RH_LOCKOUT& lock_handle,
27096     const std::string& lock_handle_name,
27097     std::string* serialized_command,
27098     AuthorizationDelegate* authorization_delegate) {
27099   VLOG(3) << __func__;
27100   TPM_RC rc = TPM_RC_SUCCESS;
27101   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27102   UINT32 command_size = 10;  // Header size.
27103   std::string handle_section_bytes;
27104   std::string parameter_section_bytes;
27105   TPM_CC command_code = TPM_CC_DictionaryAttackLockReset;
27106   bool is_command_parameter_encryption_possible = false;
27107   bool is_response_parameter_encryption_possible = false;
27108   std::string command_code_bytes;
27109   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27110   if (rc != TPM_RC_SUCCESS) {
27111     return rc;
27112   }
27113   std::string lock_handle_bytes;
27114   rc = Serialize_TPMI_RH_LOCKOUT(lock_handle, &lock_handle_bytes);
27115   if (rc != TPM_RC_SUCCESS) {
27116     return rc;
27117   }
27118   std::unique_ptr<crypto::SecureHash> hash(
27119       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27120   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27121   hash->Update(lock_handle_name.data(), lock_handle_name.size());
27122   handle_section_bytes += lock_handle_bytes;
27123   command_size += lock_handle_bytes.size();
27124   std::string command_hash(32, 0);
27125   hash->Finish(std::data(command_hash), command_hash.size());
27126   std::string authorization_section_bytes;
27127   std::string authorization_size_bytes;
27128   if (authorization_delegate) {
27129     if (!authorization_delegate->GetCommandAuthorization(
27130             command_hash, is_command_parameter_encryption_possible,
27131             is_response_parameter_encryption_possible,
27132             &authorization_section_bytes)) {
27133       return TRUNKS_RC_AUTHORIZATION_FAILED;
27134     }
27135     if (!authorization_section_bytes.empty()) {
27136       tag = TPM_ST_SESSIONS;
27137       std::string tmp;
27138       rc = Serialize_UINT32(authorization_section_bytes.size(),
27139                             &authorization_size_bytes);
27140       if (rc != TPM_RC_SUCCESS) {
27141         return rc;
27142       }
27143       command_size +=
27144           authorization_size_bytes.size() + authorization_section_bytes.size();
27145     }
27146   }
27147   std::string tag_bytes;
27148   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27149   if (rc != TPM_RC_SUCCESS) {
27150     return rc;
27151   }
27152   std::string command_size_bytes;
27153   rc = Serialize_UINT32(command_size, &command_size_bytes);
27154   if (rc != TPM_RC_SUCCESS) {
27155     return rc;
27156   }
27157   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27158                         handle_section_bytes + authorization_size_bytes +
27159                         authorization_section_bytes + parameter_section_bytes;
27160   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27161   VLOG(2) << "Command: "
27162           << base::HexEncode(serialized_command->data(),
27163                              serialized_command->size());
27164   return TPM_RC_SUCCESS;
27165 }
27166 
ParseResponse_DictionaryAttackLockReset(const std::string & response,AuthorizationDelegate * authorization_delegate)27167 TPM_RC Tpm::ParseResponse_DictionaryAttackLockReset(
27168     const std::string& response,
27169     AuthorizationDelegate* authorization_delegate) {
27170   VLOG(3) << __func__;
27171   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27172   TPM_RC rc = TPM_RC_SUCCESS;
27173   std::string buffer(response);
27174   TPM_ST tag;
27175   std::string tag_bytes;
27176   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27177   if (rc != TPM_RC_SUCCESS) {
27178     return rc;
27179   }
27180   UINT32 response_size;
27181   std::string response_size_bytes;
27182   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27183   if (rc != TPM_RC_SUCCESS) {
27184     return rc;
27185   }
27186   TPM_RC response_code;
27187   std::string response_code_bytes;
27188   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27189   if (rc != TPM_RC_SUCCESS) {
27190     return rc;
27191   }
27192   if (response_size != response.size()) {
27193     return TPM_RC_SIZE;
27194   }
27195   if (response_code != TPM_RC_SUCCESS) {
27196     return response_code;
27197   }
27198   TPM_CC command_code = TPM_CC_DictionaryAttackLockReset;
27199   std::string command_code_bytes;
27200   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27201   if (rc != TPM_RC_SUCCESS) {
27202     return rc;
27203   }
27204   std::string authorization_section_bytes;
27205   if (tag == TPM_ST_SESSIONS) {
27206     UINT32 parameter_section_size = buffer.size();
27207     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27208     if (rc != TPM_RC_SUCCESS) {
27209       return rc;
27210     }
27211     if (parameter_section_size > buffer.size()) {
27212       return TPM_RC_INSUFFICIENT;
27213     }
27214     authorization_section_bytes = buffer.substr(parameter_section_size);
27215     // Keep the parameter section in |buffer|.
27216     buffer.erase(parameter_section_size);
27217   }
27218   std::unique_ptr<crypto::SecureHash> hash(
27219       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27220   hash->Update(response_code_bytes.data(), response_code_bytes.size());
27221   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27222   hash->Update(buffer.data(), buffer.size());
27223   std::string response_hash(32, 0);
27224   hash->Finish(std::data(response_hash), response_hash.size());
27225   if (tag == TPM_ST_SESSIONS) {
27226     if (!authorization_delegate)
27227       return TRUNKS_RC_AUTHORIZATION_FAILED;
27228     if (!authorization_delegate->CheckResponseAuthorization(
27229             response_hash, authorization_section_bytes)) {
27230       return TRUNKS_RC_AUTHORIZATION_FAILED;
27231     }
27232   }
27233   return TPM_RC_SUCCESS;
27234 }
27235 
DictionaryAttackLockResetErrorCallback(Tpm::DictionaryAttackLockResetResponse callback,TPM_RC response_code)27236 void DictionaryAttackLockResetErrorCallback(
27237     Tpm::DictionaryAttackLockResetResponse callback, TPM_RC response_code) {
27238   VLOG(1) << __func__;
27239   std::move(callback).Run(response_code);
27240 }
27241 
DictionaryAttackLockResetResponseParser(Tpm::DictionaryAttackLockResetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27242 void DictionaryAttackLockResetResponseParser(
27243     Tpm::DictionaryAttackLockResetResponse callback,
27244     AuthorizationDelegate* authorization_delegate,
27245     const std::string& response) {
27246   VLOG(1) << __func__;
27247   TPM_RC rc = Tpm::ParseResponse_DictionaryAttackLockReset(
27248       response, authorization_delegate);
27249   if (rc != TPM_RC_SUCCESS) {
27250     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27251         DictionaryAttackLockResetErrorCallback, std::move(callback));
27252     std::move(error_reporter).Run(rc);
27253     return;
27254   }
27255   std::move(callback).Run(rc);
27256 }
27257 
DictionaryAttackLockReset(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,AuthorizationDelegate * authorization_delegate,DictionaryAttackLockResetResponse callback)27258 void Tpm::DictionaryAttackLockReset(
27259     const TPMI_RH_LOCKOUT& lock_handle,
27260     const std::string& lock_handle_name,
27261     AuthorizationDelegate* authorization_delegate,
27262     DictionaryAttackLockResetResponse callback) {
27263   VLOG(1) << __func__;
27264   std::string command;
27265   TPM_RC rc = SerializeCommand_DictionaryAttackLockReset(
27266       lock_handle, lock_handle_name, &command, authorization_delegate);
27267   if (rc != TPM_RC_SUCCESS) {
27268     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27269         DictionaryAttackLockResetErrorCallback, std::move(callback));
27270     std::move(error_reporter).Run(rc);
27271     return;
27272   }
27273   base::OnceCallback<void(const std::string&)> parser =
27274       base::BindOnce(DictionaryAttackLockResetResponseParser,
27275                      std::move(callback), authorization_delegate);
27276   transceiver_->SendCommand(command, std::move(parser));
27277 }
27278 
DictionaryAttackLockResetSync(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,AuthorizationDelegate * authorization_delegate)27279 TPM_RC Tpm::DictionaryAttackLockResetSync(
27280     const TPMI_RH_LOCKOUT& lock_handle,
27281     const std::string& lock_handle_name,
27282     AuthorizationDelegate* authorization_delegate) {
27283   VLOG(1) << __func__;
27284   std::string command;
27285   TPM_RC rc = SerializeCommand_DictionaryAttackLockReset(
27286       lock_handle, lock_handle_name, &command, authorization_delegate);
27287   if (rc != TPM_RC_SUCCESS) {
27288     return rc;
27289   }
27290   std::string response = transceiver_->SendCommandAndWait(command);
27291   rc =
27292       ParseResponse_DictionaryAttackLockReset(response, authorization_delegate);
27293   return rc;
27294 }
27295 
SerializeCommand_DictionaryAttackParameters(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,const UINT32 & new_max_tries,const UINT32 & new_recovery_time,const UINT32 & lockout_recovery,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27296 TPM_RC Tpm::SerializeCommand_DictionaryAttackParameters(
27297     const TPMI_RH_LOCKOUT& lock_handle,
27298     const std::string& lock_handle_name,
27299     const UINT32& new_max_tries,
27300     const UINT32& new_recovery_time,
27301     const UINT32& lockout_recovery,
27302     std::string* serialized_command,
27303     AuthorizationDelegate* authorization_delegate) {
27304   VLOG(3) << __func__;
27305   TPM_RC rc = TPM_RC_SUCCESS;
27306   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27307   UINT32 command_size = 10;  // Header size.
27308   std::string handle_section_bytes;
27309   std::string parameter_section_bytes;
27310   TPM_CC command_code = TPM_CC_DictionaryAttackParameters;
27311   bool is_command_parameter_encryption_possible = false;
27312   bool is_response_parameter_encryption_possible = false;
27313   std::string command_code_bytes;
27314   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27315   if (rc != TPM_RC_SUCCESS) {
27316     return rc;
27317   }
27318   std::string lock_handle_bytes;
27319   rc = Serialize_TPMI_RH_LOCKOUT(lock_handle, &lock_handle_bytes);
27320   if (rc != TPM_RC_SUCCESS) {
27321     return rc;
27322   }
27323   std::string new_max_tries_bytes;
27324   rc = Serialize_UINT32(new_max_tries, &new_max_tries_bytes);
27325   if (rc != TPM_RC_SUCCESS) {
27326     return rc;
27327   }
27328   std::string new_recovery_time_bytes;
27329   rc = Serialize_UINT32(new_recovery_time, &new_recovery_time_bytes);
27330   if (rc != TPM_RC_SUCCESS) {
27331     return rc;
27332   }
27333   std::string lockout_recovery_bytes;
27334   rc = Serialize_UINT32(lockout_recovery, &lockout_recovery_bytes);
27335   if (rc != TPM_RC_SUCCESS) {
27336     return rc;
27337   }
27338   std::unique_ptr<crypto::SecureHash> hash(
27339       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27340   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27341   hash->Update(lock_handle_name.data(), lock_handle_name.size());
27342   handle_section_bytes += lock_handle_bytes;
27343   command_size += lock_handle_bytes.size();
27344   hash->Update(new_max_tries_bytes.data(), new_max_tries_bytes.size());
27345   parameter_section_bytes += new_max_tries_bytes;
27346   command_size += new_max_tries_bytes.size();
27347   hash->Update(new_recovery_time_bytes.data(), new_recovery_time_bytes.size());
27348   parameter_section_bytes += new_recovery_time_bytes;
27349   command_size += new_recovery_time_bytes.size();
27350   hash->Update(lockout_recovery_bytes.data(), lockout_recovery_bytes.size());
27351   parameter_section_bytes += lockout_recovery_bytes;
27352   command_size += lockout_recovery_bytes.size();
27353   std::string command_hash(32, 0);
27354   hash->Finish(std::data(command_hash), command_hash.size());
27355   std::string authorization_section_bytes;
27356   std::string authorization_size_bytes;
27357   if (authorization_delegate) {
27358     if (!authorization_delegate->GetCommandAuthorization(
27359             command_hash, is_command_parameter_encryption_possible,
27360             is_response_parameter_encryption_possible,
27361             &authorization_section_bytes)) {
27362       return TRUNKS_RC_AUTHORIZATION_FAILED;
27363     }
27364     if (!authorization_section_bytes.empty()) {
27365       tag = TPM_ST_SESSIONS;
27366       std::string tmp;
27367       rc = Serialize_UINT32(authorization_section_bytes.size(),
27368                             &authorization_size_bytes);
27369       if (rc != TPM_RC_SUCCESS) {
27370         return rc;
27371       }
27372       command_size +=
27373           authorization_size_bytes.size() + authorization_section_bytes.size();
27374     }
27375   }
27376   std::string tag_bytes;
27377   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27378   if (rc != TPM_RC_SUCCESS) {
27379     return rc;
27380   }
27381   std::string command_size_bytes;
27382   rc = Serialize_UINT32(command_size, &command_size_bytes);
27383   if (rc != TPM_RC_SUCCESS) {
27384     return rc;
27385   }
27386   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27387                         handle_section_bytes + authorization_size_bytes +
27388                         authorization_section_bytes + parameter_section_bytes;
27389   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27390   VLOG(2) << "Command: "
27391           << base::HexEncode(serialized_command->data(),
27392                              serialized_command->size());
27393   return TPM_RC_SUCCESS;
27394 }
27395 
ParseResponse_DictionaryAttackParameters(const std::string & response,AuthorizationDelegate * authorization_delegate)27396 TPM_RC Tpm::ParseResponse_DictionaryAttackParameters(
27397     const std::string& response,
27398     AuthorizationDelegate* authorization_delegate) {
27399   VLOG(3) << __func__;
27400   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27401   TPM_RC rc = TPM_RC_SUCCESS;
27402   std::string buffer(response);
27403   TPM_ST tag;
27404   std::string tag_bytes;
27405   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27406   if (rc != TPM_RC_SUCCESS) {
27407     return rc;
27408   }
27409   UINT32 response_size;
27410   std::string response_size_bytes;
27411   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27412   if (rc != TPM_RC_SUCCESS) {
27413     return rc;
27414   }
27415   TPM_RC response_code;
27416   std::string response_code_bytes;
27417   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27418   if (rc != TPM_RC_SUCCESS) {
27419     return rc;
27420   }
27421   if (response_size != response.size()) {
27422     return TPM_RC_SIZE;
27423   }
27424   if (response_code != TPM_RC_SUCCESS) {
27425     return response_code;
27426   }
27427   TPM_CC command_code = TPM_CC_DictionaryAttackParameters;
27428   std::string command_code_bytes;
27429   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27430   if (rc != TPM_RC_SUCCESS) {
27431     return rc;
27432   }
27433   std::string authorization_section_bytes;
27434   if (tag == TPM_ST_SESSIONS) {
27435     UINT32 parameter_section_size = buffer.size();
27436     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27437     if (rc != TPM_RC_SUCCESS) {
27438       return rc;
27439     }
27440     if (parameter_section_size > buffer.size()) {
27441       return TPM_RC_INSUFFICIENT;
27442     }
27443     authorization_section_bytes = buffer.substr(parameter_section_size);
27444     // Keep the parameter section in |buffer|.
27445     buffer.erase(parameter_section_size);
27446   }
27447   std::unique_ptr<crypto::SecureHash> hash(
27448       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27449   hash->Update(response_code_bytes.data(), response_code_bytes.size());
27450   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27451   hash->Update(buffer.data(), buffer.size());
27452   std::string response_hash(32, 0);
27453   hash->Finish(std::data(response_hash), response_hash.size());
27454   if (tag == TPM_ST_SESSIONS) {
27455     if (!authorization_delegate)
27456       return TRUNKS_RC_AUTHORIZATION_FAILED;
27457     if (!authorization_delegate->CheckResponseAuthorization(
27458             response_hash, authorization_section_bytes)) {
27459       return TRUNKS_RC_AUTHORIZATION_FAILED;
27460     }
27461   }
27462   return TPM_RC_SUCCESS;
27463 }
27464 
DictionaryAttackParametersErrorCallback(Tpm::DictionaryAttackParametersResponse callback,TPM_RC response_code)27465 void DictionaryAttackParametersErrorCallback(
27466     Tpm::DictionaryAttackParametersResponse callback, TPM_RC response_code) {
27467   VLOG(1) << __func__;
27468   std::move(callback).Run(response_code);
27469 }
27470 
DictionaryAttackParametersResponseParser(Tpm::DictionaryAttackParametersResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27471 void DictionaryAttackParametersResponseParser(
27472     Tpm::DictionaryAttackParametersResponse callback,
27473     AuthorizationDelegate* authorization_delegate,
27474     const std::string& response) {
27475   VLOG(1) << __func__;
27476   TPM_RC rc = Tpm::ParseResponse_DictionaryAttackParameters(
27477       response, authorization_delegate);
27478   if (rc != TPM_RC_SUCCESS) {
27479     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27480         DictionaryAttackParametersErrorCallback, std::move(callback));
27481     std::move(error_reporter).Run(rc);
27482     return;
27483   }
27484   std::move(callback).Run(rc);
27485 }
27486 
DictionaryAttackParameters(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,const UINT32 & new_max_tries,const UINT32 & new_recovery_time,const UINT32 & lockout_recovery,AuthorizationDelegate * authorization_delegate,DictionaryAttackParametersResponse callback)27487 void Tpm::DictionaryAttackParameters(
27488     const TPMI_RH_LOCKOUT& lock_handle,
27489     const std::string& lock_handle_name,
27490     const UINT32& new_max_tries,
27491     const UINT32& new_recovery_time,
27492     const UINT32& lockout_recovery,
27493     AuthorizationDelegate* authorization_delegate,
27494     DictionaryAttackParametersResponse callback) {
27495   VLOG(1) << __func__;
27496   std::string command;
27497   TPM_RC rc = SerializeCommand_DictionaryAttackParameters(
27498       lock_handle, lock_handle_name, new_max_tries, new_recovery_time,
27499       lockout_recovery, &command, authorization_delegate);
27500   if (rc != TPM_RC_SUCCESS) {
27501     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27502         DictionaryAttackParametersErrorCallback, std::move(callback));
27503     std::move(error_reporter).Run(rc);
27504     return;
27505   }
27506   base::OnceCallback<void(const std::string&)> parser =
27507       base::BindOnce(DictionaryAttackParametersResponseParser,
27508                      std::move(callback), authorization_delegate);
27509   transceiver_->SendCommand(command, std::move(parser));
27510 }
27511 
DictionaryAttackParametersSync(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,const UINT32 & new_max_tries,const UINT32 & new_recovery_time,const UINT32 & lockout_recovery,AuthorizationDelegate * authorization_delegate)27512 TPM_RC Tpm::DictionaryAttackParametersSync(
27513     const TPMI_RH_LOCKOUT& lock_handle,
27514     const std::string& lock_handle_name,
27515     const UINT32& new_max_tries,
27516     const UINT32& new_recovery_time,
27517     const UINT32& lockout_recovery,
27518     AuthorizationDelegate* authorization_delegate) {
27519   VLOG(1) << __func__;
27520   std::string command;
27521   TPM_RC rc = SerializeCommand_DictionaryAttackParameters(
27522       lock_handle, lock_handle_name, new_max_tries, new_recovery_time,
27523       lockout_recovery, &command, authorization_delegate);
27524   if (rc != TPM_RC_SUCCESS) {
27525     return rc;
27526   }
27527   std::string response = transceiver_->SendCommandAndWait(command);
27528   rc = ParseResponse_DictionaryAttackParameters(response,
27529                                                 authorization_delegate);
27530   return rc;
27531 }
27532 
SerializeCommand_PP_Commands(const TPMI_RH_PLATFORM & auth,const std::string & auth_name,const TPML_CC & set_list,const TPML_CC & clear_list,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27533 TPM_RC Tpm::SerializeCommand_PP_Commands(
27534     const TPMI_RH_PLATFORM& auth,
27535     const std::string& auth_name,
27536     const TPML_CC& set_list,
27537     const TPML_CC& clear_list,
27538     std::string* serialized_command,
27539     AuthorizationDelegate* authorization_delegate) {
27540   VLOG(3) << __func__;
27541   TPM_RC rc = TPM_RC_SUCCESS;
27542   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27543   UINT32 command_size = 10;  // Header size.
27544   std::string handle_section_bytes;
27545   std::string parameter_section_bytes;
27546   TPM_CC command_code = TPM_CC_PP_Commands;
27547   bool is_command_parameter_encryption_possible = false;
27548   bool is_response_parameter_encryption_possible = false;
27549   std::string command_code_bytes;
27550   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27551   if (rc != TPM_RC_SUCCESS) {
27552     return rc;
27553   }
27554   std::string auth_bytes;
27555   rc = Serialize_TPMI_RH_PLATFORM(auth, &auth_bytes);
27556   if (rc != TPM_RC_SUCCESS) {
27557     return rc;
27558   }
27559   std::string set_list_bytes;
27560   rc = Serialize_TPML_CC(set_list, &set_list_bytes);
27561   if (rc != TPM_RC_SUCCESS) {
27562     return rc;
27563   }
27564   std::string clear_list_bytes;
27565   rc = Serialize_TPML_CC(clear_list, &clear_list_bytes);
27566   if (rc != TPM_RC_SUCCESS) {
27567     return rc;
27568   }
27569   std::unique_ptr<crypto::SecureHash> hash(
27570       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27571   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27572   hash->Update(auth_name.data(), auth_name.size());
27573   handle_section_bytes += auth_bytes;
27574   command_size += auth_bytes.size();
27575   hash->Update(set_list_bytes.data(), set_list_bytes.size());
27576   parameter_section_bytes += set_list_bytes;
27577   command_size += set_list_bytes.size();
27578   hash->Update(clear_list_bytes.data(), clear_list_bytes.size());
27579   parameter_section_bytes += clear_list_bytes;
27580   command_size += clear_list_bytes.size();
27581   std::string command_hash(32, 0);
27582   hash->Finish(std::data(command_hash), command_hash.size());
27583   std::string authorization_section_bytes;
27584   std::string authorization_size_bytes;
27585   if (authorization_delegate) {
27586     if (!authorization_delegate->GetCommandAuthorization(
27587             command_hash, is_command_parameter_encryption_possible,
27588             is_response_parameter_encryption_possible,
27589             &authorization_section_bytes)) {
27590       return TRUNKS_RC_AUTHORIZATION_FAILED;
27591     }
27592     if (!authorization_section_bytes.empty()) {
27593       tag = TPM_ST_SESSIONS;
27594       std::string tmp;
27595       rc = Serialize_UINT32(authorization_section_bytes.size(),
27596                             &authorization_size_bytes);
27597       if (rc != TPM_RC_SUCCESS) {
27598         return rc;
27599       }
27600       command_size +=
27601           authorization_size_bytes.size() + authorization_section_bytes.size();
27602     }
27603   }
27604   std::string tag_bytes;
27605   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27606   if (rc != TPM_RC_SUCCESS) {
27607     return rc;
27608   }
27609   std::string command_size_bytes;
27610   rc = Serialize_UINT32(command_size, &command_size_bytes);
27611   if (rc != TPM_RC_SUCCESS) {
27612     return rc;
27613   }
27614   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27615                         handle_section_bytes + authorization_size_bytes +
27616                         authorization_section_bytes + parameter_section_bytes;
27617   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27618   VLOG(2) << "Command: "
27619           << base::HexEncode(serialized_command->data(),
27620                              serialized_command->size());
27621   return TPM_RC_SUCCESS;
27622 }
27623 
ParseResponse_PP_Commands(const std::string & response,AuthorizationDelegate * authorization_delegate)27624 TPM_RC Tpm::ParseResponse_PP_Commands(
27625     const std::string& response,
27626     AuthorizationDelegate* authorization_delegate) {
27627   VLOG(3) << __func__;
27628   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27629   TPM_RC rc = TPM_RC_SUCCESS;
27630   std::string buffer(response);
27631   TPM_ST tag;
27632   std::string tag_bytes;
27633   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27634   if (rc != TPM_RC_SUCCESS) {
27635     return rc;
27636   }
27637   UINT32 response_size;
27638   std::string response_size_bytes;
27639   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27640   if (rc != TPM_RC_SUCCESS) {
27641     return rc;
27642   }
27643   TPM_RC response_code;
27644   std::string response_code_bytes;
27645   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27646   if (rc != TPM_RC_SUCCESS) {
27647     return rc;
27648   }
27649   if (response_size != response.size()) {
27650     return TPM_RC_SIZE;
27651   }
27652   if (response_code != TPM_RC_SUCCESS) {
27653     return response_code;
27654   }
27655   TPM_CC command_code = TPM_CC_PP_Commands;
27656   std::string command_code_bytes;
27657   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27658   if (rc != TPM_RC_SUCCESS) {
27659     return rc;
27660   }
27661   std::string authorization_section_bytes;
27662   if (tag == TPM_ST_SESSIONS) {
27663     UINT32 parameter_section_size = buffer.size();
27664     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27665     if (rc != TPM_RC_SUCCESS) {
27666       return rc;
27667     }
27668     if (parameter_section_size > buffer.size()) {
27669       return TPM_RC_INSUFFICIENT;
27670     }
27671     authorization_section_bytes = buffer.substr(parameter_section_size);
27672     // Keep the parameter section in |buffer|.
27673     buffer.erase(parameter_section_size);
27674   }
27675   std::unique_ptr<crypto::SecureHash> hash(
27676       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27677   hash->Update(response_code_bytes.data(), response_code_bytes.size());
27678   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27679   hash->Update(buffer.data(), buffer.size());
27680   std::string response_hash(32, 0);
27681   hash->Finish(std::data(response_hash), response_hash.size());
27682   if (tag == TPM_ST_SESSIONS) {
27683     if (!authorization_delegate)
27684       return TRUNKS_RC_AUTHORIZATION_FAILED;
27685     if (!authorization_delegate->CheckResponseAuthorization(
27686             response_hash, authorization_section_bytes)) {
27687       return TRUNKS_RC_AUTHORIZATION_FAILED;
27688     }
27689   }
27690   return TPM_RC_SUCCESS;
27691 }
27692 
PP_CommandsErrorCallback(Tpm::PP_CommandsResponse callback,TPM_RC response_code)27693 void PP_CommandsErrorCallback(Tpm::PP_CommandsResponse callback,
27694                               TPM_RC response_code) {
27695   VLOG(1) << __func__;
27696   std::move(callback).Run(response_code);
27697 }
27698 
PP_CommandsResponseParser(Tpm::PP_CommandsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27699 void PP_CommandsResponseParser(Tpm::PP_CommandsResponse callback,
27700                                AuthorizationDelegate* authorization_delegate,
27701                                const std::string& response) {
27702   VLOG(1) << __func__;
27703   TPM_RC rc = Tpm::ParseResponse_PP_Commands(response, authorization_delegate);
27704   if (rc != TPM_RC_SUCCESS) {
27705     base::OnceCallback<void(TPM_RC)> error_reporter =
27706         base::BindOnce(PP_CommandsErrorCallback, std::move(callback));
27707     std::move(error_reporter).Run(rc);
27708     return;
27709   }
27710   std::move(callback).Run(rc);
27711 }
27712 
PP_Commands(const TPMI_RH_PLATFORM & auth,const std::string & auth_name,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate,PP_CommandsResponse callback)27713 void Tpm::PP_Commands(const TPMI_RH_PLATFORM& auth,
27714                       const std::string& auth_name,
27715                       const TPML_CC& set_list,
27716                       const TPML_CC& clear_list,
27717                       AuthorizationDelegate* authorization_delegate,
27718                       PP_CommandsResponse callback) {
27719   VLOG(1) << __func__;
27720   std::string command;
27721   TPM_RC rc = SerializeCommand_PP_Commands(
27722       auth, auth_name, set_list, clear_list, &command, authorization_delegate);
27723   if (rc != TPM_RC_SUCCESS) {
27724     base::OnceCallback<void(TPM_RC)> error_reporter =
27725         base::BindOnce(PP_CommandsErrorCallback, std::move(callback));
27726     std::move(error_reporter).Run(rc);
27727     return;
27728   }
27729   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
27730       PP_CommandsResponseParser, std::move(callback), authorization_delegate);
27731   transceiver_->SendCommand(command, std::move(parser));
27732 }
27733 
PP_CommandsSync(const TPMI_RH_PLATFORM & auth,const std::string & auth_name,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate)27734 TPM_RC Tpm::PP_CommandsSync(const TPMI_RH_PLATFORM& auth,
27735                             const std::string& auth_name,
27736                             const TPML_CC& set_list,
27737                             const TPML_CC& clear_list,
27738                             AuthorizationDelegate* authorization_delegate) {
27739   VLOG(1) << __func__;
27740   std::string command;
27741   TPM_RC rc = SerializeCommand_PP_Commands(
27742       auth, auth_name, set_list, clear_list, &command, authorization_delegate);
27743   if (rc != TPM_RC_SUCCESS) {
27744     return rc;
27745   }
27746   std::string response = transceiver_->SendCommandAndWait(command);
27747   rc = ParseResponse_PP_Commands(response, authorization_delegate);
27748   return rc;
27749 }
27750 
SerializeCommand_SetAlgorithmSet(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27751 TPM_RC Tpm::SerializeCommand_SetAlgorithmSet(
27752     const TPMI_RH_PLATFORM& auth_handle,
27753     const std::string& auth_handle_name,
27754     const UINT32& algorithm_set,
27755     std::string* serialized_command,
27756     AuthorizationDelegate* authorization_delegate) {
27757   VLOG(3) << __func__;
27758   TPM_RC rc = TPM_RC_SUCCESS;
27759   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27760   UINT32 command_size = 10;  // Header size.
27761   std::string handle_section_bytes;
27762   std::string parameter_section_bytes;
27763   TPM_CC command_code = TPM_CC_SetAlgorithmSet;
27764   bool is_command_parameter_encryption_possible = false;
27765   bool is_response_parameter_encryption_possible = false;
27766   std::string command_code_bytes;
27767   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27768   if (rc != TPM_RC_SUCCESS) {
27769     return rc;
27770   }
27771   std::string auth_handle_bytes;
27772   rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
27773   if (rc != TPM_RC_SUCCESS) {
27774     return rc;
27775   }
27776   std::string algorithm_set_bytes;
27777   rc = Serialize_UINT32(algorithm_set, &algorithm_set_bytes);
27778   if (rc != TPM_RC_SUCCESS) {
27779     return rc;
27780   }
27781   std::unique_ptr<crypto::SecureHash> hash(
27782       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27783   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27784   hash->Update(auth_handle_name.data(), auth_handle_name.size());
27785   handle_section_bytes += auth_handle_bytes;
27786   command_size += auth_handle_bytes.size();
27787   hash->Update(algorithm_set_bytes.data(), algorithm_set_bytes.size());
27788   parameter_section_bytes += algorithm_set_bytes;
27789   command_size += algorithm_set_bytes.size();
27790   std::string command_hash(32, 0);
27791   hash->Finish(std::data(command_hash), command_hash.size());
27792   std::string authorization_section_bytes;
27793   std::string authorization_size_bytes;
27794   if (authorization_delegate) {
27795     if (!authorization_delegate->GetCommandAuthorization(
27796             command_hash, is_command_parameter_encryption_possible,
27797             is_response_parameter_encryption_possible,
27798             &authorization_section_bytes)) {
27799       return TRUNKS_RC_AUTHORIZATION_FAILED;
27800     }
27801     if (!authorization_section_bytes.empty()) {
27802       tag = TPM_ST_SESSIONS;
27803       std::string tmp;
27804       rc = Serialize_UINT32(authorization_section_bytes.size(),
27805                             &authorization_size_bytes);
27806       if (rc != TPM_RC_SUCCESS) {
27807         return rc;
27808       }
27809       command_size +=
27810           authorization_size_bytes.size() + authorization_section_bytes.size();
27811     }
27812   }
27813   std::string tag_bytes;
27814   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27815   if (rc != TPM_RC_SUCCESS) {
27816     return rc;
27817   }
27818   std::string command_size_bytes;
27819   rc = Serialize_UINT32(command_size, &command_size_bytes);
27820   if (rc != TPM_RC_SUCCESS) {
27821     return rc;
27822   }
27823   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27824                         handle_section_bytes + authorization_size_bytes +
27825                         authorization_section_bytes + parameter_section_bytes;
27826   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27827   VLOG(2) << "Command: "
27828           << base::HexEncode(serialized_command->data(),
27829                              serialized_command->size());
27830   return TPM_RC_SUCCESS;
27831 }
27832 
ParseResponse_SetAlgorithmSet(const std::string & response,AuthorizationDelegate * authorization_delegate)27833 TPM_RC Tpm::ParseResponse_SetAlgorithmSet(
27834     const std::string& response,
27835     AuthorizationDelegate* authorization_delegate) {
27836   VLOG(3) << __func__;
27837   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27838   TPM_RC rc = TPM_RC_SUCCESS;
27839   std::string buffer(response);
27840   TPM_ST tag;
27841   std::string tag_bytes;
27842   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27843   if (rc != TPM_RC_SUCCESS) {
27844     return rc;
27845   }
27846   UINT32 response_size;
27847   std::string response_size_bytes;
27848   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27849   if (rc != TPM_RC_SUCCESS) {
27850     return rc;
27851   }
27852   TPM_RC response_code;
27853   std::string response_code_bytes;
27854   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27855   if (rc != TPM_RC_SUCCESS) {
27856     return rc;
27857   }
27858   if (response_size != response.size()) {
27859     return TPM_RC_SIZE;
27860   }
27861   if (response_code != TPM_RC_SUCCESS) {
27862     return response_code;
27863   }
27864   TPM_CC command_code = TPM_CC_SetAlgorithmSet;
27865   std::string command_code_bytes;
27866   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27867   if (rc != TPM_RC_SUCCESS) {
27868     return rc;
27869   }
27870   std::string authorization_section_bytes;
27871   if (tag == TPM_ST_SESSIONS) {
27872     UINT32 parameter_section_size = buffer.size();
27873     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27874     if (rc != TPM_RC_SUCCESS) {
27875       return rc;
27876     }
27877     if (parameter_section_size > buffer.size()) {
27878       return TPM_RC_INSUFFICIENT;
27879     }
27880     authorization_section_bytes = buffer.substr(parameter_section_size);
27881     // Keep the parameter section in |buffer|.
27882     buffer.erase(parameter_section_size);
27883   }
27884   std::unique_ptr<crypto::SecureHash> hash(
27885       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27886   hash->Update(response_code_bytes.data(), response_code_bytes.size());
27887   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27888   hash->Update(buffer.data(), buffer.size());
27889   std::string response_hash(32, 0);
27890   hash->Finish(std::data(response_hash), response_hash.size());
27891   if (tag == TPM_ST_SESSIONS) {
27892     if (!authorization_delegate)
27893       return TRUNKS_RC_AUTHORIZATION_FAILED;
27894     if (!authorization_delegate->CheckResponseAuthorization(
27895             response_hash, authorization_section_bytes)) {
27896       return TRUNKS_RC_AUTHORIZATION_FAILED;
27897     }
27898   }
27899   return TPM_RC_SUCCESS;
27900 }
27901 
SetAlgorithmSetErrorCallback(Tpm::SetAlgorithmSetResponse callback,TPM_RC response_code)27902 void SetAlgorithmSetErrorCallback(Tpm::SetAlgorithmSetResponse callback,
27903                                   TPM_RC response_code) {
27904   VLOG(1) << __func__;
27905   std::move(callback).Run(response_code);
27906 }
27907 
SetAlgorithmSetResponseParser(Tpm::SetAlgorithmSetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27908 void SetAlgorithmSetResponseParser(
27909     Tpm::SetAlgorithmSetResponse callback,
27910     AuthorizationDelegate* authorization_delegate,
27911     const std::string& response) {
27912   VLOG(1) << __func__;
27913   TPM_RC rc =
27914       Tpm::ParseResponse_SetAlgorithmSet(response, authorization_delegate);
27915   if (rc != TPM_RC_SUCCESS) {
27916     base::OnceCallback<void(TPM_RC)> error_reporter =
27917         base::BindOnce(SetAlgorithmSetErrorCallback, std::move(callback));
27918     std::move(error_reporter).Run(rc);
27919     return;
27920   }
27921   std::move(callback).Run(rc);
27922 }
27923 
SetAlgorithmSet(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,AuthorizationDelegate * authorization_delegate,SetAlgorithmSetResponse callback)27924 void Tpm::SetAlgorithmSet(const TPMI_RH_PLATFORM& auth_handle,
27925                           const std::string& auth_handle_name,
27926                           const UINT32& algorithm_set,
27927                           AuthorizationDelegate* authorization_delegate,
27928                           SetAlgorithmSetResponse callback) {
27929   VLOG(1) << __func__;
27930   std::string command;
27931   TPM_RC rc = SerializeCommand_SetAlgorithmSet(auth_handle, auth_handle_name,
27932                                                algorithm_set, &command,
27933                                                authorization_delegate);
27934   if (rc != TPM_RC_SUCCESS) {
27935     base::OnceCallback<void(TPM_RC)> error_reporter =
27936         base::BindOnce(SetAlgorithmSetErrorCallback, std::move(callback));
27937     std::move(error_reporter).Run(rc);
27938     return;
27939   }
27940   base::OnceCallback<void(const std::string&)> parser =
27941       base::BindOnce(SetAlgorithmSetResponseParser, std::move(callback),
27942                      authorization_delegate);
27943   transceiver_->SendCommand(command, std::move(parser));
27944 }
27945 
SetAlgorithmSetSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,AuthorizationDelegate * authorization_delegate)27946 TPM_RC Tpm::SetAlgorithmSetSync(const TPMI_RH_PLATFORM& auth_handle,
27947                                 const std::string& auth_handle_name,
27948                                 const UINT32& algorithm_set,
27949                                 AuthorizationDelegate* authorization_delegate) {
27950   VLOG(1) << __func__;
27951   std::string command;
27952   TPM_RC rc = SerializeCommand_SetAlgorithmSet(auth_handle, auth_handle_name,
27953                                                algorithm_set, &command,
27954                                                authorization_delegate);
27955   if (rc != TPM_RC_SUCCESS) {
27956     return rc;
27957   }
27958   std::string response = transceiver_->SendCommandAndWait(command);
27959   rc = ParseResponse_SetAlgorithmSet(response, authorization_delegate);
27960   return rc;
27961 }
27962 
SerializeCommand_FieldUpgradeStart(const TPMI_RH_PLATFORM & authorization,const std::string & authorization_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & fu_digest,const TPMT_SIGNATURE & manifest_signature,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27963 TPM_RC Tpm::SerializeCommand_FieldUpgradeStart(
27964     const TPMI_RH_PLATFORM& authorization,
27965     const std::string& authorization_name,
27966     const TPMI_DH_OBJECT& key_handle,
27967     const std::string& key_handle_name,
27968     const TPM2B_DIGEST& fu_digest,
27969     const TPMT_SIGNATURE& manifest_signature,
27970     std::string* serialized_command,
27971     AuthorizationDelegate* authorization_delegate) {
27972   VLOG(3) << __func__;
27973   TPM_RC rc = TPM_RC_SUCCESS;
27974   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27975   UINT32 command_size = 10;  // Header size.
27976   std::string handle_section_bytes;
27977   std::string parameter_section_bytes;
27978   TPM_CC command_code = TPM_CC_FieldUpgradeStart;
27979   bool is_command_parameter_encryption_possible = true;
27980   bool is_response_parameter_encryption_possible = false;
27981   std::string command_code_bytes;
27982   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27983   if (rc != TPM_RC_SUCCESS) {
27984     return rc;
27985   }
27986   std::string authorization_bytes;
27987   rc = Serialize_TPMI_RH_PLATFORM(authorization, &authorization_bytes);
27988   if (rc != TPM_RC_SUCCESS) {
27989     return rc;
27990   }
27991   std::string key_handle_bytes;
27992   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
27993   if (rc != TPM_RC_SUCCESS) {
27994     return rc;
27995   }
27996   std::string fu_digest_bytes;
27997   rc = Serialize_TPM2B_DIGEST(fu_digest, &fu_digest_bytes);
27998   if (rc != TPM_RC_SUCCESS) {
27999     return rc;
28000   }
28001   std::string manifest_signature_bytes;
28002   rc = Serialize_TPMT_SIGNATURE(manifest_signature, &manifest_signature_bytes);
28003   if (rc != TPM_RC_SUCCESS) {
28004     return rc;
28005   }
28006   if (authorization_delegate) {
28007     // Encrypt just the parameter data, not the size.
28008     std::string tmp = fu_digest_bytes.substr(2);
28009     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
28010       return TRUNKS_RC_ENCRYPTION_FAILED;
28011     }
28012     fu_digest_bytes.replace(2, std::string::npos, tmp);
28013   }
28014   std::unique_ptr<crypto::SecureHash> hash(
28015       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28016   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28017   hash->Update(authorization_name.data(), authorization_name.size());
28018   handle_section_bytes += authorization_bytes;
28019   command_size += authorization_bytes.size();
28020   hash->Update(key_handle_name.data(), key_handle_name.size());
28021   handle_section_bytes += key_handle_bytes;
28022   command_size += key_handle_bytes.size();
28023   hash->Update(fu_digest_bytes.data(), fu_digest_bytes.size());
28024   parameter_section_bytes += fu_digest_bytes;
28025   command_size += fu_digest_bytes.size();
28026   hash->Update(manifest_signature_bytes.data(),
28027                manifest_signature_bytes.size());
28028   parameter_section_bytes += manifest_signature_bytes;
28029   command_size += manifest_signature_bytes.size();
28030   std::string command_hash(32, 0);
28031   hash->Finish(std::data(command_hash), command_hash.size());
28032   std::string authorization_section_bytes;
28033   std::string authorization_size_bytes;
28034   if (authorization_delegate) {
28035     if (!authorization_delegate->GetCommandAuthorization(
28036             command_hash, is_command_parameter_encryption_possible,
28037             is_response_parameter_encryption_possible,
28038             &authorization_section_bytes)) {
28039       return TRUNKS_RC_AUTHORIZATION_FAILED;
28040     }
28041     if (!authorization_section_bytes.empty()) {
28042       tag = TPM_ST_SESSIONS;
28043       std::string tmp;
28044       rc = Serialize_UINT32(authorization_section_bytes.size(),
28045                             &authorization_size_bytes);
28046       if (rc != TPM_RC_SUCCESS) {
28047         return rc;
28048       }
28049       command_size +=
28050           authorization_size_bytes.size() + authorization_section_bytes.size();
28051     }
28052   }
28053   std::string tag_bytes;
28054   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28055   if (rc != TPM_RC_SUCCESS) {
28056     return rc;
28057   }
28058   std::string command_size_bytes;
28059   rc = Serialize_UINT32(command_size, &command_size_bytes);
28060   if (rc != TPM_RC_SUCCESS) {
28061     return rc;
28062   }
28063   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28064                         handle_section_bytes + authorization_size_bytes +
28065                         authorization_section_bytes + parameter_section_bytes;
28066   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28067   VLOG(2) << "Command: "
28068           << base::HexEncode(serialized_command->data(),
28069                              serialized_command->size());
28070   return TPM_RC_SUCCESS;
28071 }
28072 
ParseResponse_FieldUpgradeStart(const std::string & response,AuthorizationDelegate * authorization_delegate)28073 TPM_RC Tpm::ParseResponse_FieldUpgradeStart(
28074     const std::string& response,
28075     AuthorizationDelegate* authorization_delegate) {
28076   VLOG(3) << __func__;
28077   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28078   TPM_RC rc = TPM_RC_SUCCESS;
28079   std::string buffer(response);
28080   TPM_ST tag;
28081   std::string tag_bytes;
28082   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28083   if (rc != TPM_RC_SUCCESS) {
28084     return rc;
28085   }
28086   UINT32 response_size;
28087   std::string response_size_bytes;
28088   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28089   if (rc != TPM_RC_SUCCESS) {
28090     return rc;
28091   }
28092   TPM_RC response_code;
28093   std::string response_code_bytes;
28094   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28095   if (rc != TPM_RC_SUCCESS) {
28096     return rc;
28097   }
28098   if (response_size != response.size()) {
28099     return TPM_RC_SIZE;
28100   }
28101   if (response_code != TPM_RC_SUCCESS) {
28102     return response_code;
28103   }
28104   TPM_CC command_code = TPM_CC_FieldUpgradeStart;
28105   std::string command_code_bytes;
28106   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28107   if (rc != TPM_RC_SUCCESS) {
28108     return rc;
28109   }
28110   std::string authorization_section_bytes;
28111   if (tag == TPM_ST_SESSIONS) {
28112     UINT32 parameter_section_size = buffer.size();
28113     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28114     if (rc != TPM_RC_SUCCESS) {
28115       return rc;
28116     }
28117     if (parameter_section_size > buffer.size()) {
28118       return TPM_RC_INSUFFICIENT;
28119     }
28120     authorization_section_bytes = buffer.substr(parameter_section_size);
28121     // Keep the parameter section in |buffer|.
28122     buffer.erase(parameter_section_size);
28123   }
28124   std::unique_ptr<crypto::SecureHash> hash(
28125       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28126   hash->Update(response_code_bytes.data(), response_code_bytes.size());
28127   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28128   hash->Update(buffer.data(), buffer.size());
28129   std::string response_hash(32, 0);
28130   hash->Finish(std::data(response_hash), response_hash.size());
28131   if (tag == TPM_ST_SESSIONS) {
28132     if (!authorization_delegate)
28133       return TRUNKS_RC_AUTHORIZATION_FAILED;
28134     if (!authorization_delegate->CheckResponseAuthorization(
28135             response_hash, authorization_section_bytes)) {
28136       return TRUNKS_RC_AUTHORIZATION_FAILED;
28137     }
28138   }
28139   return TPM_RC_SUCCESS;
28140 }
28141 
FieldUpgradeStartErrorCallback(Tpm::FieldUpgradeStartResponse callback,TPM_RC response_code)28142 void FieldUpgradeStartErrorCallback(Tpm::FieldUpgradeStartResponse callback,
28143                                     TPM_RC response_code) {
28144   VLOG(1) << __func__;
28145   std::move(callback).Run(response_code);
28146 }
28147 
FieldUpgradeStartResponseParser(Tpm::FieldUpgradeStartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28148 void FieldUpgradeStartResponseParser(
28149     Tpm::FieldUpgradeStartResponse callback,
28150     AuthorizationDelegate* authorization_delegate,
28151     const std::string& response) {
28152   VLOG(1) << __func__;
28153   TPM_RC rc =
28154       Tpm::ParseResponse_FieldUpgradeStart(response, authorization_delegate);
28155   if (rc != TPM_RC_SUCCESS) {
28156     base::OnceCallback<void(TPM_RC)> error_reporter =
28157         base::BindOnce(FieldUpgradeStartErrorCallback, std::move(callback));
28158     std::move(error_reporter).Run(rc);
28159     return;
28160   }
28161   std::move(callback).Run(rc);
28162 }
28163 
FieldUpgradeStart(const TPMI_RH_PLATFORM & authorization,const std::string & authorization_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & fu_digest,const TPMT_SIGNATURE & manifest_signature,AuthorizationDelegate * authorization_delegate,FieldUpgradeStartResponse callback)28164 void Tpm::FieldUpgradeStart(const TPMI_RH_PLATFORM& authorization,
28165                             const std::string& authorization_name,
28166                             const TPMI_DH_OBJECT& key_handle,
28167                             const std::string& key_handle_name,
28168                             const TPM2B_DIGEST& fu_digest,
28169                             const TPMT_SIGNATURE& manifest_signature,
28170                             AuthorizationDelegate* authorization_delegate,
28171                             FieldUpgradeStartResponse callback) {
28172   VLOG(1) << __func__;
28173   std::string command;
28174   TPM_RC rc = SerializeCommand_FieldUpgradeStart(
28175       authorization, authorization_name, key_handle, key_handle_name, fu_digest,
28176       manifest_signature, &command, authorization_delegate);
28177   if (rc != TPM_RC_SUCCESS) {
28178     base::OnceCallback<void(TPM_RC)> error_reporter =
28179         base::BindOnce(FieldUpgradeStartErrorCallback, std::move(callback));
28180     std::move(error_reporter).Run(rc);
28181     return;
28182   }
28183   base::OnceCallback<void(const std::string&)> parser =
28184       base::BindOnce(FieldUpgradeStartResponseParser, std::move(callback),
28185                      authorization_delegate);
28186   transceiver_->SendCommand(command, std::move(parser));
28187 }
28188 
FieldUpgradeStartSync(const TPMI_RH_PLATFORM & authorization,const std::string & authorization_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & fu_digest,const TPMT_SIGNATURE & manifest_signature,AuthorizationDelegate * authorization_delegate)28189 TPM_RC Tpm::FieldUpgradeStartSync(
28190     const TPMI_RH_PLATFORM& authorization,
28191     const std::string& authorization_name,
28192     const TPMI_DH_OBJECT& key_handle,
28193     const std::string& key_handle_name,
28194     const TPM2B_DIGEST& fu_digest,
28195     const TPMT_SIGNATURE& manifest_signature,
28196     AuthorizationDelegate* authorization_delegate) {
28197   VLOG(1) << __func__;
28198   std::string command;
28199   TPM_RC rc = SerializeCommand_FieldUpgradeStart(
28200       authorization, authorization_name, key_handle, key_handle_name, fu_digest,
28201       manifest_signature, &command, authorization_delegate);
28202   if (rc != TPM_RC_SUCCESS) {
28203     return rc;
28204   }
28205   std::string response = transceiver_->SendCommandAndWait(command);
28206   rc = ParseResponse_FieldUpgradeStart(response, authorization_delegate);
28207   return rc;
28208 }
28209 
SerializeCommand_FieldUpgradeData(const TPM2B_MAX_BUFFER & fu_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28210 TPM_RC Tpm::SerializeCommand_FieldUpgradeData(
28211     const TPM2B_MAX_BUFFER& fu_data,
28212     std::string* serialized_command,
28213     AuthorizationDelegate* authorization_delegate) {
28214   VLOG(3) << __func__;
28215   TPM_RC rc = TPM_RC_SUCCESS;
28216   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28217   UINT32 command_size = 10;  // Header size.
28218   std::string handle_section_bytes;
28219   std::string parameter_section_bytes;
28220   TPM_CC command_code = TPM_CC_FieldUpgradeData;
28221   bool is_command_parameter_encryption_possible = true;
28222   bool is_response_parameter_encryption_possible = false;
28223   std::string command_code_bytes;
28224   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28225   if (rc != TPM_RC_SUCCESS) {
28226     return rc;
28227   }
28228   std::string fu_data_bytes;
28229   rc = Serialize_TPM2B_MAX_BUFFER(fu_data, &fu_data_bytes);
28230   if (rc != TPM_RC_SUCCESS) {
28231     return rc;
28232   }
28233   if (authorization_delegate) {
28234     // Encrypt just the parameter data, not the size.
28235     std::string tmp = fu_data_bytes.substr(2);
28236     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
28237       return TRUNKS_RC_ENCRYPTION_FAILED;
28238     }
28239     fu_data_bytes.replace(2, std::string::npos, tmp);
28240   }
28241   std::unique_ptr<crypto::SecureHash> hash(
28242       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28243   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28244   hash->Update(fu_data_bytes.data(), fu_data_bytes.size());
28245   parameter_section_bytes += fu_data_bytes;
28246   command_size += fu_data_bytes.size();
28247   std::string command_hash(32, 0);
28248   hash->Finish(std::data(command_hash), command_hash.size());
28249   std::string authorization_section_bytes;
28250   std::string authorization_size_bytes;
28251   if (authorization_delegate) {
28252     if (!authorization_delegate->GetCommandAuthorization(
28253             command_hash, is_command_parameter_encryption_possible,
28254             is_response_parameter_encryption_possible,
28255             &authorization_section_bytes)) {
28256       return TRUNKS_RC_AUTHORIZATION_FAILED;
28257     }
28258     if (!authorization_section_bytes.empty()) {
28259       tag = TPM_ST_SESSIONS;
28260       std::string tmp;
28261       rc = Serialize_UINT32(authorization_section_bytes.size(),
28262                             &authorization_size_bytes);
28263       if (rc != TPM_RC_SUCCESS) {
28264         return rc;
28265       }
28266       command_size +=
28267           authorization_size_bytes.size() + authorization_section_bytes.size();
28268     }
28269   }
28270   std::string tag_bytes;
28271   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28272   if (rc != TPM_RC_SUCCESS) {
28273     return rc;
28274   }
28275   std::string command_size_bytes;
28276   rc = Serialize_UINT32(command_size, &command_size_bytes);
28277   if (rc != TPM_RC_SUCCESS) {
28278     return rc;
28279   }
28280   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28281                         handle_section_bytes + authorization_size_bytes +
28282                         authorization_section_bytes + parameter_section_bytes;
28283   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28284   VLOG(2) << "Command: "
28285           << base::HexEncode(serialized_command->data(),
28286                              serialized_command->size());
28287   return TPM_RC_SUCCESS;
28288 }
28289 
ParseResponse_FieldUpgradeData(const std::string & response,TPMT_HA * next_digest,TPMT_HA * first_digest,AuthorizationDelegate * authorization_delegate)28290 TPM_RC Tpm::ParseResponse_FieldUpgradeData(
28291     const std::string& response,
28292     TPMT_HA* next_digest,
28293     TPMT_HA* first_digest,
28294     AuthorizationDelegate* authorization_delegate) {
28295   VLOG(3) << __func__;
28296   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28297   TPM_RC rc = TPM_RC_SUCCESS;
28298   std::string buffer(response);
28299   TPM_ST tag;
28300   std::string tag_bytes;
28301   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28302   if (rc != TPM_RC_SUCCESS) {
28303     return rc;
28304   }
28305   UINT32 response_size;
28306   std::string response_size_bytes;
28307   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28308   if (rc != TPM_RC_SUCCESS) {
28309     return rc;
28310   }
28311   TPM_RC response_code;
28312   std::string response_code_bytes;
28313   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28314   if (rc != TPM_RC_SUCCESS) {
28315     return rc;
28316   }
28317   if (response_size != response.size()) {
28318     return TPM_RC_SIZE;
28319   }
28320   if (response_code != TPM_RC_SUCCESS) {
28321     return response_code;
28322   }
28323   TPM_CC command_code = TPM_CC_FieldUpgradeData;
28324   std::string command_code_bytes;
28325   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28326   if (rc != TPM_RC_SUCCESS) {
28327     return rc;
28328   }
28329   std::string authorization_section_bytes;
28330   if (tag == TPM_ST_SESSIONS) {
28331     UINT32 parameter_section_size = buffer.size();
28332     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28333     if (rc != TPM_RC_SUCCESS) {
28334       return rc;
28335     }
28336     if (parameter_section_size > buffer.size()) {
28337       return TPM_RC_INSUFFICIENT;
28338     }
28339     authorization_section_bytes = buffer.substr(parameter_section_size);
28340     // Keep the parameter section in |buffer|.
28341     buffer.erase(parameter_section_size);
28342   }
28343   std::unique_ptr<crypto::SecureHash> hash(
28344       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28345   hash->Update(response_code_bytes.data(), response_code_bytes.size());
28346   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28347   hash->Update(buffer.data(), buffer.size());
28348   std::string response_hash(32, 0);
28349   hash->Finish(std::data(response_hash), response_hash.size());
28350   if (tag == TPM_ST_SESSIONS) {
28351     if (!authorization_delegate)
28352       return TRUNKS_RC_AUTHORIZATION_FAILED;
28353     if (!authorization_delegate->CheckResponseAuthorization(
28354             response_hash, authorization_section_bytes)) {
28355       return TRUNKS_RC_AUTHORIZATION_FAILED;
28356     }
28357   }
28358   std::string next_digest_bytes;
28359   rc = Parse_TPMT_HA(&buffer, next_digest, &next_digest_bytes);
28360   if (rc != TPM_RC_SUCCESS) {
28361     return rc;
28362   }
28363   std::string first_digest_bytes;
28364   rc = Parse_TPMT_HA(&buffer, first_digest, &first_digest_bytes);
28365   if (rc != TPM_RC_SUCCESS) {
28366     return rc;
28367   }
28368   return TPM_RC_SUCCESS;
28369 }
28370 
FieldUpgradeDataErrorCallback(Tpm::FieldUpgradeDataResponse callback,TPM_RC response_code)28371 void FieldUpgradeDataErrorCallback(Tpm::FieldUpgradeDataResponse callback,
28372                                    TPM_RC response_code) {
28373   VLOG(1) << __func__;
28374   std::move(callback).Run(response_code, TPMT_HA(), TPMT_HA());
28375 }
28376 
FieldUpgradeDataResponseParser(Tpm::FieldUpgradeDataResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28377 void FieldUpgradeDataResponseParser(
28378     Tpm::FieldUpgradeDataResponse callback,
28379     AuthorizationDelegate* authorization_delegate,
28380     const std::string& response) {
28381   VLOG(1) << __func__;
28382   TPMT_HA next_digest;
28383   TPMT_HA first_digest;
28384   TPM_RC rc = Tpm::ParseResponse_FieldUpgradeData(
28385       response, &next_digest, &first_digest, authorization_delegate);
28386   if (rc != TPM_RC_SUCCESS) {
28387     base::OnceCallback<void(TPM_RC)> error_reporter =
28388         base::BindOnce(FieldUpgradeDataErrorCallback, std::move(callback));
28389     std::move(error_reporter).Run(rc);
28390     return;
28391   }
28392   std::move(callback).Run(rc, next_digest, first_digest);
28393 }
28394 
FieldUpgradeData(const TPM2B_MAX_BUFFER & fu_data,AuthorizationDelegate * authorization_delegate,FieldUpgradeDataResponse callback)28395 void Tpm::FieldUpgradeData(const TPM2B_MAX_BUFFER& fu_data,
28396                            AuthorizationDelegate* authorization_delegate,
28397                            FieldUpgradeDataResponse callback) {
28398   VLOG(1) << __func__;
28399   std::string command;
28400   TPM_RC rc = SerializeCommand_FieldUpgradeData(fu_data, &command,
28401                                                 authorization_delegate);
28402   if (rc != TPM_RC_SUCCESS) {
28403     base::OnceCallback<void(TPM_RC)> error_reporter =
28404         base::BindOnce(FieldUpgradeDataErrorCallback, std::move(callback));
28405     std::move(error_reporter).Run(rc);
28406     return;
28407   }
28408   base::OnceCallback<void(const std::string&)> parser =
28409       base::BindOnce(FieldUpgradeDataResponseParser, std::move(callback),
28410                      authorization_delegate);
28411   transceiver_->SendCommand(command, std::move(parser));
28412 }
28413 
FieldUpgradeDataSync(const TPM2B_MAX_BUFFER & fu_data,TPMT_HA * next_digest,TPMT_HA * first_digest,AuthorizationDelegate * authorization_delegate)28414 TPM_RC Tpm::FieldUpgradeDataSync(
28415     const TPM2B_MAX_BUFFER& fu_data,
28416     TPMT_HA* next_digest,
28417     TPMT_HA* first_digest,
28418     AuthorizationDelegate* authorization_delegate) {
28419   VLOG(1) << __func__;
28420   std::string command;
28421   TPM_RC rc = SerializeCommand_FieldUpgradeData(fu_data, &command,
28422                                                 authorization_delegate);
28423   if (rc != TPM_RC_SUCCESS) {
28424     return rc;
28425   }
28426   std::string response = transceiver_->SendCommandAndWait(command);
28427   rc = ParseResponse_FieldUpgradeData(response, next_digest, first_digest,
28428                                       authorization_delegate);
28429   return rc;
28430 }
28431 
SerializeCommand_FirmwareRead(const UINT32 & sequence_number,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28432 TPM_RC Tpm::SerializeCommand_FirmwareRead(
28433     const UINT32& sequence_number,
28434     std::string* serialized_command,
28435     AuthorizationDelegate* authorization_delegate) {
28436   VLOG(3) << __func__;
28437   TPM_RC rc = TPM_RC_SUCCESS;
28438   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28439   UINT32 command_size = 10;  // Header size.
28440   std::string handle_section_bytes;
28441   std::string parameter_section_bytes;
28442   TPM_CC command_code = TPM_CC_FirmwareRead;
28443   bool is_command_parameter_encryption_possible = false;
28444   bool is_response_parameter_encryption_possible = true;
28445   std::string command_code_bytes;
28446   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28447   if (rc != TPM_RC_SUCCESS) {
28448     return rc;
28449   }
28450   std::string sequence_number_bytes;
28451   rc = Serialize_UINT32(sequence_number, &sequence_number_bytes);
28452   if (rc != TPM_RC_SUCCESS) {
28453     return rc;
28454   }
28455   std::unique_ptr<crypto::SecureHash> hash(
28456       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28457   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28458   hash->Update(sequence_number_bytes.data(), sequence_number_bytes.size());
28459   parameter_section_bytes += sequence_number_bytes;
28460   command_size += sequence_number_bytes.size();
28461   std::string command_hash(32, 0);
28462   hash->Finish(std::data(command_hash), command_hash.size());
28463   std::string authorization_section_bytes;
28464   std::string authorization_size_bytes;
28465   if (authorization_delegate) {
28466     if (!authorization_delegate->GetCommandAuthorization(
28467             command_hash, is_command_parameter_encryption_possible,
28468             is_response_parameter_encryption_possible,
28469             &authorization_section_bytes)) {
28470       return TRUNKS_RC_AUTHORIZATION_FAILED;
28471     }
28472     if (!authorization_section_bytes.empty()) {
28473       tag = TPM_ST_SESSIONS;
28474       std::string tmp;
28475       rc = Serialize_UINT32(authorization_section_bytes.size(),
28476                             &authorization_size_bytes);
28477       if (rc != TPM_RC_SUCCESS) {
28478         return rc;
28479       }
28480       command_size +=
28481           authorization_size_bytes.size() + authorization_section_bytes.size();
28482     }
28483   }
28484   std::string tag_bytes;
28485   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28486   if (rc != TPM_RC_SUCCESS) {
28487     return rc;
28488   }
28489   std::string command_size_bytes;
28490   rc = Serialize_UINT32(command_size, &command_size_bytes);
28491   if (rc != TPM_RC_SUCCESS) {
28492     return rc;
28493   }
28494   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28495                         handle_section_bytes + authorization_size_bytes +
28496                         authorization_section_bytes + parameter_section_bytes;
28497   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28498   VLOG(2) << "Command: "
28499           << base::HexEncode(serialized_command->data(),
28500                              serialized_command->size());
28501   return TPM_RC_SUCCESS;
28502 }
28503 
ParseResponse_FirmwareRead(const std::string & response,TPM2B_MAX_BUFFER * fu_data,AuthorizationDelegate * authorization_delegate)28504 TPM_RC Tpm::ParseResponse_FirmwareRead(
28505     const std::string& response,
28506     TPM2B_MAX_BUFFER* fu_data,
28507     AuthorizationDelegate* authorization_delegate) {
28508   VLOG(3) << __func__;
28509   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28510   TPM_RC rc = TPM_RC_SUCCESS;
28511   std::string buffer(response);
28512   TPM_ST tag;
28513   std::string tag_bytes;
28514   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28515   if (rc != TPM_RC_SUCCESS) {
28516     return rc;
28517   }
28518   UINT32 response_size;
28519   std::string response_size_bytes;
28520   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28521   if (rc != TPM_RC_SUCCESS) {
28522     return rc;
28523   }
28524   TPM_RC response_code;
28525   std::string response_code_bytes;
28526   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28527   if (rc != TPM_RC_SUCCESS) {
28528     return rc;
28529   }
28530   if (response_size != response.size()) {
28531     return TPM_RC_SIZE;
28532   }
28533   if (response_code != TPM_RC_SUCCESS) {
28534     return response_code;
28535   }
28536   TPM_CC command_code = TPM_CC_FirmwareRead;
28537   std::string command_code_bytes;
28538   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28539   if (rc != TPM_RC_SUCCESS) {
28540     return rc;
28541   }
28542   std::string authorization_section_bytes;
28543   if (tag == TPM_ST_SESSIONS) {
28544     UINT32 parameter_section_size = buffer.size();
28545     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28546     if (rc != TPM_RC_SUCCESS) {
28547       return rc;
28548     }
28549     if (parameter_section_size > buffer.size()) {
28550       return TPM_RC_INSUFFICIENT;
28551     }
28552     authorization_section_bytes = buffer.substr(parameter_section_size);
28553     // Keep the parameter section in |buffer|.
28554     buffer.erase(parameter_section_size);
28555   }
28556   std::unique_ptr<crypto::SecureHash> hash(
28557       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28558   hash->Update(response_code_bytes.data(), response_code_bytes.size());
28559   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28560   hash->Update(buffer.data(), buffer.size());
28561   std::string response_hash(32, 0);
28562   hash->Finish(std::data(response_hash), response_hash.size());
28563   if (tag == TPM_ST_SESSIONS) {
28564     if (!authorization_delegate)
28565       return TRUNKS_RC_AUTHORIZATION_FAILED;
28566     if (!authorization_delegate->CheckResponseAuthorization(
28567             response_hash, authorization_section_bytes)) {
28568       return TRUNKS_RC_AUTHORIZATION_FAILED;
28569     }
28570   }
28571   if (tag == TPM_ST_SESSIONS) {
28572     if (!authorization_delegate)
28573       return TRUNKS_RC_AUTHORIZATION_FAILED;
28574 
28575     // Parse the encrypted parameter size.
28576     UINT16 size;
28577     std::string size_buffer = buffer.substr(0, 2);
28578     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
28579       return result;
28580     }
28581     if (buffer.size() < 2 + size) {
28582       return TPM_RC_INSUFFICIENT;
28583     }
28584 
28585     // Decrypt just the parameter data, not the size.
28586     std::string decrypted_data = buffer.substr(2, size);
28587     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
28588       return TRUNKS_RC_ENCRYPTION_FAILED;
28589     }
28590     buffer.replace(2, size, decrypted_data);
28591   }
28592   std::string fu_data_bytes;
28593   rc = Parse_TPM2B_MAX_BUFFER(&buffer, fu_data, &fu_data_bytes);
28594   if (rc != TPM_RC_SUCCESS) {
28595     return rc;
28596   }
28597   return TPM_RC_SUCCESS;
28598 }
28599 
FirmwareReadErrorCallback(Tpm::FirmwareReadResponse callback,TPM_RC response_code)28600 void FirmwareReadErrorCallback(Tpm::FirmwareReadResponse callback,
28601                                TPM_RC response_code) {
28602   VLOG(1) << __func__;
28603   std::move(callback).Run(response_code, TPM2B_MAX_BUFFER());
28604 }
28605 
FirmwareReadResponseParser(Tpm::FirmwareReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28606 void FirmwareReadResponseParser(Tpm::FirmwareReadResponse callback,
28607                                 AuthorizationDelegate* authorization_delegate,
28608                                 const std::string& response) {
28609   VLOG(1) << __func__;
28610   TPM2B_MAX_BUFFER fu_data;
28611   TPM_RC rc = Tpm::ParseResponse_FirmwareRead(response, &fu_data,
28612                                               authorization_delegate);
28613   if (rc != TPM_RC_SUCCESS) {
28614     base::OnceCallback<void(TPM_RC)> error_reporter =
28615         base::BindOnce(FirmwareReadErrorCallback, std::move(callback));
28616     std::move(error_reporter).Run(rc);
28617     return;
28618   }
28619   std::move(callback).Run(rc, fu_data);
28620 }
28621 
FirmwareRead(const UINT32 & sequence_number,AuthorizationDelegate * authorization_delegate,FirmwareReadResponse callback)28622 void Tpm::FirmwareRead(const UINT32& sequence_number,
28623                        AuthorizationDelegate* authorization_delegate,
28624                        FirmwareReadResponse callback) {
28625   VLOG(1) << __func__;
28626   std::string command;
28627   TPM_RC rc = SerializeCommand_FirmwareRead(sequence_number, &command,
28628                                             authorization_delegate);
28629   if (rc != TPM_RC_SUCCESS) {
28630     base::OnceCallback<void(TPM_RC)> error_reporter =
28631         base::BindOnce(FirmwareReadErrorCallback, std::move(callback));
28632     std::move(error_reporter).Run(rc);
28633     return;
28634   }
28635   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
28636       FirmwareReadResponseParser, std::move(callback), authorization_delegate);
28637   transceiver_->SendCommand(command, std::move(parser));
28638 }
28639 
FirmwareReadSync(const UINT32 & sequence_number,TPM2B_MAX_BUFFER * fu_data,AuthorizationDelegate * authorization_delegate)28640 TPM_RC Tpm::FirmwareReadSync(const UINT32& sequence_number,
28641                              TPM2B_MAX_BUFFER* fu_data,
28642                              AuthorizationDelegate* authorization_delegate) {
28643   VLOG(1) << __func__;
28644   std::string command;
28645   TPM_RC rc = SerializeCommand_FirmwareRead(sequence_number, &command,
28646                                             authorization_delegate);
28647   if (rc != TPM_RC_SUCCESS) {
28648     return rc;
28649   }
28650   std::string response = transceiver_->SendCommandAndWait(command);
28651   rc = ParseResponse_FirmwareRead(response, fu_data, authorization_delegate);
28652   return rc;
28653 }
28654 
SerializeCommand_ContextSave(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28655 TPM_RC Tpm::SerializeCommand_ContextSave(
28656     const TPMI_DH_CONTEXT& save_handle,
28657     const std::string& save_handle_name,
28658     std::string* serialized_command,
28659     AuthorizationDelegate* authorization_delegate) {
28660   VLOG(3) << __func__;
28661   TPM_RC rc = TPM_RC_SUCCESS;
28662   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28663   UINT32 command_size = 10;  // Header size.
28664   std::string handle_section_bytes;
28665   std::string parameter_section_bytes;
28666   TPM_CC command_code = TPM_CC_ContextSave;
28667   bool is_command_parameter_encryption_possible = false;
28668   bool is_response_parameter_encryption_possible = false;
28669   std::string command_code_bytes;
28670   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28671   if (rc != TPM_RC_SUCCESS) {
28672     return rc;
28673   }
28674   std::string save_handle_bytes;
28675   rc = Serialize_TPMI_DH_CONTEXT(save_handle, &save_handle_bytes);
28676   if (rc != TPM_RC_SUCCESS) {
28677     return rc;
28678   }
28679   std::unique_ptr<crypto::SecureHash> hash(
28680       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28681   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28682   hash->Update(save_handle_name.data(), save_handle_name.size());
28683   handle_section_bytes += save_handle_bytes;
28684   command_size += save_handle_bytes.size();
28685   std::string command_hash(32, 0);
28686   hash->Finish(std::data(command_hash), command_hash.size());
28687   std::string authorization_section_bytes;
28688   std::string authorization_size_bytes;
28689   if (authorization_delegate) {
28690     if (!authorization_delegate->GetCommandAuthorization(
28691             command_hash, is_command_parameter_encryption_possible,
28692             is_response_parameter_encryption_possible,
28693             &authorization_section_bytes)) {
28694       return TRUNKS_RC_AUTHORIZATION_FAILED;
28695     }
28696     if (!authorization_section_bytes.empty()) {
28697       tag = TPM_ST_SESSIONS;
28698       std::string tmp;
28699       rc = Serialize_UINT32(authorization_section_bytes.size(),
28700                             &authorization_size_bytes);
28701       if (rc != TPM_RC_SUCCESS) {
28702         return rc;
28703       }
28704       command_size +=
28705           authorization_size_bytes.size() + authorization_section_bytes.size();
28706     }
28707   }
28708   std::string tag_bytes;
28709   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28710   if (rc != TPM_RC_SUCCESS) {
28711     return rc;
28712   }
28713   std::string command_size_bytes;
28714   rc = Serialize_UINT32(command_size, &command_size_bytes);
28715   if (rc != TPM_RC_SUCCESS) {
28716     return rc;
28717   }
28718   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28719                         handle_section_bytes + authorization_size_bytes +
28720                         authorization_section_bytes + parameter_section_bytes;
28721   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28722   VLOG(2) << "Command: "
28723           << base::HexEncode(serialized_command->data(),
28724                              serialized_command->size());
28725   return TPM_RC_SUCCESS;
28726 }
28727 
ParseResponse_ContextSave(const std::string & response,TPMS_CONTEXT * context,AuthorizationDelegate * authorization_delegate)28728 TPM_RC Tpm::ParseResponse_ContextSave(
28729     const std::string& response,
28730     TPMS_CONTEXT* context,
28731     AuthorizationDelegate* authorization_delegate) {
28732   VLOG(3) << __func__;
28733   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28734   TPM_RC rc = TPM_RC_SUCCESS;
28735   std::string buffer(response);
28736   TPM_ST tag;
28737   std::string tag_bytes;
28738   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28739   if (rc != TPM_RC_SUCCESS) {
28740     return rc;
28741   }
28742   UINT32 response_size;
28743   std::string response_size_bytes;
28744   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28745   if (rc != TPM_RC_SUCCESS) {
28746     return rc;
28747   }
28748   TPM_RC response_code;
28749   std::string response_code_bytes;
28750   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28751   if (rc != TPM_RC_SUCCESS) {
28752     return rc;
28753   }
28754   if (response_size != response.size()) {
28755     return TPM_RC_SIZE;
28756   }
28757   if (response_code != TPM_RC_SUCCESS) {
28758     return response_code;
28759   }
28760   TPM_CC command_code = TPM_CC_ContextSave;
28761   std::string command_code_bytes;
28762   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28763   if (rc != TPM_RC_SUCCESS) {
28764     return rc;
28765   }
28766   std::string authorization_section_bytes;
28767   if (tag == TPM_ST_SESSIONS) {
28768     UINT32 parameter_section_size = buffer.size();
28769     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28770     if (rc != TPM_RC_SUCCESS) {
28771       return rc;
28772     }
28773     if (parameter_section_size > buffer.size()) {
28774       return TPM_RC_INSUFFICIENT;
28775     }
28776     authorization_section_bytes = buffer.substr(parameter_section_size);
28777     // Keep the parameter section in |buffer|.
28778     buffer.erase(parameter_section_size);
28779   }
28780   std::unique_ptr<crypto::SecureHash> hash(
28781       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28782   hash->Update(response_code_bytes.data(), response_code_bytes.size());
28783   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28784   hash->Update(buffer.data(), buffer.size());
28785   std::string response_hash(32, 0);
28786   hash->Finish(std::data(response_hash), response_hash.size());
28787   if (tag == TPM_ST_SESSIONS) {
28788     if (!authorization_delegate)
28789       return TRUNKS_RC_AUTHORIZATION_FAILED;
28790     if (!authorization_delegate->CheckResponseAuthorization(
28791             response_hash, authorization_section_bytes)) {
28792       return TRUNKS_RC_AUTHORIZATION_FAILED;
28793     }
28794   }
28795   std::string context_bytes;
28796   rc = Parse_TPMS_CONTEXT(&buffer, context, &context_bytes);
28797   if (rc != TPM_RC_SUCCESS) {
28798     return rc;
28799   }
28800   return TPM_RC_SUCCESS;
28801 }
28802 
ContextSaveErrorCallback(Tpm::ContextSaveResponse callback,TPM_RC response_code)28803 void ContextSaveErrorCallback(Tpm::ContextSaveResponse callback,
28804                               TPM_RC response_code) {
28805   VLOG(1) << __func__;
28806   std::move(callback).Run(response_code, TPMS_CONTEXT());
28807 }
28808 
ContextSaveResponseParser(Tpm::ContextSaveResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28809 void ContextSaveResponseParser(Tpm::ContextSaveResponse callback,
28810                                AuthorizationDelegate* authorization_delegate,
28811                                const std::string& response) {
28812   VLOG(1) << __func__;
28813   TPMS_CONTEXT context;
28814   TPM_RC rc = Tpm::ParseResponse_ContextSave(response, &context,
28815                                              authorization_delegate);
28816   if (rc != TPM_RC_SUCCESS) {
28817     base::OnceCallback<void(TPM_RC)> error_reporter =
28818         base::BindOnce(ContextSaveErrorCallback, std::move(callback));
28819     std::move(error_reporter).Run(rc);
28820     return;
28821   }
28822   std::move(callback).Run(rc, context);
28823 }
28824 
ContextSave(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,AuthorizationDelegate * authorization_delegate,ContextSaveResponse callback)28825 void Tpm::ContextSave(const TPMI_DH_CONTEXT& save_handle,
28826                       const std::string& save_handle_name,
28827                       AuthorizationDelegate* authorization_delegate,
28828                       ContextSaveResponse callback) {
28829   VLOG(1) << __func__;
28830   std::string command;
28831   TPM_RC rc = SerializeCommand_ContextSave(save_handle, save_handle_name,
28832                                            &command, authorization_delegate);
28833   if (rc != TPM_RC_SUCCESS) {
28834     base::OnceCallback<void(TPM_RC)> error_reporter =
28835         base::BindOnce(ContextSaveErrorCallback, std::move(callback));
28836     std::move(error_reporter).Run(rc);
28837     return;
28838   }
28839   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
28840       ContextSaveResponseParser, std::move(callback), authorization_delegate);
28841   transceiver_->SendCommand(command, std::move(parser));
28842 }
28843 
ContextSaveSync(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,TPMS_CONTEXT * context,AuthorizationDelegate * authorization_delegate)28844 TPM_RC Tpm::ContextSaveSync(const TPMI_DH_CONTEXT& save_handle,
28845                             const std::string& save_handle_name,
28846                             TPMS_CONTEXT* context,
28847                             AuthorizationDelegate* authorization_delegate) {
28848   VLOG(1) << __func__;
28849   std::string command;
28850   TPM_RC rc = SerializeCommand_ContextSave(save_handle, save_handle_name,
28851                                            &command, authorization_delegate);
28852   if (rc != TPM_RC_SUCCESS) {
28853     return rc;
28854   }
28855   std::string response = transceiver_->SendCommandAndWait(command);
28856   rc = ParseResponse_ContextSave(response, context, authorization_delegate);
28857   return rc;
28858 }
28859 
SerializeCommand_ContextLoad(const TPMS_CONTEXT & context,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28860 TPM_RC Tpm::SerializeCommand_ContextLoad(
28861     const TPMS_CONTEXT& context,
28862     std::string* serialized_command,
28863     AuthorizationDelegate* authorization_delegate) {
28864   VLOG(3) << __func__;
28865   TPM_RC rc = TPM_RC_SUCCESS;
28866   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28867   UINT32 command_size = 10;  // Header size.
28868   std::string handle_section_bytes;
28869   std::string parameter_section_bytes;
28870   TPM_CC command_code = TPM_CC_ContextLoad;
28871   bool is_command_parameter_encryption_possible = false;
28872   bool is_response_parameter_encryption_possible = false;
28873   std::string command_code_bytes;
28874   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28875   if (rc != TPM_RC_SUCCESS) {
28876     return rc;
28877   }
28878   std::string context_bytes;
28879   rc = Serialize_TPMS_CONTEXT(context, &context_bytes);
28880   if (rc != TPM_RC_SUCCESS) {
28881     return rc;
28882   }
28883   std::unique_ptr<crypto::SecureHash> hash(
28884       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28885   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28886   hash->Update(context_bytes.data(), context_bytes.size());
28887   parameter_section_bytes += context_bytes;
28888   command_size += context_bytes.size();
28889   std::string command_hash(32, 0);
28890   hash->Finish(std::data(command_hash), command_hash.size());
28891   std::string authorization_section_bytes;
28892   std::string authorization_size_bytes;
28893   if (authorization_delegate) {
28894     if (!authorization_delegate->GetCommandAuthorization(
28895             command_hash, is_command_parameter_encryption_possible,
28896             is_response_parameter_encryption_possible,
28897             &authorization_section_bytes)) {
28898       return TRUNKS_RC_AUTHORIZATION_FAILED;
28899     }
28900     if (!authorization_section_bytes.empty()) {
28901       tag = TPM_ST_SESSIONS;
28902       std::string tmp;
28903       rc = Serialize_UINT32(authorization_section_bytes.size(),
28904                             &authorization_size_bytes);
28905       if (rc != TPM_RC_SUCCESS) {
28906         return rc;
28907       }
28908       command_size +=
28909           authorization_size_bytes.size() + authorization_section_bytes.size();
28910     }
28911   }
28912   std::string tag_bytes;
28913   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28914   if (rc != TPM_RC_SUCCESS) {
28915     return rc;
28916   }
28917   std::string command_size_bytes;
28918   rc = Serialize_UINT32(command_size, &command_size_bytes);
28919   if (rc != TPM_RC_SUCCESS) {
28920     return rc;
28921   }
28922   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28923                         handle_section_bytes + authorization_size_bytes +
28924                         authorization_section_bytes + parameter_section_bytes;
28925   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28926   VLOG(2) << "Command: "
28927           << base::HexEncode(serialized_command->data(),
28928                              serialized_command->size());
28929   return TPM_RC_SUCCESS;
28930 }
28931 
ParseResponse_ContextLoad(const std::string & response,TPMI_DH_CONTEXT * loaded_handle,AuthorizationDelegate * authorization_delegate)28932 TPM_RC Tpm::ParseResponse_ContextLoad(
28933     const std::string& response,
28934     TPMI_DH_CONTEXT* loaded_handle,
28935     AuthorizationDelegate* authorization_delegate) {
28936   VLOG(3) << __func__;
28937   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28938   TPM_RC rc = TPM_RC_SUCCESS;
28939   std::string buffer(response);
28940   TPM_ST tag;
28941   std::string tag_bytes;
28942   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28943   if (rc != TPM_RC_SUCCESS) {
28944     return rc;
28945   }
28946   UINT32 response_size;
28947   std::string response_size_bytes;
28948   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28949   if (rc != TPM_RC_SUCCESS) {
28950     return rc;
28951   }
28952   TPM_RC response_code;
28953   std::string response_code_bytes;
28954   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28955   if (rc != TPM_RC_SUCCESS) {
28956     return rc;
28957   }
28958   if (response_size != response.size()) {
28959     return TPM_RC_SIZE;
28960   }
28961   if (response_code != TPM_RC_SUCCESS) {
28962     return response_code;
28963   }
28964   std::string loaded_handle_bytes;
28965   rc = Parse_TPMI_DH_CONTEXT(&buffer, loaded_handle, &loaded_handle_bytes);
28966   if (rc != TPM_RC_SUCCESS) {
28967     return rc;
28968   }
28969   TPM_CC command_code = TPM_CC_ContextLoad;
28970   std::string command_code_bytes;
28971   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28972   if (rc != TPM_RC_SUCCESS) {
28973     return rc;
28974   }
28975   std::string authorization_section_bytes;
28976   if (tag == TPM_ST_SESSIONS) {
28977     UINT32 parameter_section_size = buffer.size();
28978     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28979     if (rc != TPM_RC_SUCCESS) {
28980       return rc;
28981     }
28982     if (parameter_section_size > buffer.size()) {
28983       return TPM_RC_INSUFFICIENT;
28984     }
28985     authorization_section_bytes = buffer.substr(parameter_section_size);
28986     // Keep the parameter section in |buffer|.
28987     buffer.erase(parameter_section_size);
28988   }
28989   std::unique_ptr<crypto::SecureHash> hash(
28990       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28991   hash->Update(response_code_bytes.data(), response_code_bytes.size());
28992   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28993   hash->Update(buffer.data(), buffer.size());
28994   std::string response_hash(32, 0);
28995   hash->Finish(std::data(response_hash), response_hash.size());
28996   if (tag == TPM_ST_SESSIONS) {
28997     if (!authorization_delegate)
28998       return TRUNKS_RC_AUTHORIZATION_FAILED;
28999     if (!authorization_delegate->CheckResponseAuthorization(
29000             response_hash, authorization_section_bytes)) {
29001       return TRUNKS_RC_AUTHORIZATION_FAILED;
29002     }
29003   }
29004   return TPM_RC_SUCCESS;
29005 }
29006 
ContextLoadErrorCallback(Tpm::ContextLoadResponse callback,TPM_RC response_code)29007 void ContextLoadErrorCallback(Tpm::ContextLoadResponse callback,
29008                               TPM_RC response_code) {
29009   VLOG(1) << __func__;
29010   std::move(callback).Run(response_code, TPMI_DH_CONTEXT());
29011 }
29012 
ContextLoadResponseParser(Tpm::ContextLoadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29013 void ContextLoadResponseParser(Tpm::ContextLoadResponse callback,
29014                                AuthorizationDelegate* authorization_delegate,
29015                                const std::string& response) {
29016   VLOG(1) << __func__;
29017   TPMI_DH_CONTEXT loaded_handle;
29018   TPM_RC rc = Tpm::ParseResponse_ContextLoad(response, &loaded_handle,
29019                                              authorization_delegate);
29020   if (rc != TPM_RC_SUCCESS) {
29021     base::OnceCallback<void(TPM_RC)> error_reporter =
29022         base::BindOnce(ContextLoadErrorCallback, std::move(callback));
29023     std::move(error_reporter).Run(rc);
29024     return;
29025   }
29026   std::move(callback).Run(rc, loaded_handle);
29027 }
29028 
ContextLoad(const TPMS_CONTEXT & context,AuthorizationDelegate * authorization_delegate,ContextLoadResponse callback)29029 void Tpm::ContextLoad(const TPMS_CONTEXT& context,
29030                       AuthorizationDelegate* authorization_delegate,
29031                       ContextLoadResponse callback) {
29032   VLOG(1) << __func__;
29033   std::string command;
29034   TPM_RC rc =
29035       SerializeCommand_ContextLoad(context, &command, authorization_delegate);
29036   if (rc != TPM_RC_SUCCESS) {
29037     base::OnceCallback<void(TPM_RC)> error_reporter =
29038         base::BindOnce(ContextLoadErrorCallback, std::move(callback));
29039     std::move(error_reporter).Run(rc);
29040     return;
29041   }
29042   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29043       ContextLoadResponseParser, std::move(callback), authorization_delegate);
29044   transceiver_->SendCommand(command, std::move(parser));
29045 }
29046 
ContextLoadSync(const TPMS_CONTEXT & context,TPMI_DH_CONTEXT * loaded_handle,AuthorizationDelegate * authorization_delegate)29047 TPM_RC Tpm::ContextLoadSync(const TPMS_CONTEXT& context,
29048                             TPMI_DH_CONTEXT* loaded_handle,
29049                             AuthorizationDelegate* authorization_delegate) {
29050   VLOG(1) << __func__;
29051   std::string command;
29052   TPM_RC rc =
29053       SerializeCommand_ContextLoad(context, &command, authorization_delegate);
29054   if (rc != TPM_RC_SUCCESS) {
29055     return rc;
29056   }
29057   std::string response = transceiver_->SendCommandAndWait(command);
29058   rc = ParseResponse_ContextLoad(response, loaded_handle,
29059                                  authorization_delegate);
29060   return rc;
29061 }
29062 
SerializeCommand_FlushContext(const TPMI_DH_CONTEXT & flush_handle,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29063 TPM_RC Tpm::SerializeCommand_FlushContext(
29064     const TPMI_DH_CONTEXT& flush_handle,
29065     std::string* serialized_command,
29066     AuthorizationDelegate* authorization_delegate) {
29067   VLOG(3) << __func__;
29068   TPM_RC rc = TPM_RC_SUCCESS;
29069   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29070   UINT32 command_size = 10;  // Header size.
29071   std::string handle_section_bytes;
29072   std::string parameter_section_bytes;
29073   TPM_CC command_code = TPM_CC_FlushContext;
29074   bool is_command_parameter_encryption_possible = false;
29075   bool is_response_parameter_encryption_possible = false;
29076   std::string command_code_bytes;
29077   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29078   if (rc != TPM_RC_SUCCESS) {
29079     return rc;
29080   }
29081   std::string flush_handle_bytes;
29082   rc = Serialize_TPMI_DH_CONTEXT(flush_handle, &flush_handle_bytes);
29083   if (rc != TPM_RC_SUCCESS) {
29084     return rc;
29085   }
29086   std::unique_ptr<crypto::SecureHash> hash(
29087       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29088   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29089   hash->Update(flush_handle_bytes.data(), flush_handle_bytes.size());
29090   parameter_section_bytes += flush_handle_bytes;
29091   command_size += flush_handle_bytes.size();
29092   std::string command_hash(32, 0);
29093   hash->Finish(std::data(command_hash), command_hash.size());
29094   std::string authorization_section_bytes;
29095   std::string authorization_size_bytes;
29096   if (authorization_delegate) {
29097     if (!authorization_delegate->GetCommandAuthorization(
29098             command_hash, is_command_parameter_encryption_possible,
29099             is_response_parameter_encryption_possible,
29100             &authorization_section_bytes)) {
29101       return TRUNKS_RC_AUTHORIZATION_FAILED;
29102     }
29103     if (!authorization_section_bytes.empty()) {
29104       tag = TPM_ST_SESSIONS;
29105       std::string tmp;
29106       rc = Serialize_UINT32(authorization_section_bytes.size(),
29107                             &authorization_size_bytes);
29108       if (rc != TPM_RC_SUCCESS) {
29109         return rc;
29110       }
29111       command_size +=
29112           authorization_size_bytes.size() + authorization_section_bytes.size();
29113     }
29114   }
29115   std::string tag_bytes;
29116   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29117   if (rc != TPM_RC_SUCCESS) {
29118     return rc;
29119   }
29120   std::string command_size_bytes;
29121   rc = Serialize_UINT32(command_size, &command_size_bytes);
29122   if (rc != TPM_RC_SUCCESS) {
29123     return rc;
29124   }
29125   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29126                         handle_section_bytes + authorization_size_bytes +
29127                         authorization_section_bytes + parameter_section_bytes;
29128   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29129   VLOG(2) << "Command: "
29130           << base::HexEncode(serialized_command->data(),
29131                              serialized_command->size());
29132   return TPM_RC_SUCCESS;
29133 }
29134 
ParseResponse_FlushContext(const std::string & response,AuthorizationDelegate * authorization_delegate)29135 TPM_RC Tpm::ParseResponse_FlushContext(
29136     const std::string& response,
29137     AuthorizationDelegate* authorization_delegate) {
29138   VLOG(3) << __func__;
29139   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29140   TPM_RC rc = TPM_RC_SUCCESS;
29141   std::string buffer(response);
29142   TPM_ST tag;
29143   std::string tag_bytes;
29144   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29145   if (rc != TPM_RC_SUCCESS) {
29146     return rc;
29147   }
29148   UINT32 response_size;
29149   std::string response_size_bytes;
29150   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29151   if (rc != TPM_RC_SUCCESS) {
29152     return rc;
29153   }
29154   TPM_RC response_code;
29155   std::string response_code_bytes;
29156   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29157   if (rc != TPM_RC_SUCCESS) {
29158     return rc;
29159   }
29160   if (response_size != response.size()) {
29161     return TPM_RC_SIZE;
29162   }
29163   if (response_code != TPM_RC_SUCCESS) {
29164     return response_code;
29165   }
29166   TPM_CC command_code = TPM_CC_FlushContext;
29167   std::string command_code_bytes;
29168   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29169   if (rc != TPM_RC_SUCCESS) {
29170     return rc;
29171   }
29172   std::string authorization_section_bytes;
29173   if (tag == TPM_ST_SESSIONS) {
29174     UINT32 parameter_section_size = buffer.size();
29175     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29176     if (rc != TPM_RC_SUCCESS) {
29177       return rc;
29178     }
29179     if (parameter_section_size > buffer.size()) {
29180       return TPM_RC_INSUFFICIENT;
29181     }
29182     authorization_section_bytes = buffer.substr(parameter_section_size);
29183     // Keep the parameter section in |buffer|.
29184     buffer.erase(parameter_section_size);
29185   }
29186   std::unique_ptr<crypto::SecureHash> hash(
29187       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29188   hash->Update(response_code_bytes.data(), response_code_bytes.size());
29189   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29190   hash->Update(buffer.data(), buffer.size());
29191   std::string response_hash(32, 0);
29192   hash->Finish(std::data(response_hash), response_hash.size());
29193   if (tag == TPM_ST_SESSIONS) {
29194     if (!authorization_delegate)
29195       return TRUNKS_RC_AUTHORIZATION_FAILED;
29196     if (!authorization_delegate->CheckResponseAuthorization(
29197             response_hash, authorization_section_bytes)) {
29198       return TRUNKS_RC_AUTHORIZATION_FAILED;
29199     }
29200   }
29201   return TPM_RC_SUCCESS;
29202 }
29203 
FlushContextErrorCallback(Tpm::FlushContextResponse callback,TPM_RC response_code)29204 void FlushContextErrorCallback(Tpm::FlushContextResponse callback,
29205                                TPM_RC response_code) {
29206   VLOG(1) << __func__;
29207   std::move(callback).Run(response_code);
29208 }
29209 
FlushContextResponseParser(Tpm::FlushContextResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29210 void FlushContextResponseParser(Tpm::FlushContextResponse callback,
29211                                 AuthorizationDelegate* authorization_delegate,
29212                                 const std::string& response) {
29213   VLOG(1) << __func__;
29214   TPM_RC rc = Tpm::ParseResponse_FlushContext(response, authorization_delegate);
29215   if (rc != TPM_RC_SUCCESS) {
29216     base::OnceCallback<void(TPM_RC)> error_reporter =
29217         base::BindOnce(FlushContextErrorCallback, std::move(callback));
29218     std::move(error_reporter).Run(rc);
29219     return;
29220   }
29221   std::move(callback).Run(rc);
29222 }
29223 
FlushContext(const TPMI_DH_CONTEXT & flush_handle,AuthorizationDelegate * authorization_delegate,FlushContextResponse callback)29224 void Tpm::FlushContext(const TPMI_DH_CONTEXT& flush_handle,
29225                        AuthorizationDelegate* authorization_delegate,
29226                        FlushContextResponse callback) {
29227   VLOG(1) << __func__;
29228   std::string command;
29229   TPM_RC rc = SerializeCommand_FlushContext(flush_handle, &command,
29230                                             authorization_delegate);
29231   if (rc != TPM_RC_SUCCESS) {
29232     base::OnceCallback<void(TPM_RC)> error_reporter =
29233         base::BindOnce(FlushContextErrorCallback, std::move(callback));
29234     std::move(error_reporter).Run(rc);
29235     return;
29236   }
29237   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29238       FlushContextResponseParser, std::move(callback), authorization_delegate);
29239   transceiver_->SendCommand(command, std::move(parser));
29240 }
29241 
FlushContextSync(const TPMI_DH_CONTEXT & flush_handle,AuthorizationDelegate * authorization_delegate)29242 TPM_RC Tpm::FlushContextSync(const TPMI_DH_CONTEXT& flush_handle,
29243                              AuthorizationDelegate* authorization_delegate) {
29244   VLOG(1) << __func__;
29245   std::string command;
29246   TPM_RC rc = SerializeCommand_FlushContext(flush_handle, &command,
29247                                             authorization_delegate);
29248   if (rc != TPM_RC_SUCCESS) {
29249     return rc;
29250   }
29251   std::string response = transceiver_->SendCommandAndWait(command);
29252   rc = ParseResponse_FlushContext(response, authorization_delegate);
29253   return rc;
29254 }
29255 
SerializeCommand_EvictControl(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_PERSISTENT & persistent_handle,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29256 TPM_RC Tpm::SerializeCommand_EvictControl(
29257     const TPMI_RH_PROVISION& auth,
29258     const std::string& auth_name,
29259     const TPMI_DH_OBJECT& object_handle,
29260     const std::string& object_handle_name,
29261     const TPMI_DH_PERSISTENT& persistent_handle,
29262     std::string* serialized_command,
29263     AuthorizationDelegate* authorization_delegate) {
29264   VLOG(3) << __func__;
29265   TPM_RC rc = TPM_RC_SUCCESS;
29266   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29267   UINT32 command_size = 10;  // Header size.
29268   std::string handle_section_bytes;
29269   std::string parameter_section_bytes;
29270   TPM_CC command_code = TPM_CC_EvictControl;
29271   bool is_command_parameter_encryption_possible = false;
29272   bool is_response_parameter_encryption_possible = false;
29273   std::string command_code_bytes;
29274   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29275   if (rc != TPM_RC_SUCCESS) {
29276     return rc;
29277   }
29278   std::string auth_bytes;
29279   rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29280   if (rc != TPM_RC_SUCCESS) {
29281     return rc;
29282   }
29283   std::string object_handle_bytes;
29284   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
29285   if (rc != TPM_RC_SUCCESS) {
29286     return rc;
29287   }
29288   std::string persistent_handle_bytes;
29289   rc =
29290       Serialize_TPMI_DH_PERSISTENT(persistent_handle, &persistent_handle_bytes);
29291   if (rc != TPM_RC_SUCCESS) {
29292     return rc;
29293   }
29294   std::unique_ptr<crypto::SecureHash> hash(
29295       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29296   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29297   hash->Update(auth_name.data(), auth_name.size());
29298   handle_section_bytes += auth_bytes;
29299   command_size += auth_bytes.size();
29300   hash->Update(object_handle_name.data(), object_handle_name.size());
29301   handle_section_bytes += object_handle_bytes;
29302   command_size += object_handle_bytes.size();
29303   hash->Update(persistent_handle_bytes.data(), persistent_handle_bytes.size());
29304   parameter_section_bytes += persistent_handle_bytes;
29305   command_size += persistent_handle_bytes.size();
29306   std::string command_hash(32, 0);
29307   hash->Finish(std::data(command_hash), command_hash.size());
29308   std::string authorization_section_bytes;
29309   std::string authorization_size_bytes;
29310   if (authorization_delegate) {
29311     if (!authorization_delegate->GetCommandAuthorization(
29312             command_hash, is_command_parameter_encryption_possible,
29313             is_response_parameter_encryption_possible,
29314             &authorization_section_bytes)) {
29315       return TRUNKS_RC_AUTHORIZATION_FAILED;
29316     }
29317     if (!authorization_section_bytes.empty()) {
29318       tag = TPM_ST_SESSIONS;
29319       std::string tmp;
29320       rc = Serialize_UINT32(authorization_section_bytes.size(),
29321                             &authorization_size_bytes);
29322       if (rc != TPM_RC_SUCCESS) {
29323         return rc;
29324       }
29325       command_size +=
29326           authorization_size_bytes.size() + authorization_section_bytes.size();
29327     }
29328   }
29329   std::string tag_bytes;
29330   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29331   if (rc != TPM_RC_SUCCESS) {
29332     return rc;
29333   }
29334   std::string command_size_bytes;
29335   rc = Serialize_UINT32(command_size, &command_size_bytes);
29336   if (rc != TPM_RC_SUCCESS) {
29337     return rc;
29338   }
29339   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29340                         handle_section_bytes + authorization_size_bytes +
29341                         authorization_section_bytes + parameter_section_bytes;
29342   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29343   VLOG(2) << "Command: "
29344           << base::HexEncode(serialized_command->data(),
29345                              serialized_command->size());
29346   return TPM_RC_SUCCESS;
29347 }
29348 
ParseResponse_EvictControl(const std::string & response,AuthorizationDelegate * authorization_delegate)29349 TPM_RC Tpm::ParseResponse_EvictControl(
29350     const std::string& response,
29351     AuthorizationDelegate* authorization_delegate) {
29352   VLOG(3) << __func__;
29353   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29354   TPM_RC rc = TPM_RC_SUCCESS;
29355   std::string buffer(response);
29356   TPM_ST tag;
29357   std::string tag_bytes;
29358   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29359   if (rc != TPM_RC_SUCCESS) {
29360     return rc;
29361   }
29362   UINT32 response_size;
29363   std::string response_size_bytes;
29364   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29365   if (rc != TPM_RC_SUCCESS) {
29366     return rc;
29367   }
29368   TPM_RC response_code;
29369   std::string response_code_bytes;
29370   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29371   if (rc != TPM_RC_SUCCESS) {
29372     return rc;
29373   }
29374   if (response_size != response.size()) {
29375     return TPM_RC_SIZE;
29376   }
29377   if (response_code != TPM_RC_SUCCESS) {
29378     return response_code;
29379   }
29380   TPM_CC command_code = TPM_CC_EvictControl;
29381   std::string command_code_bytes;
29382   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29383   if (rc != TPM_RC_SUCCESS) {
29384     return rc;
29385   }
29386   std::string authorization_section_bytes;
29387   if (tag == TPM_ST_SESSIONS) {
29388     UINT32 parameter_section_size = buffer.size();
29389     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29390     if (rc != TPM_RC_SUCCESS) {
29391       return rc;
29392     }
29393     if (parameter_section_size > buffer.size()) {
29394       return TPM_RC_INSUFFICIENT;
29395     }
29396     authorization_section_bytes = buffer.substr(parameter_section_size);
29397     // Keep the parameter section in |buffer|.
29398     buffer.erase(parameter_section_size);
29399   }
29400   std::unique_ptr<crypto::SecureHash> hash(
29401       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29402   hash->Update(response_code_bytes.data(), response_code_bytes.size());
29403   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29404   hash->Update(buffer.data(), buffer.size());
29405   std::string response_hash(32, 0);
29406   hash->Finish(std::data(response_hash), response_hash.size());
29407   if (tag == TPM_ST_SESSIONS) {
29408     if (!authorization_delegate)
29409       return TRUNKS_RC_AUTHORIZATION_FAILED;
29410     if (!authorization_delegate->CheckResponseAuthorization(
29411             response_hash, authorization_section_bytes)) {
29412       return TRUNKS_RC_AUTHORIZATION_FAILED;
29413     }
29414   }
29415   return TPM_RC_SUCCESS;
29416 }
29417 
EvictControlErrorCallback(Tpm::EvictControlResponse callback,TPM_RC response_code)29418 void EvictControlErrorCallback(Tpm::EvictControlResponse callback,
29419                                TPM_RC response_code) {
29420   VLOG(1) << __func__;
29421   std::move(callback).Run(response_code);
29422 }
29423 
EvictControlResponseParser(Tpm::EvictControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29424 void EvictControlResponseParser(Tpm::EvictControlResponse callback,
29425                                 AuthorizationDelegate* authorization_delegate,
29426                                 const std::string& response) {
29427   VLOG(1) << __func__;
29428   TPM_RC rc = Tpm::ParseResponse_EvictControl(response, authorization_delegate);
29429   if (rc != TPM_RC_SUCCESS) {
29430     base::OnceCallback<void(TPM_RC)> error_reporter =
29431         base::BindOnce(EvictControlErrorCallback, std::move(callback));
29432     std::move(error_reporter).Run(rc);
29433     return;
29434   }
29435   std::move(callback).Run(rc);
29436 }
29437 
EvictControl(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_PERSISTENT & persistent_handle,AuthorizationDelegate * authorization_delegate,EvictControlResponse callback)29438 void Tpm::EvictControl(const TPMI_RH_PROVISION& auth,
29439                        const std::string& auth_name,
29440                        const TPMI_DH_OBJECT& object_handle,
29441                        const std::string& object_handle_name,
29442                        const TPMI_DH_PERSISTENT& persistent_handle,
29443                        AuthorizationDelegate* authorization_delegate,
29444                        EvictControlResponse callback) {
29445   VLOG(1) << __func__;
29446   std::string command;
29447   TPM_RC rc = SerializeCommand_EvictControl(
29448       auth, auth_name, object_handle, object_handle_name, persistent_handle,
29449       &command, authorization_delegate);
29450   if (rc != TPM_RC_SUCCESS) {
29451     base::OnceCallback<void(TPM_RC)> error_reporter =
29452         base::BindOnce(EvictControlErrorCallback, std::move(callback));
29453     std::move(error_reporter).Run(rc);
29454     return;
29455   }
29456   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29457       EvictControlResponseParser, std::move(callback), authorization_delegate);
29458   transceiver_->SendCommand(command, std::move(parser));
29459 }
29460 
EvictControlSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_PERSISTENT & persistent_handle,AuthorizationDelegate * authorization_delegate)29461 TPM_RC Tpm::EvictControlSync(const TPMI_RH_PROVISION& auth,
29462                              const std::string& auth_name,
29463                              const TPMI_DH_OBJECT& object_handle,
29464                              const std::string& object_handle_name,
29465                              const TPMI_DH_PERSISTENT& persistent_handle,
29466                              AuthorizationDelegate* authorization_delegate) {
29467   VLOG(1) << __func__;
29468   std::string command;
29469   TPM_RC rc = SerializeCommand_EvictControl(
29470       auth, auth_name, object_handle, object_handle_name, persistent_handle,
29471       &command, authorization_delegate);
29472   if (rc != TPM_RC_SUCCESS) {
29473     return rc;
29474   }
29475   std::string response = transceiver_->SendCommandAndWait(command);
29476   rc = ParseResponse_EvictControl(response, authorization_delegate);
29477   return rc;
29478 }
29479 
SerializeCommand_ReadClock(std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29480 TPM_RC Tpm::SerializeCommand_ReadClock(
29481     std::string* serialized_command,
29482     AuthorizationDelegate* authorization_delegate) {
29483   VLOG(3) << __func__;
29484   TPM_RC rc = TPM_RC_SUCCESS;
29485   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29486   UINT32 command_size = 10;  // Header size.
29487   std::string handle_section_bytes;
29488   std::string parameter_section_bytes;
29489   TPM_CC command_code = TPM_CC_ReadClock;
29490   bool is_command_parameter_encryption_possible = false;
29491   bool is_response_parameter_encryption_possible = false;
29492   std::string command_code_bytes;
29493   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29494   if (rc != TPM_RC_SUCCESS) {
29495     return rc;
29496   }
29497   std::unique_ptr<crypto::SecureHash> hash(
29498       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29499   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29500   std::string command_hash(32, 0);
29501   hash->Finish(std::data(command_hash), command_hash.size());
29502   std::string authorization_section_bytes;
29503   std::string authorization_size_bytes;
29504   if (authorization_delegate) {
29505     if (!authorization_delegate->GetCommandAuthorization(
29506             command_hash, is_command_parameter_encryption_possible,
29507             is_response_parameter_encryption_possible,
29508             &authorization_section_bytes)) {
29509       return TRUNKS_RC_AUTHORIZATION_FAILED;
29510     }
29511     if (!authorization_section_bytes.empty()) {
29512       tag = TPM_ST_SESSIONS;
29513       std::string tmp;
29514       rc = Serialize_UINT32(authorization_section_bytes.size(),
29515                             &authorization_size_bytes);
29516       if (rc != TPM_RC_SUCCESS) {
29517         return rc;
29518       }
29519       command_size +=
29520           authorization_size_bytes.size() + authorization_section_bytes.size();
29521     }
29522   }
29523   std::string tag_bytes;
29524   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29525   if (rc != TPM_RC_SUCCESS) {
29526     return rc;
29527   }
29528   std::string command_size_bytes;
29529   rc = Serialize_UINT32(command_size, &command_size_bytes);
29530   if (rc != TPM_RC_SUCCESS) {
29531     return rc;
29532   }
29533   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29534                         handle_section_bytes + authorization_size_bytes +
29535                         authorization_section_bytes + parameter_section_bytes;
29536   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29537   VLOG(2) << "Command: "
29538           << base::HexEncode(serialized_command->data(),
29539                              serialized_command->size());
29540   return TPM_RC_SUCCESS;
29541 }
29542 
ParseResponse_ReadClock(const std::string & response,TPMS_TIME_INFO * current_time,AuthorizationDelegate * authorization_delegate)29543 TPM_RC Tpm::ParseResponse_ReadClock(
29544     const std::string& response,
29545     TPMS_TIME_INFO* current_time,
29546     AuthorizationDelegate* authorization_delegate) {
29547   VLOG(3) << __func__;
29548   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29549   TPM_RC rc = TPM_RC_SUCCESS;
29550   std::string buffer(response);
29551   TPM_ST tag;
29552   std::string tag_bytes;
29553   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29554   if (rc != TPM_RC_SUCCESS) {
29555     return rc;
29556   }
29557   UINT32 response_size;
29558   std::string response_size_bytes;
29559   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29560   if (rc != TPM_RC_SUCCESS) {
29561     return rc;
29562   }
29563   TPM_RC response_code;
29564   std::string response_code_bytes;
29565   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29566   if (rc != TPM_RC_SUCCESS) {
29567     return rc;
29568   }
29569   if (response_size != response.size()) {
29570     return TPM_RC_SIZE;
29571   }
29572   if (response_code != TPM_RC_SUCCESS) {
29573     return response_code;
29574   }
29575   TPM_CC command_code = TPM_CC_ReadClock;
29576   std::string command_code_bytes;
29577   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29578   if (rc != TPM_RC_SUCCESS) {
29579     return rc;
29580   }
29581   std::string authorization_section_bytes;
29582   if (tag == TPM_ST_SESSIONS) {
29583     UINT32 parameter_section_size = buffer.size();
29584     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29585     if (rc != TPM_RC_SUCCESS) {
29586       return rc;
29587     }
29588     if (parameter_section_size > buffer.size()) {
29589       return TPM_RC_INSUFFICIENT;
29590     }
29591     authorization_section_bytes = buffer.substr(parameter_section_size);
29592     // Keep the parameter section in |buffer|.
29593     buffer.erase(parameter_section_size);
29594   }
29595   std::unique_ptr<crypto::SecureHash> hash(
29596       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29597   hash->Update(response_code_bytes.data(), response_code_bytes.size());
29598   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29599   hash->Update(buffer.data(), buffer.size());
29600   std::string response_hash(32, 0);
29601   hash->Finish(std::data(response_hash), response_hash.size());
29602   if (tag == TPM_ST_SESSIONS) {
29603     if (!authorization_delegate)
29604       return TRUNKS_RC_AUTHORIZATION_FAILED;
29605     if (!authorization_delegate->CheckResponseAuthorization(
29606             response_hash, authorization_section_bytes)) {
29607       return TRUNKS_RC_AUTHORIZATION_FAILED;
29608     }
29609   }
29610   std::string current_time_bytes;
29611   rc = Parse_TPMS_TIME_INFO(&buffer, current_time, &current_time_bytes);
29612   if (rc != TPM_RC_SUCCESS) {
29613     return rc;
29614   }
29615   return TPM_RC_SUCCESS;
29616 }
29617 
ReadClockErrorCallback(Tpm::ReadClockResponse callback,TPM_RC response_code)29618 void ReadClockErrorCallback(Tpm::ReadClockResponse callback,
29619                             TPM_RC response_code) {
29620   VLOG(1) << __func__;
29621   std::move(callback).Run(response_code, TPMS_TIME_INFO());
29622 }
29623 
ReadClockResponseParser(Tpm::ReadClockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29624 void ReadClockResponseParser(Tpm::ReadClockResponse callback,
29625                              AuthorizationDelegate* authorization_delegate,
29626                              const std::string& response) {
29627   VLOG(1) << __func__;
29628   TPMS_TIME_INFO current_time;
29629   TPM_RC rc = Tpm::ParseResponse_ReadClock(response, &current_time,
29630                                            authorization_delegate);
29631   if (rc != TPM_RC_SUCCESS) {
29632     base::OnceCallback<void(TPM_RC)> error_reporter =
29633         base::BindOnce(ReadClockErrorCallback, std::move(callback));
29634     std::move(error_reporter).Run(rc);
29635     return;
29636   }
29637   std::move(callback).Run(rc, current_time);
29638 }
29639 
ReadClock(AuthorizationDelegate * authorization_delegate,ReadClockResponse callback)29640 void Tpm::ReadClock(AuthorizationDelegate* authorization_delegate,
29641                     ReadClockResponse callback) {
29642   VLOG(1) << __func__;
29643   std::string command;
29644   TPM_RC rc = SerializeCommand_ReadClock(&command, authorization_delegate);
29645   if (rc != TPM_RC_SUCCESS) {
29646     base::OnceCallback<void(TPM_RC)> error_reporter =
29647         base::BindOnce(ReadClockErrorCallback, std::move(callback));
29648     std::move(error_reporter).Run(rc);
29649     return;
29650   }
29651   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29652       ReadClockResponseParser, std::move(callback), authorization_delegate);
29653   transceiver_->SendCommand(command, std::move(parser));
29654 }
29655 
ReadClockSync(TPMS_TIME_INFO * current_time,AuthorizationDelegate * authorization_delegate)29656 TPM_RC Tpm::ReadClockSync(TPMS_TIME_INFO* current_time,
29657                           AuthorizationDelegate* authorization_delegate) {
29658   VLOG(1) << __func__;
29659   std::string command;
29660   TPM_RC rc = SerializeCommand_ReadClock(&command, authorization_delegate);
29661   if (rc != TPM_RC_SUCCESS) {
29662     return rc;
29663   }
29664   std::string response = transceiver_->SendCommandAndWait(command);
29665   rc = ParseResponse_ReadClock(response, current_time, authorization_delegate);
29666   return rc;
29667 }
29668 
SerializeCommand_ClockSet(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29669 TPM_RC Tpm::SerializeCommand_ClockSet(
29670     const TPMI_RH_PROVISION& auth,
29671     const std::string& auth_name,
29672     const UINT64& new_time,
29673     std::string* serialized_command,
29674     AuthorizationDelegate* authorization_delegate) {
29675   VLOG(3) << __func__;
29676   TPM_RC rc = TPM_RC_SUCCESS;
29677   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29678   UINT32 command_size = 10;  // Header size.
29679   std::string handle_section_bytes;
29680   std::string parameter_section_bytes;
29681   TPM_CC command_code = TPM_CC_ClockSet;
29682   bool is_command_parameter_encryption_possible = false;
29683   bool is_response_parameter_encryption_possible = false;
29684   std::string command_code_bytes;
29685   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29686   if (rc != TPM_RC_SUCCESS) {
29687     return rc;
29688   }
29689   std::string auth_bytes;
29690   rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29691   if (rc != TPM_RC_SUCCESS) {
29692     return rc;
29693   }
29694   std::string new_time_bytes;
29695   rc = Serialize_UINT64(new_time, &new_time_bytes);
29696   if (rc != TPM_RC_SUCCESS) {
29697     return rc;
29698   }
29699   std::unique_ptr<crypto::SecureHash> hash(
29700       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29701   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29702   hash->Update(auth_name.data(), auth_name.size());
29703   handle_section_bytes += auth_bytes;
29704   command_size += auth_bytes.size();
29705   hash->Update(new_time_bytes.data(), new_time_bytes.size());
29706   parameter_section_bytes += new_time_bytes;
29707   command_size += new_time_bytes.size();
29708   std::string command_hash(32, 0);
29709   hash->Finish(std::data(command_hash), command_hash.size());
29710   std::string authorization_section_bytes;
29711   std::string authorization_size_bytes;
29712   if (authorization_delegate) {
29713     if (!authorization_delegate->GetCommandAuthorization(
29714             command_hash, is_command_parameter_encryption_possible,
29715             is_response_parameter_encryption_possible,
29716             &authorization_section_bytes)) {
29717       return TRUNKS_RC_AUTHORIZATION_FAILED;
29718     }
29719     if (!authorization_section_bytes.empty()) {
29720       tag = TPM_ST_SESSIONS;
29721       std::string tmp;
29722       rc = Serialize_UINT32(authorization_section_bytes.size(),
29723                             &authorization_size_bytes);
29724       if (rc != TPM_RC_SUCCESS) {
29725         return rc;
29726       }
29727       command_size +=
29728           authorization_size_bytes.size() + authorization_section_bytes.size();
29729     }
29730   }
29731   std::string tag_bytes;
29732   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29733   if (rc != TPM_RC_SUCCESS) {
29734     return rc;
29735   }
29736   std::string command_size_bytes;
29737   rc = Serialize_UINT32(command_size, &command_size_bytes);
29738   if (rc != TPM_RC_SUCCESS) {
29739     return rc;
29740   }
29741   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29742                         handle_section_bytes + authorization_size_bytes +
29743                         authorization_section_bytes + parameter_section_bytes;
29744   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29745   VLOG(2) << "Command: "
29746           << base::HexEncode(serialized_command->data(),
29747                              serialized_command->size());
29748   return TPM_RC_SUCCESS;
29749 }
29750 
ParseResponse_ClockSet(const std::string & response,AuthorizationDelegate * authorization_delegate)29751 TPM_RC Tpm::ParseResponse_ClockSet(
29752     const std::string& response,
29753     AuthorizationDelegate* authorization_delegate) {
29754   VLOG(3) << __func__;
29755   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29756   TPM_RC rc = TPM_RC_SUCCESS;
29757   std::string buffer(response);
29758   TPM_ST tag;
29759   std::string tag_bytes;
29760   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29761   if (rc != TPM_RC_SUCCESS) {
29762     return rc;
29763   }
29764   UINT32 response_size;
29765   std::string response_size_bytes;
29766   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29767   if (rc != TPM_RC_SUCCESS) {
29768     return rc;
29769   }
29770   TPM_RC response_code;
29771   std::string response_code_bytes;
29772   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29773   if (rc != TPM_RC_SUCCESS) {
29774     return rc;
29775   }
29776   if (response_size != response.size()) {
29777     return TPM_RC_SIZE;
29778   }
29779   if (response_code != TPM_RC_SUCCESS) {
29780     return response_code;
29781   }
29782   TPM_CC command_code = TPM_CC_ClockSet;
29783   std::string command_code_bytes;
29784   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29785   if (rc != TPM_RC_SUCCESS) {
29786     return rc;
29787   }
29788   std::string authorization_section_bytes;
29789   if (tag == TPM_ST_SESSIONS) {
29790     UINT32 parameter_section_size = buffer.size();
29791     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29792     if (rc != TPM_RC_SUCCESS) {
29793       return rc;
29794     }
29795     if (parameter_section_size > buffer.size()) {
29796       return TPM_RC_INSUFFICIENT;
29797     }
29798     authorization_section_bytes = buffer.substr(parameter_section_size);
29799     // Keep the parameter section in |buffer|.
29800     buffer.erase(parameter_section_size);
29801   }
29802   std::unique_ptr<crypto::SecureHash> hash(
29803       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29804   hash->Update(response_code_bytes.data(), response_code_bytes.size());
29805   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29806   hash->Update(buffer.data(), buffer.size());
29807   std::string response_hash(32, 0);
29808   hash->Finish(std::data(response_hash), response_hash.size());
29809   if (tag == TPM_ST_SESSIONS) {
29810     if (!authorization_delegate)
29811       return TRUNKS_RC_AUTHORIZATION_FAILED;
29812     if (!authorization_delegate->CheckResponseAuthorization(
29813             response_hash, authorization_section_bytes)) {
29814       return TRUNKS_RC_AUTHORIZATION_FAILED;
29815     }
29816   }
29817   return TPM_RC_SUCCESS;
29818 }
29819 
ClockSetErrorCallback(Tpm::ClockSetResponse callback,TPM_RC response_code)29820 void ClockSetErrorCallback(Tpm::ClockSetResponse callback,
29821                            TPM_RC response_code) {
29822   VLOG(1) << __func__;
29823   std::move(callback).Run(response_code);
29824 }
29825 
ClockSetResponseParser(Tpm::ClockSetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29826 void ClockSetResponseParser(Tpm::ClockSetResponse callback,
29827                             AuthorizationDelegate* authorization_delegate,
29828                             const std::string& response) {
29829   VLOG(1) << __func__;
29830   TPM_RC rc = Tpm::ParseResponse_ClockSet(response, authorization_delegate);
29831   if (rc != TPM_RC_SUCCESS) {
29832     base::OnceCallback<void(TPM_RC)> error_reporter =
29833         base::BindOnce(ClockSetErrorCallback, std::move(callback));
29834     std::move(error_reporter).Run(rc);
29835     return;
29836   }
29837   std::move(callback).Run(rc);
29838 }
29839 
ClockSet(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,AuthorizationDelegate * authorization_delegate,ClockSetResponse callback)29840 void Tpm::ClockSet(const TPMI_RH_PROVISION& auth,
29841                    const std::string& auth_name,
29842                    const UINT64& new_time,
29843                    AuthorizationDelegate* authorization_delegate,
29844                    ClockSetResponse callback) {
29845   VLOG(1) << __func__;
29846   std::string command;
29847   TPM_RC rc = SerializeCommand_ClockSet(auth, auth_name, new_time, &command,
29848                                         authorization_delegate);
29849   if (rc != TPM_RC_SUCCESS) {
29850     base::OnceCallback<void(TPM_RC)> error_reporter =
29851         base::BindOnce(ClockSetErrorCallback, std::move(callback));
29852     std::move(error_reporter).Run(rc);
29853     return;
29854   }
29855   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29856       ClockSetResponseParser, std::move(callback), authorization_delegate);
29857   transceiver_->SendCommand(command, std::move(parser));
29858 }
29859 
ClockSetSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,AuthorizationDelegate * authorization_delegate)29860 TPM_RC Tpm::ClockSetSync(const TPMI_RH_PROVISION& auth,
29861                          const std::string& auth_name,
29862                          const UINT64& new_time,
29863                          AuthorizationDelegate* authorization_delegate) {
29864   VLOG(1) << __func__;
29865   std::string command;
29866   TPM_RC rc = SerializeCommand_ClockSet(auth, auth_name, new_time, &command,
29867                                         authorization_delegate);
29868   if (rc != TPM_RC_SUCCESS) {
29869     return rc;
29870   }
29871   std::string response = transceiver_->SendCommandAndWait(command);
29872   rc = ParseResponse_ClockSet(response, authorization_delegate);
29873   return rc;
29874 }
29875 
SerializeCommand_ClockRateAdjust(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29876 TPM_RC Tpm::SerializeCommand_ClockRateAdjust(
29877     const TPMI_RH_PROVISION& auth,
29878     const std::string& auth_name,
29879     const TPM_CLOCK_ADJUST& rate_adjust,
29880     std::string* serialized_command,
29881     AuthorizationDelegate* authorization_delegate) {
29882   VLOG(3) << __func__;
29883   TPM_RC rc = TPM_RC_SUCCESS;
29884   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29885   UINT32 command_size = 10;  // Header size.
29886   std::string handle_section_bytes;
29887   std::string parameter_section_bytes;
29888   TPM_CC command_code = TPM_CC_ClockRateAdjust;
29889   bool is_command_parameter_encryption_possible = false;
29890   bool is_response_parameter_encryption_possible = false;
29891   std::string command_code_bytes;
29892   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29893   if (rc != TPM_RC_SUCCESS) {
29894     return rc;
29895   }
29896   std::string auth_bytes;
29897   rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29898   if (rc != TPM_RC_SUCCESS) {
29899     return rc;
29900   }
29901   std::string rate_adjust_bytes;
29902   rc = Serialize_TPM_CLOCK_ADJUST(rate_adjust, &rate_adjust_bytes);
29903   if (rc != TPM_RC_SUCCESS) {
29904     return rc;
29905   }
29906   std::unique_ptr<crypto::SecureHash> hash(
29907       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29908   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29909   hash->Update(auth_name.data(), auth_name.size());
29910   handle_section_bytes += auth_bytes;
29911   command_size += auth_bytes.size();
29912   hash->Update(rate_adjust_bytes.data(), rate_adjust_bytes.size());
29913   parameter_section_bytes += rate_adjust_bytes;
29914   command_size += rate_adjust_bytes.size();
29915   std::string command_hash(32, 0);
29916   hash->Finish(std::data(command_hash), command_hash.size());
29917   std::string authorization_section_bytes;
29918   std::string authorization_size_bytes;
29919   if (authorization_delegate) {
29920     if (!authorization_delegate->GetCommandAuthorization(
29921             command_hash, is_command_parameter_encryption_possible,
29922             is_response_parameter_encryption_possible,
29923             &authorization_section_bytes)) {
29924       return TRUNKS_RC_AUTHORIZATION_FAILED;
29925     }
29926     if (!authorization_section_bytes.empty()) {
29927       tag = TPM_ST_SESSIONS;
29928       std::string tmp;
29929       rc = Serialize_UINT32(authorization_section_bytes.size(),
29930                             &authorization_size_bytes);
29931       if (rc != TPM_RC_SUCCESS) {
29932         return rc;
29933       }
29934       command_size +=
29935           authorization_size_bytes.size() + authorization_section_bytes.size();
29936     }
29937   }
29938   std::string tag_bytes;
29939   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29940   if (rc != TPM_RC_SUCCESS) {
29941     return rc;
29942   }
29943   std::string command_size_bytes;
29944   rc = Serialize_UINT32(command_size, &command_size_bytes);
29945   if (rc != TPM_RC_SUCCESS) {
29946     return rc;
29947   }
29948   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29949                         handle_section_bytes + authorization_size_bytes +
29950                         authorization_section_bytes + parameter_section_bytes;
29951   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29952   VLOG(2) << "Command: "
29953           << base::HexEncode(serialized_command->data(),
29954                              serialized_command->size());
29955   return TPM_RC_SUCCESS;
29956 }
29957 
ParseResponse_ClockRateAdjust(const std::string & response,AuthorizationDelegate * authorization_delegate)29958 TPM_RC Tpm::ParseResponse_ClockRateAdjust(
29959     const std::string& response,
29960     AuthorizationDelegate* authorization_delegate) {
29961   VLOG(3) << __func__;
29962   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29963   TPM_RC rc = TPM_RC_SUCCESS;
29964   std::string buffer(response);
29965   TPM_ST tag;
29966   std::string tag_bytes;
29967   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29968   if (rc != TPM_RC_SUCCESS) {
29969     return rc;
29970   }
29971   UINT32 response_size;
29972   std::string response_size_bytes;
29973   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29974   if (rc != TPM_RC_SUCCESS) {
29975     return rc;
29976   }
29977   TPM_RC response_code;
29978   std::string response_code_bytes;
29979   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29980   if (rc != TPM_RC_SUCCESS) {
29981     return rc;
29982   }
29983   if (response_size != response.size()) {
29984     return TPM_RC_SIZE;
29985   }
29986   if (response_code != TPM_RC_SUCCESS) {
29987     return response_code;
29988   }
29989   TPM_CC command_code = TPM_CC_ClockRateAdjust;
29990   std::string command_code_bytes;
29991   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29992   if (rc != TPM_RC_SUCCESS) {
29993     return rc;
29994   }
29995   std::string authorization_section_bytes;
29996   if (tag == TPM_ST_SESSIONS) {
29997     UINT32 parameter_section_size = buffer.size();
29998     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29999     if (rc != TPM_RC_SUCCESS) {
30000       return rc;
30001     }
30002     if (parameter_section_size > buffer.size()) {
30003       return TPM_RC_INSUFFICIENT;
30004     }
30005     authorization_section_bytes = buffer.substr(parameter_section_size);
30006     // Keep the parameter section in |buffer|.
30007     buffer.erase(parameter_section_size);
30008   }
30009   std::unique_ptr<crypto::SecureHash> hash(
30010       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30011   hash->Update(response_code_bytes.data(), response_code_bytes.size());
30012   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30013   hash->Update(buffer.data(), buffer.size());
30014   std::string response_hash(32, 0);
30015   hash->Finish(std::data(response_hash), response_hash.size());
30016   if (tag == TPM_ST_SESSIONS) {
30017     if (!authorization_delegate)
30018       return TRUNKS_RC_AUTHORIZATION_FAILED;
30019     if (!authorization_delegate->CheckResponseAuthorization(
30020             response_hash, authorization_section_bytes)) {
30021       return TRUNKS_RC_AUTHORIZATION_FAILED;
30022     }
30023   }
30024   return TPM_RC_SUCCESS;
30025 }
30026 
ClockRateAdjustErrorCallback(Tpm::ClockRateAdjustResponse callback,TPM_RC response_code)30027 void ClockRateAdjustErrorCallback(Tpm::ClockRateAdjustResponse callback,
30028                                   TPM_RC response_code) {
30029   VLOG(1) << __func__;
30030   std::move(callback).Run(response_code);
30031 }
30032 
ClockRateAdjustResponseParser(Tpm::ClockRateAdjustResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30033 void ClockRateAdjustResponseParser(
30034     Tpm::ClockRateAdjustResponse callback,
30035     AuthorizationDelegate* authorization_delegate,
30036     const std::string& response) {
30037   VLOG(1) << __func__;
30038   TPM_RC rc =
30039       Tpm::ParseResponse_ClockRateAdjust(response, authorization_delegate);
30040   if (rc != TPM_RC_SUCCESS) {
30041     base::OnceCallback<void(TPM_RC)> error_reporter =
30042         base::BindOnce(ClockRateAdjustErrorCallback, std::move(callback));
30043     std::move(error_reporter).Run(rc);
30044     return;
30045   }
30046   std::move(callback).Run(rc);
30047 }
30048 
ClockRateAdjust(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,AuthorizationDelegate * authorization_delegate,ClockRateAdjustResponse callback)30049 void Tpm::ClockRateAdjust(const TPMI_RH_PROVISION& auth,
30050                           const std::string& auth_name,
30051                           const TPM_CLOCK_ADJUST& rate_adjust,
30052                           AuthorizationDelegate* authorization_delegate,
30053                           ClockRateAdjustResponse callback) {
30054   VLOG(1) << __func__;
30055   std::string command;
30056   TPM_RC rc = SerializeCommand_ClockRateAdjust(
30057       auth, auth_name, rate_adjust, &command, authorization_delegate);
30058   if (rc != TPM_RC_SUCCESS) {
30059     base::OnceCallback<void(TPM_RC)> error_reporter =
30060         base::BindOnce(ClockRateAdjustErrorCallback, std::move(callback));
30061     std::move(error_reporter).Run(rc);
30062     return;
30063   }
30064   base::OnceCallback<void(const std::string&)> parser =
30065       base::BindOnce(ClockRateAdjustResponseParser, std::move(callback),
30066                      authorization_delegate);
30067   transceiver_->SendCommand(command, std::move(parser));
30068 }
30069 
ClockRateAdjustSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,AuthorizationDelegate * authorization_delegate)30070 TPM_RC Tpm::ClockRateAdjustSync(const TPMI_RH_PROVISION& auth,
30071                                 const std::string& auth_name,
30072                                 const TPM_CLOCK_ADJUST& rate_adjust,
30073                                 AuthorizationDelegate* authorization_delegate) {
30074   VLOG(1) << __func__;
30075   std::string command;
30076   TPM_RC rc = SerializeCommand_ClockRateAdjust(
30077       auth, auth_name, rate_adjust, &command, authorization_delegate);
30078   if (rc != TPM_RC_SUCCESS) {
30079     return rc;
30080   }
30081   std::string response = transceiver_->SendCommandAndWait(command);
30082   rc = ParseResponse_ClockRateAdjust(response, authorization_delegate);
30083   return rc;
30084 }
30085 
SerializeCommand_GetCapability(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30086 TPM_RC Tpm::SerializeCommand_GetCapability(
30087     const TPM_CAP& capability,
30088     const UINT32& property,
30089     const UINT32& property_count,
30090     std::string* serialized_command,
30091     AuthorizationDelegate* authorization_delegate) {
30092   VLOG(3) << __func__;
30093   TPM_RC rc = TPM_RC_SUCCESS;
30094   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30095   UINT32 command_size = 10;  // Header size.
30096   std::string handle_section_bytes;
30097   std::string parameter_section_bytes;
30098   TPM_CC command_code = TPM_CC_GetCapability;
30099   bool is_command_parameter_encryption_possible = false;
30100   bool is_response_parameter_encryption_possible = false;
30101   std::string command_code_bytes;
30102   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30103   if (rc != TPM_RC_SUCCESS) {
30104     return rc;
30105   }
30106   std::string capability_bytes;
30107   rc = Serialize_TPM_CAP(capability, &capability_bytes);
30108   if (rc != TPM_RC_SUCCESS) {
30109     return rc;
30110   }
30111   std::string property_bytes;
30112   rc = Serialize_UINT32(property, &property_bytes);
30113   if (rc != TPM_RC_SUCCESS) {
30114     return rc;
30115   }
30116   std::string property_count_bytes;
30117   rc = Serialize_UINT32(property_count, &property_count_bytes);
30118   if (rc != TPM_RC_SUCCESS) {
30119     return rc;
30120   }
30121   std::unique_ptr<crypto::SecureHash> hash(
30122       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30123   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30124   hash->Update(capability_bytes.data(), capability_bytes.size());
30125   parameter_section_bytes += capability_bytes;
30126   command_size += capability_bytes.size();
30127   hash->Update(property_bytes.data(), property_bytes.size());
30128   parameter_section_bytes += property_bytes;
30129   command_size += property_bytes.size();
30130   hash->Update(property_count_bytes.data(), property_count_bytes.size());
30131   parameter_section_bytes += property_count_bytes;
30132   command_size += property_count_bytes.size();
30133   std::string command_hash(32, 0);
30134   hash->Finish(std::data(command_hash), command_hash.size());
30135   std::string authorization_section_bytes;
30136   std::string authorization_size_bytes;
30137   if (authorization_delegate) {
30138     if (!authorization_delegate->GetCommandAuthorization(
30139             command_hash, is_command_parameter_encryption_possible,
30140             is_response_parameter_encryption_possible,
30141             &authorization_section_bytes)) {
30142       return TRUNKS_RC_AUTHORIZATION_FAILED;
30143     }
30144     if (!authorization_section_bytes.empty()) {
30145       tag = TPM_ST_SESSIONS;
30146       std::string tmp;
30147       rc = Serialize_UINT32(authorization_section_bytes.size(),
30148                             &authorization_size_bytes);
30149       if (rc != TPM_RC_SUCCESS) {
30150         return rc;
30151       }
30152       command_size +=
30153           authorization_size_bytes.size() + authorization_section_bytes.size();
30154     }
30155   }
30156   std::string tag_bytes;
30157   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30158   if (rc != TPM_RC_SUCCESS) {
30159     return rc;
30160   }
30161   std::string command_size_bytes;
30162   rc = Serialize_UINT32(command_size, &command_size_bytes);
30163   if (rc != TPM_RC_SUCCESS) {
30164     return rc;
30165   }
30166   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30167                         handle_section_bytes + authorization_size_bytes +
30168                         authorization_section_bytes + parameter_section_bytes;
30169   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30170   VLOG(2) << "Command: "
30171           << base::HexEncode(serialized_command->data(),
30172                              serialized_command->size());
30173   return TPM_RC_SUCCESS;
30174 }
30175 
ParseResponse_GetCapability(const std::string & response,TPMI_YES_NO * more_data,TPMS_CAPABILITY_DATA * capability_data,AuthorizationDelegate * authorization_delegate)30176 TPM_RC Tpm::ParseResponse_GetCapability(
30177     const std::string& response,
30178     TPMI_YES_NO* more_data,
30179     TPMS_CAPABILITY_DATA* capability_data,
30180     AuthorizationDelegate* authorization_delegate) {
30181   VLOG(3) << __func__;
30182   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30183   TPM_RC rc = TPM_RC_SUCCESS;
30184   std::string buffer(response);
30185   TPM_ST tag;
30186   std::string tag_bytes;
30187   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30188   if (rc != TPM_RC_SUCCESS) {
30189     return rc;
30190   }
30191   UINT32 response_size;
30192   std::string response_size_bytes;
30193   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30194   if (rc != TPM_RC_SUCCESS) {
30195     return rc;
30196   }
30197   TPM_RC response_code;
30198   std::string response_code_bytes;
30199   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30200   if (rc != TPM_RC_SUCCESS) {
30201     return rc;
30202   }
30203   if (response_size != response.size()) {
30204     return TPM_RC_SIZE;
30205   }
30206   if (response_code != TPM_RC_SUCCESS) {
30207     return response_code;
30208   }
30209   TPM_CC command_code = TPM_CC_GetCapability;
30210   std::string command_code_bytes;
30211   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30212   if (rc != TPM_RC_SUCCESS) {
30213     return rc;
30214   }
30215   std::string authorization_section_bytes;
30216   if (tag == TPM_ST_SESSIONS) {
30217     UINT32 parameter_section_size = buffer.size();
30218     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30219     if (rc != TPM_RC_SUCCESS) {
30220       return rc;
30221     }
30222     if (parameter_section_size > buffer.size()) {
30223       return TPM_RC_INSUFFICIENT;
30224     }
30225     authorization_section_bytes = buffer.substr(parameter_section_size);
30226     // Keep the parameter section in |buffer|.
30227     buffer.erase(parameter_section_size);
30228   }
30229   std::unique_ptr<crypto::SecureHash> hash(
30230       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30231   hash->Update(response_code_bytes.data(), response_code_bytes.size());
30232   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30233   hash->Update(buffer.data(), buffer.size());
30234   std::string response_hash(32, 0);
30235   hash->Finish(std::data(response_hash), response_hash.size());
30236   if (tag == TPM_ST_SESSIONS) {
30237     if (!authorization_delegate)
30238       return TRUNKS_RC_AUTHORIZATION_FAILED;
30239     if (!authorization_delegate->CheckResponseAuthorization(
30240             response_hash, authorization_section_bytes)) {
30241       return TRUNKS_RC_AUTHORIZATION_FAILED;
30242     }
30243   }
30244   std::string more_data_bytes;
30245   rc = Parse_TPMI_YES_NO(&buffer, more_data, &more_data_bytes);
30246   if (rc != TPM_RC_SUCCESS) {
30247     return rc;
30248   }
30249   std::string capability_data_bytes;
30250   rc = Parse_TPMS_CAPABILITY_DATA(&buffer, capability_data,
30251                                   &capability_data_bytes);
30252   if (rc != TPM_RC_SUCCESS) {
30253     return rc;
30254   }
30255   return TPM_RC_SUCCESS;
30256 }
30257 
GetCapabilityErrorCallback(Tpm::GetCapabilityResponse callback,TPM_RC response_code)30258 void GetCapabilityErrorCallback(Tpm::GetCapabilityResponse callback,
30259                                 TPM_RC response_code) {
30260   VLOG(1) << __func__;
30261   std::move(callback).Run(response_code, TPMI_YES_NO(), TPMS_CAPABILITY_DATA());
30262 }
30263 
GetCapabilityResponseParser(Tpm::GetCapabilityResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30264 void GetCapabilityResponseParser(Tpm::GetCapabilityResponse callback,
30265                                  AuthorizationDelegate* authorization_delegate,
30266                                  const std::string& response) {
30267   VLOG(1) << __func__;
30268   TPMI_YES_NO more_data;
30269   TPMS_CAPABILITY_DATA capability_data;
30270   TPM_RC rc = Tpm::ParseResponse_GetCapability(
30271       response, &more_data, &capability_data, authorization_delegate);
30272   if (rc != TPM_RC_SUCCESS) {
30273     base::OnceCallback<void(TPM_RC)> error_reporter =
30274         base::BindOnce(GetCapabilityErrorCallback, std::move(callback));
30275     std::move(error_reporter).Run(rc);
30276     return;
30277   }
30278   std::move(callback).Run(rc, more_data, capability_data);
30279 }
30280 
GetCapability(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,AuthorizationDelegate * authorization_delegate,GetCapabilityResponse callback)30281 void Tpm::GetCapability(const TPM_CAP& capability,
30282                         const UINT32& property,
30283                         const UINT32& property_count,
30284                         AuthorizationDelegate* authorization_delegate,
30285                         GetCapabilityResponse callback) {
30286   VLOG(1) << __func__;
30287   std::string command;
30288   TPM_RC rc = SerializeCommand_GetCapability(
30289       capability, property, property_count, &command, authorization_delegate);
30290   if (rc != TPM_RC_SUCCESS) {
30291     base::OnceCallback<void(TPM_RC)> error_reporter =
30292         base::BindOnce(GetCapabilityErrorCallback, std::move(callback));
30293     std::move(error_reporter).Run(rc);
30294     return;
30295   }
30296   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
30297       GetCapabilityResponseParser, std::move(callback), authorization_delegate);
30298   transceiver_->SendCommand(command, std::move(parser));
30299 }
30300 
GetCapabilitySync(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,TPMI_YES_NO * more_data,TPMS_CAPABILITY_DATA * capability_data,AuthorizationDelegate * authorization_delegate)30301 TPM_RC Tpm::GetCapabilitySync(const TPM_CAP& capability,
30302                               const UINT32& property,
30303                               const UINT32& property_count,
30304                               TPMI_YES_NO* more_data,
30305                               TPMS_CAPABILITY_DATA* capability_data,
30306                               AuthorizationDelegate* authorization_delegate) {
30307   VLOG(1) << __func__;
30308   std::string command;
30309   TPM_RC rc = SerializeCommand_GetCapability(
30310       capability, property, property_count, &command, authorization_delegate);
30311   if (rc != TPM_RC_SUCCESS) {
30312     return rc;
30313   }
30314   std::string response = transceiver_->SendCommandAndWait(command);
30315   rc = ParseResponse_GetCapability(response, more_data, capability_data,
30316                                    authorization_delegate);
30317   return rc;
30318 }
30319 
SerializeCommand_TestParms(const TPMT_PUBLIC_PARMS & parameters,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30320 TPM_RC Tpm::SerializeCommand_TestParms(
30321     const TPMT_PUBLIC_PARMS& parameters,
30322     std::string* serialized_command,
30323     AuthorizationDelegate* authorization_delegate) {
30324   VLOG(3) << __func__;
30325   TPM_RC rc = TPM_RC_SUCCESS;
30326   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30327   UINT32 command_size = 10;  // Header size.
30328   std::string handle_section_bytes;
30329   std::string parameter_section_bytes;
30330   TPM_CC command_code = TPM_CC_TestParms;
30331   bool is_command_parameter_encryption_possible = false;
30332   bool is_response_parameter_encryption_possible = false;
30333   std::string command_code_bytes;
30334   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30335   if (rc != TPM_RC_SUCCESS) {
30336     return rc;
30337   }
30338   std::string parameters_bytes;
30339   rc = Serialize_TPMT_PUBLIC_PARMS(parameters, &parameters_bytes);
30340   if (rc != TPM_RC_SUCCESS) {
30341     return rc;
30342   }
30343   std::unique_ptr<crypto::SecureHash> hash(
30344       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30345   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30346   hash->Update(parameters_bytes.data(), parameters_bytes.size());
30347   parameter_section_bytes += parameters_bytes;
30348   command_size += parameters_bytes.size();
30349   std::string command_hash(32, 0);
30350   hash->Finish(std::data(command_hash), command_hash.size());
30351   std::string authorization_section_bytes;
30352   std::string authorization_size_bytes;
30353   if (authorization_delegate) {
30354     if (!authorization_delegate->GetCommandAuthorization(
30355             command_hash, is_command_parameter_encryption_possible,
30356             is_response_parameter_encryption_possible,
30357             &authorization_section_bytes)) {
30358       return TRUNKS_RC_AUTHORIZATION_FAILED;
30359     }
30360     if (!authorization_section_bytes.empty()) {
30361       tag = TPM_ST_SESSIONS;
30362       std::string tmp;
30363       rc = Serialize_UINT32(authorization_section_bytes.size(),
30364                             &authorization_size_bytes);
30365       if (rc != TPM_RC_SUCCESS) {
30366         return rc;
30367       }
30368       command_size +=
30369           authorization_size_bytes.size() + authorization_section_bytes.size();
30370     }
30371   }
30372   std::string tag_bytes;
30373   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30374   if (rc != TPM_RC_SUCCESS) {
30375     return rc;
30376   }
30377   std::string command_size_bytes;
30378   rc = Serialize_UINT32(command_size, &command_size_bytes);
30379   if (rc != TPM_RC_SUCCESS) {
30380     return rc;
30381   }
30382   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30383                         handle_section_bytes + authorization_size_bytes +
30384                         authorization_section_bytes + parameter_section_bytes;
30385   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30386   VLOG(2) << "Command: "
30387           << base::HexEncode(serialized_command->data(),
30388                              serialized_command->size());
30389   return TPM_RC_SUCCESS;
30390 }
30391 
ParseResponse_TestParms(const std::string & response,AuthorizationDelegate * authorization_delegate)30392 TPM_RC Tpm::ParseResponse_TestParms(
30393     const std::string& response,
30394     AuthorizationDelegate* authorization_delegate) {
30395   VLOG(3) << __func__;
30396   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30397   TPM_RC rc = TPM_RC_SUCCESS;
30398   std::string buffer(response);
30399   TPM_ST tag;
30400   std::string tag_bytes;
30401   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30402   if (rc != TPM_RC_SUCCESS) {
30403     return rc;
30404   }
30405   UINT32 response_size;
30406   std::string response_size_bytes;
30407   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30408   if (rc != TPM_RC_SUCCESS) {
30409     return rc;
30410   }
30411   TPM_RC response_code;
30412   std::string response_code_bytes;
30413   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30414   if (rc != TPM_RC_SUCCESS) {
30415     return rc;
30416   }
30417   if (response_size != response.size()) {
30418     return TPM_RC_SIZE;
30419   }
30420   if (response_code != TPM_RC_SUCCESS) {
30421     return response_code;
30422   }
30423   TPM_CC command_code = TPM_CC_TestParms;
30424   std::string command_code_bytes;
30425   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30426   if (rc != TPM_RC_SUCCESS) {
30427     return rc;
30428   }
30429   std::string authorization_section_bytes;
30430   if (tag == TPM_ST_SESSIONS) {
30431     UINT32 parameter_section_size = buffer.size();
30432     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30433     if (rc != TPM_RC_SUCCESS) {
30434       return rc;
30435     }
30436     if (parameter_section_size > buffer.size()) {
30437       return TPM_RC_INSUFFICIENT;
30438     }
30439     authorization_section_bytes = buffer.substr(parameter_section_size);
30440     // Keep the parameter section in |buffer|.
30441     buffer.erase(parameter_section_size);
30442   }
30443   std::unique_ptr<crypto::SecureHash> hash(
30444       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30445   hash->Update(response_code_bytes.data(), response_code_bytes.size());
30446   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30447   hash->Update(buffer.data(), buffer.size());
30448   std::string response_hash(32, 0);
30449   hash->Finish(std::data(response_hash), response_hash.size());
30450   if (tag == TPM_ST_SESSIONS) {
30451     if (!authorization_delegate)
30452       return TRUNKS_RC_AUTHORIZATION_FAILED;
30453     if (!authorization_delegate->CheckResponseAuthorization(
30454             response_hash, authorization_section_bytes)) {
30455       return TRUNKS_RC_AUTHORIZATION_FAILED;
30456     }
30457   }
30458   return TPM_RC_SUCCESS;
30459 }
30460 
TestParmsErrorCallback(Tpm::TestParmsResponse callback,TPM_RC response_code)30461 void TestParmsErrorCallback(Tpm::TestParmsResponse callback,
30462                             TPM_RC response_code) {
30463   VLOG(1) << __func__;
30464   std::move(callback).Run(response_code);
30465 }
30466 
TestParmsResponseParser(Tpm::TestParmsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30467 void TestParmsResponseParser(Tpm::TestParmsResponse callback,
30468                              AuthorizationDelegate* authorization_delegate,
30469                              const std::string& response) {
30470   VLOG(1) << __func__;
30471   TPM_RC rc = Tpm::ParseResponse_TestParms(response, authorization_delegate);
30472   if (rc != TPM_RC_SUCCESS) {
30473     base::OnceCallback<void(TPM_RC)> error_reporter =
30474         base::BindOnce(TestParmsErrorCallback, std::move(callback));
30475     std::move(error_reporter).Run(rc);
30476     return;
30477   }
30478   std::move(callback).Run(rc);
30479 }
30480 
TestParms(const TPMT_PUBLIC_PARMS & parameters,AuthorizationDelegate * authorization_delegate,TestParmsResponse callback)30481 void Tpm::TestParms(const TPMT_PUBLIC_PARMS& parameters,
30482                     AuthorizationDelegate* authorization_delegate,
30483                     TestParmsResponse callback) {
30484   VLOG(1) << __func__;
30485   std::string command;
30486   TPM_RC rc =
30487       SerializeCommand_TestParms(parameters, &command, authorization_delegate);
30488   if (rc != TPM_RC_SUCCESS) {
30489     base::OnceCallback<void(TPM_RC)> error_reporter =
30490         base::BindOnce(TestParmsErrorCallback, std::move(callback));
30491     std::move(error_reporter).Run(rc);
30492     return;
30493   }
30494   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
30495       TestParmsResponseParser, std::move(callback), authorization_delegate);
30496   transceiver_->SendCommand(command, std::move(parser));
30497 }
30498 
TestParmsSync(const TPMT_PUBLIC_PARMS & parameters,AuthorizationDelegate * authorization_delegate)30499 TPM_RC Tpm::TestParmsSync(const TPMT_PUBLIC_PARMS& parameters,
30500                           AuthorizationDelegate* authorization_delegate) {
30501   VLOG(1) << __func__;
30502   std::string command;
30503   TPM_RC rc =
30504       SerializeCommand_TestParms(parameters, &command, authorization_delegate);
30505   if (rc != TPM_RC_SUCCESS) {
30506     return rc;
30507   }
30508   std::string response = transceiver_->SendCommandAndWait(command);
30509   rc = ParseResponse_TestParms(response, authorization_delegate);
30510   return rc;
30511 }
30512 
SerializeCommand_NV_DefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & auth,const TPM2B_NV_PUBLIC & public_info,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30513 TPM_RC Tpm::SerializeCommand_NV_DefineSpace(
30514     const TPMI_RH_PROVISION& auth_handle,
30515     const std::string& auth_handle_name,
30516     const TPM2B_AUTH& auth,
30517     const TPM2B_NV_PUBLIC& public_info,
30518     std::string* serialized_command,
30519     AuthorizationDelegate* authorization_delegate) {
30520   VLOG(3) << __func__;
30521   TPM_RC rc = TPM_RC_SUCCESS;
30522   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30523   UINT32 command_size = 10;  // Header size.
30524   std::string handle_section_bytes;
30525   std::string parameter_section_bytes;
30526   TPM_CC command_code = TPM_CC_NV_DefineSpace;
30527   bool is_command_parameter_encryption_possible = true;
30528   bool is_response_parameter_encryption_possible = false;
30529   std::string command_code_bytes;
30530   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30531   if (rc != TPM_RC_SUCCESS) {
30532     return rc;
30533   }
30534   std::string auth_handle_bytes;
30535   rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
30536   if (rc != TPM_RC_SUCCESS) {
30537     return rc;
30538   }
30539   std::string auth_bytes;
30540   rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
30541   if (rc != TPM_RC_SUCCESS) {
30542     return rc;
30543   }
30544   std::string public_info_bytes;
30545   rc = Serialize_TPM2B_NV_PUBLIC(public_info, &public_info_bytes);
30546   if (rc != TPM_RC_SUCCESS) {
30547     return rc;
30548   }
30549   if (authorization_delegate) {
30550     // Encrypt just the parameter data, not the size.
30551     std::string tmp = auth_bytes.substr(2);
30552     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
30553       return TRUNKS_RC_ENCRYPTION_FAILED;
30554     }
30555     auth_bytes.replace(2, std::string::npos, tmp);
30556   }
30557   std::unique_ptr<crypto::SecureHash> hash(
30558       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30559   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30560   hash->Update(auth_handle_name.data(), auth_handle_name.size());
30561   handle_section_bytes += auth_handle_bytes;
30562   command_size += auth_handle_bytes.size();
30563   hash->Update(auth_bytes.data(), auth_bytes.size());
30564   parameter_section_bytes += auth_bytes;
30565   command_size += auth_bytes.size();
30566   hash->Update(public_info_bytes.data(), public_info_bytes.size());
30567   parameter_section_bytes += public_info_bytes;
30568   command_size += public_info_bytes.size();
30569   std::string command_hash(32, 0);
30570   hash->Finish(std::data(command_hash), command_hash.size());
30571   std::string authorization_section_bytes;
30572   std::string authorization_size_bytes;
30573   if (authorization_delegate) {
30574     if (!authorization_delegate->GetCommandAuthorization(
30575             command_hash, is_command_parameter_encryption_possible,
30576             is_response_parameter_encryption_possible,
30577             &authorization_section_bytes)) {
30578       return TRUNKS_RC_AUTHORIZATION_FAILED;
30579     }
30580     if (!authorization_section_bytes.empty()) {
30581       tag = TPM_ST_SESSIONS;
30582       std::string tmp;
30583       rc = Serialize_UINT32(authorization_section_bytes.size(),
30584                             &authorization_size_bytes);
30585       if (rc != TPM_RC_SUCCESS) {
30586         return rc;
30587       }
30588       command_size +=
30589           authorization_size_bytes.size() + authorization_section_bytes.size();
30590     }
30591   }
30592   std::string tag_bytes;
30593   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30594   if (rc != TPM_RC_SUCCESS) {
30595     return rc;
30596   }
30597   std::string command_size_bytes;
30598   rc = Serialize_UINT32(command_size, &command_size_bytes);
30599   if (rc != TPM_RC_SUCCESS) {
30600     return rc;
30601   }
30602   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30603                         handle_section_bytes + authorization_size_bytes +
30604                         authorization_section_bytes + parameter_section_bytes;
30605   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30606   VLOG(2) << "Command: "
30607           << base::HexEncode(serialized_command->data(),
30608                              serialized_command->size());
30609   return TPM_RC_SUCCESS;
30610 }
30611 
ParseResponse_NV_DefineSpace(const std::string & response,AuthorizationDelegate * authorization_delegate)30612 TPM_RC Tpm::ParseResponse_NV_DefineSpace(
30613     const std::string& response,
30614     AuthorizationDelegate* authorization_delegate) {
30615   VLOG(3) << __func__;
30616   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30617   TPM_RC rc = TPM_RC_SUCCESS;
30618   std::string buffer(response);
30619   TPM_ST tag;
30620   std::string tag_bytes;
30621   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30622   if (rc != TPM_RC_SUCCESS) {
30623     return rc;
30624   }
30625   UINT32 response_size;
30626   std::string response_size_bytes;
30627   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30628   if (rc != TPM_RC_SUCCESS) {
30629     return rc;
30630   }
30631   TPM_RC response_code;
30632   std::string response_code_bytes;
30633   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30634   if (rc != TPM_RC_SUCCESS) {
30635     return rc;
30636   }
30637   if (response_size != response.size()) {
30638     return TPM_RC_SIZE;
30639   }
30640   if (response_code != TPM_RC_SUCCESS) {
30641     return response_code;
30642   }
30643   TPM_CC command_code = TPM_CC_NV_DefineSpace;
30644   std::string command_code_bytes;
30645   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30646   if (rc != TPM_RC_SUCCESS) {
30647     return rc;
30648   }
30649   std::string authorization_section_bytes;
30650   if (tag == TPM_ST_SESSIONS) {
30651     UINT32 parameter_section_size = buffer.size();
30652     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30653     if (rc != TPM_RC_SUCCESS) {
30654       return rc;
30655     }
30656     if (parameter_section_size > buffer.size()) {
30657       return TPM_RC_INSUFFICIENT;
30658     }
30659     authorization_section_bytes = buffer.substr(parameter_section_size);
30660     // Keep the parameter section in |buffer|.
30661     buffer.erase(parameter_section_size);
30662   }
30663   std::unique_ptr<crypto::SecureHash> hash(
30664       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30665   hash->Update(response_code_bytes.data(), response_code_bytes.size());
30666   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30667   hash->Update(buffer.data(), buffer.size());
30668   std::string response_hash(32, 0);
30669   hash->Finish(std::data(response_hash), response_hash.size());
30670   if (tag == TPM_ST_SESSIONS) {
30671     if (!authorization_delegate)
30672       return TRUNKS_RC_AUTHORIZATION_FAILED;
30673     if (!authorization_delegate->CheckResponseAuthorization(
30674             response_hash, authorization_section_bytes)) {
30675       return TRUNKS_RC_AUTHORIZATION_FAILED;
30676     }
30677   }
30678   return TPM_RC_SUCCESS;
30679 }
30680 
NV_DefineSpaceErrorCallback(Tpm::NV_DefineSpaceResponse callback,TPM_RC response_code)30681 void NV_DefineSpaceErrorCallback(Tpm::NV_DefineSpaceResponse callback,
30682                                  TPM_RC response_code) {
30683   VLOG(1) << __func__;
30684   std::move(callback).Run(response_code);
30685 }
30686 
NV_DefineSpaceResponseParser(Tpm::NV_DefineSpaceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30687 void NV_DefineSpaceResponseParser(Tpm::NV_DefineSpaceResponse callback,
30688                                   AuthorizationDelegate* authorization_delegate,
30689                                   const std::string& response) {
30690   VLOG(1) << __func__;
30691   TPM_RC rc =
30692       Tpm::ParseResponse_NV_DefineSpace(response, authorization_delegate);
30693   if (rc != TPM_RC_SUCCESS) {
30694     base::OnceCallback<void(TPM_RC)> error_reporter =
30695         base::BindOnce(NV_DefineSpaceErrorCallback, std::move(callback));
30696     std::move(error_reporter).Run(rc);
30697     return;
30698   }
30699   std::move(callback).Run(rc);
30700 }
30701 
NV_DefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & auth,const TPM2B_NV_PUBLIC & public_info,AuthorizationDelegate * authorization_delegate,NV_DefineSpaceResponse callback)30702 void Tpm::NV_DefineSpace(const TPMI_RH_PROVISION& auth_handle,
30703                          const std::string& auth_handle_name,
30704                          const TPM2B_AUTH& auth,
30705                          const TPM2B_NV_PUBLIC& public_info,
30706                          AuthorizationDelegate* authorization_delegate,
30707                          NV_DefineSpaceResponse callback) {
30708   VLOG(1) << __func__;
30709   std::string command;
30710   TPM_RC rc = SerializeCommand_NV_DefineSpace(auth_handle, auth_handle_name,
30711                                               auth, public_info, &command,
30712                                               authorization_delegate);
30713   if (rc != TPM_RC_SUCCESS) {
30714     base::OnceCallback<void(TPM_RC)> error_reporter =
30715         base::BindOnce(NV_DefineSpaceErrorCallback, std::move(callback));
30716     std::move(error_reporter).Run(rc);
30717     return;
30718   }
30719   base::OnceCallback<void(const std::string&)> parser =
30720       base::BindOnce(NV_DefineSpaceResponseParser, std::move(callback),
30721                      authorization_delegate);
30722   transceiver_->SendCommand(command, std::move(parser));
30723 }
30724 
NV_DefineSpaceSync(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & auth,const TPM2B_NV_PUBLIC & public_info,AuthorizationDelegate * authorization_delegate)30725 TPM_RC Tpm::NV_DefineSpaceSync(const TPMI_RH_PROVISION& auth_handle,
30726                                const std::string& auth_handle_name,
30727                                const TPM2B_AUTH& auth,
30728                                const TPM2B_NV_PUBLIC& public_info,
30729                                AuthorizationDelegate* authorization_delegate) {
30730   VLOG(1) << __func__;
30731   std::string command;
30732   TPM_RC rc = SerializeCommand_NV_DefineSpace(auth_handle, auth_handle_name,
30733                                               auth, public_info, &command,
30734                                               authorization_delegate);
30735   if (rc != TPM_RC_SUCCESS) {
30736     return rc;
30737   }
30738   std::string response = transceiver_->SendCommandAndWait(command);
30739   rc = ParseResponse_NV_DefineSpace(response, authorization_delegate);
30740   return rc;
30741 }
30742 
SerializeCommand_NV_UndefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30743 TPM_RC Tpm::SerializeCommand_NV_UndefineSpace(
30744     const TPMI_RH_PROVISION& auth_handle,
30745     const std::string& auth_handle_name,
30746     const TPMI_RH_NV_INDEX& nv_index,
30747     const std::string& nv_index_name,
30748     std::string* serialized_command,
30749     AuthorizationDelegate* authorization_delegate) {
30750   VLOG(3) << __func__;
30751   TPM_RC rc = TPM_RC_SUCCESS;
30752   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30753   UINT32 command_size = 10;  // Header size.
30754   std::string handle_section_bytes;
30755   std::string parameter_section_bytes;
30756   TPM_CC command_code = TPM_CC_NV_UndefineSpace;
30757   bool is_command_parameter_encryption_possible = false;
30758   bool is_response_parameter_encryption_possible = false;
30759   std::string command_code_bytes;
30760   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30761   if (rc != TPM_RC_SUCCESS) {
30762     return rc;
30763   }
30764   std::string auth_handle_bytes;
30765   rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
30766   if (rc != TPM_RC_SUCCESS) {
30767     return rc;
30768   }
30769   std::string nv_index_bytes;
30770   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30771   if (rc != TPM_RC_SUCCESS) {
30772     return rc;
30773   }
30774   std::unique_ptr<crypto::SecureHash> hash(
30775       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30776   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30777   hash->Update(auth_handle_name.data(), auth_handle_name.size());
30778   handle_section_bytes += auth_handle_bytes;
30779   command_size += auth_handle_bytes.size();
30780   hash->Update(nv_index_name.data(), nv_index_name.size());
30781   handle_section_bytes += nv_index_bytes;
30782   command_size += nv_index_bytes.size();
30783   std::string command_hash(32, 0);
30784   hash->Finish(std::data(command_hash), command_hash.size());
30785   std::string authorization_section_bytes;
30786   std::string authorization_size_bytes;
30787   if (authorization_delegate) {
30788     if (!authorization_delegate->GetCommandAuthorization(
30789             command_hash, is_command_parameter_encryption_possible,
30790             is_response_parameter_encryption_possible,
30791             &authorization_section_bytes)) {
30792       return TRUNKS_RC_AUTHORIZATION_FAILED;
30793     }
30794     if (!authorization_section_bytes.empty()) {
30795       tag = TPM_ST_SESSIONS;
30796       std::string tmp;
30797       rc = Serialize_UINT32(authorization_section_bytes.size(),
30798                             &authorization_size_bytes);
30799       if (rc != TPM_RC_SUCCESS) {
30800         return rc;
30801       }
30802       command_size +=
30803           authorization_size_bytes.size() + authorization_section_bytes.size();
30804     }
30805   }
30806   std::string tag_bytes;
30807   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30808   if (rc != TPM_RC_SUCCESS) {
30809     return rc;
30810   }
30811   std::string command_size_bytes;
30812   rc = Serialize_UINT32(command_size, &command_size_bytes);
30813   if (rc != TPM_RC_SUCCESS) {
30814     return rc;
30815   }
30816   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30817                         handle_section_bytes + authorization_size_bytes +
30818                         authorization_section_bytes + parameter_section_bytes;
30819   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30820   VLOG(2) << "Command: "
30821           << base::HexEncode(serialized_command->data(),
30822                              serialized_command->size());
30823   return TPM_RC_SUCCESS;
30824 }
30825 
ParseResponse_NV_UndefineSpace(const std::string & response,AuthorizationDelegate * authorization_delegate)30826 TPM_RC Tpm::ParseResponse_NV_UndefineSpace(
30827     const std::string& response,
30828     AuthorizationDelegate* authorization_delegate) {
30829   VLOG(3) << __func__;
30830   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30831   TPM_RC rc = TPM_RC_SUCCESS;
30832   std::string buffer(response);
30833   TPM_ST tag;
30834   std::string tag_bytes;
30835   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30836   if (rc != TPM_RC_SUCCESS) {
30837     return rc;
30838   }
30839   UINT32 response_size;
30840   std::string response_size_bytes;
30841   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30842   if (rc != TPM_RC_SUCCESS) {
30843     return rc;
30844   }
30845   TPM_RC response_code;
30846   std::string response_code_bytes;
30847   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30848   if (rc != TPM_RC_SUCCESS) {
30849     return rc;
30850   }
30851   if (response_size != response.size()) {
30852     return TPM_RC_SIZE;
30853   }
30854   if (response_code != TPM_RC_SUCCESS) {
30855     return response_code;
30856   }
30857   TPM_CC command_code = TPM_CC_NV_UndefineSpace;
30858   std::string command_code_bytes;
30859   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30860   if (rc != TPM_RC_SUCCESS) {
30861     return rc;
30862   }
30863   std::string authorization_section_bytes;
30864   if (tag == TPM_ST_SESSIONS) {
30865     UINT32 parameter_section_size = buffer.size();
30866     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30867     if (rc != TPM_RC_SUCCESS) {
30868       return rc;
30869     }
30870     if (parameter_section_size > buffer.size()) {
30871       return TPM_RC_INSUFFICIENT;
30872     }
30873     authorization_section_bytes = buffer.substr(parameter_section_size);
30874     // Keep the parameter section in |buffer|.
30875     buffer.erase(parameter_section_size);
30876   }
30877   std::unique_ptr<crypto::SecureHash> hash(
30878       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30879   hash->Update(response_code_bytes.data(), response_code_bytes.size());
30880   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30881   hash->Update(buffer.data(), buffer.size());
30882   std::string response_hash(32, 0);
30883   hash->Finish(std::data(response_hash), response_hash.size());
30884   if (tag == TPM_ST_SESSIONS) {
30885     if (!authorization_delegate)
30886       return TRUNKS_RC_AUTHORIZATION_FAILED;
30887     if (!authorization_delegate->CheckResponseAuthorization(
30888             response_hash, authorization_section_bytes)) {
30889       return TRUNKS_RC_AUTHORIZATION_FAILED;
30890     }
30891   }
30892   return TPM_RC_SUCCESS;
30893 }
30894 
NV_UndefineSpaceErrorCallback(Tpm::NV_UndefineSpaceResponse callback,TPM_RC response_code)30895 void NV_UndefineSpaceErrorCallback(Tpm::NV_UndefineSpaceResponse callback,
30896                                    TPM_RC response_code) {
30897   VLOG(1) << __func__;
30898   std::move(callback).Run(response_code);
30899 }
30900 
NV_UndefineSpaceResponseParser(Tpm::NV_UndefineSpaceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30901 void NV_UndefineSpaceResponseParser(
30902     Tpm::NV_UndefineSpaceResponse callback,
30903     AuthorizationDelegate* authorization_delegate,
30904     const std::string& response) {
30905   VLOG(1) << __func__;
30906   TPM_RC rc =
30907       Tpm::ParseResponse_NV_UndefineSpace(response, authorization_delegate);
30908   if (rc != TPM_RC_SUCCESS) {
30909     base::OnceCallback<void(TPM_RC)> error_reporter =
30910         base::BindOnce(NV_UndefineSpaceErrorCallback, std::move(callback));
30911     std::move(error_reporter).Run(rc);
30912     return;
30913   }
30914   std::move(callback).Run(rc);
30915 }
30916 
NV_UndefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_UndefineSpaceResponse callback)30917 void Tpm::NV_UndefineSpace(const TPMI_RH_PROVISION& auth_handle,
30918                            const std::string& auth_handle_name,
30919                            const TPMI_RH_NV_INDEX& nv_index,
30920                            const std::string& nv_index_name,
30921                            AuthorizationDelegate* authorization_delegate,
30922                            NV_UndefineSpaceResponse callback) {
30923   VLOG(1) << __func__;
30924   std::string command;
30925   TPM_RC rc = SerializeCommand_NV_UndefineSpace(
30926       auth_handle, auth_handle_name, nv_index, nv_index_name, &command,
30927       authorization_delegate);
30928   if (rc != TPM_RC_SUCCESS) {
30929     base::OnceCallback<void(TPM_RC)> error_reporter =
30930         base::BindOnce(NV_UndefineSpaceErrorCallback, std::move(callback));
30931     std::move(error_reporter).Run(rc);
30932     return;
30933   }
30934   base::OnceCallback<void(const std::string&)> parser =
30935       base::BindOnce(NV_UndefineSpaceResponseParser, std::move(callback),
30936                      authorization_delegate);
30937   transceiver_->SendCommand(command, std::move(parser));
30938 }
30939 
NV_UndefineSpaceSync(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)30940 TPM_RC Tpm::NV_UndefineSpaceSync(
30941     const TPMI_RH_PROVISION& auth_handle,
30942     const std::string& auth_handle_name,
30943     const TPMI_RH_NV_INDEX& nv_index,
30944     const std::string& nv_index_name,
30945     AuthorizationDelegate* authorization_delegate) {
30946   VLOG(1) << __func__;
30947   std::string command;
30948   TPM_RC rc = SerializeCommand_NV_UndefineSpace(
30949       auth_handle, auth_handle_name, nv_index, nv_index_name, &command,
30950       authorization_delegate);
30951   if (rc != TPM_RC_SUCCESS) {
30952     return rc;
30953   }
30954   std::string response = transceiver_->SendCommandAndWait(command);
30955   rc = ParseResponse_NV_UndefineSpace(response, authorization_delegate);
30956   return rc;
30957 }
30958 
SerializeCommand_NV_UndefineSpaceSpecial(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_RH_PLATFORM & platform,const std::string & platform_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30959 TPM_RC Tpm::SerializeCommand_NV_UndefineSpaceSpecial(
30960     const TPMI_RH_NV_INDEX& nv_index,
30961     const std::string& nv_index_name,
30962     const TPMI_RH_PLATFORM& platform,
30963     const std::string& platform_name,
30964     std::string* serialized_command,
30965     AuthorizationDelegate* authorization_delegate) {
30966   VLOG(3) << __func__;
30967   TPM_RC rc = TPM_RC_SUCCESS;
30968   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30969   UINT32 command_size = 10;  // Header size.
30970   std::string handle_section_bytes;
30971   std::string parameter_section_bytes;
30972   TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial;
30973   bool is_command_parameter_encryption_possible = false;
30974   bool is_response_parameter_encryption_possible = false;
30975   std::string command_code_bytes;
30976   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30977   if (rc != TPM_RC_SUCCESS) {
30978     return rc;
30979   }
30980   std::string nv_index_bytes;
30981   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30982   if (rc != TPM_RC_SUCCESS) {
30983     return rc;
30984   }
30985   std::string platform_bytes;
30986   rc = Serialize_TPMI_RH_PLATFORM(platform, &platform_bytes);
30987   if (rc != TPM_RC_SUCCESS) {
30988     return rc;
30989   }
30990   std::unique_ptr<crypto::SecureHash> hash(
30991       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30992   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30993   hash->Update(nv_index_name.data(), nv_index_name.size());
30994   handle_section_bytes += nv_index_bytes;
30995   command_size += nv_index_bytes.size();
30996   hash->Update(platform_name.data(), platform_name.size());
30997   handle_section_bytes += platform_bytes;
30998   command_size += platform_bytes.size();
30999   std::string command_hash(32, 0);
31000   hash->Finish(std::data(command_hash), command_hash.size());
31001   std::string authorization_section_bytes;
31002   std::string authorization_size_bytes;
31003   if (authorization_delegate) {
31004     if (!authorization_delegate->GetCommandAuthorization(
31005             command_hash, is_command_parameter_encryption_possible,
31006             is_response_parameter_encryption_possible,
31007             &authorization_section_bytes)) {
31008       return TRUNKS_RC_AUTHORIZATION_FAILED;
31009     }
31010     if (!authorization_section_bytes.empty()) {
31011       tag = TPM_ST_SESSIONS;
31012       std::string tmp;
31013       rc = Serialize_UINT32(authorization_section_bytes.size(),
31014                             &authorization_size_bytes);
31015       if (rc != TPM_RC_SUCCESS) {
31016         return rc;
31017       }
31018       command_size +=
31019           authorization_size_bytes.size() + authorization_section_bytes.size();
31020     }
31021   }
31022   std::string tag_bytes;
31023   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31024   if (rc != TPM_RC_SUCCESS) {
31025     return rc;
31026   }
31027   std::string command_size_bytes;
31028   rc = Serialize_UINT32(command_size, &command_size_bytes);
31029   if (rc != TPM_RC_SUCCESS) {
31030     return rc;
31031   }
31032   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31033                         handle_section_bytes + authorization_size_bytes +
31034                         authorization_section_bytes + parameter_section_bytes;
31035   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31036   VLOG(2) << "Command: "
31037           << base::HexEncode(serialized_command->data(),
31038                              serialized_command->size());
31039   return TPM_RC_SUCCESS;
31040 }
31041 
ParseResponse_NV_UndefineSpaceSpecial(const std::string & response,AuthorizationDelegate * authorization_delegate)31042 TPM_RC Tpm::ParseResponse_NV_UndefineSpaceSpecial(
31043     const std::string& response,
31044     AuthorizationDelegate* authorization_delegate) {
31045   VLOG(3) << __func__;
31046   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31047   TPM_RC rc = TPM_RC_SUCCESS;
31048   std::string buffer(response);
31049   TPM_ST tag;
31050   std::string tag_bytes;
31051   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31052   if (rc != TPM_RC_SUCCESS) {
31053     return rc;
31054   }
31055   UINT32 response_size;
31056   std::string response_size_bytes;
31057   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31058   if (rc != TPM_RC_SUCCESS) {
31059     return rc;
31060   }
31061   TPM_RC response_code;
31062   std::string response_code_bytes;
31063   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31064   if (rc != TPM_RC_SUCCESS) {
31065     return rc;
31066   }
31067   if (response_size != response.size()) {
31068     return TPM_RC_SIZE;
31069   }
31070   if (response_code != TPM_RC_SUCCESS) {
31071     return response_code;
31072   }
31073   TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial;
31074   std::string command_code_bytes;
31075   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31076   if (rc != TPM_RC_SUCCESS) {
31077     return rc;
31078   }
31079   std::string authorization_section_bytes;
31080   if (tag == TPM_ST_SESSIONS) {
31081     UINT32 parameter_section_size = buffer.size();
31082     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31083     if (rc != TPM_RC_SUCCESS) {
31084       return rc;
31085     }
31086     if (parameter_section_size > buffer.size()) {
31087       return TPM_RC_INSUFFICIENT;
31088     }
31089     authorization_section_bytes = buffer.substr(parameter_section_size);
31090     // Keep the parameter section in |buffer|.
31091     buffer.erase(parameter_section_size);
31092   }
31093   std::unique_ptr<crypto::SecureHash> hash(
31094       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31095   hash->Update(response_code_bytes.data(), response_code_bytes.size());
31096   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31097   hash->Update(buffer.data(), buffer.size());
31098   std::string response_hash(32, 0);
31099   hash->Finish(std::data(response_hash), response_hash.size());
31100   if (tag == TPM_ST_SESSIONS) {
31101     if (!authorization_delegate)
31102       return TRUNKS_RC_AUTHORIZATION_FAILED;
31103     if (!authorization_delegate->CheckResponseAuthorization(
31104             response_hash, authorization_section_bytes)) {
31105       return TRUNKS_RC_AUTHORIZATION_FAILED;
31106     }
31107   }
31108   return TPM_RC_SUCCESS;
31109 }
31110 
NV_UndefineSpaceSpecialErrorCallback(Tpm::NV_UndefineSpaceSpecialResponse callback,TPM_RC response_code)31111 void NV_UndefineSpaceSpecialErrorCallback(
31112     Tpm::NV_UndefineSpaceSpecialResponse callback, TPM_RC response_code) {
31113   VLOG(1) << __func__;
31114   std::move(callback).Run(response_code);
31115 }
31116 
NV_UndefineSpaceSpecialResponseParser(Tpm::NV_UndefineSpaceSpecialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31117 void NV_UndefineSpaceSpecialResponseParser(
31118     Tpm::NV_UndefineSpaceSpecialResponse callback,
31119     AuthorizationDelegate* authorization_delegate,
31120     const std::string& response) {
31121   VLOG(1) << __func__;
31122   TPM_RC rc = Tpm::ParseResponse_NV_UndefineSpaceSpecial(
31123       response, authorization_delegate);
31124   if (rc != TPM_RC_SUCCESS) {
31125     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
31126         NV_UndefineSpaceSpecialErrorCallback, std::move(callback));
31127     std::move(error_reporter).Run(rc);
31128     return;
31129   }
31130   std::move(callback).Run(rc);
31131 }
31132 
NV_UndefineSpaceSpecial(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_RH_PLATFORM & platform,const std::string & platform_name,AuthorizationDelegate * authorization_delegate,NV_UndefineSpaceSpecialResponse callback)31133 void Tpm::NV_UndefineSpaceSpecial(const TPMI_RH_NV_INDEX& nv_index,
31134                                   const std::string& nv_index_name,
31135                                   const TPMI_RH_PLATFORM& platform,
31136                                   const std::string& platform_name,
31137                                   AuthorizationDelegate* authorization_delegate,
31138                                   NV_UndefineSpaceSpecialResponse callback) {
31139   VLOG(1) << __func__;
31140   std::string command;
31141   TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial(
31142       nv_index, nv_index_name, platform, platform_name, &command,
31143       authorization_delegate);
31144   if (rc != TPM_RC_SUCCESS) {
31145     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
31146         NV_UndefineSpaceSpecialErrorCallback, std::move(callback));
31147     std::move(error_reporter).Run(rc);
31148     return;
31149   }
31150   base::OnceCallback<void(const std::string&)> parser =
31151       base::BindOnce(NV_UndefineSpaceSpecialResponseParser, std::move(callback),
31152                      authorization_delegate);
31153   transceiver_->SendCommand(command, std::move(parser));
31154 }
31155 
NV_UndefineSpaceSpecialSync(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_RH_PLATFORM & platform,const std::string & platform_name,AuthorizationDelegate * authorization_delegate)31156 TPM_RC Tpm::NV_UndefineSpaceSpecialSync(
31157     const TPMI_RH_NV_INDEX& nv_index,
31158     const std::string& nv_index_name,
31159     const TPMI_RH_PLATFORM& platform,
31160     const std::string& platform_name,
31161     AuthorizationDelegate* authorization_delegate) {
31162   VLOG(1) << __func__;
31163   std::string command;
31164   TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial(
31165       nv_index, nv_index_name, platform, platform_name, &command,
31166       authorization_delegate);
31167   if (rc != TPM_RC_SUCCESS) {
31168     return rc;
31169   }
31170   std::string response = transceiver_->SendCommandAndWait(command);
31171   rc = ParseResponse_NV_UndefineSpaceSpecial(response, authorization_delegate);
31172   return rc;
31173 }
31174 
SerializeCommand_NV_ReadPublic(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31175 TPM_RC Tpm::SerializeCommand_NV_ReadPublic(
31176     const TPMI_RH_NV_INDEX& nv_index,
31177     const std::string& nv_index_name,
31178     std::string* serialized_command,
31179     AuthorizationDelegate* authorization_delegate) {
31180   VLOG(3) << __func__;
31181   TPM_RC rc = TPM_RC_SUCCESS;
31182   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31183   UINT32 command_size = 10;  // Header size.
31184   std::string handle_section_bytes;
31185   std::string parameter_section_bytes;
31186   TPM_CC command_code = TPM_CC_NV_ReadPublic;
31187   bool is_command_parameter_encryption_possible = false;
31188   bool is_response_parameter_encryption_possible = true;
31189   std::string command_code_bytes;
31190   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31191   if (rc != TPM_RC_SUCCESS) {
31192     return rc;
31193   }
31194   std::string nv_index_bytes;
31195   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31196   if (rc != TPM_RC_SUCCESS) {
31197     return rc;
31198   }
31199   std::unique_ptr<crypto::SecureHash> hash(
31200       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31201   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31202   hash->Update(nv_index_name.data(), nv_index_name.size());
31203   handle_section_bytes += nv_index_bytes;
31204   command_size += nv_index_bytes.size();
31205   std::string command_hash(32, 0);
31206   hash->Finish(std::data(command_hash), command_hash.size());
31207   std::string authorization_section_bytes;
31208   std::string authorization_size_bytes;
31209   if (authorization_delegate) {
31210     if (!authorization_delegate->GetCommandAuthorization(
31211             command_hash, is_command_parameter_encryption_possible,
31212             is_response_parameter_encryption_possible,
31213             &authorization_section_bytes)) {
31214       return TRUNKS_RC_AUTHORIZATION_FAILED;
31215     }
31216     if (!authorization_section_bytes.empty()) {
31217       tag = TPM_ST_SESSIONS;
31218       std::string tmp;
31219       rc = Serialize_UINT32(authorization_section_bytes.size(),
31220                             &authorization_size_bytes);
31221       if (rc != TPM_RC_SUCCESS) {
31222         return rc;
31223       }
31224       command_size +=
31225           authorization_size_bytes.size() + authorization_section_bytes.size();
31226     }
31227   }
31228   std::string tag_bytes;
31229   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31230   if (rc != TPM_RC_SUCCESS) {
31231     return rc;
31232   }
31233   std::string command_size_bytes;
31234   rc = Serialize_UINT32(command_size, &command_size_bytes);
31235   if (rc != TPM_RC_SUCCESS) {
31236     return rc;
31237   }
31238   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31239                         handle_section_bytes + authorization_size_bytes +
31240                         authorization_section_bytes + parameter_section_bytes;
31241   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31242   VLOG(2) << "Command: "
31243           << base::HexEncode(serialized_command->data(),
31244                              serialized_command->size());
31245   return TPM_RC_SUCCESS;
31246 }
31247 
ParseResponse_NV_ReadPublic(const std::string & response,TPM2B_NV_PUBLIC * nv_public,TPM2B_NAME * nv_name,AuthorizationDelegate * authorization_delegate)31248 TPM_RC Tpm::ParseResponse_NV_ReadPublic(
31249     const std::string& response,
31250     TPM2B_NV_PUBLIC* nv_public,
31251     TPM2B_NAME* nv_name,
31252     AuthorizationDelegate* authorization_delegate) {
31253   VLOG(3) << __func__;
31254   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31255   TPM_RC rc = TPM_RC_SUCCESS;
31256   std::string buffer(response);
31257   TPM_ST tag;
31258   std::string tag_bytes;
31259   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31260   if (rc != TPM_RC_SUCCESS) {
31261     return rc;
31262   }
31263   UINT32 response_size;
31264   std::string response_size_bytes;
31265   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31266   if (rc != TPM_RC_SUCCESS) {
31267     return rc;
31268   }
31269   TPM_RC response_code;
31270   std::string response_code_bytes;
31271   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31272   if (rc != TPM_RC_SUCCESS) {
31273     return rc;
31274   }
31275   if (response_size != response.size()) {
31276     return TPM_RC_SIZE;
31277   }
31278   if (response_code != TPM_RC_SUCCESS) {
31279     return response_code;
31280   }
31281   TPM_CC command_code = TPM_CC_NV_ReadPublic;
31282   std::string command_code_bytes;
31283   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31284   if (rc != TPM_RC_SUCCESS) {
31285     return rc;
31286   }
31287   std::string authorization_section_bytes;
31288   if (tag == TPM_ST_SESSIONS) {
31289     UINT32 parameter_section_size = buffer.size();
31290     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31291     if (rc != TPM_RC_SUCCESS) {
31292       return rc;
31293     }
31294     if (parameter_section_size > buffer.size()) {
31295       return TPM_RC_INSUFFICIENT;
31296     }
31297     authorization_section_bytes = buffer.substr(parameter_section_size);
31298     // Keep the parameter section in |buffer|.
31299     buffer.erase(parameter_section_size);
31300   }
31301   std::unique_ptr<crypto::SecureHash> hash(
31302       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31303   hash->Update(response_code_bytes.data(), response_code_bytes.size());
31304   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31305   hash->Update(buffer.data(), buffer.size());
31306   std::string response_hash(32, 0);
31307   hash->Finish(std::data(response_hash), response_hash.size());
31308   if (tag == TPM_ST_SESSIONS) {
31309     if (!authorization_delegate)
31310       return TRUNKS_RC_AUTHORIZATION_FAILED;
31311     if (!authorization_delegate->CheckResponseAuthorization(
31312             response_hash, authorization_section_bytes)) {
31313       return TRUNKS_RC_AUTHORIZATION_FAILED;
31314     }
31315   }
31316   if (tag == TPM_ST_SESSIONS) {
31317     if (!authorization_delegate)
31318       return TRUNKS_RC_AUTHORIZATION_FAILED;
31319 
31320     // Parse the encrypted parameter size.
31321     UINT16 size;
31322     std::string size_buffer = buffer.substr(0, 2);
31323     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
31324       return result;
31325     }
31326     if (buffer.size() < 2 + size) {
31327       return TPM_RC_INSUFFICIENT;
31328     }
31329 
31330     // Decrypt just the parameter data, not the size.
31331     std::string decrypted_data = buffer.substr(2, size);
31332     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
31333       return TRUNKS_RC_ENCRYPTION_FAILED;
31334     }
31335     buffer.replace(2, size, decrypted_data);
31336   }
31337   std::string nv_public_bytes;
31338   rc = Parse_TPM2B_NV_PUBLIC(&buffer, nv_public, &nv_public_bytes);
31339   if (rc != TPM_RC_SUCCESS) {
31340     return rc;
31341   }
31342   std::string nv_name_bytes;
31343   rc = Parse_TPM2B_NAME(&buffer, nv_name, &nv_name_bytes);
31344   if (rc != TPM_RC_SUCCESS) {
31345     return rc;
31346   }
31347   return TPM_RC_SUCCESS;
31348 }
31349 
NV_ReadPublicErrorCallback(Tpm::NV_ReadPublicResponse callback,TPM_RC response_code)31350 void NV_ReadPublicErrorCallback(Tpm::NV_ReadPublicResponse callback,
31351                                 TPM_RC response_code) {
31352   VLOG(1) << __func__;
31353   std::move(callback).Run(response_code, TPM2B_NV_PUBLIC(), TPM2B_NAME());
31354 }
31355 
NV_ReadPublicResponseParser(Tpm::NV_ReadPublicResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31356 void NV_ReadPublicResponseParser(Tpm::NV_ReadPublicResponse callback,
31357                                  AuthorizationDelegate* authorization_delegate,
31358                                  const std::string& response) {
31359   VLOG(1) << __func__;
31360   TPM2B_NV_PUBLIC nv_public;
31361   TPM2B_NAME nv_name;
31362   TPM_RC rc = Tpm::ParseResponse_NV_ReadPublic(response, &nv_public, &nv_name,
31363                                                authorization_delegate);
31364   if (rc != TPM_RC_SUCCESS) {
31365     base::OnceCallback<void(TPM_RC)> error_reporter =
31366         base::BindOnce(NV_ReadPublicErrorCallback, std::move(callback));
31367     std::move(error_reporter).Run(rc);
31368     return;
31369   }
31370   std::move(callback).Run(rc, nv_public, nv_name);
31371 }
31372 
NV_ReadPublic(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_ReadPublicResponse callback)31373 void Tpm::NV_ReadPublic(const TPMI_RH_NV_INDEX& nv_index,
31374                         const std::string& nv_index_name,
31375                         AuthorizationDelegate* authorization_delegate,
31376                         NV_ReadPublicResponse callback) {
31377   VLOG(1) << __func__;
31378   std::string command;
31379   TPM_RC rc = SerializeCommand_NV_ReadPublic(nv_index, nv_index_name, &command,
31380                                              authorization_delegate);
31381   if (rc != TPM_RC_SUCCESS) {
31382     base::OnceCallback<void(TPM_RC)> error_reporter =
31383         base::BindOnce(NV_ReadPublicErrorCallback, std::move(callback));
31384     std::move(error_reporter).Run(rc);
31385     return;
31386   }
31387   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31388       NV_ReadPublicResponseParser, std::move(callback), authorization_delegate);
31389   transceiver_->SendCommand(command, std::move(parser));
31390 }
31391 
NV_ReadPublicSync(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,TPM2B_NV_PUBLIC * nv_public,TPM2B_NAME * nv_name,AuthorizationDelegate * authorization_delegate)31392 TPM_RC Tpm::NV_ReadPublicSync(const TPMI_RH_NV_INDEX& nv_index,
31393                               const std::string& nv_index_name,
31394                               TPM2B_NV_PUBLIC* nv_public,
31395                               TPM2B_NAME* nv_name,
31396                               AuthorizationDelegate* authorization_delegate) {
31397   VLOG(1) << __func__;
31398   std::string command;
31399   TPM_RC rc = SerializeCommand_NV_ReadPublic(nv_index, nv_index_name, &command,
31400                                              authorization_delegate);
31401   if (rc != TPM_RC_SUCCESS) {
31402     return rc;
31403   }
31404   std::string response = transceiver_->SendCommandAndWait(command);
31405   rc = ParseResponse_NV_ReadPublic(response, nv_public, nv_name,
31406                                    authorization_delegate);
31407   return rc;
31408 }
31409 
SerializeCommand_NV_Write(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,const UINT16 & offset,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31410 TPM_RC Tpm::SerializeCommand_NV_Write(
31411     const TPMI_RH_NV_AUTH& auth_handle,
31412     const std::string& auth_handle_name,
31413     const TPMI_RH_NV_INDEX& nv_index,
31414     const std::string& nv_index_name,
31415     const TPM2B_MAX_NV_BUFFER& data,
31416     const UINT16& offset,
31417     std::string* serialized_command,
31418     AuthorizationDelegate* authorization_delegate) {
31419   VLOG(3) << __func__;
31420   TPM_RC rc = TPM_RC_SUCCESS;
31421   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31422   UINT32 command_size = 10;  // Header size.
31423   std::string handle_section_bytes;
31424   std::string parameter_section_bytes;
31425   TPM_CC command_code = TPM_CC_NV_Write;
31426   bool is_command_parameter_encryption_possible = true;
31427   bool is_response_parameter_encryption_possible = false;
31428   std::string command_code_bytes;
31429   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31430   if (rc != TPM_RC_SUCCESS) {
31431     return rc;
31432   }
31433   std::string auth_handle_bytes;
31434   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31435   if (rc != TPM_RC_SUCCESS) {
31436     return rc;
31437   }
31438   std::string nv_index_bytes;
31439   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31440   if (rc != TPM_RC_SUCCESS) {
31441     return rc;
31442   }
31443   std::string data_bytes;
31444   rc = Serialize_TPM2B_MAX_NV_BUFFER(data, &data_bytes);
31445   if (rc != TPM_RC_SUCCESS) {
31446     return rc;
31447   }
31448   std::string offset_bytes;
31449   rc = Serialize_UINT16(offset, &offset_bytes);
31450   if (rc != TPM_RC_SUCCESS) {
31451     return rc;
31452   }
31453   if (authorization_delegate) {
31454     // Encrypt just the parameter data, not the size.
31455     std::string tmp = data_bytes.substr(2);
31456     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
31457       return TRUNKS_RC_ENCRYPTION_FAILED;
31458     }
31459     data_bytes.replace(2, std::string::npos, tmp);
31460   }
31461   std::unique_ptr<crypto::SecureHash> hash(
31462       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31463   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31464   hash->Update(auth_handle_name.data(), auth_handle_name.size());
31465   handle_section_bytes += auth_handle_bytes;
31466   command_size += auth_handle_bytes.size();
31467   hash->Update(nv_index_name.data(), nv_index_name.size());
31468   handle_section_bytes += nv_index_bytes;
31469   command_size += nv_index_bytes.size();
31470   hash->Update(data_bytes.data(), data_bytes.size());
31471   parameter_section_bytes += data_bytes;
31472   command_size += data_bytes.size();
31473   hash->Update(offset_bytes.data(), offset_bytes.size());
31474   parameter_section_bytes += offset_bytes;
31475   command_size += offset_bytes.size();
31476   std::string command_hash(32, 0);
31477   hash->Finish(std::data(command_hash), command_hash.size());
31478   std::string authorization_section_bytes;
31479   std::string authorization_size_bytes;
31480   if (authorization_delegate) {
31481     if (!authorization_delegate->GetCommandAuthorization(
31482             command_hash, is_command_parameter_encryption_possible,
31483             is_response_parameter_encryption_possible,
31484             &authorization_section_bytes)) {
31485       return TRUNKS_RC_AUTHORIZATION_FAILED;
31486     }
31487     if (!authorization_section_bytes.empty()) {
31488       tag = TPM_ST_SESSIONS;
31489       std::string tmp;
31490       rc = Serialize_UINT32(authorization_section_bytes.size(),
31491                             &authorization_size_bytes);
31492       if (rc != TPM_RC_SUCCESS) {
31493         return rc;
31494       }
31495       command_size +=
31496           authorization_size_bytes.size() + authorization_section_bytes.size();
31497     }
31498   }
31499   std::string tag_bytes;
31500   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31501   if (rc != TPM_RC_SUCCESS) {
31502     return rc;
31503   }
31504   std::string command_size_bytes;
31505   rc = Serialize_UINT32(command_size, &command_size_bytes);
31506   if (rc != TPM_RC_SUCCESS) {
31507     return rc;
31508   }
31509   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31510                         handle_section_bytes + authorization_size_bytes +
31511                         authorization_section_bytes + parameter_section_bytes;
31512   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31513   VLOG(2) << "Command: "
31514           << base::HexEncode(serialized_command->data(),
31515                              serialized_command->size());
31516   return TPM_RC_SUCCESS;
31517 }
31518 
ParseResponse_NV_Write(const std::string & response,AuthorizationDelegate * authorization_delegate)31519 TPM_RC Tpm::ParseResponse_NV_Write(
31520     const std::string& response,
31521     AuthorizationDelegate* authorization_delegate) {
31522   VLOG(3) << __func__;
31523   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31524   TPM_RC rc = TPM_RC_SUCCESS;
31525   std::string buffer(response);
31526   TPM_ST tag;
31527   std::string tag_bytes;
31528   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31529   if (rc != TPM_RC_SUCCESS) {
31530     return rc;
31531   }
31532   UINT32 response_size;
31533   std::string response_size_bytes;
31534   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31535   if (rc != TPM_RC_SUCCESS) {
31536     return rc;
31537   }
31538   TPM_RC response_code;
31539   std::string response_code_bytes;
31540   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31541   if (rc != TPM_RC_SUCCESS) {
31542     return rc;
31543   }
31544   if (response_size != response.size()) {
31545     return TPM_RC_SIZE;
31546   }
31547   if (response_code != TPM_RC_SUCCESS) {
31548     return response_code;
31549   }
31550   TPM_CC command_code = TPM_CC_NV_Write;
31551   std::string command_code_bytes;
31552   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31553   if (rc != TPM_RC_SUCCESS) {
31554     return rc;
31555   }
31556   std::string authorization_section_bytes;
31557   if (tag == TPM_ST_SESSIONS) {
31558     UINT32 parameter_section_size = buffer.size();
31559     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31560     if (rc != TPM_RC_SUCCESS) {
31561       return rc;
31562     }
31563     if (parameter_section_size > buffer.size()) {
31564       return TPM_RC_INSUFFICIENT;
31565     }
31566     authorization_section_bytes = buffer.substr(parameter_section_size);
31567     // Keep the parameter section in |buffer|.
31568     buffer.erase(parameter_section_size);
31569   }
31570   std::unique_ptr<crypto::SecureHash> hash(
31571       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31572   hash->Update(response_code_bytes.data(), response_code_bytes.size());
31573   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31574   hash->Update(buffer.data(), buffer.size());
31575   std::string response_hash(32, 0);
31576   hash->Finish(std::data(response_hash), response_hash.size());
31577   if (tag == TPM_ST_SESSIONS) {
31578     if (!authorization_delegate)
31579       return TRUNKS_RC_AUTHORIZATION_FAILED;
31580     if (!authorization_delegate->CheckResponseAuthorization(
31581             response_hash, authorization_section_bytes)) {
31582       return TRUNKS_RC_AUTHORIZATION_FAILED;
31583     }
31584   }
31585   return TPM_RC_SUCCESS;
31586 }
31587 
NV_WriteErrorCallback(Tpm::NV_WriteResponse callback,TPM_RC response_code)31588 void NV_WriteErrorCallback(Tpm::NV_WriteResponse callback,
31589                            TPM_RC response_code) {
31590   VLOG(1) << __func__;
31591   std::move(callback).Run(response_code);
31592 }
31593 
NV_WriteResponseParser(Tpm::NV_WriteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31594 void NV_WriteResponseParser(Tpm::NV_WriteResponse callback,
31595                             AuthorizationDelegate* authorization_delegate,
31596                             const std::string& response) {
31597   VLOG(1) << __func__;
31598   TPM_RC rc = Tpm::ParseResponse_NV_Write(response, authorization_delegate);
31599   if (rc != TPM_RC_SUCCESS) {
31600     base::OnceCallback<void(TPM_RC)> error_reporter =
31601         base::BindOnce(NV_WriteErrorCallback, std::move(callback));
31602     std::move(error_reporter).Run(rc);
31603     return;
31604   }
31605   std::move(callback).Run(rc);
31606 }
31607 
NV_Write(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,const UINT16 & offset,AuthorizationDelegate * authorization_delegate,NV_WriteResponse callback)31608 void Tpm::NV_Write(const TPMI_RH_NV_AUTH& auth_handle,
31609                    const std::string& auth_handle_name,
31610                    const TPMI_RH_NV_INDEX& nv_index,
31611                    const std::string& nv_index_name,
31612                    const TPM2B_MAX_NV_BUFFER& data,
31613                    const UINT16& offset,
31614                    AuthorizationDelegate* authorization_delegate,
31615                    NV_WriteResponse callback) {
31616   VLOG(1) << __func__;
31617   std::string command;
31618   TPM_RC rc = SerializeCommand_NV_Write(auth_handle, auth_handle_name, nv_index,
31619                                         nv_index_name, data, offset, &command,
31620                                         authorization_delegate);
31621   if (rc != TPM_RC_SUCCESS) {
31622     base::OnceCallback<void(TPM_RC)> error_reporter =
31623         base::BindOnce(NV_WriteErrorCallback, std::move(callback));
31624     std::move(error_reporter).Run(rc);
31625     return;
31626   }
31627   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31628       NV_WriteResponseParser, std::move(callback), authorization_delegate);
31629   transceiver_->SendCommand(command, std::move(parser));
31630 }
31631 
NV_WriteSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,const UINT16 & offset,AuthorizationDelegate * authorization_delegate)31632 TPM_RC Tpm::NV_WriteSync(const TPMI_RH_NV_AUTH& auth_handle,
31633                          const std::string& auth_handle_name,
31634                          const TPMI_RH_NV_INDEX& nv_index,
31635                          const std::string& nv_index_name,
31636                          const TPM2B_MAX_NV_BUFFER& data,
31637                          const UINT16& offset,
31638                          AuthorizationDelegate* authorization_delegate) {
31639   VLOG(1) << __func__;
31640   std::string command;
31641   TPM_RC rc = SerializeCommand_NV_Write(auth_handle, auth_handle_name, nv_index,
31642                                         nv_index_name, data, offset, &command,
31643                                         authorization_delegate);
31644   if (rc != TPM_RC_SUCCESS) {
31645     return rc;
31646   }
31647   std::string response = transceiver_->SendCommandAndWait(command);
31648   rc = ParseResponse_NV_Write(response, authorization_delegate);
31649   return rc;
31650 }
31651 
SerializeCommand_NV_Increment(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31652 TPM_RC Tpm::SerializeCommand_NV_Increment(
31653     const TPMI_RH_NV_AUTH& auth_handle,
31654     const std::string& auth_handle_name,
31655     const TPMI_RH_NV_INDEX& nv_index,
31656     const std::string& nv_index_name,
31657     std::string* serialized_command,
31658     AuthorizationDelegate* authorization_delegate) {
31659   VLOG(3) << __func__;
31660   TPM_RC rc = TPM_RC_SUCCESS;
31661   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31662   UINT32 command_size = 10;  // Header size.
31663   std::string handle_section_bytes;
31664   std::string parameter_section_bytes;
31665   TPM_CC command_code = TPM_CC_NV_Increment;
31666   bool is_command_parameter_encryption_possible = false;
31667   bool is_response_parameter_encryption_possible = false;
31668   std::string command_code_bytes;
31669   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31670   if (rc != TPM_RC_SUCCESS) {
31671     return rc;
31672   }
31673   std::string auth_handle_bytes;
31674   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31675   if (rc != TPM_RC_SUCCESS) {
31676     return rc;
31677   }
31678   std::string nv_index_bytes;
31679   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31680   if (rc != TPM_RC_SUCCESS) {
31681     return rc;
31682   }
31683   std::unique_ptr<crypto::SecureHash> hash(
31684       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31685   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31686   hash->Update(auth_handle_name.data(), auth_handle_name.size());
31687   handle_section_bytes += auth_handle_bytes;
31688   command_size += auth_handle_bytes.size();
31689   hash->Update(nv_index_name.data(), nv_index_name.size());
31690   handle_section_bytes += nv_index_bytes;
31691   command_size += nv_index_bytes.size();
31692   std::string command_hash(32, 0);
31693   hash->Finish(std::data(command_hash), command_hash.size());
31694   std::string authorization_section_bytes;
31695   std::string authorization_size_bytes;
31696   if (authorization_delegate) {
31697     if (!authorization_delegate->GetCommandAuthorization(
31698             command_hash, is_command_parameter_encryption_possible,
31699             is_response_parameter_encryption_possible,
31700             &authorization_section_bytes)) {
31701       return TRUNKS_RC_AUTHORIZATION_FAILED;
31702     }
31703     if (!authorization_section_bytes.empty()) {
31704       tag = TPM_ST_SESSIONS;
31705       std::string tmp;
31706       rc = Serialize_UINT32(authorization_section_bytes.size(),
31707                             &authorization_size_bytes);
31708       if (rc != TPM_RC_SUCCESS) {
31709         return rc;
31710       }
31711       command_size +=
31712           authorization_size_bytes.size() + authorization_section_bytes.size();
31713     }
31714   }
31715   std::string tag_bytes;
31716   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31717   if (rc != TPM_RC_SUCCESS) {
31718     return rc;
31719   }
31720   std::string command_size_bytes;
31721   rc = Serialize_UINT32(command_size, &command_size_bytes);
31722   if (rc != TPM_RC_SUCCESS) {
31723     return rc;
31724   }
31725   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31726                         handle_section_bytes + authorization_size_bytes +
31727                         authorization_section_bytes + parameter_section_bytes;
31728   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31729   VLOG(2) << "Command: "
31730           << base::HexEncode(serialized_command->data(),
31731                              serialized_command->size());
31732   return TPM_RC_SUCCESS;
31733 }
31734 
ParseResponse_NV_Increment(const std::string & response,AuthorizationDelegate * authorization_delegate)31735 TPM_RC Tpm::ParseResponse_NV_Increment(
31736     const std::string& response,
31737     AuthorizationDelegate* authorization_delegate) {
31738   VLOG(3) << __func__;
31739   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31740   TPM_RC rc = TPM_RC_SUCCESS;
31741   std::string buffer(response);
31742   TPM_ST tag;
31743   std::string tag_bytes;
31744   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31745   if (rc != TPM_RC_SUCCESS) {
31746     return rc;
31747   }
31748   UINT32 response_size;
31749   std::string response_size_bytes;
31750   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31751   if (rc != TPM_RC_SUCCESS) {
31752     return rc;
31753   }
31754   TPM_RC response_code;
31755   std::string response_code_bytes;
31756   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31757   if (rc != TPM_RC_SUCCESS) {
31758     return rc;
31759   }
31760   if (response_size != response.size()) {
31761     return TPM_RC_SIZE;
31762   }
31763   if (response_code != TPM_RC_SUCCESS) {
31764     return response_code;
31765   }
31766   TPM_CC command_code = TPM_CC_NV_Increment;
31767   std::string command_code_bytes;
31768   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31769   if (rc != TPM_RC_SUCCESS) {
31770     return rc;
31771   }
31772   std::string authorization_section_bytes;
31773   if (tag == TPM_ST_SESSIONS) {
31774     UINT32 parameter_section_size = buffer.size();
31775     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31776     if (rc != TPM_RC_SUCCESS) {
31777       return rc;
31778     }
31779     if (parameter_section_size > buffer.size()) {
31780       return TPM_RC_INSUFFICIENT;
31781     }
31782     authorization_section_bytes = buffer.substr(parameter_section_size);
31783     // Keep the parameter section in |buffer|.
31784     buffer.erase(parameter_section_size);
31785   }
31786   std::unique_ptr<crypto::SecureHash> hash(
31787       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31788   hash->Update(response_code_bytes.data(), response_code_bytes.size());
31789   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31790   hash->Update(buffer.data(), buffer.size());
31791   std::string response_hash(32, 0);
31792   hash->Finish(std::data(response_hash), response_hash.size());
31793   if (tag == TPM_ST_SESSIONS) {
31794     if (!authorization_delegate)
31795       return TRUNKS_RC_AUTHORIZATION_FAILED;
31796     if (!authorization_delegate->CheckResponseAuthorization(
31797             response_hash, authorization_section_bytes)) {
31798       return TRUNKS_RC_AUTHORIZATION_FAILED;
31799     }
31800   }
31801   return TPM_RC_SUCCESS;
31802 }
31803 
NV_IncrementErrorCallback(Tpm::NV_IncrementResponse callback,TPM_RC response_code)31804 void NV_IncrementErrorCallback(Tpm::NV_IncrementResponse callback,
31805                                TPM_RC response_code) {
31806   VLOG(1) << __func__;
31807   std::move(callback).Run(response_code);
31808 }
31809 
NV_IncrementResponseParser(Tpm::NV_IncrementResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31810 void NV_IncrementResponseParser(Tpm::NV_IncrementResponse callback,
31811                                 AuthorizationDelegate* authorization_delegate,
31812                                 const std::string& response) {
31813   VLOG(1) << __func__;
31814   TPM_RC rc = Tpm::ParseResponse_NV_Increment(response, authorization_delegate);
31815   if (rc != TPM_RC_SUCCESS) {
31816     base::OnceCallback<void(TPM_RC)> error_reporter =
31817         base::BindOnce(NV_IncrementErrorCallback, std::move(callback));
31818     std::move(error_reporter).Run(rc);
31819     return;
31820   }
31821   std::move(callback).Run(rc);
31822 }
31823 
NV_Increment(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_IncrementResponse callback)31824 void Tpm::NV_Increment(const TPMI_RH_NV_AUTH& auth_handle,
31825                        const std::string& auth_handle_name,
31826                        const TPMI_RH_NV_INDEX& nv_index,
31827                        const std::string& nv_index_name,
31828                        AuthorizationDelegate* authorization_delegate,
31829                        NV_IncrementResponse callback) {
31830   VLOG(1) << __func__;
31831   std::string command;
31832   TPM_RC rc = SerializeCommand_NV_Increment(auth_handle, auth_handle_name,
31833                                             nv_index, nv_index_name, &command,
31834                                             authorization_delegate);
31835   if (rc != TPM_RC_SUCCESS) {
31836     base::OnceCallback<void(TPM_RC)> error_reporter =
31837         base::BindOnce(NV_IncrementErrorCallback, std::move(callback));
31838     std::move(error_reporter).Run(rc);
31839     return;
31840   }
31841   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31842       NV_IncrementResponseParser, std::move(callback), authorization_delegate);
31843   transceiver_->SendCommand(command, std::move(parser));
31844 }
31845 
NV_IncrementSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)31846 TPM_RC Tpm::NV_IncrementSync(const TPMI_RH_NV_AUTH& auth_handle,
31847                              const std::string& auth_handle_name,
31848                              const TPMI_RH_NV_INDEX& nv_index,
31849                              const std::string& nv_index_name,
31850                              AuthorizationDelegate* authorization_delegate) {
31851   VLOG(1) << __func__;
31852   std::string command;
31853   TPM_RC rc = SerializeCommand_NV_Increment(auth_handle, auth_handle_name,
31854                                             nv_index, nv_index_name, &command,
31855                                             authorization_delegate);
31856   if (rc != TPM_RC_SUCCESS) {
31857     return rc;
31858   }
31859   std::string response = transceiver_->SendCommandAndWait(command);
31860   rc = ParseResponse_NV_Increment(response, authorization_delegate);
31861   return rc;
31862 }
31863 
SerializeCommand_NV_Extend(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31864 TPM_RC Tpm::SerializeCommand_NV_Extend(
31865     const TPMI_RH_NV_AUTH& auth_handle,
31866     const std::string& auth_handle_name,
31867     const TPMI_RH_NV_INDEX& nv_index,
31868     const std::string& nv_index_name,
31869     const TPM2B_MAX_NV_BUFFER& data,
31870     std::string* serialized_command,
31871     AuthorizationDelegate* authorization_delegate) {
31872   VLOG(3) << __func__;
31873   TPM_RC rc = TPM_RC_SUCCESS;
31874   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31875   UINT32 command_size = 10;  // Header size.
31876   std::string handle_section_bytes;
31877   std::string parameter_section_bytes;
31878   TPM_CC command_code = TPM_CC_NV_Extend;
31879   bool is_command_parameter_encryption_possible = true;
31880   bool is_response_parameter_encryption_possible = false;
31881   std::string command_code_bytes;
31882   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31883   if (rc != TPM_RC_SUCCESS) {
31884     return rc;
31885   }
31886   std::string auth_handle_bytes;
31887   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31888   if (rc != TPM_RC_SUCCESS) {
31889     return rc;
31890   }
31891   std::string nv_index_bytes;
31892   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31893   if (rc != TPM_RC_SUCCESS) {
31894     return rc;
31895   }
31896   std::string data_bytes;
31897   rc = Serialize_TPM2B_MAX_NV_BUFFER(data, &data_bytes);
31898   if (rc != TPM_RC_SUCCESS) {
31899     return rc;
31900   }
31901   if (authorization_delegate) {
31902     // Encrypt just the parameter data, not the size.
31903     std::string tmp = data_bytes.substr(2);
31904     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
31905       return TRUNKS_RC_ENCRYPTION_FAILED;
31906     }
31907     data_bytes.replace(2, std::string::npos, tmp);
31908   }
31909   std::unique_ptr<crypto::SecureHash> hash(
31910       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31911   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31912   hash->Update(auth_handle_name.data(), auth_handle_name.size());
31913   handle_section_bytes += auth_handle_bytes;
31914   command_size += auth_handle_bytes.size();
31915   hash->Update(nv_index_name.data(), nv_index_name.size());
31916   handle_section_bytes += nv_index_bytes;
31917   command_size += nv_index_bytes.size();
31918   hash->Update(data_bytes.data(), data_bytes.size());
31919   parameter_section_bytes += data_bytes;
31920   command_size += data_bytes.size();
31921   std::string command_hash(32, 0);
31922   hash->Finish(std::data(command_hash), command_hash.size());
31923   std::string authorization_section_bytes;
31924   std::string authorization_size_bytes;
31925   if (authorization_delegate) {
31926     if (!authorization_delegate->GetCommandAuthorization(
31927             command_hash, is_command_parameter_encryption_possible,
31928             is_response_parameter_encryption_possible,
31929             &authorization_section_bytes)) {
31930       return TRUNKS_RC_AUTHORIZATION_FAILED;
31931     }
31932     if (!authorization_section_bytes.empty()) {
31933       tag = TPM_ST_SESSIONS;
31934       std::string tmp;
31935       rc = Serialize_UINT32(authorization_section_bytes.size(),
31936                             &authorization_size_bytes);
31937       if (rc != TPM_RC_SUCCESS) {
31938         return rc;
31939       }
31940       command_size +=
31941           authorization_size_bytes.size() + authorization_section_bytes.size();
31942     }
31943   }
31944   std::string tag_bytes;
31945   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31946   if (rc != TPM_RC_SUCCESS) {
31947     return rc;
31948   }
31949   std::string command_size_bytes;
31950   rc = Serialize_UINT32(command_size, &command_size_bytes);
31951   if (rc != TPM_RC_SUCCESS) {
31952     return rc;
31953   }
31954   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31955                         handle_section_bytes + authorization_size_bytes +
31956                         authorization_section_bytes + parameter_section_bytes;
31957   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31958   VLOG(2) << "Command: "
31959           << base::HexEncode(serialized_command->data(),
31960                              serialized_command->size());
31961   return TPM_RC_SUCCESS;
31962 }
31963 
ParseResponse_NV_Extend(const std::string & response,AuthorizationDelegate * authorization_delegate)31964 TPM_RC Tpm::ParseResponse_NV_Extend(
31965     const std::string& response,
31966     AuthorizationDelegate* authorization_delegate) {
31967   VLOG(3) << __func__;
31968   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31969   TPM_RC rc = TPM_RC_SUCCESS;
31970   std::string buffer(response);
31971   TPM_ST tag;
31972   std::string tag_bytes;
31973   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31974   if (rc != TPM_RC_SUCCESS) {
31975     return rc;
31976   }
31977   UINT32 response_size;
31978   std::string response_size_bytes;
31979   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31980   if (rc != TPM_RC_SUCCESS) {
31981     return rc;
31982   }
31983   TPM_RC response_code;
31984   std::string response_code_bytes;
31985   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31986   if (rc != TPM_RC_SUCCESS) {
31987     return rc;
31988   }
31989   if (response_size != response.size()) {
31990     return TPM_RC_SIZE;
31991   }
31992   if (response_code != TPM_RC_SUCCESS) {
31993     return response_code;
31994   }
31995   TPM_CC command_code = TPM_CC_NV_Extend;
31996   std::string command_code_bytes;
31997   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31998   if (rc != TPM_RC_SUCCESS) {
31999     return rc;
32000   }
32001   std::string authorization_section_bytes;
32002   if (tag == TPM_ST_SESSIONS) {
32003     UINT32 parameter_section_size = buffer.size();
32004     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32005     if (rc != TPM_RC_SUCCESS) {
32006       return rc;
32007     }
32008     if (parameter_section_size > buffer.size()) {
32009       return TPM_RC_INSUFFICIENT;
32010     }
32011     authorization_section_bytes = buffer.substr(parameter_section_size);
32012     // Keep the parameter section in |buffer|.
32013     buffer.erase(parameter_section_size);
32014   }
32015   std::unique_ptr<crypto::SecureHash> hash(
32016       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32017   hash->Update(response_code_bytes.data(), response_code_bytes.size());
32018   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32019   hash->Update(buffer.data(), buffer.size());
32020   std::string response_hash(32, 0);
32021   hash->Finish(std::data(response_hash), response_hash.size());
32022   if (tag == TPM_ST_SESSIONS) {
32023     if (!authorization_delegate)
32024       return TRUNKS_RC_AUTHORIZATION_FAILED;
32025     if (!authorization_delegate->CheckResponseAuthorization(
32026             response_hash, authorization_section_bytes)) {
32027       return TRUNKS_RC_AUTHORIZATION_FAILED;
32028     }
32029   }
32030   return TPM_RC_SUCCESS;
32031 }
32032 
NV_ExtendErrorCallback(Tpm::NV_ExtendResponse callback,TPM_RC response_code)32033 void NV_ExtendErrorCallback(Tpm::NV_ExtendResponse callback,
32034                             TPM_RC response_code) {
32035   VLOG(1) << __func__;
32036   std::move(callback).Run(response_code);
32037 }
32038 
NV_ExtendResponseParser(Tpm::NV_ExtendResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32039 void NV_ExtendResponseParser(Tpm::NV_ExtendResponse callback,
32040                              AuthorizationDelegate* authorization_delegate,
32041                              const std::string& response) {
32042   VLOG(1) << __func__;
32043   TPM_RC rc = Tpm::ParseResponse_NV_Extend(response, authorization_delegate);
32044   if (rc != TPM_RC_SUCCESS) {
32045     base::OnceCallback<void(TPM_RC)> error_reporter =
32046         base::BindOnce(NV_ExtendErrorCallback, std::move(callback));
32047     std::move(error_reporter).Run(rc);
32048     return;
32049   }
32050   std::move(callback).Run(rc);
32051 }
32052 
NV_Extend(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,AuthorizationDelegate * authorization_delegate,NV_ExtendResponse callback)32053 void Tpm::NV_Extend(const TPMI_RH_NV_AUTH& auth_handle,
32054                     const std::string& auth_handle_name,
32055                     const TPMI_RH_NV_INDEX& nv_index,
32056                     const std::string& nv_index_name,
32057                     const TPM2B_MAX_NV_BUFFER& data,
32058                     AuthorizationDelegate* authorization_delegate,
32059                     NV_ExtendResponse callback) {
32060   VLOG(1) << __func__;
32061   std::string command;
32062   TPM_RC rc = SerializeCommand_NV_Extend(auth_handle, auth_handle_name,
32063                                          nv_index, nv_index_name, data,
32064                                          &command, authorization_delegate);
32065   if (rc != TPM_RC_SUCCESS) {
32066     base::OnceCallback<void(TPM_RC)> error_reporter =
32067         base::BindOnce(NV_ExtendErrorCallback, std::move(callback));
32068     std::move(error_reporter).Run(rc);
32069     return;
32070   }
32071   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32072       NV_ExtendResponseParser, std::move(callback), authorization_delegate);
32073   transceiver_->SendCommand(command, std::move(parser));
32074 }
32075 
NV_ExtendSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,AuthorizationDelegate * authorization_delegate)32076 TPM_RC Tpm::NV_ExtendSync(const TPMI_RH_NV_AUTH& auth_handle,
32077                           const std::string& auth_handle_name,
32078                           const TPMI_RH_NV_INDEX& nv_index,
32079                           const std::string& nv_index_name,
32080                           const TPM2B_MAX_NV_BUFFER& data,
32081                           AuthorizationDelegate* authorization_delegate) {
32082   VLOG(1) << __func__;
32083   std::string command;
32084   TPM_RC rc = SerializeCommand_NV_Extend(auth_handle, auth_handle_name,
32085                                          nv_index, nv_index_name, data,
32086                                          &command, authorization_delegate);
32087   if (rc != TPM_RC_SUCCESS) {
32088     return rc;
32089   }
32090   std::string response = transceiver_->SendCommandAndWait(command);
32091   rc = ParseResponse_NV_Extend(response, authorization_delegate);
32092   return rc;
32093 }
32094 
SerializeCommand_NV_SetBits(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT64 & bits,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32095 TPM_RC Tpm::SerializeCommand_NV_SetBits(
32096     const TPMI_RH_NV_AUTH& auth_handle,
32097     const std::string& auth_handle_name,
32098     const TPMI_RH_NV_INDEX& nv_index,
32099     const std::string& nv_index_name,
32100     const UINT64& bits,
32101     std::string* serialized_command,
32102     AuthorizationDelegate* authorization_delegate) {
32103   VLOG(3) << __func__;
32104   TPM_RC rc = TPM_RC_SUCCESS;
32105   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32106   UINT32 command_size = 10;  // Header size.
32107   std::string handle_section_bytes;
32108   std::string parameter_section_bytes;
32109   TPM_CC command_code = TPM_CC_NV_SetBits;
32110   bool is_command_parameter_encryption_possible = false;
32111   bool is_response_parameter_encryption_possible = false;
32112   std::string command_code_bytes;
32113   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32114   if (rc != TPM_RC_SUCCESS) {
32115     return rc;
32116   }
32117   std::string auth_handle_bytes;
32118   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32119   if (rc != TPM_RC_SUCCESS) {
32120     return rc;
32121   }
32122   std::string nv_index_bytes;
32123   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32124   if (rc != TPM_RC_SUCCESS) {
32125     return rc;
32126   }
32127   std::string bits_bytes;
32128   rc = Serialize_UINT64(bits, &bits_bytes);
32129   if (rc != TPM_RC_SUCCESS) {
32130     return rc;
32131   }
32132   std::unique_ptr<crypto::SecureHash> hash(
32133       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32134   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32135   hash->Update(auth_handle_name.data(), auth_handle_name.size());
32136   handle_section_bytes += auth_handle_bytes;
32137   command_size += auth_handle_bytes.size();
32138   hash->Update(nv_index_name.data(), nv_index_name.size());
32139   handle_section_bytes += nv_index_bytes;
32140   command_size += nv_index_bytes.size();
32141   hash->Update(bits_bytes.data(), bits_bytes.size());
32142   parameter_section_bytes += bits_bytes;
32143   command_size += bits_bytes.size();
32144   std::string command_hash(32, 0);
32145   hash->Finish(std::data(command_hash), command_hash.size());
32146   std::string authorization_section_bytes;
32147   std::string authorization_size_bytes;
32148   if (authorization_delegate) {
32149     if (!authorization_delegate->GetCommandAuthorization(
32150             command_hash, is_command_parameter_encryption_possible,
32151             is_response_parameter_encryption_possible,
32152             &authorization_section_bytes)) {
32153       return TRUNKS_RC_AUTHORIZATION_FAILED;
32154     }
32155     if (!authorization_section_bytes.empty()) {
32156       tag = TPM_ST_SESSIONS;
32157       std::string tmp;
32158       rc = Serialize_UINT32(authorization_section_bytes.size(),
32159                             &authorization_size_bytes);
32160       if (rc != TPM_RC_SUCCESS) {
32161         return rc;
32162       }
32163       command_size +=
32164           authorization_size_bytes.size() + authorization_section_bytes.size();
32165     }
32166   }
32167   std::string tag_bytes;
32168   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32169   if (rc != TPM_RC_SUCCESS) {
32170     return rc;
32171   }
32172   std::string command_size_bytes;
32173   rc = Serialize_UINT32(command_size, &command_size_bytes);
32174   if (rc != TPM_RC_SUCCESS) {
32175     return rc;
32176   }
32177   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32178                         handle_section_bytes + authorization_size_bytes +
32179                         authorization_section_bytes + parameter_section_bytes;
32180   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32181   VLOG(2) << "Command: "
32182           << base::HexEncode(serialized_command->data(),
32183                              serialized_command->size());
32184   return TPM_RC_SUCCESS;
32185 }
32186 
ParseResponse_NV_SetBits(const std::string & response,AuthorizationDelegate * authorization_delegate)32187 TPM_RC Tpm::ParseResponse_NV_SetBits(
32188     const std::string& response,
32189     AuthorizationDelegate* authorization_delegate) {
32190   VLOG(3) << __func__;
32191   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32192   TPM_RC rc = TPM_RC_SUCCESS;
32193   std::string buffer(response);
32194   TPM_ST tag;
32195   std::string tag_bytes;
32196   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32197   if (rc != TPM_RC_SUCCESS) {
32198     return rc;
32199   }
32200   UINT32 response_size;
32201   std::string response_size_bytes;
32202   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32203   if (rc != TPM_RC_SUCCESS) {
32204     return rc;
32205   }
32206   TPM_RC response_code;
32207   std::string response_code_bytes;
32208   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32209   if (rc != TPM_RC_SUCCESS) {
32210     return rc;
32211   }
32212   if (response_size != response.size()) {
32213     return TPM_RC_SIZE;
32214   }
32215   if (response_code != TPM_RC_SUCCESS) {
32216     return response_code;
32217   }
32218   TPM_CC command_code = TPM_CC_NV_SetBits;
32219   std::string command_code_bytes;
32220   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32221   if (rc != TPM_RC_SUCCESS) {
32222     return rc;
32223   }
32224   std::string authorization_section_bytes;
32225   if (tag == TPM_ST_SESSIONS) {
32226     UINT32 parameter_section_size = buffer.size();
32227     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32228     if (rc != TPM_RC_SUCCESS) {
32229       return rc;
32230     }
32231     if (parameter_section_size > buffer.size()) {
32232       return TPM_RC_INSUFFICIENT;
32233     }
32234     authorization_section_bytes = buffer.substr(parameter_section_size);
32235     // Keep the parameter section in |buffer|.
32236     buffer.erase(parameter_section_size);
32237   }
32238   std::unique_ptr<crypto::SecureHash> hash(
32239       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32240   hash->Update(response_code_bytes.data(), response_code_bytes.size());
32241   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32242   hash->Update(buffer.data(), buffer.size());
32243   std::string response_hash(32, 0);
32244   hash->Finish(std::data(response_hash), response_hash.size());
32245   if (tag == TPM_ST_SESSIONS) {
32246     if (!authorization_delegate)
32247       return TRUNKS_RC_AUTHORIZATION_FAILED;
32248     if (!authorization_delegate->CheckResponseAuthorization(
32249             response_hash, authorization_section_bytes)) {
32250       return TRUNKS_RC_AUTHORIZATION_FAILED;
32251     }
32252   }
32253   return TPM_RC_SUCCESS;
32254 }
32255 
NV_SetBitsErrorCallback(Tpm::NV_SetBitsResponse callback,TPM_RC response_code)32256 void NV_SetBitsErrorCallback(Tpm::NV_SetBitsResponse callback,
32257                              TPM_RC response_code) {
32258   VLOG(1) << __func__;
32259   std::move(callback).Run(response_code);
32260 }
32261 
NV_SetBitsResponseParser(Tpm::NV_SetBitsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32262 void NV_SetBitsResponseParser(Tpm::NV_SetBitsResponse callback,
32263                               AuthorizationDelegate* authorization_delegate,
32264                               const std::string& response) {
32265   VLOG(1) << __func__;
32266   TPM_RC rc = Tpm::ParseResponse_NV_SetBits(response, authorization_delegate);
32267   if (rc != TPM_RC_SUCCESS) {
32268     base::OnceCallback<void(TPM_RC)> error_reporter =
32269         base::BindOnce(NV_SetBitsErrorCallback, std::move(callback));
32270     std::move(error_reporter).Run(rc);
32271     return;
32272   }
32273   std::move(callback).Run(rc);
32274 }
32275 
NV_SetBits(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT64 & bits,AuthorizationDelegate * authorization_delegate,NV_SetBitsResponse callback)32276 void Tpm::NV_SetBits(const TPMI_RH_NV_AUTH& auth_handle,
32277                      const std::string& auth_handle_name,
32278                      const TPMI_RH_NV_INDEX& nv_index,
32279                      const std::string& nv_index_name,
32280                      const UINT64& bits,
32281                      AuthorizationDelegate* authorization_delegate,
32282                      NV_SetBitsResponse callback) {
32283   VLOG(1) << __func__;
32284   std::string command;
32285   TPM_RC rc = SerializeCommand_NV_SetBits(auth_handle, auth_handle_name,
32286                                           nv_index, nv_index_name, bits,
32287                                           &command, authorization_delegate);
32288   if (rc != TPM_RC_SUCCESS) {
32289     base::OnceCallback<void(TPM_RC)> error_reporter =
32290         base::BindOnce(NV_SetBitsErrorCallback, std::move(callback));
32291     std::move(error_reporter).Run(rc);
32292     return;
32293   }
32294   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32295       NV_SetBitsResponseParser, std::move(callback), authorization_delegate);
32296   transceiver_->SendCommand(command, std::move(parser));
32297 }
32298 
NV_SetBitsSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT64 & bits,AuthorizationDelegate * authorization_delegate)32299 TPM_RC Tpm::NV_SetBitsSync(const TPMI_RH_NV_AUTH& auth_handle,
32300                            const std::string& auth_handle_name,
32301                            const TPMI_RH_NV_INDEX& nv_index,
32302                            const std::string& nv_index_name,
32303                            const UINT64& bits,
32304                            AuthorizationDelegate* authorization_delegate) {
32305   VLOG(1) << __func__;
32306   std::string command;
32307   TPM_RC rc = SerializeCommand_NV_SetBits(auth_handle, auth_handle_name,
32308                                           nv_index, nv_index_name, bits,
32309                                           &command, authorization_delegate);
32310   if (rc != TPM_RC_SUCCESS) {
32311     return rc;
32312   }
32313   std::string response = transceiver_->SendCommandAndWait(command);
32314   rc = ParseResponse_NV_SetBits(response, authorization_delegate);
32315   return rc;
32316 }
32317 
SerializeCommand_NV_WriteLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32318 TPM_RC Tpm::SerializeCommand_NV_WriteLock(
32319     const TPMI_RH_NV_AUTH& auth_handle,
32320     const std::string& auth_handle_name,
32321     const TPMI_RH_NV_INDEX& nv_index,
32322     const std::string& nv_index_name,
32323     std::string* serialized_command,
32324     AuthorizationDelegate* authorization_delegate) {
32325   VLOG(3) << __func__;
32326   TPM_RC rc = TPM_RC_SUCCESS;
32327   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32328   UINT32 command_size = 10;  // Header size.
32329   std::string handle_section_bytes;
32330   std::string parameter_section_bytes;
32331   TPM_CC command_code = TPM_CC_NV_WriteLock;
32332   bool is_command_parameter_encryption_possible = false;
32333   bool is_response_parameter_encryption_possible = false;
32334   std::string command_code_bytes;
32335   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32336   if (rc != TPM_RC_SUCCESS) {
32337     return rc;
32338   }
32339   std::string auth_handle_bytes;
32340   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32341   if (rc != TPM_RC_SUCCESS) {
32342     return rc;
32343   }
32344   std::string nv_index_bytes;
32345   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32346   if (rc != TPM_RC_SUCCESS) {
32347     return rc;
32348   }
32349   std::unique_ptr<crypto::SecureHash> hash(
32350       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32351   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32352   hash->Update(auth_handle_name.data(), auth_handle_name.size());
32353   handle_section_bytes += auth_handle_bytes;
32354   command_size += auth_handle_bytes.size();
32355   hash->Update(nv_index_name.data(), nv_index_name.size());
32356   handle_section_bytes += nv_index_bytes;
32357   command_size += nv_index_bytes.size();
32358   std::string command_hash(32, 0);
32359   hash->Finish(std::data(command_hash), command_hash.size());
32360   std::string authorization_section_bytes;
32361   std::string authorization_size_bytes;
32362   if (authorization_delegate) {
32363     if (!authorization_delegate->GetCommandAuthorization(
32364             command_hash, is_command_parameter_encryption_possible,
32365             is_response_parameter_encryption_possible,
32366             &authorization_section_bytes)) {
32367       return TRUNKS_RC_AUTHORIZATION_FAILED;
32368     }
32369     if (!authorization_section_bytes.empty()) {
32370       tag = TPM_ST_SESSIONS;
32371       std::string tmp;
32372       rc = Serialize_UINT32(authorization_section_bytes.size(),
32373                             &authorization_size_bytes);
32374       if (rc != TPM_RC_SUCCESS) {
32375         return rc;
32376       }
32377       command_size +=
32378           authorization_size_bytes.size() + authorization_section_bytes.size();
32379     }
32380   }
32381   std::string tag_bytes;
32382   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32383   if (rc != TPM_RC_SUCCESS) {
32384     return rc;
32385   }
32386   std::string command_size_bytes;
32387   rc = Serialize_UINT32(command_size, &command_size_bytes);
32388   if (rc != TPM_RC_SUCCESS) {
32389     return rc;
32390   }
32391   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32392                         handle_section_bytes + authorization_size_bytes +
32393                         authorization_section_bytes + parameter_section_bytes;
32394   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32395   VLOG(2) << "Command: "
32396           << base::HexEncode(serialized_command->data(),
32397                              serialized_command->size());
32398   return TPM_RC_SUCCESS;
32399 }
32400 
ParseResponse_NV_WriteLock(const std::string & response,AuthorizationDelegate * authorization_delegate)32401 TPM_RC Tpm::ParseResponse_NV_WriteLock(
32402     const std::string& response,
32403     AuthorizationDelegate* authorization_delegate) {
32404   VLOG(3) << __func__;
32405   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32406   TPM_RC rc = TPM_RC_SUCCESS;
32407   std::string buffer(response);
32408   TPM_ST tag;
32409   std::string tag_bytes;
32410   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32411   if (rc != TPM_RC_SUCCESS) {
32412     return rc;
32413   }
32414   UINT32 response_size;
32415   std::string response_size_bytes;
32416   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32417   if (rc != TPM_RC_SUCCESS) {
32418     return rc;
32419   }
32420   TPM_RC response_code;
32421   std::string response_code_bytes;
32422   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32423   if (rc != TPM_RC_SUCCESS) {
32424     return rc;
32425   }
32426   if (response_size != response.size()) {
32427     return TPM_RC_SIZE;
32428   }
32429   if (response_code != TPM_RC_SUCCESS) {
32430     return response_code;
32431   }
32432   TPM_CC command_code = TPM_CC_NV_WriteLock;
32433   std::string command_code_bytes;
32434   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32435   if (rc != TPM_RC_SUCCESS) {
32436     return rc;
32437   }
32438   std::string authorization_section_bytes;
32439   if (tag == TPM_ST_SESSIONS) {
32440     UINT32 parameter_section_size = buffer.size();
32441     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32442     if (rc != TPM_RC_SUCCESS) {
32443       return rc;
32444     }
32445     if (parameter_section_size > buffer.size()) {
32446       return TPM_RC_INSUFFICIENT;
32447     }
32448     authorization_section_bytes = buffer.substr(parameter_section_size);
32449     // Keep the parameter section in |buffer|.
32450     buffer.erase(parameter_section_size);
32451   }
32452   std::unique_ptr<crypto::SecureHash> hash(
32453       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32454   hash->Update(response_code_bytes.data(), response_code_bytes.size());
32455   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32456   hash->Update(buffer.data(), buffer.size());
32457   std::string response_hash(32, 0);
32458   hash->Finish(std::data(response_hash), response_hash.size());
32459   if (tag == TPM_ST_SESSIONS) {
32460     if (!authorization_delegate)
32461       return TRUNKS_RC_AUTHORIZATION_FAILED;
32462     if (!authorization_delegate->CheckResponseAuthorization(
32463             response_hash, authorization_section_bytes)) {
32464       return TRUNKS_RC_AUTHORIZATION_FAILED;
32465     }
32466   }
32467   return TPM_RC_SUCCESS;
32468 }
32469 
NV_WriteLockErrorCallback(Tpm::NV_WriteLockResponse callback,TPM_RC response_code)32470 void NV_WriteLockErrorCallback(Tpm::NV_WriteLockResponse callback,
32471                                TPM_RC response_code) {
32472   VLOG(1) << __func__;
32473   std::move(callback).Run(response_code);
32474 }
32475 
NV_WriteLockResponseParser(Tpm::NV_WriteLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32476 void NV_WriteLockResponseParser(Tpm::NV_WriteLockResponse callback,
32477                                 AuthorizationDelegate* authorization_delegate,
32478                                 const std::string& response) {
32479   VLOG(1) << __func__;
32480   TPM_RC rc = Tpm::ParseResponse_NV_WriteLock(response, authorization_delegate);
32481   if (rc != TPM_RC_SUCCESS) {
32482     base::OnceCallback<void(TPM_RC)> error_reporter =
32483         base::BindOnce(NV_WriteLockErrorCallback, std::move(callback));
32484     std::move(error_reporter).Run(rc);
32485     return;
32486   }
32487   std::move(callback).Run(rc);
32488 }
32489 
NV_WriteLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_WriteLockResponse callback)32490 void Tpm::NV_WriteLock(const TPMI_RH_NV_AUTH& auth_handle,
32491                        const std::string& auth_handle_name,
32492                        const TPMI_RH_NV_INDEX& nv_index,
32493                        const std::string& nv_index_name,
32494                        AuthorizationDelegate* authorization_delegate,
32495                        NV_WriteLockResponse callback) {
32496   VLOG(1) << __func__;
32497   std::string command;
32498   TPM_RC rc = SerializeCommand_NV_WriteLock(auth_handle, auth_handle_name,
32499                                             nv_index, nv_index_name, &command,
32500                                             authorization_delegate);
32501   if (rc != TPM_RC_SUCCESS) {
32502     base::OnceCallback<void(TPM_RC)> error_reporter =
32503         base::BindOnce(NV_WriteLockErrorCallback, std::move(callback));
32504     std::move(error_reporter).Run(rc);
32505     return;
32506   }
32507   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32508       NV_WriteLockResponseParser, std::move(callback), authorization_delegate);
32509   transceiver_->SendCommand(command, std::move(parser));
32510 }
32511 
NV_WriteLockSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)32512 TPM_RC Tpm::NV_WriteLockSync(const TPMI_RH_NV_AUTH& auth_handle,
32513                              const std::string& auth_handle_name,
32514                              const TPMI_RH_NV_INDEX& nv_index,
32515                              const std::string& nv_index_name,
32516                              AuthorizationDelegate* authorization_delegate) {
32517   VLOG(1) << __func__;
32518   std::string command;
32519   TPM_RC rc = SerializeCommand_NV_WriteLock(auth_handle, auth_handle_name,
32520                                             nv_index, nv_index_name, &command,
32521                                             authorization_delegate);
32522   if (rc != TPM_RC_SUCCESS) {
32523     return rc;
32524   }
32525   std::string response = transceiver_->SendCommandAndWait(command);
32526   rc = ParseResponse_NV_WriteLock(response, authorization_delegate);
32527   return rc;
32528 }
32529 
SerializeCommand_NV_GlobalWriteLock(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32530 TPM_RC Tpm::SerializeCommand_NV_GlobalWriteLock(
32531     const TPMI_RH_PROVISION& auth_handle,
32532     const std::string& auth_handle_name,
32533     std::string* serialized_command,
32534     AuthorizationDelegate* authorization_delegate) {
32535   VLOG(3) << __func__;
32536   TPM_RC rc = TPM_RC_SUCCESS;
32537   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32538   UINT32 command_size = 10;  // Header size.
32539   std::string handle_section_bytes;
32540   std::string parameter_section_bytes;
32541   TPM_CC command_code = TPM_CC_NV_GlobalWriteLock;
32542   bool is_command_parameter_encryption_possible = false;
32543   bool is_response_parameter_encryption_possible = false;
32544   std::string command_code_bytes;
32545   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32546   if (rc != TPM_RC_SUCCESS) {
32547     return rc;
32548   }
32549   std::string auth_handle_bytes;
32550   rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
32551   if (rc != TPM_RC_SUCCESS) {
32552     return rc;
32553   }
32554   std::unique_ptr<crypto::SecureHash> hash(
32555       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32556   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32557   hash->Update(auth_handle_name.data(), auth_handle_name.size());
32558   handle_section_bytes += auth_handle_bytes;
32559   command_size += auth_handle_bytes.size();
32560   std::string command_hash(32, 0);
32561   hash->Finish(std::data(command_hash), command_hash.size());
32562   std::string authorization_section_bytes;
32563   std::string authorization_size_bytes;
32564   if (authorization_delegate) {
32565     if (!authorization_delegate->GetCommandAuthorization(
32566             command_hash, is_command_parameter_encryption_possible,
32567             is_response_parameter_encryption_possible,
32568             &authorization_section_bytes)) {
32569       return TRUNKS_RC_AUTHORIZATION_FAILED;
32570     }
32571     if (!authorization_section_bytes.empty()) {
32572       tag = TPM_ST_SESSIONS;
32573       std::string tmp;
32574       rc = Serialize_UINT32(authorization_section_bytes.size(),
32575                             &authorization_size_bytes);
32576       if (rc != TPM_RC_SUCCESS) {
32577         return rc;
32578       }
32579       command_size +=
32580           authorization_size_bytes.size() + authorization_section_bytes.size();
32581     }
32582   }
32583   std::string tag_bytes;
32584   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32585   if (rc != TPM_RC_SUCCESS) {
32586     return rc;
32587   }
32588   std::string command_size_bytes;
32589   rc = Serialize_UINT32(command_size, &command_size_bytes);
32590   if (rc != TPM_RC_SUCCESS) {
32591     return rc;
32592   }
32593   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32594                         handle_section_bytes + authorization_size_bytes +
32595                         authorization_section_bytes + parameter_section_bytes;
32596   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32597   VLOG(2) << "Command: "
32598           << base::HexEncode(serialized_command->data(),
32599                              serialized_command->size());
32600   return TPM_RC_SUCCESS;
32601 }
32602 
ParseResponse_NV_GlobalWriteLock(const std::string & response,AuthorizationDelegate * authorization_delegate)32603 TPM_RC Tpm::ParseResponse_NV_GlobalWriteLock(
32604     const std::string& response,
32605     AuthorizationDelegate* authorization_delegate) {
32606   VLOG(3) << __func__;
32607   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32608   TPM_RC rc = TPM_RC_SUCCESS;
32609   std::string buffer(response);
32610   TPM_ST tag;
32611   std::string tag_bytes;
32612   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32613   if (rc != TPM_RC_SUCCESS) {
32614     return rc;
32615   }
32616   UINT32 response_size;
32617   std::string response_size_bytes;
32618   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32619   if (rc != TPM_RC_SUCCESS) {
32620     return rc;
32621   }
32622   TPM_RC response_code;
32623   std::string response_code_bytes;
32624   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32625   if (rc != TPM_RC_SUCCESS) {
32626     return rc;
32627   }
32628   if (response_size != response.size()) {
32629     return TPM_RC_SIZE;
32630   }
32631   if (response_code != TPM_RC_SUCCESS) {
32632     return response_code;
32633   }
32634   TPM_CC command_code = TPM_CC_NV_GlobalWriteLock;
32635   std::string command_code_bytes;
32636   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32637   if (rc != TPM_RC_SUCCESS) {
32638     return rc;
32639   }
32640   std::string authorization_section_bytes;
32641   if (tag == TPM_ST_SESSIONS) {
32642     UINT32 parameter_section_size = buffer.size();
32643     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32644     if (rc != TPM_RC_SUCCESS) {
32645       return rc;
32646     }
32647     if (parameter_section_size > buffer.size()) {
32648       return TPM_RC_INSUFFICIENT;
32649     }
32650     authorization_section_bytes = buffer.substr(parameter_section_size);
32651     // Keep the parameter section in |buffer|.
32652     buffer.erase(parameter_section_size);
32653   }
32654   std::unique_ptr<crypto::SecureHash> hash(
32655       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32656   hash->Update(response_code_bytes.data(), response_code_bytes.size());
32657   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32658   hash->Update(buffer.data(), buffer.size());
32659   std::string response_hash(32, 0);
32660   hash->Finish(std::data(response_hash), response_hash.size());
32661   if (tag == TPM_ST_SESSIONS) {
32662     if (!authorization_delegate)
32663       return TRUNKS_RC_AUTHORIZATION_FAILED;
32664     if (!authorization_delegate->CheckResponseAuthorization(
32665             response_hash, authorization_section_bytes)) {
32666       return TRUNKS_RC_AUTHORIZATION_FAILED;
32667     }
32668   }
32669   return TPM_RC_SUCCESS;
32670 }
32671 
NV_GlobalWriteLockErrorCallback(Tpm::NV_GlobalWriteLockResponse callback,TPM_RC response_code)32672 void NV_GlobalWriteLockErrorCallback(Tpm::NV_GlobalWriteLockResponse callback,
32673                                      TPM_RC response_code) {
32674   VLOG(1) << __func__;
32675   std::move(callback).Run(response_code);
32676 }
32677 
NV_GlobalWriteLockResponseParser(Tpm::NV_GlobalWriteLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32678 void NV_GlobalWriteLockResponseParser(
32679     Tpm::NV_GlobalWriteLockResponse callback,
32680     AuthorizationDelegate* authorization_delegate,
32681     const std::string& response) {
32682   VLOG(1) << __func__;
32683   TPM_RC rc =
32684       Tpm::ParseResponse_NV_GlobalWriteLock(response, authorization_delegate);
32685   if (rc != TPM_RC_SUCCESS) {
32686     base::OnceCallback<void(TPM_RC)> error_reporter =
32687         base::BindOnce(NV_GlobalWriteLockErrorCallback, std::move(callback));
32688     std::move(error_reporter).Run(rc);
32689     return;
32690   }
32691   std::move(callback).Run(rc);
32692 }
32693 
NV_GlobalWriteLock(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,NV_GlobalWriteLockResponse callback)32694 void Tpm::NV_GlobalWriteLock(const TPMI_RH_PROVISION& auth_handle,
32695                              const std::string& auth_handle_name,
32696                              AuthorizationDelegate* authorization_delegate,
32697                              NV_GlobalWriteLockResponse callback) {
32698   VLOG(1) << __func__;
32699   std::string command;
32700   TPM_RC rc = SerializeCommand_NV_GlobalWriteLock(
32701       auth_handle, auth_handle_name, &command, authorization_delegate);
32702   if (rc != TPM_RC_SUCCESS) {
32703     base::OnceCallback<void(TPM_RC)> error_reporter =
32704         base::BindOnce(NV_GlobalWriteLockErrorCallback, std::move(callback));
32705     std::move(error_reporter).Run(rc);
32706     return;
32707   }
32708   base::OnceCallback<void(const std::string&)> parser =
32709       base::BindOnce(NV_GlobalWriteLockResponseParser, std::move(callback),
32710                      authorization_delegate);
32711   transceiver_->SendCommand(command, std::move(parser));
32712 }
32713 
NV_GlobalWriteLockSync(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)32714 TPM_RC Tpm::NV_GlobalWriteLockSync(
32715     const TPMI_RH_PROVISION& auth_handle,
32716     const std::string& auth_handle_name,
32717     AuthorizationDelegate* authorization_delegate) {
32718   VLOG(1) << __func__;
32719   std::string command;
32720   TPM_RC rc = SerializeCommand_NV_GlobalWriteLock(
32721       auth_handle, auth_handle_name, &command, authorization_delegate);
32722   if (rc != TPM_RC_SUCCESS) {
32723     return rc;
32724   }
32725   std::string response = transceiver_->SendCommandAndWait(command);
32726   rc = ParseResponse_NV_GlobalWriteLock(response, authorization_delegate);
32727   return rc;
32728 }
32729 
SerializeCommand_NV_Read(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT16 & size,const UINT16 & offset,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32730 TPM_RC Tpm::SerializeCommand_NV_Read(
32731     const TPMI_RH_NV_AUTH& auth_handle,
32732     const std::string& auth_handle_name,
32733     const TPMI_RH_NV_INDEX& nv_index,
32734     const std::string& nv_index_name,
32735     const UINT16& size,
32736     const UINT16& offset,
32737     std::string* serialized_command,
32738     AuthorizationDelegate* authorization_delegate) {
32739   VLOG(3) << __func__;
32740   TPM_RC rc = TPM_RC_SUCCESS;
32741   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32742   UINT32 command_size = 10;  // Header size.
32743   std::string handle_section_bytes;
32744   std::string parameter_section_bytes;
32745   TPM_CC command_code = TPM_CC_NV_Read;
32746   bool is_command_parameter_encryption_possible = false;
32747   bool is_response_parameter_encryption_possible = true;
32748   std::string command_code_bytes;
32749   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32750   if (rc != TPM_RC_SUCCESS) {
32751     return rc;
32752   }
32753   std::string auth_handle_bytes;
32754   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32755   if (rc != TPM_RC_SUCCESS) {
32756     return rc;
32757   }
32758   std::string nv_index_bytes;
32759   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32760   if (rc != TPM_RC_SUCCESS) {
32761     return rc;
32762   }
32763   std::string size_bytes;
32764   rc = Serialize_UINT16(size, &size_bytes);
32765   if (rc != TPM_RC_SUCCESS) {
32766     return rc;
32767   }
32768   std::string offset_bytes;
32769   rc = Serialize_UINT16(offset, &offset_bytes);
32770   if (rc != TPM_RC_SUCCESS) {
32771     return rc;
32772   }
32773   std::unique_ptr<crypto::SecureHash> hash(
32774       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32775   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32776   hash->Update(auth_handle_name.data(), auth_handle_name.size());
32777   handle_section_bytes += auth_handle_bytes;
32778   command_size += auth_handle_bytes.size();
32779   hash->Update(nv_index_name.data(), nv_index_name.size());
32780   handle_section_bytes += nv_index_bytes;
32781   command_size += nv_index_bytes.size();
32782   hash->Update(size_bytes.data(), size_bytes.size());
32783   parameter_section_bytes += size_bytes;
32784   command_size += size_bytes.size();
32785   hash->Update(offset_bytes.data(), offset_bytes.size());
32786   parameter_section_bytes += offset_bytes;
32787   command_size += offset_bytes.size();
32788   std::string command_hash(32, 0);
32789   hash->Finish(std::data(command_hash), command_hash.size());
32790   std::string authorization_section_bytes;
32791   std::string authorization_size_bytes;
32792   if (authorization_delegate) {
32793     if (!authorization_delegate->GetCommandAuthorization(
32794             command_hash, is_command_parameter_encryption_possible,
32795             is_response_parameter_encryption_possible,
32796             &authorization_section_bytes)) {
32797       return TRUNKS_RC_AUTHORIZATION_FAILED;
32798     }
32799     if (!authorization_section_bytes.empty()) {
32800       tag = TPM_ST_SESSIONS;
32801       std::string tmp;
32802       rc = Serialize_UINT32(authorization_section_bytes.size(),
32803                             &authorization_size_bytes);
32804       if (rc != TPM_RC_SUCCESS) {
32805         return rc;
32806       }
32807       command_size +=
32808           authorization_size_bytes.size() + authorization_section_bytes.size();
32809     }
32810   }
32811   std::string tag_bytes;
32812   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32813   if (rc != TPM_RC_SUCCESS) {
32814     return rc;
32815   }
32816   std::string command_size_bytes;
32817   rc = Serialize_UINT32(command_size, &command_size_bytes);
32818   if (rc != TPM_RC_SUCCESS) {
32819     return rc;
32820   }
32821   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32822                         handle_section_bytes + authorization_size_bytes +
32823                         authorization_section_bytes + parameter_section_bytes;
32824   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32825   VLOG(2) << "Command: "
32826           << base::HexEncode(serialized_command->data(),
32827                              serialized_command->size());
32828   return TPM_RC_SUCCESS;
32829 }
32830 
ParseResponse_NV_Read(const std::string & response,TPM2B_MAX_NV_BUFFER * data,AuthorizationDelegate * authorization_delegate)32831 TPM_RC Tpm::ParseResponse_NV_Read(
32832     const std::string& response,
32833     TPM2B_MAX_NV_BUFFER* data,
32834     AuthorizationDelegate* authorization_delegate) {
32835   VLOG(3) << __func__;
32836   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32837   TPM_RC rc = TPM_RC_SUCCESS;
32838   std::string buffer(response);
32839   TPM_ST tag;
32840   std::string tag_bytes;
32841   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32842   if (rc != TPM_RC_SUCCESS) {
32843     return rc;
32844   }
32845   UINT32 response_size;
32846   std::string response_size_bytes;
32847   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32848   if (rc != TPM_RC_SUCCESS) {
32849     return rc;
32850   }
32851   TPM_RC response_code;
32852   std::string response_code_bytes;
32853   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32854   if (rc != TPM_RC_SUCCESS) {
32855     return rc;
32856   }
32857   if (response_size != response.size()) {
32858     return TPM_RC_SIZE;
32859   }
32860   if (response_code != TPM_RC_SUCCESS) {
32861     return response_code;
32862   }
32863   TPM_CC command_code = TPM_CC_NV_Read;
32864   std::string command_code_bytes;
32865   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32866   if (rc != TPM_RC_SUCCESS) {
32867     return rc;
32868   }
32869   std::string authorization_section_bytes;
32870   if (tag == TPM_ST_SESSIONS) {
32871     UINT32 parameter_section_size = buffer.size();
32872     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32873     if (rc != TPM_RC_SUCCESS) {
32874       return rc;
32875     }
32876     if (parameter_section_size > buffer.size()) {
32877       return TPM_RC_INSUFFICIENT;
32878     }
32879     authorization_section_bytes = buffer.substr(parameter_section_size);
32880     // Keep the parameter section in |buffer|.
32881     buffer.erase(parameter_section_size);
32882   }
32883   std::unique_ptr<crypto::SecureHash> hash(
32884       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32885   hash->Update(response_code_bytes.data(), response_code_bytes.size());
32886   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32887   hash->Update(buffer.data(), buffer.size());
32888   std::string response_hash(32, 0);
32889   hash->Finish(std::data(response_hash), response_hash.size());
32890   if (tag == TPM_ST_SESSIONS) {
32891     if (!authorization_delegate)
32892       return TRUNKS_RC_AUTHORIZATION_FAILED;
32893     if (!authorization_delegate->CheckResponseAuthorization(
32894             response_hash, authorization_section_bytes)) {
32895       return TRUNKS_RC_AUTHORIZATION_FAILED;
32896     }
32897   }
32898   if (tag == TPM_ST_SESSIONS) {
32899     if (!authorization_delegate)
32900       return TRUNKS_RC_AUTHORIZATION_FAILED;
32901 
32902     // Parse the encrypted parameter size.
32903     UINT16 size;
32904     std::string size_buffer = buffer.substr(0, 2);
32905     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
32906       return result;
32907     }
32908     if (buffer.size() < 2 + size) {
32909       return TPM_RC_INSUFFICIENT;
32910     }
32911 
32912     // Decrypt just the parameter data, not the size.
32913     std::string decrypted_data = buffer.substr(2, size);
32914     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
32915       return TRUNKS_RC_ENCRYPTION_FAILED;
32916     }
32917     buffer.replace(2, size, decrypted_data);
32918   }
32919   std::string data_bytes;
32920   rc = Parse_TPM2B_MAX_NV_BUFFER(&buffer, data, &data_bytes);
32921   if (rc != TPM_RC_SUCCESS) {
32922     return rc;
32923   }
32924   return TPM_RC_SUCCESS;
32925 }
32926 
NV_ReadErrorCallback(Tpm::NV_ReadResponse callback,TPM_RC response_code)32927 void NV_ReadErrorCallback(Tpm::NV_ReadResponse callback, TPM_RC response_code) {
32928   VLOG(1) << __func__;
32929   std::move(callback).Run(response_code, TPM2B_MAX_NV_BUFFER());
32930 }
32931 
NV_ReadResponseParser(Tpm::NV_ReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32932 void NV_ReadResponseParser(Tpm::NV_ReadResponse callback,
32933                            AuthorizationDelegate* authorization_delegate,
32934                            const std::string& response) {
32935   VLOG(1) << __func__;
32936   TPM2B_MAX_NV_BUFFER data;
32937   TPM_RC rc =
32938       Tpm::ParseResponse_NV_Read(response, &data, authorization_delegate);
32939   if (rc != TPM_RC_SUCCESS) {
32940     base::OnceCallback<void(TPM_RC)> error_reporter =
32941         base::BindOnce(NV_ReadErrorCallback, std::move(callback));
32942     std::move(error_reporter).Run(rc);
32943     return;
32944   }
32945   std::move(callback).Run(rc, data);
32946 }
32947 
NV_Read(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT16 & size,const UINT16 & offset,AuthorizationDelegate * authorization_delegate,NV_ReadResponse callback)32948 void Tpm::NV_Read(const TPMI_RH_NV_AUTH& auth_handle,
32949                   const std::string& auth_handle_name,
32950                   const TPMI_RH_NV_INDEX& nv_index,
32951                   const std::string& nv_index_name,
32952                   const UINT16& size,
32953                   const UINT16& offset,
32954                   AuthorizationDelegate* authorization_delegate,
32955                   NV_ReadResponse callback) {
32956   VLOG(1) << __func__;
32957   std::string command;
32958   TPM_RC rc = SerializeCommand_NV_Read(auth_handle, auth_handle_name, nv_index,
32959                                        nv_index_name, size, offset, &command,
32960                                        authorization_delegate);
32961   if (rc != TPM_RC_SUCCESS) {
32962     base::OnceCallback<void(TPM_RC)> error_reporter =
32963         base::BindOnce(NV_ReadErrorCallback, std::move(callback));
32964     std::move(error_reporter).Run(rc);
32965     return;
32966   }
32967   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32968       NV_ReadResponseParser, std::move(callback), authorization_delegate);
32969   transceiver_->SendCommand(command, std::move(parser));
32970 }
32971 
NV_ReadSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT16 & size,const UINT16 & offset,TPM2B_MAX_NV_BUFFER * data,AuthorizationDelegate * authorization_delegate)32972 TPM_RC Tpm::NV_ReadSync(const TPMI_RH_NV_AUTH& auth_handle,
32973                         const std::string& auth_handle_name,
32974                         const TPMI_RH_NV_INDEX& nv_index,
32975                         const std::string& nv_index_name,
32976                         const UINT16& size,
32977                         const UINT16& offset,
32978                         TPM2B_MAX_NV_BUFFER* data,
32979                         AuthorizationDelegate* authorization_delegate) {
32980   VLOG(1) << __func__;
32981   std::string command;
32982   TPM_RC rc = SerializeCommand_NV_Read(auth_handle, auth_handle_name, nv_index,
32983                                        nv_index_name, size, offset, &command,
32984                                        authorization_delegate);
32985   if (rc != TPM_RC_SUCCESS) {
32986     return rc;
32987   }
32988   std::string response = transceiver_->SendCommandAndWait(command);
32989   rc = ParseResponse_NV_Read(response, data, authorization_delegate);
32990   return rc;
32991 }
32992 
SerializeCommand_NV_ReadLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32993 TPM_RC Tpm::SerializeCommand_NV_ReadLock(
32994     const TPMI_RH_NV_AUTH& auth_handle,
32995     const std::string& auth_handle_name,
32996     const TPMI_RH_NV_INDEX& nv_index,
32997     const std::string& nv_index_name,
32998     std::string* serialized_command,
32999     AuthorizationDelegate* authorization_delegate) {
33000   VLOG(3) << __func__;
33001   TPM_RC rc = TPM_RC_SUCCESS;
33002   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33003   UINT32 command_size = 10;  // Header size.
33004   std::string handle_section_bytes;
33005   std::string parameter_section_bytes;
33006   TPM_CC command_code = TPM_CC_NV_ReadLock;
33007   bool is_command_parameter_encryption_possible = false;
33008   bool is_response_parameter_encryption_possible = false;
33009   std::string command_code_bytes;
33010   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33011   if (rc != TPM_RC_SUCCESS) {
33012     return rc;
33013   }
33014   std::string auth_handle_bytes;
33015   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
33016   if (rc != TPM_RC_SUCCESS) {
33017     return rc;
33018   }
33019   std::string nv_index_bytes;
33020   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33021   if (rc != TPM_RC_SUCCESS) {
33022     return rc;
33023   }
33024   std::unique_ptr<crypto::SecureHash> hash(
33025       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33026   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33027   hash->Update(auth_handle_name.data(), auth_handle_name.size());
33028   handle_section_bytes += auth_handle_bytes;
33029   command_size += auth_handle_bytes.size();
33030   hash->Update(nv_index_name.data(), nv_index_name.size());
33031   handle_section_bytes += nv_index_bytes;
33032   command_size += nv_index_bytes.size();
33033   std::string command_hash(32, 0);
33034   hash->Finish(std::data(command_hash), command_hash.size());
33035   std::string authorization_section_bytes;
33036   std::string authorization_size_bytes;
33037   if (authorization_delegate) {
33038     if (!authorization_delegate->GetCommandAuthorization(
33039             command_hash, is_command_parameter_encryption_possible,
33040             is_response_parameter_encryption_possible,
33041             &authorization_section_bytes)) {
33042       return TRUNKS_RC_AUTHORIZATION_FAILED;
33043     }
33044     if (!authorization_section_bytes.empty()) {
33045       tag = TPM_ST_SESSIONS;
33046       std::string tmp;
33047       rc = Serialize_UINT32(authorization_section_bytes.size(),
33048                             &authorization_size_bytes);
33049       if (rc != TPM_RC_SUCCESS) {
33050         return rc;
33051       }
33052       command_size +=
33053           authorization_size_bytes.size() + authorization_section_bytes.size();
33054     }
33055   }
33056   std::string tag_bytes;
33057   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33058   if (rc != TPM_RC_SUCCESS) {
33059     return rc;
33060   }
33061   std::string command_size_bytes;
33062   rc = Serialize_UINT32(command_size, &command_size_bytes);
33063   if (rc != TPM_RC_SUCCESS) {
33064     return rc;
33065   }
33066   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33067                         handle_section_bytes + authorization_size_bytes +
33068                         authorization_section_bytes + parameter_section_bytes;
33069   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33070   VLOG(2) << "Command: "
33071           << base::HexEncode(serialized_command->data(),
33072                              serialized_command->size());
33073   return TPM_RC_SUCCESS;
33074 }
33075 
ParseResponse_NV_ReadLock(const std::string & response,AuthorizationDelegate * authorization_delegate)33076 TPM_RC Tpm::ParseResponse_NV_ReadLock(
33077     const std::string& response,
33078     AuthorizationDelegate* authorization_delegate) {
33079   VLOG(3) << __func__;
33080   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33081   TPM_RC rc = TPM_RC_SUCCESS;
33082   std::string buffer(response);
33083   TPM_ST tag;
33084   std::string tag_bytes;
33085   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33086   if (rc != TPM_RC_SUCCESS) {
33087     return rc;
33088   }
33089   UINT32 response_size;
33090   std::string response_size_bytes;
33091   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33092   if (rc != TPM_RC_SUCCESS) {
33093     return rc;
33094   }
33095   TPM_RC response_code;
33096   std::string response_code_bytes;
33097   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33098   if (rc != TPM_RC_SUCCESS) {
33099     return rc;
33100   }
33101   if (response_size != response.size()) {
33102     return TPM_RC_SIZE;
33103   }
33104   if (response_code != TPM_RC_SUCCESS) {
33105     return response_code;
33106   }
33107   TPM_CC command_code = TPM_CC_NV_ReadLock;
33108   std::string command_code_bytes;
33109   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33110   if (rc != TPM_RC_SUCCESS) {
33111     return rc;
33112   }
33113   std::string authorization_section_bytes;
33114   if (tag == TPM_ST_SESSIONS) {
33115     UINT32 parameter_section_size = buffer.size();
33116     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
33117     if (rc != TPM_RC_SUCCESS) {
33118       return rc;
33119     }
33120     if (parameter_section_size > buffer.size()) {
33121       return TPM_RC_INSUFFICIENT;
33122     }
33123     authorization_section_bytes = buffer.substr(parameter_section_size);
33124     // Keep the parameter section in |buffer|.
33125     buffer.erase(parameter_section_size);
33126   }
33127   std::unique_ptr<crypto::SecureHash> hash(
33128       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33129   hash->Update(response_code_bytes.data(), response_code_bytes.size());
33130   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33131   hash->Update(buffer.data(), buffer.size());
33132   std::string response_hash(32, 0);
33133   hash->Finish(std::data(response_hash), response_hash.size());
33134   if (tag == TPM_ST_SESSIONS) {
33135     if (!authorization_delegate)
33136       return TRUNKS_RC_AUTHORIZATION_FAILED;
33137     if (!authorization_delegate->CheckResponseAuthorization(
33138             response_hash, authorization_section_bytes)) {
33139       return TRUNKS_RC_AUTHORIZATION_FAILED;
33140     }
33141   }
33142   return TPM_RC_SUCCESS;
33143 }
33144 
NV_ReadLockErrorCallback(Tpm::NV_ReadLockResponse callback,TPM_RC response_code)33145 void NV_ReadLockErrorCallback(Tpm::NV_ReadLockResponse callback,
33146                               TPM_RC response_code) {
33147   VLOG(1) << __func__;
33148   std::move(callback).Run(response_code);
33149 }
33150 
NV_ReadLockResponseParser(Tpm::NV_ReadLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33151 void NV_ReadLockResponseParser(Tpm::NV_ReadLockResponse callback,
33152                                AuthorizationDelegate* authorization_delegate,
33153                                const std::string& response) {
33154   VLOG(1) << __func__;
33155   TPM_RC rc = Tpm::ParseResponse_NV_ReadLock(response, authorization_delegate);
33156   if (rc != TPM_RC_SUCCESS) {
33157     base::OnceCallback<void(TPM_RC)> error_reporter =
33158         base::BindOnce(NV_ReadLockErrorCallback, std::move(callback));
33159     std::move(error_reporter).Run(rc);
33160     return;
33161   }
33162   std::move(callback).Run(rc);
33163 }
33164 
NV_ReadLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_ReadLockResponse callback)33165 void Tpm::NV_ReadLock(const TPMI_RH_NV_AUTH& auth_handle,
33166                       const std::string& auth_handle_name,
33167                       const TPMI_RH_NV_INDEX& nv_index,
33168                       const std::string& nv_index_name,
33169                       AuthorizationDelegate* authorization_delegate,
33170                       NV_ReadLockResponse callback) {
33171   VLOG(1) << __func__;
33172   std::string command;
33173   TPM_RC rc = SerializeCommand_NV_ReadLock(auth_handle, auth_handle_name,
33174                                            nv_index, nv_index_name, &command,
33175                                            authorization_delegate);
33176   if (rc != TPM_RC_SUCCESS) {
33177     base::OnceCallback<void(TPM_RC)> error_reporter =
33178         base::BindOnce(NV_ReadLockErrorCallback, std::move(callback));
33179     std::move(error_reporter).Run(rc);
33180     return;
33181   }
33182   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33183       NV_ReadLockResponseParser, std::move(callback), authorization_delegate);
33184   transceiver_->SendCommand(command, std::move(parser));
33185 }
33186 
NV_ReadLockSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)33187 TPM_RC Tpm::NV_ReadLockSync(const TPMI_RH_NV_AUTH& auth_handle,
33188                             const std::string& auth_handle_name,
33189                             const TPMI_RH_NV_INDEX& nv_index,
33190                             const std::string& nv_index_name,
33191                             AuthorizationDelegate* authorization_delegate) {
33192   VLOG(1) << __func__;
33193   std::string command;
33194   TPM_RC rc = SerializeCommand_NV_ReadLock(auth_handle, auth_handle_name,
33195                                            nv_index, nv_index_name, &command,
33196                                            authorization_delegate);
33197   if (rc != TPM_RC_SUCCESS) {
33198     return rc;
33199   }
33200   std::string response = transceiver_->SendCommandAndWait(command);
33201   rc = ParseResponse_NV_ReadLock(response, authorization_delegate);
33202   return rc;
33203 }
33204 
SerializeCommand_NV_ChangeAuth(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_AUTH & new_auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)33205 TPM_RC Tpm::SerializeCommand_NV_ChangeAuth(
33206     const TPMI_RH_NV_INDEX& nv_index,
33207     const std::string& nv_index_name,
33208     const TPM2B_AUTH& new_auth,
33209     std::string* serialized_command,
33210     AuthorizationDelegate* authorization_delegate) {
33211   VLOG(3) << __func__;
33212   TPM_RC rc = TPM_RC_SUCCESS;
33213   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33214   UINT32 command_size = 10;  // Header size.
33215   std::string handle_section_bytes;
33216   std::string parameter_section_bytes;
33217   TPM_CC command_code = TPM_CC_NV_ChangeAuth;
33218   bool is_command_parameter_encryption_possible = true;
33219   bool is_response_parameter_encryption_possible = false;
33220   std::string command_code_bytes;
33221   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33222   if (rc != TPM_RC_SUCCESS) {
33223     return rc;
33224   }
33225   std::string nv_index_bytes;
33226   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33227   if (rc != TPM_RC_SUCCESS) {
33228     return rc;
33229   }
33230   std::string new_auth_bytes;
33231   rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
33232   if (rc != TPM_RC_SUCCESS) {
33233     return rc;
33234   }
33235   if (authorization_delegate) {
33236     // Encrypt just the parameter data, not the size.
33237     std::string tmp = new_auth_bytes.substr(2);
33238     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
33239       return TRUNKS_RC_ENCRYPTION_FAILED;
33240     }
33241     new_auth_bytes.replace(2, std::string::npos, tmp);
33242   }
33243   std::unique_ptr<crypto::SecureHash> hash(
33244       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33245   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33246   hash->Update(nv_index_name.data(), nv_index_name.size());
33247   handle_section_bytes += nv_index_bytes;
33248   command_size += nv_index_bytes.size();
33249   hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
33250   parameter_section_bytes += new_auth_bytes;
33251   command_size += new_auth_bytes.size();
33252   std::string command_hash(32, 0);
33253   hash->Finish(std::data(command_hash), command_hash.size());
33254   std::string authorization_section_bytes;
33255   std::string authorization_size_bytes;
33256   if (authorization_delegate) {
33257     if (!authorization_delegate->GetCommandAuthorization(
33258             command_hash, is_command_parameter_encryption_possible,
33259             is_response_parameter_encryption_possible,
33260             &authorization_section_bytes)) {
33261       return TRUNKS_RC_AUTHORIZATION_FAILED;
33262     }
33263     if (!authorization_section_bytes.empty()) {
33264       tag = TPM_ST_SESSIONS;
33265       std::string tmp;
33266       rc = Serialize_UINT32(authorization_section_bytes.size(),
33267                             &authorization_size_bytes);
33268       if (rc != TPM_RC_SUCCESS) {
33269         return rc;
33270       }
33271       command_size +=
33272           authorization_size_bytes.size() + authorization_section_bytes.size();
33273     }
33274   }
33275   std::string tag_bytes;
33276   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33277   if (rc != TPM_RC_SUCCESS) {
33278     return rc;
33279   }
33280   std::string command_size_bytes;
33281   rc = Serialize_UINT32(command_size, &command_size_bytes);
33282   if (rc != TPM_RC_SUCCESS) {
33283     return rc;
33284   }
33285   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33286                         handle_section_bytes + authorization_size_bytes +
33287                         authorization_section_bytes + parameter_section_bytes;
33288   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33289   VLOG(2) << "Command: "
33290           << base::HexEncode(serialized_command->data(),
33291                              serialized_command->size());
33292   return TPM_RC_SUCCESS;
33293 }
33294 
ParseResponse_NV_ChangeAuth(const std::string & response,AuthorizationDelegate * authorization_delegate)33295 TPM_RC Tpm::ParseResponse_NV_ChangeAuth(
33296     const std::string& response,
33297     AuthorizationDelegate* authorization_delegate) {
33298   VLOG(3) << __func__;
33299   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33300   TPM_RC rc = TPM_RC_SUCCESS;
33301   std::string buffer(response);
33302   TPM_ST tag;
33303   std::string tag_bytes;
33304   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33305   if (rc != TPM_RC_SUCCESS) {
33306     return rc;
33307   }
33308   UINT32 response_size;
33309   std::string response_size_bytes;
33310   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33311   if (rc != TPM_RC_SUCCESS) {
33312     return rc;
33313   }
33314   TPM_RC response_code;
33315   std::string response_code_bytes;
33316   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33317   if (rc != TPM_RC_SUCCESS) {
33318     return rc;
33319   }
33320   if (response_size != response.size()) {
33321     return TPM_RC_SIZE;
33322   }
33323   if (response_code != TPM_RC_SUCCESS) {
33324     return response_code;
33325   }
33326   TPM_CC command_code = TPM_CC_NV_ChangeAuth;
33327   std::string command_code_bytes;
33328   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33329   if (rc != TPM_RC_SUCCESS) {
33330     return rc;
33331   }
33332   std::string authorization_section_bytes;
33333   if (tag == TPM_ST_SESSIONS) {
33334     UINT32 parameter_section_size = buffer.size();
33335     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
33336     if (rc != TPM_RC_SUCCESS) {
33337       return rc;
33338     }
33339     if (parameter_section_size > buffer.size()) {
33340       return TPM_RC_INSUFFICIENT;
33341     }
33342     authorization_section_bytes = buffer.substr(parameter_section_size);
33343     // Keep the parameter section in |buffer|.
33344     buffer.erase(parameter_section_size);
33345   }
33346   std::unique_ptr<crypto::SecureHash> hash(
33347       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33348   hash->Update(response_code_bytes.data(), response_code_bytes.size());
33349   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33350   hash->Update(buffer.data(), buffer.size());
33351   std::string response_hash(32, 0);
33352   hash->Finish(std::data(response_hash), response_hash.size());
33353   if (tag == TPM_ST_SESSIONS) {
33354     if (!authorization_delegate)
33355       return TRUNKS_RC_AUTHORIZATION_FAILED;
33356     if (!authorization_delegate->CheckResponseAuthorization(
33357             response_hash, authorization_section_bytes)) {
33358       return TRUNKS_RC_AUTHORIZATION_FAILED;
33359     }
33360   }
33361   return TPM_RC_SUCCESS;
33362 }
33363 
NV_ChangeAuthErrorCallback(Tpm::NV_ChangeAuthResponse callback,TPM_RC response_code)33364 void NV_ChangeAuthErrorCallback(Tpm::NV_ChangeAuthResponse callback,
33365                                 TPM_RC response_code) {
33366   VLOG(1) << __func__;
33367   std::move(callback).Run(response_code);
33368 }
33369 
NV_ChangeAuthResponseParser(Tpm::NV_ChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33370 void NV_ChangeAuthResponseParser(Tpm::NV_ChangeAuthResponse callback,
33371                                  AuthorizationDelegate* authorization_delegate,
33372                                  const std::string& response) {
33373   VLOG(1) << __func__;
33374   TPM_RC rc =
33375       Tpm::ParseResponse_NV_ChangeAuth(response, authorization_delegate);
33376   if (rc != TPM_RC_SUCCESS) {
33377     base::OnceCallback<void(TPM_RC)> error_reporter =
33378         base::BindOnce(NV_ChangeAuthErrorCallback, std::move(callback));
33379     std::move(error_reporter).Run(rc);
33380     return;
33381   }
33382   std::move(callback).Run(rc);
33383 }
33384 
NV_ChangeAuth(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate,NV_ChangeAuthResponse callback)33385 void Tpm::NV_ChangeAuth(const TPMI_RH_NV_INDEX& nv_index,
33386                         const std::string& nv_index_name,
33387                         const TPM2B_AUTH& new_auth,
33388                         AuthorizationDelegate* authorization_delegate,
33389                         NV_ChangeAuthResponse callback) {
33390   VLOG(1) << __func__;
33391   std::string command;
33392   TPM_RC rc = SerializeCommand_NV_ChangeAuth(nv_index, nv_index_name, new_auth,
33393                                              &command, authorization_delegate);
33394   if (rc != TPM_RC_SUCCESS) {
33395     base::OnceCallback<void(TPM_RC)> error_reporter =
33396         base::BindOnce(NV_ChangeAuthErrorCallback, std::move(callback));
33397     std::move(error_reporter).Run(rc);
33398     return;
33399   }
33400   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33401       NV_ChangeAuthResponseParser, std::move(callback), authorization_delegate);
33402   transceiver_->SendCommand(command, std::move(parser));
33403 }
33404 
NV_ChangeAuthSync(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate)33405 TPM_RC Tpm::NV_ChangeAuthSync(const TPMI_RH_NV_INDEX& nv_index,
33406                               const std::string& nv_index_name,
33407                               const TPM2B_AUTH& new_auth,
33408                               AuthorizationDelegate* authorization_delegate) {
33409   VLOG(1) << __func__;
33410   std::string command;
33411   TPM_RC rc = SerializeCommand_NV_ChangeAuth(nv_index, nv_index_name, new_auth,
33412                                              &command, authorization_delegate);
33413   if (rc != TPM_RC_SUCCESS) {
33414     return rc;
33415   }
33416   std::string response = transceiver_->SendCommandAndWait(command);
33417   rc = ParseResponse_NV_ChangeAuth(response, authorization_delegate);
33418   return rc;
33419 }
33420 
SerializeCommand_NV_Certify(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const UINT16 & size,const UINT16 & offset,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)33421 TPM_RC Tpm::SerializeCommand_NV_Certify(
33422     const TPMI_DH_OBJECT& sign_handle,
33423     const std::string& sign_handle_name,
33424     const TPMI_RH_NV_AUTH& auth_handle,
33425     const std::string& auth_handle_name,
33426     const TPMI_RH_NV_INDEX& nv_index,
33427     const std::string& nv_index_name,
33428     const TPM2B_DATA& qualifying_data,
33429     const TPMT_SIG_SCHEME& in_scheme,
33430     const UINT16& size,
33431     const UINT16& offset,
33432     std::string* serialized_command,
33433     AuthorizationDelegate* authorization_delegate) {
33434   VLOG(3) << __func__;
33435   TPM_RC rc = TPM_RC_SUCCESS;
33436   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33437   UINT32 command_size = 10;  // Header size.
33438   std::string handle_section_bytes;
33439   std::string parameter_section_bytes;
33440   TPM_CC command_code = TPM_CC_NV_Certify;
33441   bool is_command_parameter_encryption_possible = true;
33442   bool is_response_parameter_encryption_possible = true;
33443   std::string command_code_bytes;
33444   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33445   if (rc != TPM_RC_SUCCESS) {
33446     return rc;
33447   }
33448   std::string sign_handle_bytes;
33449   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
33450   if (rc != TPM_RC_SUCCESS) {
33451     return rc;
33452   }
33453   std::string auth_handle_bytes;
33454   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
33455   if (rc != TPM_RC_SUCCESS) {
33456     return rc;
33457   }
33458   std::string nv_index_bytes;
33459   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33460   if (rc != TPM_RC_SUCCESS) {
33461     return rc;
33462   }
33463   std::string qualifying_data_bytes;
33464   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
33465   if (rc != TPM_RC_SUCCESS) {
33466     return rc;
33467   }
33468   std::string in_scheme_bytes;
33469   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
33470   if (rc != TPM_RC_SUCCESS) {
33471     return rc;
33472   }
33473   std::string size_bytes;
33474   rc = Serialize_UINT16(size, &size_bytes);
33475   if (rc != TPM_RC_SUCCESS) {
33476     return rc;
33477   }
33478   std::string offset_bytes;
33479   rc = Serialize_UINT16(offset, &offset_bytes);
33480   if (rc != TPM_RC_SUCCESS) {
33481     return rc;
33482   }
33483   if (authorization_delegate) {
33484     // Encrypt just the parameter data, not the size.
33485     std::string tmp = qualifying_data_bytes.substr(2);
33486     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
33487       return TRUNKS_RC_ENCRYPTION_FAILED;
33488     }
33489     qualifying_data_bytes.replace(2, std::string::npos, tmp);
33490   }
33491   std::unique_ptr<crypto::SecureHash> hash(
33492       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33493   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33494   hash->Update(sign_handle_name.data(), sign_handle_name.size());
33495   handle_section_bytes += sign_handle_bytes;
33496   command_size += sign_handle_bytes.size();
33497   hash->Update(auth_handle_name.data(), auth_handle_name.size());
33498   handle_section_bytes += auth_handle_bytes;
33499   command_size += auth_handle_bytes.size();
33500   hash->Update(nv_index_name.data(), nv_index_name.size());
33501   handle_section_bytes += nv_index_bytes;
33502   command_size += nv_index_bytes.size();
33503   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
33504   parameter_section_bytes += qualifying_data_bytes;
33505   command_size += qualifying_data_bytes.size();
33506   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
33507   parameter_section_bytes += in_scheme_bytes;
33508   command_size += in_scheme_bytes.size();
33509   hash->Update(size_bytes.data(), size_bytes.size());
33510   parameter_section_bytes += size_bytes;
33511   command_size += size_bytes.size();
33512   hash->Update(offset_bytes.data(), offset_bytes.size());
33513   parameter_section_bytes += offset_bytes;
33514   command_size += offset_bytes.size();
33515   std::string command_hash(32, 0);
33516   hash->Finish(std::data(command_hash), command_hash.size());
33517   std::string authorization_section_bytes;
33518   std::string authorization_size_bytes;
33519   if (authorization_delegate) {
33520     if (!authorization_delegate->GetCommandAuthorization(
33521             command_hash, is_command_parameter_encryption_possible,
33522             is_response_parameter_encryption_possible,
33523             &authorization_section_bytes)) {
33524       return TRUNKS_RC_AUTHORIZATION_FAILED;
33525     }
33526     if (!authorization_section_bytes.empty()) {
33527       tag = TPM_ST_SESSIONS;
33528       std::string tmp;
33529       rc = Serialize_UINT32(authorization_section_bytes.size(),
33530                             &authorization_size_bytes);
33531       if (rc != TPM_RC_SUCCESS) {
33532         return rc;
33533       }
33534       command_size +=
33535           authorization_size_bytes.size() + authorization_section_bytes.size();
33536     }
33537   }
33538   std::string tag_bytes;
33539   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33540   if (rc != TPM_RC_SUCCESS) {
33541     return rc;
33542   }
33543   std::string command_size_bytes;
33544   rc = Serialize_UINT32(command_size, &command_size_bytes);
33545   if (rc != TPM_RC_SUCCESS) {
33546     return rc;
33547   }
33548   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33549                         handle_section_bytes + authorization_size_bytes +
33550                         authorization_section_bytes + parameter_section_bytes;
33551   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33552   VLOG(2) << "Command: "
33553           << base::HexEncode(serialized_command->data(),
33554                              serialized_command->size());
33555   return TPM_RC_SUCCESS;
33556 }
33557 
ParseResponse_NV_Certify(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)33558 TPM_RC Tpm::ParseResponse_NV_Certify(
33559     const std::string& response,
33560     TPM2B_ATTEST* certify_info,
33561     TPMT_SIGNATURE* signature,
33562     AuthorizationDelegate* authorization_delegate) {
33563   VLOG(3) << __func__;
33564   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33565   TPM_RC rc = TPM_RC_SUCCESS;
33566   std::string buffer(response);
33567   TPM_ST tag;
33568   std::string tag_bytes;
33569   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33570   if (rc != TPM_RC_SUCCESS) {
33571     return rc;
33572   }
33573   UINT32 response_size;
33574   std::string response_size_bytes;
33575   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33576   if (rc != TPM_RC_SUCCESS) {
33577     return rc;
33578   }
33579   TPM_RC response_code;
33580   std::string response_code_bytes;
33581   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33582   if (rc != TPM_RC_SUCCESS) {
33583     return rc;
33584   }
33585   if (response_size != response.size()) {
33586     return TPM_RC_SIZE;
33587   }
33588   if (response_code != TPM_RC_SUCCESS) {
33589     return response_code;
33590   }
33591   TPM_CC command_code = TPM_CC_NV_Certify;
33592   std::string command_code_bytes;
33593   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33594   if (rc != TPM_RC_SUCCESS) {
33595     return rc;
33596   }
33597   std::string authorization_section_bytes;
33598   if (tag == TPM_ST_SESSIONS) {
33599     UINT32 parameter_section_size = buffer.size();
33600     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
33601     if (rc != TPM_RC_SUCCESS) {
33602       return rc;
33603     }
33604     if (parameter_section_size > buffer.size()) {
33605       return TPM_RC_INSUFFICIENT;
33606     }
33607     authorization_section_bytes = buffer.substr(parameter_section_size);
33608     // Keep the parameter section in |buffer|.
33609     buffer.erase(parameter_section_size);
33610   }
33611   std::unique_ptr<crypto::SecureHash> hash(
33612       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33613   hash->Update(response_code_bytes.data(), response_code_bytes.size());
33614   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33615   hash->Update(buffer.data(), buffer.size());
33616   std::string response_hash(32, 0);
33617   hash->Finish(std::data(response_hash), response_hash.size());
33618   if (tag == TPM_ST_SESSIONS) {
33619     if (!authorization_delegate)
33620       return TRUNKS_RC_AUTHORIZATION_FAILED;
33621     if (!authorization_delegate->CheckResponseAuthorization(
33622             response_hash, authorization_section_bytes)) {
33623       return TRUNKS_RC_AUTHORIZATION_FAILED;
33624     }
33625   }
33626   if (tag == TPM_ST_SESSIONS) {
33627     if (!authorization_delegate)
33628       return TRUNKS_RC_AUTHORIZATION_FAILED;
33629 
33630     // Parse the encrypted parameter size.
33631     UINT16 size;
33632     std::string size_buffer = buffer.substr(0, 2);
33633     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
33634       return result;
33635     }
33636     if (buffer.size() < 2 + size) {
33637       return TPM_RC_INSUFFICIENT;
33638     }
33639 
33640     // Decrypt just the parameter data, not the size.
33641     std::string decrypted_data = buffer.substr(2, size);
33642     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
33643       return TRUNKS_RC_ENCRYPTION_FAILED;
33644     }
33645     buffer.replace(2, size, decrypted_data);
33646   }
33647   std::string certify_info_bytes;
33648   rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
33649   if (rc != TPM_RC_SUCCESS) {
33650     return rc;
33651   }
33652   std::string signature_bytes;
33653   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
33654   if (rc != TPM_RC_SUCCESS) {
33655     return rc;
33656   }
33657   return TPM_RC_SUCCESS;
33658 }
33659 
NV_CertifyErrorCallback(Tpm::NV_CertifyResponse callback,TPM_RC response_code)33660 void NV_CertifyErrorCallback(Tpm::NV_CertifyResponse callback,
33661                              TPM_RC response_code) {
33662   VLOG(1) << __func__;
33663   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
33664 }
33665 
NV_CertifyResponseParser(Tpm::NV_CertifyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33666 void NV_CertifyResponseParser(Tpm::NV_CertifyResponse callback,
33667                               AuthorizationDelegate* authorization_delegate,
33668                               const std::string& response) {
33669   VLOG(1) << __func__;
33670   TPM2B_ATTEST certify_info;
33671   TPMT_SIGNATURE signature;
33672   TPM_RC rc = Tpm::ParseResponse_NV_Certify(response, &certify_info, &signature,
33673                                             authorization_delegate);
33674   if (rc != TPM_RC_SUCCESS) {
33675     base::OnceCallback<void(TPM_RC)> error_reporter =
33676         base::BindOnce(NV_CertifyErrorCallback, std::move(callback));
33677     std::move(error_reporter).Run(rc);
33678     return;
33679   }
33680   std::move(callback).Run(rc, certify_info, signature);
33681 }
33682 
NV_Certify(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const UINT16 & size,const UINT16 & offset,AuthorizationDelegate * authorization_delegate,NV_CertifyResponse callback)33683 void Tpm::NV_Certify(const TPMI_DH_OBJECT& sign_handle,
33684                      const std::string& sign_handle_name,
33685                      const TPMI_RH_NV_AUTH& auth_handle,
33686                      const std::string& auth_handle_name,
33687                      const TPMI_RH_NV_INDEX& nv_index,
33688                      const std::string& nv_index_name,
33689                      const TPM2B_DATA& qualifying_data,
33690                      const TPMT_SIG_SCHEME& in_scheme,
33691                      const UINT16& size,
33692                      const UINT16& offset,
33693                      AuthorizationDelegate* authorization_delegate,
33694                      NV_CertifyResponse callback) {
33695   VLOG(1) << __func__;
33696   std::string command;
33697   TPM_RC rc = SerializeCommand_NV_Certify(
33698       sign_handle, sign_handle_name, auth_handle, auth_handle_name, nv_index,
33699       nv_index_name, qualifying_data, in_scheme, size, offset, &command,
33700       authorization_delegate);
33701   if (rc != TPM_RC_SUCCESS) {
33702     base::OnceCallback<void(TPM_RC)> error_reporter =
33703         base::BindOnce(NV_CertifyErrorCallback, std::move(callback));
33704     std::move(error_reporter).Run(rc);
33705     return;
33706   }
33707   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33708       NV_CertifyResponseParser, std::move(callback), authorization_delegate);
33709   transceiver_->SendCommand(command, std::move(parser));
33710 }
33711 
NV_CertifySync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const UINT16 & size,const UINT16 & offset,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)33712 TPM_RC Tpm::NV_CertifySync(const TPMI_DH_OBJECT& sign_handle,
33713                            const std::string& sign_handle_name,
33714                            const TPMI_RH_NV_AUTH& auth_handle,
33715                            const std::string& auth_handle_name,
33716                            const TPMI_RH_NV_INDEX& nv_index,
33717                            const std::string& nv_index_name,
33718                            const TPM2B_DATA& qualifying_data,
33719                            const TPMT_SIG_SCHEME& in_scheme,
33720                            const UINT16& size,
33721                            const UINT16& offset,
33722                            TPM2B_ATTEST* certify_info,
33723                            TPMT_SIGNATURE* signature,
33724                            AuthorizationDelegate* authorization_delegate) {
33725   VLOG(1) << __func__;
33726   std::string command;
33727   TPM_RC rc = SerializeCommand_NV_Certify(
33728       sign_handle, sign_handle_name, auth_handle, auth_handle_name, nv_index,
33729       nv_index_name, qualifying_data, in_scheme, size, offset, &command,
33730       authorization_delegate);
33731   if (rc != TPM_RC_SUCCESS) {
33732     return rc;
33733   }
33734   std::string response = transceiver_->SendCommandAndWait(command);
33735   rc = ParseResponse_NV_Certify(response, certify_info, signature,
33736                                 authorization_delegate);
33737   return rc;
33738 }
33739 
33740 }  // namespace trunks
33741