• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // THIS CODE IS GENERATED - DO NOT MODIFY!
6 
7 #include "tpm_generated.h"
8 
9 #include <iterator>
10 #include <memory>
11 #include <string>
12 
13 #include <android-base/endian.h>
14 #include <android-base/logging.h>
15 #include <secure_hash.h>
16 
17 #include "authorization_delegate.h"
18 #include "callback.h"
19 #include "command_transceiver.h"
20 #include "error_codes.h"
21 
22 // Redirect VLOG invocations written for libchrome to android-base's LOG macro.
23 // The severities are not compatible with each other (e.g. libchrome's INFO is 0
24 // but android-base's is 2), so we drop the severity information. This code can
25 // generate tons of output so we map everything to VERBOSE so it can easily be
26 // filtered out.
27 #define VLOG(x) LOG(VERBOSE)
28 
29 namespace trunks {
30 
GetNumberOfRequestHandles(TPM_CC command_code)31 size_t GetNumberOfRequestHandles(TPM_CC command_code) {
32   switch (command_code) {
33     case TPM_CC_Startup:
34       return 0;
35     case TPM_CC_Shutdown:
36       return 0;
37     case TPM_CC_SelfTest:
38       return 0;
39     case TPM_CC_IncrementalSelfTest:
40       return 0;
41     case TPM_CC_GetTestResult:
42       return 0;
43     case TPM_CC_StartAuthSession:
44       return 2;
45     case TPM_CC_PolicyRestart:
46       return 1;
47     case TPM_CC_Create:
48       return 1;
49     case TPM_CC_Load:
50       return 1;
51     case TPM_CC_LoadExternal:
52       return 0;
53     case TPM_CC_ReadPublic:
54       return 1;
55     case TPM_CC_ActivateCredential:
56       return 2;
57     case TPM_CC_MakeCredential:
58       return 1;
59     case TPM_CC_Unseal:
60       return 1;
61     case TPM_CC_ObjectChangeAuth:
62       return 2;
63     case TPM_CC_Duplicate:
64       return 2;
65     case TPM_CC_Rewrap:
66       return 2;
67     case TPM_CC_Import:
68       return 1;
69     case TPM_CC_RSA_Encrypt:
70       return 1;
71     case TPM_CC_RSA_Decrypt:
72       return 1;
73     case TPM_CC_ECDH_KeyGen:
74       return 1;
75     case TPM_CC_ECDH_ZGen:
76       return 1;
77     case TPM_CC_ECC_Parameters:
78       return 0;
79     case TPM_CC_ZGen_2Phase:
80       return 1;
81     case TPM_CC_EncryptDecrypt:
82       return 1;
83     case TPM_CC_Hash:
84       return 0;
85     case TPM_CC_HMAC:
86       return 1;
87     case TPM_CC_GetRandom:
88       return 0;
89     case TPM_CC_StirRandom:
90       return 0;
91     case TPM_CC_HMAC_Start:
92       return 1;
93     case TPM_CC_HashSequenceStart:
94       return 0;
95     case TPM_CC_SequenceUpdate:
96       return 1;
97     case TPM_CC_SequenceComplete:
98       return 1;
99     case TPM_CC_EventSequenceComplete:
100       return 2;
101     case TPM_CC_Certify:
102       return 2;
103     case TPM_CC_CertifyCreation:
104       return 2;
105     case TPM_CC_Quote:
106       return 1;
107     case TPM_CC_GetSessionAuditDigest:
108       return 3;
109     case TPM_CC_GetCommandAuditDigest:
110       return 2;
111     case TPM_CC_GetTime:
112       return 2;
113     case TPM_CC_Commit:
114       return 1;
115     case TPM_CC_EC_Ephemeral:
116       return 0;
117     case TPM_CC_VerifySignature:
118       return 1;
119     case TPM_CC_Sign:
120       return 1;
121     case TPM_CC_SetCommandCodeAuditStatus:
122       return 1;
123     case TPM_CC_PCR_Extend:
124       return 1;
125     case TPM_CC_PCR_Event:
126       return 1;
127     case TPM_CC_PCR_Read:
128       return 0;
129     case TPM_CC_PCR_Allocate:
130       return 1;
131     case TPM_CC_PCR_SetAuthPolicy:
132       return 2;
133     case TPM_CC_PCR_SetAuthValue:
134       return 1;
135     case TPM_CC_PCR_Reset:
136       return 1;
137     case TPM_CC_PolicySigned:
138       return 2;
139     case TPM_CC_PolicySecret:
140       return 2;
141     case TPM_CC_PolicyTicket:
142       return 1;
143     case TPM_CC_PolicyOR:
144       return 1;
145     case TPM_CC_PolicyPCR:
146       return 1;
147     case TPM_CC_PolicyLocality:
148       return 1;
149     case TPM_CC_PolicyNV:
150       return 3;
151     case TPM_CC_PolicyCounterTimer:
152       return 1;
153     case TPM_CC_PolicyCommandCode:
154       return 1;
155     case TPM_CC_PolicyPhysicalPresence:
156       return 1;
157     case TPM_CC_PolicyCpHash:
158       return 1;
159     case TPM_CC_PolicyNameHash:
160       return 1;
161     case TPM_CC_PolicyDuplicationSelect:
162       return 1;
163     case TPM_CC_PolicyAuthorize:
164       return 1;
165     case TPM_CC_PolicyAuthValue:
166       return 1;
167     case TPM_CC_PolicyPassword:
168       return 1;
169     case TPM_CC_PolicyGetDigest:
170       return 1;
171     case TPM_CC_PolicyNvWritten:
172       return 1;
173     case TPM_CC_CreatePrimary:
174       return 1;
175     case TPM_CC_HierarchyControl:
176       return 1;
177     case TPM_CC_SetPrimaryPolicy:
178       return 1;
179     case TPM_CC_ChangePPS:
180       return 1;
181     case TPM_CC_ChangeEPS:
182       return 1;
183     case TPM_CC_Clear:
184       return 1;
185     case TPM_CC_ClearControl:
186       return 1;
187     case TPM_CC_HierarchyChangeAuth:
188       return 1;
189     case TPM_CC_DictionaryAttackLockReset:
190       return 1;
191     case TPM_CC_DictionaryAttackParameters:
192       return 1;
193     case TPM_CC_PP_Commands:
194       return 1;
195     case TPM_CC_SetAlgorithmSet:
196       return 1;
197     case TPM_CC_FieldUpgradeStart:
198       return 2;
199     case TPM_CC_FieldUpgradeData:
200       return 0;
201     case TPM_CC_FirmwareRead:
202       return 0;
203     case TPM_CC_ContextSave:
204       return 1;
205     case TPM_CC_ContextLoad:
206       return 0;
207     case TPM_CC_FlushContext:
208       return 0;
209     case TPM_CC_EvictControl:
210       return 2;
211     case TPM_CC_ReadClock:
212       return 0;
213     case TPM_CC_ClockSet:
214       return 1;
215     case TPM_CC_ClockRateAdjust:
216       return 1;
217     case TPM_CC_GetCapability:
218       return 0;
219     case TPM_CC_TestParms:
220       return 0;
221     case TPM_CC_NV_DefineSpace:
222       return 1;
223     case TPM_CC_NV_UndefineSpace:
224       return 2;
225     case TPM_CC_NV_UndefineSpaceSpecial:
226       return 2;
227     case TPM_CC_NV_ReadPublic:
228       return 1;
229     case TPM_CC_NV_Write:
230       return 2;
231     case TPM_CC_NV_Increment:
232       return 2;
233     case TPM_CC_NV_Extend:
234       return 2;
235     case TPM_CC_NV_SetBits:
236       return 2;
237     case TPM_CC_NV_WriteLock:
238       return 2;
239     case TPM_CC_NV_GlobalWriteLock:
240       return 1;
241     case TPM_CC_NV_Read:
242       return 2;
243     case TPM_CC_NV_ReadLock:
244       return 2;
245     case TPM_CC_NV_ChangeAuth:
246       return 1;
247     case TPM_CC_NV_Certify:
248       return 3;
249     case TPM_CCE_PolicyFidoSigned:
250       return 2;
251     default:
252       LOG(WARNING) << "Unknown command code: " << command_code;
253   }
254   return 0;
255 }
256 
GetNumberOfResponseHandles(TPM_CC command_code)257 size_t GetNumberOfResponseHandles(TPM_CC command_code) {
258   switch (command_code) {
259     case TPM_CC_Startup:
260       return 0;
261     case TPM_CC_Shutdown:
262       return 0;
263     case TPM_CC_SelfTest:
264       return 0;
265     case TPM_CC_IncrementalSelfTest:
266       return 0;
267     case TPM_CC_GetTestResult:
268       return 0;
269     case TPM_CC_StartAuthSession:
270       return 1;
271     case TPM_CC_PolicyRestart:
272       return 0;
273     case TPM_CC_Create:
274       return 0;
275     case TPM_CC_Load:
276       return 1;
277     case TPM_CC_LoadExternal:
278       return 1;
279     case TPM_CC_ReadPublic:
280       return 0;
281     case TPM_CC_ActivateCredential:
282       return 0;
283     case TPM_CC_MakeCredential:
284       return 0;
285     case TPM_CC_Unseal:
286       return 0;
287     case TPM_CC_ObjectChangeAuth:
288       return 0;
289     case TPM_CC_Duplicate:
290       return 0;
291     case TPM_CC_Rewrap:
292       return 0;
293     case TPM_CC_Import:
294       return 0;
295     case TPM_CC_RSA_Encrypt:
296       return 0;
297     case TPM_CC_RSA_Decrypt:
298       return 0;
299     case TPM_CC_ECDH_KeyGen:
300       return 0;
301     case TPM_CC_ECDH_ZGen:
302       return 0;
303     case TPM_CC_ECC_Parameters:
304       return 0;
305     case TPM_CC_ZGen_2Phase:
306       return 0;
307     case TPM_CC_EncryptDecrypt:
308       return 0;
309     case TPM_CC_Hash:
310       return 0;
311     case TPM_CC_HMAC:
312       return 0;
313     case TPM_CC_GetRandom:
314       return 0;
315     case TPM_CC_StirRandom:
316       return 0;
317     case TPM_CC_HMAC_Start:
318       return 1;
319     case TPM_CC_HashSequenceStart:
320       return 1;
321     case TPM_CC_SequenceUpdate:
322       return 0;
323     case TPM_CC_SequenceComplete:
324       return 0;
325     case TPM_CC_EventSequenceComplete:
326       return 0;
327     case TPM_CC_Certify:
328       return 0;
329     case TPM_CC_CertifyCreation:
330       return 0;
331     case TPM_CC_Quote:
332       return 0;
333     case TPM_CC_GetSessionAuditDigest:
334       return 0;
335     case TPM_CC_GetCommandAuditDigest:
336       return 0;
337     case TPM_CC_GetTime:
338       return 0;
339     case TPM_CC_Commit:
340       return 0;
341     case TPM_CC_EC_Ephemeral:
342       return 0;
343     case TPM_CC_VerifySignature:
344       return 0;
345     case TPM_CC_Sign:
346       return 0;
347     case TPM_CC_SetCommandCodeAuditStatus:
348       return 0;
349     case TPM_CC_PCR_Extend:
350       return 0;
351     case TPM_CC_PCR_Event:
352       return 0;
353     case TPM_CC_PCR_Read:
354       return 0;
355     case TPM_CC_PCR_Allocate:
356       return 0;
357     case TPM_CC_PCR_SetAuthPolicy:
358       return 0;
359     case TPM_CC_PCR_SetAuthValue:
360       return 0;
361     case TPM_CC_PCR_Reset:
362       return 0;
363     case TPM_CC_PolicySigned:
364       return 0;
365     case TPM_CC_PolicySecret:
366       return 0;
367     case TPM_CC_PolicyTicket:
368       return 0;
369     case TPM_CC_PolicyOR:
370       return 0;
371     case TPM_CC_PolicyPCR:
372       return 0;
373     case TPM_CC_PolicyLocality:
374       return 0;
375     case TPM_CC_PolicyNV:
376       return 0;
377     case TPM_CC_PolicyCounterTimer:
378       return 0;
379     case TPM_CC_PolicyCommandCode:
380       return 0;
381     case TPM_CC_PolicyPhysicalPresence:
382       return 0;
383     case TPM_CC_PolicyCpHash:
384       return 0;
385     case TPM_CC_PolicyNameHash:
386       return 0;
387     case TPM_CC_PolicyDuplicationSelect:
388       return 0;
389     case TPM_CC_PolicyAuthorize:
390       return 0;
391     case TPM_CC_PolicyAuthValue:
392       return 0;
393     case TPM_CC_PolicyPassword:
394       return 0;
395     case TPM_CC_PolicyGetDigest:
396       return 0;
397     case TPM_CC_PolicyNvWritten:
398       return 0;
399     case TPM_CC_CreatePrimary:
400       return 1;
401     case TPM_CC_HierarchyControl:
402       return 0;
403     case TPM_CC_SetPrimaryPolicy:
404       return 0;
405     case TPM_CC_ChangePPS:
406       return 0;
407     case TPM_CC_ChangeEPS:
408       return 0;
409     case TPM_CC_Clear:
410       return 0;
411     case TPM_CC_ClearControl:
412       return 0;
413     case TPM_CC_HierarchyChangeAuth:
414       return 0;
415     case TPM_CC_DictionaryAttackLockReset:
416       return 0;
417     case TPM_CC_DictionaryAttackParameters:
418       return 0;
419     case TPM_CC_PP_Commands:
420       return 0;
421     case TPM_CC_SetAlgorithmSet:
422       return 0;
423     case TPM_CC_FieldUpgradeStart:
424       return 0;
425     case TPM_CC_FieldUpgradeData:
426       return 0;
427     case TPM_CC_FirmwareRead:
428       return 0;
429     case TPM_CC_ContextSave:
430       return 0;
431     case TPM_CC_ContextLoad:
432       return 1;
433     case TPM_CC_FlushContext:
434       return 0;
435     case TPM_CC_EvictControl:
436       return 0;
437     case TPM_CC_ReadClock:
438       return 0;
439     case TPM_CC_ClockSet:
440       return 0;
441     case TPM_CC_ClockRateAdjust:
442       return 0;
443     case TPM_CC_GetCapability:
444       return 0;
445     case TPM_CC_TestParms:
446       return 0;
447     case TPM_CC_NV_DefineSpace:
448       return 0;
449     case TPM_CC_NV_UndefineSpace:
450       return 0;
451     case TPM_CC_NV_UndefineSpaceSpecial:
452       return 0;
453     case TPM_CC_NV_ReadPublic:
454       return 0;
455     case TPM_CC_NV_Write:
456       return 0;
457     case TPM_CC_NV_Increment:
458       return 0;
459     case TPM_CC_NV_Extend:
460       return 0;
461     case TPM_CC_NV_SetBits:
462       return 0;
463     case TPM_CC_NV_WriteLock:
464       return 0;
465     case TPM_CC_NV_GlobalWriteLock:
466       return 0;
467     case TPM_CC_NV_Read:
468       return 0;
469     case TPM_CC_NV_ReadLock:
470       return 0;
471     case TPM_CC_NV_ChangeAuth:
472       return 0;
473     case TPM_CC_NV_Certify:
474       return 0;
475     case TPM_CCE_PolicyFidoSigned:
476       return 0;
477     default:
478       LOG(WARNING) << "Unknown command code: " << command_code;
479   }
480   return 0;
481 }
482 
Serialize_uint8_t(const uint8_t & value,std::string * buffer)483 TPM_RC Serialize_uint8_t(const uint8_t& value, std::string* buffer) {
484   VLOG(3) << __func__;
485   uint8_t value_net = value;
486   switch (sizeof(uint8_t)) {
487     case 2:
488       value_net = htons(value);
489       break;
490     case 4:
491       value_net = htonl(value);
492       break;
493     case 8:
494       value_net = htonq(value);
495       break;
496     default:
497       break;
498   }
499   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
500   buffer->append(value_bytes, sizeof(uint8_t));
501   return TPM_RC_SUCCESS;
502 }
503 
Parse_uint8_t(std::string * buffer,uint8_t * value,std::string * value_bytes)504 TPM_RC Parse_uint8_t(std::string* buffer,
505                      uint8_t* value,
506                      std::string* value_bytes) {
507   VLOG(3) << __func__;
508   if (buffer->size() < sizeof(uint8_t))
509     return TPM_RC_INSUFFICIENT;
510   uint8_t value_net = 0;
511   memcpy(&value_net, buffer->data(), sizeof(uint8_t));
512   switch (sizeof(uint8_t)) {
513     case 2:
514       *value = ntohs(value_net);
515       break;
516     case 4:
517       *value = ntohl(value_net);
518       break;
519     case 8:
520       *value = ntohq(value_net);
521       break;
522     default:
523       *value = value_net;
524   }
525   if (value_bytes) {
526     value_bytes->append(buffer->substr(0, sizeof(uint8_t)));
527   }
528   buffer->erase(0, sizeof(uint8_t));
529   return TPM_RC_SUCCESS;
530 }
531 
Serialize_int8_t(const int8_t & value,std::string * buffer)532 TPM_RC Serialize_int8_t(const int8_t& value, std::string* buffer) {
533   VLOG(3) << __func__;
534   int8_t value_net = value;
535   switch (sizeof(int8_t)) {
536     case 2:
537       value_net = htons(value);
538       break;
539     case 4:
540       value_net = htonl(value);
541       break;
542     case 8:
543       value_net = htonq(value);
544       break;
545     default:
546       break;
547   }
548   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
549   buffer->append(value_bytes, sizeof(int8_t));
550   return TPM_RC_SUCCESS;
551 }
552 
Parse_int8_t(std::string * buffer,int8_t * value,std::string * value_bytes)553 TPM_RC Parse_int8_t(std::string* buffer,
554                     int8_t* value,
555                     std::string* value_bytes) {
556   VLOG(3) << __func__;
557   if (buffer->size() < sizeof(int8_t))
558     return TPM_RC_INSUFFICIENT;
559   int8_t value_net = 0;
560   memcpy(&value_net, buffer->data(), sizeof(int8_t));
561   switch (sizeof(int8_t)) {
562     case 2:
563       *value = ntohs(value_net);
564       break;
565     case 4:
566       *value = ntohl(value_net);
567       break;
568     case 8:
569       *value = ntohq(value_net);
570       break;
571     default:
572       *value = value_net;
573   }
574   if (value_bytes) {
575     value_bytes->append(buffer->substr(0, sizeof(int8_t)));
576   }
577   buffer->erase(0, sizeof(int8_t));
578   return TPM_RC_SUCCESS;
579 }
580 
Serialize_int(const int & value,std::string * buffer)581 TPM_RC Serialize_int(const int& value, std::string* buffer) {
582   VLOG(3) << __func__;
583   int value_net = value;
584   switch (sizeof(int)) {
585     case 2:
586       value_net = htons(value);
587       break;
588     case 4:
589       value_net = htonl(value);
590       break;
591     case 8:
592       value_net = htonq(value);
593       break;
594     default:
595       break;
596   }
597   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
598   buffer->append(value_bytes, sizeof(int));
599   return TPM_RC_SUCCESS;
600 }
601 
Parse_int(std::string * buffer,int * value,std::string * value_bytes)602 TPM_RC Parse_int(std::string* buffer, int* value, std::string* value_bytes) {
603   VLOG(3) << __func__;
604   if (buffer->size() < sizeof(int))
605     return TPM_RC_INSUFFICIENT;
606   int value_net = 0;
607   memcpy(&value_net, buffer->data(), sizeof(int));
608   switch (sizeof(int)) {
609     case 2:
610       *value = ntohs(value_net);
611       break;
612     case 4:
613       *value = ntohl(value_net);
614       break;
615     case 8:
616       *value = ntohq(value_net);
617       break;
618     default:
619       *value = value_net;
620   }
621   if (value_bytes) {
622     value_bytes->append(buffer->substr(0, sizeof(int)));
623   }
624   buffer->erase(0, sizeof(int));
625   return TPM_RC_SUCCESS;
626 }
627 
Serialize_uint16_t(const uint16_t & value,std::string * buffer)628 TPM_RC Serialize_uint16_t(const uint16_t& value, std::string* buffer) {
629   VLOG(3) << __func__;
630   uint16_t value_net = value;
631   switch (sizeof(uint16_t)) {
632     case 2:
633       value_net = htons(value);
634       break;
635     case 4:
636       value_net = htonl(value);
637       break;
638     case 8:
639       value_net = htonq(value);
640       break;
641     default:
642       break;
643   }
644   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
645   buffer->append(value_bytes, sizeof(uint16_t));
646   return TPM_RC_SUCCESS;
647 }
648 
Parse_uint16_t(std::string * buffer,uint16_t * value,std::string * value_bytes)649 TPM_RC Parse_uint16_t(std::string* buffer,
650                       uint16_t* value,
651                       std::string* value_bytes) {
652   VLOG(3) << __func__;
653   if (buffer->size() < sizeof(uint16_t))
654     return TPM_RC_INSUFFICIENT;
655   uint16_t value_net = 0;
656   memcpy(&value_net, buffer->data(), sizeof(uint16_t));
657   switch (sizeof(uint16_t)) {
658     case 2:
659       *value = ntohs(value_net);
660       break;
661     case 4:
662       *value = ntohl(value_net);
663       break;
664     case 8:
665       *value = ntohq(value_net);
666       break;
667     default:
668       *value = value_net;
669   }
670   if (value_bytes) {
671     value_bytes->append(buffer->substr(0, sizeof(uint16_t)));
672   }
673   buffer->erase(0, sizeof(uint16_t));
674   return TPM_RC_SUCCESS;
675 }
676 
Serialize_int16_t(const int16_t & value,std::string * buffer)677 TPM_RC Serialize_int16_t(const int16_t& value, std::string* buffer) {
678   VLOG(3) << __func__;
679   int16_t value_net = value;
680   switch (sizeof(int16_t)) {
681     case 2:
682       value_net = htons(value);
683       break;
684     case 4:
685       value_net = htonl(value);
686       break;
687     case 8:
688       value_net = htonq(value);
689       break;
690     default:
691       break;
692   }
693   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
694   buffer->append(value_bytes, sizeof(int16_t));
695   return TPM_RC_SUCCESS;
696 }
697 
Parse_int16_t(std::string * buffer,int16_t * value,std::string * value_bytes)698 TPM_RC Parse_int16_t(std::string* buffer,
699                      int16_t* value,
700                      std::string* value_bytes) {
701   VLOG(3) << __func__;
702   if (buffer->size() < sizeof(int16_t))
703     return TPM_RC_INSUFFICIENT;
704   int16_t value_net = 0;
705   memcpy(&value_net, buffer->data(), sizeof(int16_t));
706   switch (sizeof(int16_t)) {
707     case 2:
708       *value = ntohs(value_net);
709       break;
710     case 4:
711       *value = ntohl(value_net);
712       break;
713     case 8:
714       *value = ntohq(value_net);
715       break;
716     default:
717       *value = value_net;
718   }
719   if (value_bytes) {
720     value_bytes->append(buffer->substr(0, sizeof(int16_t)));
721   }
722   buffer->erase(0, sizeof(int16_t));
723   return TPM_RC_SUCCESS;
724 }
725 
Serialize_uint32_t(const uint32_t & value,std::string * buffer)726 TPM_RC Serialize_uint32_t(const uint32_t& value, std::string* buffer) {
727   VLOG(3) << __func__;
728   uint32_t value_net = value;
729   switch (sizeof(uint32_t)) {
730     case 2:
731       value_net = htons(value);
732       break;
733     case 4:
734       value_net = htonl(value);
735       break;
736     case 8:
737       value_net = htonq(value);
738       break;
739     default:
740       break;
741   }
742   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
743   buffer->append(value_bytes, sizeof(uint32_t));
744   return TPM_RC_SUCCESS;
745 }
746 
Parse_uint32_t(std::string * buffer,uint32_t * value,std::string * value_bytes)747 TPM_RC Parse_uint32_t(std::string* buffer,
748                       uint32_t* value,
749                       std::string* value_bytes) {
750   VLOG(3) << __func__;
751   if (buffer->size() < sizeof(uint32_t))
752     return TPM_RC_INSUFFICIENT;
753   uint32_t value_net = 0;
754   memcpy(&value_net, buffer->data(), sizeof(uint32_t));
755   switch (sizeof(uint32_t)) {
756     case 2:
757       *value = ntohs(value_net);
758       break;
759     case 4:
760       *value = ntohl(value_net);
761       break;
762     case 8:
763       *value = ntohq(value_net);
764       break;
765     default:
766       *value = value_net;
767   }
768   if (value_bytes) {
769     value_bytes->append(buffer->substr(0, sizeof(uint32_t)));
770   }
771   buffer->erase(0, sizeof(uint32_t));
772   return TPM_RC_SUCCESS;
773 }
774 
Serialize_int32_t(const int32_t & value,std::string * buffer)775 TPM_RC Serialize_int32_t(const int32_t& value, std::string* buffer) {
776   VLOG(3) << __func__;
777   int32_t value_net = value;
778   switch (sizeof(int32_t)) {
779     case 2:
780       value_net = htons(value);
781       break;
782     case 4:
783       value_net = htonl(value);
784       break;
785     case 8:
786       value_net = htonq(value);
787       break;
788     default:
789       break;
790   }
791   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
792   buffer->append(value_bytes, sizeof(int32_t));
793   return TPM_RC_SUCCESS;
794 }
795 
Parse_int32_t(std::string * buffer,int32_t * value,std::string * value_bytes)796 TPM_RC Parse_int32_t(std::string* buffer,
797                      int32_t* value,
798                      std::string* value_bytes) {
799   VLOG(3) << __func__;
800   if (buffer->size() < sizeof(int32_t))
801     return TPM_RC_INSUFFICIENT;
802   int32_t value_net = 0;
803   memcpy(&value_net, buffer->data(), sizeof(int32_t));
804   switch (sizeof(int32_t)) {
805     case 2:
806       *value = ntohs(value_net);
807       break;
808     case 4:
809       *value = ntohl(value_net);
810       break;
811     case 8:
812       *value = ntohq(value_net);
813       break;
814     default:
815       *value = value_net;
816   }
817   if (value_bytes) {
818     value_bytes->append(buffer->substr(0, sizeof(int32_t)));
819   }
820   buffer->erase(0, sizeof(int32_t));
821   return TPM_RC_SUCCESS;
822 }
823 
Serialize_uint64_t(const uint64_t & value,std::string * buffer)824 TPM_RC Serialize_uint64_t(const uint64_t& value, std::string* buffer) {
825   VLOG(3) << __func__;
826   uint64_t value_net = value;
827   switch (sizeof(uint64_t)) {
828     case 2:
829       value_net = htons(value);
830       break;
831     case 4:
832       value_net = htonl(value);
833       break;
834     case 8:
835       value_net = htonq(value);
836       break;
837     default:
838       break;
839   }
840   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
841   buffer->append(value_bytes, sizeof(uint64_t));
842   return TPM_RC_SUCCESS;
843 }
844 
Parse_uint64_t(std::string * buffer,uint64_t * value,std::string * value_bytes)845 TPM_RC Parse_uint64_t(std::string* buffer,
846                       uint64_t* value,
847                       std::string* value_bytes) {
848   VLOG(3) << __func__;
849   if (buffer->size() < sizeof(uint64_t))
850     return TPM_RC_INSUFFICIENT;
851   uint64_t value_net = 0;
852   memcpy(&value_net, buffer->data(), sizeof(uint64_t));
853   switch (sizeof(uint64_t)) {
854     case 2:
855       *value = ntohs(value_net);
856       break;
857     case 4:
858       *value = ntohl(value_net);
859       break;
860     case 8:
861       *value = ntohq(value_net);
862       break;
863     default:
864       *value = value_net;
865   }
866   if (value_bytes) {
867     value_bytes->append(buffer->substr(0, sizeof(uint64_t)));
868   }
869   buffer->erase(0, sizeof(uint64_t));
870   return TPM_RC_SUCCESS;
871 }
872 
Serialize_int64_t(const int64_t & value,std::string * buffer)873 TPM_RC Serialize_int64_t(const int64_t& value, std::string* buffer) {
874   VLOG(3) << __func__;
875   int64_t value_net = value;
876   switch (sizeof(int64_t)) {
877     case 2:
878       value_net = htons(value);
879       break;
880     case 4:
881       value_net = htonl(value);
882       break;
883     case 8:
884       value_net = htonq(value);
885       break;
886     default:
887       break;
888   }
889   const char* value_bytes = reinterpret_cast<const char*>(&value_net);
890   buffer->append(value_bytes, sizeof(int64_t));
891   return TPM_RC_SUCCESS;
892 }
893 
Parse_int64_t(std::string * buffer,int64_t * value,std::string * value_bytes)894 TPM_RC Parse_int64_t(std::string* buffer,
895                      int64_t* value,
896                      std::string* value_bytes) {
897   VLOG(3) << __func__;
898   if (buffer->size() < sizeof(int64_t))
899     return TPM_RC_INSUFFICIENT;
900   int64_t value_net = 0;
901   memcpy(&value_net, buffer->data(), sizeof(int64_t));
902   switch (sizeof(int64_t)) {
903     case 2:
904       *value = ntohs(value_net);
905       break;
906     case 4:
907       *value = ntohl(value_net);
908       break;
909     case 8:
910       *value = ntohq(value_net);
911       break;
912     default:
913       *value = value_net;
914   }
915   if (value_bytes) {
916     value_bytes->append(buffer->substr(0, sizeof(int64_t)));
917   }
918   buffer->erase(0, sizeof(int64_t));
919   return TPM_RC_SUCCESS;
920 }
921 
Serialize_UINT8(const UINT8 & value,std::string * buffer)922 TPM_RC Serialize_UINT8(const UINT8& value, std::string* buffer) {
923   VLOG(3) << __func__;
924   return Serialize_uint8_t(value, buffer);
925 }
926 
Parse_UINT8(std::string * buffer,UINT8 * value,std::string * value_bytes)927 TPM_RC Parse_UINT8(std::string* buffer,
928                    UINT8* value,
929                    std::string* value_bytes) {
930   VLOG(3) << __func__;
931   return Parse_uint8_t(buffer, value, value_bytes);
932 }
933 
Serialize_BYTE(const BYTE & value,std::string * buffer)934 TPM_RC Serialize_BYTE(const BYTE& value, std::string* buffer) {
935   VLOG(3) << __func__;
936   return Serialize_uint8_t(value, buffer);
937 }
938 
Parse_BYTE(std::string * buffer,BYTE * value,std::string * value_bytes)939 TPM_RC Parse_BYTE(std::string* buffer, BYTE* value, std::string* value_bytes) {
940   VLOG(3) << __func__;
941   return Parse_uint8_t(buffer, value, value_bytes);
942 }
943 
Serialize_INT8(const INT8 & value,std::string * buffer)944 TPM_RC Serialize_INT8(const INT8& value, std::string* buffer) {
945   VLOG(3) << __func__;
946   return Serialize_int8_t(value, buffer);
947 }
948 
Parse_INT8(std::string * buffer,INT8 * value,std::string * value_bytes)949 TPM_RC Parse_INT8(std::string* buffer, INT8* value, std::string* value_bytes) {
950   VLOG(3) << __func__;
951   return Parse_int8_t(buffer, value, value_bytes);
952 }
953 
Serialize_BOOL(const BOOL & value,std::string * buffer)954 TPM_RC Serialize_BOOL(const BOOL& value, std::string* buffer) {
955   VLOG(3) << __func__;
956   return Serialize_int(value, buffer);
957 }
958 
Parse_BOOL(std::string * buffer,BOOL * value,std::string * value_bytes)959 TPM_RC Parse_BOOL(std::string* buffer, BOOL* value, std::string* value_bytes) {
960   VLOG(3) << __func__;
961   return Parse_int(buffer, value, value_bytes);
962 }
963 
Serialize_UINT16(const UINT16 & value,std::string * buffer)964 TPM_RC Serialize_UINT16(const UINT16& value, std::string* buffer) {
965   VLOG(3) << __func__;
966   return Serialize_uint16_t(value, buffer);
967 }
968 
Parse_UINT16(std::string * buffer,UINT16 * value,std::string * value_bytes)969 TPM_RC Parse_UINT16(std::string* buffer,
970                     UINT16* value,
971                     std::string* value_bytes) {
972   VLOG(3) << __func__;
973   return Parse_uint16_t(buffer, value, value_bytes);
974 }
975 
Serialize_INT16(const INT16 & value,std::string * buffer)976 TPM_RC Serialize_INT16(const INT16& value, std::string* buffer) {
977   VLOG(3) << __func__;
978   return Serialize_int16_t(value, buffer);
979 }
980 
Parse_INT16(std::string * buffer,INT16 * value,std::string * value_bytes)981 TPM_RC Parse_INT16(std::string* buffer,
982                    INT16* value,
983                    std::string* value_bytes) {
984   VLOG(3) << __func__;
985   return Parse_int16_t(buffer, value, value_bytes);
986 }
987 
Serialize_UINT32(const UINT32 & value,std::string * buffer)988 TPM_RC Serialize_UINT32(const UINT32& value, std::string* buffer) {
989   VLOG(3) << __func__;
990   return Serialize_uint32_t(value, buffer);
991 }
992 
Parse_UINT32(std::string * buffer,UINT32 * value,std::string * value_bytes)993 TPM_RC Parse_UINT32(std::string* buffer,
994                     UINT32* value,
995                     std::string* value_bytes) {
996   VLOG(3) << __func__;
997   return Parse_uint32_t(buffer, value, value_bytes);
998 }
999 
Serialize_INT32(const INT32 & value,std::string * buffer)1000 TPM_RC Serialize_INT32(const INT32& value, std::string* buffer) {
1001   VLOG(3) << __func__;
1002   return Serialize_int32_t(value, buffer);
1003 }
1004 
Parse_INT32(std::string * buffer,INT32 * value,std::string * value_bytes)1005 TPM_RC Parse_INT32(std::string* buffer,
1006                    INT32* value,
1007                    std::string* value_bytes) {
1008   VLOG(3) << __func__;
1009   return Parse_int32_t(buffer, value, value_bytes);
1010 }
1011 
Serialize_UINT64(const UINT64 & value,std::string * buffer)1012 TPM_RC Serialize_UINT64(const UINT64& value, std::string* buffer) {
1013   VLOG(3) << __func__;
1014   return Serialize_uint64_t(value, buffer);
1015 }
1016 
Parse_UINT64(std::string * buffer,UINT64 * value,std::string * value_bytes)1017 TPM_RC Parse_UINT64(std::string* buffer,
1018                     UINT64* value,
1019                     std::string* value_bytes) {
1020   VLOG(3) << __func__;
1021   return Parse_uint64_t(buffer, value, value_bytes);
1022 }
1023 
Serialize_INT64(const INT64 & value,std::string * buffer)1024 TPM_RC Serialize_INT64(const INT64& value, std::string* buffer) {
1025   VLOG(3) << __func__;
1026   return Serialize_int64_t(value, buffer);
1027 }
1028 
Parse_INT64(std::string * buffer,INT64 * value,std::string * value_bytes)1029 TPM_RC Parse_INT64(std::string* buffer,
1030                    INT64* value,
1031                    std::string* value_bytes) {
1032   VLOG(3) << __func__;
1033   return Parse_int64_t(buffer, value, value_bytes);
1034 }
1035 
Serialize_TPM_ALGORITHM_ID(const TPM_ALGORITHM_ID & value,std::string * buffer)1036 TPM_RC Serialize_TPM_ALGORITHM_ID(const TPM_ALGORITHM_ID& value,
1037                                   std::string* buffer) {
1038   VLOG(3) << __func__;
1039   return Serialize_UINT32(value, buffer);
1040 }
1041 
Parse_TPM_ALGORITHM_ID(std::string * buffer,TPM_ALGORITHM_ID * value,std::string * value_bytes)1042 TPM_RC Parse_TPM_ALGORITHM_ID(std::string* buffer,
1043                               TPM_ALGORITHM_ID* value,
1044                               std::string* value_bytes) {
1045   VLOG(3) << __func__;
1046   return Parse_UINT32(buffer, value, value_bytes);
1047 }
1048 
Serialize_TPM_MODIFIER_INDICATOR(const TPM_MODIFIER_INDICATOR & value,std::string * buffer)1049 TPM_RC Serialize_TPM_MODIFIER_INDICATOR(const TPM_MODIFIER_INDICATOR& value,
1050                                         std::string* buffer) {
1051   VLOG(3) << __func__;
1052   return Serialize_UINT32(value, buffer);
1053 }
1054 
Parse_TPM_MODIFIER_INDICATOR(std::string * buffer,TPM_MODIFIER_INDICATOR * value,std::string * value_bytes)1055 TPM_RC Parse_TPM_MODIFIER_INDICATOR(std::string* buffer,
1056                                     TPM_MODIFIER_INDICATOR* value,
1057                                     std::string* value_bytes) {
1058   VLOG(3) << __func__;
1059   return Parse_UINT32(buffer, value, value_bytes);
1060 }
1061 
Serialize_TPM_AUTHORIZATION_SIZE(const TPM_AUTHORIZATION_SIZE & value,std::string * buffer)1062 TPM_RC Serialize_TPM_AUTHORIZATION_SIZE(const TPM_AUTHORIZATION_SIZE& value,
1063                                         std::string* buffer) {
1064   VLOG(3) << __func__;
1065   return Serialize_UINT32(value, buffer);
1066 }
1067 
Parse_TPM_AUTHORIZATION_SIZE(std::string * buffer,TPM_AUTHORIZATION_SIZE * value,std::string * value_bytes)1068 TPM_RC Parse_TPM_AUTHORIZATION_SIZE(std::string* buffer,
1069                                     TPM_AUTHORIZATION_SIZE* value,
1070                                     std::string* value_bytes) {
1071   VLOG(3) << __func__;
1072   return Parse_UINT32(buffer, value, value_bytes);
1073 }
1074 
Serialize_TPM_PARAMETER_SIZE(const TPM_PARAMETER_SIZE & value,std::string * buffer)1075 TPM_RC Serialize_TPM_PARAMETER_SIZE(const TPM_PARAMETER_SIZE& value,
1076                                     std::string* buffer) {
1077   VLOG(3) << __func__;
1078   return Serialize_UINT32(value, buffer);
1079 }
1080 
Parse_TPM_PARAMETER_SIZE(std::string * buffer,TPM_PARAMETER_SIZE * value,std::string * value_bytes)1081 TPM_RC Parse_TPM_PARAMETER_SIZE(std::string* buffer,
1082                                 TPM_PARAMETER_SIZE* value,
1083                                 std::string* value_bytes) {
1084   VLOG(3) << __func__;
1085   return Parse_UINT32(buffer, value, value_bytes);
1086 }
1087 
Serialize_TPM_KEY_SIZE(const TPM_KEY_SIZE & value,std::string * buffer)1088 TPM_RC Serialize_TPM_KEY_SIZE(const TPM_KEY_SIZE& value, std::string* buffer) {
1089   VLOG(3) << __func__;
1090   return Serialize_UINT16(value, buffer);
1091 }
1092 
Parse_TPM_KEY_SIZE(std::string * buffer,TPM_KEY_SIZE * value,std::string * value_bytes)1093 TPM_RC Parse_TPM_KEY_SIZE(std::string* buffer,
1094                           TPM_KEY_SIZE* value,
1095                           std::string* value_bytes) {
1096   VLOG(3) << __func__;
1097   return Parse_UINT16(buffer, value, value_bytes);
1098 }
1099 
Serialize_TPM_KEY_BITS(const TPM_KEY_BITS & value,std::string * buffer)1100 TPM_RC Serialize_TPM_KEY_BITS(const TPM_KEY_BITS& value, std::string* buffer) {
1101   VLOG(3) << __func__;
1102   return Serialize_UINT16(value, buffer);
1103 }
1104 
Parse_TPM_KEY_BITS(std::string * buffer,TPM_KEY_BITS * value,std::string * value_bytes)1105 TPM_RC Parse_TPM_KEY_BITS(std::string* buffer,
1106                           TPM_KEY_BITS* value,
1107                           std::string* value_bytes) {
1108   VLOG(3) << __func__;
1109   return Parse_UINT16(buffer, value, value_bytes);
1110 }
1111 
Serialize_TPM_HANDLE(const TPM_HANDLE & value,std::string * buffer)1112 TPM_RC Serialize_TPM_HANDLE(const TPM_HANDLE& value, std::string* buffer) {
1113   VLOG(3) << __func__;
1114   return Serialize_UINT32(value, buffer);
1115 }
1116 
Parse_TPM_HANDLE(std::string * buffer,TPM_HANDLE * value,std::string * value_bytes)1117 TPM_RC Parse_TPM_HANDLE(std::string* buffer,
1118                         TPM_HANDLE* value,
1119                         std::string* value_bytes) {
1120   VLOG(3) << __func__;
1121   return Parse_UINT32(buffer, value, value_bytes);
1122 }
1123 
Serialize_TPM2B_DIGEST(const TPM2B_DIGEST & value,std::string * buffer)1124 TPM_RC Serialize_TPM2B_DIGEST(const TPM2B_DIGEST& value, std::string* buffer) {
1125   TPM_RC result = TPM_RC_SUCCESS;
1126   VLOG(3) << __func__;
1127 
1128   result = Serialize_UINT16(value.size, buffer);
1129   if (result) {
1130     return result;
1131   }
1132 
1133   if (std::size(value.buffer) < value.size) {
1134     return TPM_RC_INSUFFICIENT;
1135   }
1136   for (uint32_t i = 0; i < value.size; ++i) {
1137     result = Serialize_BYTE(value.buffer[i], buffer);
1138     if (result) {
1139       return result;
1140     }
1141   }
1142   return result;
1143 }
1144 
Parse_TPM2B_DIGEST(std::string * buffer,TPM2B_DIGEST * value,std::string * value_bytes)1145 TPM_RC Parse_TPM2B_DIGEST(std::string* buffer,
1146                           TPM2B_DIGEST* value,
1147                           std::string* value_bytes) {
1148   TPM_RC result = TPM_RC_SUCCESS;
1149   VLOG(3) << __func__;
1150 
1151   result = Parse_UINT16(buffer, &value->size, value_bytes);
1152   if (result) {
1153     return result;
1154   }
1155 
1156   if (std::size(value->buffer) < value->size) {
1157     return TPM_RC_INSUFFICIENT;
1158   }
1159   for (uint32_t i = 0; i < value->size; ++i) {
1160     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
1161     if (result) {
1162       return result;
1163     }
1164   }
1165   return result;
1166 }
1167 
Make_TPM2B_DIGEST(const std::string & bytes)1168 TPM2B_DIGEST Make_TPM2B_DIGEST(const std::string& bytes) {
1169   TPM2B_DIGEST tpm2b;
1170   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
1171   memset(&tpm2b, 0, sizeof(TPM2B_DIGEST));
1172   tpm2b.size = bytes.size();
1173   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
1174   return tpm2b;
1175 }
1176 
StringFrom_TPM2B_DIGEST(const TPM2B_DIGEST & tpm2b)1177 std::string StringFrom_TPM2B_DIGEST(const TPM2B_DIGEST& tpm2b) {
1178   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
1179   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
1180   return std::string(char_buffer, tpm2b.size);
1181 }
1182 
Serialize_TPM2B_NONCE(const TPM2B_NONCE & value,std::string * buffer)1183 TPM_RC Serialize_TPM2B_NONCE(const TPM2B_NONCE& value, std::string* buffer) {
1184   VLOG(3) << __func__;
1185   return Serialize_TPM2B_DIGEST(value, buffer);
1186 }
1187 
Parse_TPM2B_NONCE(std::string * buffer,TPM2B_NONCE * value,std::string * value_bytes)1188 TPM_RC Parse_TPM2B_NONCE(std::string* buffer,
1189                          TPM2B_NONCE* value,
1190                          std::string* value_bytes) {
1191   VLOG(3) << __func__;
1192   return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1193 }
1194 
Serialize_TPM2B_AUTH(const TPM2B_AUTH & value,std::string * buffer)1195 TPM_RC Serialize_TPM2B_AUTH(const TPM2B_AUTH& value, std::string* buffer) {
1196   VLOG(3) << __func__;
1197   return Serialize_TPM2B_DIGEST(value, buffer);
1198 }
1199 
Parse_TPM2B_AUTH(std::string * buffer,TPM2B_AUTH * value,std::string * value_bytes)1200 TPM_RC Parse_TPM2B_AUTH(std::string* buffer,
1201                         TPM2B_AUTH* value,
1202                         std::string* value_bytes) {
1203   VLOG(3) << __func__;
1204   return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1205 }
1206 
Serialize_TPM2B_OPERAND(const TPM2B_OPERAND & value,std::string * buffer)1207 TPM_RC Serialize_TPM2B_OPERAND(const TPM2B_OPERAND& value,
1208                                std::string* buffer) {
1209   VLOG(3) << __func__;
1210   return Serialize_TPM2B_DIGEST(value, buffer);
1211 }
1212 
Parse_TPM2B_OPERAND(std::string * buffer,TPM2B_OPERAND * value,std::string * value_bytes)1213 TPM_RC Parse_TPM2B_OPERAND(std::string* buffer,
1214                            TPM2B_OPERAND* value,
1215                            std::string* value_bytes) {
1216   VLOG(3) << __func__;
1217   return Parse_TPM2B_DIGEST(buffer, value, value_bytes);
1218 }
1219 
Serialize_TPM_ALG_ID(const TPM_ALG_ID & value,std::string * buffer)1220 TPM_RC Serialize_TPM_ALG_ID(const TPM_ALG_ID& value, std::string* buffer) {
1221   VLOG(3) << __func__;
1222   return Serialize_UINT16(value, buffer);
1223 }
1224 
Parse_TPM_ALG_ID(std::string * buffer,TPM_ALG_ID * value,std::string * value_bytes)1225 TPM_RC Parse_TPM_ALG_ID(std::string* buffer,
1226                         TPM_ALG_ID* value,
1227                         std::string* value_bytes) {
1228   VLOG(3) << __func__;
1229   return Parse_UINT16(buffer, value, value_bytes);
1230 }
1231 
Serialize_TPMI_ALG_HASH(const TPMI_ALG_HASH & value,std::string * buffer)1232 TPM_RC Serialize_TPMI_ALG_HASH(const TPMI_ALG_HASH& value,
1233                                std::string* buffer) {
1234   VLOG(3) << __func__;
1235   return Serialize_TPM_ALG_ID(value, buffer);
1236 }
1237 
Parse_TPMI_ALG_HASH(std::string * buffer,TPMI_ALG_HASH * value,std::string * value_bytes)1238 TPM_RC Parse_TPMI_ALG_HASH(std::string* buffer,
1239                            TPMI_ALG_HASH* value,
1240                            std::string* value_bytes) {
1241   VLOG(3) << __func__;
1242   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1243 }
1244 
Serialize_TPMS_SCHEME_SIGHASH(const TPMS_SCHEME_SIGHASH & value,std::string * buffer)1245 TPM_RC Serialize_TPMS_SCHEME_SIGHASH(const TPMS_SCHEME_SIGHASH& value,
1246                                      std::string* buffer) {
1247   TPM_RC result = TPM_RC_SUCCESS;
1248   VLOG(3) << __func__;
1249 
1250   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
1251   if (result) {
1252     return result;
1253   }
1254   return result;
1255 }
1256 
Parse_TPMS_SCHEME_SIGHASH(std::string * buffer,TPMS_SCHEME_SIGHASH * value,std::string * value_bytes)1257 TPM_RC Parse_TPMS_SCHEME_SIGHASH(std::string* buffer,
1258                                  TPMS_SCHEME_SIGHASH* value,
1259                                  std::string* value_bytes) {
1260   TPM_RC result = TPM_RC_SUCCESS;
1261   VLOG(3) << __func__;
1262 
1263   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
1264   if (result) {
1265     return result;
1266   }
1267   return result;
1268 }
1269 
Serialize_TPMS_SCHEME_HMAC(const TPMS_SCHEME_HMAC & value,std::string * buffer)1270 TPM_RC Serialize_TPMS_SCHEME_HMAC(const TPMS_SCHEME_HMAC& value,
1271                                   std::string* buffer) {
1272   VLOG(3) << __func__;
1273   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1274 }
1275 
Parse_TPMS_SCHEME_HMAC(std::string * buffer,TPMS_SCHEME_HMAC * value,std::string * value_bytes)1276 TPM_RC Parse_TPMS_SCHEME_HMAC(std::string* buffer,
1277                               TPMS_SCHEME_HMAC* value,
1278                               std::string* value_bytes) {
1279   VLOG(3) << __func__;
1280   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1281 }
1282 
Serialize_TPMS_SCHEME_RSASSA(const TPMS_SCHEME_RSASSA & value,std::string * buffer)1283 TPM_RC Serialize_TPMS_SCHEME_RSASSA(const TPMS_SCHEME_RSASSA& value,
1284                                     std::string* buffer) {
1285   VLOG(3) << __func__;
1286   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1287 }
1288 
Parse_TPMS_SCHEME_RSASSA(std::string * buffer,TPMS_SCHEME_RSASSA * value,std::string * value_bytes)1289 TPM_RC Parse_TPMS_SCHEME_RSASSA(std::string* buffer,
1290                                 TPMS_SCHEME_RSASSA* value,
1291                                 std::string* value_bytes) {
1292   VLOG(3) << __func__;
1293   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1294 }
1295 
Serialize_TPMS_SCHEME_RSAPSS(const TPMS_SCHEME_RSAPSS & value,std::string * buffer)1296 TPM_RC Serialize_TPMS_SCHEME_RSAPSS(const TPMS_SCHEME_RSAPSS& value,
1297                                     std::string* buffer) {
1298   VLOG(3) << __func__;
1299   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1300 }
1301 
Parse_TPMS_SCHEME_RSAPSS(std::string * buffer,TPMS_SCHEME_RSAPSS * value,std::string * value_bytes)1302 TPM_RC Parse_TPMS_SCHEME_RSAPSS(std::string* buffer,
1303                                 TPMS_SCHEME_RSAPSS* value,
1304                                 std::string* value_bytes) {
1305   VLOG(3) << __func__;
1306   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1307 }
1308 
Serialize_TPMS_SCHEME_ECDSA(const TPMS_SCHEME_ECDSA & value,std::string * buffer)1309 TPM_RC Serialize_TPMS_SCHEME_ECDSA(const TPMS_SCHEME_ECDSA& value,
1310                                    std::string* buffer) {
1311   VLOG(3) << __func__;
1312   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1313 }
1314 
Parse_TPMS_SCHEME_ECDSA(std::string * buffer,TPMS_SCHEME_ECDSA * value,std::string * value_bytes)1315 TPM_RC Parse_TPMS_SCHEME_ECDSA(std::string* buffer,
1316                                TPMS_SCHEME_ECDSA* value,
1317                                std::string* value_bytes) {
1318   VLOG(3) << __func__;
1319   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1320 }
1321 
Serialize_TPMS_SCHEME_SM2(const TPMS_SCHEME_SM2 & value,std::string * buffer)1322 TPM_RC Serialize_TPMS_SCHEME_SM2(const TPMS_SCHEME_SM2& value,
1323                                  std::string* buffer) {
1324   VLOG(3) << __func__;
1325   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1326 }
1327 
Parse_TPMS_SCHEME_SM2(std::string * buffer,TPMS_SCHEME_SM2 * value,std::string * value_bytes)1328 TPM_RC Parse_TPMS_SCHEME_SM2(std::string* buffer,
1329                              TPMS_SCHEME_SM2* value,
1330                              std::string* value_bytes) {
1331   VLOG(3) << __func__;
1332   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1333 }
1334 
Serialize_TPMS_SCHEME_ECSCHNORR(const TPMS_SCHEME_ECSCHNORR & value,std::string * buffer)1335 TPM_RC Serialize_TPMS_SCHEME_ECSCHNORR(const TPMS_SCHEME_ECSCHNORR& value,
1336                                        std::string* buffer) {
1337   VLOG(3) << __func__;
1338   return Serialize_TPMS_SCHEME_SIGHASH(value, buffer);
1339 }
1340 
Parse_TPMS_SCHEME_ECSCHNORR(std::string * buffer,TPMS_SCHEME_ECSCHNORR * value,std::string * value_bytes)1341 TPM_RC Parse_TPMS_SCHEME_ECSCHNORR(std::string* buffer,
1342                                    TPMS_SCHEME_ECSCHNORR* value,
1343                                    std::string* value_bytes) {
1344   VLOG(3) << __func__;
1345   return Parse_TPMS_SCHEME_SIGHASH(buffer, value, value_bytes);
1346 }
1347 
Serialize_TPMI_YES_NO(const TPMI_YES_NO & value,std::string * buffer)1348 TPM_RC Serialize_TPMI_YES_NO(const TPMI_YES_NO& value, std::string* buffer) {
1349   VLOG(3) << __func__;
1350   return Serialize_BYTE(value, buffer);
1351 }
1352 
Parse_TPMI_YES_NO(std::string * buffer,TPMI_YES_NO * value,std::string * value_bytes)1353 TPM_RC Parse_TPMI_YES_NO(std::string* buffer,
1354                          TPMI_YES_NO* value,
1355                          std::string* value_bytes) {
1356   VLOG(3) << __func__;
1357   return Parse_BYTE(buffer, value, value_bytes);
1358 }
1359 
Serialize_TPMI_DH_OBJECT(const TPMI_DH_OBJECT & value,std::string * buffer)1360 TPM_RC Serialize_TPMI_DH_OBJECT(const TPMI_DH_OBJECT& value,
1361                                 std::string* buffer) {
1362   VLOG(3) << __func__;
1363   return Serialize_TPM_HANDLE(value, buffer);
1364 }
1365 
Parse_TPMI_DH_OBJECT(std::string * buffer,TPMI_DH_OBJECT * value,std::string * value_bytes)1366 TPM_RC Parse_TPMI_DH_OBJECT(std::string* buffer,
1367                             TPMI_DH_OBJECT* value,
1368                             std::string* value_bytes) {
1369   VLOG(3) << __func__;
1370   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1371 }
1372 
Serialize_TPMI_DH_PERSISTENT(const TPMI_DH_PERSISTENT & value,std::string * buffer)1373 TPM_RC Serialize_TPMI_DH_PERSISTENT(const TPMI_DH_PERSISTENT& value,
1374                                     std::string* buffer) {
1375   VLOG(3) << __func__;
1376   return Serialize_TPM_HANDLE(value, buffer);
1377 }
1378 
Parse_TPMI_DH_PERSISTENT(std::string * buffer,TPMI_DH_PERSISTENT * value,std::string * value_bytes)1379 TPM_RC Parse_TPMI_DH_PERSISTENT(std::string* buffer,
1380                                 TPMI_DH_PERSISTENT* value,
1381                                 std::string* value_bytes) {
1382   VLOG(3) << __func__;
1383   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1384 }
1385 
Serialize_TPMI_DH_ENTITY(const TPMI_DH_ENTITY & value,std::string * buffer)1386 TPM_RC Serialize_TPMI_DH_ENTITY(const TPMI_DH_ENTITY& value,
1387                                 std::string* buffer) {
1388   VLOG(3) << __func__;
1389   return Serialize_TPM_HANDLE(value, buffer);
1390 }
1391 
Parse_TPMI_DH_ENTITY(std::string * buffer,TPMI_DH_ENTITY * value,std::string * value_bytes)1392 TPM_RC Parse_TPMI_DH_ENTITY(std::string* buffer,
1393                             TPMI_DH_ENTITY* value,
1394                             std::string* value_bytes) {
1395   VLOG(3) << __func__;
1396   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1397 }
1398 
Serialize_TPMI_DH_PCR(const TPMI_DH_PCR & value,std::string * buffer)1399 TPM_RC Serialize_TPMI_DH_PCR(const TPMI_DH_PCR& value, std::string* buffer) {
1400   VLOG(3) << __func__;
1401   return Serialize_TPM_HANDLE(value, buffer);
1402 }
1403 
Parse_TPMI_DH_PCR(std::string * buffer,TPMI_DH_PCR * value,std::string * value_bytes)1404 TPM_RC Parse_TPMI_DH_PCR(std::string* buffer,
1405                          TPMI_DH_PCR* value,
1406                          std::string* value_bytes) {
1407   VLOG(3) << __func__;
1408   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1409 }
1410 
Serialize_TPMI_SH_AUTH_SESSION(const TPMI_SH_AUTH_SESSION & value,std::string * buffer)1411 TPM_RC Serialize_TPMI_SH_AUTH_SESSION(const TPMI_SH_AUTH_SESSION& value,
1412                                       std::string* buffer) {
1413   VLOG(3) << __func__;
1414   return Serialize_TPM_HANDLE(value, buffer);
1415 }
1416 
Parse_TPMI_SH_AUTH_SESSION(std::string * buffer,TPMI_SH_AUTH_SESSION * value,std::string * value_bytes)1417 TPM_RC Parse_TPMI_SH_AUTH_SESSION(std::string* buffer,
1418                                   TPMI_SH_AUTH_SESSION* value,
1419                                   std::string* value_bytes) {
1420   VLOG(3) << __func__;
1421   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1422 }
1423 
Serialize_TPMI_SH_HMAC(const TPMI_SH_HMAC & value,std::string * buffer)1424 TPM_RC Serialize_TPMI_SH_HMAC(const TPMI_SH_HMAC& value, std::string* buffer) {
1425   VLOG(3) << __func__;
1426   return Serialize_TPM_HANDLE(value, buffer);
1427 }
1428 
Parse_TPMI_SH_HMAC(std::string * buffer,TPMI_SH_HMAC * value,std::string * value_bytes)1429 TPM_RC Parse_TPMI_SH_HMAC(std::string* buffer,
1430                           TPMI_SH_HMAC* value,
1431                           std::string* value_bytes) {
1432   VLOG(3) << __func__;
1433   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1434 }
1435 
Serialize_TPMI_SH_POLICY(const TPMI_SH_POLICY & value,std::string * buffer)1436 TPM_RC Serialize_TPMI_SH_POLICY(const TPMI_SH_POLICY& value,
1437                                 std::string* buffer) {
1438   VLOG(3) << __func__;
1439   return Serialize_TPM_HANDLE(value, buffer);
1440 }
1441 
Parse_TPMI_SH_POLICY(std::string * buffer,TPMI_SH_POLICY * value,std::string * value_bytes)1442 TPM_RC Parse_TPMI_SH_POLICY(std::string* buffer,
1443                             TPMI_SH_POLICY* value,
1444                             std::string* value_bytes) {
1445   VLOG(3) << __func__;
1446   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1447 }
1448 
Serialize_TPMI_DH_CONTEXT(const TPMI_DH_CONTEXT & value,std::string * buffer)1449 TPM_RC Serialize_TPMI_DH_CONTEXT(const TPMI_DH_CONTEXT& value,
1450                                  std::string* buffer) {
1451   VLOG(3) << __func__;
1452   return Serialize_TPM_HANDLE(value, buffer);
1453 }
1454 
Parse_TPMI_DH_CONTEXT(std::string * buffer,TPMI_DH_CONTEXT * value,std::string * value_bytes)1455 TPM_RC Parse_TPMI_DH_CONTEXT(std::string* buffer,
1456                              TPMI_DH_CONTEXT* value,
1457                              std::string* value_bytes) {
1458   VLOG(3) << __func__;
1459   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1460 }
1461 
Serialize_TPMI_RH_HIERARCHY(const TPMI_RH_HIERARCHY & value,std::string * buffer)1462 TPM_RC Serialize_TPMI_RH_HIERARCHY(const TPMI_RH_HIERARCHY& value,
1463                                    std::string* buffer) {
1464   VLOG(3) << __func__;
1465   return Serialize_TPM_HANDLE(value, buffer);
1466 }
1467 
Parse_TPMI_RH_HIERARCHY(std::string * buffer,TPMI_RH_HIERARCHY * value,std::string * value_bytes)1468 TPM_RC Parse_TPMI_RH_HIERARCHY(std::string* buffer,
1469                                TPMI_RH_HIERARCHY* value,
1470                                std::string* value_bytes) {
1471   VLOG(3) << __func__;
1472   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1473 }
1474 
Serialize_TPMI_RH_ENABLES(const TPMI_RH_ENABLES & value,std::string * buffer)1475 TPM_RC Serialize_TPMI_RH_ENABLES(const TPMI_RH_ENABLES& value,
1476                                  std::string* buffer) {
1477   VLOG(3) << __func__;
1478   return Serialize_TPM_HANDLE(value, buffer);
1479 }
1480 
Parse_TPMI_RH_ENABLES(std::string * buffer,TPMI_RH_ENABLES * value,std::string * value_bytes)1481 TPM_RC Parse_TPMI_RH_ENABLES(std::string* buffer,
1482                              TPMI_RH_ENABLES* value,
1483                              std::string* value_bytes) {
1484   VLOG(3) << __func__;
1485   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1486 }
1487 
Serialize_TPMI_RH_HIERARCHY_AUTH(const TPMI_RH_HIERARCHY_AUTH & value,std::string * buffer)1488 TPM_RC Serialize_TPMI_RH_HIERARCHY_AUTH(const TPMI_RH_HIERARCHY_AUTH& value,
1489                                         std::string* buffer) {
1490   VLOG(3) << __func__;
1491   return Serialize_TPM_HANDLE(value, buffer);
1492 }
1493 
Parse_TPMI_RH_HIERARCHY_AUTH(std::string * buffer,TPMI_RH_HIERARCHY_AUTH * value,std::string * value_bytes)1494 TPM_RC Parse_TPMI_RH_HIERARCHY_AUTH(std::string* buffer,
1495                                     TPMI_RH_HIERARCHY_AUTH* value,
1496                                     std::string* value_bytes) {
1497   VLOG(3) << __func__;
1498   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1499 }
1500 
Serialize_TPMI_RH_PLATFORM(const TPMI_RH_PLATFORM & value,std::string * buffer)1501 TPM_RC Serialize_TPMI_RH_PLATFORM(const TPMI_RH_PLATFORM& value,
1502                                   std::string* buffer) {
1503   VLOG(3) << __func__;
1504   return Serialize_TPM_HANDLE(value, buffer);
1505 }
1506 
Parse_TPMI_RH_PLATFORM(std::string * buffer,TPMI_RH_PLATFORM * value,std::string * value_bytes)1507 TPM_RC Parse_TPMI_RH_PLATFORM(std::string* buffer,
1508                               TPMI_RH_PLATFORM* value,
1509                               std::string* value_bytes) {
1510   VLOG(3) << __func__;
1511   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1512 }
1513 
Serialize_TPMI_RH_OWNER(const TPMI_RH_OWNER & value,std::string * buffer)1514 TPM_RC Serialize_TPMI_RH_OWNER(const TPMI_RH_OWNER& value,
1515                                std::string* buffer) {
1516   VLOG(3) << __func__;
1517   return Serialize_TPM_HANDLE(value, buffer);
1518 }
1519 
Parse_TPMI_RH_OWNER(std::string * buffer,TPMI_RH_OWNER * value,std::string * value_bytes)1520 TPM_RC Parse_TPMI_RH_OWNER(std::string* buffer,
1521                            TPMI_RH_OWNER* value,
1522                            std::string* value_bytes) {
1523   VLOG(3) << __func__;
1524   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1525 }
1526 
Serialize_TPMI_RH_ENDORSEMENT(const TPMI_RH_ENDORSEMENT & value,std::string * buffer)1527 TPM_RC Serialize_TPMI_RH_ENDORSEMENT(const TPMI_RH_ENDORSEMENT& value,
1528                                      std::string* buffer) {
1529   VLOG(3) << __func__;
1530   return Serialize_TPM_HANDLE(value, buffer);
1531 }
1532 
Parse_TPMI_RH_ENDORSEMENT(std::string * buffer,TPMI_RH_ENDORSEMENT * value,std::string * value_bytes)1533 TPM_RC Parse_TPMI_RH_ENDORSEMENT(std::string* buffer,
1534                                  TPMI_RH_ENDORSEMENT* value,
1535                                  std::string* value_bytes) {
1536   VLOG(3) << __func__;
1537   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1538 }
1539 
Serialize_TPMI_RH_PROVISION(const TPMI_RH_PROVISION & value,std::string * buffer)1540 TPM_RC Serialize_TPMI_RH_PROVISION(const TPMI_RH_PROVISION& value,
1541                                    std::string* buffer) {
1542   VLOG(3) << __func__;
1543   return Serialize_TPM_HANDLE(value, buffer);
1544 }
1545 
Parse_TPMI_RH_PROVISION(std::string * buffer,TPMI_RH_PROVISION * value,std::string * value_bytes)1546 TPM_RC Parse_TPMI_RH_PROVISION(std::string* buffer,
1547                                TPMI_RH_PROVISION* value,
1548                                std::string* value_bytes) {
1549   VLOG(3) << __func__;
1550   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1551 }
1552 
Serialize_TPMI_RH_CLEAR(const TPMI_RH_CLEAR & value,std::string * buffer)1553 TPM_RC Serialize_TPMI_RH_CLEAR(const TPMI_RH_CLEAR& value,
1554                                std::string* buffer) {
1555   VLOG(3) << __func__;
1556   return Serialize_TPM_HANDLE(value, buffer);
1557 }
1558 
Parse_TPMI_RH_CLEAR(std::string * buffer,TPMI_RH_CLEAR * value,std::string * value_bytes)1559 TPM_RC Parse_TPMI_RH_CLEAR(std::string* buffer,
1560                            TPMI_RH_CLEAR* value,
1561                            std::string* value_bytes) {
1562   VLOG(3) << __func__;
1563   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1564 }
1565 
Serialize_TPMI_RH_NV_AUTH(const TPMI_RH_NV_AUTH & value,std::string * buffer)1566 TPM_RC Serialize_TPMI_RH_NV_AUTH(const TPMI_RH_NV_AUTH& value,
1567                                  std::string* buffer) {
1568   VLOG(3) << __func__;
1569   return Serialize_TPM_HANDLE(value, buffer);
1570 }
1571 
Parse_TPMI_RH_NV_AUTH(std::string * buffer,TPMI_RH_NV_AUTH * value,std::string * value_bytes)1572 TPM_RC Parse_TPMI_RH_NV_AUTH(std::string* buffer,
1573                              TPMI_RH_NV_AUTH* value,
1574                              std::string* value_bytes) {
1575   VLOG(3) << __func__;
1576   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1577 }
1578 
Serialize_TPMI_RH_LOCKOUT(const TPMI_RH_LOCKOUT & value,std::string * buffer)1579 TPM_RC Serialize_TPMI_RH_LOCKOUT(const TPMI_RH_LOCKOUT& value,
1580                                  std::string* buffer) {
1581   VLOG(3) << __func__;
1582   return Serialize_TPM_HANDLE(value, buffer);
1583 }
1584 
Parse_TPMI_RH_LOCKOUT(std::string * buffer,TPMI_RH_LOCKOUT * value,std::string * value_bytes)1585 TPM_RC Parse_TPMI_RH_LOCKOUT(std::string* buffer,
1586                              TPMI_RH_LOCKOUT* value,
1587                              std::string* value_bytes) {
1588   VLOG(3) << __func__;
1589   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1590 }
1591 
Serialize_TPMI_RH_NV_INDEX(const TPMI_RH_NV_INDEX & value,std::string * buffer)1592 TPM_RC Serialize_TPMI_RH_NV_INDEX(const TPMI_RH_NV_INDEX& value,
1593                                   std::string* buffer) {
1594   VLOG(3) << __func__;
1595   return Serialize_TPM_HANDLE(value, buffer);
1596 }
1597 
Parse_TPMI_RH_NV_INDEX(std::string * buffer,TPMI_RH_NV_INDEX * value,std::string * value_bytes)1598 TPM_RC Parse_TPMI_RH_NV_INDEX(std::string* buffer,
1599                               TPMI_RH_NV_INDEX* value,
1600                               std::string* value_bytes) {
1601   VLOG(3) << __func__;
1602   return Parse_TPM_HANDLE(buffer, value, value_bytes);
1603 }
1604 
Serialize_TPMI_ALG_ASYM(const TPMI_ALG_ASYM & value,std::string * buffer)1605 TPM_RC Serialize_TPMI_ALG_ASYM(const TPMI_ALG_ASYM& value,
1606                                std::string* buffer) {
1607   VLOG(3) << __func__;
1608   return Serialize_TPM_ALG_ID(value, buffer);
1609 }
1610 
Parse_TPMI_ALG_ASYM(std::string * buffer,TPMI_ALG_ASYM * value,std::string * value_bytes)1611 TPM_RC Parse_TPMI_ALG_ASYM(std::string* buffer,
1612                            TPMI_ALG_ASYM* value,
1613                            std::string* value_bytes) {
1614   VLOG(3) << __func__;
1615   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1616 }
1617 
Serialize_TPMI_ALG_SYM(const TPMI_ALG_SYM & value,std::string * buffer)1618 TPM_RC Serialize_TPMI_ALG_SYM(const TPMI_ALG_SYM& value, std::string* buffer) {
1619   VLOG(3) << __func__;
1620   return Serialize_TPM_ALG_ID(value, buffer);
1621 }
1622 
Parse_TPMI_ALG_SYM(std::string * buffer,TPMI_ALG_SYM * value,std::string * value_bytes)1623 TPM_RC Parse_TPMI_ALG_SYM(std::string* buffer,
1624                           TPMI_ALG_SYM* value,
1625                           std::string* value_bytes) {
1626   VLOG(3) << __func__;
1627   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1628 }
1629 
Serialize_TPMI_ALG_SYM_OBJECT(const TPMI_ALG_SYM_OBJECT & value,std::string * buffer)1630 TPM_RC Serialize_TPMI_ALG_SYM_OBJECT(const TPMI_ALG_SYM_OBJECT& value,
1631                                      std::string* buffer) {
1632   VLOG(3) << __func__;
1633   return Serialize_TPM_ALG_ID(value, buffer);
1634 }
1635 
Parse_TPMI_ALG_SYM_OBJECT(std::string * buffer,TPMI_ALG_SYM_OBJECT * value,std::string * value_bytes)1636 TPM_RC Parse_TPMI_ALG_SYM_OBJECT(std::string* buffer,
1637                                  TPMI_ALG_SYM_OBJECT* value,
1638                                  std::string* value_bytes) {
1639   VLOG(3) << __func__;
1640   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1641 }
1642 
Serialize_TPMI_ALG_SYM_MODE(const TPMI_ALG_SYM_MODE & value,std::string * buffer)1643 TPM_RC Serialize_TPMI_ALG_SYM_MODE(const TPMI_ALG_SYM_MODE& value,
1644                                    std::string* buffer) {
1645   VLOG(3) << __func__;
1646   return Serialize_TPM_ALG_ID(value, buffer);
1647 }
1648 
Parse_TPMI_ALG_SYM_MODE(std::string * buffer,TPMI_ALG_SYM_MODE * value,std::string * value_bytes)1649 TPM_RC Parse_TPMI_ALG_SYM_MODE(std::string* buffer,
1650                                TPMI_ALG_SYM_MODE* value,
1651                                std::string* value_bytes) {
1652   VLOG(3) << __func__;
1653   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1654 }
1655 
Serialize_TPMI_ALG_KDF(const TPMI_ALG_KDF & value,std::string * buffer)1656 TPM_RC Serialize_TPMI_ALG_KDF(const TPMI_ALG_KDF& value, std::string* buffer) {
1657   VLOG(3) << __func__;
1658   return Serialize_TPM_ALG_ID(value, buffer);
1659 }
1660 
Parse_TPMI_ALG_KDF(std::string * buffer,TPMI_ALG_KDF * value,std::string * value_bytes)1661 TPM_RC Parse_TPMI_ALG_KDF(std::string* buffer,
1662                           TPMI_ALG_KDF* value,
1663                           std::string* value_bytes) {
1664   VLOG(3) << __func__;
1665   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1666 }
1667 
Serialize_TPMI_ALG_SIG_SCHEME(const TPMI_ALG_SIG_SCHEME & value,std::string * buffer)1668 TPM_RC Serialize_TPMI_ALG_SIG_SCHEME(const TPMI_ALG_SIG_SCHEME& value,
1669                                      std::string* buffer) {
1670   VLOG(3) << __func__;
1671   return Serialize_TPM_ALG_ID(value, buffer);
1672 }
1673 
Parse_TPMI_ALG_SIG_SCHEME(std::string * buffer,TPMI_ALG_SIG_SCHEME * value,std::string * value_bytes)1674 TPM_RC Parse_TPMI_ALG_SIG_SCHEME(std::string* buffer,
1675                                  TPMI_ALG_SIG_SCHEME* value,
1676                                  std::string* value_bytes) {
1677   VLOG(3) << __func__;
1678   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1679 }
1680 
Serialize_TPMI_ECC_KEY_EXCHANGE(const TPMI_ECC_KEY_EXCHANGE & value,std::string * buffer)1681 TPM_RC Serialize_TPMI_ECC_KEY_EXCHANGE(const TPMI_ECC_KEY_EXCHANGE& value,
1682                                        std::string* buffer) {
1683   VLOG(3) << __func__;
1684   return Serialize_TPM_ALG_ID(value, buffer);
1685 }
1686 
Parse_TPMI_ECC_KEY_EXCHANGE(std::string * buffer,TPMI_ECC_KEY_EXCHANGE * value,std::string * value_bytes)1687 TPM_RC Parse_TPMI_ECC_KEY_EXCHANGE(std::string* buffer,
1688                                    TPMI_ECC_KEY_EXCHANGE* value,
1689                                    std::string* value_bytes) {
1690   VLOG(3) << __func__;
1691   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1692 }
1693 
Serialize_TPM_ST(const TPM_ST & value,std::string * buffer)1694 TPM_RC Serialize_TPM_ST(const TPM_ST& value, std::string* buffer) {
1695   VLOG(3) << __func__;
1696   return Serialize_UINT16(value, buffer);
1697 }
1698 
Parse_TPM_ST(std::string * buffer,TPM_ST * value,std::string * value_bytes)1699 TPM_RC Parse_TPM_ST(std::string* buffer,
1700                     TPM_ST* value,
1701                     std::string* value_bytes) {
1702   VLOG(3) << __func__;
1703   return Parse_UINT16(buffer, value, value_bytes);
1704 }
1705 
Serialize_TPMI_ST_COMMAND_TAG(const TPMI_ST_COMMAND_TAG & value,std::string * buffer)1706 TPM_RC Serialize_TPMI_ST_COMMAND_TAG(const TPMI_ST_COMMAND_TAG& value,
1707                                      std::string* buffer) {
1708   VLOG(3) << __func__;
1709   return Serialize_TPM_ST(value, buffer);
1710 }
1711 
Parse_TPMI_ST_COMMAND_TAG(std::string * buffer,TPMI_ST_COMMAND_TAG * value,std::string * value_bytes)1712 TPM_RC Parse_TPMI_ST_COMMAND_TAG(std::string* buffer,
1713                                  TPMI_ST_COMMAND_TAG* value,
1714                                  std::string* value_bytes) {
1715   VLOG(3) << __func__;
1716   return Parse_TPM_ST(buffer, value, value_bytes);
1717 }
1718 
Serialize_TPMI_ST_ATTEST(const TPMI_ST_ATTEST & value,std::string * buffer)1719 TPM_RC Serialize_TPMI_ST_ATTEST(const TPMI_ST_ATTEST& value,
1720                                 std::string* buffer) {
1721   VLOG(3) << __func__;
1722   return Serialize_TPM_ST(value, buffer);
1723 }
1724 
Parse_TPMI_ST_ATTEST(std::string * buffer,TPMI_ST_ATTEST * value,std::string * value_bytes)1725 TPM_RC Parse_TPMI_ST_ATTEST(std::string* buffer,
1726                             TPMI_ST_ATTEST* value,
1727                             std::string* value_bytes) {
1728   VLOG(3) << __func__;
1729   return Parse_TPM_ST(buffer, value, value_bytes);
1730 }
1731 
Serialize_TPMI_AES_KEY_BITS(const TPMI_AES_KEY_BITS & value,std::string * buffer)1732 TPM_RC Serialize_TPMI_AES_KEY_BITS(const TPMI_AES_KEY_BITS& value,
1733                                    std::string* buffer) {
1734   VLOG(3) << __func__;
1735   return Serialize_TPM_KEY_BITS(value, buffer);
1736 }
1737 
Parse_TPMI_AES_KEY_BITS(std::string * buffer,TPMI_AES_KEY_BITS * value,std::string * value_bytes)1738 TPM_RC Parse_TPMI_AES_KEY_BITS(std::string* buffer,
1739                                TPMI_AES_KEY_BITS* value,
1740                                std::string* value_bytes) {
1741   VLOG(3) << __func__;
1742   return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1743 }
1744 
Serialize_TPMI_SM4_KEY_BITS(const TPMI_SM4_KEY_BITS & value,std::string * buffer)1745 TPM_RC Serialize_TPMI_SM4_KEY_BITS(const TPMI_SM4_KEY_BITS& value,
1746                                    std::string* buffer) {
1747   VLOG(3) << __func__;
1748   return Serialize_TPM_KEY_BITS(value, buffer);
1749 }
1750 
Parse_TPMI_SM4_KEY_BITS(std::string * buffer,TPMI_SM4_KEY_BITS * value,std::string * value_bytes)1751 TPM_RC Parse_TPMI_SM4_KEY_BITS(std::string* buffer,
1752                                TPMI_SM4_KEY_BITS* value,
1753                                std::string* value_bytes) {
1754   VLOG(3) << __func__;
1755   return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1756 }
1757 
Serialize_TPMI_ALG_KEYEDHASH_SCHEME(const TPMI_ALG_KEYEDHASH_SCHEME & value,std::string * buffer)1758 TPM_RC Serialize_TPMI_ALG_KEYEDHASH_SCHEME(
1759     const TPMI_ALG_KEYEDHASH_SCHEME& value, std::string* buffer) {
1760   VLOG(3) << __func__;
1761   return Serialize_TPM_ALG_ID(value, buffer);
1762 }
1763 
Parse_TPMI_ALG_KEYEDHASH_SCHEME(std::string * buffer,TPMI_ALG_KEYEDHASH_SCHEME * value,std::string * value_bytes)1764 TPM_RC Parse_TPMI_ALG_KEYEDHASH_SCHEME(std::string* buffer,
1765                                        TPMI_ALG_KEYEDHASH_SCHEME* value,
1766                                        std::string* value_bytes) {
1767   VLOG(3) << __func__;
1768   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1769 }
1770 
Serialize_TPMI_ALG_ASYM_SCHEME(const TPMI_ALG_ASYM_SCHEME & value,std::string * buffer)1771 TPM_RC Serialize_TPMI_ALG_ASYM_SCHEME(const TPMI_ALG_ASYM_SCHEME& value,
1772                                       std::string* buffer) {
1773   VLOG(3) << __func__;
1774   return Serialize_TPM_ALG_ID(value, buffer);
1775 }
1776 
Parse_TPMI_ALG_ASYM_SCHEME(std::string * buffer,TPMI_ALG_ASYM_SCHEME * value,std::string * value_bytes)1777 TPM_RC Parse_TPMI_ALG_ASYM_SCHEME(std::string* buffer,
1778                                   TPMI_ALG_ASYM_SCHEME* value,
1779                                   std::string* value_bytes) {
1780   VLOG(3) << __func__;
1781   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1782 }
1783 
Serialize_TPMI_ALG_RSA_SCHEME(const TPMI_ALG_RSA_SCHEME & value,std::string * buffer)1784 TPM_RC Serialize_TPMI_ALG_RSA_SCHEME(const TPMI_ALG_RSA_SCHEME& value,
1785                                      std::string* buffer) {
1786   VLOG(3) << __func__;
1787   return Serialize_TPM_ALG_ID(value, buffer);
1788 }
1789 
Parse_TPMI_ALG_RSA_SCHEME(std::string * buffer,TPMI_ALG_RSA_SCHEME * value,std::string * value_bytes)1790 TPM_RC Parse_TPMI_ALG_RSA_SCHEME(std::string* buffer,
1791                                  TPMI_ALG_RSA_SCHEME* value,
1792                                  std::string* value_bytes) {
1793   VLOG(3) << __func__;
1794   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1795 }
1796 
Serialize_TPMI_ALG_RSA_DECRYPT(const TPMI_ALG_RSA_DECRYPT & value,std::string * buffer)1797 TPM_RC Serialize_TPMI_ALG_RSA_DECRYPT(const TPMI_ALG_RSA_DECRYPT& value,
1798                                       std::string* buffer) {
1799   VLOG(3) << __func__;
1800   return Serialize_TPM_ALG_ID(value, buffer);
1801 }
1802 
Parse_TPMI_ALG_RSA_DECRYPT(std::string * buffer,TPMI_ALG_RSA_DECRYPT * value,std::string * value_bytes)1803 TPM_RC Parse_TPMI_ALG_RSA_DECRYPT(std::string* buffer,
1804                                   TPMI_ALG_RSA_DECRYPT* value,
1805                                   std::string* value_bytes) {
1806   VLOG(3) << __func__;
1807   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1808 }
1809 
Serialize_TPMI_RSA_KEY_BITS(const TPMI_RSA_KEY_BITS & value,std::string * buffer)1810 TPM_RC Serialize_TPMI_RSA_KEY_BITS(const TPMI_RSA_KEY_BITS& value,
1811                                    std::string* buffer) {
1812   VLOG(3) << __func__;
1813   return Serialize_TPM_KEY_BITS(value, buffer);
1814 }
1815 
Parse_TPMI_RSA_KEY_BITS(std::string * buffer,TPMI_RSA_KEY_BITS * value,std::string * value_bytes)1816 TPM_RC Parse_TPMI_RSA_KEY_BITS(std::string* buffer,
1817                                TPMI_RSA_KEY_BITS* value,
1818                                std::string* value_bytes) {
1819   VLOG(3) << __func__;
1820   return Parse_TPM_KEY_BITS(buffer, value, value_bytes);
1821 }
1822 
Serialize_TPMI_ALG_ECC_SCHEME(const TPMI_ALG_ECC_SCHEME & value,std::string * buffer)1823 TPM_RC Serialize_TPMI_ALG_ECC_SCHEME(const TPMI_ALG_ECC_SCHEME& value,
1824                                      std::string* buffer) {
1825   VLOG(3) << __func__;
1826   return Serialize_TPM_ALG_ID(value, buffer);
1827 }
1828 
Parse_TPMI_ALG_ECC_SCHEME(std::string * buffer,TPMI_ALG_ECC_SCHEME * value,std::string * value_bytes)1829 TPM_RC Parse_TPMI_ALG_ECC_SCHEME(std::string* buffer,
1830                                  TPMI_ALG_ECC_SCHEME* value,
1831                                  std::string* value_bytes) {
1832   VLOG(3) << __func__;
1833   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1834 }
1835 
Serialize_TPM_ECC_CURVE(const TPM_ECC_CURVE & value,std::string * buffer)1836 TPM_RC Serialize_TPM_ECC_CURVE(const TPM_ECC_CURVE& value,
1837                                std::string* buffer) {
1838   VLOG(3) << __func__;
1839   return Serialize_UINT16(value, buffer);
1840 }
1841 
Parse_TPM_ECC_CURVE(std::string * buffer,TPM_ECC_CURVE * value,std::string * value_bytes)1842 TPM_RC Parse_TPM_ECC_CURVE(std::string* buffer,
1843                            TPM_ECC_CURVE* value,
1844                            std::string* value_bytes) {
1845   VLOG(3) << __func__;
1846   return Parse_UINT16(buffer, value, value_bytes);
1847 }
1848 
Serialize_TPMI_ECC_CURVE(const TPMI_ECC_CURVE & value,std::string * buffer)1849 TPM_RC Serialize_TPMI_ECC_CURVE(const TPMI_ECC_CURVE& value,
1850                                 std::string* buffer) {
1851   VLOG(3) << __func__;
1852   return Serialize_TPM_ECC_CURVE(value, buffer);
1853 }
1854 
Parse_TPMI_ECC_CURVE(std::string * buffer,TPMI_ECC_CURVE * value,std::string * value_bytes)1855 TPM_RC Parse_TPMI_ECC_CURVE(std::string* buffer,
1856                             TPMI_ECC_CURVE* value,
1857                             std::string* value_bytes) {
1858   VLOG(3) << __func__;
1859   return Parse_TPM_ECC_CURVE(buffer, value, value_bytes);
1860 }
1861 
Serialize_TPMI_ALG_PUBLIC(const TPMI_ALG_PUBLIC & value,std::string * buffer)1862 TPM_RC Serialize_TPMI_ALG_PUBLIC(const TPMI_ALG_PUBLIC& value,
1863                                  std::string* buffer) {
1864   VLOG(3) << __func__;
1865   return Serialize_TPM_ALG_ID(value, buffer);
1866 }
1867 
Parse_TPMI_ALG_PUBLIC(std::string * buffer,TPMI_ALG_PUBLIC * value,std::string * value_bytes)1868 TPM_RC Parse_TPMI_ALG_PUBLIC(std::string* buffer,
1869                              TPMI_ALG_PUBLIC* value,
1870                              std::string* value_bytes) {
1871   VLOG(3) << __func__;
1872   return Parse_TPM_ALG_ID(buffer, value, value_bytes);
1873 }
1874 
Serialize_TPMA_ALGORITHM(const TPMA_ALGORITHM & value,std::string * buffer)1875 TPM_RC Serialize_TPMA_ALGORITHM(const TPMA_ALGORITHM& value,
1876                                 std::string* buffer) {
1877   VLOG(3) << __func__;
1878   return Serialize_UINT32(value, buffer);
1879 }
1880 
Parse_TPMA_ALGORITHM(std::string * buffer,TPMA_ALGORITHM * value,std::string * value_bytes)1881 TPM_RC Parse_TPMA_ALGORITHM(std::string* buffer,
1882                             TPMA_ALGORITHM* value,
1883                             std::string* value_bytes) {
1884   VLOG(3) << __func__;
1885   return Parse_UINT32(buffer, value, value_bytes);
1886 }
1887 
Serialize_TPMA_OBJECT(const TPMA_OBJECT & value,std::string * buffer)1888 TPM_RC Serialize_TPMA_OBJECT(const TPMA_OBJECT& value, std::string* buffer) {
1889   VLOG(3) << __func__;
1890   return Serialize_UINT32(value, buffer);
1891 }
1892 
Parse_TPMA_OBJECT(std::string * buffer,TPMA_OBJECT * value,std::string * value_bytes)1893 TPM_RC Parse_TPMA_OBJECT(std::string* buffer,
1894                          TPMA_OBJECT* value,
1895                          std::string* value_bytes) {
1896   VLOG(3) << __func__;
1897   return Parse_UINT32(buffer, value, value_bytes);
1898 }
1899 
Serialize_TPMA_SESSION(const TPMA_SESSION & value,std::string * buffer)1900 TPM_RC Serialize_TPMA_SESSION(const TPMA_SESSION& value, std::string* buffer) {
1901   VLOG(3) << __func__;
1902   return Serialize_UINT8(value, buffer);
1903 }
1904 
Parse_TPMA_SESSION(std::string * buffer,TPMA_SESSION * value,std::string * value_bytes)1905 TPM_RC Parse_TPMA_SESSION(std::string* buffer,
1906                           TPMA_SESSION* value,
1907                           std::string* value_bytes) {
1908   VLOG(3) << __func__;
1909   return Parse_UINT8(buffer, value, value_bytes);
1910 }
1911 
Serialize_TPMA_LOCALITY(const TPMA_LOCALITY & value,std::string * buffer)1912 TPM_RC Serialize_TPMA_LOCALITY(const TPMA_LOCALITY& value,
1913                                std::string* buffer) {
1914   VLOG(3) << __func__;
1915   return Serialize_UINT8(value, buffer);
1916 }
1917 
Parse_TPMA_LOCALITY(std::string * buffer,TPMA_LOCALITY * value,std::string * value_bytes)1918 TPM_RC Parse_TPMA_LOCALITY(std::string* buffer,
1919                            TPMA_LOCALITY* value,
1920                            std::string* value_bytes) {
1921   VLOG(3) << __func__;
1922   return Parse_UINT8(buffer, value, value_bytes);
1923 }
1924 
Serialize_TPMA_PERMANENT(const TPMA_PERMANENT & value,std::string * buffer)1925 TPM_RC Serialize_TPMA_PERMANENT(const TPMA_PERMANENT& value,
1926                                 std::string* buffer) {
1927   VLOG(3) << __func__;
1928   return Serialize_UINT32(value, buffer);
1929 }
1930 
Parse_TPMA_PERMANENT(std::string * buffer,TPMA_PERMANENT * value,std::string * value_bytes)1931 TPM_RC Parse_TPMA_PERMANENT(std::string* buffer,
1932                             TPMA_PERMANENT* value,
1933                             std::string* value_bytes) {
1934   VLOG(3) << __func__;
1935   return Parse_UINT32(buffer, value, value_bytes);
1936 }
1937 
Serialize_TPMA_STARTUP_CLEAR(const TPMA_STARTUP_CLEAR & value,std::string * buffer)1938 TPM_RC Serialize_TPMA_STARTUP_CLEAR(const TPMA_STARTUP_CLEAR& value,
1939                                     std::string* buffer) {
1940   VLOG(3) << __func__;
1941   return Serialize_UINT32(value, buffer);
1942 }
1943 
Parse_TPMA_STARTUP_CLEAR(std::string * buffer,TPMA_STARTUP_CLEAR * value,std::string * value_bytes)1944 TPM_RC Parse_TPMA_STARTUP_CLEAR(std::string* buffer,
1945                                 TPMA_STARTUP_CLEAR* value,
1946                                 std::string* value_bytes) {
1947   VLOG(3) << __func__;
1948   return Parse_UINT32(buffer, value, value_bytes);
1949 }
1950 
Serialize_TPMA_MEMORY(const TPMA_MEMORY & value,std::string * buffer)1951 TPM_RC Serialize_TPMA_MEMORY(const TPMA_MEMORY& value, std::string* buffer) {
1952   VLOG(3) << __func__;
1953   return Serialize_UINT32(value, buffer);
1954 }
1955 
Parse_TPMA_MEMORY(std::string * buffer,TPMA_MEMORY * value,std::string * value_bytes)1956 TPM_RC Parse_TPMA_MEMORY(std::string* buffer,
1957                          TPMA_MEMORY* value,
1958                          std::string* value_bytes) {
1959   VLOG(3) << __func__;
1960   return Parse_UINT32(buffer, value, value_bytes);
1961 }
1962 
Serialize_TPM_CC(const TPM_CC & value,std::string * buffer)1963 TPM_RC Serialize_TPM_CC(const TPM_CC& value, std::string* buffer) {
1964   VLOG(3) << __func__;
1965   return Serialize_UINT32(value, buffer);
1966 }
1967 
Parse_TPM_CC(std::string * buffer,TPM_CC * value,std::string * value_bytes)1968 TPM_RC Parse_TPM_CC(std::string* buffer,
1969                     TPM_CC* value,
1970                     std::string* value_bytes) {
1971   VLOG(3) << __func__;
1972   return Parse_UINT32(buffer, value, value_bytes);
1973 }
1974 
Serialize_TPMA_CC(const TPMA_CC & value,std::string * buffer)1975 TPM_RC Serialize_TPMA_CC(const TPMA_CC& value, std::string* buffer) {
1976   VLOG(3) << __func__;
1977   return Serialize_TPM_CC(value, buffer);
1978 }
1979 
Parse_TPMA_CC(std::string * buffer,TPMA_CC * value,std::string * value_bytes)1980 TPM_RC Parse_TPMA_CC(std::string* buffer,
1981                      TPMA_CC* value,
1982                      std::string* value_bytes) {
1983   VLOG(3) << __func__;
1984   return Parse_TPM_CC(buffer, value, value_bytes);
1985 }
1986 
Serialize_TPM_NV_INDEX(const TPM_NV_INDEX & value,std::string * buffer)1987 TPM_RC Serialize_TPM_NV_INDEX(const TPM_NV_INDEX& value, std::string* buffer) {
1988   VLOG(3) << __func__;
1989   return Serialize_UINT32(value, buffer);
1990 }
1991 
Parse_TPM_NV_INDEX(std::string * buffer,TPM_NV_INDEX * value,std::string * value_bytes)1992 TPM_RC Parse_TPM_NV_INDEX(std::string* buffer,
1993                           TPM_NV_INDEX* value,
1994                           std::string* value_bytes) {
1995   VLOG(3) << __func__;
1996   return Parse_UINT32(buffer, value, value_bytes);
1997 }
1998 
Serialize_TPMA_NV(const TPMA_NV & value,std::string * buffer)1999 TPM_RC Serialize_TPMA_NV(const TPMA_NV& value, std::string* buffer) {
2000   VLOG(3) << __func__;
2001   return Serialize_UINT32(value, buffer);
2002 }
2003 
Parse_TPMA_NV(std::string * buffer,TPMA_NV * value,std::string * value_bytes)2004 TPM_RC Parse_TPMA_NV(std::string* buffer,
2005                      TPMA_NV* value,
2006                      std::string* value_bytes) {
2007   VLOG(3) << __func__;
2008   return Parse_UINT32(buffer, value, value_bytes);
2009 }
2010 
Serialize_TPM_SPEC(const TPM_SPEC & value,std::string * buffer)2011 TPM_RC Serialize_TPM_SPEC(const TPM_SPEC& value, std::string* buffer) {
2012   VLOG(3) << __func__;
2013   return Serialize_UINT32(value, buffer);
2014 }
2015 
Parse_TPM_SPEC(std::string * buffer,TPM_SPEC * value,std::string * value_bytes)2016 TPM_RC Parse_TPM_SPEC(std::string* buffer,
2017                       TPM_SPEC* value,
2018                       std::string* value_bytes) {
2019   VLOG(3) << __func__;
2020   return Parse_UINT32(buffer, value, value_bytes);
2021 }
2022 
Serialize_TPM_GENERATED(const TPM_GENERATED & value,std::string * buffer)2023 TPM_RC Serialize_TPM_GENERATED(const TPM_GENERATED& value,
2024                                std::string* buffer) {
2025   VLOG(3) << __func__;
2026   return Serialize_UINT32(value, buffer);
2027 }
2028 
Parse_TPM_GENERATED(std::string * buffer,TPM_GENERATED * value,std::string * value_bytes)2029 TPM_RC Parse_TPM_GENERATED(std::string* buffer,
2030                            TPM_GENERATED* value,
2031                            std::string* value_bytes) {
2032   VLOG(3) << __func__;
2033   return Parse_UINT32(buffer, value, value_bytes);
2034 }
2035 
Serialize_TPM_RC(const TPM_RC & value,std::string * buffer)2036 TPM_RC Serialize_TPM_RC(const TPM_RC& value, std::string* buffer) {
2037   VLOG(3) << __func__;
2038   return Serialize_UINT32(value, buffer);
2039 }
2040 
Parse_TPM_RC(std::string * buffer,TPM_RC * value,std::string * value_bytes)2041 TPM_RC Parse_TPM_RC(std::string* buffer,
2042                     TPM_RC* value,
2043                     std::string* value_bytes) {
2044   VLOG(3) << __func__;
2045   return Parse_UINT32(buffer, value, value_bytes);
2046 }
2047 
Serialize_TPM_CLOCK_ADJUST(const TPM_CLOCK_ADJUST & value,std::string * buffer)2048 TPM_RC Serialize_TPM_CLOCK_ADJUST(const TPM_CLOCK_ADJUST& value,
2049                                   std::string* buffer) {
2050   VLOG(3) << __func__;
2051   return Serialize_INT8(value, buffer);
2052 }
2053 
Parse_TPM_CLOCK_ADJUST(std::string * buffer,TPM_CLOCK_ADJUST * value,std::string * value_bytes)2054 TPM_RC Parse_TPM_CLOCK_ADJUST(std::string* buffer,
2055                               TPM_CLOCK_ADJUST* value,
2056                               std::string* value_bytes) {
2057   VLOG(3) << __func__;
2058   return Parse_INT8(buffer, value, value_bytes);
2059 }
2060 
Serialize_TPM_EO(const TPM_EO & value,std::string * buffer)2061 TPM_RC Serialize_TPM_EO(const TPM_EO& value, std::string* buffer) {
2062   VLOG(3) << __func__;
2063   return Serialize_UINT16(value, buffer);
2064 }
2065 
Parse_TPM_EO(std::string * buffer,TPM_EO * value,std::string * value_bytes)2066 TPM_RC Parse_TPM_EO(std::string* buffer,
2067                     TPM_EO* value,
2068                     std::string* value_bytes) {
2069   VLOG(3) << __func__;
2070   return Parse_UINT16(buffer, value, value_bytes);
2071 }
2072 
Serialize_TPM_SU(const TPM_SU & value,std::string * buffer)2073 TPM_RC Serialize_TPM_SU(const TPM_SU& value, std::string* buffer) {
2074   VLOG(3) << __func__;
2075   return Serialize_UINT16(value, buffer);
2076 }
2077 
Parse_TPM_SU(std::string * buffer,TPM_SU * value,std::string * value_bytes)2078 TPM_RC Parse_TPM_SU(std::string* buffer,
2079                     TPM_SU* value,
2080                     std::string* value_bytes) {
2081   VLOG(3) << __func__;
2082   return Parse_UINT16(buffer, value, value_bytes);
2083 }
2084 
Serialize_TPM_SE(const TPM_SE & value,std::string * buffer)2085 TPM_RC Serialize_TPM_SE(const TPM_SE& value, std::string* buffer) {
2086   VLOG(3) << __func__;
2087   return Serialize_UINT8(value, buffer);
2088 }
2089 
Parse_TPM_SE(std::string * buffer,TPM_SE * value,std::string * value_bytes)2090 TPM_RC Parse_TPM_SE(std::string* buffer,
2091                     TPM_SE* value,
2092                     std::string* value_bytes) {
2093   VLOG(3) << __func__;
2094   return Parse_UINT8(buffer, value, value_bytes);
2095 }
2096 
Serialize_TPM_CAP(const TPM_CAP & value,std::string * buffer)2097 TPM_RC Serialize_TPM_CAP(const TPM_CAP& value, std::string* buffer) {
2098   VLOG(3) << __func__;
2099   return Serialize_UINT32(value, buffer);
2100 }
2101 
Parse_TPM_CAP(std::string * buffer,TPM_CAP * value,std::string * value_bytes)2102 TPM_RC Parse_TPM_CAP(std::string* buffer,
2103                      TPM_CAP* value,
2104                      std::string* value_bytes) {
2105   VLOG(3) << __func__;
2106   return Parse_UINT32(buffer, value, value_bytes);
2107 }
2108 
Serialize_TPM_PT(const TPM_PT & value,std::string * buffer)2109 TPM_RC Serialize_TPM_PT(const TPM_PT& value, std::string* buffer) {
2110   VLOG(3) << __func__;
2111   return Serialize_UINT32(value, buffer);
2112 }
2113 
Parse_TPM_PT(std::string * buffer,TPM_PT * value,std::string * value_bytes)2114 TPM_RC Parse_TPM_PT(std::string* buffer,
2115                     TPM_PT* value,
2116                     std::string* value_bytes) {
2117   VLOG(3) << __func__;
2118   return Parse_UINT32(buffer, value, value_bytes);
2119 }
2120 
Serialize_TPM_PT_PCR(const TPM_PT_PCR & value,std::string * buffer)2121 TPM_RC Serialize_TPM_PT_PCR(const TPM_PT_PCR& value, std::string* buffer) {
2122   VLOG(3) << __func__;
2123   return Serialize_UINT32(value, buffer);
2124 }
2125 
Parse_TPM_PT_PCR(std::string * buffer,TPM_PT_PCR * value,std::string * value_bytes)2126 TPM_RC Parse_TPM_PT_PCR(std::string* buffer,
2127                         TPM_PT_PCR* value,
2128                         std::string* value_bytes) {
2129   VLOG(3) << __func__;
2130   return Parse_UINT32(buffer, value, value_bytes);
2131 }
2132 
Serialize_TPM_PS(const TPM_PS & value,std::string * buffer)2133 TPM_RC Serialize_TPM_PS(const TPM_PS& value, std::string* buffer) {
2134   VLOG(3) << __func__;
2135   return Serialize_UINT32(value, buffer);
2136 }
2137 
Parse_TPM_PS(std::string * buffer,TPM_PS * value,std::string * value_bytes)2138 TPM_RC Parse_TPM_PS(std::string* buffer,
2139                     TPM_PS* value,
2140                     std::string* value_bytes) {
2141   VLOG(3) << __func__;
2142   return Parse_UINT32(buffer, value, value_bytes);
2143 }
2144 
Serialize_TPM_HT(const TPM_HT & value,std::string * buffer)2145 TPM_RC Serialize_TPM_HT(const TPM_HT& value, std::string* buffer) {
2146   VLOG(3) << __func__;
2147   return Serialize_UINT8(value, buffer);
2148 }
2149 
Parse_TPM_HT(std::string * buffer,TPM_HT * value,std::string * value_bytes)2150 TPM_RC Parse_TPM_HT(std::string* buffer,
2151                     TPM_HT* value,
2152                     std::string* value_bytes) {
2153   VLOG(3) << __func__;
2154   return Parse_UINT8(buffer, value, value_bytes);
2155 }
2156 
Serialize_TPM_RH(const TPM_RH & value,std::string * buffer)2157 TPM_RC Serialize_TPM_RH(const TPM_RH& value, std::string* buffer) {
2158   VLOG(3) << __func__;
2159   return Serialize_UINT32(value, buffer);
2160 }
2161 
Parse_TPM_RH(std::string * buffer,TPM_RH * value,std::string * value_bytes)2162 TPM_RC Parse_TPM_RH(std::string* buffer,
2163                     TPM_RH* value,
2164                     std::string* value_bytes) {
2165   VLOG(3) << __func__;
2166   return Parse_UINT32(buffer, value, value_bytes);
2167 }
2168 
Serialize_TPM_HC(const TPM_HC & value,std::string * buffer)2169 TPM_RC Serialize_TPM_HC(const TPM_HC& value, std::string* buffer) {
2170   VLOG(3) << __func__;
2171   return Serialize_TPM_HANDLE(value, buffer);
2172 }
2173 
Parse_TPM_HC(std::string * buffer,TPM_HC * value,std::string * value_bytes)2174 TPM_RC Parse_TPM_HC(std::string* buffer,
2175                     TPM_HC* value,
2176                     std::string* value_bytes) {
2177   VLOG(3) << __func__;
2178   return Parse_TPM_HANDLE(buffer, value, value_bytes);
2179 }
2180 
Serialize_TPMS_ALGORITHM_DESCRIPTION(const TPMS_ALGORITHM_DESCRIPTION & value,std::string * buffer)2181 TPM_RC Serialize_TPMS_ALGORITHM_DESCRIPTION(
2182     const TPMS_ALGORITHM_DESCRIPTION& value, std::string* buffer) {
2183   TPM_RC result = TPM_RC_SUCCESS;
2184   VLOG(3) << __func__;
2185 
2186   result = Serialize_TPM_ALG_ID(value.alg, buffer);
2187   if (result) {
2188     return result;
2189   }
2190 
2191   result = Serialize_TPMA_ALGORITHM(value.attributes, buffer);
2192   if (result) {
2193     return result;
2194   }
2195   return result;
2196 }
2197 
Parse_TPMS_ALGORITHM_DESCRIPTION(std::string * buffer,TPMS_ALGORITHM_DESCRIPTION * value,std::string * value_bytes)2198 TPM_RC Parse_TPMS_ALGORITHM_DESCRIPTION(std::string* buffer,
2199                                         TPMS_ALGORITHM_DESCRIPTION* value,
2200                                         std::string* value_bytes) {
2201   TPM_RC result = TPM_RC_SUCCESS;
2202   VLOG(3) << __func__;
2203 
2204   result = Parse_TPM_ALG_ID(buffer, &value->alg, value_bytes);
2205   if (result) {
2206     return result;
2207   }
2208 
2209   result = Parse_TPMA_ALGORITHM(buffer, &value->attributes, value_bytes);
2210   if (result) {
2211     return result;
2212   }
2213   return result;
2214 }
2215 
Serialize_TPMU_HA(const TPMU_HA & value,TPMI_ALG_HASH selector,std::string * buffer)2216 TPM_RC Serialize_TPMU_HA(const TPMU_HA& value,
2217                          TPMI_ALG_HASH selector,
2218                          std::string* buffer) {
2219   TPM_RC result = TPM_RC_SUCCESS;
2220   VLOG(3) << __func__;
2221 
2222   if (selector == TPM_ALG_SHA384) {
2223     if (std::size(value.sha384) < SHA384_DIGEST_SIZE) {
2224       return TPM_RC_INSUFFICIENT;
2225     }
2226     for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) {
2227       result = Serialize_BYTE(value.sha384[i], buffer);
2228       if (result) {
2229         return result;
2230       }
2231     }
2232   }
2233 
2234   if (selector == TPM_ALG_SHA1) {
2235     if (std::size(value.sha1) < SHA1_DIGEST_SIZE) {
2236       return TPM_RC_INSUFFICIENT;
2237     }
2238     for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) {
2239       result = Serialize_BYTE(value.sha1[i], buffer);
2240       if (result) {
2241         return result;
2242       }
2243     }
2244   }
2245 
2246   if (selector == TPM_ALG_SM3_256) {
2247     if (std::size(value.sm3_256) < SM3_256_DIGEST_SIZE) {
2248       return TPM_RC_INSUFFICIENT;
2249     }
2250     for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) {
2251       result = Serialize_BYTE(value.sm3_256[i], buffer);
2252       if (result) {
2253         return result;
2254       }
2255     }
2256   }
2257 
2258   if (selector == TPM_ALG_NULL) {
2259     // Do nothing.
2260   }
2261 
2262   if (selector == TPM_ALG_SHA256) {
2263     if (std::size(value.sha256) < SHA256_DIGEST_SIZE) {
2264       return TPM_RC_INSUFFICIENT;
2265     }
2266     for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) {
2267       result = Serialize_BYTE(value.sha256[i], buffer);
2268       if (result) {
2269         return result;
2270       }
2271     }
2272   }
2273 
2274   if (selector == TPM_ALG_SHA512) {
2275     if (std::size(value.sha512) < SHA512_DIGEST_SIZE) {
2276       return TPM_RC_INSUFFICIENT;
2277     }
2278     for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) {
2279       result = Serialize_BYTE(value.sha512[i], buffer);
2280       if (result) {
2281         return result;
2282       }
2283     }
2284   }
2285   return result;
2286 }
2287 
Parse_TPMU_HA(std::string * buffer,TPMI_ALG_HASH selector,TPMU_HA * value,std::string * value_bytes)2288 TPM_RC Parse_TPMU_HA(std::string* buffer,
2289                      TPMI_ALG_HASH selector,
2290                      TPMU_HA* value,
2291                      std::string* value_bytes) {
2292   TPM_RC result = TPM_RC_SUCCESS;
2293   VLOG(3) << __func__;
2294 
2295   if (selector == TPM_ALG_SHA384) {
2296     if (std::size(value->sha384) < SHA384_DIGEST_SIZE) {
2297       return TPM_RC_INSUFFICIENT;
2298     }
2299     for (uint32_t i = 0; i < SHA384_DIGEST_SIZE; ++i) {
2300       result = Parse_BYTE(buffer, &value->sha384[i], value_bytes);
2301       if (result) {
2302         return result;
2303       }
2304     }
2305   }
2306 
2307   if (selector == TPM_ALG_SHA1) {
2308     if (std::size(value->sha1) < SHA1_DIGEST_SIZE) {
2309       return TPM_RC_INSUFFICIENT;
2310     }
2311     for (uint32_t i = 0; i < SHA1_DIGEST_SIZE; ++i) {
2312       result = Parse_BYTE(buffer, &value->sha1[i], value_bytes);
2313       if (result) {
2314         return result;
2315       }
2316     }
2317   }
2318 
2319   if (selector == TPM_ALG_SM3_256) {
2320     if (std::size(value->sm3_256) < SM3_256_DIGEST_SIZE) {
2321       return TPM_RC_INSUFFICIENT;
2322     }
2323     for (uint32_t i = 0; i < SM3_256_DIGEST_SIZE; ++i) {
2324       result = Parse_BYTE(buffer, &value->sm3_256[i], value_bytes);
2325       if (result) {
2326         return result;
2327       }
2328     }
2329   }
2330 
2331   if (selector == TPM_ALG_NULL) {
2332     // Do nothing.
2333   }
2334 
2335   if (selector == TPM_ALG_SHA256) {
2336     if (std::size(value->sha256) < SHA256_DIGEST_SIZE) {
2337       return TPM_RC_INSUFFICIENT;
2338     }
2339     for (uint32_t i = 0; i < SHA256_DIGEST_SIZE; ++i) {
2340       result = Parse_BYTE(buffer, &value->sha256[i], value_bytes);
2341       if (result) {
2342         return result;
2343       }
2344     }
2345   }
2346 
2347   if (selector == TPM_ALG_SHA512) {
2348     if (std::size(value->sha512) < SHA512_DIGEST_SIZE) {
2349       return TPM_RC_INSUFFICIENT;
2350     }
2351     for (uint32_t i = 0; i < SHA512_DIGEST_SIZE; ++i) {
2352       result = Parse_BYTE(buffer, &value->sha512[i], value_bytes);
2353       if (result) {
2354         return result;
2355       }
2356     }
2357   }
2358   return result;
2359 }
2360 
Serialize_TPMT_HA(const TPMT_HA & value,std::string * buffer)2361 TPM_RC Serialize_TPMT_HA(const TPMT_HA& value, std::string* buffer) {
2362   TPM_RC result = TPM_RC_SUCCESS;
2363   VLOG(3) << __func__;
2364 
2365   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
2366   if (result) {
2367     return result;
2368   }
2369 
2370   result = Serialize_TPMU_HA(value.digest, value.hash_alg, buffer);
2371   if (result) {
2372     return result;
2373   }
2374   return result;
2375 }
2376 
Parse_TPMT_HA(std::string * buffer,TPMT_HA * value,std::string * value_bytes)2377 TPM_RC Parse_TPMT_HA(std::string* buffer,
2378                      TPMT_HA* value,
2379                      std::string* value_bytes) {
2380   TPM_RC result = TPM_RC_SUCCESS;
2381   VLOG(3) << __func__;
2382 
2383   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
2384   if (result) {
2385     return result;
2386   }
2387 
2388   result = Parse_TPMU_HA(buffer, value->hash_alg, &value->digest, value_bytes);
2389   if (result) {
2390     return result;
2391   }
2392   return result;
2393 }
2394 
Serialize_TPM2B_DATA(const TPM2B_DATA & value,std::string * buffer)2395 TPM_RC Serialize_TPM2B_DATA(const TPM2B_DATA& value, std::string* buffer) {
2396   TPM_RC result = TPM_RC_SUCCESS;
2397   VLOG(3) << __func__;
2398 
2399   result = Serialize_UINT16(value.size, buffer);
2400   if (result) {
2401     return result;
2402   }
2403 
2404   if (std::size(value.buffer) < value.size) {
2405     return TPM_RC_INSUFFICIENT;
2406   }
2407   for (uint32_t i = 0; i < value.size; ++i) {
2408     result = Serialize_BYTE(value.buffer[i], buffer);
2409     if (result) {
2410       return result;
2411     }
2412   }
2413   return result;
2414 }
2415 
Parse_TPM2B_DATA(std::string * buffer,TPM2B_DATA * value,std::string * value_bytes)2416 TPM_RC Parse_TPM2B_DATA(std::string* buffer,
2417                         TPM2B_DATA* value,
2418                         std::string* value_bytes) {
2419   TPM_RC result = TPM_RC_SUCCESS;
2420   VLOG(3) << __func__;
2421 
2422   result = Parse_UINT16(buffer, &value->size, value_bytes);
2423   if (result) {
2424     return result;
2425   }
2426 
2427   if (std::size(value->buffer) < value->size) {
2428     return TPM_RC_INSUFFICIENT;
2429   }
2430   for (uint32_t i = 0; i < value->size; ++i) {
2431     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2432     if (result) {
2433       return result;
2434     }
2435   }
2436   return result;
2437 }
2438 
Make_TPM2B_DATA(const std::string & bytes)2439 TPM2B_DATA Make_TPM2B_DATA(const std::string& bytes) {
2440   TPM2B_DATA tpm2b;
2441   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2442   memset(&tpm2b, 0, sizeof(TPM2B_DATA));
2443   tpm2b.size = bytes.size();
2444   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2445   return tpm2b;
2446 }
2447 
StringFrom_TPM2B_DATA(const TPM2B_DATA & tpm2b)2448 std::string StringFrom_TPM2B_DATA(const TPM2B_DATA& tpm2b) {
2449   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2450   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2451   return std::string(char_buffer, tpm2b.size);
2452 }
2453 
Serialize_TPM2B_EVENT(const TPM2B_EVENT & value,std::string * buffer)2454 TPM_RC Serialize_TPM2B_EVENT(const TPM2B_EVENT& value, std::string* buffer) {
2455   TPM_RC result = TPM_RC_SUCCESS;
2456   VLOG(3) << __func__;
2457 
2458   result = Serialize_UINT16(value.size, buffer);
2459   if (result) {
2460     return result;
2461   }
2462 
2463   if (std::size(value.buffer) < value.size) {
2464     return TPM_RC_INSUFFICIENT;
2465   }
2466   for (uint32_t i = 0; i < value.size; ++i) {
2467     result = Serialize_BYTE(value.buffer[i], buffer);
2468     if (result) {
2469       return result;
2470     }
2471   }
2472   return result;
2473 }
2474 
Parse_TPM2B_EVENT(std::string * buffer,TPM2B_EVENT * value,std::string * value_bytes)2475 TPM_RC Parse_TPM2B_EVENT(std::string* buffer,
2476                          TPM2B_EVENT* value,
2477                          std::string* value_bytes) {
2478   TPM_RC result = TPM_RC_SUCCESS;
2479   VLOG(3) << __func__;
2480 
2481   result = Parse_UINT16(buffer, &value->size, value_bytes);
2482   if (result) {
2483     return result;
2484   }
2485 
2486   if (std::size(value->buffer) < value->size) {
2487     return TPM_RC_INSUFFICIENT;
2488   }
2489   for (uint32_t i = 0; i < value->size; ++i) {
2490     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2491     if (result) {
2492       return result;
2493     }
2494   }
2495   return result;
2496 }
2497 
Make_TPM2B_EVENT(const std::string & bytes)2498 TPM2B_EVENT Make_TPM2B_EVENT(const std::string& bytes) {
2499   TPM2B_EVENT tpm2b;
2500   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2501   memset(&tpm2b, 0, sizeof(TPM2B_EVENT));
2502   tpm2b.size = bytes.size();
2503   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2504   return tpm2b;
2505 }
2506 
StringFrom_TPM2B_EVENT(const TPM2B_EVENT & tpm2b)2507 std::string StringFrom_TPM2B_EVENT(const TPM2B_EVENT& tpm2b) {
2508   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2509   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2510   return std::string(char_buffer, tpm2b.size);
2511 }
2512 
Serialize_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER & value,std::string * buffer)2513 TPM_RC Serialize_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER& value,
2514                                   std::string* buffer) {
2515   TPM_RC result = TPM_RC_SUCCESS;
2516   VLOG(3) << __func__;
2517 
2518   result = Serialize_UINT16(value.size, buffer);
2519   if (result) {
2520     return result;
2521   }
2522 
2523   if (std::size(value.buffer) < value.size) {
2524     return TPM_RC_INSUFFICIENT;
2525   }
2526   for (uint32_t i = 0; i < value.size; ++i) {
2527     result = Serialize_BYTE(value.buffer[i], buffer);
2528     if (result) {
2529       return result;
2530     }
2531   }
2532   return result;
2533 }
2534 
Parse_TPM2B_MAX_BUFFER(std::string * buffer,TPM2B_MAX_BUFFER * value,std::string * value_bytes)2535 TPM_RC Parse_TPM2B_MAX_BUFFER(std::string* buffer,
2536                               TPM2B_MAX_BUFFER* value,
2537                               std::string* value_bytes) {
2538   TPM_RC result = TPM_RC_SUCCESS;
2539   VLOG(3) << __func__;
2540 
2541   result = Parse_UINT16(buffer, &value->size, value_bytes);
2542   if (result) {
2543     return result;
2544   }
2545 
2546   if (std::size(value->buffer) < value->size) {
2547     return TPM_RC_INSUFFICIENT;
2548   }
2549   for (uint32_t i = 0; i < value->size; ++i) {
2550     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2551     if (result) {
2552       return result;
2553     }
2554   }
2555   return result;
2556 }
2557 
Make_TPM2B_MAX_BUFFER(const std::string & bytes)2558 TPM2B_MAX_BUFFER Make_TPM2B_MAX_BUFFER(const std::string& bytes) {
2559   TPM2B_MAX_BUFFER tpm2b;
2560   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2561   memset(&tpm2b, 0, sizeof(TPM2B_MAX_BUFFER));
2562   tpm2b.size = bytes.size();
2563   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2564   return tpm2b;
2565 }
2566 
StringFrom_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER & tpm2b)2567 std::string StringFrom_TPM2B_MAX_BUFFER(const TPM2B_MAX_BUFFER& tpm2b) {
2568   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2569   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2570   return std::string(char_buffer, tpm2b.size);
2571 }
2572 
Serialize_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER & value,std::string * buffer)2573 TPM_RC Serialize_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER& value,
2574                                      std::string* buffer) {
2575   TPM_RC result = TPM_RC_SUCCESS;
2576   VLOG(3) << __func__;
2577 
2578   result = Serialize_UINT16(value.size, buffer);
2579   if (result) {
2580     return result;
2581   }
2582 
2583   if (std::size(value.buffer) < value.size) {
2584     return TPM_RC_INSUFFICIENT;
2585   }
2586   for (uint32_t i = 0; i < value.size; ++i) {
2587     result = Serialize_BYTE(value.buffer[i], buffer);
2588     if (result) {
2589       return result;
2590     }
2591   }
2592   return result;
2593 }
2594 
Parse_TPM2B_MAX_NV_BUFFER(std::string * buffer,TPM2B_MAX_NV_BUFFER * value,std::string * value_bytes)2595 TPM_RC Parse_TPM2B_MAX_NV_BUFFER(std::string* buffer,
2596                                  TPM2B_MAX_NV_BUFFER* value,
2597                                  std::string* value_bytes) {
2598   TPM_RC result = TPM_RC_SUCCESS;
2599   VLOG(3) << __func__;
2600 
2601   result = Parse_UINT16(buffer, &value->size, value_bytes);
2602   if (result) {
2603     return result;
2604   }
2605 
2606   if (std::size(value->buffer) < value->size) {
2607     return TPM_RC_INSUFFICIENT;
2608   }
2609   for (uint32_t i = 0; i < value->size; ++i) {
2610     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2611     if (result) {
2612       return result;
2613     }
2614   }
2615   return result;
2616 }
2617 
Make_TPM2B_MAX_NV_BUFFER(const std::string & bytes)2618 TPM2B_MAX_NV_BUFFER Make_TPM2B_MAX_NV_BUFFER(const std::string& bytes) {
2619   TPM2B_MAX_NV_BUFFER tpm2b;
2620   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2621   memset(&tpm2b, 0, sizeof(TPM2B_MAX_NV_BUFFER));
2622   tpm2b.size = bytes.size();
2623   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2624   return tpm2b;
2625 }
2626 
StringFrom_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER & tpm2b)2627 std::string StringFrom_TPM2B_MAX_NV_BUFFER(const TPM2B_MAX_NV_BUFFER& tpm2b) {
2628   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2629   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2630   return std::string(char_buffer, tpm2b.size);
2631 }
2632 
Serialize_TPM2B_TIMEOUT(const TPM2B_TIMEOUT & value,std::string * buffer)2633 TPM_RC Serialize_TPM2B_TIMEOUT(const TPM2B_TIMEOUT& value,
2634                                std::string* buffer) {
2635   TPM_RC result = TPM_RC_SUCCESS;
2636   VLOG(3) << __func__;
2637 
2638   result = Serialize_UINT16(value.size, buffer);
2639   if (result) {
2640     return result;
2641   }
2642 
2643   if (std::size(value.buffer) < value.size) {
2644     return TPM_RC_INSUFFICIENT;
2645   }
2646   for (uint32_t i = 0; i < value.size; ++i) {
2647     result = Serialize_BYTE(value.buffer[i], buffer);
2648     if (result) {
2649       return result;
2650     }
2651   }
2652   return result;
2653 }
2654 
Parse_TPM2B_TIMEOUT(std::string * buffer,TPM2B_TIMEOUT * value,std::string * value_bytes)2655 TPM_RC Parse_TPM2B_TIMEOUT(std::string* buffer,
2656                            TPM2B_TIMEOUT* value,
2657                            std::string* value_bytes) {
2658   TPM_RC result = TPM_RC_SUCCESS;
2659   VLOG(3) << __func__;
2660 
2661   result = Parse_UINT16(buffer, &value->size, value_bytes);
2662   if (result) {
2663     return result;
2664   }
2665 
2666   if (std::size(value->buffer) < value->size) {
2667     return TPM_RC_INSUFFICIENT;
2668   }
2669   for (uint32_t i = 0; i < value->size; ++i) {
2670     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2671     if (result) {
2672       return result;
2673     }
2674   }
2675   return result;
2676 }
2677 
Make_TPM2B_TIMEOUT(const std::string & bytes)2678 TPM2B_TIMEOUT Make_TPM2B_TIMEOUT(const std::string& bytes) {
2679   TPM2B_TIMEOUT tpm2b;
2680   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2681   memset(&tpm2b, 0, sizeof(TPM2B_TIMEOUT));
2682   tpm2b.size = bytes.size();
2683   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2684   return tpm2b;
2685 }
2686 
StringFrom_TPM2B_TIMEOUT(const TPM2B_TIMEOUT & tpm2b)2687 std::string StringFrom_TPM2B_TIMEOUT(const TPM2B_TIMEOUT& tpm2b) {
2688   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2689   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2690   return std::string(char_buffer, tpm2b.size);
2691 }
2692 
Serialize_TPM2B_IV(const TPM2B_IV & value,std::string * buffer)2693 TPM_RC Serialize_TPM2B_IV(const TPM2B_IV& value, std::string* buffer) {
2694   TPM_RC result = TPM_RC_SUCCESS;
2695   VLOG(3) << __func__;
2696 
2697   result = Serialize_UINT16(value.size, buffer);
2698   if (result) {
2699     return result;
2700   }
2701 
2702   if (std::size(value.buffer) < value.size) {
2703     return TPM_RC_INSUFFICIENT;
2704   }
2705   for (uint32_t i = 0; i < value.size; ++i) {
2706     result = Serialize_BYTE(value.buffer[i], buffer);
2707     if (result) {
2708       return result;
2709     }
2710   }
2711   return result;
2712 }
2713 
Parse_TPM2B_IV(std::string * buffer,TPM2B_IV * value,std::string * value_bytes)2714 TPM_RC Parse_TPM2B_IV(std::string* buffer,
2715                       TPM2B_IV* value,
2716                       std::string* value_bytes) {
2717   TPM_RC result = TPM_RC_SUCCESS;
2718   VLOG(3) << __func__;
2719 
2720   result = Parse_UINT16(buffer, &value->size, value_bytes);
2721   if (result) {
2722     return result;
2723   }
2724 
2725   if (std::size(value->buffer) < value->size) {
2726     return TPM_RC_INSUFFICIENT;
2727   }
2728   for (uint32_t i = 0; i < value->size; ++i) {
2729     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
2730     if (result) {
2731       return result;
2732     }
2733   }
2734   return result;
2735 }
2736 
Make_TPM2B_IV(const std::string & bytes)2737 TPM2B_IV Make_TPM2B_IV(const std::string& bytes) {
2738   TPM2B_IV tpm2b;
2739   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
2740   memset(&tpm2b, 0, sizeof(TPM2B_IV));
2741   tpm2b.size = bytes.size();
2742   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
2743   return tpm2b;
2744 }
2745 
StringFrom_TPM2B_IV(const TPM2B_IV & tpm2b)2746 std::string StringFrom_TPM2B_IV(const TPM2B_IV& tpm2b) {
2747   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
2748   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
2749   return std::string(char_buffer, tpm2b.size);
2750 }
2751 
Serialize_TPM2B_NAME(const TPM2B_NAME & value,std::string * buffer)2752 TPM_RC Serialize_TPM2B_NAME(const TPM2B_NAME& value, std::string* buffer) {
2753   TPM_RC result = TPM_RC_SUCCESS;
2754   VLOG(3) << __func__;
2755 
2756   result = Serialize_UINT16(value.size, buffer);
2757   if (result) {
2758     return result;
2759   }
2760 
2761   if (std::size(value.name) < value.size) {
2762     return TPM_RC_INSUFFICIENT;
2763   }
2764   for (uint32_t i = 0; i < value.size; ++i) {
2765     result = Serialize_BYTE(value.name[i], buffer);
2766     if (result) {
2767       return result;
2768     }
2769   }
2770   return result;
2771 }
2772 
Parse_TPM2B_NAME(std::string * buffer,TPM2B_NAME * value,std::string * value_bytes)2773 TPM_RC Parse_TPM2B_NAME(std::string* buffer,
2774                         TPM2B_NAME* value,
2775                         std::string* value_bytes) {
2776   TPM_RC result = TPM_RC_SUCCESS;
2777   VLOG(3) << __func__;
2778 
2779   result = Parse_UINT16(buffer, &value->size, value_bytes);
2780   if (result) {
2781     return result;
2782   }
2783 
2784   if (std::size(value->name) < value->size) {
2785     return TPM_RC_INSUFFICIENT;
2786   }
2787   for (uint32_t i = 0; i < value->size; ++i) {
2788     result = Parse_BYTE(buffer, &value->name[i], value_bytes);
2789     if (result) {
2790       return result;
2791     }
2792   }
2793   return result;
2794 }
2795 
Make_TPM2B_NAME(const std::string & bytes)2796 TPM2B_NAME Make_TPM2B_NAME(const std::string& bytes) {
2797   TPM2B_NAME tpm2b;
2798   CHECK(bytes.size() <= sizeof(tpm2b.name));
2799   memset(&tpm2b, 0, sizeof(TPM2B_NAME));
2800   tpm2b.size = bytes.size();
2801   memcpy(tpm2b.name, bytes.data(), bytes.size());
2802   return tpm2b;
2803 }
2804 
StringFrom_TPM2B_NAME(const TPM2B_NAME & tpm2b)2805 std::string StringFrom_TPM2B_NAME(const TPM2B_NAME& tpm2b) {
2806   CHECK(tpm2b.size <= std::size(tpm2b.name));
2807   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.name);
2808   return std::string(char_buffer, tpm2b.size);
2809 }
2810 
Serialize_TPMS_PCR_SELECT(const TPMS_PCR_SELECT & value,std::string * buffer)2811 TPM_RC Serialize_TPMS_PCR_SELECT(const TPMS_PCR_SELECT& value,
2812                                  std::string* buffer) {
2813   TPM_RC result = TPM_RC_SUCCESS;
2814   VLOG(3) << __func__;
2815 
2816   result = Serialize_UINT8(value.sizeof_select, buffer);
2817   if (result) {
2818     return result;
2819   }
2820 
2821   if (std::size(value.pcr_select) < value.sizeof_select) {
2822     return TPM_RC_INSUFFICIENT;
2823   }
2824   for (uint32_t i = 0; i < value.sizeof_select; ++i) {
2825     result = Serialize_BYTE(value.pcr_select[i], buffer);
2826     if (result) {
2827       return result;
2828     }
2829   }
2830   return result;
2831 }
2832 
Parse_TPMS_PCR_SELECT(std::string * buffer,TPMS_PCR_SELECT * value,std::string * value_bytes)2833 TPM_RC Parse_TPMS_PCR_SELECT(std::string* buffer,
2834                              TPMS_PCR_SELECT* value,
2835                              std::string* value_bytes) {
2836   TPM_RC result = TPM_RC_SUCCESS;
2837   VLOG(3) << __func__;
2838 
2839   result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
2840   if (result) {
2841     return result;
2842   }
2843 
2844   if (std::size(value->pcr_select) < value->sizeof_select) {
2845     return TPM_RC_INSUFFICIENT;
2846   }
2847   for (uint32_t i = 0; i < value->sizeof_select; ++i) {
2848     result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
2849     if (result) {
2850       return result;
2851     }
2852   }
2853   return result;
2854 }
2855 
Serialize_TPMS_PCR_SELECTION(const TPMS_PCR_SELECTION & value,std::string * buffer)2856 TPM_RC Serialize_TPMS_PCR_SELECTION(const TPMS_PCR_SELECTION& value,
2857                                     std::string* buffer) {
2858   TPM_RC result = TPM_RC_SUCCESS;
2859   VLOG(3) << __func__;
2860 
2861   result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
2862   if (result) {
2863     return result;
2864   }
2865 
2866   result = Serialize_UINT8(value.sizeof_select, buffer);
2867   if (result) {
2868     return result;
2869   }
2870 
2871   if (std::size(value.pcr_select) < value.sizeof_select) {
2872     return TPM_RC_INSUFFICIENT;
2873   }
2874   for (uint32_t i = 0; i < value.sizeof_select; ++i) {
2875     result = Serialize_BYTE(value.pcr_select[i], buffer);
2876     if (result) {
2877       return result;
2878     }
2879   }
2880   return result;
2881 }
2882 
Parse_TPMS_PCR_SELECTION(std::string * buffer,TPMS_PCR_SELECTION * value,std::string * value_bytes)2883 TPM_RC Parse_TPMS_PCR_SELECTION(std::string* buffer,
2884                                 TPMS_PCR_SELECTION* value,
2885                                 std::string* value_bytes) {
2886   TPM_RC result = TPM_RC_SUCCESS;
2887   VLOG(3) << __func__;
2888 
2889   result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
2890   if (result) {
2891     return result;
2892   }
2893 
2894   result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
2895   if (result) {
2896     return result;
2897   }
2898 
2899   if (std::size(value->pcr_select) < value->sizeof_select) {
2900     return TPM_RC_INSUFFICIENT;
2901   }
2902   for (uint32_t i = 0; i < value->sizeof_select; ++i) {
2903     result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
2904     if (result) {
2905       return result;
2906     }
2907   }
2908   return result;
2909 }
2910 
Serialize_TPMT_TK_CREATION(const TPMT_TK_CREATION & value,std::string * buffer)2911 TPM_RC Serialize_TPMT_TK_CREATION(const TPMT_TK_CREATION& value,
2912                                   std::string* buffer) {
2913   TPM_RC result = TPM_RC_SUCCESS;
2914   VLOG(3) << __func__;
2915 
2916   result = Serialize_TPM_ST(value.tag, buffer);
2917   if (result) {
2918     return result;
2919   }
2920 
2921   result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
2922   if (result) {
2923     return result;
2924   }
2925 
2926   result = Serialize_TPM2B_DIGEST(value.digest, buffer);
2927   if (result) {
2928     return result;
2929   }
2930   return result;
2931 }
2932 
Parse_TPMT_TK_CREATION(std::string * buffer,TPMT_TK_CREATION * value,std::string * value_bytes)2933 TPM_RC Parse_TPMT_TK_CREATION(std::string* buffer,
2934                               TPMT_TK_CREATION* value,
2935                               std::string* value_bytes) {
2936   TPM_RC result = TPM_RC_SUCCESS;
2937   VLOG(3) << __func__;
2938 
2939   result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
2940   if (result) {
2941     return result;
2942   }
2943 
2944   result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
2945   if (result) {
2946     return result;
2947   }
2948 
2949   result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
2950   if (result) {
2951     return result;
2952   }
2953   return result;
2954 }
2955 
Serialize_TPMT_TK_VERIFIED(const TPMT_TK_VERIFIED & value,std::string * buffer)2956 TPM_RC Serialize_TPMT_TK_VERIFIED(const TPMT_TK_VERIFIED& value,
2957                                   std::string* buffer) {
2958   TPM_RC result = TPM_RC_SUCCESS;
2959   VLOG(3) << __func__;
2960 
2961   result = Serialize_TPM_ST(value.tag, buffer);
2962   if (result) {
2963     return result;
2964   }
2965 
2966   result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
2967   if (result) {
2968     return result;
2969   }
2970 
2971   result = Serialize_TPM2B_DIGEST(value.digest, buffer);
2972   if (result) {
2973     return result;
2974   }
2975   return result;
2976 }
2977 
Parse_TPMT_TK_VERIFIED(std::string * buffer,TPMT_TK_VERIFIED * value,std::string * value_bytes)2978 TPM_RC Parse_TPMT_TK_VERIFIED(std::string* buffer,
2979                               TPMT_TK_VERIFIED* value,
2980                               std::string* value_bytes) {
2981   TPM_RC result = TPM_RC_SUCCESS;
2982   VLOG(3) << __func__;
2983 
2984   result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
2985   if (result) {
2986     return result;
2987   }
2988 
2989   result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
2990   if (result) {
2991     return result;
2992   }
2993 
2994   result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
2995   if (result) {
2996     return result;
2997   }
2998   return result;
2999 }
3000 
Serialize_TPMT_TK_AUTH(const TPMT_TK_AUTH & value,std::string * buffer)3001 TPM_RC Serialize_TPMT_TK_AUTH(const TPMT_TK_AUTH& value, std::string* buffer) {
3002   TPM_RC result = TPM_RC_SUCCESS;
3003   VLOG(3) << __func__;
3004 
3005   result = Serialize_TPM_ST(value.tag, buffer);
3006   if (result) {
3007     return result;
3008   }
3009 
3010   result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
3011   if (result) {
3012     return result;
3013   }
3014 
3015   result = Serialize_TPM2B_DIGEST(value.digest, buffer);
3016   if (result) {
3017     return result;
3018   }
3019   return result;
3020 }
3021 
Parse_TPMT_TK_AUTH(std::string * buffer,TPMT_TK_AUTH * value,std::string * value_bytes)3022 TPM_RC Parse_TPMT_TK_AUTH(std::string* buffer,
3023                           TPMT_TK_AUTH* value,
3024                           std::string* value_bytes) {
3025   TPM_RC result = TPM_RC_SUCCESS;
3026   VLOG(3) << __func__;
3027 
3028   result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
3029   if (result) {
3030     return result;
3031   }
3032 
3033   result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
3034   if (result) {
3035     return result;
3036   }
3037 
3038   result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
3039   if (result) {
3040     return result;
3041   }
3042   return result;
3043 }
3044 
Serialize_TPMT_TK_HASHCHECK(const TPMT_TK_HASHCHECK & value,std::string * buffer)3045 TPM_RC Serialize_TPMT_TK_HASHCHECK(const TPMT_TK_HASHCHECK& value,
3046                                    std::string* buffer) {
3047   TPM_RC result = TPM_RC_SUCCESS;
3048   VLOG(3) << __func__;
3049 
3050   result = Serialize_TPM_ST(value.tag, buffer);
3051   if (result) {
3052     return result;
3053   }
3054 
3055   result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
3056   if (result) {
3057     return result;
3058   }
3059 
3060   result = Serialize_TPM2B_DIGEST(value.digest, buffer);
3061   if (result) {
3062     return result;
3063   }
3064   return result;
3065 }
3066 
Parse_TPMT_TK_HASHCHECK(std::string * buffer,TPMT_TK_HASHCHECK * value,std::string * value_bytes)3067 TPM_RC Parse_TPMT_TK_HASHCHECK(std::string* buffer,
3068                                TPMT_TK_HASHCHECK* value,
3069                                std::string* value_bytes) {
3070   TPM_RC result = TPM_RC_SUCCESS;
3071   VLOG(3) << __func__;
3072 
3073   result = Parse_TPM_ST(buffer, &value->tag, value_bytes);
3074   if (result) {
3075     return result;
3076   }
3077 
3078   result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
3079   if (result) {
3080     return result;
3081   }
3082 
3083   result = Parse_TPM2B_DIGEST(buffer, &value->digest, value_bytes);
3084   if (result) {
3085     return result;
3086   }
3087   return result;
3088 }
3089 
Serialize_TPMS_ALG_PROPERTY(const TPMS_ALG_PROPERTY & value,std::string * buffer)3090 TPM_RC Serialize_TPMS_ALG_PROPERTY(const TPMS_ALG_PROPERTY& value,
3091                                    std::string* buffer) {
3092   TPM_RC result = TPM_RC_SUCCESS;
3093   VLOG(3) << __func__;
3094 
3095   result = Serialize_TPM_ALG_ID(value.alg, buffer);
3096   if (result) {
3097     return result;
3098   }
3099 
3100   result = Serialize_TPMA_ALGORITHM(value.alg_properties, buffer);
3101   if (result) {
3102     return result;
3103   }
3104   return result;
3105 }
3106 
Parse_TPMS_ALG_PROPERTY(std::string * buffer,TPMS_ALG_PROPERTY * value,std::string * value_bytes)3107 TPM_RC Parse_TPMS_ALG_PROPERTY(std::string* buffer,
3108                                TPMS_ALG_PROPERTY* value,
3109                                std::string* value_bytes) {
3110   TPM_RC result = TPM_RC_SUCCESS;
3111   VLOG(3) << __func__;
3112 
3113   result = Parse_TPM_ALG_ID(buffer, &value->alg, value_bytes);
3114   if (result) {
3115     return result;
3116   }
3117 
3118   result = Parse_TPMA_ALGORITHM(buffer, &value->alg_properties, value_bytes);
3119   if (result) {
3120     return result;
3121   }
3122   return result;
3123 }
3124 
Serialize_TPMS_TAGGED_PROPERTY(const TPMS_TAGGED_PROPERTY & value,std::string * buffer)3125 TPM_RC Serialize_TPMS_TAGGED_PROPERTY(const TPMS_TAGGED_PROPERTY& value,
3126                                       std::string* buffer) {
3127   TPM_RC result = TPM_RC_SUCCESS;
3128   VLOG(3) << __func__;
3129 
3130   result = Serialize_TPM_PT(value.property, buffer);
3131   if (result) {
3132     return result;
3133   }
3134 
3135   result = Serialize_UINT32(value.value, buffer);
3136   if (result) {
3137     return result;
3138   }
3139   return result;
3140 }
3141 
Parse_TPMS_TAGGED_PROPERTY(std::string * buffer,TPMS_TAGGED_PROPERTY * value,std::string * value_bytes)3142 TPM_RC Parse_TPMS_TAGGED_PROPERTY(std::string* buffer,
3143                                   TPMS_TAGGED_PROPERTY* value,
3144                                   std::string* value_bytes) {
3145   TPM_RC result = TPM_RC_SUCCESS;
3146   VLOG(3) << __func__;
3147 
3148   result = Parse_TPM_PT(buffer, &value->property, value_bytes);
3149   if (result) {
3150     return result;
3151   }
3152 
3153   result = Parse_UINT32(buffer, &value->value, value_bytes);
3154   if (result) {
3155     return result;
3156   }
3157   return result;
3158 }
3159 
Serialize_TPMS_TAGGED_PCR_SELECT(const TPMS_TAGGED_PCR_SELECT & value,std::string * buffer)3160 TPM_RC Serialize_TPMS_TAGGED_PCR_SELECT(const TPMS_TAGGED_PCR_SELECT& value,
3161                                         std::string* buffer) {
3162   TPM_RC result = TPM_RC_SUCCESS;
3163   VLOG(3) << __func__;
3164 
3165   result = Serialize_TPM_PT(value.tag, buffer);
3166   if (result) {
3167     return result;
3168   }
3169 
3170   result = Serialize_UINT8(value.sizeof_select, buffer);
3171   if (result) {
3172     return result;
3173   }
3174 
3175   if (std::size(value.pcr_select) < value.sizeof_select) {
3176     return TPM_RC_INSUFFICIENT;
3177   }
3178   for (uint32_t i = 0; i < value.sizeof_select; ++i) {
3179     result = Serialize_BYTE(value.pcr_select[i], buffer);
3180     if (result) {
3181       return result;
3182     }
3183   }
3184   return result;
3185 }
3186 
Parse_TPMS_TAGGED_PCR_SELECT(std::string * buffer,TPMS_TAGGED_PCR_SELECT * value,std::string * value_bytes)3187 TPM_RC Parse_TPMS_TAGGED_PCR_SELECT(std::string* buffer,
3188                                     TPMS_TAGGED_PCR_SELECT* value,
3189                                     std::string* value_bytes) {
3190   TPM_RC result = TPM_RC_SUCCESS;
3191   VLOG(3) << __func__;
3192 
3193   result = Parse_TPM_PT(buffer, &value->tag, value_bytes);
3194   if (result) {
3195     return result;
3196   }
3197 
3198   result = Parse_UINT8(buffer, &value->sizeof_select, value_bytes);
3199   if (result) {
3200     return result;
3201   }
3202 
3203   if (std::size(value->pcr_select) < value->sizeof_select) {
3204     return TPM_RC_INSUFFICIENT;
3205   }
3206   for (uint32_t i = 0; i < value->sizeof_select; ++i) {
3207     result = Parse_BYTE(buffer, &value->pcr_select[i], value_bytes);
3208     if (result) {
3209       return result;
3210     }
3211   }
3212   return result;
3213 }
3214 
Serialize_TPML_CC(const TPML_CC & value,std::string * buffer)3215 TPM_RC Serialize_TPML_CC(const TPML_CC& value, std::string* buffer) {
3216   TPM_RC result = TPM_RC_SUCCESS;
3217   VLOG(3) << __func__;
3218 
3219   result = Serialize_UINT32(value.count, buffer);
3220   if (result) {
3221     return result;
3222   }
3223 
3224   if (std::size(value.command_codes) < value.count) {
3225     return TPM_RC_INSUFFICIENT;
3226   }
3227   for (uint32_t i = 0; i < value.count; ++i) {
3228     result = Serialize_TPM_CC(value.command_codes[i], buffer);
3229     if (result) {
3230       return result;
3231     }
3232   }
3233   return result;
3234 }
3235 
Parse_TPML_CC(std::string * buffer,TPML_CC * value,std::string * value_bytes)3236 TPM_RC Parse_TPML_CC(std::string* buffer,
3237                      TPML_CC* value,
3238                      std::string* value_bytes) {
3239   TPM_RC result = TPM_RC_SUCCESS;
3240   VLOG(3) << __func__;
3241 
3242   result = Parse_UINT32(buffer, &value->count, value_bytes);
3243   if (result) {
3244     return result;
3245   }
3246 
3247   if (std::size(value->command_codes) < value->count) {
3248     return TPM_RC_INSUFFICIENT;
3249   }
3250   for (uint32_t i = 0; i < value->count; ++i) {
3251     result = Parse_TPM_CC(buffer, &value->command_codes[i], value_bytes);
3252     if (result) {
3253       return result;
3254     }
3255   }
3256   return result;
3257 }
3258 
Serialize_TPML_CCA(const TPML_CCA & value,std::string * buffer)3259 TPM_RC Serialize_TPML_CCA(const TPML_CCA& value, std::string* buffer) {
3260   TPM_RC result = TPM_RC_SUCCESS;
3261   VLOG(3) << __func__;
3262 
3263   result = Serialize_UINT32(value.count, buffer);
3264   if (result) {
3265     return result;
3266   }
3267 
3268   if (std::size(value.command_attributes) < value.count) {
3269     return TPM_RC_INSUFFICIENT;
3270   }
3271   for (uint32_t i = 0; i < value.count; ++i) {
3272     result = Serialize_TPMA_CC(value.command_attributes[i], buffer);
3273     if (result) {
3274       return result;
3275     }
3276   }
3277   return result;
3278 }
3279 
Parse_TPML_CCA(std::string * buffer,TPML_CCA * value,std::string * value_bytes)3280 TPM_RC Parse_TPML_CCA(std::string* buffer,
3281                       TPML_CCA* value,
3282                       std::string* value_bytes) {
3283   TPM_RC result = TPM_RC_SUCCESS;
3284   VLOG(3) << __func__;
3285 
3286   result = Parse_UINT32(buffer, &value->count, value_bytes);
3287   if (result) {
3288     return result;
3289   }
3290 
3291   if (std::size(value->command_attributes) < value->count) {
3292     return TPM_RC_INSUFFICIENT;
3293   }
3294   for (uint32_t i = 0; i < value->count; ++i) {
3295     result = Parse_TPMA_CC(buffer, &value->command_attributes[i], value_bytes);
3296     if (result) {
3297       return result;
3298     }
3299   }
3300   return result;
3301 }
3302 
Serialize_TPML_ALG(const TPML_ALG & value,std::string * buffer)3303 TPM_RC Serialize_TPML_ALG(const TPML_ALG& value, std::string* buffer) {
3304   TPM_RC result = TPM_RC_SUCCESS;
3305   VLOG(3) << __func__;
3306 
3307   result = Serialize_UINT32(value.count, buffer);
3308   if (result) {
3309     return result;
3310   }
3311 
3312   if (std::size(value.algorithms) < value.count) {
3313     return TPM_RC_INSUFFICIENT;
3314   }
3315   for (uint32_t i = 0; i < value.count; ++i) {
3316     result = Serialize_TPM_ALG_ID(value.algorithms[i], buffer);
3317     if (result) {
3318       return result;
3319     }
3320   }
3321   return result;
3322 }
3323 
Parse_TPML_ALG(std::string * buffer,TPML_ALG * value,std::string * value_bytes)3324 TPM_RC Parse_TPML_ALG(std::string* buffer,
3325                       TPML_ALG* value,
3326                       std::string* value_bytes) {
3327   TPM_RC result = TPM_RC_SUCCESS;
3328   VLOG(3) << __func__;
3329 
3330   result = Parse_UINT32(buffer, &value->count, value_bytes);
3331   if (result) {
3332     return result;
3333   }
3334 
3335   if (std::size(value->algorithms) < value->count) {
3336     return TPM_RC_INSUFFICIENT;
3337   }
3338   for (uint32_t i = 0; i < value->count; ++i) {
3339     result = Parse_TPM_ALG_ID(buffer, &value->algorithms[i], value_bytes);
3340     if (result) {
3341       return result;
3342     }
3343   }
3344   return result;
3345 }
3346 
Serialize_TPML_HANDLE(const TPML_HANDLE & value,std::string * buffer)3347 TPM_RC Serialize_TPML_HANDLE(const TPML_HANDLE& value, std::string* buffer) {
3348   TPM_RC result = TPM_RC_SUCCESS;
3349   VLOG(3) << __func__;
3350 
3351   result = Serialize_UINT32(value.count, buffer);
3352   if (result) {
3353     return result;
3354   }
3355 
3356   if (std::size(value.handle) < value.count) {
3357     return TPM_RC_INSUFFICIENT;
3358   }
3359   for (uint32_t i = 0; i < value.count; ++i) {
3360     result = Serialize_TPM_HANDLE(value.handle[i], buffer);
3361     if (result) {
3362       return result;
3363     }
3364   }
3365   return result;
3366 }
3367 
Parse_TPML_HANDLE(std::string * buffer,TPML_HANDLE * value,std::string * value_bytes)3368 TPM_RC Parse_TPML_HANDLE(std::string* buffer,
3369                          TPML_HANDLE* value,
3370                          std::string* value_bytes) {
3371   TPM_RC result = TPM_RC_SUCCESS;
3372   VLOG(3) << __func__;
3373 
3374   result = Parse_UINT32(buffer, &value->count, value_bytes);
3375   if (result) {
3376     return result;
3377   }
3378 
3379   if (std::size(value->handle) < value->count) {
3380     return TPM_RC_INSUFFICIENT;
3381   }
3382   for (uint32_t i = 0; i < value->count; ++i) {
3383     result = Parse_TPM_HANDLE(buffer, &value->handle[i], value_bytes);
3384     if (result) {
3385       return result;
3386     }
3387   }
3388   return result;
3389 }
3390 
Serialize_TPML_DIGEST(const TPML_DIGEST & value,std::string * buffer)3391 TPM_RC Serialize_TPML_DIGEST(const TPML_DIGEST& value, std::string* buffer) {
3392   TPM_RC result = TPM_RC_SUCCESS;
3393   VLOG(3) << __func__;
3394 
3395   result = Serialize_UINT32(value.count, buffer);
3396   if (result) {
3397     return result;
3398   }
3399 
3400   if (std::size(value.digests) < value.count) {
3401     return TPM_RC_INSUFFICIENT;
3402   }
3403   for (uint32_t i = 0; i < value.count; ++i) {
3404     result = Serialize_TPM2B_DIGEST(value.digests[i], buffer);
3405     if (result) {
3406       return result;
3407     }
3408   }
3409   return result;
3410 }
3411 
Parse_TPML_DIGEST(std::string * buffer,TPML_DIGEST * value,std::string * value_bytes)3412 TPM_RC Parse_TPML_DIGEST(std::string* buffer,
3413                          TPML_DIGEST* value,
3414                          std::string* value_bytes) {
3415   TPM_RC result = TPM_RC_SUCCESS;
3416   VLOG(3) << __func__;
3417 
3418   result = Parse_UINT32(buffer, &value->count, value_bytes);
3419   if (result) {
3420     return result;
3421   }
3422 
3423   if (std::size(value->digests) < value->count) {
3424     return TPM_RC_INSUFFICIENT;
3425   }
3426   for (uint32_t i = 0; i < value->count; ++i) {
3427     result = Parse_TPM2B_DIGEST(buffer, &value->digests[i], value_bytes);
3428     if (result) {
3429       return result;
3430     }
3431   }
3432   return result;
3433 }
3434 
Serialize_TPML_DIGEST_VALUES(const TPML_DIGEST_VALUES & value,std::string * buffer)3435 TPM_RC Serialize_TPML_DIGEST_VALUES(const TPML_DIGEST_VALUES& value,
3436                                     std::string* buffer) {
3437   TPM_RC result = TPM_RC_SUCCESS;
3438   VLOG(3) << __func__;
3439 
3440   result = Serialize_UINT32(value.count, buffer);
3441   if (result) {
3442     return result;
3443   }
3444 
3445   if (std::size(value.digests) < value.count) {
3446     return TPM_RC_INSUFFICIENT;
3447   }
3448   for (uint32_t i = 0; i < value.count; ++i) {
3449     result = Serialize_TPMT_HA(value.digests[i], buffer);
3450     if (result) {
3451       return result;
3452     }
3453   }
3454   return result;
3455 }
3456 
Parse_TPML_DIGEST_VALUES(std::string * buffer,TPML_DIGEST_VALUES * value,std::string * value_bytes)3457 TPM_RC Parse_TPML_DIGEST_VALUES(std::string* buffer,
3458                                 TPML_DIGEST_VALUES* value,
3459                                 std::string* value_bytes) {
3460   TPM_RC result = TPM_RC_SUCCESS;
3461   VLOG(3) << __func__;
3462 
3463   result = Parse_UINT32(buffer, &value->count, value_bytes);
3464   if (result) {
3465     return result;
3466   }
3467 
3468   if (std::size(value->digests) < value->count) {
3469     return TPM_RC_INSUFFICIENT;
3470   }
3471   for (uint32_t i = 0; i < value->count; ++i) {
3472     result = Parse_TPMT_HA(buffer, &value->digests[i], value_bytes);
3473     if (result) {
3474       return result;
3475     }
3476   }
3477   return result;
3478 }
3479 
Serialize_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES & value,std::string * buffer)3480 TPM_RC Serialize_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES& value,
3481                                      std::string* buffer) {
3482   TPM_RC result = TPM_RC_SUCCESS;
3483   VLOG(3) << __func__;
3484 
3485   result = Serialize_UINT16(value.size, buffer);
3486   if (result) {
3487     return result;
3488   }
3489 
3490   if (std::size(value.buffer) < value.size) {
3491     return TPM_RC_INSUFFICIENT;
3492   }
3493   for (uint32_t i = 0; i < value.size; ++i) {
3494     result = Serialize_BYTE(value.buffer[i], buffer);
3495     if (result) {
3496       return result;
3497     }
3498   }
3499   return result;
3500 }
3501 
Parse_TPM2B_DIGEST_VALUES(std::string * buffer,TPM2B_DIGEST_VALUES * value,std::string * value_bytes)3502 TPM_RC Parse_TPM2B_DIGEST_VALUES(std::string* buffer,
3503                                  TPM2B_DIGEST_VALUES* value,
3504                                  std::string* value_bytes) {
3505   TPM_RC result = TPM_RC_SUCCESS;
3506   VLOG(3) << __func__;
3507 
3508   result = Parse_UINT16(buffer, &value->size, value_bytes);
3509   if (result) {
3510     return result;
3511   }
3512 
3513   if (std::size(value->buffer) < value->size) {
3514     return TPM_RC_INSUFFICIENT;
3515   }
3516   for (uint32_t i = 0; i < value->size; ++i) {
3517     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
3518     if (result) {
3519       return result;
3520     }
3521   }
3522   return result;
3523 }
3524 
Make_TPM2B_DIGEST_VALUES(const std::string & bytes)3525 TPM2B_DIGEST_VALUES Make_TPM2B_DIGEST_VALUES(const std::string& bytes) {
3526   TPM2B_DIGEST_VALUES tpm2b;
3527   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
3528   memset(&tpm2b, 0, sizeof(TPM2B_DIGEST_VALUES));
3529   tpm2b.size = bytes.size();
3530   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
3531   return tpm2b;
3532 }
3533 
StringFrom_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES & tpm2b)3534 std::string StringFrom_TPM2B_DIGEST_VALUES(const TPM2B_DIGEST_VALUES& tpm2b) {
3535   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
3536   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
3537   return std::string(char_buffer, tpm2b.size);
3538 }
3539 
Serialize_TPML_PCR_SELECTION(const TPML_PCR_SELECTION & value,std::string * buffer)3540 TPM_RC Serialize_TPML_PCR_SELECTION(const TPML_PCR_SELECTION& value,
3541                                     std::string* buffer) {
3542   TPM_RC result = TPM_RC_SUCCESS;
3543   VLOG(3) << __func__;
3544 
3545   result = Serialize_UINT32(value.count, buffer);
3546   if (result) {
3547     return result;
3548   }
3549 
3550   if (std::size(value.pcr_selections) < value.count) {
3551     return TPM_RC_INSUFFICIENT;
3552   }
3553   for (uint32_t i = 0; i < value.count; ++i) {
3554     result = Serialize_TPMS_PCR_SELECTION(value.pcr_selections[i], buffer);
3555     if (result) {
3556       return result;
3557     }
3558   }
3559   return result;
3560 }
3561 
Parse_TPML_PCR_SELECTION(std::string * buffer,TPML_PCR_SELECTION * value,std::string * value_bytes)3562 TPM_RC Parse_TPML_PCR_SELECTION(std::string* buffer,
3563                                 TPML_PCR_SELECTION* value,
3564                                 std::string* value_bytes) {
3565   TPM_RC result = TPM_RC_SUCCESS;
3566   VLOG(3) << __func__;
3567 
3568   result = Parse_UINT32(buffer, &value->count, value_bytes);
3569   if (result) {
3570     return result;
3571   }
3572 
3573   if (std::size(value->pcr_selections) < value->count) {
3574     return TPM_RC_INSUFFICIENT;
3575   }
3576   for (uint32_t i = 0; i < value->count; ++i) {
3577     result = Parse_TPMS_PCR_SELECTION(buffer, &value->pcr_selections[i],
3578                                       value_bytes);
3579     if (result) {
3580       return result;
3581     }
3582   }
3583   return result;
3584 }
3585 
Serialize_TPML_ALG_PROPERTY(const TPML_ALG_PROPERTY & value,std::string * buffer)3586 TPM_RC Serialize_TPML_ALG_PROPERTY(const TPML_ALG_PROPERTY& value,
3587                                    std::string* buffer) {
3588   TPM_RC result = TPM_RC_SUCCESS;
3589   VLOG(3) << __func__;
3590 
3591   result = Serialize_UINT32(value.count, buffer);
3592   if (result) {
3593     return result;
3594   }
3595 
3596   if (std::size(value.alg_properties) < value.count) {
3597     return TPM_RC_INSUFFICIENT;
3598   }
3599   for (uint32_t i = 0; i < value.count; ++i) {
3600     result = Serialize_TPMS_ALG_PROPERTY(value.alg_properties[i], buffer);
3601     if (result) {
3602       return result;
3603     }
3604   }
3605   return result;
3606 }
3607 
Parse_TPML_ALG_PROPERTY(std::string * buffer,TPML_ALG_PROPERTY * value,std::string * value_bytes)3608 TPM_RC Parse_TPML_ALG_PROPERTY(std::string* buffer,
3609                                TPML_ALG_PROPERTY* value,
3610                                std::string* value_bytes) {
3611   TPM_RC result = TPM_RC_SUCCESS;
3612   VLOG(3) << __func__;
3613 
3614   result = Parse_UINT32(buffer, &value->count, value_bytes);
3615   if (result) {
3616     return result;
3617   }
3618 
3619   if (std::size(value->alg_properties) < value->count) {
3620     return TPM_RC_INSUFFICIENT;
3621   }
3622   for (uint32_t i = 0; i < value->count; ++i) {
3623     result =
3624         Parse_TPMS_ALG_PROPERTY(buffer, &value->alg_properties[i], value_bytes);
3625     if (result) {
3626       return result;
3627     }
3628   }
3629   return result;
3630 }
3631 
Serialize_TPML_TAGGED_TPM_PROPERTY(const TPML_TAGGED_TPM_PROPERTY & value,std::string * buffer)3632 TPM_RC Serialize_TPML_TAGGED_TPM_PROPERTY(const TPML_TAGGED_TPM_PROPERTY& value,
3633                                           std::string* buffer) {
3634   TPM_RC result = TPM_RC_SUCCESS;
3635   VLOG(3) << __func__;
3636 
3637   result = Serialize_UINT32(value.count, buffer);
3638   if (result) {
3639     return result;
3640   }
3641 
3642   if (std::size(value.tpm_property) < value.count) {
3643     return TPM_RC_INSUFFICIENT;
3644   }
3645   for (uint32_t i = 0; i < value.count; ++i) {
3646     result = Serialize_TPMS_TAGGED_PROPERTY(value.tpm_property[i], buffer);
3647     if (result) {
3648       return result;
3649     }
3650   }
3651   return result;
3652 }
3653 
Parse_TPML_TAGGED_TPM_PROPERTY(std::string * buffer,TPML_TAGGED_TPM_PROPERTY * value,std::string * value_bytes)3654 TPM_RC Parse_TPML_TAGGED_TPM_PROPERTY(std::string* buffer,
3655                                       TPML_TAGGED_TPM_PROPERTY* value,
3656                                       std::string* value_bytes) {
3657   TPM_RC result = TPM_RC_SUCCESS;
3658   VLOG(3) << __func__;
3659 
3660   result = Parse_UINT32(buffer, &value->count, value_bytes);
3661   if (result) {
3662     return result;
3663   }
3664 
3665   if (std::size(value->tpm_property) < value->count) {
3666     return TPM_RC_INSUFFICIENT;
3667   }
3668   for (uint32_t i = 0; i < value->count; ++i) {
3669     result = Parse_TPMS_TAGGED_PROPERTY(buffer, &value->tpm_property[i],
3670                                         value_bytes);
3671     if (result) {
3672       return result;
3673     }
3674   }
3675   return result;
3676 }
3677 
Serialize_TPML_TAGGED_PCR_PROPERTY(const TPML_TAGGED_PCR_PROPERTY & value,std::string * buffer)3678 TPM_RC Serialize_TPML_TAGGED_PCR_PROPERTY(const TPML_TAGGED_PCR_PROPERTY& value,
3679                                           std::string* buffer) {
3680   TPM_RC result = TPM_RC_SUCCESS;
3681   VLOG(3) << __func__;
3682 
3683   result = Serialize_UINT32(value.count, buffer);
3684   if (result) {
3685     return result;
3686   }
3687 
3688   if (std::size(value.pcr_property) < value.count) {
3689     return TPM_RC_INSUFFICIENT;
3690   }
3691   for (uint32_t i = 0; i < value.count; ++i) {
3692     result = Serialize_TPMS_TAGGED_PCR_SELECT(value.pcr_property[i], buffer);
3693     if (result) {
3694       return result;
3695     }
3696   }
3697   return result;
3698 }
3699 
Parse_TPML_TAGGED_PCR_PROPERTY(std::string * buffer,TPML_TAGGED_PCR_PROPERTY * value,std::string * value_bytes)3700 TPM_RC Parse_TPML_TAGGED_PCR_PROPERTY(std::string* buffer,
3701                                       TPML_TAGGED_PCR_PROPERTY* value,
3702                                       std::string* value_bytes) {
3703   TPM_RC result = TPM_RC_SUCCESS;
3704   VLOG(3) << __func__;
3705 
3706   result = Parse_UINT32(buffer, &value->count, value_bytes);
3707   if (result) {
3708     return result;
3709   }
3710 
3711   if (std::size(value->pcr_property) < value->count) {
3712     return TPM_RC_INSUFFICIENT;
3713   }
3714   for (uint32_t i = 0; i < value->count; ++i) {
3715     result = Parse_TPMS_TAGGED_PCR_SELECT(buffer, &value->pcr_property[i],
3716                                           value_bytes);
3717     if (result) {
3718       return result;
3719     }
3720   }
3721   return result;
3722 }
3723 
Serialize_TPML_ECC_CURVE(const TPML_ECC_CURVE & value,std::string * buffer)3724 TPM_RC Serialize_TPML_ECC_CURVE(const TPML_ECC_CURVE& value,
3725                                 std::string* buffer) {
3726   TPM_RC result = TPM_RC_SUCCESS;
3727   VLOG(3) << __func__;
3728 
3729   result = Serialize_UINT32(value.count, buffer);
3730   if (result) {
3731     return result;
3732   }
3733 
3734   if (std::size(value.ecc_curves) < value.count) {
3735     return TPM_RC_INSUFFICIENT;
3736   }
3737   for (uint32_t i = 0; i < value.count; ++i) {
3738     result = Serialize_TPM_ECC_CURVE(value.ecc_curves[i], buffer);
3739     if (result) {
3740       return result;
3741     }
3742   }
3743   return result;
3744 }
3745 
Parse_TPML_ECC_CURVE(std::string * buffer,TPML_ECC_CURVE * value,std::string * value_bytes)3746 TPM_RC Parse_TPML_ECC_CURVE(std::string* buffer,
3747                             TPML_ECC_CURVE* value,
3748                             std::string* value_bytes) {
3749   TPM_RC result = TPM_RC_SUCCESS;
3750   VLOG(3) << __func__;
3751 
3752   result = Parse_UINT32(buffer, &value->count, value_bytes);
3753   if (result) {
3754     return result;
3755   }
3756 
3757   if (std::size(value->ecc_curves) < value->count) {
3758     return TPM_RC_INSUFFICIENT;
3759   }
3760   for (uint32_t i = 0; i < value->count; ++i) {
3761     result = Parse_TPM_ECC_CURVE(buffer, &value->ecc_curves[i], value_bytes);
3762     if (result) {
3763       return result;
3764     }
3765   }
3766   return result;
3767 }
3768 
Serialize_TPMU_CAPABILITIES(const TPMU_CAPABILITIES & value,TPM_CAP selector,std::string * buffer)3769 TPM_RC Serialize_TPMU_CAPABILITIES(const TPMU_CAPABILITIES& value,
3770                                    TPM_CAP selector,
3771                                    std::string* buffer) {
3772   TPM_RC result = TPM_RC_SUCCESS;
3773   VLOG(3) << __func__;
3774 
3775   if (selector == TPM_CAP_PCRS) {
3776     result = Serialize_TPML_PCR_SELECTION(value.assigned_pcr, buffer);
3777     if (result) {
3778       return result;
3779     }
3780   }
3781 
3782   if (selector == TPM_CAP_TPM_PROPERTIES) {
3783     result = Serialize_TPML_TAGGED_TPM_PROPERTY(value.tpm_properties, buffer);
3784     if (result) {
3785       return result;
3786     }
3787   }
3788 
3789   if (selector == TPM_CAP_PP_COMMANDS) {
3790     result = Serialize_TPML_CC(value.pp_commands, buffer);
3791     if (result) {
3792       return result;
3793     }
3794   }
3795 
3796   if (selector == TPM_CAP_AUDIT_COMMANDS) {
3797     result = Serialize_TPML_CC(value.audit_commands, buffer);
3798     if (result) {
3799       return result;
3800     }
3801   }
3802 
3803   if (selector == TPM_CAP_COMMANDS) {
3804     result = Serialize_TPML_CCA(value.command, buffer);
3805     if (result) {
3806       return result;
3807     }
3808   }
3809 
3810   if (selector == TPM_CAP_ECC_CURVES) {
3811     result = Serialize_TPML_ECC_CURVE(value.ecc_curves, buffer);
3812     if (result) {
3813       return result;
3814     }
3815   }
3816 
3817   if (selector == TPM_CAP_PCR_PROPERTIES) {
3818     result = Serialize_TPML_TAGGED_PCR_PROPERTY(value.pcr_properties, buffer);
3819     if (result) {
3820       return result;
3821     }
3822   }
3823 
3824   if (selector == TPM_CAP_HANDLES) {
3825     result = Serialize_TPML_HANDLE(value.handles, buffer);
3826     if (result) {
3827       return result;
3828     }
3829   }
3830 
3831   if (selector == TPM_CAP_ALGS) {
3832     result = Serialize_TPML_ALG_PROPERTY(value.algorithms, buffer);
3833     if (result) {
3834       return result;
3835     }
3836   }
3837   return result;
3838 }
3839 
Parse_TPMU_CAPABILITIES(std::string * buffer,TPM_CAP selector,TPMU_CAPABILITIES * value,std::string * value_bytes)3840 TPM_RC Parse_TPMU_CAPABILITIES(std::string* buffer,
3841                                TPM_CAP selector,
3842                                TPMU_CAPABILITIES* value,
3843                                std::string* value_bytes) {
3844   TPM_RC result = TPM_RC_SUCCESS;
3845   VLOG(3) << __func__;
3846 
3847   if (selector == TPM_CAP_PCRS) {
3848     result =
3849         Parse_TPML_PCR_SELECTION(buffer, &value->assigned_pcr, value_bytes);
3850     if (result) {
3851       return result;
3852     }
3853   }
3854 
3855   if (selector == TPM_CAP_TPM_PROPERTIES) {
3856     result = Parse_TPML_TAGGED_TPM_PROPERTY(buffer, &value->tpm_properties,
3857                                             value_bytes);
3858     if (result) {
3859       return result;
3860     }
3861   }
3862 
3863   if (selector == TPM_CAP_PP_COMMANDS) {
3864     result = Parse_TPML_CC(buffer, &value->pp_commands, value_bytes);
3865     if (result) {
3866       return result;
3867     }
3868   }
3869 
3870   if (selector == TPM_CAP_AUDIT_COMMANDS) {
3871     result = Parse_TPML_CC(buffer, &value->audit_commands, value_bytes);
3872     if (result) {
3873       return result;
3874     }
3875   }
3876 
3877   if (selector == TPM_CAP_COMMANDS) {
3878     result = Parse_TPML_CCA(buffer, &value->command, value_bytes);
3879     if (result) {
3880       return result;
3881     }
3882   }
3883 
3884   if (selector == TPM_CAP_ECC_CURVES) {
3885     result = Parse_TPML_ECC_CURVE(buffer, &value->ecc_curves, value_bytes);
3886     if (result) {
3887       return result;
3888     }
3889   }
3890 
3891   if (selector == TPM_CAP_PCR_PROPERTIES) {
3892     result = Parse_TPML_TAGGED_PCR_PROPERTY(buffer, &value->pcr_properties,
3893                                             value_bytes);
3894     if (result) {
3895       return result;
3896     }
3897   }
3898 
3899   if (selector == TPM_CAP_HANDLES) {
3900     result = Parse_TPML_HANDLE(buffer, &value->handles, value_bytes);
3901     if (result) {
3902       return result;
3903     }
3904   }
3905 
3906   if (selector == TPM_CAP_ALGS) {
3907     result = Parse_TPML_ALG_PROPERTY(buffer, &value->algorithms, value_bytes);
3908     if (result) {
3909       return result;
3910     }
3911   }
3912   return result;
3913 }
3914 
Serialize_TPMS_CAPABILITY_DATA(const TPMS_CAPABILITY_DATA & value,std::string * buffer)3915 TPM_RC Serialize_TPMS_CAPABILITY_DATA(const TPMS_CAPABILITY_DATA& value,
3916                                       std::string* buffer) {
3917   TPM_RC result = TPM_RC_SUCCESS;
3918   VLOG(3) << __func__;
3919 
3920   result = Serialize_TPM_CAP(value.capability, buffer);
3921   if (result) {
3922     return result;
3923   }
3924 
3925   result = Serialize_TPMU_CAPABILITIES(value.data, value.capability, buffer);
3926   if (result) {
3927     return result;
3928   }
3929   return result;
3930 }
3931 
Parse_TPMS_CAPABILITY_DATA(std::string * buffer,TPMS_CAPABILITY_DATA * value,std::string * value_bytes)3932 TPM_RC Parse_TPMS_CAPABILITY_DATA(std::string* buffer,
3933                                   TPMS_CAPABILITY_DATA* value,
3934                                   std::string* value_bytes) {
3935   TPM_RC result = TPM_RC_SUCCESS;
3936   VLOG(3) << __func__;
3937 
3938   result = Parse_TPM_CAP(buffer, &value->capability, value_bytes);
3939   if (result) {
3940     return result;
3941   }
3942 
3943   result = Parse_TPMU_CAPABILITIES(buffer, value->capability, &value->data,
3944                                    value_bytes);
3945   if (result) {
3946     return result;
3947   }
3948   return result;
3949 }
3950 
Serialize_TPMS_CLOCK_INFO(const TPMS_CLOCK_INFO & value,std::string * buffer)3951 TPM_RC Serialize_TPMS_CLOCK_INFO(const TPMS_CLOCK_INFO& value,
3952                                  std::string* buffer) {
3953   TPM_RC result = TPM_RC_SUCCESS;
3954   VLOG(3) << __func__;
3955 
3956   result = Serialize_UINT64(value.clock, buffer);
3957   if (result) {
3958     return result;
3959   }
3960 
3961   result = Serialize_UINT32(value.reset_count, buffer);
3962   if (result) {
3963     return result;
3964   }
3965 
3966   result = Serialize_UINT32(value.restart_count, buffer);
3967   if (result) {
3968     return result;
3969   }
3970 
3971   result = Serialize_TPMI_YES_NO(value.safe, buffer);
3972   if (result) {
3973     return result;
3974   }
3975   return result;
3976 }
3977 
Parse_TPMS_CLOCK_INFO(std::string * buffer,TPMS_CLOCK_INFO * value,std::string * value_bytes)3978 TPM_RC Parse_TPMS_CLOCK_INFO(std::string* buffer,
3979                              TPMS_CLOCK_INFO* value,
3980                              std::string* value_bytes) {
3981   TPM_RC result = TPM_RC_SUCCESS;
3982   VLOG(3) << __func__;
3983 
3984   result = Parse_UINT64(buffer, &value->clock, value_bytes);
3985   if (result) {
3986     return result;
3987   }
3988 
3989   result = Parse_UINT32(buffer, &value->reset_count, value_bytes);
3990   if (result) {
3991     return result;
3992   }
3993 
3994   result = Parse_UINT32(buffer, &value->restart_count, value_bytes);
3995   if (result) {
3996     return result;
3997   }
3998 
3999   result = Parse_TPMI_YES_NO(buffer, &value->safe, value_bytes);
4000   if (result) {
4001     return result;
4002   }
4003   return result;
4004 }
4005 
Serialize_TPMS_TIME_INFO(const TPMS_TIME_INFO & value,std::string * buffer)4006 TPM_RC Serialize_TPMS_TIME_INFO(const TPMS_TIME_INFO& value,
4007                                 std::string* buffer) {
4008   TPM_RC result = TPM_RC_SUCCESS;
4009   VLOG(3) << __func__;
4010 
4011   result = Serialize_UINT64(value.time, buffer);
4012   if (result) {
4013     return result;
4014   }
4015 
4016   result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer);
4017   if (result) {
4018     return result;
4019   }
4020   return result;
4021 }
4022 
Parse_TPMS_TIME_INFO(std::string * buffer,TPMS_TIME_INFO * value,std::string * value_bytes)4023 TPM_RC Parse_TPMS_TIME_INFO(std::string* buffer,
4024                             TPMS_TIME_INFO* value,
4025                             std::string* value_bytes) {
4026   TPM_RC result = TPM_RC_SUCCESS;
4027   VLOG(3) << __func__;
4028 
4029   result = Parse_UINT64(buffer, &value->time, value_bytes);
4030   if (result) {
4031     return result;
4032   }
4033 
4034   result = Parse_TPMS_CLOCK_INFO(buffer, &value->clock_info, value_bytes);
4035   if (result) {
4036     return result;
4037   }
4038   return result;
4039 }
4040 
Serialize_TPMS_TIME_ATTEST_INFO(const TPMS_TIME_ATTEST_INFO & value,std::string * buffer)4041 TPM_RC Serialize_TPMS_TIME_ATTEST_INFO(const TPMS_TIME_ATTEST_INFO& value,
4042                                        std::string* buffer) {
4043   TPM_RC result = TPM_RC_SUCCESS;
4044   VLOG(3) << __func__;
4045 
4046   result = Serialize_TPMS_TIME_INFO(value.time, buffer);
4047   if (result) {
4048     return result;
4049   }
4050 
4051   result = Serialize_UINT64(value.firmware_version, buffer);
4052   if (result) {
4053     return result;
4054   }
4055   return result;
4056 }
4057 
Parse_TPMS_TIME_ATTEST_INFO(std::string * buffer,TPMS_TIME_ATTEST_INFO * value,std::string * value_bytes)4058 TPM_RC Parse_TPMS_TIME_ATTEST_INFO(std::string* buffer,
4059                                    TPMS_TIME_ATTEST_INFO* value,
4060                                    std::string* value_bytes) {
4061   TPM_RC result = TPM_RC_SUCCESS;
4062   VLOG(3) << __func__;
4063 
4064   result = Parse_TPMS_TIME_INFO(buffer, &value->time, value_bytes);
4065   if (result) {
4066     return result;
4067   }
4068 
4069   result = Parse_UINT64(buffer, &value->firmware_version, value_bytes);
4070   if (result) {
4071     return result;
4072   }
4073   return result;
4074 }
4075 
Serialize_TPMS_CERTIFY_INFO(const TPMS_CERTIFY_INFO & value,std::string * buffer)4076 TPM_RC Serialize_TPMS_CERTIFY_INFO(const TPMS_CERTIFY_INFO& value,
4077                                    std::string* buffer) {
4078   TPM_RC result = TPM_RC_SUCCESS;
4079   VLOG(3) << __func__;
4080 
4081   result = Serialize_TPM2B_NAME(value.name, buffer);
4082   if (result) {
4083     return result;
4084   }
4085 
4086   result = Serialize_TPM2B_NAME(value.qualified_name, buffer);
4087   if (result) {
4088     return result;
4089   }
4090   return result;
4091 }
4092 
Parse_TPMS_CERTIFY_INFO(std::string * buffer,TPMS_CERTIFY_INFO * value,std::string * value_bytes)4093 TPM_RC Parse_TPMS_CERTIFY_INFO(std::string* buffer,
4094                                TPMS_CERTIFY_INFO* value,
4095                                std::string* value_bytes) {
4096   TPM_RC result = TPM_RC_SUCCESS;
4097   VLOG(3) << __func__;
4098 
4099   result = Parse_TPM2B_NAME(buffer, &value->name, value_bytes);
4100   if (result) {
4101     return result;
4102   }
4103 
4104   result = Parse_TPM2B_NAME(buffer, &value->qualified_name, value_bytes);
4105   if (result) {
4106     return result;
4107   }
4108   return result;
4109 }
4110 
Serialize_TPMS_QUOTE_INFO(const TPMS_QUOTE_INFO & value,std::string * buffer)4111 TPM_RC Serialize_TPMS_QUOTE_INFO(const TPMS_QUOTE_INFO& value,
4112                                  std::string* buffer) {
4113   TPM_RC result = TPM_RC_SUCCESS;
4114   VLOG(3) << __func__;
4115 
4116   result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer);
4117   if (result) {
4118     return result;
4119   }
4120 
4121   result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer);
4122   if (result) {
4123     return result;
4124   }
4125   return result;
4126 }
4127 
Parse_TPMS_QUOTE_INFO(std::string * buffer,TPMS_QUOTE_INFO * value,std::string * value_bytes)4128 TPM_RC Parse_TPMS_QUOTE_INFO(std::string* buffer,
4129                              TPMS_QUOTE_INFO* value,
4130                              std::string* value_bytes) {
4131   TPM_RC result = TPM_RC_SUCCESS;
4132   VLOG(3) << __func__;
4133 
4134   result = Parse_TPML_PCR_SELECTION(buffer, &value->pcr_select, value_bytes);
4135   if (result) {
4136     return result;
4137   }
4138 
4139   result = Parse_TPM2B_DIGEST(buffer, &value->pcr_digest, value_bytes);
4140   if (result) {
4141     return result;
4142   }
4143   return result;
4144 }
4145 
Serialize_TPMS_COMMAND_AUDIT_INFO(const TPMS_COMMAND_AUDIT_INFO & value,std::string * buffer)4146 TPM_RC Serialize_TPMS_COMMAND_AUDIT_INFO(const TPMS_COMMAND_AUDIT_INFO& value,
4147                                          std::string* buffer) {
4148   TPM_RC result = TPM_RC_SUCCESS;
4149   VLOG(3) << __func__;
4150 
4151   result = Serialize_UINT64(value.audit_counter, buffer);
4152   if (result) {
4153     return result;
4154   }
4155 
4156   result = Serialize_TPM_ALG_ID(value.digest_alg, buffer);
4157   if (result) {
4158     return result;
4159   }
4160 
4161   result = Serialize_TPM2B_DIGEST(value.audit_digest, buffer);
4162   if (result) {
4163     return result;
4164   }
4165 
4166   result = Serialize_TPM2B_DIGEST(value.command_digest, buffer);
4167   if (result) {
4168     return result;
4169   }
4170   return result;
4171 }
4172 
Parse_TPMS_COMMAND_AUDIT_INFO(std::string * buffer,TPMS_COMMAND_AUDIT_INFO * value,std::string * value_bytes)4173 TPM_RC Parse_TPMS_COMMAND_AUDIT_INFO(std::string* buffer,
4174                                      TPMS_COMMAND_AUDIT_INFO* value,
4175                                      std::string* value_bytes) {
4176   TPM_RC result = TPM_RC_SUCCESS;
4177   VLOG(3) << __func__;
4178 
4179   result = Parse_UINT64(buffer, &value->audit_counter, value_bytes);
4180   if (result) {
4181     return result;
4182   }
4183 
4184   result = Parse_TPM_ALG_ID(buffer, &value->digest_alg, value_bytes);
4185   if (result) {
4186     return result;
4187   }
4188 
4189   result = Parse_TPM2B_DIGEST(buffer, &value->audit_digest, value_bytes);
4190   if (result) {
4191     return result;
4192   }
4193 
4194   result = Parse_TPM2B_DIGEST(buffer, &value->command_digest, value_bytes);
4195   if (result) {
4196     return result;
4197   }
4198   return result;
4199 }
4200 
Serialize_TPMS_SESSION_AUDIT_INFO(const TPMS_SESSION_AUDIT_INFO & value,std::string * buffer)4201 TPM_RC Serialize_TPMS_SESSION_AUDIT_INFO(const TPMS_SESSION_AUDIT_INFO& value,
4202                                          std::string* buffer) {
4203   TPM_RC result = TPM_RC_SUCCESS;
4204   VLOG(3) << __func__;
4205 
4206   result = Serialize_TPMI_YES_NO(value.exclusive_session, buffer);
4207   if (result) {
4208     return result;
4209   }
4210 
4211   result = Serialize_TPM2B_DIGEST(value.session_digest, buffer);
4212   if (result) {
4213     return result;
4214   }
4215   return result;
4216 }
4217 
Parse_TPMS_SESSION_AUDIT_INFO(std::string * buffer,TPMS_SESSION_AUDIT_INFO * value,std::string * value_bytes)4218 TPM_RC Parse_TPMS_SESSION_AUDIT_INFO(std::string* buffer,
4219                                      TPMS_SESSION_AUDIT_INFO* value,
4220                                      std::string* value_bytes) {
4221   TPM_RC result = TPM_RC_SUCCESS;
4222   VLOG(3) << __func__;
4223 
4224   result = Parse_TPMI_YES_NO(buffer, &value->exclusive_session, value_bytes);
4225   if (result) {
4226     return result;
4227   }
4228 
4229   result = Parse_TPM2B_DIGEST(buffer, &value->session_digest, value_bytes);
4230   if (result) {
4231     return result;
4232   }
4233   return result;
4234 }
4235 
Serialize_TPMS_CREATION_INFO(const TPMS_CREATION_INFO & value,std::string * buffer)4236 TPM_RC Serialize_TPMS_CREATION_INFO(const TPMS_CREATION_INFO& value,
4237                                     std::string* buffer) {
4238   TPM_RC result = TPM_RC_SUCCESS;
4239   VLOG(3) << __func__;
4240 
4241   result = Serialize_TPM2B_NAME(value.object_name, buffer);
4242   if (result) {
4243     return result;
4244   }
4245 
4246   result = Serialize_TPM2B_DIGEST(value.creation_hash, buffer);
4247   if (result) {
4248     return result;
4249   }
4250   return result;
4251 }
4252 
Parse_TPMS_CREATION_INFO(std::string * buffer,TPMS_CREATION_INFO * value,std::string * value_bytes)4253 TPM_RC Parse_TPMS_CREATION_INFO(std::string* buffer,
4254                                 TPMS_CREATION_INFO* value,
4255                                 std::string* value_bytes) {
4256   TPM_RC result = TPM_RC_SUCCESS;
4257   VLOG(3) << __func__;
4258 
4259   result = Parse_TPM2B_NAME(buffer, &value->object_name, value_bytes);
4260   if (result) {
4261     return result;
4262   }
4263 
4264   result = Parse_TPM2B_DIGEST(buffer, &value->creation_hash, value_bytes);
4265   if (result) {
4266     return result;
4267   }
4268   return result;
4269 }
4270 
Serialize_TPMS_NV_CERTIFY_INFO(const TPMS_NV_CERTIFY_INFO & value,std::string * buffer)4271 TPM_RC Serialize_TPMS_NV_CERTIFY_INFO(const TPMS_NV_CERTIFY_INFO& value,
4272                                       std::string* buffer) {
4273   TPM_RC result = TPM_RC_SUCCESS;
4274   VLOG(3) << __func__;
4275 
4276   result = Serialize_TPM2B_NAME(value.index_name, buffer);
4277   if (result) {
4278     return result;
4279   }
4280 
4281   result = Serialize_UINT16(value.offset, buffer);
4282   if (result) {
4283     return result;
4284   }
4285 
4286   result = Serialize_TPM2B_MAX_NV_BUFFER(value.nv_contents, buffer);
4287   if (result) {
4288     return result;
4289   }
4290   return result;
4291 }
4292 
Parse_TPMS_NV_CERTIFY_INFO(std::string * buffer,TPMS_NV_CERTIFY_INFO * value,std::string * value_bytes)4293 TPM_RC Parse_TPMS_NV_CERTIFY_INFO(std::string* buffer,
4294                                   TPMS_NV_CERTIFY_INFO* value,
4295                                   std::string* value_bytes) {
4296   TPM_RC result = TPM_RC_SUCCESS;
4297   VLOG(3) << __func__;
4298 
4299   result = Parse_TPM2B_NAME(buffer, &value->index_name, value_bytes);
4300   if (result) {
4301     return result;
4302   }
4303 
4304   result = Parse_UINT16(buffer, &value->offset, value_bytes);
4305   if (result) {
4306     return result;
4307   }
4308 
4309   result = Parse_TPM2B_MAX_NV_BUFFER(buffer, &value->nv_contents, value_bytes);
4310   if (result) {
4311     return result;
4312   }
4313   return result;
4314 }
4315 
Serialize_TPMU_ATTEST(const TPMU_ATTEST & value,TPMI_ST_ATTEST selector,std::string * buffer)4316 TPM_RC Serialize_TPMU_ATTEST(const TPMU_ATTEST& value,
4317                              TPMI_ST_ATTEST selector,
4318                              std::string* buffer) {
4319   TPM_RC result = TPM_RC_SUCCESS;
4320   VLOG(3) << __func__;
4321 
4322   if (selector == TPM_ST_ATTEST_SESSION_AUDIT) {
4323     result = Serialize_TPMS_SESSION_AUDIT_INFO(value.session_audit, buffer);
4324     if (result) {
4325       return result;
4326     }
4327   }
4328 
4329   if (selector == TPM_ST_ATTEST_QUOTE) {
4330     result = Serialize_TPMS_QUOTE_INFO(value.quote, buffer);
4331     if (result) {
4332       return result;
4333     }
4334   }
4335 
4336   if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) {
4337     result = Serialize_TPMS_COMMAND_AUDIT_INFO(value.command_audit, buffer);
4338     if (result) {
4339       return result;
4340     }
4341   }
4342 
4343   if (selector == TPM_ST_ATTEST_CERTIFY) {
4344     result = Serialize_TPMS_CERTIFY_INFO(value.certify, buffer);
4345     if (result) {
4346       return result;
4347     }
4348   }
4349 
4350   if (selector == TPM_ST_ATTEST_NV) {
4351     result = Serialize_TPMS_NV_CERTIFY_INFO(value.nv, buffer);
4352     if (result) {
4353       return result;
4354     }
4355   }
4356 
4357   if (selector == TPM_ST_ATTEST_TIME) {
4358     result = Serialize_TPMS_TIME_ATTEST_INFO(value.time, buffer);
4359     if (result) {
4360       return result;
4361     }
4362   }
4363 
4364   if (selector == TPM_ST_ATTEST_CREATION) {
4365     result = Serialize_TPMS_CREATION_INFO(value.creation, buffer);
4366     if (result) {
4367       return result;
4368     }
4369   }
4370   return result;
4371 }
4372 
Parse_TPMU_ATTEST(std::string * buffer,TPMI_ST_ATTEST selector,TPMU_ATTEST * value,std::string * value_bytes)4373 TPM_RC Parse_TPMU_ATTEST(std::string* buffer,
4374                          TPMI_ST_ATTEST selector,
4375                          TPMU_ATTEST* value,
4376                          std::string* value_bytes) {
4377   TPM_RC result = TPM_RC_SUCCESS;
4378   VLOG(3) << __func__;
4379 
4380   if (selector == TPM_ST_ATTEST_SESSION_AUDIT) {
4381     result = Parse_TPMS_SESSION_AUDIT_INFO(buffer, &value->session_audit,
4382                                            value_bytes);
4383     if (result) {
4384       return result;
4385     }
4386   }
4387 
4388   if (selector == TPM_ST_ATTEST_QUOTE) {
4389     result = Parse_TPMS_QUOTE_INFO(buffer, &value->quote, value_bytes);
4390     if (result) {
4391       return result;
4392     }
4393   }
4394 
4395   if (selector == TPM_ST_ATTEST_COMMAND_AUDIT) {
4396     result = Parse_TPMS_COMMAND_AUDIT_INFO(buffer, &value->command_audit,
4397                                            value_bytes);
4398     if (result) {
4399       return result;
4400     }
4401   }
4402 
4403   if (selector == TPM_ST_ATTEST_CERTIFY) {
4404     result = Parse_TPMS_CERTIFY_INFO(buffer, &value->certify, value_bytes);
4405     if (result) {
4406       return result;
4407     }
4408   }
4409 
4410   if (selector == TPM_ST_ATTEST_NV) {
4411     result = Parse_TPMS_NV_CERTIFY_INFO(buffer, &value->nv, value_bytes);
4412     if (result) {
4413       return result;
4414     }
4415   }
4416 
4417   if (selector == TPM_ST_ATTEST_TIME) {
4418     result = Parse_TPMS_TIME_ATTEST_INFO(buffer, &value->time, value_bytes);
4419     if (result) {
4420       return result;
4421     }
4422   }
4423 
4424   if (selector == TPM_ST_ATTEST_CREATION) {
4425     result = Parse_TPMS_CREATION_INFO(buffer, &value->creation, value_bytes);
4426     if (result) {
4427       return result;
4428     }
4429   }
4430   return result;
4431 }
4432 
Serialize_TPMS_ATTEST(const TPMS_ATTEST & value,std::string * buffer)4433 TPM_RC Serialize_TPMS_ATTEST(const TPMS_ATTEST& value, std::string* buffer) {
4434   TPM_RC result = TPM_RC_SUCCESS;
4435   VLOG(3) << __func__;
4436 
4437   result = Serialize_TPM_GENERATED(value.magic, buffer);
4438   if (result) {
4439     return result;
4440   }
4441 
4442   result = Serialize_TPMI_ST_ATTEST(value.type, buffer);
4443   if (result) {
4444     return result;
4445   }
4446 
4447   result = Serialize_TPM2B_NAME(value.qualified_signer, buffer);
4448   if (result) {
4449     return result;
4450   }
4451 
4452   result = Serialize_TPM2B_DATA(value.extra_data, buffer);
4453   if (result) {
4454     return result;
4455   }
4456 
4457   result = Serialize_TPMS_CLOCK_INFO(value.clock_info, buffer);
4458   if (result) {
4459     return result;
4460   }
4461 
4462   result = Serialize_UINT64(value.firmware_version, buffer);
4463   if (result) {
4464     return result;
4465   }
4466 
4467   result = Serialize_TPMU_ATTEST(value.attested, value.type, buffer);
4468   if (result) {
4469     return result;
4470   }
4471   return result;
4472 }
4473 
Parse_TPMS_ATTEST(std::string * buffer,TPMS_ATTEST * value,std::string * value_bytes)4474 TPM_RC Parse_TPMS_ATTEST(std::string* buffer,
4475                          TPMS_ATTEST* value,
4476                          std::string* value_bytes) {
4477   TPM_RC result = TPM_RC_SUCCESS;
4478   VLOG(3) << __func__;
4479 
4480   result = Parse_TPM_GENERATED(buffer, &value->magic, value_bytes);
4481   if (result) {
4482     return result;
4483   }
4484 
4485   result = Parse_TPMI_ST_ATTEST(buffer, &value->type, value_bytes);
4486   if (result) {
4487     return result;
4488   }
4489 
4490   result = Parse_TPM2B_NAME(buffer, &value->qualified_signer, value_bytes);
4491   if (result) {
4492     return result;
4493   }
4494 
4495   result = Parse_TPM2B_DATA(buffer, &value->extra_data, value_bytes);
4496   if (result) {
4497     return result;
4498   }
4499 
4500   result = Parse_TPMS_CLOCK_INFO(buffer, &value->clock_info, value_bytes);
4501   if (result) {
4502     return result;
4503   }
4504 
4505   result = Parse_UINT64(buffer, &value->firmware_version, value_bytes);
4506   if (result) {
4507     return result;
4508   }
4509 
4510   result =
4511       Parse_TPMU_ATTEST(buffer, value->type, &value->attested, value_bytes);
4512   if (result) {
4513     return result;
4514   }
4515   return result;
4516 }
4517 
Serialize_TPM2B_ATTEST(const TPM2B_ATTEST & value,std::string * buffer)4518 TPM_RC Serialize_TPM2B_ATTEST(const TPM2B_ATTEST& value, std::string* buffer) {
4519   TPM_RC result = TPM_RC_SUCCESS;
4520   VLOG(3) << __func__;
4521 
4522   result = Serialize_UINT16(value.size, buffer);
4523   if (result) {
4524     return result;
4525   }
4526 
4527   if (std::size(value.attestation_data) < value.size) {
4528     return TPM_RC_INSUFFICIENT;
4529   }
4530   for (uint32_t i = 0; i < value.size; ++i) {
4531     result = Serialize_BYTE(value.attestation_data[i], buffer);
4532     if (result) {
4533       return result;
4534     }
4535   }
4536   return result;
4537 }
4538 
Parse_TPM2B_ATTEST(std::string * buffer,TPM2B_ATTEST * value,std::string * value_bytes)4539 TPM_RC Parse_TPM2B_ATTEST(std::string* buffer,
4540                           TPM2B_ATTEST* value,
4541                           std::string* value_bytes) {
4542   TPM_RC result = TPM_RC_SUCCESS;
4543   VLOG(3) << __func__;
4544 
4545   result = Parse_UINT16(buffer, &value->size, value_bytes);
4546   if (result) {
4547     return result;
4548   }
4549 
4550   if (std::size(value->attestation_data) < value->size) {
4551     return TPM_RC_INSUFFICIENT;
4552   }
4553   for (uint32_t i = 0; i < value->size; ++i) {
4554     result = Parse_BYTE(buffer, &value->attestation_data[i], value_bytes);
4555     if (result) {
4556       return result;
4557     }
4558   }
4559   return result;
4560 }
4561 
Make_TPM2B_ATTEST(const std::string & bytes)4562 TPM2B_ATTEST Make_TPM2B_ATTEST(const std::string& bytes) {
4563   TPM2B_ATTEST tpm2b;
4564   CHECK(bytes.size() <= sizeof(tpm2b.attestation_data));
4565   memset(&tpm2b, 0, sizeof(TPM2B_ATTEST));
4566   tpm2b.size = bytes.size();
4567   memcpy(tpm2b.attestation_data, bytes.data(), bytes.size());
4568   return tpm2b;
4569 }
4570 
StringFrom_TPM2B_ATTEST(const TPM2B_ATTEST & tpm2b)4571 std::string StringFrom_TPM2B_ATTEST(const TPM2B_ATTEST& tpm2b) {
4572   CHECK(tpm2b.size <= std::size(tpm2b.attestation_data));
4573   const char* char_buffer =
4574       reinterpret_cast<const char*>(tpm2b.attestation_data);
4575   return std::string(char_buffer, tpm2b.size);
4576 }
4577 
Serialize_TPMS_AUTH_COMMAND(const TPMS_AUTH_COMMAND & value,std::string * buffer)4578 TPM_RC Serialize_TPMS_AUTH_COMMAND(const TPMS_AUTH_COMMAND& value,
4579                                    std::string* buffer) {
4580   TPM_RC result = TPM_RC_SUCCESS;
4581   VLOG(3) << __func__;
4582 
4583   result = Serialize_TPMI_SH_AUTH_SESSION(value.session_handle, buffer);
4584   if (result) {
4585     return result;
4586   }
4587 
4588   result = Serialize_TPM2B_NONCE(value.nonce, buffer);
4589   if (result) {
4590     return result;
4591   }
4592 
4593   result = Serialize_TPMA_SESSION(value.session_attributes, buffer);
4594   if (result) {
4595     return result;
4596   }
4597 
4598   result = Serialize_TPM2B_AUTH(value.hmac, buffer);
4599   if (result) {
4600     return result;
4601   }
4602   return result;
4603 }
4604 
Parse_TPMS_AUTH_COMMAND(std::string * buffer,TPMS_AUTH_COMMAND * value,std::string * value_bytes)4605 TPM_RC Parse_TPMS_AUTH_COMMAND(std::string* buffer,
4606                                TPMS_AUTH_COMMAND* value,
4607                                std::string* value_bytes) {
4608   TPM_RC result = TPM_RC_SUCCESS;
4609   VLOG(3) << __func__;
4610 
4611   result =
4612       Parse_TPMI_SH_AUTH_SESSION(buffer, &value->session_handle, value_bytes);
4613   if (result) {
4614     return result;
4615   }
4616 
4617   result = Parse_TPM2B_NONCE(buffer, &value->nonce, value_bytes);
4618   if (result) {
4619     return result;
4620   }
4621 
4622   result = Parse_TPMA_SESSION(buffer, &value->session_attributes, value_bytes);
4623   if (result) {
4624     return result;
4625   }
4626 
4627   result = Parse_TPM2B_AUTH(buffer, &value->hmac, value_bytes);
4628   if (result) {
4629     return result;
4630   }
4631   return result;
4632 }
4633 
Serialize_TPMS_AUTH_RESPONSE(const TPMS_AUTH_RESPONSE & value,std::string * buffer)4634 TPM_RC Serialize_TPMS_AUTH_RESPONSE(const TPMS_AUTH_RESPONSE& value,
4635                                     std::string* buffer) {
4636   TPM_RC result = TPM_RC_SUCCESS;
4637   VLOG(3) << __func__;
4638 
4639   result = Serialize_TPM2B_NONCE(value.nonce, buffer);
4640   if (result) {
4641     return result;
4642   }
4643 
4644   result = Serialize_TPMA_SESSION(value.session_attributes, buffer);
4645   if (result) {
4646     return result;
4647   }
4648 
4649   result = Serialize_TPM2B_AUTH(value.hmac, buffer);
4650   if (result) {
4651     return result;
4652   }
4653   return result;
4654 }
4655 
Parse_TPMS_AUTH_RESPONSE(std::string * buffer,TPMS_AUTH_RESPONSE * value,std::string * value_bytes)4656 TPM_RC Parse_TPMS_AUTH_RESPONSE(std::string* buffer,
4657                                 TPMS_AUTH_RESPONSE* value,
4658                                 std::string* value_bytes) {
4659   TPM_RC result = TPM_RC_SUCCESS;
4660   VLOG(3) << __func__;
4661 
4662   result = Parse_TPM2B_NONCE(buffer, &value->nonce, value_bytes);
4663   if (result) {
4664     return result;
4665   }
4666 
4667   result = Parse_TPMA_SESSION(buffer, &value->session_attributes, value_bytes);
4668   if (result) {
4669     return result;
4670   }
4671 
4672   result = Parse_TPM2B_AUTH(buffer, &value->hmac, value_bytes);
4673   if (result) {
4674     return result;
4675   }
4676   return result;
4677 }
4678 
Serialize_TPMU_SYM_KEY_BITS(const TPMU_SYM_KEY_BITS & value,TPMI_ALG_SYM selector,std::string * buffer)4679 TPM_RC Serialize_TPMU_SYM_KEY_BITS(const TPMU_SYM_KEY_BITS& value,
4680                                    TPMI_ALG_SYM selector,
4681                                    std::string* buffer) {
4682   TPM_RC result = TPM_RC_SUCCESS;
4683   VLOG(3) << __func__;
4684 
4685   if (selector == TPM_ALG_NULL) {
4686     // Do nothing.
4687   }
4688 
4689   if (selector == TPM_ALG_SM4) {
4690     result = Serialize_TPMI_SM4_KEY_BITS(value.sm4, buffer);
4691     if (result) {
4692       return result;
4693     }
4694   }
4695 
4696   if (selector == TPM_ALG_AES) {
4697     result = Serialize_TPMI_AES_KEY_BITS(value.aes, buffer);
4698     if (result) {
4699       return result;
4700     }
4701   }
4702 
4703   if (selector == TPM_ALG_XOR) {
4704     result = Serialize_TPMI_ALG_HASH(value.xor_, buffer);
4705     if (result) {
4706       return result;
4707     }
4708   }
4709   return result;
4710 }
4711 
Parse_TPMU_SYM_KEY_BITS(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_KEY_BITS * value,std::string * value_bytes)4712 TPM_RC Parse_TPMU_SYM_KEY_BITS(std::string* buffer,
4713                                TPMI_ALG_SYM selector,
4714                                TPMU_SYM_KEY_BITS* value,
4715                                std::string* value_bytes) {
4716   TPM_RC result = TPM_RC_SUCCESS;
4717   VLOG(3) << __func__;
4718 
4719   if (selector == TPM_ALG_NULL) {
4720     // Do nothing.
4721   }
4722 
4723   if (selector == TPM_ALG_SM4) {
4724     result = Parse_TPMI_SM4_KEY_BITS(buffer, &value->sm4, value_bytes);
4725     if (result) {
4726       return result;
4727     }
4728   }
4729 
4730   if (selector == TPM_ALG_AES) {
4731     result = Parse_TPMI_AES_KEY_BITS(buffer, &value->aes, value_bytes);
4732     if (result) {
4733       return result;
4734     }
4735   }
4736 
4737   if (selector == TPM_ALG_XOR) {
4738     result = Parse_TPMI_ALG_HASH(buffer, &value->xor_, value_bytes);
4739     if (result) {
4740       return result;
4741     }
4742   }
4743   return result;
4744 }
4745 
Serialize_TPMU_SYM_MODE(const TPMU_SYM_MODE & value,TPMI_ALG_SYM selector,std::string * buffer)4746 TPM_RC Serialize_TPMU_SYM_MODE(const TPMU_SYM_MODE& value,
4747                                TPMI_ALG_SYM selector,
4748                                std::string* buffer) {
4749   TPM_RC result = TPM_RC_SUCCESS;
4750   VLOG(3) << __func__;
4751 
4752   if (selector == TPM_ALG_NULL) {
4753     // Do nothing.
4754   }
4755 
4756   if (selector == TPM_ALG_SM4) {
4757     result = Serialize_TPMI_ALG_SYM_MODE(value.sm4, buffer);
4758     if (result) {
4759       return result;
4760     }
4761   }
4762 
4763   if (selector == TPM_ALG_AES) {
4764     result = Serialize_TPMI_ALG_SYM_MODE(value.aes, buffer);
4765     if (result) {
4766       return result;
4767     }
4768   }
4769 
4770   if (selector == TPM_ALG_XOR) {
4771     // Do nothing.
4772   }
4773   return result;
4774 }
4775 
Parse_TPMU_SYM_MODE(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_MODE * value,std::string * value_bytes)4776 TPM_RC Parse_TPMU_SYM_MODE(std::string* buffer,
4777                            TPMI_ALG_SYM selector,
4778                            TPMU_SYM_MODE* value,
4779                            std::string* value_bytes) {
4780   TPM_RC result = TPM_RC_SUCCESS;
4781   VLOG(3) << __func__;
4782 
4783   if (selector == TPM_ALG_NULL) {
4784     // Do nothing.
4785   }
4786 
4787   if (selector == TPM_ALG_SM4) {
4788     result = Parse_TPMI_ALG_SYM_MODE(buffer, &value->sm4, value_bytes);
4789     if (result) {
4790       return result;
4791     }
4792   }
4793 
4794   if (selector == TPM_ALG_AES) {
4795     result = Parse_TPMI_ALG_SYM_MODE(buffer, &value->aes, value_bytes);
4796     if (result) {
4797       return result;
4798     }
4799   }
4800 
4801   if (selector == TPM_ALG_XOR) {
4802     // Do nothing.
4803   }
4804   return result;
4805 }
4806 
Serialize_TPMU_SYM_DETAILS(const TPMU_SYM_DETAILS & value,TPMI_ALG_SYM selector,std::string * buffer)4807 TPM_RC Serialize_TPMU_SYM_DETAILS(const TPMU_SYM_DETAILS& value,
4808                                   TPMI_ALG_SYM selector,
4809                                   std::string* buffer) {
4810   TPM_RC result = TPM_RC_SUCCESS;
4811   VLOG(3) << __func__;
4812   return result;
4813 }
4814 
Parse_TPMU_SYM_DETAILS(std::string * buffer,TPMI_ALG_SYM selector,TPMU_SYM_DETAILS * value,std::string * value_bytes)4815 TPM_RC Parse_TPMU_SYM_DETAILS(std::string* buffer,
4816                               TPMI_ALG_SYM selector,
4817                               TPMU_SYM_DETAILS* value,
4818                               std::string* value_bytes) {
4819   TPM_RC result = TPM_RC_SUCCESS;
4820   VLOG(3) << __func__;
4821   return result;
4822 }
4823 
Serialize_TPMT_SYM_DEF(const TPMT_SYM_DEF & value,std::string * buffer)4824 TPM_RC Serialize_TPMT_SYM_DEF(const TPMT_SYM_DEF& value, std::string* buffer) {
4825   TPM_RC result = TPM_RC_SUCCESS;
4826   VLOG(3) << __func__;
4827 
4828   result = Serialize_TPMI_ALG_SYM(value.algorithm, buffer);
4829   if (result) {
4830     return result;
4831   }
4832 
4833   result = Serialize_TPMU_SYM_KEY_BITS(value.key_bits, value.algorithm, buffer);
4834   if (result) {
4835     return result;
4836   }
4837 
4838   result = Serialize_TPMU_SYM_MODE(value.mode, value.algorithm, buffer);
4839   if (result) {
4840     return result;
4841   }
4842 
4843   result = Serialize_TPMU_SYM_DETAILS(value.details, value.algorithm, buffer);
4844   if (result) {
4845     return result;
4846   }
4847   return result;
4848 }
4849 
Parse_TPMT_SYM_DEF(std::string * buffer,TPMT_SYM_DEF * value,std::string * value_bytes)4850 TPM_RC Parse_TPMT_SYM_DEF(std::string* buffer,
4851                           TPMT_SYM_DEF* value,
4852                           std::string* value_bytes) {
4853   TPM_RC result = TPM_RC_SUCCESS;
4854   VLOG(3) << __func__;
4855 
4856   result = Parse_TPMI_ALG_SYM(buffer, &value->algorithm, value_bytes);
4857   if (result) {
4858     return result;
4859   }
4860 
4861   result = Parse_TPMU_SYM_KEY_BITS(buffer, value->algorithm, &value->key_bits,
4862                                    value_bytes);
4863   if (result) {
4864     return result;
4865   }
4866 
4867   result =
4868       Parse_TPMU_SYM_MODE(buffer, value->algorithm, &value->mode, value_bytes);
4869   if (result) {
4870     return result;
4871   }
4872 
4873   result = Parse_TPMU_SYM_DETAILS(buffer, value->algorithm, &value->details,
4874                                   value_bytes);
4875   if (result) {
4876     return result;
4877   }
4878   return result;
4879 }
4880 
Serialize_TPMT_SYM_DEF_OBJECT(const TPMT_SYM_DEF_OBJECT & value,std::string * buffer)4881 TPM_RC Serialize_TPMT_SYM_DEF_OBJECT(const TPMT_SYM_DEF_OBJECT& value,
4882                                      std::string* buffer) {
4883   TPM_RC result = TPM_RC_SUCCESS;
4884   VLOG(3) << __func__;
4885 
4886   result = Serialize_TPMI_ALG_SYM_OBJECT(value.algorithm, buffer);
4887   if (result) {
4888     return result;
4889   }
4890 
4891   result = Serialize_TPMU_SYM_KEY_BITS(value.key_bits, value.algorithm, buffer);
4892   if (result) {
4893     return result;
4894   }
4895 
4896   result = Serialize_TPMU_SYM_MODE(value.mode, value.algorithm, buffer);
4897   if (result) {
4898     return result;
4899   }
4900 
4901   result = Serialize_TPMU_SYM_DETAILS(value.details, value.algorithm, buffer);
4902   if (result) {
4903     return result;
4904   }
4905   return result;
4906 }
4907 
Parse_TPMT_SYM_DEF_OBJECT(std::string * buffer,TPMT_SYM_DEF_OBJECT * value,std::string * value_bytes)4908 TPM_RC Parse_TPMT_SYM_DEF_OBJECT(std::string* buffer,
4909                                  TPMT_SYM_DEF_OBJECT* value,
4910                                  std::string* value_bytes) {
4911   TPM_RC result = TPM_RC_SUCCESS;
4912   VLOG(3) << __func__;
4913 
4914   result = Parse_TPMI_ALG_SYM_OBJECT(buffer, &value->algorithm, value_bytes);
4915   if (result) {
4916     return result;
4917   }
4918 
4919   result = Parse_TPMU_SYM_KEY_BITS(buffer, value->algorithm, &value->key_bits,
4920                                    value_bytes);
4921   if (result) {
4922     return result;
4923   }
4924 
4925   result =
4926       Parse_TPMU_SYM_MODE(buffer, value->algorithm, &value->mode, value_bytes);
4927   if (result) {
4928     return result;
4929   }
4930 
4931   result = Parse_TPMU_SYM_DETAILS(buffer, value->algorithm, &value->details,
4932                                   value_bytes);
4933   if (result) {
4934     return result;
4935   }
4936   return result;
4937 }
4938 
Serialize_TPM2B_SYM_KEY(const TPM2B_SYM_KEY & value,std::string * buffer)4939 TPM_RC Serialize_TPM2B_SYM_KEY(const TPM2B_SYM_KEY& value,
4940                                std::string* buffer) {
4941   TPM_RC result = TPM_RC_SUCCESS;
4942   VLOG(3) << __func__;
4943 
4944   result = Serialize_UINT16(value.size, buffer);
4945   if (result) {
4946     return result;
4947   }
4948 
4949   if (std::size(value.buffer) < value.size) {
4950     return TPM_RC_INSUFFICIENT;
4951   }
4952   for (uint32_t i = 0; i < value.size; ++i) {
4953     result = Serialize_BYTE(value.buffer[i], buffer);
4954     if (result) {
4955       return result;
4956     }
4957   }
4958   return result;
4959 }
4960 
Parse_TPM2B_SYM_KEY(std::string * buffer,TPM2B_SYM_KEY * value,std::string * value_bytes)4961 TPM_RC Parse_TPM2B_SYM_KEY(std::string* buffer,
4962                            TPM2B_SYM_KEY* value,
4963                            std::string* value_bytes) {
4964   TPM_RC result = TPM_RC_SUCCESS;
4965   VLOG(3) << __func__;
4966 
4967   result = Parse_UINT16(buffer, &value->size, value_bytes);
4968   if (result) {
4969     return result;
4970   }
4971 
4972   if (std::size(value->buffer) < value->size) {
4973     return TPM_RC_INSUFFICIENT;
4974   }
4975   for (uint32_t i = 0; i < value->size; ++i) {
4976     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
4977     if (result) {
4978       return result;
4979     }
4980   }
4981   return result;
4982 }
4983 
Make_TPM2B_SYM_KEY(const std::string & bytes)4984 TPM2B_SYM_KEY Make_TPM2B_SYM_KEY(const std::string& bytes) {
4985   TPM2B_SYM_KEY tpm2b;
4986   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
4987   memset(&tpm2b, 0, sizeof(TPM2B_SYM_KEY));
4988   tpm2b.size = bytes.size();
4989   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
4990   return tpm2b;
4991 }
4992 
StringFrom_TPM2B_SYM_KEY(const TPM2B_SYM_KEY & tpm2b)4993 std::string StringFrom_TPM2B_SYM_KEY(const TPM2B_SYM_KEY& tpm2b) {
4994   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
4995   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
4996   return std::string(char_buffer, tpm2b.size);
4997 }
4998 
Serialize_TPMS_SYMCIPHER_PARMS(const TPMS_SYMCIPHER_PARMS & value,std::string * buffer)4999 TPM_RC Serialize_TPMS_SYMCIPHER_PARMS(const TPMS_SYMCIPHER_PARMS& value,
5000                                       std::string* buffer) {
5001   TPM_RC result = TPM_RC_SUCCESS;
5002   VLOG(3) << __func__;
5003 
5004   result = Serialize_TPMT_SYM_DEF_OBJECT(value.sym, buffer);
5005   if (result) {
5006     return result;
5007   }
5008   return result;
5009 }
5010 
Parse_TPMS_SYMCIPHER_PARMS(std::string * buffer,TPMS_SYMCIPHER_PARMS * value,std::string * value_bytes)5011 TPM_RC Parse_TPMS_SYMCIPHER_PARMS(std::string* buffer,
5012                                   TPMS_SYMCIPHER_PARMS* value,
5013                                   std::string* value_bytes) {
5014   TPM_RC result = TPM_RC_SUCCESS;
5015   VLOG(3) << __func__;
5016 
5017   result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->sym, value_bytes);
5018   if (result) {
5019     return result;
5020   }
5021   return result;
5022 }
5023 
Serialize_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA & value,std::string * buffer)5024 TPM_RC Serialize_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA& value,
5025                                       std::string* buffer) {
5026   TPM_RC result = TPM_RC_SUCCESS;
5027   VLOG(3) << __func__;
5028 
5029   result = Serialize_UINT16(value.size, buffer);
5030   if (result) {
5031     return result;
5032   }
5033 
5034   if (std::size(value.buffer) < value.size) {
5035     return TPM_RC_INSUFFICIENT;
5036   }
5037   for (uint32_t i = 0; i < value.size; ++i) {
5038     result = Serialize_BYTE(value.buffer[i], buffer);
5039     if (result) {
5040       return result;
5041     }
5042   }
5043   return result;
5044 }
5045 
Parse_TPM2B_SENSITIVE_DATA(std::string * buffer,TPM2B_SENSITIVE_DATA * value,std::string * value_bytes)5046 TPM_RC Parse_TPM2B_SENSITIVE_DATA(std::string* buffer,
5047                                   TPM2B_SENSITIVE_DATA* value,
5048                                   std::string* value_bytes) {
5049   TPM_RC result = TPM_RC_SUCCESS;
5050   VLOG(3) << __func__;
5051 
5052   result = Parse_UINT16(buffer, &value->size, value_bytes);
5053   if (result) {
5054     return result;
5055   }
5056 
5057   if (std::size(value->buffer) < value->size) {
5058     return TPM_RC_INSUFFICIENT;
5059   }
5060   for (uint32_t i = 0; i < value->size; ++i) {
5061     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
5062     if (result) {
5063       return result;
5064     }
5065   }
5066   return result;
5067 }
5068 
Make_TPM2B_SENSITIVE_DATA(const std::string & bytes)5069 TPM2B_SENSITIVE_DATA Make_TPM2B_SENSITIVE_DATA(const std::string& bytes) {
5070   TPM2B_SENSITIVE_DATA tpm2b;
5071   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
5072   memset(&tpm2b, 0, sizeof(TPM2B_SENSITIVE_DATA));
5073   tpm2b.size = bytes.size();
5074   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
5075   return tpm2b;
5076 }
5077 
StringFrom_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA & tpm2b)5078 std::string StringFrom_TPM2B_SENSITIVE_DATA(const TPM2B_SENSITIVE_DATA& tpm2b) {
5079   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
5080   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
5081   return std::string(char_buffer, tpm2b.size);
5082 }
5083 
Serialize_TPMS_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE & value,std::string * buffer)5084 TPM_RC Serialize_TPMS_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE& value,
5085                                        std::string* buffer) {
5086   TPM_RC result = TPM_RC_SUCCESS;
5087   VLOG(3) << __func__;
5088 
5089   result = Serialize_TPM2B_AUTH(value.user_auth, buffer);
5090   if (result) {
5091     return result;
5092   }
5093 
5094   result = Serialize_TPM2B_SENSITIVE_DATA(value.data, buffer);
5095   if (result) {
5096     return result;
5097   }
5098   return result;
5099 }
5100 
Parse_TPMS_SENSITIVE_CREATE(std::string * buffer,TPMS_SENSITIVE_CREATE * value,std::string * value_bytes)5101 TPM_RC Parse_TPMS_SENSITIVE_CREATE(std::string* buffer,
5102                                    TPMS_SENSITIVE_CREATE* value,
5103                                    std::string* value_bytes) {
5104   TPM_RC result = TPM_RC_SUCCESS;
5105   VLOG(3) << __func__;
5106 
5107   result = Parse_TPM2B_AUTH(buffer, &value->user_auth, value_bytes);
5108   if (result) {
5109     return result;
5110   }
5111 
5112   result = Parse_TPM2B_SENSITIVE_DATA(buffer, &value->data, value_bytes);
5113   if (result) {
5114     return result;
5115   }
5116   return result;
5117 }
5118 
Serialize_TPM2B_SENSITIVE_CREATE(const TPM2B_SENSITIVE_CREATE & value,std::string * buffer)5119 TPM_RC Serialize_TPM2B_SENSITIVE_CREATE(const TPM2B_SENSITIVE_CREATE& value,
5120                                         std::string* buffer) {
5121   TPM_RC result = TPM_RC_SUCCESS;
5122   VLOG(3) << __func__;
5123 
5124   std::string field_bytes;
5125   if (value.size) {
5126     if (value.size != sizeof(TPMS_SENSITIVE_CREATE)) {
5127       return TPM_RC_SIZE;
5128     }
5129     result = Serialize_TPMS_SENSITIVE_CREATE(value.sensitive, &field_bytes);
5130     if (result) {
5131       return result;
5132     }
5133   }
5134   std::string size_bytes;
5135   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
5136   if (result) {
5137     return result;
5138   }
5139   buffer->append(size_bytes + field_bytes);
5140   return result;
5141 }
5142 
Parse_TPM2B_SENSITIVE_CREATE(std::string * buffer,TPM2B_SENSITIVE_CREATE * value,std::string * value_bytes)5143 TPM_RC Parse_TPM2B_SENSITIVE_CREATE(std::string* buffer,
5144                                     TPM2B_SENSITIVE_CREATE* value,
5145                                     std::string* value_bytes) {
5146   TPM_RC result = TPM_RC_SUCCESS;
5147   VLOG(3) << __func__;
5148 
5149   UINT16 parsed_size = 0;
5150   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
5151   if (result) {
5152     return result;
5153   }
5154   if (!parsed_size) {
5155     value->size = 0;
5156   } else {
5157     value->size = sizeof(TPMS_SENSITIVE_CREATE);
5158     result =
5159         Parse_TPMS_SENSITIVE_CREATE(buffer, &value->sensitive, value_bytes);
5160     if (result) {
5161       return result;
5162     }
5163   }
5164   return result;
5165 }
5166 
Make_TPM2B_SENSITIVE_CREATE(const TPMS_SENSITIVE_CREATE & inner)5167 TPM2B_SENSITIVE_CREATE Make_TPM2B_SENSITIVE_CREATE(
5168     const TPMS_SENSITIVE_CREATE& inner) {
5169   TPM2B_SENSITIVE_CREATE tpm2b;
5170   tpm2b.size = sizeof(TPMS_SENSITIVE_CREATE);
5171   tpm2b.sensitive = inner;
5172   return tpm2b;
5173 }
5174 
Serialize_TPMS_SCHEME_XOR(const TPMS_SCHEME_XOR & value,std::string * buffer)5175 TPM_RC Serialize_TPMS_SCHEME_XOR(const TPMS_SCHEME_XOR& value,
5176                                  std::string* buffer) {
5177   TPM_RC result = TPM_RC_SUCCESS;
5178   VLOG(3) << __func__;
5179 
5180   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5181   if (result) {
5182     return result;
5183   }
5184 
5185   result = Serialize_TPMI_ALG_KDF(value.kdf, buffer);
5186   if (result) {
5187     return result;
5188   }
5189   return result;
5190 }
5191 
Parse_TPMS_SCHEME_XOR(std::string * buffer,TPMS_SCHEME_XOR * value,std::string * value_bytes)5192 TPM_RC Parse_TPMS_SCHEME_XOR(std::string* buffer,
5193                              TPMS_SCHEME_XOR* value,
5194                              std::string* value_bytes) {
5195   TPM_RC result = TPM_RC_SUCCESS;
5196   VLOG(3) << __func__;
5197 
5198   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5199   if (result) {
5200     return result;
5201   }
5202 
5203   result = Parse_TPMI_ALG_KDF(buffer, &value->kdf, value_bytes);
5204   if (result) {
5205     return result;
5206   }
5207   return result;
5208 }
5209 
Serialize_TPMU_SCHEME_KEYEDHASH(const TPMU_SCHEME_KEYEDHASH & value,TPMI_ALG_KEYEDHASH_SCHEME selector,std::string * buffer)5210 TPM_RC Serialize_TPMU_SCHEME_KEYEDHASH(const TPMU_SCHEME_KEYEDHASH& value,
5211                                        TPMI_ALG_KEYEDHASH_SCHEME selector,
5212                                        std::string* buffer) {
5213   TPM_RC result = TPM_RC_SUCCESS;
5214   VLOG(3) << __func__;
5215 
5216   if (selector == TPM_ALG_NULL) {
5217     // Do nothing.
5218   }
5219 
5220   if (selector == TPM_ALG_HMAC) {
5221     result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer);
5222     if (result) {
5223       return result;
5224     }
5225   }
5226 
5227   if (selector == TPM_ALG_XOR) {
5228     result = Serialize_TPMS_SCHEME_XOR(value.xor_, buffer);
5229     if (result) {
5230       return result;
5231     }
5232   }
5233   return result;
5234 }
5235 
Parse_TPMU_SCHEME_KEYEDHASH(std::string * buffer,TPMI_ALG_KEYEDHASH_SCHEME selector,TPMU_SCHEME_KEYEDHASH * value,std::string * value_bytes)5236 TPM_RC Parse_TPMU_SCHEME_KEYEDHASH(std::string* buffer,
5237                                    TPMI_ALG_KEYEDHASH_SCHEME selector,
5238                                    TPMU_SCHEME_KEYEDHASH* value,
5239                                    std::string* value_bytes) {
5240   TPM_RC result = TPM_RC_SUCCESS;
5241   VLOG(3) << __func__;
5242 
5243   if (selector == TPM_ALG_NULL) {
5244     // Do nothing.
5245   }
5246 
5247   if (selector == TPM_ALG_HMAC) {
5248     result = Parse_TPMS_SCHEME_HMAC(buffer, &value->hmac, value_bytes);
5249     if (result) {
5250       return result;
5251     }
5252   }
5253 
5254   if (selector == TPM_ALG_XOR) {
5255     result = Parse_TPMS_SCHEME_XOR(buffer, &value->xor_, value_bytes);
5256     if (result) {
5257       return result;
5258     }
5259   }
5260   return result;
5261 }
5262 
Serialize_TPMT_KEYEDHASH_SCHEME(const TPMT_KEYEDHASH_SCHEME & value,std::string * buffer)5263 TPM_RC Serialize_TPMT_KEYEDHASH_SCHEME(const TPMT_KEYEDHASH_SCHEME& value,
5264                                        std::string* buffer) {
5265   TPM_RC result = TPM_RC_SUCCESS;
5266   VLOG(3) << __func__;
5267 
5268   result = Serialize_TPMI_ALG_KEYEDHASH_SCHEME(value.scheme, buffer);
5269   if (result) {
5270     return result;
5271   }
5272 
5273   result = Serialize_TPMU_SCHEME_KEYEDHASH(value.details, value.scheme, buffer);
5274   if (result) {
5275     return result;
5276   }
5277   return result;
5278 }
5279 
Parse_TPMT_KEYEDHASH_SCHEME(std::string * buffer,TPMT_KEYEDHASH_SCHEME * value,std::string * value_bytes)5280 TPM_RC Parse_TPMT_KEYEDHASH_SCHEME(std::string* buffer,
5281                                    TPMT_KEYEDHASH_SCHEME* value,
5282                                    std::string* value_bytes) {
5283   TPM_RC result = TPM_RC_SUCCESS;
5284   VLOG(3) << __func__;
5285 
5286   result = Parse_TPMI_ALG_KEYEDHASH_SCHEME(buffer, &value->scheme, value_bytes);
5287   if (result) {
5288     return result;
5289   }
5290 
5291   result = Parse_TPMU_SCHEME_KEYEDHASH(buffer, value->scheme, &value->details,
5292                                        value_bytes);
5293   if (result) {
5294     return result;
5295   }
5296   return result;
5297 }
5298 
Serialize_TPMS_SCHEME_ECDAA(const TPMS_SCHEME_ECDAA & value,std::string * buffer)5299 TPM_RC Serialize_TPMS_SCHEME_ECDAA(const TPMS_SCHEME_ECDAA& value,
5300                                    std::string* buffer) {
5301   TPM_RC result = TPM_RC_SUCCESS;
5302   VLOG(3) << __func__;
5303 
5304   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5305   if (result) {
5306     return result;
5307   }
5308 
5309   result = Serialize_UINT16(value.count, buffer);
5310   if (result) {
5311     return result;
5312   }
5313   return result;
5314 }
5315 
Parse_TPMS_SCHEME_ECDAA(std::string * buffer,TPMS_SCHEME_ECDAA * value,std::string * value_bytes)5316 TPM_RC Parse_TPMS_SCHEME_ECDAA(std::string* buffer,
5317                                TPMS_SCHEME_ECDAA* value,
5318                                std::string* value_bytes) {
5319   TPM_RC result = TPM_RC_SUCCESS;
5320   VLOG(3) << __func__;
5321 
5322   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5323   if (result) {
5324     return result;
5325   }
5326 
5327   result = Parse_UINT16(buffer, &value->count, value_bytes);
5328   if (result) {
5329     return result;
5330   }
5331   return result;
5332 }
5333 
Serialize_TPMU_SIG_SCHEME(const TPMU_SIG_SCHEME & value,TPMI_ALG_SIG_SCHEME selector,std::string * buffer)5334 TPM_RC Serialize_TPMU_SIG_SCHEME(const TPMU_SIG_SCHEME& value,
5335                                  TPMI_ALG_SIG_SCHEME selector,
5336                                  std::string* buffer) {
5337   TPM_RC result = TPM_RC_SUCCESS;
5338   VLOG(3) << __func__;
5339 
5340   if (selector == TPM_ALG_HMAC) {
5341     result = Serialize_TPMS_SCHEME_HMAC(value.hmac, buffer);
5342     if (result) {
5343       return result;
5344     }
5345   }
5346 
5347   if (selector == TPM_ALG_ECSCHNORR) {
5348     result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer);
5349     if (result) {
5350       return result;
5351     }
5352   }
5353 
5354   if (selector == TPM_ALG_RSAPSS) {
5355     result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer);
5356     if (result) {
5357       return result;
5358     }
5359   }
5360 
5361   if (selector == TPM_ALG_ECDAA) {
5362     result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer);
5363     if (result) {
5364       return result;
5365     }
5366   }
5367 
5368   if (selector == TPM_ALG_RSASSA) {
5369     result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer);
5370     if (result) {
5371       return result;
5372     }
5373   }
5374 
5375   if (selector == TPM_ALG_SM2) {
5376     result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer);
5377     if (result) {
5378       return result;
5379     }
5380   }
5381 
5382   if (selector == TPM_ALG_ECDSA) {
5383     result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer);
5384     if (result) {
5385       return result;
5386     }
5387   }
5388 
5389   if (selector == TPM_ALG_NULL) {
5390     // Do nothing.
5391   }
5392   return result;
5393 }
5394 
Parse_TPMU_SIG_SCHEME(std::string * buffer,TPMI_ALG_SIG_SCHEME selector,TPMU_SIG_SCHEME * value,std::string * value_bytes)5395 TPM_RC Parse_TPMU_SIG_SCHEME(std::string* buffer,
5396                              TPMI_ALG_SIG_SCHEME selector,
5397                              TPMU_SIG_SCHEME* value,
5398                              std::string* value_bytes) {
5399   TPM_RC result = TPM_RC_SUCCESS;
5400   VLOG(3) << __func__;
5401 
5402   if (selector == TPM_ALG_HMAC) {
5403     result = Parse_TPMS_SCHEME_HMAC(buffer, &value->hmac, value_bytes);
5404     if (result) {
5405       return result;
5406     }
5407   }
5408 
5409   if (selector == TPM_ALG_ECSCHNORR) {
5410     result =
5411         Parse_TPMS_SCHEME_ECSCHNORR(buffer, &value->ec_schnorr, value_bytes);
5412     if (result) {
5413       return result;
5414     }
5415   }
5416 
5417   if (selector == TPM_ALG_RSAPSS) {
5418     result = Parse_TPMS_SCHEME_RSAPSS(buffer, &value->rsapss, value_bytes);
5419     if (result) {
5420       return result;
5421     }
5422   }
5423 
5424   if (selector == TPM_ALG_ECDAA) {
5425     result = Parse_TPMS_SCHEME_ECDAA(buffer, &value->ecdaa, value_bytes);
5426     if (result) {
5427       return result;
5428     }
5429   }
5430 
5431   if (selector == TPM_ALG_RSASSA) {
5432     result = Parse_TPMS_SCHEME_RSASSA(buffer, &value->rsassa, value_bytes);
5433     if (result) {
5434       return result;
5435     }
5436   }
5437 
5438   if (selector == TPM_ALG_SM2) {
5439     result = Parse_TPMS_SCHEME_SM2(buffer, &value->sm2, value_bytes);
5440     if (result) {
5441       return result;
5442     }
5443   }
5444 
5445   if (selector == TPM_ALG_ECDSA) {
5446     result = Parse_TPMS_SCHEME_ECDSA(buffer, &value->ecdsa, value_bytes);
5447     if (result) {
5448       return result;
5449     }
5450   }
5451 
5452   if (selector == TPM_ALG_NULL) {
5453     // Do nothing.
5454   }
5455   return result;
5456 }
5457 
Serialize_TPMT_SIG_SCHEME(const TPMT_SIG_SCHEME & value,std::string * buffer)5458 TPM_RC Serialize_TPMT_SIG_SCHEME(const TPMT_SIG_SCHEME& value,
5459                                  std::string* buffer) {
5460   TPM_RC result = TPM_RC_SUCCESS;
5461   VLOG(3) << __func__;
5462 
5463   result = Serialize_TPMI_ALG_SIG_SCHEME(value.scheme, buffer);
5464   if (result) {
5465     return result;
5466   }
5467 
5468   result = Serialize_TPMU_SIG_SCHEME(value.details, value.scheme, buffer);
5469   if (result) {
5470     return result;
5471   }
5472   return result;
5473 }
5474 
Parse_TPMT_SIG_SCHEME(std::string * buffer,TPMT_SIG_SCHEME * value,std::string * value_bytes)5475 TPM_RC Parse_TPMT_SIG_SCHEME(std::string* buffer,
5476                              TPMT_SIG_SCHEME* value,
5477                              std::string* value_bytes) {
5478   TPM_RC result = TPM_RC_SUCCESS;
5479   VLOG(3) << __func__;
5480 
5481   result = Parse_TPMI_ALG_SIG_SCHEME(buffer, &value->scheme, value_bytes);
5482   if (result) {
5483     return result;
5484   }
5485 
5486   result = Parse_TPMU_SIG_SCHEME(buffer, value->scheme, &value->details,
5487                                  value_bytes);
5488   if (result) {
5489     return result;
5490   }
5491   return result;
5492 }
5493 
Serialize_TPMS_SCHEME_OAEP(const TPMS_SCHEME_OAEP & value,std::string * buffer)5494 TPM_RC Serialize_TPMS_SCHEME_OAEP(const TPMS_SCHEME_OAEP& value,
5495                                   std::string* buffer) {
5496   TPM_RC result = TPM_RC_SUCCESS;
5497   VLOG(3) << __func__;
5498 
5499   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5500   if (result) {
5501     return result;
5502   }
5503   return result;
5504 }
5505 
Parse_TPMS_SCHEME_OAEP(std::string * buffer,TPMS_SCHEME_OAEP * value,std::string * value_bytes)5506 TPM_RC Parse_TPMS_SCHEME_OAEP(std::string* buffer,
5507                               TPMS_SCHEME_OAEP* value,
5508                               std::string* value_bytes) {
5509   TPM_RC result = TPM_RC_SUCCESS;
5510   VLOG(3) << __func__;
5511 
5512   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5513   if (result) {
5514     return result;
5515   }
5516   return result;
5517 }
5518 
Serialize_TPMS_SCHEME_ECDH(const TPMS_SCHEME_ECDH & value,std::string * buffer)5519 TPM_RC Serialize_TPMS_SCHEME_ECDH(const TPMS_SCHEME_ECDH& value,
5520                                   std::string* buffer) {
5521   TPM_RC result = TPM_RC_SUCCESS;
5522   VLOG(3) << __func__;
5523 
5524   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5525   if (result) {
5526     return result;
5527   }
5528   return result;
5529 }
5530 
Parse_TPMS_SCHEME_ECDH(std::string * buffer,TPMS_SCHEME_ECDH * value,std::string * value_bytes)5531 TPM_RC Parse_TPMS_SCHEME_ECDH(std::string* buffer,
5532                               TPMS_SCHEME_ECDH* value,
5533                               std::string* value_bytes) {
5534   TPM_RC result = TPM_RC_SUCCESS;
5535   VLOG(3) << __func__;
5536 
5537   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5538   if (result) {
5539     return result;
5540   }
5541   return result;
5542 }
5543 
Serialize_TPMS_SCHEME_MGF1(const TPMS_SCHEME_MGF1 & value,std::string * buffer)5544 TPM_RC Serialize_TPMS_SCHEME_MGF1(const TPMS_SCHEME_MGF1& value,
5545                                   std::string* buffer) {
5546   TPM_RC result = TPM_RC_SUCCESS;
5547   VLOG(3) << __func__;
5548 
5549   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5550   if (result) {
5551     return result;
5552   }
5553   return result;
5554 }
5555 
Parse_TPMS_SCHEME_MGF1(std::string * buffer,TPMS_SCHEME_MGF1 * value,std::string * value_bytes)5556 TPM_RC Parse_TPMS_SCHEME_MGF1(std::string* buffer,
5557                               TPMS_SCHEME_MGF1* value,
5558                               std::string* value_bytes) {
5559   TPM_RC result = TPM_RC_SUCCESS;
5560   VLOG(3) << __func__;
5561 
5562   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5563   if (result) {
5564     return result;
5565   }
5566   return result;
5567 }
5568 
Serialize_TPMS_SCHEME_KDF1_SP800_56a(const TPMS_SCHEME_KDF1_SP800_56a & value,std::string * buffer)5569 TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_56a(
5570     const TPMS_SCHEME_KDF1_SP800_56a& value, std::string* buffer) {
5571   TPM_RC result = TPM_RC_SUCCESS;
5572   VLOG(3) << __func__;
5573 
5574   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5575   if (result) {
5576     return result;
5577   }
5578   return result;
5579 }
5580 
Parse_TPMS_SCHEME_KDF1_SP800_56a(std::string * buffer,TPMS_SCHEME_KDF1_SP800_56a * value,std::string * value_bytes)5581 TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_56a(std::string* buffer,
5582                                         TPMS_SCHEME_KDF1_SP800_56a* value,
5583                                         std::string* value_bytes) {
5584   TPM_RC result = TPM_RC_SUCCESS;
5585   VLOG(3) << __func__;
5586 
5587   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5588   if (result) {
5589     return result;
5590   }
5591   return result;
5592 }
5593 
Serialize_TPMS_SCHEME_KDF2(const TPMS_SCHEME_KDF2 & value,std::string * buffer)5594 TPM_RC Serialize_TPMS_SCHEME_KDF2(const TPMS_SCHEME_KDF2& value,
5595                                   std::string* buffer) {
5596   TPM_RC result = TPM_RC_SUCCESS;
5597   VLOG(3) << __func__;
5598 
5599   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5600   if (result) {
5601     return result;
5602   }
5603   return result;
5604 }
5605 
Parse_TPMS_SCHEME_KDF2(std::string * buffer,TPMS_SCHEME_KDF2 * value,std::string * value_bytes)5606 TPM_RC Parse_TPMS_SCHEME_KDF2(std::string* buffer,
5607                               TPMS_SCHEME_KDF2* value,
5608                               std::string* value_bytes) {
5609   TPM_RC result = TPM_RC_SUCCESS;
5610   VLOG(3) << __func__;
5611 
5612   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5613   if (result) {
5614     return result;
5615   }
5616   return result;
5617 }
5618 
Serialize_TPMS_SCHEME_KDF1_SP800_108(const TPMS_SCHEME_KDF1_SP800_108 & value,std::string * buffer)5619 TPM_RC Serialize_TPMS_SCHEME_KDF1_SP800_108(
5620     const TPMS_SCHEME_KDF1_SP800_108& value, std::string* buffer) {
5621   TPM_RC result = TPM_RC_SUCCESS;
5622   VLOG(3) << __func__;
5623 
5624   result = Serialize_TPMI_ALG_HASH(value.hash_alg, buffer);
5625   if (result) {
5626     return result;
5627   }
5628   return result;
5629 }
5630 
Parse_TPMS_SCHEME_KDF1_SP800_108(std::string * buffer,TPMS_SCHEME_KDF1_SP800_108 * value,std::string * value_bytes)5631 TPM_RC Parse_TPMS_SCHEME_KDF1_SP800_108(std::string* buffer,
5632                                         TPMS_SCHEME_KDF1_SP800_108* value,
5633                                         std::string* value_bytes) {
5634   TPM_RC result = TPM_RC_SUCCESS;
5635   VLOG(3) << __func__;
5636 
5637   result = Parse_TPMI_ALG_HASH(buffer, &value->hash_alg, value_bytes);
5638   if (result) {
5639     return result;
5640   }
5641   return result;
5642 }
5643 
Serialize_TPMU_KDF_SCHEME(const TPMU_KDF_SCHEME & value,TPMI_ALG_KDF selector,std::string * buffer)5644 TPM_RC Serialize_TPMU_KDF_SCHEME(const TPMU_KDF_SCHEME& value,
5645                                  TPMI_ALG_KDF selector,
5646                                  std::string* buffer) {
5647   TPM_RC result = TPM_RC_SUCCESS;
5648   VLOG(3) << __func__;
5649 
5650   if (selector == TPM_ALG_KDF1_SP800_56a) {
5651     result = Serialize_TPMS_SCHEME_KDF1_SP800_56a(value.kdf1_sp800_56a, buffer);
5652     if (result) {
5653       return result;
5654     }
5655   }
5656 
5657   if (selector == TPM_ALG_MGF1) {
5658     result = Serialize_TPMS_SCHEME_MGF1(value.mgf1, buffer);
5659     if (result) {
5660       return result;
5661     }
5662   }
5663 
5664   if (selector == TPM_ALG_KDF1_SP800_108) {
5665     result = Serialize_TPMS_SCHEME_KDF1_SP800_108(value.kdf1_sp800_108, buffer);
5666     if (result) {
5667       return result;
5668     }
5669   }
5670 
5671   if (selector == TPM_ALG_KDF2) {
5672     result = Serialize_TPMS_SCHEME_KDF2(value.kdf2, buffer);
5673     if (result) {
5674       return result;
5675     }
5676   }
5677 
5678   if (selector == TPM_ALG_NULL) {
5679     // Do nothing.
5680   }
5681   return result;
5682 }
5683 
Parse_TPMU_KDF_SCHEME(std::string * buffer,TPMI_ALG_KDF selector,TPMU_KDF_SCHEME * value,std::string * value_bytes)5684 TPM_RC Parse_TPMU_KDF_SCHEME(std::string* buffer,
5685                              TPMI_ALG_KDF selector,
5686                              TPMU_KDF_SCHEME* value,
5687                              std::string* value_bytes) {
5688   TPM_RC result = TPM_RC_SUCCESS;
5689   VLOG(3) << __func__;
5690 
5691   if (selector == TPM_ALG_KDF1_SP800_56a) {
5692     result = Parse_TPMS_SCHEME_KDF1_SP800_56a(buffer, &value->kdf1_sp800_56a,
5693                                               value_bytes);
5694     if (result) {
5695       return result;
5696     }
5697   }
5698 
5699   if (selector == TPM_ALG_MGF1) {
5700     result = Parse_TPMS_SCHEME_MGF1(buffer, &value->mgf1, value_bytes);
5701     if (result) {
5702       return result;
5703     }
5704   }
5705 
5706   if (selector == TPM_ALG_KDF1_SP800_108) {
5707     result = Parse_TPMS_SCHEME_KDF1_SP800_108(buffer, &value->kdf1_sp800_108,
5708                                               value_bytes);
5709     if (result) {
5710       return result;
5711     }
5712   }
5713 
5714   if (selector == TPM_ALG_KDF2) {
5715     result = Parse_TPMS_SCHEME_KDF2(buffer, &value->kdf2, value_bytes);
5716     if (result) {
5717       return result;
5718     }
5719   }
5720 
5721   if (selector == TPM_ALG_NULL) {
5722     // Do nothing.
5723   }
5724   return result;
5725 }
5726 
Serialize_TPMT_KDF_SCHEME(const TPMT_KDF_SCHEME & value,std::string * buffer)5727 TPM_RC Serialize_TPMT_KDF_SCHEME(const TPMT_KDF_SCHEME& value,
5728                                  std::string* buffer) {
5729   TPM_RC result = TPM_RC_SUCCESS;
5730   VLOG(3) << __func__;
5731 
5732   result = Serialize_TPMI_ALG_KDF(value.scheme, buffer);
5733   if (result) {
5734     return result;
5735   }
5736 
5737   result = Serialize_TPMU_KDF_SCHEME(value.details, value.scheme, buffer);
5738   if (result) {
5739     return result;
5740   }
5741   return result;
5742 }
5743 
Parse_TPMT_KDF_SCHEME(std::string * buffer,TPMT_KDF_SCHEME * value,std::string * value_bytes)5744 TPM_RC Parse_TPMT_KDF_SCHEME(std::string* buffer,
5745                              TPMT_KDF_SCHEME* value,
5746                              std::string* value_bytes) {
5747   TPM_RC result = TPM_RC_SUCCESS;
5748   VLOG(3) << __func__;
5749 
5750   result = Parse_TPMI_ALG_KDF(buffer, &value->scheme, value_bytes);
5751   if (result) {
5752     return result;
5753   }
5754 
5755   result = Parse_TPMU_KDF_SCHEME(buffer, value->scheme, &value->details,
5756                                  value_bytes);
5757   if (result) {
5758     return result;
5759   }
5760   return result;
5761 }
5762 
Serialize_TPMU_ASYM_SCHEME(const TPMU_ASYM_SCHEME & value,TPMI_ALG_ASYM_SCHEME selector,std::string * buffer)5763 TPM_RC Serialize_TPMU_ASYM_SCHEME(const TPMU_ASYM_SCHEME& value,
5764                                   TPMI_ALG_ASYM_SCHEME selector,
5765                                   std::string* buffer) {
5766   TPM_RC result = TPM_RC_SUCCESS;
5767   VLOG(3) << __func__;
5768 
5769   if (selector == TPM_ALG_RSAES) {
5770     // Do nothing.
5771   }
5772 
5773   if (selector == TPM_ALG_ECSCHNORR) {
5774     result = Serialize_TPMS_SCHEME_ECSCHNORR(value.ec_schnorr, buffer);
5775     if (result) {
5776       return result;
5777     }
5778   }
5779 
5780   if (selector == TPM_ALG_NULL) {
5781     // Do nothing.
5782   }
5783 
5784   if (selector == TPM_ALG_ECDH) {
5785     result = Serialize_TPMS_SCHEME_ECDH(value.ecdh, buffer);
5786     if (result) {
5787       return result;
5788     }
5789   }
5790 
5791   if (selector == TPM_ALG_OAEP) {
5792     result = Serialize_TPMS_SCHEME_OAEP(value.oaep, buffer);
5793     if (result) {
5794       return result;
5795     }
5796   }
5797 
5798   if (selector == TPM_ALG_RSAPSS) {
5799     result = Serialize_TPMS_SCHEME_RSAPSS(value.rsapss, buffer);
5800     if (result) {
5801       return result;
5802     }
5803   }
5804 
5805   if (selector == TPM_ALG_ECDAA) {
5806     result = Serialize_TPMS_SCHEME_ECDAA(value.ecdaa, buffer);
5807     if (result) {
5808       return result;
5809     }
5810   }
5811 
5812   if (selector == TPM_ALG_RSASSA) {
5813     result = Serialize_TPMS_SCHEME_RSASSA(value.rsassa, buffer);
5814     if (result) {
5815       return result;
5816     }
5817   }
5818 
5819   if (selector == TPM_ALG_SM2) {
5820     result = Serialize_TPMS_SCHEME_SM2(value.sm2, buffer);
5821     if (result) {
5822       return result;
5823     }
5824   }
5825 
5826   if (selector == TPM_ALG_ECDSA) {
5827     result = Serialize_TPMS_SCHEME_ECDSA(value.ecdsa, buffer);
5828     if (result) {
5829       return result;
5830     }
5831   }
5832   return result;
5833 }
5834 
Parse_TPMU_ASYM_SCHEME(std::string * buffer,TPMI_ALG_ASYM_SCHEME selector,TPMU_ASYM_SCHEME * value,std::string * value_bytes)5835 TPM_RC Parse_TPMU_ASYM_SCHEME(std::string* buffer,
5836                               TPMI_ALG_ASYM_SCHEME selector,
5837                               TPMU_ASYM_SCHEME* value,
5838                               std::string* value_bytes) {
5839   TPM_RC result = TPM_RC_SUCCESS;
5840   VLOG(3) << __func__;
5841 
5842   if (selector == TPM_ALG_RSAES) {
5843     // Do nothing.
5844   }
5845 
5846   if (selector == TPM_ALG_ECSCHNORR) {
5847     result =
5848         Parse_TPMS_SCHEME_ECSCHNORR(buffer, &value->ec_schnorr, value_bytes);
5849     if (result) {
5850       return result;
5851     }
5852   }
5853 
5854   if (selector == TPM_ALG_NULL) {
5855     // Do nothing.
5856   }
5857 
5858   if (selector == TPM_ALG_ECDH) {
5859     result = Parse_TPMS_SCHEME_ECDH(buffer, &value->ecdh, value_bytes);
5860     if (result) {
5861       return result;
5862     }
5863   }
5864 
5865   if (selector == TPM_ALG_OAEP) {
5866     result = Parse_TPMS_SCHEME_OAEP(buffer, &value->oaep, value_bytes);
5867     if (result) {
5868       return result;
5869     }
5870   }
5871 
5872   if (selector == TPM_ALG_RSAPSS) {
5873     result = Parse_TPMS_SCHEME_RSAPSS(buffer, &value->rsapss, value_bytes);
5874     if (result) {
5875       return result;
5876     }
5877   }
5878 
5879   if (selector == TPM_ALG_ECDAA) {
5880     result = Parse_TPMS_SCHEME_ECDAA(buffer, &value->ecdaa, value_bytes);
5881     if (result) {
5882       return result;
5883     }
5884   }
5885 
5886   if (selector == TPM_ALG_RSASSA) {
5887     result = Parse_TPMS_SCHEME_RSASSA(buffer, &value->rsassa, value_bytes);
5888     if (result) {
5889       return result;
5890     }
5891   }
5892 
5893   if (selector == TPM_ALG_SM2) {
5894     result = Parse_TPMS_SCHEME_SM2(buffer, &value->sm2, value_bytes);
5895     if (result) {
5896       return result;
5897     }
5898   }
5899 
5900   if (selector == TPM_ALG_ECDSA) {
5901     result = Parse_TPMS_SCHEME_ECDSA(buffer, &value->ecdsa, value_bytes);
5902     if (result) {
5903       return result;
5904     }
5905   }
5906   return result;
5907 }
5908 
Serialize_TPMT_ASYM_SCHEME(const TPMT_ASYM_SCHEME & value,std::string * buffer)5909 TPM_RC Serialize_TPMT_ASYM_SCHEME(const TPMT_ASYM_SCHEME& value,
5910                                   std::string* buffer) {
5911   TPM_RC result = TPM_RC_SUCCESS;
5912   VLOG(3) << __func__;
5913 
5914   result = Serialize_TPMI_ALG_ASYM_SCHEME(value.scheme, buffer);
5915   if (result) {
5916     return result;
5917   }
5918 
5919   result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5920   if (result) {
5921     return result;
5922   }
5923   return result;
5924 }
5925 
Parse_TPMT_ASYM_SCHEME(std::string * buffer,TPMT_ASYM_SCHEME * value,std::string * value_bytes)5926 TPM_RC Parse_TPMT_ASYM_SCHEME(std::string* buffer,
5927                               TPMT_ASYM_SCHEME* value,
5928                               std::string* value_bytes) {
5929   TPM_RC result = TPM_RC_SUCCESS;
5930   VLOG(3) << __func__;
5931 
5932   result = Parse_TPMI_ALG_ASYM_SCHEME(buffer, &value->scheme, value_bytes);
5933   if (result) {
5934     return result;
5935   }
5936 
5937   result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5938                                   value_bytes);
5939   if (result) {
5940     return result;
5941   }
5942   return result;
5943 }
5944 
Serialize_TPMT_RSA_SCHEME(const TPMT_RSA_SCHEME & value,std::string * buffer)5945 TPM_RC Serialize_TPMT_RSA_SCHEME(const TPMT_RSA_SCHEME& value,
5946                                  std::string* buffer) {
5947   TPM_RC result = TPM_RC_SUCCESS;
5948   VLOG(3) << __func__;
5949 
5950   result = Serialize_TPMI_ALG_RSA_SCHEME(value.scheme, buffer);
5951   if (result) {
5952     return result;
5953   }
5954 
5955   result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5956   if (result) {
5957     return result;
5958   }
5959   return result;
5960 }
5961 
Parse_TPMT_RSA_SCHEME(std::string * buffer,TPMT_RSA_SCHEME * value,std::string * value_bytes)5962 TPM_RC Parse_TPMT_RSA_SCHEME(std::string* buffer,
5963                              TPMT_RSA_SCHEME* value,
5964                              std::string* value_bytes) {
5965   TPM_RC result = TPM_RC_SUCCESS;
5966   VLOG(3) << __func__;
5967 
5968   result = Parse_TPMI_ALG_RSA_SCHEME(buffer, &value->scheme, value_bytes);
5969   if (result) {
5970     return result;
5971   }
5972 
5973   result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
5974                                   value_bytes);
5975   if (result) {
5976     return result;
5977   }
5978   return result;
5979 }
5980 
Serialize_TPMT_RSA_DECRYPT(const TPMT_RSA_DECRYPT & value,std::string * buffer)5981 TPM_RC Serialize_TPMT_RSA_DECRYPT(const TPMT_RSA_DECRYPT& value,
5982                                   std::string* buffer) {
5983   TPM_RC result = TPM_RC_SUCCESS;
5984   VLOG(3) << __func__;
5985 
5986   result = Serialize_TPMI_ALG_RSA_DECRYPT(value.scheme, buffer);
5987   if (result) {
5988     return result;
5989   }
5990 
5991   result = Serialize_TPMU_ASYM_SCHEME(value.details, value.scheme, buffer);
5992   if (result) {
5993     return result;
5994   }
5995   return result;
5996 }
5997 
Parse_TPMT_RSA_DECRYPT(std::string * buffer,TPMT_RSA_DECRYPT * value,std::string * value_bytes)5998 TPM_RC Parse_TPMT_RSA_DECRYPT(std::string* buffer,
5999                               TPMT_RSA_DECRYPT* value,
6000                               std::string* value_bytes) {
6001   TPM_RC result = TPM_RC_SUCCESS;
6002   VLOG(3) << __func__;
6003 
6004   result = Parse_TPMI_ALG_RSA_DECRYPT(buffer, &value->scheme, value_bytes);
6005   if (result) {
6006     return result;
6007   }
6008 
6009   result = Parse_TPMU_ASYM_SCHEME(buffer, value->scheme, &value->details,
6010                                   value_bytes);
6011   if (result) {
6012     return result;
6013   }
6014   return result;
6015 }
6016 
Serialize_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA & value,std::string * buffer)6017 TPM_RC Serialize_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA& value,
6018                                       std::string* buffer) {
6019   TPM_RC result = TPM_RC_SUCCESS;
6020   VLOG(3) << __func__;
6021 
6022   result = Serialize_UINT16(value.size, buffer);
6023   if (result) {
6024     return result;
6025   }
6026 
6027   if (std::size(value.buffer) < value.size) {
6028     return TPM_RC_INSUFFICIENT;
6029   }
6030   for (uint32_t i = 0; i < value.size; ++i) {
6031     result = Serialize_BYTE(value.buffer[i], buffer);
6032     if (result) {
6033       return result;
6034     }
6035   }
6036   return result;
6037 }
6038 
Parse_TPM2B_PUBLIC_KEY_RSA(std::string * buffer,TPM2B_PUBLIC_KEY_RSA * value,std::string * value_bytes)6039 TPM_RC Parse_TPM2B_PUBLIC_KEY_RSA(std::string* buffer,
6040                                   TPM2B_PUBLIC_KEY_RSA* value,
6041                                   std::string* value_bytes) {
6042   TPM_RC result = TPM_RC_SUCCESS;
6043   VLOG(3) << __func__;
6044 
6045   result = Parse_UINT16(buffer, &value->size, value_bytes);
6046   if (result) {
6047     return result;
6048   }
6049 
6050   if (std::size(value->buffer) < value->size) {
6051     return TPM_RC_INSUFFICIENT;
6052   }
6053   for (uint32_t i = 0; i < value->size; ++i) {
6054     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6055     if (result) {
6056       return result;
6057     }
6058   }
6059   return result;
6060 }
6061 
Make_TPM2B_PUBLIC_KEY_RSA(const std::string & bytes)6062 TPM2B_PUBLIC_KEY_RSA Make_TPM2B_PUBLIC_KEY_RSA(const std::string& bytes) {
6063   TPM2B_PUBLIC_KEY_RSA tpm2b;
6064   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6065   memset(&tpm2b, 0, sizeof(TPM2B_PUBLIC_KEY_RSA));
6066   tpm2b.size = bytes.size();
6067   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6068   return tpm2b;
6069 }
6070 
StringFrom_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA & tpm2b)6071 std::string StringFrom_TPM2B_PUBLIC_KEY_RSA(const TPM2B_PUBLIC_KEY_RSA& tpm2b) {
6072   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6073   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6074   return std::string(char_buffer, tpm2b.size);
6075 }
6076 
Serialize_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA & value,std::string * buffer)6077 TPM_RC Serialize_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA& value,
6078                                        std::string* buffer) {
6079   TPM_RC result = TPM_RC_SUCCESS;
6080   VLOG(3) << __func__;
6081 
6082   result = Serialize_UINT16(value.size, buffer);
6083   if (result) {
6084     return result;
6085   }
6086 
6087   if (std::size(value.buffer) < value.size) {
6088     return TPM_RC_INSUFFICIENT;
6089   }
6090   for (uint32_t i = 0; i < value.size; ++i) {
6091     result = Serialize_BYTE(value.buffer[i], buffer);
6092     if (result) {
6093       return result;
6094     }
6095   }
6096   return result;
6097 }
6098 
Parse_TPM2B_PRIVATE_KEY_RSA(std::string * buffer,TPM2B_PRIVATE_KEY_RSA * value,std::string * value_bytes)6099 TPM_RC Parse_TPM2B_PRIVATE_KEY_RSA(std::string* buffer,
6100                                    TPM2B_PRIVATE_KEY_RSA* value,
6101                                    std::string* value_bytes) {
6102   TPM_RC result = TPM_RC_SUCCESS;
6103   VLOG(3) << __func__;
6104 
6105   result = Parse_UINT16(buffer, &value->size, value_bytes);
6106   if (result) {
6107     return result;
6108   }
6109 
6110   if (std::size(value->buffer) < value->size) {
6111     return TPM_RC_INSUFFICIENT;
6112   }
6113   for (uint32_t i = 0; i < value->size; ++i) {
6114     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6115     if (result) {
6116       return result;
6117     }
6118   }
6119   return result;
6120 }
6121 
Make_TPM2B_PRIVATE_KEY_RSA(const std::string & bytes)6122 TPM2B_PRIVATE_KEY_RSA Make_TPM2B_PRIVATE_KEY_RSA(const std::string& bytes) {
6123   TPM2B_PRIVATE_KEY_RSA tpm2b;
6124   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6125   memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_KEY_RSA));
6126   tpm2b.size = bytes.size();
6127   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6128   return tpm2b;
6129 }
6130 
StringFrom_TPM2B_PRIVATE_KEY_RSA(const TPM2B_PRIVATE_KEY_RSA & tpm2b)6131 std::string StringFrom_TPM2B_PRIVATE_KEY_RSA(
6132     const TPM2B_PRIVATE_KEY_RSA& tpm2b) {
6133   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6134   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6135   return std::string(char_buffer, tpm2b.size);
6136 }
6137 
Serialize_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER & value,std::string * buffer)6138 TPM_RC Serialize_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER& value,
6139                                      std::string* buffer) {
6140   TPM_RC result = TPM_RC_SUCCESS;
6141   VLOG(3) << __func__;
6142 
6143   result = Serialize_UINT16(value.size, buffer);
6144   if (result) {
6145     return result;
6146   }
6147 
6148   if (std::size(value.buffer) < value.size) {
6149     return TPM_RC_INSUFFICIENT;
6150   }
6151   for (uint32_t i = 0; i < value.size; ++i) {
6152     result = Serialize_BYTE(value.buffer[i], buffer);
6153     if (result) {
6154       return result;
6155     }
6156   }
6157   return result;
6158 }
6159 
Parse_TPM2B_ECC_PARAMETER(std::string * buffer,TPM2B_ECC_PARAMETER * value,std::string * value_bytes)6160 TPM_RC Parse_TPM2B_ECC_PARAMETER(std::string* buffer,
6161                                  TPM2B_ECC_PARAMETER* value,
6162                                  std::string* value_bytes) {
6163   TPM_RC result = TPM_RC_SUCCESS;
6164   VLOG(3) << __func__;
6165 
6166   result = Parse_UINT16(buffer, &value->size, value_bytes);
6167   if (result) {
6168     return result;
6169   }
6170 
6171   if (std::size(value->buffer) < value->size) {
6172     return TPM_RC_INSUFFICIENT;
6173   }
6174   for (uint32_t i = 0; i < value->size; ++i) {
6175     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
6176     if (result) {
6177       return result;
6178     }
6179   }
6180   return result;
6181 }
6182 
Make_TPM2B_ECC_PARAMETER(const std::string & bytes)6183 TPM2B_ECC_PARAMETER Make_TPM2B_ECC_PARAMETER(const std::string& bytes) {
6184   TPM2B_ECC_PARAMETER tpm2b;
6185   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
6186   memset(&tpm2b, 0, sizeof(TPM2B_ECC_PARAMETER));
6187   tpm2b.size = bytes.size();
6188   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
6189   return tpm2b;
6190 }
6191 
StringFrom_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER & tpm2b)6192 std::string StringFrom_TPM2B_ECC_PARAMETER(const TPM2B_ECC_PARAMETER& tpm2b) {
6193   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
6194   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
6195   return std::string(char_buffer, tpm2b.size);
6196 }
6197 
Serialize_TPMS_ECC_POINT(const TPMS_ECC_POINT & value,std::string * buffer)6198 TPM_RC Serialize_TPMS_ECC_POINT(const TPMS_ECC_POINT& value,
6199                                 std::string* buffer) {
6200   TPM_RC result = TPM_RC_SUCCESS;
6201   VLOG(3) << __func__;
6202 
6203   result = Serialize_TPM2B_ECC_PARAMETER(value.x, buffer);
6204   if (result) {
6205     return result;
6206   }
6207 
6208   result = Serialize_TPM2B_ECC_PARAMETER(value.y, buffer);
6209   if (result) {
6210     return result;
6211   }
6212   return result;
6213 }
6214 
Parse_TPMS_ECC_POINT(std::string * buffer,TPMS_ECC_POINT * value,std::string * value_bytes)6215 TPM_RC Parse_TPMS_ECC_POINT(std::string* buffer,
6216                             TPMS_ECC_POINT* value,
6217                             std::string* value_bytes) {
6218   TPM_RC result = TPM_RC_SUCCESS;
6219   VLOG(3) << __func__;
6220 
6221   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->x, value_bytes);
6222   if (result) {
6223     return result;
6224   }
6225 
6226   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->y, value_bytes);
6227   if (result) {
6228     return result;
6229   }
6230   return result;
6231 }
6232 
Serialize_TPM2B_ECC_POINT(const TPM2B_ECC_POINT & value,std::string * buffer)6233 TPM_RC Serialize_TPM2B_ECC_POINT(const TPM2B_ECC_POINT& value,
6234                                  std::string* buffer) {
6235   TPM_RC result = TPM_RC_SUCCESS;
6236   VLOG(3) << __func__;
6237 
6238   std::string field_bytes;
6239   if (value.size) {
6240     if (value.size != sizeof(TPMS_ECC_POINT)) {
6241       return TPM_RC_SIZE;
6242     }
6243     result = Serialize_TPMS_ECC_POINT(value.point, &field_bytes);
6244     if (result) {
6245       return result;
6246     }
6247   }
6248   std::string size_bytes;
6249   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
6250   if (result) {
6251     return result;
6252   }
6253   buffer->append(size_bytes + field_bytes);
6254   return result;
6255 }
6256 
Parse_TPM2B_ECC_POINT(std::string * buffer,TPM2B_ECC_POINT * value,std::string * value_bytes)6257 TPM_RC Parse_TPM2B_ECC_POINT(std::string* buffer,
6258                              TPM2B_ECC_POINT* value,
6259                              std::string* value_bytes) {
6260   TPM_RC result = TPM_RC_SUCCESS;
6261   VLOG(3) << __func__;
6262 
6263   UINT16 parsed_size = 0;
6264   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
6265   if (result) {
6266     return result;
6267   }
6268   if (!parsed_size) {
6269     value->size = 0;
6270   } else {
6271     value->size = sizeof(TPMS_ECC_POINT);
6272     result = Parse_TPMS_ECC_POINT(buffer, &value->point, value_bytes);
6273     if (result) {
6274       return result;
6275     }
6276   }
6277   return result;
6278 }
6279 
Make_TPM2B_ECC_POINT(const TPMS_ECC_POINT & inner)6280 TPM2B_ECC_POINT Make_TPM2B_ECC_POINT(const TPMS_ECC_POINT& inner) {
6281   TPM2B_ECC_POINT tpm2b;
6282   tpm2b.size = sizeof(TPMS_ECC_POINT);
6283   tpm2b.point = inner;
6284   return tpm2b;
6285 }
6286 
Serialize_TPMT_ECC_SCHEME(const TPMT_ECC_SCHEME & value,std::string * buffer)6287 TPM_RC Serialize_TPMT_ECC_SCHEME(const TPMT_ECC_SCHEME& value,
6288                                  std::string* buffer) {
6289   TPM_RC result = TPM_RC_SUCCESS;
6290   VLOG(3) << __func__;
6291 
6292   result = Serialize_TPMI_ALG_ECC_SCHEME(value.scheme, buffer);
6293   if (result) {
6294     return result;
6295   }
6296 
6297   result = Serialize_TPMU_SIG_SCHEME(value.details, value.scheme, buffer);
6298   if (result) {
6299     return result;
6300   }
6301   return result;
6302 }
6303 
Parse_TPMT_ECC_SCHEME(std::string * buffer,TPMT_ECC_SCHEME * value,std::string * value_bytes)6304 TPM_RC Parse_TPMT_ECC_SCHEME(std::string* buffer,
6305                              TPMT_ECC_SCHEME* value,
6306                              std::string* value_bytes) {
6307   TPM_RC result = TPM_RC_SUCCESS;
6308   VLOG(3) << __func__;
6309 
6310   result = Parse_TPMI_ALG_ECC_SCHEME(buffer, &value->scheme, value_bytes);
6311   if (result) {
6312     return result;
6313   }
6314 
6315   result = Parse_TPMU_SIG_SCHEME(buffer, value->scheme, &value->details,
6316                                  value_bytes);
6317   if (result) {
6318     return result;
6319   }
6320   return result;
6321 }
6322 
Serialize_TPMS_ALGORITHM_DETAIL_ECC(const TPMS_ALGORITHM_DETAIL_ECC & value,std::string * buffer)6323 TPM_RC Serialize_TPMS_ALGORITHM_DETAIL_ECC(
6324     const TPMS_ALGORITHM_DETAIL_ECC& value, std::string* buffer) {
6325   TPM_RC result = TPM_RC_SUCCESS;
6326   VLOG(3) << __func__;
6327 
6328   result = Serialize_TPM_ECC_CURVE(value.curve_id, buffer);
6329   if (result) {
6330     return result;
6331   }
6332 
6333   result = Serialize_UINT16(value.key_size, buffer);
6334   if (result) {
6335     return result;
6336   }
6337 
6338   result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer);
6339   if (result) {
6340     return result;
6341   }
6342 
6343   result = Serialize_TPMT_ECC_SCHEME(value.sign, buffer);
6344   if (result) {
6345     return result;
6346   }
6347 
6348   result = Serialize_TPM2B_ECC_PARAMETER(value.p, buffer);
6349   if (result) {
6350     return result;
6351   }
6352 
6353   result = Serialize_TPM2B_ECC_PARAMETER(value.a, buffer);
6354   if (result) {
6355     return result;
6356   }
6357 
6358   result = Serialize_TPM2B_ECC_PARAMETER(value.b, buffer);
6359   if (result) {
6360     return result;
6361   }
6362 
6363   result = Serialize_TPM2B_ECC_PARAMETER(value.g_x, buffer);
6364   if (result) {
6365     return result;
6366   }
6367 
6368   result = Serialize_TPM2B_ECC_PARAMETER(value.g_y, buffer);
6369   if (result) {
6370     return result;
6371   }
6372 
6373   result = Serialize_TPM2B_ECC_PARAMETER(value.n, buffer);
6374   if (result) {
6375     return result;
6376   }
6377 
6378   result = Serialize_TPM2B_ECC_PARAMETER(value.h, buffer);
6379   if (result) {
6380     return result;
6381   }
6382   return result;
6383 }
6384 
Parse_TPMS_ALGORITHM_DETAIL_ECC(std::string * buffer,TPMS_ALGORITHM_DETAIL_ECC * value,std::string * value_bytes)6385 TPM_RC Parse_TPMS_ALGORITHM_DETAIL_ECC(std::string* buffer,
6386                                        TPMS_ALGORITHM_DETAIL_ECC* value,
6387                                        std::string* value_bytes) {
6388   TPM_RC result = TPM_RC_SUCCESS;
6389   VLOG(3) << __func__;
6390 
6391   result = Parse_TPM_ECC_CURVE(buffer, &value->curve_id, value_bytes);
6392   if (result) {
6393     return result;
6394   }
6395 
6396   result = Parse_UINT16(buffer, &value->key_size, value_bytes);
6397   if (result) {
6398     return result;
6399   }
6400 
6401   result = Parse_TPMT_KDF_SCHEME(buffer, &value->kdf, value_bytes);
6402   if (result) {
6403     return result;
6404   }
6405 
6406   result = Parse_TPMT_ECC_SCHEME(buffer, &value->sign, value_bytes);
6407   if (result) {
6408     return result;
6409   }
6410 
6411   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->p, value_bytes);
6412   if (result) {
6413     return result;
6414   }
6415 
6416   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->a, value_bytes);
6417   if (result) {
6418     return result;
6419   }
6420 
6421   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->b, value_bytes);
6422   if (result) {
6423     return result;
6424   }
6425 
6426   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->g_x, value_bytes);
6427   if (result) {
6428     return result;
6429   }
6430 
6431   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->g_y, value_bytes);
6432   if (result) {
6433     return result;
6434   }
6435 
6436   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->n, value_bytes);
6437   if (result) {
6438     return result;
6439   }
6440 
6441   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->h, value_bytes);
6442   if (result) {
6443     return result;
6444   }
6445   return result;
6446 }
6447 
Serialize_TPMS_SIGNATURE_RSASSA(const TPMS_SIGNATURE_RSASSA & value,std::string * buffer)6448 TPM_RC Serialize_TPMS_SIGNATURE_RSASSA(const TPMS_SIGNATURE_RSASSA& value,
6449                                        std::string* buffer) {
6450   TPM_RC result = TPM_RC_SUCCESS;
6451   VLOG(3) << __func__;
6452 
6453   result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6454   if (result) {
6455     return result;
6456   }
6457 
6458   result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer);
6459   if (result) {
6460     return result;
6461   }
6462   return result;
6463 }
6464 
Parse_TPMS_SIGNATURE_RSASSA(std::string * buffer,TPMS_SIGNATURE_RSASSA * value,std::string * value_bytes)6465 TPM_RC Parse_TPMS_SIGNATURE_RSASSA(std::string* buffer,
6466                                    TPMS_SIGNATURE_RSASSA* value,
6467                                    std::string* value_bytes) {
6468   TPM_RC result = TPM_RC_SUCCESS;
6469   VLOG(3) << __func__;
6470 
6471   result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6472   if (result) {
6473     return result;
6474   }
6475 
6476   result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->sig, value_bytes);
6477   if (result) {
6478     return result;
6479   }
6480   return result;
6481 }
6482 
Serialize_TPMS_SIGNATURE_RSAPSS(const TPMS_SIGNATURE_RSAPSS & value,std::string * buffer)6483 TPM_RC Serialize_TPMS_SIGNATURE_RSAPSS(const TPMS_SIGNATURE_RSAPSS& value,
6484                                        std::string* buffer) {
6485   TPM_RC result = TPM_RC_SUCCESS;
6486   VLOG(3) << __func__;
6487 
6488   result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6489   if (result) {
6490     return result;
6491   }
6492 
6493   result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.sig, buffer);
6494   if (result) {
6495     return result;
6496   }
6497   return result;
6498 }
6499 
Parse_TPMS_SIGNATURE_RSAPSS(std::string * buffer,TPMS_SIGNATURE_RSAPSS * value,std::string * value_bytes)6500 TPM_RC Parse_TPMS_SIGNATURE_RSAPSS(std::string* buffer,
6501                                    TPMS_SIGNATURE_RSAPSS* value,
6502                                    std::string* value_bytes) {
6503   TPM_RC result = TPM_RC_SUCCESS;
6504   VLOG(3) << __func__;
6505 
6506   result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6507   if (result) {
6508     return result;
6509   }
6510 
6511   result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->sig, value_bytes);
6512   if (result) {
6513     return result;
6514   }
6515   return result;
6516 }
6517 
Serialize_TPMS_SIGNATURE_ECDSA(const TPMS_SIGNATURE_ECDSA & value,std::string * buffer)6518 TPM_RC Serialize_TPMS_SIGNATURE_ECDSA(const TPMS_SIGNATURE_ECDSA& value,
6519                                       std::string* buffer) {
6520   TPM_RC result = TPM_RC_SUCCESS;
6521   VLOG(3) << __func__;
6522 
6523   result = Serialize_TPMI_ALG_HASH(value.hash, buffer);
6524   if (result) {
6525     return result;
6526   }
6527 
6528   result = Serialize_TPM2B_ECC_PARAMETER(value.signature_r, buffer);
6529   if (result) {
6530     return result;
6531   }
6532 
6533   result = Serialize_TPM2B_ECC_PARAMETER(value.signature_s, buffer);
6534   if (result) {
6535     return result;
6536   }
6537   return result;
6538 }
6539 
Parse_TPMS_SIGNATURE_ECDSA(std::string * buffer,TPMS_SIGNATURE_ECDSA * value,std::string * value_bytes)6540 TPM_RC Parse_TPMS_SIGNATURE_ECDSA(std::string* buffer,
6541                                   TPMS_SIGNATURE_ECDSA* value,
6542                                   std::string* value_bytes) {
6543   TPM_RC result = TPM_RC_SUCCESS;
6544   VLOG(3) << __func__;
6545 
6546   result = Parse_TPMI_ALG_HASH(buffer, &value->hash, value_bytes);
6547   if (result) {
6548     return result;
6549   }
6550 
6551   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->signature_r, value_bytes);
6552   if (result) {
6553     return result;
6554   }
6555 
6556   result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->signature_s, value_bytes);
6557   if (result) {
6558     return result;
6559   }
6560   return result;
6561 }
6562 
Serialize_TPMU_SIGNATURE(const TPMU_SIGNATURE & value,TPMI_ALG_SIG_SCHEME selector,std::string * buffer)6563 TPM_RC Serialize_TPMU_SIGNATURE(const TPMU_SIGNATURE& value,
6564                                 TPMI_ALG_SIG_SCHEME selector,
6565                                 std::string* buffer) {
6566   TPM_RC result = TPM_RC_SUCCESS;
6567   VLOG(3) << __func__;
6568 
6569   if (selector == TPM_ALG_HMAC) {
6570     result = Serialize_TPMT_HA(value.hmac, buffer);
6571     if (result) {
6572       return result;
6573     }
6574   }
6575 
6576   if (selector == TPM_ALG_ECSCHNORR) {
6577     result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecschnorr, buffer);
6578     if (result) {
6579       return result;
6580     }
6581   }
6582 
6583   if (selector == TPM_ALG_RSAPSS) {
6584     result = Serialize_TPMS_SIGNATURE_RSAPSS(value.rsapss, buffer);
6585     if (result) {
6586       return result;
6587     }
6588   }
6589 
6590   if (selector == TPM_ALG_ECDAA) {
6591     result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdaa, buffer);
6592     if (result) {
6593       return result;
6594     }
6595   }
6596 
6597   if (selector == TPM_ALG_RSASSA) {
6598     result = Serialize_TPMS_SIGNATURE_RSASSA(value.rsassa, buffer);
6599     if (result) {
6600       return result;
6601     }
6602   }
6603 
6604   if (selector == TPM_ALG_SM2) {
6605     result = Serialize_TPMS_SIGNATURE_ECDSA(value.sm2, buffer);
6606     if (result) {
6607       return result;
6608     }
6609   }
6610 
6611   if (selector == TPM_ALG_ECDSA) {
6612     result = Serialize_TPMS_SIGNATURE_ECDSA(value.ecdsa, buffer);
6613     if (result) {
6614       return result;
6615     }
6616   }
6617 
6618   if (selector == TPM_ALG_NULL) {
6619     // Do nothing.
6620   }
6621   return result;
6622 }
6623 
Parse_TPMU_SIGNATURE(std::string * buffer,TPMI_ALG_SIG_SCHEME selector,TPMU_SIGNATURE * value,std::string * value_bytes)6624 TPM_RC Parse_TPMU_SIGNATURE(std::string* buffer,
6625                             TPMI_ALG_SIG_SCHEME selector,
6626                             TPMU_SIGNATURE* value,
6627                             std::string* value_bytes) {
6628   TPM_RC result = TPM_RC_SUCCESS;
6629   VLOG(3) << __func__;
6630 
6631   if (selector == TPM_ALG_HMAC) {
6632     result = Parse_TPMT_HA(buffer, &value->hmac, value_bytes);
6633     if (result) {
6634       return result;
6635     }
6636   }
6637 
6638   if (selector == TPM_ALG_ECSCHNORR) {
6639     result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecschnorr, value_bytes);
6640     if (result) {
6641       return result;
6642     }
6643   }
6644 
6645   if (selector == TPM_ALG_RSAPSS) {
6646     result = Parse_TPMS_SIGNATURE_RSAPSS(buffer, &value->rsapss, value_bytes);
6647     if (result) {
6648       return result;
6649     }
6650   }
6651 
6652   if (selector == TPM_ALG_ECDAA) {
6653     result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecdaa, value_bytes);
6654     if (result) {
6655       return result;
6656     }
6657   }
6658 
6659   if (selector == TPM_ALG_RSASSA) {
6660     result = Parse_TPMS_SIGNATURE_RSASSA(buffer, &value->rsassa, value_bytes);
6661     if (result) {
6662       return result;
6663     }
6664   }
6665 
6666   if (selector == TPM_ALG_SM2) {
6667     result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->sm2, value_bytes);
6668     if (result) {
6669       return result;
6670     }
6671   }
6672 
6673   if (selector == TPM_ALG_ECDSA) {
6674     result = Parse_TPMS_SIGNATURE_ECDSA(buffer, &value->ecdsa, value_bytes);
6675     if (result) {
6676       return result;
6677     }
6678   }
6679 
6680   if (selector == TPM_ALG_NULL) {
6681     // Do nothing.
6682   }
6683   return result;
6684 }
6685 
Serialize_TPMT_SIGNATURE(const TPMT_SIGNATURE & value,std::string * buffer)6686 TPM_RC Serialize_TPMT_SIGNATURE(const TPMT_SIGNATURE& value,
6687                                 std::string* buffer) {
6688   TPM_RC result = TPM_RC_SUCCESS;
6689   VLOG(3) << __func__;
6690 
6691   result = Serialize_TPMI_ALG_SIG_SCHEME(value.sig_alg, buffer);
6692   if (result) {
6693     return result;
6694   }
6695 
6696   result = Serialize_TPMU_SIGNATURE(value.signature, value.sig_alg, buffer);
6697   if (result) {
6698     return result;
6699   }
6700   return result;
6701 }
6702 
Parse_TPMT_SIGNATURE(std::string * buffer,TPMT_SIGNATURE * value,std::string * value_bytes)6703 TPM_RC Parse_TPMT_SIGNATURE(std::string* buffer,
6704                             TPMT_SIGNATURE* value,
6705                             std::string* value_bytes) {
6706   TPM_RC result = TPM_RC_SUCCESS;
6707   VLOG(3) << __func__;
6708 
6709   result = Parse_TPMI_ALG_SIG_SCHEME(buffer, &value->sig_alg, value_bytes);
6710   if (result) {
6711     return result;
6712   }
6713 
6714   result = Parse_TPMU_SIGNATURE(buffer, value->sig_alg, &value->signature,
6715                                 value_bytes);
6716   if (result) {
6717     return result;
6718   }
6719   return result;
6720 }
6721 
Serialize_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET & value,std::string * buffer)6722 TPM_RC Serialize_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET& value,
6723                                         std::string* buffer) {
6724   TPM_RC result = TPM_RC_SUCCESS;
6725   VLOG(3) << __func__;
6726 
6727   result = Serialize_UINT16(value.size, buffer);
6728   if (result) {
6729     return result;
6730   }
6731 
6732   if (std::size(value.secret) < value.size) {
6733     return TPM_RC_INSUFFICIENT;
6734   }
6735   for (uint32_t i = 0; i < value.size; ++i) {
6736     result = Serialize_BYTE(value.secret[i], buffer);
6737     if (result) {
6738       return result;
6739     }
6740   }
6741   return result;
6742 }
6743 
Parse_TPM2B_ENCRYPTED_SECRET(std::string * buffer,TPM2B_ENCRYPTED_SECRET * value,std::string * value_bytes)6744 TPM_RC Parse_TPM2B_ENCRYPTED_SECRET(std::string* buffer,
6745                                     TPM2B_ENCRYPTED_SECRET* value,
6746                                     std::string* value_bytes) {
6747   TPM_RC result = TPM_RC_SUCCESS;
6748   VLOG(3) << __func__;
6749 
6750   result = Parse_UINT16(buffer, &value->size, value_bytes);
6751   if (result) {
6752     return result;
6753   }
6754 
6755   if (std::size(value->secret) < value->size) {
6756     return TPM_RC_INSUFFICIENT;
6757   }
6758   for (uint32_t i = 0; i < value->size; ++i) {
6759     result = Parse_BYTE(buffer, &value->secret[i], value_bytes);
6760     if (result) {
6761       return result;
6762     }
6763   }
6764   return result;
6765 }
6766 
Make_TPM2B_ENCRYPTED_SECRET(const std::string & bytes)6767 TPM2B_ENCRYPTED_SECRET Make_TPM2B_ENCRYPTED_SECRET(const std::string& bytes) {
6768   TPM2B_ENCRYPTED_SECRET tpm2b;
6769   CHECK(bytes.size() <= sizeof(tpm2b.secret));
6770   memset(&tpm2b, 0, sizeof(TPM2B_ENCRYPTED_SECRET));
6771   tpm2b.size = bytes.size();
6772   memcpy(tpm2b.secret, bytes.data(), bytes.size());
6773   return tpm2b;
6774 }
6775 
StringFrom_TPM2B_ENCRYPTED_SECRET(const TPM2B_ENCRYPTED_SECRET & tpm2b)6776 std::string StringFrom_TPM2B_ENCRYPTED_SECRET(
6777     const TPM2B_ENCRYPTED_SECRET& tpm2b) {
6778   CHECK(tpm2b.size <= std::size(tpm2b.secret));
6779   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.secret);
6780   return std::string(char_buffer, tpm2b.size);
6781 }
6782 
Serialize_TPMS_KEYEDHASH_PARMS(const TPMS_KEYEDHASH_PARMS & value,std::string * buffer)6783 TPM_RC Serialize_TPMS_KEYEDHASH_PARMS(const TPMS_KEYEDHASH_PARMS& value,
6784                                       std::string* buffer) {
6785   TPM_RC result = TPM_RC_SUCCESS;
6786   VLOG(3) << __func__;
6787 
6788   result = Serialize_TPMT_KEYEDHASH_SCHEME(value.scheme, buffer);
6789   if (result) {
6790     return result;
6791   }
6792   return result;
6793 }
6794 
Parse_TPMS_KEYEDHASH_PARMS(std::string * buffer,TPMS_KEYEDHASH_PARMS * value,std::string * value_bytes)6795 TPM_RC Parse_TPMS_KEYEDHASH_PARMS(std::string* buffer,
6796                                   TPMS_KEYEDHASH_PARMS* value,
6797                                   std::string* value_bytes) {
6798   TPM_RC result = TPM_RC_SUCCESS;
6799   VLOG(3) << __func__;
6800 
6801   result = Parse_TPMT_KEYEDHASH_SCHEME(buffer, &value->scheme, value_bytes);
6802   if (result) {
6803     return result;
6804   }
6805   return result;
6806 }
6807 
Serialize_TPMS_ASYM_PARMS(const TPMS_ASYM_PARMS & value,std::string * buffer)6808 TPM_RC Serialize_TPMS_ASYM_PARMS(const TPMS_ASYM_PARMS& value,
6809                                  std::string* buffer) {
6810   TPM_RC result = TPM_RC_SUCCESS;
6811   VLOG(3) << __func__;
6812 
6813   result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6814   if (result) {
6815     return result;
6816   }
6817 
6818   result = Serialize_TPMT_ASYM_SCHEME(value.scheme, buffer);
6819   if (result) {
6820     return result;
6821   }
6822   return result;
6823 }
6824 
Parse_TPMS_ASYM_PARMS(std::string * buffer,TPMS_ASYM_PARMS * value,std::string * value_bytes)6825 TPM_RC Parse_TPMS_ASYM_PARMS(std::string* buffer,
6826                              TPMS_ASYM_PARMS* value,
6827                              std::string* value_bytes) {
6828   TPM_RC result = TPM_RC_SUCCESS;
6829   VLOG(3) << __func__;
6830 
6831   result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6832   if (result) {
6833     return result;
6834   }
6835 
6836   result = Parse_TPMT_ASYM_SCHEME(buffer, &value->scheme, value_bytes);
6837   if (result) {
6838     return result;
6839   }
6840   return result;
6841 }
6842 
Serialize_TPMS_RSA_PARMS(const TPMS_RSA_PARMS & value,std::string * buffer)6843 TPM_RC Serialize_TPMS_RSA_PARMS(const TPMS_RSA_PARMS& value,
6844                                 std::string* buffer) {
6845   TPM_RC result = TPM_RC_SUCCESS;
6846   VLOG(3) << __func__;
6847 
6848   result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6849   if (result) {
6850     return result;
6851   }
6852 
6853   result = Serialize_TPMT_RSA_SCHEME(value.scheme, buffer);
6854   if (result) {
6855     return result;
6856   }
6857 
6858   result = Serialize_TPMI_RSA_KEY_BITS(value.key_bits, buffer);
6859   if (result) {
6860     return result;
6861   }
6862 
6863   result = Serialize_UINT32(value.exponent, buffer);
6864   if (result) {
6865     return result;
6866   }
6867   return result;
6868 }
6869 
Parse_TPMS_RSA_PARMS(std::string * buffer,TPMS_RSA_PARMS * value,std::string * value_bytes)6870 TPM_RC Parse_TPMS_RSA_PARMS(std::string* buffer,
6871                             TPMS_RSA_PARMS* value,
6872                             std::string* value_bytes) {
6873   TPM_RC result = TPM_RC_SUCCESS;
6874   VLOG(3) << __func__;
6875 
6876   result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6877   if (result) {
6878     return result;
6879   }
6880 
6881   result = Parse_TPMT_RSA_SCHEME(buffer, &value->scheme, value_bytes);
6882   if (result) {
6883     return result;
6884   }
6885 
6886   result = Parse_TPMI_RSA_KEY_BITS(buffer, &value->key_bits, value_bytes);
6887   if (result) {
6888     return result;
6889   }
6890 
6891   result = Parse_UINT32(buffer, &value->exponent, value_bytes);
6892   if (result) {
6893     return result;
6894   }
6895   return result;
6896 }
6897 
Serialize_TPMS_ECC_PARMS(const TPMS_ECC_PARMS & value,std::string * buffer)6898 TPM_RC Serialize_TPMS_ECC_PARMS(const TPMS_ECC_PARMS& value,
6899                                 std::string* buffer) {
6900   TPM_RC result = TPM_RC_SUCCESS;
6901   VLOG(3) << __func__;
6902 
6903   result = Serialize_TPMT_SYM_DEF_OBJECT(value.symmetric, buffer);
6904   if (result) {
6905     return result;
6906   }
6907 
6908   result = Serialize_TPMT_ECC_SCHEME(value.scheme, buffer);
6909   if (result) {
6910     return result;
6911   }
6912 
6913   result = Serialize_TPMI_ECC_CURVE(value.curve_id, buffer);
6914   if (result) {
6915     return result;
6916   }
6917 
6918   result = Serialize_TPMT_KDF_SCHEME(value.kdf, buffer);
6919   if (result) {
6920     return result;
6921   }
6922   return result;
6923 }
6924 
Parse_TPMS_ECC_PARMS(std::string * buffer,TPMS_ECC_PARMS * value,std::string * value_bytes)6925 TPM_RC Parse_TPMS_ECC_PARMS(std::string* buffer,
6926                             TPMS_ECC_PARMS* value,
6927                             std::string* value_bytes) {
6928   TPM_RC result = TPM_RC_SUCCESS;
6929   VLOG(3) << __func__;
6930 
6931   result = Parse_TPMT_SYM_DEF_OBJECT(buffer, &value->symmetric, value_bytes);
6932   if (result) {
6933     return result;
6934   }
6935 
6936   result = Parse_TPMT_ECC_SCHEME(buffer, &value->scheme, value_bytes);
6937   if (result) {
6938     return result;
6939   }
6940 
6941   result = Parse_TPMI_ECC_CURVE(buffer, &value->curve_id, value_bytes);
6942   if (result) {
6943     return result;
6944   }
6945 
6946   result = Parse_TPMT_KDF_SCHEME(buffer, &value->kdf, value_bytes);
6947   if (result) {
6948     return result;
6949   }
6950   return result;
6951 }
6952 
Serialize_TPMU_PUBLIC_PARMS(const TPMU_PUBLIC_PARMS & value,TPMI_ALG_PUBLIC selector,std::string * buffer)6953 TPM_RC Serialize_TPMU_PUBLIC_PARMS(const TPMU_PUBLIC_PARMS& value,
6954                                    TPMI_ALG_PUBLIC selector,
6955                                    std::string* buffer) {
6956   TPM_RC result = TPM_RC_SUCCESS;
6957   VLOG(3) << __func__;
6958 
6959   if (selector == TPM_ALG_KEYEDHASH) {
6960     result = Serialize_TPMS_KEYEDHASH_PARMS(value.keyed_hash_detail, buffer);
6961     if (result) {
6962       return result;
6963     }
6964   }
6965 
6966   if (selector == TPM_ALG_RSA) {
6967     result = Serialize_TPMS_RSA_PARMS(value.rsa_detail, buffer);
6968     if (result) {
6969       return result;
6970     }
6971   }
6972 
6973   if (selector == TPM_ALG_SYMCIPHER) {
6974     result = Serialize_TPMS_SYMCIPHER_PARMS(value.sym_detail, buffer);
6975     if (result) {
6976       return result;
6977     }
6978   }
6979 
6980   if (selector == TPM_ALG_ECC) {
6981     result = Serialize_TPMS_ECC_PARMS(value.ecc_detail, buffer);
6982     if (result) {
6983       return result;
6984     }
6985   }
6986   return result;
6987 }
6988 
Parse_TPMU_PUBLIC_PARMS(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_PUBLIC_PARMS * value,std::string * value_bytes)6989 TPM_RC Parse_TPMU_PUBLIC_PARMS(std::string* buffer,
6990                                TPMI_ALG_PUBLIC selector,
6991                                TPMU_PUBLIC_PARMS* value,
6992                                std::string* value_bytes) {
6993   TPM_RC result = TPM_RC_SUCCESS;
6994   VLOG(3) << __func__;
6995 
6996   if (selector == TPM_ALG_KEYEDHASH) {
6997     result = Parse_TPMS_KEYEDHASH_PARMS(buffer, &value->keyed_hash_detail,
6998                                         value_bytes);
6999     if (result) {
7000       return result;
7001     }
7002   }
7003 
7004   if (selector == TPM_ALG_RSA) {
7005     result = Parse_TPMS_RSA_PARMS(buffer, &value->rsa_detail, value_bytes);
7006     if (result) {
7007       return result;
7008     }
7009   }
7010 
7011   if (selector == TPM_ALG_SYMCIPHER) {
7012     result =
7013         Parse_TPMS_SYMCIPHER_PARMS(buffer, &value->sym_detail, value_bytes);
7014     if (result) {
7015       return result;
7016     }
7017   }
7018 
7019   if (selector == TPM_ALG_ECC) {
7020     result = Parse_TPMS_ECC_PARMS(buffer, &value->ecc_detail, value_bytes);
7021     if (result) {
7022       return result;
7023     }
7024   }
7025   return result;
7026 }
7027 
Serialize_TPMT_PUBLIC_PARMS(const TPMT_PUBLIC_PARMS & value,std::string * buffer)7028 TPM_RC Serialize_TPMT_PUBLIC_PARMS(const TPMT_PUBLIC_PARMS& value,
7029                                    std::string* buffer) {
7030   TPM_RC result = TPM_RC_SUCCESS;
7031   VLOG(3) << __func__;
7032 
7033   result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer);
7034   if (result) {
7035     return result;
7036   }
7037 
7038   result = Serialize_TPMU_PUBLIC_PARMS(value.parameters, value.type, buffer);
7039   if (result) {
7040     return result;
7041   }
7042   return result;
7043 }
7044 
Parse_TPMT_PUBLIC_PARMS(std::string * buffer,TPMT_PUBLIC_PARMS * value,std::string * value_bytes)7045 TPM_RC Parse_TPMT_PUBLIC_PARMS(std::string* buffer,
7046                                TPMT_PUBLIC_PARMS* value,
7047                                std::string* value_bytes) {
7048   TPM_RC result = TPM_RC_SUCCESS;
7049   VLOG(3) << __func__;
7050 
7051   result = Parse_TPMI_ALG_PUBLIC(buffer, &value->type, value_bytes);
7052   if (result) {
7053     return result;
7054   }
7055 
7056   result = Parse_TPMU_PUBLIC_PARMS(buffer, value->type, &value->parameters,
7057                                    value_bytes);
7058   if (result) {
7059     return result;
7060   }
7061   return result;
7062 }
7063 
Serialize_TPMU_PUBLIC_ID(const TPMU_PUBLIC_ID & value,TPMI_ALG_PUBLIC selector,std::string * buffer)7064 TPM_RC Serialize_TPMU_PUBLIC_ID(const TPMU_PUBLIC_ID& value,
7065                                 TPMI_ALG_PUBLIC selector,
7066                                 std::string* buffer) {
7067   TPM_RC result = TPM_RC_SUCCESS;
7068   VLOG(3) << __func__;
7069 
7070   if (selector == TPM_ALG_KEYEDHASH) {
7071     result = Serialize_TPM2B_DIGEST(value.keyed_hash, buffer);
7072     if (result) {
7073       return result;
7074     }
7075   }
7076 
7077   if (selector == TPM_ALG_RSA) {
7078     result = Serialize_TPM2B_PUBLIC_KEY_RSA(value.rsa, buffer);
7079     if (result) {
7080       return result;
7081     }
7082   }
7083 
7084   if (selector == TPM_ALG_SYMCIPHER) {
7085     result = Serialize_TPM2B_DIGEST(value.sym, buffer);
7086     if (result) {
7087       return result;
7088     }
7089   }
7090 
7091   if (selector == TPM_ALG_ECC) {
7092     result = Serialize_TPMS_ECC_POINT(value.ecc, buffer);
7093     if (result) {
7094       return result;
7095     }
7096   }
7097   return result;
7098 }
7099 
Parse_TPMU_PUBLIC_ID(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_PUBLIC_ID * value,std::string * value_bytes)7100 TPM_RC Parse_TPMU_PUBLIC_ID(std::string* buffer,
7101                             TPMI_ALG_PUBLIC selector,
7102                             TPMU_PUBLIC_ID* value,
7103                             std::string* value_bytes) {
7104   TPM_RC result = TPM_RC_SUCCESS;
7105   VLOG(3) << __func__;
7106 
7107   if (selector == TPM_ALG_KEYEDHASH) {
7108     result = Parse_TPM2B_DIGEST(buffer, &value->keyed_hash, value_bytes);
7109     if (result) {
7110       return result;
7111     }
7112   }
7113 
7114   if (selector == TPM_ALG_RSA) {
7115     result = Parse_TPM2B_PUBLIC_KEY_RSA(buffer, &value->rsa, value_bytes);
7116     if (result) {
7117       return result;
7118     }
7119   }
7120 
7121   if (selector == TPM_ALG_SYMCIPHER) {
7122     result = Parse_TPM2B_DIGEST(buffer, &value->sym, value_bytes);
7123     if (result) {
7124       return result;
7125     }
7126   }
7127 
7128   if (selector == TPM_ALG_ECC) {
7129     result = Parse_TPMS_ECC_POINT(buffer, &value->ecc, value_bytes);
7130     if (result) {
7131       return result;
7132     }
7133   }
7134   return result;
7135 }
7136 
Serialize_TPMT_PUBLIC(const TPMT_PUBLIC & value,std::string * buffer)7137 TPM_RC Serialize_TPMT_PUBLIC(const TPMT_PUBLIC& value, std::string* buffer) {
7138   TPM_RC result = TPM_RC_SUCCESS;
7139   VLOG(3) << __func__;
7140 
7141   result = Serialize_TPMI_ALG_PUBLIC(value.type, buffer);
7142   if (result) {
7143     return result;
7144   }
7145 
7146   result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer);
7147   if (result) {
7148     return result;
7149   }
7150 
7151   result = Serialize_TPMA_OBJECT(value.object_attributes, buffer);
7152   if (result) {
7153     return result;
7154   }
7155 
7156   result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer);
7157   if (result) {
7158     return result;
7159   }
7160 
7161   result = Serialize_TPMU_PUBLIC_PARMS(value.parameters, value.type, buffer);
7162   if (result) {
7163     return result;
7164   }
7165 
7166   result = Serialize_TPMU_PUBLIC_ID(value.unique, value.type, buffer);
7167   if (result) {
7168     return result;
7169   }
7170   return result;
7171 }
7172 
Parse_TPMT_PUBLIC(std::string * buffer,TPMT_PUBLIC * value,std::string * value_bytes)7173 TPM_RC Parse_TPMT_PUBLIC(std::string* buffer,
7174                          TPMT_PUBLIC* value,
7175                          std::string* value_bytes) {
7176   TPM_RC result = TPM_RC_SUCCESS;
7177   VLOG(3) << __func__;
7178 
7179   result = Parse_TPMI_ALG_PUBLIC(buffer, &value->type, value_bytes);
7180   if (result) {
7181     return result;
7182   }
7183 
7184   result = Parse_TPMI_ALG_HASH(buffer, &value->name_alg, value_bytes);
7185   if (result) {
7186     return result;
7187   }
7188 
7189   result = Parse_TPMA_OBJECT(buffer, &value->object_attributes, value_bytes);
7190   if (result) {
7191     return result;
7192   }
7193 
7194   result = Parse_TPM2B_DIGEST(buffer, &value->auth_policy, value_bytes);
7195   if (result) {
7196     return result;
7197   }
7198 
7199   result = Parse_TPMU_PUBLIC_PARMS(buffer, value->type, &value->parameters,
7200                                    value_bytes);
7201   if (result) {
7202     return result;
7203   }
7204 
7205   result =
7206       Parse_TPMU_PUBLIC_ID(buffer, value->type, &value->unique, value_bytes);
7207   if (result) {
7208     return result;
7209   }
7210   return result;
7211 }
7212 
Serialize_TPM2B_PUBLIC(const TPM2B_PUBLIC & value,std::string * buffer)7213 TPM_RC Serialize_TPM2B_PUBLIC(const TPM2B_PUBLIC& value, std::string* buffer) {
7214   TPM_RC result = TPM_RC_SUCCESS;
7215   VLOG(3) << __func__;
7216 
7217   std::string field_bytes;
7218   if (value.size) {
7219     if (value.size != sizeof(TPMT_PUBLIC)) {
7220       return TPM_RC_SIZE;
7221     }
7222     result = Serialize_TPMT_PUBLIC(value.public_area, &field_bytes);
7223     if (result) {
7224       return result;
7225     }
7226   }
7227   std::string size_bytes;
7228   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7229   if (result) {
7230     return result;
7231   }
7232   buffer->append(size_bytes + field_bytes);
7233   return result;
7234 }
7235 
Parse_TPM2B_PUBLIC(std::string * buffer,TPM2B_PUBLIC * value,std::string * value_bytes)7236 TPM_RC Parse_TPM2B_PUBLIC(std::string* buffer,
7237                           TPM2B_PUBLIC* value,
7238                           std::string* value_bytes) {
7239   TPM_RC result = TPM_RC_SUCCESS;
7240   VLOG(3) << __func__;
7241 
7242   UINT16 parsed_size = 0;
7243   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7244   if (result) {
7245     return result;
7246   }
7247   if (!parsed_size) {
7248     value->size = 0;
7249   } else {
7250     value->size = sizeof(TPMT_PUBLIC);
7251     result = Parse_TPMT_PUBLIC(buffer, &value->public_area, value_bytes);
7252     if (result) {
7253       return result;
7254     }
7255   }
7256   return result;
7257 }
7258 
Make_TPM2B_PUBLIC(const TPMT_PUBLIC & inner)7259 TPM2B_PUBLIC Make_TPM2B_PUBLIC(const TPMT_PUBLIC& inner) {
7260   TPM2B_PUBLIC tpm2b;
7261   tpm2b.size = sizeof(TPMT_PUBLIC);
7262   tpm2b.public_area = inner;
7263   return tpm2b;
7264 }
7265 
Serialize_TPM2B_PRIVATE_VENDOR_SPECIFIC(const TPM2B_PRIVATE_VENDOR_SPECIFIC & value,std::string * buffer)7266 TPM_RC Serialize_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7267     const TPM2B_PRIVATE_VENDOR_SPECIFIC& value, std::string* buffer) {
7268   TPM_RC result = TPM_RC_SUCCESS;
7269   VLOG(3) << __func__;
7270 
7271   result = Serialize_UINT16(value.size, buffer);
7272   if (result) {
7273     return result;
7274   }
7275 
7276   if (std::size(value.buffer) < value.size) {
7277     return TPM_RC_INSUFFICIENT;
7278   }
7279   for (uint32_t i = 0; i < value.size; ++i) {
7280     result = Serialize_BYTE(value.buffer[i], buffer);
7281     if (result) {
7282       return result;
7283     }
7284   }
7285   return result;
7286 }
7287 
Parse_TPM2B_PRIVATE_VENDOR_SPECIFIC(std::string * buffer,TPM2B_PRIVATE_VENDOR_SPECIFIC * value,std::string * value_bytes)7288 TPM_RC Parse_TPM2B_PRIVATE_VENDOR_SPECIFIC(std::string* buffer,
7289                                            TPM2B_PRIVATE_VENDOR_SPECIFIC* value,
7290                                            std::string* value_bytes) {
7291   TPM_RC result = TPM_RC_SUCCESS;
7292   VLOG(3) << __func__;
7293 
7294   result = Parse_UINT16(buffer, &value->size, value_bytes);
7295   if (result) {
7296     return result;
7297   }
7298 
7299   if (std::size(value->buffer) < value->size) {
7300     return TPM_RC_INSUFFICIENT;
7301   }
7302   for (uint32_t i = 0; i < value->size; ++i) {
7303     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7304     if (result) {
7305       return result;
7306     }
7307   }
7308   return result;
7309 }
7310 
Make_TPM2B_PRIVATE_VENDOR_SPECIFIC(const std::string & bytes)7311 TPM2B_PRIVATE_VENDOR_SPECIFIC Make_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7312     const std::string& bytes) {
7313   TPM2B_PRIVATE_VENDOR_SPECIFIC tpm2b;
7314   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7315   memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE_VENDOR_SPECIFIC));
7316   tpm2b.size = bytes.size();
7317   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7318   return tpm2b;
7319 }
7320 
StringFrom_TPM2B_PRIVATE_VENDOR_SPECIFIC(const TPM2B_PRIVATE_VENDOR_SPECIFIC & tpm2b)7321 std::string StringFrom_TPM2B_PRIVATE_VENDOR_SPECIFIC(
7322     const TPM2B_PRIVATE_VENDOR_SPECIFIC& tpm2b) {
7323   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7324   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7325   return std::string(char_buffer, tpm2b.size);
7326 }
7327 
Serialize_TPMU_SENSITIVE_COMPOSITE(const TPMU_SENSITIVE_COMPOSITE & value,TPMI_ALG_PUBLIC selector,std::string * buffer)7328 TPM_RC Serialize_TPMU_SENSITIVE_COMPOSITE(const TPMU_SENSITIVE_COMPOSITE& value,
7329                                           TPMI_ALG_PUBLIC selector,
7330                                           std::string* buffer) {
7331   TPM_RC result = TPM_RC_SUCCESS;
7332   VLOG(3) << __func__;
7333 
7334   if (selector == TPM_ALG_KEYEDHASH) {
7335     result = Serialize_TPM2B_SENSITIVE_DATA(value.bits, buffer);
7336     if (result) {
7337       return result;
7338     }
7339   }
7340 
7341   if (selector == TPM_ALG_RSA) {
7342     result = Serialize_TPM2B_PRIVATE_KEY_RSA(value.rsa, buffer);
7343     if (result) {
7344       return result;
7345     }
7346   }
7347 
7348   if (selector == TPM_ALG_SYMCIPHER) {
7349     result = Serialize_TPM2B_SYM_KEY(value.sym, buffer);
7350     if (result) {
7351       return result;
7352     }
7353   }
7354 
7355   if (selector == TPM_ALG_ECC) {
7356     result = Serialize_TPM2B_ECC_PARAMETER(value.ecc, buffer);
7357     if (result) {
7358       return result;
7359     }
7360   }
7361   return result;
7362 }
7363 
Parse_TPMU_SENSITIVE_COMPOSITE(std::string * buffer,TPMI_ALG_PUBLIC selector,TPMU_SENSITIVE_COMPOSITE * value,std::string * value_bytes)7364 TPM_RC Parse_TPMU_SENSITIVE_COMPOSITE(std::string* buffer,
7365                                       TPMI_ALG_PUBLIC selector,
7366                                       TPMU_SENSITIVE_COMPOSITE* value,
7367                                       std::string* value_bytes) {
7368   TPM_RC result = TPM_RC_SUCCESS;
7369   VLOG(3) << __func__;
7370 
7371   if (selector == TPM_ALG_KEYEDHASH) {
7372     result = Parse_TPM2B_SENSITIVE_DATA(buffer, &value->bits, value_bytes);
7373     if (result) {
7374       return result;
7375     }
7376   }
7377 
7378   if (selector == TPM_ALG_RSA) {
7379     result = Parse_TPM2B_PRIVATE_KEY_RSA(buffer, &value->rsa, value_bytes);
7380     if (result) {
7381       return result;
7382     }
7383   }
7384 
7385   if (selector == TPM_ALG_SYMCIPHER) {
7386     result = Parse_TPM2B_SYM_KEY(buffer, &value->sym, value_bytes);
7387     if (result) {
7388       return result;
7389     }
7390   }
7391 
7392   if (selector == TPM_ALG_ECC) {
7393     result = Parse_TPM2B_ECC_PARAMETER(buffer, &value->ecc, value_bytes);
7394     if (result) {
7395       return result;
7396     }
7397   }
7398   return result;
7399 }
7400 
Serialize_TPMT_SENSITIVE(const TPMT_SENSITIVE & value,std::string * buffer)7401 TPM_RC Serialize_TPMT_SENSITIVE(const TPMT_SENSITIVE& value,
7402                                 std::string* buffer) {
7403   TPM_RC result = TPM_RC_SUCCESS;
7404   VLOG(3) << __func__;
7405 
7406   result = Serialize_TPMI_ALG_PUBLIC(value.sensitive_type, buffer);
7407   if (result) {
7408     return result;
7409   }
7410 
7411   result = Serialize_TPM2B_AUTH(value.auth_value, buffer);
7412   if (result) {
7413     return result;
7414   }
7415 
7416   result = Serialize_TPM2B_DIGEST(value.seed_value, buffer);
7417   if (result) {
7418     return result;
7419   }
7420 
7421   result = Serialize_TPMU_SENSITIVE_COMPOSITE(value.sensitive,
7422                                               value.sensitive_type, buffer);
7423   if (result) {
7424     return result;
7425   }
7426   return result;
7427 }
7428 
Parse_TPMT_SENSITIVE(std::string * buffer,TPMT_SENSITIVE * value,std::string * value_bytes)7429 TPM_RC Parse_TPMT_SENSITIVE(std::string* buffer,
7430                             TPMT_SENSITIVE* value,
7431                             std::string* value_bytes) {
7432   TPM_RC result = TPM_RC_SUCCESS;
7433   VLOG(3) << __func__;
7434 
7435   result = Parse_TPMI_ALG_PUBLIC(buffer, &value->sensitive_type, value_bytes);
7436   if (result) {
7437     return result;
7438   }
7439 
7440   result = Parse_TPM2B_AUTH(buffer, &value->auth_value, value_bytes);
7441   if (result) {
7442     return result;
7443   }
7444 
7445   result = Parse_TPM2B_DIGEST(buffer, &value->seed_value, value_bytes);
7446   if (result) {
7447     return result;
7448   }
7449 
7450   result = Parse_TPMU_SENSITIVE_COMPOSITE(buffer, value->sensitive_type,
7451                                           &value->sensitive, value_bytes);
7452   if (result) {
7453     return result;
7454   }
7455   return result;
7456 }
7457 
Serialize_TPM2B_SENSITIVE(const TPM2B_SENSITIVE & value,std::string * buffer)7458 TPM_RC Serialize_TPM2B_SENSITIVE(const TPM2B_SENSITIVE& value,
7459                                  std::string* buffer) {
7460   TPM_RC result = TPM_RC_SUCCESS;
7461   VLOG(3) << __func__;
7462 
7463   std::string field_bytes;
7464   if (value.size) {
7465     if (value.size != sizeof(TPMT_SENSITIVE)) {
7466       return TPM_RC_SIZE;
7467     }
7468     result = Serialize_TPMT_SENSITIVE(value.sensitive_area, &field_bytes);
7469     if (result) {
7470       return result;
7471     }
7472   }
7473   std::string size_bytes;
7474   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7475   if (result) {
7476     return result;
7477   }
7478   buffer->append(size_bytes + field_bytes);
7479   return result;
7480 }
7481 
Parse_TPM2B_SENSITIVE(std::string * buffer,TPM2B_SENSITIVE * value,std::string * value_bytes)7482 TPM_RC Parse_TPM2B_SENSITIVE(std::string* buffer,
7483                              TPM2B_SENSITIVE* value,
7484                              std::string* value_bytes) {
7485   TPM_RC result = TPM_RC_SUCCESS;
7486   VLOG(3) << __func__;
7487 
7488   UINT16 parsed_size = 0;
7489   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7490   if (result) {
7491     return result;
7492   }
7493   if (!parsed_size) {
7494     value->size = 0;
7495   } else {
7496     value->size = sizeof(TPMT_SENSITIVE);
7497     result = Parse_TPMT_SENSITIVE(buffer, &value->sensitive_area, value_bytes);
7498     if (result) {
7499       return result;
7500     }
7501   }
7502   return result;
7503 }
7504 
Make_TPM2B_SENSITIVE(const TPMT_SENSITIVE & inner)7505 TPM2B_SENSITIVE Make_TPM2B_SENSITIVE(const TPMT_SENSITIVE& inner) {
7506   TPM2B_SENSITIVE tpm2b;
7507   tpm2b.size = sizeof(TPMT_SENSITIVE);
7508   tpm2b.sensitive_area = inner;
7509   return tpm2b;
7510 }
7511 
Serialize_TPM2B_PRIVATE(const TPM2B_PRIVATE & value,std::string * buffer)7512 TPM_RC Serialize_TPM2B_PRIVATE(const TPM2B_PRIVATE& value,
7513                                std::string* buffer) {
7514   TPM_RC result = TPM_RC_SUCCESS;
7515   VLOG(3) << __func__;
7516 
7517   result = Serialize_UINT16(value.size, buffer);
7518   if (result) {
7519     return result;
7520   }
7521 
7522   if (std::size(value.buffer) < value.size) {
7523     return TPM_RC_INSUFFICIENT;
7524   }
7525   for (uint32_t i = 0; i < value.size; ++i) {
7526     result = Serialize_BYTE(value.buffer[i], buffer);
7527     if (result) {
7528       return result;
7529     }
7530   }
7531   return result;
7532 }
7533 
Parse_TPM2B_PRIVATE(std::string * buffer,TPM2B_PRIVATE * value,std::string * value_bytes)7534 TPM_RC Parse_TPM2B_PRIVATE(std::string* buffer,
7535                            TPM2B_PRIVATE* value,
7536                            std::string* value_bytes) {
7537   TPM_RC result = TPM_RC_SUCCESS;
7538   VLOG(3) << __func__;
7539 
7540   result = Parse_UINT16(buffer, &value->size, value_bytes);
7541   if (result) {
7542     return result;
7543   }
7544 
7545   if (std::size(value->buffer) < value->size) {
7546     return TPM_RC_INSUFFICIENT;
7547   }
7548   for (uint32_t i = 0; i < value->size; ++i) {
7549     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7550     if (result) {
7551       return result;
7552     }
7553   }
7554   return result;
7555 }
7556 
Make_TPM2B_PRIVATE(const std::string & bytes)7557 TPM2B_PRIVATE Make_TPM2B_PRIVATE(const std::string& bytes) {
7558   TPM2B_PRIVATE tpm2b;
7559   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7560   memset(&tpm2b, 0, sizeof(TPM2B_PRIVATE));
7561   tpm2b.size = bytes.size();
7562   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7563   return tpm2b;
7564 }
7565 
StringFrom_TPM2B_PRIVATE(const TPM2B_PRIVATE & tpm2b)7566 std::string StringFrom_TPM2B_PRIVATE(const TPM2B_PRIVATE& tpm2b) {
7567   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7568   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7569   return std::string(char_buffer, tpm2b.size);
7570 }
7571 
Serialize_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT & value,std::string * buffer)7572 TPM_RC Serialize_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT& value,
7573                                  std::string* buffer) {
7574   TPM_RC result = TPM_RC_SUCCESS;
7575   VLOG(3) << __func__;
7576 
7577   result = Serialize_UINT16(value.size, buffer);
7578   if (result) {
7579     return result;
7580   }
7581 
7582   if (std::size(value.credential) < value.size) {
7583     return TPM_RC_INSUFFICIENT;
7584   }
7585   for (uint32_t i = 0; i < value.size; ++i) {
7586     result = Serialize_BYTE(value.credential[i], buffer);
7587     if (result) {
7588       return result;
7589     }
7590   }
7591   return result;
7592 }
7593 
Parse_TPM2B_ID_OBJECT(std::string * buffer,TPM2B_ID_OBJECT * value,std::string * value_bytes)7594 TPM_RC Parse_TPM2B_ID_OBJECT(std::string* buffer,
7595                              TPM2B_ID_OBJECT* value,
7596                              std::string* value_bytes) {
7597   TPM_RC result = TPM_RC_SUCCESS;
7598   VLOG(3) << __func__;
7599 
7600   result = Parse_UINT16(buffer, &value->size, value_bytes);
7601   if (result) {
7602     return result;
7603   }
7604 
7605   if (std::size(value->credential) < value->size) {
7606     return TPM_RC_INSUFFICIENT;
7607   }
7608   for (uint32_t i = 0; i < value->size; ++i) {
7609     result = Parse_BYTE(buffer, &value->credential[i], value_bytes);
7610     if (result) {
7611       return result;
7612     }
7613   }
7614   return result;
7615 }
7616 
Make_TPM2B_ID_OBJECT(const std::string & bytes)7617 TPM2B_ID_OBJECT Make_TPM2B_ID_OBJECT(const std::string& bytes) {
7618   TPM2B_ID_OBJECT tpm2b;
7619   CHECK(bytes.size() <= sizeof(tpm2b.credential));
7620   memset(&tpm2b, 0, sizeof(TPM2B_ID_OBJECT));
7621   tpm2b.size = bytes.size();
7622   memcpy(tpm2b.credential, bytes.data(), bytes.size());
7623   return tpm2b;
7624 }
7625 
StringFrom_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT & tpm2b)7626 std::string StringFrom_TPM2B_ID_OBJECT(const TPM2B_ID_OBJECT& tpm2b) {
7627   CHECK(tpm2b.size <= std::size(tpm2b.credential));
7628   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.credential);
7629   return std::string(char_buffer, tpm2b.size);
7630 }
7631 
Serialize_TPMS_NV_PUBLIC(const TPMS_NV_PUBLIC & value,std::string * buffer)7632 TPM_RC Serialize_TPMS_NV_PUBLIC(const TPMS_NV_PUBLIC& value,
7633                                 std::string* buffer) {
7634   TPM_RC result = TPM_RC_SUCCESS;
7635   VLOG(3) << __func__;
7636 
7637   result = Serialize_TPMI_RH_NV_INDEX(value.nv_index, buffer);
7638   if (result) {
7639     return result;
7640   }
7641 
7642   result = Serialize_TPMI_ALG_HASH(value.name_alg, buffer);
7643   if (result) {
7644     return result;
7645   }
7646 
7647   result = Serialize_TPMA_NV(value.attributes, buffer);
7648   if (result) {
7649     return result;
7650   }
7651 
7652   result = Serialize_TPM2B_DIGEST(value.auth_policy, buffer);
7653   if (result) {
7654     return result;
7655   }
7656 
7657   result = Serialize_UINT16(value.data_size, buffer);
7658   if (result) {
7659     return result;
7660   }
7661   return result;
7662 }
7663 
Parse_TPMS_NV_PUBLIC(std::string * buffer,TPMS_NV_PUBLIC * value,std::string * value_bytes)7664 TPM_RC Parse_TPMS_NV_PUBLIC(std::string* buffer,
7665                             TPMS_NV_PUBLIC* value,
7666                             std::string* value_bytes) {
7667   TPM_RC result = TPM_RC_SUCCESS;
7668   VLOG(3) << __func__;
7669 
7670   result = Parse_TPMI_RH_NV_INDEX(buffer, &value->nv_index, value_bytes);
7671   if (result) {
7672     return result;
7673   }
7674 
7675   result = Parse_TPMI_ALG_HASH(buffer, &value->name_alg, value_bytes);
7676   if (result) {
7677     return result;
7678   }
7679 
7680   result = Parse_TPMA_NV(buffer, &value->attributes, value_bytes);
7681   if (result) {
7682     return result;
7683   }
7684 
7685   result = Parse_TPM2B_DIGEST(buffer, &value->auth_policy, value_bytes);
7686   if (result) {
7687     return result;
7688   }
7689 
7690   result = Parse_UINT16(buffer, &value->data_size, value_bytes);
7691   if (result) {
7692     return result;
7693   }
7694   return result;
7695 }
7696 
Serialize_TPM2B_NV_PUBLIC(const TPM2B_NV_PUBLIC & value,std::string * buffer)7697 TPM_RC Serialize_TPM2B_NV_PUBLIC(const TPM2B_NV_PUBLIC& value,
7698                                  std::string* buffer) {
7699   TPM_RC result = TPM_RC_SUCCESS;
7700   VLOG(3) << __func__;
7701 
7702   std::string field_bytes;
7703   if (value.size) {
7704     if (value.size != sizeof(TPMS_NV_PUBLIC)) {
7705       return TPM_RC_SIZE;
7706     }
7707     result = Serialize_TPMS_NV_PUBLIC(value.nv_public, &field_bytes);
7708     if (result) {
7709       return result;
7710     }
7711   }
7712   std::string size_bytes;
7713   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
7714   if (result) {
7715     return result;
7716   }
7717   buffer->append(size_bytes + field_bytes);
7718   return result;
7719 }
7720 
Parse_TPM2B_NV_PUBLIC(std::string * buffer,TPM2B_NV_PUBLIC * value,std::string * value_bytes)7721 TPM_RC Parse_TPM2B_NV_PUBLIC(std::string* buffer,
7722                              TPM2B_NV_PUBLIC* value,
7723                              std::string* value_bytes) {
7724   TPM_RC result = TPM_RC_SUCCESS;
7725   VLOG(3) << __func__;
7726 
7727   UINT16 parsed_size = 0;
7728   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
7729   if (result) {
7730     return result;
7731   }
7732   if (!parsed_size) {
7733     value->size = 0;
7734   } else {
7735     value->size = sizeof(TPMS_NV_PUBLIC);
7736     result = Parse_TPMS_NV_PUBLIC(buffer, &value->nv_public, value_bytes);
7737     if (result) {
7738       return result;
7739     }
7740   }
7741   return result;
7742 }
7743 
Make_TPM2B_NV_PUBLIC(const TPMS_NV_PUBLIC & inner)7744 TPM2B_NV_PUBLIC Make_TPM2B_NV_PUBLIC(const TPMS_NV_PUBLIC& inner) {
7745   TPM2B_NV_PUBLIC tpm2b;
7746   tpm2b.size = sizeof(TPMS_NV_PUBLIC);
7747   tpm2b.nv_public = inner;
7748   return tpm2b;
7749 }
7750 
Serialize_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE & value,std::string * buffer)7751 TPM_RC Serialize_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE& value,
7752                                          std::string* buffer) {
7753   TPM_RC result = TPM_RC_SUCCESS;
7754   VLOG(3) << __func__;
7755 
7756   result = Serialize_UINT16(value.size, buffer);
7757   if (result) {
7758     return result;
7759   }
7760 
7761   if (std::size(value.buffer) < value.size) {
7762     return TPM_RC_INSUFFICIENT;
7763   }
7764   for (uint32_t i = 0; i < value.size; ++i) {
7765     result = Serialize_BYTE(value.buffer[i], buffer);
7766     if (result) {
7767       return result;
7768     }
7769   }
7770   return result;
7771 }
7772 
Parse_TPM2B_CONTEXT_SENSITIVE(std::string * buffer,TPM2B_CONTEXT_SENSITIVE * value,std::string * value_bytes)7773 TPM_RC Parse_TPM2B_CONTEXT_SENSITIVE(std::string* buffer,
7774                                      TPM2B_CONTEXT_SENSITIVE* value,
7775                                      std::string* value_bytes) {
7776   TPM_RC result = TPM_RC_SUCCESS;
7777   VLOG(3) << __func__;
7778 
7779   result = Parse_UINT16(buffer, &value->size, value_bytes);
7780   if (result) {
7781     return result;
7782   }
7783 
7784   if (std::size(value->buffer) < value->size) {
7785     return TPM_RC_INSUFFICIENT;
7786   }
7787   for (uint32_t i = 0; i < value->size; ++i) {
7788     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7789     if (result) {
7790       return result;
7791     }
7792   }
7793   return result;
7794 }
7795 
Make_TPM2B_CONTEXT_SENSITIVE(const std::string & bytes)7796 TPM2B_CONTEXT_SENSITIVE Make_TPM2B_CONTEXT_SENSITIVE(const std::string& bytes) {
7797   TPM2B_CONTEXT_SENSITIVE tpm2b;
7798   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7799   memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_SENSITIVE));
7800   tpm2b.size = bytes.size();
7801   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7802   return tpm2b;
7803 }
7804 
StringFrom_TPM2B_CONTEXT_SENSITIVE(const TPM2B_CONTEXT_SENSITIVE & tpm2b)7805 std::string StringFrom_TPM2B_CONTEXT_SENSITIVE(
7806     const TPM2B_CONTEXT_SENSITIVE& tpm2b) {
7807   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7808   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7809   return std::string(char_buffer, tpm2b.size);
7810 }
7811 
Serialize_TPMS_CONTEXT_DATA(const TPMS_CONTEXT_DATA & value,std::string * buffer)7812 TPM_RC Serialize_TPMS_CONTEXT_DATA(const TPMS_CONTEXT_DATA& value,
7813                                    std::string* buffer) {
7814   TPM_RC result = TPM_RC_SUCCESS;
7815   VLOG(3) << __func__;
7816 
7817   result = Serialize_TPM2B_DIGEST(value.integrity, buffer);
7818   if (result) {
7819     return result;
7820   }
7821 
7822   result = Serialize_TPM2B_CONTEXT_SENSITIVE(value.encrypted, buffer);
7823   if (result) {
7824     return result;
7825   }
7826   return result;
7827 }
7828 
Parse_TPMS_CONTEXT_DATA(std::string * buffer,TPMS_CONTEXT_DATA * value,std::string * value_bytes)7829 TPM_RC Parse_TPMS_CONTEXT_DATA(std::string* buffer,
7830                                TPMS_CONTEXT_DATA* value,
7831                                std::string* value_bytes) {
7832   TPM_RC result = TPM_RC_SUCCESS;
7833   VLOG(3) << __func__;
7834 
7835   result = Parse_TPM2B_DIGEST(buffer, &value->integrity, value_bytes);
7836   if (result) {
7837     return result;
7838   }
7839 
7840   result =
7841       Parse_TPM2B_CONTEXT_SENSITIVE(buffer, &value->encrypted, value_bytes);
7842   if (result) {
7843     return result;
7844   }
7845   return result;
7846 }
7847 
Serialize_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA & value,std::string * buffer)7848 TPM_RC Serialize_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA& value,
7849                                     std::string* buffer) {
7850   TPM_RC result = TPM_RC_SUCCESS;
7851   VLOG(3) << __func__;
7852 
7853   result = Serialize_UINT16(value.size, buffer);
7854   if (result) {
7855     return result;
7856   }
7857 
7858   if (std::size(value.buffer) < value.size) {
7859     return TPM_RC_INSUFFICIENT;
7860   }
7861   for (uint32_t i = 0; i < value.size; ++i) {
7862     result = Serialize_BYTE(value.buffer[i], buffer);
7863     if (result) {
7864       return result;
7865     }
7866   }
7867   return result;
7868 }
7869 
Parse_TPM2B_CONTEXT_DATA(std::string * buffer,TPM2B_CONTEXT_DATA * value,std::string * value_bytes)7870 TPM_RC Parse_TPM2B_CONTEXT_DATA(std::string* buffer,
7871                                 TPM2B_CONTEXT_DATA* value,
7872                                 std::string* value_bytes) {
7873   TPM_RC result = TPM_RC_SUCCESS;
7874   VLOG(3) << __func__;
7875 
7876   result = Parse_UINT16(buffer, &value->size, value_bytes);
7877   if (result) {
7878     return result;
7879   }
7880 
7881   if (std::size(value->buffer) < value->size) {
7882     return TPM_RC_INSUFFICIENT;
7883   }
7884   for (uint32_t i = 0; i < value->size; ++i) {
7885     result = Parse_BYTE(buffer, &value->buffer[i], value_bytes);
7886     if (result) {
7887       return result;
7888     }
7889   }
7890   return result;
7891 }
7892 
Make_TPM2B_CONTEXT_DATA(const std::string & bytes)7893 TPM2B_CONTEXT_DATA Make_TPM2B_CONTEXT_DATA(const std::string& bytes) {
7894   TPM2B_CONTEXT_DATA tpm2b;
7895   CHECK(bytes.size() <= sizeof(tpm2b.buffer));
7896   memset(&tpm2b, 0, sizeof(TPM2B_CONTEXT_DATA));
7897   tpm2b.size = bytes.size();
7898   memcpy(tpm2b.buffer, bytes.data(), bytes.size());
7899   return tpm2b;
7900 }
7901 
StringFrom_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA & tpm2b)7902 std::string StringFrom_TPM2B_CONTEXT_DATA(const TPM2B_CONTEXT_DATA& tpm2b) {
7903   CHECK(tpm2b.size <= std::size(tpm2b.buffer));
7904   const char* char_buffer = reinterpret_cast<const char*>(tpm2b.buffer);
7905   return std::string(char_buffer, tpm2b.size);
7906 }
7907 
Serialize_TPMS_CONTEXT(const TPMS_CONTEXT & value,std::string * buffer)7908 TPM_RC Serialize_TPMS_CONTEXT(const TPMS_CONTEXT& value, std::string* buffer) {
7909   TPM_RC result = TPM_RC_SUCCESS;
7910   VLOG(3) << __func__;
7911 
7912   result = Serialize_UINT64(value.sequence, buffer);
7913   if (result) {
7914     return result;
7915   }
7916 
7917   result = Serialize_TPMI_DH_CONTEXT(value.saved_handle, buffer);
7918   if (result) {
7919     return result;
7920   }
7921 
7922   result = Serialize_TPMI_RH_HIERARCHY(value.hierarchy, buffer);
7923   if (result) {
7924     return result;
7925   }
7926 
7927   result = Serialize_TPM2B_CONTEXT_DATA(value.context_blob, buffer);
7928   if (result) {
7929     return result;
7930   }
7931   return result;
7932 }
7933 
Parse_TPMS_CONTEXT(std::string * buffer,TPMS_CONTEXT * value,std::string * value_bytes)7934 TPM_RC Parse_TPMS_CONTEXT(std::string* buffer,
7935                           TPMS_CONTEXT* value,
7936                           std::string* value_bytes) {
7937   TPM_RC result = TPM_RC_SUCCESS;
7938   VLOG(3) << __func__;
7939 
7940   result = Parse_UINT64(buffer, &value->sequence, value_bytes);
7941   if (result) {
7942     return result;
7943   }
7944 
7945   result = Parse_TPMI_DH_CONTEXT(buffer, &value->saved_handle, value_bytes);
7946   if (result) {
7947     return result;
7948   }
7949 
7950   result = Parse_TPMI_RH_HIERARCHY(buffer, &value->hierarchy, value_bytes);
7951   if (result) {
7952     return result;
7953   }
7954 
7955   result = Parse_TPM2B_CONTEXT_DATA(buffer, &value->context_blob, value_bytes);
7956   if (result) {
7957     return result;
7958   }
7959   return result;
7960 }
7961 
Serialize_TPMS_CREATION_DATA(const TPMS_CREATION_DATA & value,std::string * buffer)7962 TPM_RC Serialize_TPMS_CREATION_DATA(const TPMS_CREATION_DATA& value,
7963                                     std::string* buffer) {
7964   TPM_RC result = TPM_RC_SUCCESS;
7965   VLOG(3) << __func__;
7966 
7967   result = Serialize_TPML_PCR_SELECTION(value.pcr_select, buffer);
7968   if (result) {
7969     return result;
7970   }
7971 
7972   result = Serialize_TPM2B_DIGEST(value.pcr_digest, buffer);
7973   if (result) {
7974     return result;
7975   }
7976 
7977   result = Serialize_TPMA_LOCALITY(value.locality, buffer);
7978   if (result) {
7979     return result;
7980   }
7981 
7982   result = Serialize_TPM_ALG_ID(value.parent_name_alg, buffer);
7983   if (result) {
7984     return result;
7985   }
7986 
7987   result = Serialize_TPM2B_NAME(value.parent_name, buffer);
7988   if (result) {
7989     return result;
7990   }
7991 
7992   result = Serialize_TPM2B_NAME(value.parent_qualified_name, buffer);
7993   if (result) {
7994     return result;
7995   }
7996 
7997   result = Serialize_TPM2B_DATA(value.outside_info, buffer);
7998   if (result) {
7999     return result;
8000   }
8001   return result;
8002 }
8003 
Parse_TPMS_CREATION_DATA(std::string * buffer,TPMS_CREATION_DATA * value,std::string * value_bytes)8004 TPM_RC Parse_TPMS_CREATION_DATA(std::string* buffer,
8005                                 TPMS_CREATION_DATA* value,
8006                                 std::string* value_bytes) {
8007   TPM_RC result = TPM_RC_SUCCESS;
8008   VLOG(3) << __func__;
8009 
8010   result = Parse_TPML_PCR_SELECTION(buffer, &value->pcr_select, value_bytes);
8011   if (result) {
8012     return result;
8013   }
8014 
8015   result = Parse_TPM2B_DIGEST(buffer, &value->pcr_digest, value_bytes);
8016   if (result) {
8017     return result;
8018   }
8019 
8020   result = Parse_TPMA_LOCALITY(buffer, &value->locality, value_bytes);
8021   if (result) {
8022     return result;
8023   }
8024 
8025   result = Parse_TPM_ALG_ID(buffer, &value->parent_name_alg, value_bytes);
8026   if (result) {
8027     return result;
8028   }
8029 
8030   result = Parse_TPM2B_NAME(buffer, &value->parent_name, value_bytes);
8031   if (result) {
8032     return result;
8033   }
8034 
8035   result = Parse_TPM2B_NAME(buffer, &value->parent_qualified_name, value_bytes);
8036   if (result) {
8037     return result;
8038   }
8039 
8040   result = Parse_TPM2B_DATA(buffer, &value->outside_info, value_bytes);
8041   if (result) {
8042     return result;
8043   }
8044   return result;
8045 }
8046 
Serialize_TPM2B_CREATION_DATA(const TPM2B_CREATION_DATA & value,std::string * buffer)8047 TPM_RC Serialize_TPM2B_CREATION_DATA(const TPM2B_CREATION_DATA& value,
8048                                      std::string* buffer) {
8049   TPM_RC result = TPM_RC_SUCCESS;
8050   VLOG(3) << __func__;
8051 
8052   std::string field_bytes;
8053   if (value.size) {
8054     if (value.size != sizeof(TPMS_CREATION_DATA)) {
8055       return TPM_RC_SIZE;
8056     }
8057     result = Serialize_TPMS_CREATION_DATA(value.creation_data, &field_bytes);
8058     if (result) {
8059       return result;
8060     }
8061   }
8062   std::string size_bytes;
8063   result = Serialize_UINT16(field_bytes.size(), &size_bytes);
8064   if (result) {
8065     return result;
8066   }
8067   buffer->append(size_bytes + field_bytes);
8068   return result;
8069 }
8070 
Parse_TPM2B_CREATION_DATA(std::string * buffer,TPM2B_CREATION_DATA * value,std::string * value_bytes)8071 TPM_RC Parse_TPM2B_CREATION_DATA(std::string* buffer,
8072                                  TPM2B_CREATION_DATA* value,
8073                                  std::string* value_bytes) {
8074   TPM_RC result = TPM_RC_SUCCESS;
8075   VLOG(3) << __func__;
8076 
8077   UINT16 parsed_size = 0;
8078   result = Parse_UINT16(buffer, &parsed_size, value_bytes);
8079   if (result) {
8080     return result;
8081   }
8082   if (!parsed_size) {
8083     value->size = 0;
8084   } else {
8085     value->size = sizeof(TPMS_CREATION_DATA);
8086     result =
8087         Parse_TPMS_CREATION_DATA(buffer, &value->creation_data, value_bytes);
8088     if (result) {
8089       return result;
8090     }
8091   }
8092   return result;
8093 }
8094 
Make_TPM2B_CREATION_DATA(const TPMS_CREATION_DATA & inner)8095 TPM2B_CREATION_DATA Make_TPM2B_CREATION_DATA(const TPMS_CREATION_DATA& inner) {
8096   TPM2B_CREATION_DATA tpm2b;
8097   tpm2b.size = sizeof(TPMS_CREATION_DATA);
8098   tpm2b.creation_data = inner;
8099   return tpm2b;
8100 }
8101 
SerializeCommand_Startup(const TPM_SU & startup_type,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8102 TPM_RC Tpm::SerializeCommand_Startup(
8103     const TPM_SU& startup_type,
8104     std::string* serialized_command,
8105     AuthorizationDelegate* authorization_delegate) {
8106   VLOG(3) << __func__;
8107   TPM_RC rc = TPM_RC_SUCCESS;
8108   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8109   UINT32 command_size = 10;  // Header size.
8110   std::string handle_section_bytes;
8111   std::string parameter_section_bytes;
8112   TPM_CC command_code = TPM_CC_Startup;
8113   bool is_command_parameter_encryption_possible = false;
8114   bool is_response_parameter_encryption_possible = false;
8115   std::string command_code_bytes;
8116   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8117   if (rc != TPM_RC_SUCCESS) {
8118     return rc;
8119   }
8120   std::string startup_type_bytes;
8121   rc = Serialize_TPM_SU(startup_type, &startup_type_bytes);
8122   if (rc != TPM_RC_SUCCESS) {
8123     return rc;
8124   }
8125   std::unique_ptr<crypto::SecureHash> hash(
8126       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8127   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8128   hash->Update(startup_type_bytes.data(), startup_type_bytes.size());
8129   parameter_section_bytes += startup_type_bytes;
8130   command_size += startup_type_bytes.size();
8131   std::string command_hash(32, 0);
8132   hash->Finish(std::data(command_hash), command_hash.size());
8133   std::string authorization_section_bytes;
8134   std::string authorization_size_bytes;
8135   if (authorization_delegate) {
8136     if (!authorization_delegate->GetCommandAuthorization(
8137             command_hash, is_command_parameter_encryption_possible,
8138             is_response_parameter_encryption_possible,
8139             &authorization_section_bytes)) {
8140       return TRUNKS_RC_AUTHORIZATION_FAILED;
8141     }
8142     if (!authorization_section_bytes.empty()) {
8143       tag = TPM_ST_SESSIONS;
8144       std::string tmp;
8145       rc = Serialize_UINT32(authorization_section_bytes.size(),
8146                             &authorization_size_bytes);
8147       if (rc != TPM_RC_SUCCESS) {
8148         return rc;
8149       }
8150       command_size +=
8151           authorization_size_bytes.size() + authorization_section_bytes.size();
8152     }
8153   }
8154   std::string tag_bytes;
8155   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8156   if (rc != TPM_RC_SUCCESS) {
8157     return rc;
8158   }
8159   std::string command_size_bytes;
8160   rc = Serialize_UINT32(command_size, &command_size_bytes);
8161   if (rc != TPM_RC_SUCCESS) {
8162     return rc;
8163   }
8164   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8165                         handle_section_bytes + authorization_size_bytes +
8166                         authorization_section_bytes + parameter_section_bytes;
8167   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8168   VLOG(2) << "Command: "
8169           << base::HexEncode(serialized_command->data(),
8170                              serialized_command->size());
8171   return TPM_RC_SUCCESS;
8172 }
8173 
ParseResponse_Startup(const std::string & response,AuthorizationDelegate * authorization_delegate)8174 TPM_RC Tpm::ParseResponse_Startup(
8175     const std::string& response,
8176     AuthorizationDelegate* authorization_delegate) {
8177   VLOG(3) << __func__;
8178   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8179   TPM_RC rc = TPM_RC_SUCCESS;
8180   std::string buffer(response);
8181   TPM_ST tag;
8182   std::string tag_bytes;
8183   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8184   if (rc != TPM_RC_SUCCESS) {
8185     return rc;
8186   }
8187   UINT32 response_size;
8188   std::string response_size_bytes;
8189   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8190   if (rc != TPM_RC_SUCCESS) {
8191     return rc;
8192   }
8193   TPM_RC response_code;
8194   std::string response_code_bytes;
8195   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8196   if (rc != TPM_RC_SUCCESS) {
8197     return rc;
8198   }
8199   if (response_size != response.size()) {
8200     return TPM_RC_SIZE;
8201   }
8202   if (response_code != TPM_RC_SUCCESS) {
8203     return response_code;
8204   }
8205   TPM_CC command_code = TPM_CC_Startup;
8206   std::string command_code_bytes;
8207   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8208   if (rc != TPM_RC_SUCCESS) {
8209     return rc;
8210   }
8211   std::string authorization_section_bytes;
8212   if (tag == TPM_ST_SESSIONS) {
8213     UINT32 parameter_section_size = buffer.size();
8214     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8215     if (rc != TPM_RC_SUCCESS) {
8216       return rc;
8217     }
8218     if (parameter_section_size > buffer.size()) {
8219       return TPM_RC_INSUFFICIENT;
8220     }
8221     authorization_section_bytes = buffer.substr(parameter_section_size);
8222     // Keep the parameter section in |buffer|.
8223     buffer.erase(parameter_section_size);
8224   }
8225   std::unique_ptr<crypto::SecureHash> hash(
8226       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8227   hash->Update(response_code_bytes.data(), response_code_bytes.size());
8228   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8229   hash->Update(buffer.data(), buffer.size());
8230   std::string response_hash(32, 0);
8231   hash->Finish(std::data(response_hash), response_hash.size());
8232   if (tag == TPM_ST_SESSIONS) {
8233     if (!authorization_delegate)
8234       return TRUNKS_RC_AUTHORIZATION_FAILED;
8235     if (!authorization_delegate->CheckResponseAuthorization(
8236             response_hash, authorization_section_bytes)) {
8237       return TRUNKS_RC_AUTHORIZATION_FAILED;
8238     }
8239   }
8240   return TPM_RC_SUCCESS;
8241 }
8242 
StartupErrorCallback(Tpm::StartupResponse callback,TPM_RC response_code)8243 void StartupErrorCallback(Tpm::StartupResponse callback, TPM_RC response_code) {
8244   VLOG(1) << __func__;
8245   std::move(callback).Run(response_code);
8246 }
8247 
StartupResponseParser(Tpm::StartupResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8248 void StartupResponseParser(Tpm::StartupResponse callback,
8249                            AuthorizationDelegate* authorization_delegate,
8250                            const std::string& response) {
8251   VLOG(1) << __func__;
8252   TPM_RC rc = Tpm::ParseResponse_Startup(response, authorization_delegate);
8253   if (rc != TPM_RC_SUCCESS) {
8254     base::OnceCallback<void(TPM_RC)> error_reporter =
8255         base::BindOnce(StartupErrorCallback, std::move(callback));
8256     std::move(error_reporter).Run(rc);
8257     return;
8258   }
8259   std::move(callback).Run(rc);
8260 }
8261 
Startup(const TPM_SU & startup_type,AuthorizationDelegate * authorization_delegate,StartupResponse callback)8262 void Tpm::Startup(const TPM_SU& startup_type,
8263                   AuthorizationDelegate* authorization_delegate,
8264                   StartupResponse callback) {
8265   VLOG(1) << __func__;
8266   std::string command;
8267   TPM_RC rc =
8268       SerializeCommand_Startup(startup_type, &command, authorization_delegate);
8269   if (rc != TPM_RC_SUCCESS) {
8270     base::OnceCallback<void(TPM_RC)> error_reporter =
8271         base::BindOnce(StartupErrorCallback, std::move(callback));
8272     std::move(error_reporter).Run(rc);
8273     return;
8274   }
8275   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8276       StartupResponseParser, std::move(callback), authorization_delegate);
8277   transceiver_->SendCommand(command, std::move(parser));
8278 }
8279 
StartupSync(const TPM_SU & startup_type,AuthorizationDelegate * authorization_delegate)8280 TPM_RC Tpm::StartupSync(const TPM_SU& startup_type,
8281                         AuthorizationDelegate* authorization_delegate) {
8282   VLOG(1) << __func__;
8283   std::string command;
8284   TPM_RC rc =
8285       SerializeCommand_Startup(startup_type, &command, authorization_delegate);
8286   if (rc != TPM_RC_SUCCESS) {
8287     return rc;
8288   }
8289   std::string response = transceiver_->SendCommandAndWait(command);
8290   rc = ParseResponse_Startup(response, authorization_delegate);
8291   return rc;
8292 }
8293 
SerializeCommand_Shutdown(const TPM_SU & shutdown_type,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8294 TPM_RC Tpm::SerializeCommand_Shutdown(
8295     const TPM_SU& shutdown_type,
8296     std::string* serialized_command,
8297     AuthorizationDelegate* authorization_delegate) {
8298   VLOG(3) << __func__;
8299   TPM_RC rc = TPM_RC_SUCCESS;
8300   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8301   UINT32 command_size = 10;  // Header size.
8302   std::string handle_section_bytes;
8303   std::string parameter_section_bytes;
8304   TPM_CC command_code = TPM_CC_Shutdown;
8305   bool is_command_parameter_encryption_possible = false;
8306   bool is_response_parameter_encryption_possible = false;
8307   std::string command_code_bytes;
8308   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8309   if (rc != TPM_RC_SUCCESS) {
8310     return rc;
8311   }
8312   std::string shutdown_type_bytes;
8313   rc = Serialize_TPM_SU(shutdown_type, &shutdown_type_bytes);
8314   if (rc != TPM_RC_SUCCESS) {
8315     return rc;
8316   }
8317   std::unique_ptr<crypto::SecureHash> hash(
8318       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8319   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8320   hash->Update(shutdown_type_bytes.data(), shutdown_type_bytes.size());
8321   parameter_section_bytes += shutdown_type_bytes;
8322   command_size += shutdown_type_bytes.size();
8323   std::string command_hash(32, 0);
8324   hash->Finish(std::data(command_hash), command_hash.size());
8325   std::string authorization_section_bytes;
8326   std::string authorization_size_bytes;
8327   if (authorization_delegate) {
8328     if (!authorization_delegate->GetCommandAuthorization(
8329             command_hash, is_command_parameter_encryption_possible,
8330             is_response_parameter_encryption_possible,
8331             &authorization_section_bytes)) {
8332       return TRUNKS_RC_AUTHORIZATION_FAILED;
8333     }
8334     if (!authorization_section_bytes.empty()) {
8335       tag = TPM_ST_SESSIONS;
8336       std::string tmp;
8337       rc = Serialize_UINT32(authorization_section_bytes.size(),
8338                             &authorization_size_bytes);
8339       if (rc != TPM_RC_SUCCESS) {
8340         return rc;
8341       }
8342       command_size +=
8343           authorization_size_bytes.size() + authorization_section_bytes.size();
8344     }
8345   }
8346   std::string tag_bytes;
8347   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8348   if (rc != TPM_RC_SUCCESS) {
8349     return rc;
8350   }
8351   std::string command_size_bytes;
8352   rc = Serialize_UINT32(command_size, &command_size_bytes);
8353   if (rc != TPM_RC_SUCCESS) {
8354     return rc;
8355   }
8356   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8357                         handle_section_bytes + authorization_size_bytes +
8358                         authorization_section_bytes + parameter_section_bytes;
8359   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8360   VLOG(2) << "Command: "
8361           << base::HexEncode(serialized_command->data(),
8362                              serialized_command->size());
8363   return TPM_RC_SUCCESS;
8364 }
8365 
ParseResponse_Shutdown(const std::string & response,AuthorizationDelegate * authorization_delegate)8366 TPM_RC Tpm::ParseResponse_Shutdown(
8367     const std::string& response,
8368     AuthorizationDelegate* authorization_delegate) {
8369   VLOG(3) << __func__;
8370   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8371   TPM_RC rc = TPM_RC_SUCCESS;
8372   std::string buffer(response);
8373   TPM_ST tag;
8374   std::string tag_bytes;
8375   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8376   if (rc != TPM_RC_SUCCESS) {
8377     return rc;
8378   }
8379   UINT32 response_size;
8380   std::string response_size_bytes;
8381   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8382   if (rc != TPM_RC_SUCCESS) {
8383     return rc;
8384   }
8385   TPM_RC response_code;
8386   std::string response_code_bytes;
8387   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8388   if (rc != TPM_RC_SUCCESS) {
8389     return rc;
8390   }
8391   if (response_size != response.size()) {
8392     return TPM_RC_SIZE;
8393   }
8394   if (response_code != TPM_RC_SUCCESS) {
8395     return response_code;
8396   }
8397   TPM_CC command_code = TPM_CC_Shutdown;
8398   std::string command_code_bytes;
8399   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8400   if (rc != TPM_RC_SUCCESS) {
8401     return rc;
8402   }
8403   std::string authorization_section_bytes;
8404   if (tag == TPM_ST_SESSIONS) {
8405     UINT32 parameter_section_size = buffer.size();
8406     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8407     if (rc != TPM_RC_SUCCESS) {
8408       return rc;
8409     }
8410     if (parameter_section_size > buffer.size()) {
8411       return TPM_RC_INSUFFICIENT;
8412     }
8413     authorization_section_bytes = buffer.substr(parameter_section_size);
8414     // Keep the parameter section in |buffer|.
8415     buffer.erase(parameter_section_size);
8416   }
8417   std::unique_ptr<crypto::SecureHash> hash(
8418       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8419   hash->Update(response_code_bytes.data(), response_code_bytes.size());
8420   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8421   hash->Update(buffer.data(), buffer.size());
8422   std::string response_hash(32, 0);
8423   hash->Finish(std::data(response_hash), response_hash.size());
8424   if (tag == TPM_ST_SESSIONS) {
8425     if (!authorization_delegate)
8426       return TRUNKS_RC_AUTHORIZATION_FAILED;
8427     if (!authorization_delegate->CheckResponseAuthorization(
8428             response_hash, authorization_section_bytes)) {
8429       return TRUNKS_RC_AUTHORIZATION_FAILED;
8430     }
8431   }
8432   return TPM_RC_SUCCESS;
8433 }
8434 
ShutdownErrorCallback(Tpm::ShutdownResponse callback,TPM_RC response_code)8435 void ShutdownErrorCallback(Tpm::ShutdownResponse callback,
8436                            TPM_RC response_code) {
8437   VLOG(1) << __func__;
8438   std::move(callback).Run(response_code);
8439 }
8440 
ShutdownResponseParser(Tpm::ShutdownResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8441 void ShutdownResponseParser(Tpm::ShutdownResponse callback,
8442                             AuthorizationDelegate* authorization_delegate,
8443                             const std::string& response) {
8444   VLOG(1) << __func__;
8445   TPM_RC rc = Tpm::ParseResponse_Shutdown(response, authorization_delegate);
8446   if (rc != TPM_RC_SUCCESS) {
8447     base::OnceCallback<void(TPM_RC)> error_reporter =
8448         base::BindOnce(ShutdownErrorCallback, std::move(callback));
8449     std::move(error_reporter).Run(rc);
8450     return;
8451   }
8452   std::move(callback).Run(rc);
8453 }
8454 
Shutdown(const TPM_SU & shutdown_type,AuthorizationDelegate * authorization_delegate,ShutdownResponse callback)8455 void Tpm::Shutdown(const TPM_SU& shutdown_type,
8456                    AuthorizationDelegate* authorization_delegate,
8457                    ShutdownResponse callback) {
8458   VLOG(1) << __func__;
8459   std::string command;
8460   TPM_RC rc = SerializeCommand_Shutdown(shutdown_type, &command,
8461                                         authorization_delegate);
8462   if (rc != TPM_RC_SUCCESS) {
8463     base::OnceCallback<void(TPM_RC)> error_reporter =
8464         base::BindOnce(ShutdownErrorCallback, std::move(callback));
8465     std::move(error_reporter).Run(rc);
8466     return;
8467   }
8468   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8469       ShutdownResponseParser, std::move(callback), authorization_delegate);
8470   transceiver_->SendCommand(command, std::move(parser));
8471 }
8472 
ShutdownSync(const TPM_SU & shutdown_type,AuthorizationDelegate * authorization_delegate)8473 TPM_RC Tpm::ShutdownSync(const TPM_SU& shutdown_type,
8474                          AuthorizationDelegate* authorization_delegate) {
8475   VLOG(1) << __func__;
8476   std::string command;
8477   TPM_RC rc = SerializeCommand_Shutdown(shutdown_type, &command,
8478                                         authorization_delegate);
8479   if (rc != TPM_RC_SUCCESS) {
8480     return rc;
8481   }
8482   std::string response = transceiver_->SendCommandAndWait(command);
8483   rc = ParseResponse_Shutdown(response, authorization_delegate);
8484   return rc;
8485 }
8486 
SerializeCommand_SelfTest(const TPMI_YES_NO & full_test,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8487 TPM_RC Tpm::SerializeCommand_SelfTest(
8488     const TPMI_YES_NO& full_test,
8489     std::string* serialized_command,
8490     AuthorizationDelegate* authorization_delegate) {
8491   VLOG(3) << __func__;
8492   TPM_RC rc = TPM_RC_SUCCESS;
8493   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8494   UINT32 command_size = 10;  // Header size.
8495   std::string handle_section_bytes;
8496   std::string parameter_section_bytes;
8497   TPM_CC command_code = TPM_CC_SelfTest;
8498   bool is_command_parameter_encryption_possible = false;
8499   bool is_response_parameter_encryption_possible = false;
8500   std::string command_code_bytes;
8501   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8502   if (rc != TPM_RC_SUCCESS) {
8503     return rc;
8504   }
8505   std::string full_test_bytes;
8506   rc = Serialize_TPMI_YES_NO(full_test, &full_test_bytes);
8507   if (rc != TPM_RC_SUCCESS) {
8508     return rc;
8509   }
8510   std::unique_ptr<crypto::SecureHash> hash(
8511       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8512   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8513   hash->Update(full_test_bytes.data(), full_test_bytes.size());
8514   parameter_section_bytes += full_test_bytes;
8515   command_size += full_test_bytes.size();
8516   std::string command_hash(32, 0);
8517   hash->Finish(std::data(command_hash), command_hash.size());
8518   std::string authorization_section_bytes;
8519   std::string authorization_size_bytes;
8520   if (authorization_delegate) {
8521     if (!authorization_delegate->GetCommandAuthorization(
8522             command_hash, is_command_parameter_encryption_possible,
8523             is_response_parameter_encryption_possible,
8524             &authorization_section_bytes)) {
8525       return TRUNKS_RC_AUTHORIZATION_FAILED;
8526     }
8527     if (!authorization_section_bytes.empty()) {
8528       tag = TPM_ST_SESSIONS;
8529       std::string tmp;
8530       rc = Serialize_UINT32(authorization_section_bytes.size(),
8531                             &authorization_size_bytes);
8532       if (rc != TPM_RC_SUCCESS) {
8533         return rc;
8534       }
8535       command_size +=
8536           authorization_size_bytes.size() + authorization_section_bytes.size();
8537     }
8538   }
8539   std::string tag_bytes;
8540   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8541   if (rc != TPM_RC_SUCCESS) {
8542     return rc;
8543   }
8544   std::string command_size_bytes;
8545   rc = Serialize_UINT32(command_size, &command_size_bytes);
8546   if (rc != TPM_RC_SUCCESS) {
8547     return rc;
8548   }
8549   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8550                         handle_section_bytes + authorization_size_bytes +
8551                         authorization_section_bytes + parameter_section_bytes;
8552   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8553   VLOG(2) << "Command: "
8554           << base::HexEncode(serialized_command->data(),
8555                              serialized_command->size());
8556   return TPM_RC_SUCCESS;
8557 }
8558 
ParseResponse_SelfTest(const std::string & response,AuthorizationDelegate * authorization_delegate)8559 TPM_RC Tpm::ParseResponse_SelfTest(
8560     const std::string& response,
8561     AuthorizationDelegate* authorization_delegate) {
8562   VLOG(3) << __func__;
8563   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8564   TPM_RC rc = TPM_RC_SUCCESS;
8565   std::string buffer(response);
8566   TPM_ST tag;
8567   std::string tag_bytes;
8568   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8569   if (rc != TPM_RC_SUCCESS) {
8570     return rc;
8571   }
8572   UINT32 response_size;
8573   std::string response_size_bytes;
8574   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8575   if (rc != TPM_RC_SUCCESS) {
8576     return rc;
8577   }
8578   TPM_RC response_code;
8579   std::string response_code_bytes;
8580   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8581   if (rc != TPM_RC_SUCCESS) {
8582     return rc;
8583   }
8584   if (response_size != response.size()) {
8585     return TPM_RC_SIZE;
8586   }
8587   if (response_code != TPM_RC_SUCCESS) {
8588     return response_code;
8589   }
8590   TPM_CC command_code = TPM_CC_SelfTest;
8591   std::string command_code_bytes;
8592   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8593   if (rc != TPM_RC_SUCCESS) {
8594     return rc;
8595   }
8596   std::string authorization_section_bytes;
8597   if (tag == TPM_ST_SESSIONS) {
8598     UINT32 parameter_section_size = buffer.size();
8599     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8600     if (rc != TPM_RC_SUCCESS) {
8601       return rc;
8602     }
8603     if (parameter_section_size > buffer.size()) {
8604       return TPM_RC_INSUFFICIENT;
8605     }
8606     authorization_section_bytes = buffer.substr(parameter_section_size);
8607     // Keep the parameter section in |buffer|.
8608     buffer.erase(parameter_section_size);
8609   }
8610   std::unique_ptr<crypto::SecureHash> hash(
8611       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8612   hash->Update(response_code_bytes.data(), response_code_bytes.size());
8613   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8614   hash->Update(buffer.data(), buffer.size());
8615   std::string response_hash(32, 0);
8616   hash->Finish(std::data(response_hash), response_hash.size());
8617   if (tag == TPM_ST_SESSIONS) {
8618     if (!authorization_delegate)
8619       return TRUNKS_RC_AUTHORIZATION_FAILED;
8620     if (!authorization_delegate->CheckResponseAuthorization(
8621             response_hash, authorization_section_bytes)) {
8622       return TRUNKS_RC_AUTHORIZATION_FAILED;
8623     }
8624   }
8625   return TPM_RC_SUCCESS;
8626 }
8627 
SelfTestErrorCallback(Tpm::SelfTestResponse callback,TPM_RC response_code)8628 void SelfTestErrorCallback(Tpm::SelfTestResponse callback,
8629                            TPM_RC response_code) {
8630   VLOG(1) << __func__;
8631   std::move(callback).Run(response_code);
8632 }
8633 
SelfTestResponseParser(Tpm::SelfTestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8634 void SelfTestResponseParser(Tpm::SelfTestResponse callback,
8635                             AuthorizationDelegate* authorization_delegate,
8636                             const std::string& response) {
8637   VLOG(1) << __func__;
8638   TPM_RC rc = Tpm::ParseResponse_SelfTest(response, authorization_delegate);
8639   if (rc != TPM_RC_SUCCESS) {
8640     base::OnceCallback<void(TPM_RC)> error_reporter =
8641         base::BindOnce(SelfTestErrorCallback, std::move(callback));
8642     std::move(error_reporter).Run(rc);
8643     return;
8644   }
8645   std::move(callback).Run(rc);
8646 }
8647 
SelfTest(const TPMI_YES_NO & full_test,AuthorizationDelegate * authorization_delegate,SelfTestResponse callback)8648 void Tpm::SelfTest(const TPMI_YES_NO& full_test,
8649                    AuthorizationDelegate* authorization_delegate,
8650                    SelfTestResponse callback) {
8651   VLOG(1) << __func__;
8652   std::string command;
8653   TPM_RC rc =
8654       SerializeCommand_SelfTest(full_test, &command, authorization_delegate);
8655   if (rc != TPM_RC_SUCCESS) {
8656     base::OnceCallback<void(TPM_RC)> error_reporter =
8657         base::BindOnce(SelfTestErrorCallback, std::move(callback));
8658     std::move(error_reporter).Run(rc);
8659     return;
8660   }
8661   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
8662       SelfTestResponseParser, std::move(callback), authorization_delegate);
8663   transceiver_->SendCommand(command, std::move(parser));
8664 }
8665 
SelfTestSync(const TPMI_YES_NO & full_test,AuthorizationDelegate * authorization_delegate)8666 TPM_RC Tpm::SelfTestSync(const TPMI_YES_NO& full_test,
8667                          AuthorizationDelegate* authorization_delegate) {
8668   VLOG(1) << __func__;
8669   std::string command;
8670   TPM_RC rc =
8671       SerializeCommand_SelfTest(full_test, &command, authorization_delegate);
8672   if (rc != TPM_RC_SUCCESS) {
8673     return rc;
8674   }
8675   std::string response = transceiver_->SendCommandAndWait(command);
8676   rc = ParseResponse_SelfTest(response, authorization_delegate);
8677   return rc;
8678 }
8679 
SerializeCommand_IncrementalSelfTest(const TPML_ALG & to_test,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8680 TPM_RC Tpm::SerializeCommand_IncrementalSelfTest(
8681     const TPML_ALG& to_test,
8682     std::string* serialized_command,
8683     AuthorizationDelegate* authorization_delegate) {
8684   VLOG(3) << __func__;
8685   TPM_RC rc = TPM_RC_SUCCESS;
8686   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8687   UINT32 command_size = 10;  // Header size.
8688   std::string handle_section_bytes;
8689   std::string parameter_section_bytes;
8690   TPM_CC command_code = TPM_CC_IncrementalSelfTest;
8691   bool is_command_parameter_encryption_possible = false;
8692   bool is_response_parameter_encryption_possible = false;
8693   std::string command_code_bytes;
8694   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8695   if (rc != TPM_RC_SUCCESS) {
8696     return rc;
8697   }
8698   std::string to_test_bytes;
8699   rc = Serialize_TPML_ALG(to_test, &to_test_bytes);
8700   if (rc != TPM_RC_SUCCESS) {
8701     return rc;
8702   }
8703   std::unique_ptr<crypto::SecureHash> hash(
8704       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8705   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8706   hash->Update(to_test_bytes.data(), to_test_bytes.size());
8707   parameter_section_bytes += to_test_bytes;
8708   command_size += to_test_bytes.size();
8709   std::string command_hash(32, 0);
8710   hash->Finish(std::data(command_hash), command_hash.size());
8711   std::string authorization_section_bytes;
8712   std::string authorization_size_bytes;
8713   if (authorization_delegate) {
8714     if (!authorization_delegate->GetCommandAuthorization(
8715             command_hash, is_command_parameter_encryption_possible,
8716             is_response_parameter_encryption_possible,
8717             &authorization_section_bytes)) {
8718       return TRUNKS_RC_AUTHORIZATION_FAILED;
8719     }
8720     if (!authorization_section_bytes.empty()) {
8721       tag = TPM_ST_SESSIONS;
8722       std::string tmp;
8723       rc = Serialize_UINT32(authorization_section_bytes.size(),
8724                             &authorization_size_bytes);
8725       if (rc != TPM_RC_SUCCESS) {
8726         return rc;
8727       }
8728       command_size +=
8729           authorization_size_bytes.size() + authorization_section_bytes.size();
8730     }
8731   }
8732   std::string tag_bytes;
8733   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8734   if (rc != TPM_RC_SUCCESS) {
8735     return rc;
8736   }
8737   std::string command_size_bytes;
8738   rc = Serialize_UINT32(command_size, &command_size_bytes);
8739   if (rc != TPM_RC_SUCCESS) {
8740     return rc;
8741   }
8742   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8743                         handle_section_bytes + authorization_size_bytes +
8744                         authorization_section_bytes + parameter_section_bytes;
8745   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8746   VLOG(2) << "Command: "
8747           << base::HexEncode(serialized_command->data(),
8748                              serialized_command->size());
8749   return TPM_RC_SUCCESS;
8750 }
8751 
ParseResponse_IncrementalSelfTest(const std::string & response,TPML_ALG * to_do_list,AuthorizationDelegate * authorization_delegate)8752 TPM_RC Tpm::ParseResponse_IncrementalSelfTest(
8753     const std::string& response,
8754     TPML_ALG* to_do_list,
8755     AuthorizationDelegate* authorization_delegate) {
8756   VLOG(3) << __func__;
8757   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8758   TPM_RC rc = TPM_RC_SUCCESS;
8759   std::string buffer(response);
8760   TPM_ST tag;
8761   std::string tag_bytes;
8762   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8763   if (rc != TPM_RC_SUCCESS) {
8764     return rc;
8765   }
8766   UINT32 response_size;
8767   std::string response_size_bytes;
8768   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8769   if (rc != TPM_RC_SUCCESS) {
8770     return rc;
8771   }
8772   TPM_RC response_code;
8773   std::string response_code_bytes;
8774   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8775   if (rc != TPM_RC_SUCCESS) {
8776     return rc;
8777   }
8778   if (response_size != response.size()) {
8779     return TPM_RC_SIZE;
8780   }
8781   if (response_code != TPM_RC_SUCCESS) {
8782     return response_code;
8783   }
8784   TPM_CC command_code = TPM_CC_IncrementalSelfTest;
8785   std::string command_code_bytes;
8786   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8787   if (rc != TPM_RC_SUCCESS) {
8788     return rc;
8789   }
8790   std::string authorization_section_bytes;
8791   if (tag == TPM_ST_SESSIONS) {
8792     UINT32 parameter_section_size = buffer.size();
8793     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8794     if (rc != TPM_RC_SUCCESS) {
8795       return rc;
8796     }
8797     if (parameter_section_size > buffer.size()) {
8798       return TPM_RC_INSUFFICIENT;
8799     }
8800     authorization_section_bytes = buffer.substr(parameter_section_size);
8801     // Keep the parameter section in |buffer|.
8802     buffer.erase(parameter_section_size);
8803   }
8804   std::unique_ptr<crypto::SecureHash> hash(
8805       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8806   hash->Update(response_code_bytes.data(), response_code_bytes.size());
8807   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8808   hash->Update(buffer.data(), buffer.size());
8809   std::string response_hash(32, 0);
8810   hash->Finish(std::data(response_hash), response_hash.size());
8811   if (tag == TPM_ST_SESSIONS) {
8812     if (!authorization_delegate)
8813       return TRUNKS_RC_AUTHORIZATION_FAILED;
8814     if (!authorization_delegate->CheckResponseAuthorization(
8815             response_hash, authorization_section_bytes)) {
8816       return TRUNKS_RC_AUTHORIZATION_FAILED;
8817     }
8818   }
8819   std::string to_do_list_bytes;
8820   rc = Parse_TPML_ALG(&buffer, to_do_list, &to_do_list_bytes);
8821   if (rc != TPM_RC_SUCCESS) {
8822     return rc;
8823   }
8824   return TPM_RC_SUCCESS;
8825 }
8826 
IncrementalSelfTestErrorCallback(Tpm::IncrementalSelfTestResponse callback,TPM_RC response_code)8827 void IncrementalSelfTestErrorCallback(Tpm::IncrementalSelfTestResponse callback,
8828                                       TPM_RC response_code) {
8829   VLOG(1) << __func__;
8830   std::move(callback).Run(response_code, TPML_ALG());
8831 }
8832 
IncrementalSelfTestResponseParser(Tpm::IncrementalSelfTestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)8833 void IncrementalSelfTestResponseParser(
8834     Tpm::IncrementalSelfTestResponse callback,
8835     AuthorizationDelegate* authorization_delegate,
8836     const std::string& response) {
8837   VLOG(1) << __func__;
8838   TPML_ALG to_do_list;
8839   TPM_RC rc = Tpm::ParseResponse_IncrementalSelfTest(response, &to_do_list,
8840                                                      authorization_delegate);
8841   if (rc != TPM_RC_SUCCESS) {
8842     base::OnceCallback<void(TPM_RC)> error_reporter =
8843         base::BindOnce(IncrementalSelfTestErrorCallback, std::move(callback));
8844     std::move(error_reporter).Run(rc);
8845     return;
8846   }
8847   std::move(callback).Run(rc, to_do_list);
8848 }
8849 
IncrementalSelfTest(const TPML_ALG & to_test,AuthorizationDelegate * authorization_delegate,IncrementalSelfTestResponse callback)8850 void Tpm::IncrementalSelfTest(const TPML_ALG& to_test,
8851                               AuthorizationDelegate* authorization_delegate,
8852                               IncrementalSelfTestResponse callback) {
8853   VLOG(1) << __func__;
8854   std::string command;
8855   TPM_RC rc = SerializeCommand_IncrementalSelfTest(to_test, &command,
8856                                                    authorization_delegate);
8857   if (rc != TPM_RC_SUCCESS) {
8858     base::OnceCallback<void(TPM_RC)> error_reporter =
8859         base::BindOnce(IncrementalSelfTestErrorCallback, std::move(callback));
8860     std::move(error_reporter).Run(rc);
8861     return;
8862   }
8863   base::OnceCallback<void(const std::string&)> parser =
8864       base::BindOnce(IncrementalSelfTestResponseParser, std::move(callback),
8865                      authorization_delegate);
8866   transceiver_->SendCommand(command, std::move(parser));
8867 }
8868 
IncrementalSelfTestSync(const TPML_ALG & to_test,TPML_ALG * to_do_list,AuthorizationDelegate * authorization_delegate)8869 TPM_RC Tpm::IncrementalSelfTestSync(
8870     const TPML_ALG& to_test,
8871     TPML_ALG* to_do_list,
8872     AuthorizationDelegate* authorization_delegate) {
8873   VLOG(1) << __func__;
8874   std::string command;
8875   TPM_RC rc = SerializeCommand_IncrementalSelfTest(to_test, &command,
8876                                                    authorization_delegate);
8877   if (rc != TPM_RC_SUCCESS) {
8878     return rc;
8879   }
8880   std::string response = transceiver_->SendCommandAndWait(command);
8881   rc = ParseResponse_IncrementalSelfTest(response, to_do_list,
8882                                          authorization_delegate);
8883   return rc;
8884 }
8885 
SerializeCommand_GetTestResult(std::string * serialized_command,AuthorizationDelegate * authorization_delegate)8886 TPM_RC Tpm::SerializeCommand_GetTestResult(
8887     std::string* serialized_command,
8888     AuthorizationDelegate* authorization_delegate) {
8889   VLOG(3) << __func__;
8890   TPM_RC rc = TPM_RC_SUCCESS;
8891   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
8892   UINT32 command_size = 10;  // Header size.
8893   std::string handle_section_bytes;
8894   std::string parameter_section_bytes;
8895   TPM_CC command_code = TPM_CC_GetTestResult;
8896   bool is_command_parameter_encryption_possible = false;
8897   bool is_response_parameter_encryption_possible = true;
8898   std::string command_code_bytes;
8899   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8900   if (rc != TPM_RC_SUCCESS) {
8901     return rc;
8902   }
8903   std::unique_ptr<crypto::SecureHash> hash(
8904       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
8905   hash->Update(command_code_bytes.data(), command_code_bytes.size());
8906   std::string command_hash(32, 0);
8907   hash->Finish(std::data(command_hash), command_hash.size());
8908   std::string authorization_section_bytes;
8909   std::string authorization_size_bytes;
8910   if (authorization_delegate) {
8911     if (!authorization_delegate->GetCommandAuthorization(
8912             command_hash, is_command_parameter_encryption_possible,
8913             is_response_parameter_encryption_possible,
8914             &authorization_section_bytes)) {
8915       return TRUNKS_RC_AUTHORIZATION_FAILED;
8916     }
8917     if (!authorization_section_bytes.empty()) {
8918       tag = TPM_ST_SESSIONS;
8919       std::string tmp;
8920       rc = Serialize_UINT32(authorization_section_bytes.size(),
8921                             &authorization_size_bytes);
8922       if (rc != TPM_RC_SUCCESS) {
8923         return rc;
8924       }
8925       command_size +=
8926           authorization_size_bytes.size() + authorization_section_bytes.size();
8927     }
8928   }
8929   std::string tag_bytes;
8930   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
8931   if (rc != TPM_RC_SUCCESS) {
8932     return rc;
8933   }
8934   std::string command_size_bytes;
8935   rc = Serialize_UINT32(command_size, &command_size_bytes);
8936   if (rc != TPM_RC_SUCCESS) {
8937     return rc;
8938   }
8939   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
8940                         handle_section_bytes + authorization_size_bytes +
8941                         authorization_section_bytes + parameter_section_bytes;
8942   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
8943   VLOG(2) << "Command: "
8944           << base::HexEncode(serialized_command->data(),
8945                              serialized_command->size());
8946   return TPM_RC_SUCCESS;
8947 }
8948 
ParseResponse_GetTestResult(const std::string & response,TPM2B_MAX_BUFFER * out_data,TPM_RC * test_result,AuthorizationDelegate * authorization_delegate)8949 TPM_RC Tpm::ParseResponse_GetTestResult(
8950     const std::string& response,
8951     TPM2B_MAX_BUFFER* out_data,
8952     TPM_RC* test_result,
8953     AuthorizationDelegate* authorization_delegate) {
8954   VLOG(3) << __func__;
8955   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
8956   TPM_RC rc = TPM_RC_SUCCESS;
8957   std::string buffer(response);
8958   TPM_ST tag;
8959   std::string tag_bytes;
8960   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
8961   if (rc != TPM_RC_SUCCESS) {
8962     return rc;
8963   }
8964   UINT32 response_size;
8965   std::string response_size_bytes;
8966   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
8967   if (rc != TPM_RC_SUCCESS) {
8968     return rc;
8969   }
8970   TPM_RC response_code;
8971   std::string response_code_bytes;
8972   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
8973   if (rc != TPM_RC_SUCCESS) {
8974     return rc;
8975   }
8976   if (response_size != response.size()) {
8977     return TPM_RC_SIZE;
8978   }
8979   if (response_code != TPM_RC_SUCCESS) {
8980     return response_code;
8981   }
8982   TPM_CC command_code = TPM_CC_GetTestResult;
8983   std::string command_code_bytes;
8984   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
8985   if (rc != TPM_RC_SUCCESS) {
8986     return rc;
8987   }
8988   std::string authorization_section_bytes;
8989   if (tag == TPM_ST_SESSIONS) {
8990     UINT32 parameter_section_size = buffer.size();
8991     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
8992     if (rc != TPM_RC_SUCCESS) {
8993       return rc;
8994     }
8995     if (parameter_section_size > buffer.size()) {
8996       return TPM_RC_INSUFFICIENT;
8997     }
8998     authorization_section_bytes = buffer.substr(parameter_section_size);
8999     // Keep the parameter section in |buffer|.
9000     buffer.erase(parameter_section_size);
9001   }
9002   std::unique_ptr<crypto::SecureHash> hash(
9003       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9004   hash->Update(response_code_bytes.data(), response_code_bytes.size());
9005   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9006   hash->Update(buffer.data(), buffer.size());
9007   std::string response_hash(32, 0);
9008   hash->Finish(std::data(response_hash), response_hash.size());
9009   if (tag == TPM_ST_SESSIONS) {
9010     if (!authorization_delegate)
9011       return TRUNKS_RC_AUTHORIZATION_FAILED;
9012     if (!authorization_delegate->CheckResponseAuthorization(
9013             response_hash, authorization_section_bytes)) {
9014       return TRUNKS_RC_AUTHORIZATION_FAILED;
9015     }
9016   }
9017   if (tag == TPM_ST_SESSIONS) {
9018     if (!authorization_delegate)
9019       return TRUNKS_RC_AUTHORIZATION_FAILED;
9020 
9021     // Parse the encrypted parameter size.
9022     UINT16 size;
9023     std::string size_buffer = buffer.substr(0, 2);
9024     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9025       return result;
9026     }
9027     if (buffer.size() < 2 + size) {
9028       return TPM_RC_INSUFFICIENT;
9029     }
9030 
9031     // Decrypt just the parameter data, not the size.
9032     std::string decrypted_data = buffer.substr(2, size);
9033     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9034       return TRUNKS_RC_ENCRYPTION_FAILED;
9035     }
9036     buffer.replace(2, size, decrypted_data);
9037   }
9038   std::string out_data_bytes;
9039   rc = Parse_TPM2B_MAX_BUFFER(&buffer, out_data, &out_data_bytes);
9040   if (rc != TPM_RC_SUCCESS) {
9041     return rc;
9042   }
9043   std::string test_result_bytes;
9044   rc = Parse_TPM_RC(&buffer, test_result, &test_result_bytes);
9045   if (rc != TPM_RC_SUCCESS) {
9046     return rc;
9047   }
9048   return TPM_RC_SUCCESS;
9049 }
9050 
GetTestResultErrorCallback(Tpm::GetTestResultResponse callback,TPM_RC response_code)9051 void GetTestResultErrorCallback(Tpm::GetTestResultResponse callback,
9052                                 TPM_RC response_code) {
9053   VLOG(1) << __func__;
9054   std::move(callback).Run(response_code, TPM2B_MAX_BUFFER(), TPM_RC());
9055 }
9056 
GetTestResultResponseParser(Tpm::GetTestResultResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9057 void GetTestResultResponseParser(Tpm::GetTestResultResponse callback,
9058                                  AuthorizationDelegate* authorization_delegate,
9059                                  const std::string& response) {
9060   VLOG(1) << __func__;
9061   TPM2B_MAX_BUFFER out_data;
9062   TPM_RC test_result;
9063   TPM_RC rc = Tpm::ParseResponse_GetTestResult(
9064       response, &out_data, &test_result, authorization_delegate);
9065   if (rc != TPM_RC_SUCCESS) {
9066     base::OnceCallback<void(TPM_RC)> error_reporter =
9067         base::BindOnce(GetTestResultErrorCallback, std::move(callback));
9068     std::move(error_reporter).Run(rc);
9069     return;
9070   }
9071   std::move(callback).Run(rc, out_data, test_result);
9072 }
9073 
GetTestResult(AuthorizationDelegate * authorization_delegate,GetTestResultResponse callback)9074 void Tpm::GetTestResult(AuthorizationDelegate* authorization_delegate,
9075                         GetTestResultResponse callback) {
9076   VLOG(1) << __func__;
9077   std::string command;
9078   TPM_RC rc = SerializeCommand_GetTestResult(&command, authorization_delegate);
9079   if (rc != TPM_RC_SUCCESS) {
9080     base::OnceCallback<void(TPM_RC)> error_reporter =
9081         base::BindOnce(GetTestResultErrorCallback, std::move(callback));
9082     std::move(error_reporter).Run(rc);
9083     return;
9084   }
9085   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9086       GetTestResultResponseParser, std::move(callback), authorization_delegate);
9087   transceiver_->SendCommand(command, std::move(parser));
9088 }
9089 
GetTestResultSync(TPM2B_MAX_BUFFER * out_data,TPM_RC * test_result,AuthorizationDelegate * authorization_delegate)9090 TPM_RC Tpm::GetTestResultSync(TPM2B_MAX_BUFFER* out_data,
9091                               TPM_RC* test_result,
9092                               AuthorizationDelegate* authorization_delegate) {
9093   VLOG(1) << __func__;
9094   std::string command;
9095   TPM_RC rc = SerializeCommand_GetTestResult(&command, authorization_delegate);
9096   if (rc != TPM_RC_SUCCESS) {
9097     return rc;
9098   }
9099   std::string response = transceiver_->SendCommandAndWait(command);
9100   rc = ParseResponse_GetTestResult(response, out_data, test_result,
9101                                    authorization_delegate);
9102   return rc;
9103 }
9104 
SerializeCommand_StartAuthSession(const TPMI_DH_OBJECT & tpm_key,const std::string & tpm_key_name,const TPMI_DH_ENTITY & bind,const std::string & bind_name,const TPM2B_NONCE & nonce_caller,const TPM2B_ENCRYPTED_SECRET & encrypted_salt,const TPM_SE & session_type,const TPMT_SYM_DEF & symmetric,const TPMI_ALG_HASH & auth_hash,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9105 TPM_RC Tpm::SerializeCommand_StartAuthSession(
9106     const TPMI_DH_OBJECT& tpm_key,
9107     const std::string& tpm_key_name,
9108     const TPMI_DH_ENTITY& bind,
9109     const std::string& bind_name,
9110     const TPM2B_NONCE& nonce_caller,
9111     const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9112     const TPM_SE& session_type,
9113     const TPMT_SYM_DEF& symmetric,
9114     const TPMI_ALG_HASH& auth_hash,
9115     std::string* serialized_command,
9116     AuthorizationDelegate* authorization_delegate) {
9117   VLOG(3) << __func__;
9118   TPM_RC rc = TPM_RC_SUCCESS;
9119   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9120   UINT32 command_size = 10;  // Header size.
9121   std::string handle_section_bytes;
9122   std::string parameter_section_bytes;
9123   TPM_CC command_code = TPM_CC_StartAuthSession;
9124   bool is_command_parameter_encryption_possible = true;
9125   bool is_response_parameter_encryption_possible = true;
9126   std::string command_code_bytes;
9127   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9128   if (rc != TPM_RC_SUCCESS) {
9129     return rc;
9130   }
9131   std::string tpm_key_bytes;
9132   rc = Serialize_TPMI_DH_OBJECT(tpm_key, &tpm_key_bytes);
9133   if (rc != TPM_RC_SUCCESS) {
9134     return rc;
9135   }
9136   std::string bind_bytes;
9137   rc = Serialize_TPMI_DH_ENTITY(bind, &bind_bytes);
9138   if (rc != TPM_RC_SUCCESS) {
9139     return rc;
9140   }
9141   std::string nonce_caller_bytes;
9142   rc = Serialize_TPM2B_NONCE(nonce_caller, &nonce_caller_bytes);
9143   if (rc != TPM_RC_SUCCESS) {
9144     return rc;
9145   }
9146   std::string encrypted_salt_bytes;
9147   rc = Serialize_TPM2B_ENCRYPTED_SECRET(encrypted_salt, &encrypted_salt_bytes);
9148   if (rc != TPM_RC_SUCCESS) {
9149     return rc;
9150   }
9151   std::string session_type_bytes;
9152   rc = Serialize_TPM_SE(session_type, &session_type_bytes);
9153   if (rc != TPM_RC_SUCCESS) {
9154     return rc;
9155   }
9156   std::string symmetric_bytes;
9157   rc = Serialize_TPMT_SYM_DEF(symmetric, &symmetric_bytes);
9158   if (rc != TPM_RC_SUCCESS) {
9159     return rc;
9160   }
9161   std::string auth_hash_bytes;
9162   rc = Serialize_TPMI_ALG_HASH(auth_hash, &auth_hash_bytes);
9163   if (rc != TPM_RC_SUCCESS) {
9164     return rc;
9165   }
9166   if (authorization_delegate) {
9167     // Encrypt just the parameter data, not the size.
9168     std::string tmp = nonce_caller_bytes.substr(2);
9169     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9170       return TRUNKS_RC_ENCRYPTION_FAILED;
9171     }
9172     nonce_caller_bytes.replace(2, std::string::npos, tmp);
9173   }
9174   std::unique_ptr<crypto::SecureHash> hash(
9175       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9176   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9177   hash->Update(tpm_key_name.data(), tpm_key_name.size());
9178   handle_section_bytes += tpm_key_bytes;
9179   command_size += tpm_key_bytes.size();
9180   hash->Update(bind_name.data(), bind_name.size());
9181   handle_section_bytes += bind_bytes;
9182   command_size += bind_bytes.size();
9183   hash->Update(nonce_caller_bytes.data(), nonce_caller_bytes.size());
9184   parameter_section_bytes += nonce_caller_bytes;
9185   command_size += nonce_caller_bytes.size();
9186   hash->Update(encrypted_salt_bytes.data(), encrypted_salt_bytes.size());
9187   parameter_section_bytes += encrypted_salt_bytes;
9188   command_size += encrypted_salt_bytes.size();
9189   hash->Update(session_type_bytes.data(), session_type_bytes.size());
9190   parameter_section_bytes += session_type_bytes;
9191   command_size += session_type_bytes.size();
9192   hash->Update(symmetric_bytes.data(), symmetric_bytes.size());
9193   parameter_section_bytes += symmetric_bytes;
9194   command_size += symmetric_bytes.size();
9195   hash->Update(auth_hash_bytes.data(), auth_hash_bytes.size());
9196   parameter_section_bytes += auth_hash_bytes;
9197   command_size += auth_hash_bytes.size();
9198   std::string command_hash(32, 0);
9199   hash->Finish(std::data(command_hash), command_hash.size());
9200   std::string authorization_section_bytes;
9201   std::string authorization_size_bytes;
9202   if (authorization_delegate) {
9203     if (!authorization_delegate->GetCommandAuthorization(
9204             command_hash, is_command_parameter_encryption_possible,
9205             is_response_parameter_encryption_possible,
9206             &authorization_section_bytes)) {
9207       return TRUNKS_RC_AUTHORIZATION_FAILED;
9208     }
9209     if (!authorization_section_bytes.empty()) {
9210       tag = TPM_ST_SESSIONS;
9211       std::string tmp;
9212       rc = Serialize_UINT32(authorization_section_bytes.size(),
9213                             &authorization_size_bytes);
9214       if (rc != TPM_RC_SUCCESS) {
9215         return rc;
9216       }
9217       command_size +=
9218           authorization_size_bytes.size() + authorization_section_bytes.size();
9219     }
9220   }
9221   std::string tag_bytes;
9222   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9223   if (rc != TPM_RC_SUCCESS) {
9224     return rc;
9225   }
9226   std::string command_size_bytes;
9227   rc = Serialize_UINT32(command_size, &command_size_bytes);
9228   if (rc != TPM_RC_SUCCESS) {
9229     return rc;
9230   }
9231   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9232                         handle_section_bytes + authorization_size_bytes +
9233                         authorization_section_bytes + parameter_section_bytes;
9234   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9235   VLOG(2) << "Command: "
9236           << base::HexEncode(serialized_command->data(),
9237                              serialized_command->size());
9238   return TPM_RC_SUCCESS;
9239 }
9240 
ParseResponse_StartAuthSession(const std::string & response,TPMI_SH_AUTH_SESSION * session_handle,TPM2B_NONCE * nonce_tpm,AuthorizationDelegate * authorization_delegate)9241 TPM_RC Tpm::ParseResponse_StartAuthSession(
9242     const std::string& response,
9243     TPMI_SH_AUTH_SESSION* session_handle,
9244     TPM2B_NONCE* nonce_tpm,
9245     AuthorizationDelegate* authorization_delegate) {
9246   VLOG(3) << __func__;
9247   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9248   TPM_RC rc = TPM_RC_SUCCESS;
9249   std::string buffer(response);
9250   TPM_ST tag;
9251   std::string tag_bytes;
9252   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9253   if (rc != TPM_RC_SUCCESS) {
9254     return rc;
9255   }
9256   UINT32 response_size;
9257   std::string response_size_bytes;
9258   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9259   if (rc != TPM_RC_SUCCESS) {
9260     return rc;
9261   }
9262   TPM_RC response_code;
9263   std::string response_code_bytes;
9264   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9265   if (rc != TPM_RC_SUCCESS) {
9266     return rc;
9267   }
9268   if (response_size != response.size()) {
9269     return TPM_RC_SIZE;
9270   }
9271   if (response_code != TPM_RC_SUCCESS) {
9272     return response_code;
9273   }
9274   std::string session_handle_bytes;
9275   rc = Parse_TPMI_SH_AUTH_SESSION(&buffer, session_handle,
9276                                   &session_handle_bytes);
9277   if (rc != TPM_RC_SUCCESS) {
9278     return rc;
9279   }
9280   TPM_CC command_code = TPM_CC_StartAuthSession;
9281   std::string command_code_bytes;
9282   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9283   if (rc != TPM_RC_SUCCESS) {
9284     return rc;
9285   }
9286   std::string authorization_section_bytes;
9287   if (tag == TPM_ST_SESSIONS) {
9288     UINT32 parameter_section_size = buffer.size();
9289     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
9290     if (rc != TPM_RC_SUCCESS) {
9291       return rc;
9292     }
9293     if (parameter_section_size > buffer.size()) {
9294       return TPM_RC_INSUFFICIENT;
9295     }
9296     authorization_section_bytes = buffer.substr(parameter_section_size);
9297     // Keep the parameter section in |buffer|.
9298     buffer.erase(parameter_section_size);
9299   }
9300   std::unique_ptr<crypto::SecureHash> hash(
9301       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9302   hash->Update(response_code_bytes.data(), response_code_bytes.size());
9303   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9304   hash->Update(buffer.data(), buffer.size());
9305   std::string response_hash(32, 0);
9306   hash->Finish(std::data(response_hash), response_hash.size());
9307   if (tag == TPM_ST_SESSIONS) {
9308     if (!authorization_delegate)
9309       return TRUNKS_RC_AUTHORIZATION_FAILED;
9310     if (!authorization_delegate->CheckResponseAuthorization(
9311             response_hash, authorization_section_bytes)) {
9312       return TRUNKS_RC_AUTHORIZATION_FAILED;
9313     }
9314   }
9315   if (tag == TPM_ST_SESSIONS) {
9316     if (!authorization_delegate)
9317       return TRUNKS_RC_AUTHORIZATION_FAILED;
9318 
9319     // Parse the encrypted parameter size.
9320     UINT16 size;
9321     std::string size_buffer = buffer.substr(0, 2);
9322     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9323       return result;
9324     }
9325     if (buffer.size() < 2 + size) {
9326       return TPM_RC_INSUFFICIENT;
9327     }
9328 
9329     // Decrypt just the parameter data, not the size.
9330     std::string decrypted_data = buffer.substr(2, size);
9331     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9332       return TRUNKS_RC_ENCRYPTION_FAILED;
9333     }
9334     buffer.replace(2, size, decrypted_data);
9335   }
9336   std::string nonce_tpm_bytes;
9337   rc = Parse_TPM2B_NONCE(&buffer, nonce_tpm, &nonce_tpm_bytes);
9338   if (rc != TPM_RC_SUCCESS) {
9339     return rc;
9340   }
9341   return TPM_RC_SUCCESS;
9342 }
9343 
StartAuthSessionErrorCallback(Tpm::StartAuthSessionResponse callback,TPM_RC response_code)9344 void StartAuthSessionErrorCallback(Tpm::StartAuthSessionResponse callback,
9345                                    TPM_RC response_code) {
9346   VLOG(1) << __func__;
9347   std::move(callback).Run(response_code, TPMI_SH_AUTH_SESSION(), TPM2B_NONCE());
9348 }
9349 
StartAuthSessionResponseParser(Tpm::StartAuthSessionResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9350 void StartAuthSessionResponseParser(
9351     Tpm::StartAuthSessionResponse callback,
9352     AuthorizationDelegate* authorization_delegate,
9353     const std::string& response) {
9354   VLOG(1) << __func__;
9355   TPMI_SH_AUTH_SESSION session_handle;
9356   TPM2B_NONCE nonce_tpm;
9357   TPM_RC rc = Tpm::ParseResponse_StartAuthSession(
9358       response, &session_handle, &nonce_tpm, authorization_delegate);
9359   if (rc != TPM_RC_SUCCESS) {
9360     base::OnceCallback<void(TPM_RC)> error_reporter =
9361         base::BindOnce(StartAuthSessionErrorCallback, std::move(callback));
9362     std::move(error_reporter).Run(rc);
9363     return;
9364   }
9365   std::move(callback).Run(rc, session_handle, nonce_tpm);
9366 }
9367 
StartAuthSession(const TPMI_DH_OBJECT & tpm_key,const std::string & tpm_key_name,const TPMI_DH_ENTITY & bind,const std::string & bind_name,const TPM2B_NONCE & nonce_caller,const TPM2B_ENCRYPTED_SECRET & encrypted_salt,const TPM_SE & session_type,const TPMT_SYM_DEF & symmetric,const TPMI_ALG_HASH & auth_hash,AuthorizationDelegate * authorization_delegate,StartAuthSessionResponse callback)9368 void Tpm::StartAuthSession(const TPMI_DH_OBJECT& tpm_key,
9369                            const std::string& tpm_key_name,
9370                            const TPMI_DH_ENTITY& bind,
9371                            const std::string& bind_name,
9372                            const TPM2B_NONCE& nonce_caller,
9373                            const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9374                            const TPM_SE& session_type,
9375                            const TPMT_SYM_DEF& symmetric,
9376                            const TPMI_ALG_HASH& auth_hash,
9377                            AuthorizationDelegate* authorization_delegate,
9378                            StartAuthSessionResponse callback) {
9379   VLOG(1) << __func__;
9380   std::string command;
9381   TPM_RC rc = SerializeCommand_StartAuthSession(
9382       tpm_key, tpm_key_name, bind, bind_name, nonce_caller, encrypted_salt,
9383       session_type, symmetric, auth_hash, &command, authorization_delegate);
9384   if (rc != TPM_RC_SUCCESS) {
9385     base::OnceCallback<void(TPM_RC)> error_reporter =
9386         base::BindOnce(StartAuthSessionErrorCallback, std::move(callback));
9387     std::move(error_reporter).Run(rc);
9388     return;
9389   }
9390   base::OnceCallback<void(const std::string&)> parser =
9391       base::BindOnce(StartAuthSessionResponseParser, std::move(callback),
9392                      authorization_delegate);
9393   transceiver_->SendCommand(command, std::move(parser));
9394 }
9395 
StartAuthSessionSync(const TPMI_DH_OBJECT & tpm_key,const std::string & tpm_key_name,const TPMI_DH_ENTITY & bind,const std::string & bind_name,const TPM2B_NONCE & nonce_caller,const TPM2B_ENCRYPTED_SECRET & encrypted_salt,const TPM_SE & session_type,const TPMT_SYM_DEF & symmetric,const TPMI_ALG_HASH & auth_hash,TPMI_SH_AUTH_SESSION * session_handle,TPM2B_NONCE * nonce_tpm,AuthorizationDelegate * authorization_delegate)9396 TPM_RC Tpm::StartAuthSessionSync(
9397     const TPMI_DH_OBJECT& tpm_key,
9398     const std::string& tpm_key_name,
9399     const TPMI_DH_ENTITY& bind,
9400     const std::string& bind_name,
9401     const TPM2B_NONCE& nonce_caller,
9402     const TPM2B_ENCRYPTED_SECRET& encrypted_salt,
9403     const TPM_SE& session_type,
9404     const TPMT_SYM_DEF& symmetric,
9405     const TPMI_ALG_HASH& auth_hash,
9406     TPMI_SH_AUTH_SESSION* session_handle,
9407     TPM2B_NONCE* nonce_tpm,
9408     AuthorizationDelegate* authorization_delegate) {
9409   VLOG(1) << __func__;
9410   std::string command;
9411   TPM_RC rc = SerializeCommand_StartAuthSession(
9412       tpm_key, tpm_key_name, bind, bind_name, nonce_caller, encrypted_salt,
9413       session_type, symmetric, auth_hash, &command, authorization_delegate);
9414   if (rc != TPM_RC_SUCCESS) {
9415     return rc;
9416   }
9417   std::string response = transceiver_->SendCommandAndWait(command);
9418   rc = ParseResponse_StartAuthSession(response, session_handle, nonce_tpm,
9419                                       authorization_delegate);
9420   return rc;
9421 }
9422 
SerializeCommand_PolicyRestart(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9423 TPM_RC Tpm::SerializeCommand_PolicyRestart(
9424     const TPMI_SH_POLICY& session_handle,
9425     const std::string& session_handle_name,
9426     std::string* serialized_command,
9427     AuthorizationDelegate* authorization_delegate) {
9428   VLOG(3) << __func__;
9429   TPM_RC rc = TPM_RC_SUCCESS;
9430   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9431   UINT32 command_size = 10;  // Header size.
9432   std::string handle_section_bytes;
9433   std::string parameter_section_bytes;
9434   TPM_CC command_code = TPM_CC_PolicyRestart;
9435   bool is_command_parameter_encryption_possible = false;
9436   bool is_response_parameter_encryption_possible = false;
9437   std::string command_code_bytes;
9438   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9439   if (rc != TPM_RC_SUCCESS) {
9440     return rc;
9441   }
9442   std::string session_handle_bytes;
9443   rc = Serialize_TPMI_SH_POLICY(session_handle, &session_handle_bytes);
9444   if (rc != TPM_RC_SUCCESS) {
9445     return rc;
9446   }
9447   std::unique_ptr<crypto::SecureHash> hash(
9448       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9449   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9450   hash->Update(session_handle_name.data(), session_handle_name.size());
9451   handle_section_bytes += session_handle_bytes;
9452   command_size += session_handle_bytes.size();
9453   std::string command_hash(32, 0);
9454   hash->Finish(std::data(command_hash), command_hash.size());
9455   std::string authorization_section_bytes;
9456   std::string authorization_size_bytes;
9457   if (authorization_delegate) {
9458     if (!authorization_delegate->GetCommandAuthorization(
9459             command_hash, is_command_parameter_encryption_possible,
9460             is_response_parameter_encryption_possible,
9461             &authorization_section_bytes)) {
9462       return TRUNKS_RC_AUTHORIZATION_FAILED;
9463     }
9464     if (!authorization_section_bytes.empty()) {
9465       tag = TPM_ST_SESSIONS;
9466       std::string tmp;
9467       rc = Serialize_UINT32(authorization_section_bytes.size(),
9468                             &authorization_size_bytes);
9469       if (rc != TPM_RC_SUCCESS) {
9470         return rc;
9471       }
9472       command_size +=
9473           authorization_size_bytes.size() + authorization_section_bytes.size();
9474     }
9475   }
9476   std::string tag_bytes;
9477   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9478   if (rc != TPM_RC_SUCCESS) {
9479     return rc;
9480   }
9481   std::string command_size_bytes;
9482   rc = Serialize_UINT32(command_size, &command_size_bytes);
9483   if (rc != TPM_RC_SUCCESS) {
9484     return rc;
9485   }
9486   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9487                         handle_section_bytes + authorization_size_bytes +
9488                         authorization_section_bytes + parameter_section_bytes;
9489   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9490   VLOG(2) << "Command: "
9491           << base::HexEncode(serialized_command->data(),
9492                              serialized_command->size());
9493   return TPM_RC_SUCCESS;
9494 }
9495 
ParseResponse_PolicyRestart(const std::string & response,AuthorizationDelegate * authorization_delegate)9496 TPM_RC Tpm::ParseResponse_PolicyRestart(
9497     const std::string& response,
9498     AuthorizationDelegate* authorization_delegate) {
9499   VLOG(3) << __func__;
9500   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9501   TPM_RC rc = TPM_RC_SUCCESS;
9502   std::string buffer(response);
9503   TPM_ST tag;
9504   std::string tag_bytes;
9505   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9506   if (rc != TPM_RC_SUCCESS) {
9507     return rc;
9508   }
9509   UINT32 response_size;
9510   std::string response_size_bytes;
9511   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9512   if (rc != TPM_RC_SUCCESS) {
9513     return rc;
9514   }
9515   TPM_RC response_code;
9516   std::string response_code_bytes;
9517   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9518   if (rc != TPM_RC_SUCCESS) {
9519     return rc;
9520   }
9521   if (response_size != response.size()) {
9522     return TPM_RC_SIZE;
9523   }
9524   if (response_code != TPM_RC_SUCCESS) {
9525     return response_code;
9526   }
9527   TPM_CC command_code = TPM_CC_PolicyRestart;
9528   std::string command_code_bytes;
9529   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9530   if (rc != TPM_RC_SUCCESS) {
9531     return rc;
9532   }
9533   std::string authorization_section_bytes;
9534   if (tag == TPM_ST_SESSIONS) {
9535     UINT32 parameter_section_size = buffer.size();
9536     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
9537     if (rc != TPM_RC_SUCCESS) {
9538       return rc;
9539     }
9540     if (parameter_section_size > buffer.size()) {
9541       return TPM_RC_INSUFFICIENT;
9542     }
9543     authorization_section_bytes = buffer.substr(parameter_section_size);
9544     // Keep the parameter section in |buffer|.
9545     buffer.erase(parameter_section_size);
9546   }
9547   std::unique_ptr<crypto::SecureHash> hash(
9548       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9549   hash->Update(response_code_bytes.data(), response_code_bytes.size());
9550   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9551   hash->Update(buffer.data(), buffer.size());
9552   std::string response_hash(32, 0);
9553   hash->Finish(std::data(response_hash), response_hash.size());
9554   if (tag == TPM_ST_SESSIONS) {
9555     if (!authorization_delegate)
9556       return TRUNKS_RC_AUTHORIZATION_FAILED;
9557     if (!authorization_delegate->CheckResponseAuthorization(
9558             response_hash, authorization_section_bytes)) {
9559       return TRUNKS_RC_AUTHORIZATION_FAILED;
9560     }
9561   }
9562   return TPM_RC_SUCCESS;
9563 }
9564 
PolicyRestartErrorCallback(Tpm::PolicyRestartResponse callback,TPM_RC response_code)9565 void PolicyRestartErrorCallback(Tpm::PolicyRestartResponse callback,
9566                                 TPM_RC response_code) {
9567   VLOG(1) << __func__;
9568   std::move(callback).Run(response_code);
9569 }
9570 
PolicyRestartResponseParser(Tpm::PolicyRestartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9571 void PolicyRestartResponseParser(Tpm::PolicyRestartResponse callback,
9572                                  AuthorizationDelegate* authorization_delegate,
9573                                  const std::string& response) {
9574   VLOG(1) << __func__;
9575   TPM_RC rc =
9576       Tpm::ParseResponse_PolicyRestart(response, authorization_delegate);
9577   if (rc != TPM_RC_SUCCESS) {
9578     base::OnceCallback<void(TPM_RC)> error_reporter =
9579         base::BindOnce(PolicyRestartErrorCallback, std::move(callback));
9580     std::move(error_reporter).Run(rc);
9581     return;
9582   }
9583   std::move(callback).Run(rc);
9584 }
9585 
PolicyRestart(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,AuthorizationDelegate * authorization_delegate,PolicyRestartResponse callback)9586 void Tpm::PolicyRestart(const TPMI_SH_POLICY& session_handle,
9587                         const std::string& session_handle_name,
9588                         AuthorizationDelegate* authorization_delegate,
9589                         PolicyRestartResponse callback) {
9590   VLOG(1) << __func__;
9591   std::string command;
9592   TPM_RC rc = SerializeCommand_PolicyRestart(
9593       session_handle, session_handle_name, &command, authorization_delegate);
9594   if (rc != TPM_RC_SUCCESS) {
9595     base::OnceCallback<void(TPM_RC)> error_reporter =
9596         base::BindOnce(PolicyRestartErrorCallback, std::move(callback));
9597     std::move(error_reporter).Run(rc);
9598     return;
9599   }
9600   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9601       PolicyRestartResponseParser, std::move(callback), authorization_delegate);
9602   transceiver_->SendCommand(command, std::move(parser));
9603 }
9604 
PolicyRestartSync(const TPMI_SH_POLICY & session_handle,const std::string & session_handle_name,AuthorizationDelegate * authorization_delegate)9605 TPM_RC Tpm::PolicyRestartSync(const TPMI_SH_POLICY& session_handle,
9606                               const std::string& session_handle_name,
9607                               AuthorizationDelegate* authorization_delegate) {
9608   VLOG(1) << __func__;
9609   std::string command;
9610   TPM_RC rc = SerializeCommand_PolicyRestart(
9611       session_handle, session_handle_name, &command, authorization_delegate);
9612   if (rc != TPM_RC_SUCCESS) {
9613     return rc;
9614   }
9615   std::string response = transceiver_->SendCommandAndWait(command);
9616   rc = ParseResponse_PolicyRestart(response, authorization_delegate);
9617   return rc;
9618 }
9619 
SerializeCommand_Create(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9620 TPM_RC Tpm::SerializeCommand_Create(
9621     const TPMI_DH_OBJECT& parent_handle,
9622     const std::string& parent_handle_name,
9623     const TPM2B_SENSITIVE_CREATE& in_sensitive,
9624     const TPM2B_PUBLIC& in_public,
9625     const TPM2B_DATA& outside_info,
9626     const TPML_PCR_SELECTION& creation_pcr,
9627     std::string* serialized_command,
9628     AuthorizationDelegate* authorization_delegate) {
9629   VLOG(3) << __func__;
9630   TPM_RC rc = TPM_RC_SUCCESS;
9631   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9632   UINT32 command_size = 10;  // Header size.
9633   std::string handle_section_bytes;
9634   std::string parameter_section_bytes;
9635   TPM_CC command_code = TPM_CC_Create;
9636   bool is_command_parameter_encryption_possible = true;
9637   bool is_response_parameter_encryption_possible = true;
9638   std::string command_code_bytes;
9639   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9640   if (rc != TPM_RC_SUCCESS) {
9641     return rc;
9642   }
9643   std::string parent_handle_bytes;
9644   rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
9645   if (rc != TPM_RC_SUCCESS) {
9646     return rc;
9647   }
9648   std::string in_sensitive_bytes;
9649   rc = Serialize_TPM2B_SENSITIVE_CREATE(in_sensitive, &in_sensitive_bytes);
9650   if (rc != TPM_RC_SUCCESS) {
9651     return rc;
9652   }
9653   std::string in_public_bytes;
9654   rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
9655   if (rc != TPM_RC_SUCCESS) {
9656     return rc;
9657   }
9658   std::string outside_info_bytes;
9659   rc = Serialize_TPM2B_DATA(outside_info, &outside_info_bytes);
9660   if (rc != TPM_RC_SUCCESS) {
9661     return rc;
9662   }
9663   std::string creation_pcr_bytes;
9664   rc = Serialize_TPML_PCR_SELECTION(creation_pcr, &creation_pcr_bytes);
9665   if (rc != TPM_RC_SUCCESS) {
9666     return rc;
9667   }
9668   if (authorization_delegate) {
9669     // Encrypt just the parameter data, not the size.
9670     std::string tmp = in_sensitive_bytes.substr(2);
9671     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9672       return TRUNKS_RC_ENCRYPTION_FAILED;
9673     }
9674     in_sensitive_bytes.replace(2, std::string::npos, tmp);
9675   }
9676   std::unique_ptr<crypto::SecureHash> hash(
9677       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9678   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9679   hash->Update(parent_handle_name.data(), parent_handle_name.size());
9680   handle_section_bytes += parent_handle_bytes;
9681   command_size += parent_handle_bytes.size();
9682   hash->Update(in_sensitive_bytes.data(), in_sensitive_bytes.size());
9683   parameter_section_bytes += in_sensitive_bytes;
9684   command_size += in_sensitive_bytes.size();
9685   hash->Update(in_public_bytes.data(), in_public_bytes.size());
9686   parameter_section_bytes += in_public_bytes;
9687   command_size += in_public_bytes.size();
9688   hash->Update(outside_info_bytes.data(), outside_info_bytes.size());
9689   parameter_section_bytes += outside_info_bytes;
9690   command_size += outside_info_bytes.size();
9691   hash->Update(creation_pcr_bytes.data(), creation_pcr_bytes.size());
9692   parameter_section_bytes += creation_pcr_bytes;
9693   command_size += creation_pcr_bytes.size();
9694   std::string command_hash(32, 0);
9695   hash->Finish(std::data(command_hash), command_hash.size());
9696   std::string authorization_section_bytes;
9697   std::string authorization_size_bytes;
9698   if (authorization_delegate) {
9699     if (!authorization_delegate->GetCommandAuthorization(
9700             command_hash, is_command_parameter_encryption_possible,
9701             is_response_parameter_encryption_possible,
9702             &authorization_section_bytes)) {
9703       return TRUNKS_RC_AUTHORIZATION_FAILED;
9704     }
9705     if (!authorization_section_bytes.empty()) {
9706       tag = TPM_ST_SESSIONS;
9707       std::string tmp;
9708       rc = Serialize_UINT32(authorization_section_bytes.size(),
9709                             &authorization_size_bytes);
9710       if (rc != TPM_RC_SUCCESS) {
9711         return rc;
9712       }
9713       command_size +=
9714           authorization_size_bytes.size() + authorization_section_bytes.size();
9715     }
9716   }
9717   std::string tag_bytes;
9718   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
9719   if (rc != TPM_RC_SUCCESS) {
9720     return rc;
9721   }
9722   std::string command_size_bytes;
9723   rc = Serialize_UINT32(command_size, &command_size_bytes);
9724   if (rc != TPM_RC_SUCCESS) {
9725     return rc;
9726   }
9727   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
9728                         handle_section_bytes + authorization_size_bytes +
9729                         authorization_section_bytes + parameter_section_bytes;
9730   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
9731   VLOG(2) << "Command: "
9732           << base::HexEncode(serialized_command->data(),
9733                              serialized_command->size());
9734   return TPM_RC_SUCCESS;
9735 }
9736 
ParseResponse_Create(const std::string & response,TPM2B_PRIVATE * out_private,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,AuthorizationDelegate * authorization_delegate)9737 TPM_RC Tpm::ParseResponse_Create(
9738     const std::string& response,
9739     TPM2B_PRIVATE* out_private,
9740     TPM2B_PUBLIC* out_public,
9741     TPM2B_CREATION_DATA* creation_data,
9742     TPM2B_DIGEST* creation_hash,
9743     TPMT_TK_CREATION* creation_ticket,
9744     AuthorizationDelegate* authorization_delegate) {
9745   VLOG(3) << __func__;
9746   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
9747   TPM_RC rc = TPM_RC_SUCCESS;
9748   std::string buffer(response);
9749   TPM_ST tag;
9750   std::string tag_bytes;
9751   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
9752   if (rc != TPM_RC_SUCCESS) {
9753     return rc;
9754   }
9755   UINT32 response_size;
9756   std::string response_size_bytes;
9757   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
9758   if (rc != TPM_RC_SUCCESS) {
9759     return rc;
9760   }
9761   TPM_RC response_code;
9762   std::string response_code_bytes;
9763   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
9764   if (rc != TPM_RC_SUCCESS) {
9765     return rc;
9766   }
9767   if (response_size != response.size()) {
9768     return TPM_RC_SIZE;
9769   }
9770   if (response_code != TPM_RC_SUCCESS) {
9771     return response_code;
9772   }
9773   TPM_CC command_code = TPM_CC_Create;
9774   std::string command_code_bytes;
9775   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9776   if (rc != TPM_RC_SUCCESS) {
9777     return rc;
9778   }
9779   std::string authorization_section_bytes;
9780   if (tag == TPM_ST_SESSIONS) {
9781     UINT32 parameter_section_size = buffer.size();
9782     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
9783     if (rc != TPM_RC_SUCCESS) {
9784       return rc;
9785     }
9786     if (parameter_section_size > buffer.size()) {
9787       return TPM_RC_INSUFFICIENT;
9788     }
9789     authorization_section_bytes = buffer.substr(parameter_section_size);
9790     // Keep the parameter section in |buffer|.
9791     buffer.erase(parameter_section_size);
9792   }
9793   std::unique_ptr<crypto::SecureHash> hash(
9794       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9795   hash->Update(response_code_bytes.data(), response_code_bytes.size());
9796   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9797   hash->Update(buffer.data(), buffer.size());
9798   std::string response_hash(32, 0);
9799   hash->Finish(std::data(response_hash), response_hash.size());
9800   if (tag == TPM_ST_SESSIONS) {
9801     if (!authorization_delegate)
9802       return TRUNKS_RC_AUTHORIZATION_FAILED;
9803     if (!authorization_delegate->CheckResponseAuthorization(
9804             response_hash, authorization_section_bytes)) {
9805       return TRUNKS_RC_AUTHORIZATION_FAILED;
9806     }
9807   }
9808   if (tag == TPM_ST_SESSIONS) {
9809     if (!authorization_delegate)
9810       return TRUNKS_RC_AUTHORIZATION_FAILED;
9811 
9812     // Parse the encrypted parameter size.
9813     UINT16 size;
9814     std::string size_buffer = buffer.substr(0, 2);
9815     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
9816       return result;
9817     }
9818     if (buffer.size() < 2 + size) {
9819       return TPM_RC_INSUFFICIENT;
9820     }
9821 
9822     // Decrypt just the parameter data, not the size.
9823     std::string decrypted_data = buffer.substr(2, size);
9824     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
9825       return TRUNKS_RC_ENCRYPTION_FAILED;
9826     }
9827     buffer.replace(2, size, decrypted_data);
9828   }
9829   std::string out_private_bytes;
9830   rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
9831   if (rc != TPM_RC_SUCCESS) {
9832     return rc;
9833   }
9834   std::string out_public_bytes;
9835   rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
9836   if (rc != TPM_RC_SUCCESS) {
9837     return rc;
9838   }
9839   std::string creation_data_bytes;
9840   rc = Parse_TPM2B_CREATION_DATA(&buffer, creation_data, &creation_data_bytes);
9841   if (rc != TPM_RC_SUCCESS) {
9842     return rc;
9843   }
9844   std::string creation_hash_bytes;
9845   rc = Parse_TPM2B_DIGEST(&buffer, creation_hash, &creation_hash_bytes);
9846   if (rc != TPM_RC_SUCCESS) {
9847     return rc;
9848   }
9849   std::string creation_ticket_bytes;
9850   rc = Parse_TPMT_TK_CREATION(&buffer, creation_ticket, &creation_ticket_bytes);
9851   if (rc != TPM_RC_SUCCESS) {
9852     return rc;
9853   }
9854   return TPM_RC_SUCCESS;
9855 }
9856 
CreateErrorCallback(Tpm::CreateResponse callback,TPM_RC response_code)9857 void CreateErrorCallback(Tpm::CreateResponse callback, TPM_RC response_code) {
9858   VLOG(1) << __func__;
9859   std::move(callback).Run(response_code, TPM2B_PRIVATE(), TPM2B_PUBLIC(),
9860                           TPM2B_CREATION_DATA(), TPM2B_DIGEST(),
9861                           TPMT_TK_CREATION());
9862 }
9863 
CreateResponseParser(Tpm::CreateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)9864 void CreateResponseParser(Tpm::CreateResponse callback,
9865                           AuthorizationDelegate* authorization_delegate,
9866                           const std::string& response) {
9867   VLOG(1) << __func__;
9868   TPM2B_PRIVATE out_private;
9869   TPM2B_PUBLIC out_public;
9870   TPM2B_CREATION_DATA creation_data;
9871   TPM2B_DIGEST creation_hash;
9872   TPMT_TK_CREATION creation_ticket;
9873   TPM_RC rc = Tpm::ParseResponse_Create(
9874       response, &out_private, &out_public, &creation_data, &creation_hash,
9875       &creation_ticket, authorization_delegate);
9876   if (rc != TPM_RC_SUCCESS) {
9877     base::OnceCallback<void(TPM_RC)> error_reporter =
9878         base::BindOnce(CreateErrorCallback, std::move(callback));
9879     std::move(error_reporter).Run(rc);
9880     return;
9881   }
9882   std::move(callback).Run(rc, out_private, out_public, creation_data,
9883                           creation_hash, creation_ticket);
9884 }
9885 
Create(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,AuthorizationDelegate * authorization_delegate,CreateResponse callback)9886 void Tpm::Create(const TPMI_DH_OBJECT& parent_handle,
9887                  const std::string& parent_handle_name,
9888                  const TPM2B_SENSITIVE_CREATE& in_sensitive,
9889                  const TPM2B_PUBLIC& in_public,
9890                  const TPM2B_DATA& outside_info,
9891                  const TPML_PCR_SELECTION& creation_pcr,
9892                  AuthorizationDelegate* authorization_delegate,
9893                  CreateResponse callback) {
9894   VLOG(1) << __func__;
9895   std::string command;
9896   TPM_RC rc = SerializeCommand_Create(
9897       parent_handle, parent_handle_name, in_sensitive, in_public, outside_info,
9898       creation_pcr, &command, authorization_delegate);
9899   if (rc != TPM_RC_SUCCESS) {
9900     base::OnceCallback<void(TPM_RC)> error_reporter =
9901         base::BindOnce(CreateErrorCallback, std::move(callback));
9902     std::move(error_reporter).Run(rc);
9903     return;
9904   }
9905   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
9906       CreateResponseParser, std::move(callback), authorization_delegate);
9907   transceiver_->SendCommand(command, std::move(parser));
9908 }
9909 
CreateSync(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,TPM2B_PRIVATE * out_private,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,AuthorizationDelegate * authorization_delegate)9910 TPM_RC Tpm::CreateSync(const TPMI_DH_OBJECT& parent_handle,
9911                        const std::string& parent_handle_name,
9912                        const TPM2B_SENSITIVE_CREATE& in_sensitive,
9913                        const TPM2B_PUBLIC& in_public,
9914                        const TPM2B_DATA& outside_info,
9915                        const TPML_PCR_SELECTION& creation_pcr,
9916                        TPM2B_PRIVATE* out_private,
9917                        TPM2B_PUBLIC* out_public,
9918                        TPM2B_CREATION_DATA* creation_data,
9919                        TPM2B_DIGEST* creation_hash,
9920                        TPMT_TK_CREATION* creation_ticket,
9921                        AuthorizationDelegate* authorization_delegate) {
9922   VLOG(1) << __func__;
9923   std::string command;
9924   TPM_RC rc = SerializeCommand_Create(
9925       parent_handle, parent_handle_name, in_sensitive, in_public, outside_info,
9926       creation_pcr, &command, authorization_delegate);
9927   if (rc != TPM_RC_SUCCESS) {
9928     return rc;
9929   }
9930   std::string response = transceiver_->SendCommandAndWait(command);
9931   rc = ParseResponse_Create(response, out_private, out_public, creation_data,
9932                             creation_hash, creation_ticket,
9933                             authorization_delegate);
9934   return rc;
9935 }
9936 
SerializeCommand_Load(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_PRIVATE & in_private,const TPM2B_PUBLIC & in_public,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)9937 TPM_RC Tpm::SerializeCommand_Load(
9938     const TPMI_DH_OBJECT& parent_handle,
9939     const std::string& parent_handle_name,
9940     const TPM2B_PRIVATE& in_private,
9941     const TPM2B_PUBLIC& in_public,
9942     std::string* serialized_command,
9943     AuthorizationDelegate* authorization_delegate) {
9944   VLOG(3) << __func__;
9945   TPM_RC rc = TPM_RC_SUCCESS;
9946   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
9947   UINT32 command_size = 10;  // Header size.
9948   std::string handle_section_bytes;
9949   std::string parameter_section_bytes;
9950   TPM_CC command_code = TPM_CC_Load;
9951   bool is_command_parameter_encryption_possible = true;
9952   bool is_response_parameter_encryption_possible = true;
9953   std::string command_code_bytes;
9954   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
9955   if (rc != TPM_RC_SUCCESS) {
9956     return rc;
9957   }
9958   std::string parent_handle_bytes;
9959   rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
9960   if (rc != TPM_RC_SUCCESS) {
9961     return rc;
9962   }
9963   std::string in_private_bytes;
9964   rc = Serialize_TPM2B_PRIVATE(in_private, &in_private_bytes);
9965   if (rc != TPM_RC_SUCCESS) {
9966     return rc;
9967   }
9968   std::string in_public_bytes;
9969   rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
9970   if (rc != TPM_RC_SUCCESS) {
9971     return rc;
9972   }
9973   if (authorization_delegate) {
9974     // Encrypt just the parameter data, not the size.
9975     std::string tmp = in_private_bytes.substr(2);
9976     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
9977       return TRUNKS_RC_ENCRYPTION_FAILED;
9978     }
9979     in_private_bytes.replace(2, std::string::npos, tmp);
9980   }
9981   std::unique_ptr<crypto::SecureHash> hash(
9982       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
9983   hash->Update(command_code_bytes.data(), command_code_bytes.size());
9984   hash->Update(parent_handle_name.data(), parent_handle_name.size());
9985   handle_section_bytes += parent_handle_bytes;
9986   command_size += parent_handle_bytes.size();
9987   hash->Update(in_private_bytes.data(), in_private_bytes.size());
9988   parameter_section_bytes += in_private_bytes;
9989   command_size += in_private_bytes.size();
9990   hash->Update(in_public_bytes.data(), in_public_bytes.size());
9991   parameter_section_bytes += in_public_bytes;
9992   command_size += in_public_bytes.size();
9993   std::string command_hash(32, 0);
9994   hash->Finish(std::data(command_hash), command_hash.size());
9995   std::string authorization_section_bytes;
9996   std::string authorization_size_bytes;
9997   if (authorization_delegate) {
9998     if (!authorization_delegate->GetCommandAuthorization(
9999             command_hash, is_command_parameter_encryption_possible,
10000             is_response_parameter_encryption_possible,
10001             &authorization_section_bytes)) {
10002       return TRUNKS_RC_AUTHORIZATION_FAILED;
10003     }
10004     if (!authorization_section_bytes.empty()) {
10005       tag = TPM_ST_SESSIONS;
10006       std::string tmp;
10007       rc = Serialize_UINT32(authorization_section_bytes.size(),
10008                             &authorization_size_bytes);
10009       if (rc != TPM_RC_SUCCESS) {
10010         return rc;
10011       }
10012       command_size +=
10013           authorization_size_bytes.size() + authorization_section_bytes.size();
10014     }
10015   }
10016   std::string tag_bytes;
10017   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10018   if (rc != TPM_RC_SUCCESS) {
10019     return rc;
10020   }
10021   std::string command_size_bytes;
10022   rc = Serialize_UINT32(command_size, &command_size_bytes);
10023   if (rc != TPM_RC_SUCCESS) {
10024     return rc;
10025   }
10026   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10027                         handle_section_bytes + authorization_size_bytes +
10028                         authorization_section_bytes + parameter_section_bytes;
10029   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10030   VLOG(2) << "Command: "
10031           << base::HexEncode(serialized_command->data(),
10032                              serialized_command->size());
10033   return TPM_RC_SUCCESS;
10034 }
10035 
ParseResponse_Load(const std::string & response,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10036 TPM_RC Tpm::ParseResponse_Load(const std::string& response,
10037                                TPM_HANDLE* object_handle,
10038                                TPM2B_NAME* name,
10039                                AuthorizationDelegate* authorization_delegate) {
10040   VLOG(3) << __func__;
10041   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10042   TPM_RC rc = TPM_RC_SUCCESS;
10043   std::string buffer(response);
10044   TPM_ST tag;
10045   std::string tag_bytes;
10046   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10047   if (rc != TPM_RC_SUCCESS) {
10048     return rc;
10049   }
10050   UINT32 response_size;
10051   std::string response_size_bytes;
10052   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10053   if (rc != TPM_RC_SUCCESS) {
10054     return rc;
10055   }
10056   TPM_RC response_code;
10057   std::string response_code_bytes;
10058   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10059   if (rc != TPM_RC_SUCCESS) {
10060     return rc;
10061   }
10062   if (response_size != response.size()) {
10063     return TPM_RC_SIZE;
10064   }
10065   if (response_code != TPM_RC_SUCCESS) {
10066     return response_code;
10067   }
10068   std::string object_handle_bytes;
10069   rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
10070   if (rc != TPM_RC_SUCCESS) {
10071     return rc;
10072   }
10073   TPM_CC command_code = TPM_CC_Load;
10074   std::string command_code_bytes;
10075   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10076   if (rc != TPM_RC_SUCCESS) {
10077     return rc;
10078   }
10079   std::string authorization_section_bytes;
10080   if (tag == TPM_ST_SESSIONS) {
10081     UINT32 parameter_section_size = buffer.size();
10082     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10083     if (rc != TPM_RC_SUCCESS) {
10084       return rc;
10085     }
10086     if (parameter_section_size > buffer.size()) {
10087       return TPM_RC_INSUFFICIENT;
10088     }
10089     authorization_section_bytes = buffer.substr(parameter_section_size);
10090     // Keep the parameter section in |buffer|.
10091     buffer.erase(parameter_section_size);
10092   }
10093   std::unique_ptr<crypto::SecureHash> hash(
10094       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10095   hash->Update(response_code_bytes.data(), response_code_bytes.size());
10096   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10097   hash->Update(buffer.data(), buffer.size());
10098   std::string response_hash(32, 0);
10099   hash->Finish(std::data(response_hash), response_hash.size());
10100   if (tag == TPM_ST_SESSIONS) {
10101     if (!authorization_delegate)
10102       return TRUNKS_RC_AUTHORIZATION_FAILED;
10103     if (!authorization_delegate->CheckResponseAuthorization(
10104             response_hash, authorization_section_bytes)) {
10105       return TRUNKS_RC_AUTHORIZATION_FAILED;
10106     }
10107   }
10108   if (tag == TPM_ST_SESSIONS) {
10109     if (!authorization_delegate)
10110       return TRUNKS_RC_AUTHORIZATION_FAILED;
10111 
10112     // Parse the encrypted parameter size.
10113     UINT16 size;
10114     std::string size_buffer = buffer.substr(0, 2);
10115     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10116       return result;
10117     }
10118     if (buffer.size() < 2 + size) {
10119       return TPM_RC_INSUFFICIENT;
10120     }
10121 
10122     // Decrypt just the parameter data, not the size.
10123     std::string decrypted_data = buffer.substr(2, size);
10124     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10125       return TRUNKS_RC_ENCRYPTION_FAILED;
10126     }
10127     buffer.replace(2, size, decrypted_data);
10128   }
10129   std::string name_bytes;
10130   rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10131   if (rc != TPM_RC_SUCCESS) {
10132     return rc;
10133   }
10134   return TPM_RC_SUCCESS;
10135 }
10136 
LoadErrorCallback(Tpm::LoadResponse callback,TPM_RC response_code)10137 void LoadErrorCallback(Tpm::LoadResponse callback, TPM_RC response_code) {
10138   VLOG(1) << __func__;
10139   std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_NAME());
10140 }
10141 
LoadResponseParser(Tpm::LoadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10142 void LoadResponseParser(Tpm::LoadResponse callback,
10143                         AuthorizationDelegate* authorization_delegate,
10144                         const std::string& response) {
10145   VLOG(1) << __func__;
10146   TPM_HANDLE object_handle;
10147   TPM2B_NAME name;
10148   TPM_RC rc = Tpm::ParseResponse_Load(response, &object_handle, &name,
10149                                       authorization_delegate);
10150   if (rc != TPM_RC_SUCCESS) {
10151     base::OnceCallback<void(TPM_RC)> error_reporter =
10152         base::BindOnce(LoadErrorCallback, std::move(callback));
10153     std::move(error_reporter).Run(rc);
10154     return;
10155   }
10156   std::move(callback).Run(rc, object_handle, name);
10157 }
10158 
Load(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_PRIVATE & in_private,const TPM2B_PUBLIC & in_public,AuthorizationDelegate * authorization_delegate,LoadResponse callback)10159 void Tpm::Load(const TPMI_DH_OBJECT& parent_handle,
10160                const std::string& parent_handle_name,
10161                const TPM2B_PRIVATE& in_private,
10162                const TPM2B_PUBLIC& in_public,
10163                AuthorizationDelegate* authorization_delegate,
10164                LoadResponse callback) {
10165   VLOG(1) << __func__;
10166   std::string command;
10167   TPM_RC rc =
10168       SerializeCommand_Load(parent_handle, parent_handle_name, in_private,
10169                             in_public, &command, authorization_delegate);
10170   if (rc != TPM_RC_SUCCESS) {
10171     base::OnceCallback<void(TPM_RC)> error_reporter =
10172         base::BindOnce(LoadErrorCallback, std::move(callback));
10173     std::move(error_reporter).Run(rc);
10174     return;
10175   }
10176   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10177       LoadResponseParser, std::move(callback), authorization_delegate);
10178   transceiver_->SendCommand(command, std::move(parser));
10179 }
10180 
LoadSync(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_PRIVATE & in_private,const TPM2B_PUBLIC & in_public,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10181 TPM_RC Tpm::LoadSync(const TPMI_DH_OBJECT& parent_handle,
10182                      const std::string& parent_handle_name,
10183                      const TPM2B_PRIVATE& in_private,
10184                      const TPM2B_PUBLIC& in_public,
10185                      TPM_HANDLE* object_handle,
10186                      TPM2B_NAME* name,
10187                      AuthorizationDelegate* authorization_delegate) {
10188   VLOG(1) << __func__;
10189   std::string command;
10190   TPM_RC rc =
10191       SerializeCommand_Load(parent_handle, parent_handle_name, in_private,
10192                             in_public, &command, authorization_delegate);
10193   if (rc != TPM_RC_SUCCESS) {
10194     return rc;
10195   }
10196   std::string response = transceiver_->SendCommandAndWait(command);
10197   rc =
10198       ParseResponse_Load(response, object_handle, name, authorization_delegate);
10199   return rc;
10200 }
10201 
SerializeCommand_LoadExternal(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10202 TPM_RC Tpm::SerializeCommand_LoadExternal(
10203     const TPM2B_SENSITIVE& in_private,
10204     const TPM2B_PUBLIC& in_public,
10205     const TPMI_RH_HIERARCHY& hierarchy,
10206     std::string* serialized_command,
10207     AuthorizationDelegate* authorization_delegate) {
10208   VLOG(3) << __func__;
10209   TPM_RC rc = TPM_RC_SUCCESS;
10210   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10211   UINT32 command_size = 10;  // Header size.
10212   std::string handle_section_bytes;
10213   std::string parameter_section_bytes;
10214   TPM_CC command_code = TPM_CC_LoadExternal;
10215   bool is_command_parameter_encryption_possible = true;
10216   bool is_response_parameter_encryption_possible = true;
10217   std::string command_code_bytes;
10218   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10219   if (rc != TPM_RC_SUCCESS) {
10220     return rc;
10221   }
10222   std::string in_private_bytes;
10223   rc = Serialize_TPM2B_SENSITIVE(in_private, &in_private_bytes);
10224   if (rc != TPM_RC_SUCCESS) {
10225     return rc;
10226   }
10227   std::string in_public_bytes;
10228   rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
10229   if (rc != TPM_RC_SUCCESS) {
10230     return rc;
10231   }
10232   std::string hierarchy_bytes;
10233   rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
10234   if (rc != TPM_RC_SUCCESS) {
10235     return rc;
10236   }
10237   if (authorization_delegate) {
10238     // Encrypt just the parameter data, not the size.
10239     std::string tmp = in_private_bytes.substr(2);
10240     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10241       return TRUNKS_RC_ENCRYPTION_FAILED;
10242     }
10243     in_private_bytes.replace(2, std::string::npos, tmp);
10244   }
10245   std::unique_ptr<crypto::SecureHash> hash(
10246       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10247   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10248   hash->Update(in_private_bytes.data(), in_private_bytes.size());
10249   parameter_section_bytes += in_private_bytes;
10250   command_size += in_private_bytes.size();
10251   hash->Update(in_public_bytes.data(), in_public_bytes.size());
10252   parameter_section_bytes += in_public_bytes;
10253   command_size += in_public_bytes.size();
10254   hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
10255   parameter_section_bytes += hierarchy_bytes;
10256   command_size += hierarchy_bytes.size();
10257   std::string command_hash(32, 0);
10258   hash->Finish(std::data(command_hash), command_hash.size());
10259   std::string authorization_section_bytes;
10260   std::string authorization_size_bytes;
10261   if (authorization_delegate) {
10262     if (!authorization_delegate->GetCommandAuthorization(
10263             command_hash, is_command_parameter_encryption_possible,
10264             is_response_parameter_encryption_possible,
10265             &authorization_section_bytes)) {
10266       return TRUNKS_RC_AUTHORIZATION_FAILED;
10267     }
10268     if (!authorization_section_bytes.empty()) {
10269       tag = TPM_ST_SESSIONS;
10270       std::string tmp;
10271       rc = Serialize_UINT32(authorization_section_bytes.size(),
10272                             &authorization_size_bytes);
10273       if (rc != TPM_RC_SUCCESS) {
10274         return rc;
10275       }
10276       command_size +=
10277           authorization_size_bytes.size() + authorization_section_bytes.size();
10278     }
10279   }
10280   std::string tag_bytes;
10281   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10282   if (rc != TPM_RC_SUCCESS) {
10283     return rc;
10284   }
10285   std::string command_size_bytes;
10286   rc = Serialize_UINT32(command_size, &command_size_bytes);
10287   if (rc != TPM_RC_SUCCESS) {
10288     return rc;
10289   }
10290   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10291                         handle_section_bytes + authorization_size_bytes +
10292                         authorization_section_bytes + parameter_section_bytes;
10293   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10294   VLOG(2) << "Command: "
10295           << base::HexEncode(serialized_command->data(),
10296                              serialized_command->size());
10297   return TPM_RC_SUCCESS;
10298 }
10299 
ParseResponse_LoadExternal(const std::string & response,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10300 TPM_RC Tpm::ParseResponse_LoadExternal(
10301     const std::string& response,
10302     TPM_HANDLE* object_handle,
10303     TPM2B_NAME* name,
10304     AuthorizationDelegate* authorization_delegate) {
10305   VLOG(3) << __func__;
10306   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10307   TPM_RC rc = TPM_RC_SUCCESS;
10308   std::string buffer(response);
10309   TPM_ST tag;
10310   std::string tag_bytes;
10311   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10312   if (rc != TPM_RC_SUCCESS) {
10313     return rc;
10314   }
10315   UINT32 response_size;
10316   std::string response_size_bytes;
10317   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10318   if (rc != TPM_RC_SUCCESS) {
10319     return rc;
10320   }
10321   TPM_RC response_code;
10322   std::string response_code_bytes;
10323   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10324   if (rc != TPM_RC_SUCCESS) {
10325     return rc;
10326   }
10327   if (response_size != response.size()) {
10328     return TPM_RC_SIZE;
10329   }
10330   if (response_code != TPM_RC_SUCCESS) {
10331     return response_code;
10332   }
10333   std::string object_handle_bytes;
10334   rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
10335   if (rc != TPM_RC_SUCCESS) {
10336     return rc;
10337   }
10338   TPM_CC command_code = TPM_CC_LoadExternal;
10339   std::string command_code_bytes;
10340   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10341   if (rc != TPM_RC_SUCCESS) {
10342     return rc;
10343   }
10344   std::string authorization_section_bytes;
10345   if (tag == TPM_ST_SESSIONS) {
10346     UINT32 parameter_section_size = buffer.size();
10347     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10348     if (rc != TPM_RC_SUCCESS) {
10349       return rc;
10350     }
10351     if (parameter_section_size > buffer.size()) {
10352       return TPM_RC_INSUFFICIENT;
10353     }
10354     authorization_section_bytes = buffer.substr(parameter_section_size);
10355     // Keep the parameter section in |buffer|.
10356     buffer.erase(parameter_section_size);
10357   }
10358   std::unique_ptr<crypto::SecureHash> hash(
10359       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10360   hash->Update(response_code_bytes.data(), response_code_bytes.size());
10361   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10362   hash->Update(buffer.data(), buffer.size());
10363   std::string response_hash(32, 0);
10364   hash->Finish(std::data(response_hash), response_hash.size());
10365   if (tag == TPM_ST_SESSIONS) {
10366     if (!authorization_delegate)
10367       return TRUNKS_RC_AUTHORIZATION_FAILED;
10368     if (!authorization_delegate->CheckResponseAuthorization(
10369             response_hash, authorization_section_bytes)) {
10370       return TRUNKS_RC_AUTHORIZATION_FAILED;
10371     }
10372   }
10373   if (tag == TPM_ST_SESSIONS) {
10374     if (!authorization_delegate)
10375       return TRUNKS_RC_AUTHORIZATION_FAILED;
10376 
10377     // Parse the encrypted parameter size.
10378     UINT16 size;
10379     std::string size_buffer = buffer.substr(0, 2);
10380     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10381       return result;
10382     }
10383     if (buffer.size() < 2 + size) {
10384       return TPM_RC_INSUFFICIENT;
10385     }
10386 
10387     // Decrypt just the parameter data, not the size.
10388     std::string decrypted_data = buffer.substr(2, size);
10389     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10390       return TRUNKS_RC_ENCRYPTION_FAILED;
10391     }
10392     buffer.replace(2, size, decrypted_data);
10393   }
10394   std::string name_bytes;
10395   rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10396   if (rc != TPM_RC_SUCCESS) {
10397     return rc;
10398   }
10399   return TPM_RC_SUCCESS;
10400 }
10401 
LoadExternalErrorCallback(Tpm::LoadExternalResponse callback,TPM_RC response_code)10402 void LoadExternalErrorCallback(Tpm::LoadExternalResponse callback,
10403                                TPM_RC response_code) {
10404   VLOG(1) << __func__;
10405   std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_NAME());
10406 }
10407 
LoadExternalResponseParser(Tpm::LoadExternalResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10408 void LoadExternalResponseParser(Tpm::LoadExternalResponse callback,
10409                                 AuthorizationDelegate* authorization_delegate,
10410                                 const std::string& response) {
10411   VLOG(1) << __func__;
10412   TPM_HANDLE object_handle;
10413   TPM2B_NAME name;
10414   TPM_RC rc = Tpm::ParseResponse_LoadExternal(response, &object_handle, &name,
10415                                               authorization_delegate);
10416   if (rc != TPM_RC_SUCCESS) {
10417     base::OnceCallback<void(TPM_RC)> error_reporter =
10418         base::BindOnce(LoadExternalErrorCallback, std::move(callback));
10419     std::move(error_reporter).Run(rc);
10420     return;
10421   }
10422   std::move(callback).Run(rc, object_handle, name);
10423 }
10424 
LoadExternal(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,LoadExternalResponse callback)10425 void Tpm::LoadExternal(const TPM2B_SENSITIVE& in_private,
10426                        const TPM2B_PUBLIC& in_public,
10427                        const TPMI_RH_HIERARCHY& hierarchy,
10428                        AuthorizationDelegate* authorization_delegate,
10429                        LoadExternalResponse callback) {
10430   VLOG(1) << __func__;
10431   std::string command;
10432   TPM_RC rc = SerializeCommand_LoadExternal(in_private, in_public, hierarchy,
10433                                             &command, authorization_delegate);
10434   if (rc != TPM_RC_SUCCESS) {
10435     base::OnceCallback<void(TPM_RC)> error_reporter =
10436         base::BindOnce(LoadExternalErrorCallback, std::move(callback));
10437     std::move(error_reporter).Run(rc);
10438     return;
10439   }
10440   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10441       LoadExternalResponseParser, std::move(callback), authorization_delegate);
10442   transceiver_->SendCommand(command, std::move(parser));
10443 }
10444 
LoadExternalSync(const TPM2B_SENSITIVE & in_private,const TPM2B_PUBLIC & in_public,const TPMI_RH_HIERARCHY & hierarchy,TPM_HANDLE * object_handle,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)10445 TPM_RC Tpm::LoadExternalSync(const TPM2B_SENSITIVE& in_private,
10446                              const TPM2B_PUBLIC& in_public,
10447                              const TPMI_RH_HIERARCHY& hierarchy,
10448                              TPM_HANDLE* object_handle,
10449                              TPM2B_NAME* name,
10450                              AuthorizationDelegate* authorization_delegate) {
10451   VLOG(1) << __func__;
10452   std::string command;
10453   TPM_RC rc = SerializeCommand_LoadExternal(in_private, in_public, hierarchy,
10454                                             &command, authorization_delegate);
10455   if (rc != TPM_RC_SUCCESS) {
10456     return rc;
10457   }
10458   std::string response = transceiver_->SendCommandAndWait(command);
10459   rc = ParseResponse_LoadExternal(response, object_handle, name,
10460                                   authorization_delegate);
10461   return rc;
10462 }
10463 
SerializeCommand_ReadPublic(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10464 TPM_RC Tpm::SerializeCommand_ReadPublic(
10465     const TPMI_DH_OBJECT& object_handle,
10466     const std::string& object_handle_name,
10467     std::string* serialized_command,
10468     AuthorizationDelegate* authorization_delegate) {
10469   VLOG(3) << __func__;
10470   TPM_RC rc = TPM_RC_SUCCESS;
10471   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10472   UINT32 command_size = 10;  // Header size.
10473   std::string handle_section_bytes;
10474   std::string parameter_section_bytes;
10475   TPM_CC command_code = TPM_CC_ReadPublic;
10476   bool is_command_parameter_encryption_possible = false;
10477   bool is_response_parameter_encryption_possible = true;
10478   std::string command_code_bytes;
10479   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10480   if (rc != TPM_RC_SUCCESS) {
10481     return rc;
10482   }
10483   std::string object_handle_bytes;
10484   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
10485   if (rc != TPM_RC_SUCCESS) {
10486     return rc;
10487   }
10488   std::unique_ptr<crypto::SecureHash> hash(
10489       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10490   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10491   hash->Update(object_handle_name.data(), object_handle_name.size());
10492   handle_section_bytes += object_handle_bytes;
10493   command_size += object_handle_bytes.size();
10494   std::string command_hash(32, 0);
10495   hash->Finish(std::data(command_hash), command_hash.size());
10496   std::string authorization_section_bytes;
10497   std::string authorization_size_bytes;
10498   if (authorization_delegate) {
10499     if (!authorization_delegate->GetCommandAuthorization(
10500             command_hash, is_command_parameter_encryption_possible,
10501             is_response_parameter_encryption_possible,
10502             &authorization_section_bytes)) {
10503       return TRUNKS_RC_AUTHORIZATION_FAILED;
10504     }
10505     if (!authorization_section_bytes.empty()) {
10506       tag = TPM_ST_SESSIONS;
10507       std::string tmp;
10508       rc = Serialize_UINT32(authorization_section_bytes.size(),
10509                             &authorization_size_bytes);
10510       if (rc != TPM_RC_SUCCESS) {
10511         return rc;
10512       }
10513       command_size +=
10514           authorization_size_bytes.size() + authorization_section_bytes.size();
10515     }
10516   }
10517   std::string tag_bytes;
10518   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10519   if (rc != TPM_RC_SUCCESS) {
10520     return rc;
10521   }
10522   std::string command_size_bytes;
10523   rc = Serialize_UINT32(command_size, &command_size_bytes);
10524   if (rc != TPM_RC_SUCCESS) {
10525     return rc;
10526   }
10527   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10528                         handle_section_bytes + authorization_size_bytes +
10529                         authorization_section_bytes + parameter_section_bytes;
10530   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10531   VLOG(2) << "Command: "
10532           << base::HexEncode(serialized_command->data(),
10533                              serialized_command->size());
10534   return TPM_RC_SUCCESS;
10535 }
10536 
ParseResponse_ReadPublic(const std::string & response,TPM2B_PUBLIC * out_public,TPM2B_NAME * name,TPM2B_NAME * qualified_name,AuthorizationDelegate * authorization_delegate)10537 TPM_RC Tpm::ParseResponse_ReadPublic(
10538     const std::string& response,
10539     TPM2B_PUBLIC* out_public,
10540     TPM2B_NAME* name,
10541     TPM2B_NAME* qualified_name,
10542     AuthorizationDelegate* authorization_delegate) {
10543   VLOG(3) << __func__;
10544   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10545   TPM_RC rc = TPM_RC_SUCCESS;
10546   std::string buffer(response);
10547   TPM_ST tag;
10548   std::string tag_bytes;
10549   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10550   if (rc != TPM_RC_SUCCESS) {
10551     return rc;
10552   }
10553   UINT32 response_size;
10554   std::string response_size_bytes;
10555   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10556   if (rc != TPM_RC_SUCCESS) {
10557     return rc;
10558   }
10559   TPM_RC response_code;
10560   std::string response_code_bytes;
10561   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10562   if (rc != TPM_RC_SUCCESS) {
10563     return rc;
10564   }
10565   if (response_size != response.size()) {
10566     return TPM_RC_SIZE;
10567   }
10568   if (response_code != TPM_RC_SUCCESS) {
10569     return response_code;
10570   }
10571   TPM_CC command_code = TPM_CC_ReadPublic;
10572   std::string command_code_bytes;
10573   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10574   if (rc != TPM_RC_SUCCESS) {
10575     return rc;
10576   }
10577   std::string authorization_section_bytes;
10578   if (tag == TPM_ST_SESSIONS) {
10579     UINT32 parameter_section_size = buffer.size();
10580     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10581     if (rc != TPM_RC_SUCCESS) {
10582       return rc;
10583     }
10584     if (parameter_section_size > buffer.size()) {
10585       return TPM_RC_INSUFFICIENT;
10586     }
10587     authorization_section_bytes = buffer.substr(parameter_section_size);
10588     // Keep the parameter section in |buffer|.
10589     buffer.erase(parameter_section_size);
10590   }
10591   std::unique_ptr<crypto::SecureHash> hash(
10592       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10593   hash->Update(response_code_bytes.data(), response_code_bytes.size());
10594   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10595   hash->Update(buffer.data(), buffer.size());
10596   std::string response_hash(32, 0);
10597   hash->Finish(std::data(response_hash), response_hash.size());
10598   if (tag == TPM_ST_SESSIONS) {
10599     if (!authorization_delegate)
10600       return TRUNKS_RC_AUTHORIZATION_FAILED;
10601     if (!authorization_delegate->CheckResponseAuthorization(
10602             response_hash, authorization_section_bytes)) {
10603       return TRUNKS_RC_AUTHORIZATION_FAILED;
10604     }
10605   }
10606   if (tag == TPM_ST_SESSIONS) {
10607     if (!authorization_delegate)
10608       return TRUNKS_RC_AUTHORIZATION_FAILED;
10609 
10610     // Parse the encrypted parameter size.
10611     UINT16 size;
10612     std::string size_buffer = buffer.substr(0, 2);
10613     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10614       return result;
10615     }
10616     if (buffer.size() < 2 + size) {
10617       return TPM_RC_INSUFFICIENT;
10618     }
10619 
10620     // Decrypt just the parameter data, not the size.
10621     std::string decrypted_data = buffer.substr(2, size);
10622     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10623       return TRUNKS_RC_ENCRYPTION_FAILED;
10624     }
10625     buffer.replace(2, size, decrypted_data);
10626   }
10627   std::string out_public_bytes;
10628   rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
10629   if (rc != TPM_RC_SUCCESS) {
10630     return rc;
10631   }
10632   std::string name_bytes;
10633   rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
10634   if (rc != TPM_RC_SUCCESS) {
10635     return rc;
10636   }
10637   std::string qualified_name_bytes;
10638   rc = Parse_TPM2B_NAME(&buffer, qualified_name, &qualified_name_bytes);
10639   if (rc != TPM_RC_SUCCESS) {
10640     return rc;
10641   }
10642   return TPM_RC_SUCCESS;
10643 }
10644 
ReadPublicErrorCallback(Tpm::ReadPublicResponse callback,TPM_RC response_code)10645 void ReadPublicErrorCallback(Tpm::ReadPublicResponse callback,
10646                              TPM_RC response_code) {
10647   VLOG(1) << __func__;
10648   std::move(callback).Run(response_code, TPM2B_PUBLIC(), TPM2B_NAME(),
10649                           TPM2B_NAME());
10650 }
10651 
ReadPublicResponseParser(Tpm::ReadPublicResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10652 void ReadPublicResponseParser(Tpm::ReadPublicResponse callback,
10653                               AuthorizationDelegate* authorization_delegate,
10654                               const std::string& response) {
10655   VLOG(1) << __func__;
10656   TPM2B_PUBLIC out_public;
10657   TPM2B_NAME name;
10658   TPM2B_NAME qualified_name;
10659   TPM_RC rc = Tpm::ParseResponse_ReadPublic(
10660       response, &out_public, &name, &qualified_name, authorization_delegate);
10661   if (rc != TPM_RC_SUCCESS) {
10662     base::OnceCallback<void(TPM_RC)> error_reporter =
10663         base::BindOnce(ReadPublicErrorCallback, std::move(callback));
10664     std::move(error_reporter).Run(rc);
10665     return;
10666   }
10667   std::move(callback).Run(rc, out_public, name, qualified_name);
10668 }
10669 
ReadPublic(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,AuthorizationDelegate * authorization_delegate,ReadPublicResponse callback)10670 void Tpm::ReadPublic(const TPMI_DH_OBJECT& object_handle,
10671                      const std::string& object_handle_name,
10672                      AuthorizationDelegate* authorization_delegate,
10673                      ReadPublicResponse callback) {
10674   VLOG(1) << __func__;
10675   std::string command;
10676   TPM_RC rc = SerializeCommand_ReadPublic(object_handle, object_handle_name,
10677                                           &command, authorization_delegate);
10678   if (rc != TPM_RC_SUCCESS) {
10679     base::OnceCallback<void(TPM_RC)> error_reporter =
10680         base::BindOnce(ReadPublicErrorCallback, std::move(callback));
10681     std::move(error_reporter).Run(rc);
10682     return;
10683   }
10684   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
10685       ReadPublicResponseParser, std::move(callback), authorization_delegate);
10686   transceiver_->SendCommand(command, std::move(parser));
10687 }
10688 
ReadPublicSync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,TPM2B_PUBLIC * out_public,TPM2B_NAME * name,TPM2B_NAME * qualified_name,AuthorizationDelegate * authorization_delegate)10689 TPM_RC Tpm::ReadPublicSync(const TPMI_DH_OBJECT& object_handle,
10690                            const std::string& object_handle_name,
10691                            TPM2B_PUBLIC* out_public,
10692                            TPM2B_NAME* name,
10693                            TPM2B_NAME* qualified_name,
10694                            AuthorizationDelegate* authorization_delegate) {
10695   VLOG(1) << __func__;
10696   std::string command;
10697   TPM_RC rc = SerializeCommand_ReadPublic(object_handle, object_handle_name,
10698                                           &command, authorization_delegate);
10699   if (rc != TPM_RC_SUCCESS) {
10700     return rc;
10701   }
10702   std::string response = transceiver_->SendCommandAndWait(command);
10703   rc = ParseResponse_ReadPublic(response, out_public, name, qualified_name,
10704                                 authorization_delegate);
10705   return rc;
10706 }
10707 
SerializeCommand_ActivateCredential(const TPMI_DH_OBJECT & activate_handle,const std::string & activate_handle_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ID_OBJECT & credential_blob,const TPM2B_ENCRYPTED_SECRET & secret,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10708 TPM_RC Tpm::SerializeCommand_ActivateCredential(
10709     const TPMI_DH_OBJECT& activate_handle,
10710     const std::string& activate_handle_name,
10711     const TPMI_DH_OBJECT& key_handle,
10712     const std::string& key_handle_name,
10713     const TPM2B_ID_OBJECT& credential_blob,
10714     const TPM2B_ENCRYPTED_SECRET& secret,
10715     std::string* serialized_command,
10716     AuthorizationDelegate* authorization_delegate) {
10717   VLOG(3) << __func__;
10718   TPM_RC rc = TPM_RC_SUCCESS;
10719   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10720   UINT32 command_size = 10;  // Header size.
10721   std::string handle_section_bytes;
10722   std::string parameter_section_bytes;
10723   TPM_CC command_code = TPM_CC_ActivateCredential;
10724   bool is_command_parameter_encryption_possible = true;
10725   bool is_response_parameter_encryption_possible = true;
10726   std::string command_code_bytes;
10727   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10728   if (rc != TPM_RC_SUCCESS) {
10729     return rc;
10730   }
10731   std::string activate_handle_bytes;
10732   rc = Serialize_TPMI_DH_OBJECT(activate_handle, &activate_handle_bytes);
10733   if (rc != TPM_RC_SUCCESS) {
10734     return rc;
10735   }
10736   std::string key_handle_bytes;
10737   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
10738   if (rc != TPM_RC_SUCCESS) {
10739     return rc;
10740   }
10741   std::string credential_blob_bytes;
10742   rc = Serialize_TPM2B_ID_OBJECT(credential_blob, &credential_blob_bytes);
10743   if (rc != TPM_RC_SUCCESS) {
10744     return rc;
10745   }
10746   std::string secret_bytes;
10747   rc = Serialize_TPM2B_ENCRYPTED_SECRET(secret, &secret_bytes);
10748   if (rc != TPM_RC_SUCCESS) {
10749     return rc;
10750   }
10751   if (authorization_delegate) {
10752     // Encrypt just the parameter data, not the size.
10753     std::string tmp = credential_blob_bytes.substr(2);
10754     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
10755       return TRUNKS_RC_ENCRYPTION_FAILED;
10756     }
10757     credential_blob_bytes.replace(2, std::string::npos, tmp);
10758   }
10759   std::unique_ptr<crypto::SecureHash> hash(
10760       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10761   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10762   hash->Update(activate_handle_name.data(), activate_handle_name.size());
10763   handle_section_bytes += activate_handle_bytes;
10764   command_size += activate_handle_bytes.size();
10765   hash->Update(key_handle_name.data(), key_handle_name.size());
10766   handle_section_bytes += key_handle_bytes;
10767   command_size += key_handle_bytes.size();
10768   hash->Update(credential_blob_bytes.data(), credential_blob_bytes.size());
10769   parameter_section_bytes += credential_blob_bytes;
10770   command_size += credential_blob_bytes.size();
10771   hash->Update(secret_bytes.data(), secret_bytes.size());
10772   parameter_section_bytes += secret_bytes;
10773   command_size += secret_bytes.size();
10774   std::string command_hash(32, 0);
10775   hash->Finish(std::data(command_hash), command_hash.size());
10776   std::string authorization_section_bytes;
10777   std::string authorization_size_bytes;
10778   if (authorization_delegate) {
10779     if (!authorization_delegate->GetCommandAuthorization(
10780             command_hash, is_command_parameter_encryption_possible,
10781             is_response_parameter_encryption_possible,
10782             &authorization_section_bytes)) {
10783       return TRUNKS_RC_AUTHORIZATION_FAILED;
10784     }
10785     if (!authorization_section_bytes.empty()) {
10786       tag = TPM_ST_SESSIONS;
10787       std::string tmp;
10788       rc = Serialize_UINT32(authorization_section_bytes.size(),
10789                             &authorization_size_bytes);
10790       if (rc != TPM_RC_SUCCESS) {
10791         return rc;
10792       }
10793       command_size +=
10794           authorization_size_bytes.size() + authorization_section_bytes.size();
10795     }
10796   }
10797   std::string tag_bytes;
10798   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
10799   if (rc != TPM_RC_SUCCESS) {
10800     return rc;
10801   }
10802   std::string command_size_bytes;
10803   rc = Serialize_UINT32(command_size, &command_size_bytes);
10804   if (rc != TPM_RC_SUCCESS) {
10805     return rc;
10806   }
10807   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
10808                         handle_section_bytes + authorization_size_bytes +
10809                         authorization_section_bytes + parameter_section_bytes;
10810   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
10811   VLOG(2) << "Command: "
10812           << base::HexEncode(serialized_command->data(),
10813                              serialized_command->size());
10814   return TPM_RC_SUCCESS;
10815 }
10816 
ParseResponse_ActivateCredential(const std::string & response,TPM2B_DIGEST * cert_info,AuthorizationDelegate * authorization_delegate)10817 TPM_RC Tpm::ParseResponse_ActivateCredential(
10818     const std::string& response,
10819     TPM2B_DIGEST* cert_info,
10820     AuthorizationDelegate* authorization_delegate) {
10821   VLOG(3) << __func__;
10822   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
10823   TPM_RC rc = TPM_RC_SUCCESS;
10824   std::string buffer(response);
10825   TPM_ST tag;
10826   std::string tag_bytes;
10827   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
10828   if (rc != TPM_RC_SUCCESS) {
10829     return rc;
10830   }
10831   UINT32 response_size;
10832   std::string response_size_bytes;
10833   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
10834   if (rc != TPM_RC_SUCCESS) {
10835     return rc;
10836   }
10837   TPM_RC response_code;
10838   std::string response_code_bytes;
10839   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
10840   if (rc != TPM_RC_SUCCESS) {
10841     return rc;
10842   }
10843   if (response_size != response.size()) {
10844     return TPM_RC_SIZE;
10845   }
10846   if (response_code != TPM_RC_SUCCESS) {
10847     return response_code;
10848   }
10849   TPM_CC command_code = TPM_CC_ActivateCredential;
10850   std::string command_code_bytes;
10851   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
10852   if (rc != TPM_RC_SUCCESS) {
10853     return rc;
10854   }
10855   std::string authorization_section_bytes;
10856   if (tag == TPM_ST_SESSIONS) {
10857     UINT32 parameter_section_size = buffer.size();
10858     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
10859     if (rc != TPM_RC_SUCCESS) {
10860       return rc;
10861     }
10862     if (parameter_section_size > buffer.size()) {
10863       return TPM_RC_INSUFFICIENT;
10864     }
10865     authorization_section_bytes = buffer.substr(parameter_section_size);
10866     // Keep the parameter section in |buffer|.
10867     buffer.erase(parameter_section_size);
10868   }
10869   std::unique_ptr<crypto::SecureHash> hash(
10870       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
10871   hash->Update(response_code_bytes.data(), response_code_bytes.size());
10872   hash->Update(command_code_bytes.data(), command_code_bytes.size());
10873   hash->Update(buffer.data(), buffer.size());
10874   std::string response_hash(32, 0);
10875   hash->Finish(std::data(response_hash), response_hash.size());
10876   if (tag == TPM_ST_SESSIONS) {
10877     if (!authorization_delegate)
10878       return TRUNKS_RC_AUTHORIZATION_FAILED;
10879     if (!authorization_delegate->CheckResponseAuthorization(
10880             response_hash, authorization_section_bytes)) {
10881       return TRUNKS_RC_AUTHORIZATION_FAILED;
10882     }
10883   }
10884   if (tag == TPM_ST_SESSIONS) {
10885     if (!authorization_delegate)
10886       return TRUNKS_RC_AUTHORIZATION_FAILED;
10887 
10888     // Parse the encrypted parameter size.
10889     UINT16 size;
10890     std::string size_buffer = buffer.substr(0, 2);
10891     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
10892       return result;
10893     }
10894     if (buffer.size() < 2 + size) {
10895       return TPM_RC_INSUFFICIENT;
10896     }
10897 
10898     // Decrypt just the parameter data, not the size.
10899     std::string decrypted_data = buffer.substr(2, size);
10900     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
10901       return TRUNKS_RC_ENCRYPTION_FAILED;
10902     }
10903     buffer.replace(2, size, decrypted_data);
10904   }
10905   std::string cert_info_bytes;
10906   rc = Parse_TPM2B_DIGEST(&buffer, cert_info, &cert_info_bytes);
10907   if (rc != TPM_RC_SUCCESS) {
10908     return rc;
10909   }
10910   return TPM_RC_SUCCESS;
10911 }
10912 
ActivateCredentialErrorCallback(Tpm::ActivateCredentialResponse callback,TPM_RC response_code)10913 void ActivateCredentialErrorCallback(Tpm::ActivateCredentialResponse callback,
10914                                      TPM_RC response_code) {
10915   VLOG(1) << __func__;
10916   std::move(callback).Run(response_code, TPM2B_DIGEST());
10917 }
10918 
ActivateCredentialResponseParser(Tpm::ActivateCredentialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)10919 void ActivateCredentialResponseParser(
10920     Tpm::ActivateCredentialResponse callback,
10921     AuthorizationDelegate* authorization_delegate,
10922     const std::string& response) {
10923   VLOG(1) << __func__;
10924   TPM2B_DIGEST cert_info;
10925   TPM_RC rc = Tpm::ParseResponse_ActivateCredential(response, &cert_info,
10926                                                     authorization_delegate);
10927   if (rc != TPM_RC_SUCCESS) {
10928     base::OnceCallback<void(TPM_RC)> error_reporter =
10929         base::BindOnce(ActivateCredentialErrorCallback, std::move(callback));
10930     std::move(error_reporter).Run(rc);
10931     return;
10932   }
10933   std::move(callback).Run(rc, cert_info);
10934 }
10935 
ActivateCredential(const TPMI_DH_OBJECT & activate_handle,const std::string & activate_handle_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ID_OBJECT & credential_blob,const TPM2B_ENCRYPTED_SECRET & secret,AuthorizationDelegate * authorization_delegate,ActivateCredentialResponse callback)10936 void Tpm::ActivateCredential(const TPMI_DH_OBJECT& activate_handle,
10937                              const std::string& activate_handle_name,
10938                              const TPMI_DH_OBJECT& key_handle,
10939                              const std::string& key_handle_name,
10940                              const TPM2B_ID_OBJECT& credential_blob,
10941                              const TPM2B_ENCRYPTED_SECRET& secret,
10942                              AuthorizationDelegate* authorization_delegate,
10943                              ActivateCredentialResponse callback) {
10944   VLOG(1) << __func__;
10945   std::string command;
10946   TPM_RC rc = SerializeCommand_ActivateCredential(
10947       activate_handle, activate_handle_name, key_handle, key_handle_name,
10948       credential_blob, secret, &command, authorization_delegate);
10949   if (rc != TPM_RC_SUCCESS) {
10950     base::OnceCallback<void(TPM_RC)> error_reporter =
10951         base::BindOnce(ActivateCredentialErrorCallback, std::move(callback));
10952     std::move(error_reporter).Run(rc);
10953     return;
10954   }
10955   base::OnceCallback<void(const std::string&)> parser =
10956       base::BindOnce(ActivateCredentialResponseParser, std::move(callback),
10957                      authorization_delegate);
10958   transceiver_->SendCommand(command, std::move(parser));
10959 }
10960 
ActivateCredentialSync(const TPMI_DH_OBJECT & activate_handle,const std::string & activate_handle_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ID_OBJECT & credential_blob,const TPM2B_ENCRYPTED_SECRET & secret,TPM2B_DIGEST * cert_info,AuthorizationDelegate * authorization_delegate)10961 TPM_RC Tpm::ActivateCredentialSync(
10962     const TPMI_DH_OBJECT& activate_handle,
10963     const std::string& activate_handle_name,
10964     const TPMI_DH_OBJECT& key_handle,
10965     const std::string& key_handle_name,
10966     const TPM2B_ID_OBJECT& credential_blob,
10967     const TPM2B_ENCRYPTED_SECRET& secret,
10968     TPM2B_DIGEST* cert_info,
10969     AuthorizationDelegate* authorization_delegate) {
10970   VLOG(1) << __func__;
10971   std::string command;
10972   TPM_RC rc = SerializeCommand_ActivateCredential(
10973       activate_handle, activate_handle_name, key_handle, key_handle_name,
10974       credential_blob, secret, &command, authorization_delegate);
10975   if (rc != TPM_RC_SUCCESS) {
10976     return rc;
10977   }
10978   std::string response = transceiver_->SendCommandAndWait(command);
10979   rc = ParseResponse_ActivateCredential(response, cert_info,
10980                                         authorization_delegate);
10981   return rc;
10982 }
10983 
SerializeCommand_MakeCredential(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_DIGEST & credential,const TPM2B_NAME & object_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)10984 TPM_RC Tpm::SerializeCommand_MakeCredential(
10985     const TPMI_DH_OBJECT& handle,
10986     const std::string& handle_name,
10987     const TPM2B_DIGEST& credential,
10988     const TPM2B_NAME& object_name,
10989     std::string* serialized_command,
10990     AuthorizationDelegate* authorization_delegate) {
10991   VLOG(3) << __func__;
10992   TPM_RC rc = TPM_RC_SUCCESS;
10993   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
10994   UINT32 command_size = 10;  // Header size.
10995   std::string handle_section_bytes;
10996   std::string parameter_section_bytes;
10997   TPM_CC command_code = TPM_CC_MakeCredential;
10998   bool is_command_parameter_encryption_possible = true;
10999   bool is_response_parameter_encryption_possible = true;
11000   std::string command_code_bytes;
11001   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11002   if (rc != TPM_RC_SUCCESS) {
11003     return rc;
11004   }
11005   std::string handle_bytes;
11006   rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
11007   if (rc != TPM_RC_SUCCESS) {
11008     return rc;
11009   }
11010   std::string credential_bytes;
11011   rc = Serialize_TPM2B_DIGEST(credential, &credential_bytes);
11012   if (rc != TPM_RC_SUCCESS) {
11013     return rc;
11014   }
11015   std::string object_name_bytes;
11016   rc = Serialize_TPM2B_NAME(object_name, &object_name_bytes);
11017   if (rc != TPM_RC_SUCCESS) {
11018     return rc;
11019   }
11020   if (authorization_delegate) {
11021     // Encrypt just the parameter data, not the size.
11022     std::string tmp = credential_bytes.substr(2);
11023     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11024       return TRUNKS_RC_ENCRYPTION_FAILED;
11025     }
11026     credential_bytes.replace(2, std::string::npos, tmp);
11027   }
11028   std::unique_ptr<crypto::SecureHash> hash(
11029       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11030   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11031   hash->Update(handle_name.data(), handle_name.size());
11032   handle_section_bytes += handle_bytes;
11033   command_size += handle_bytes.size();
11034   hash->Update(credential_bytes.data(), credential_bytes.size());
11035   parameter_section_bytes += credential_bytes;
11036   command_size += credential_bytes.size();
11037   hash->Update(object_name_bytes.data(), object_name_bytes.size());
11038   parameter_section_bytes += object_name_bytes;
11039   command_size += object_name_bytes.size();
11040   std::string command_hash(32, 0);
11041   hash->Finish(std::data(command_hash), command_hash.size());
11042   std::string authorization_section_bytes;
11043   std::string authorization_size_bytes;
11044   if (authorization_delegate) {
11045     if (!authorization_delegate->GetCommandAuthorization(
11046             command_hash, is_command_parameter_encryption_possible,
11047             is_response_parameter_encryption_possible,
11048             &authorization_section_bytes)) {
11049       return TRUNKS_RC_AUTHORIZATION_FAILED;
11050     }
11051     if (!authorization_section_bytes.empty()) {
11052       tag = TPM_ST_SESSIONS;
11053       std::string tmp;
11054       rc = Serialize_UINT32(authorization_section_bytes.size(),
11055                             &authorization_size_bytes);
11056       if (rc != TPM_RC_SUCCESS) {
11057         return rc;
11058       }
11059       command_size +=
11060           authorization_size_bytes.size() + authorization_section_bytes.size();
11061     }
11062   }
11063   std::string tag_bytes;
11064   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11065   if (rc != TPM_RC_SUCCESS) {
11066     return rc;
11067   }
11068   std::string command_size_bytes;
11069   rc = Serialize_UINT32(command_size, &command_size_bytes);
11070   if (rc != TPM_RC_SUCCESS) {
11071     return rc;
11072   }
11073   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11074                         handle_section_bytes + authorization_size_bytes +
11075                         authorization_section_bytes + parameter_section_bytes;
11076   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11077   VLOG(2) << "Command: "
11078           << base::HexEncode(serialized_command->data(),
11079                              serialized_command->size());
11080   return TPM_RC_SUCCESS;
11081 }
11082 
ParseResponse_MakeCredential(const std::string & response,TPM2B_ID_OBJECT * credential_blob,TPM2B_ENCRYPTED_SECRET * secret,AuthorizationDelegate * authorization_delegate)11083 TPM_RC Tpm::ParseResponse_MakeCredential(
11084     const std::string& response,
11085     TPM2B_ID_OBJECT* credential_blob,
11086     TPM2B_ENCRYPTED_SECRET* secret,
11087     AuthorizationDelegate* authorization_delegate) {
11088   VLOG(3) << __func__;
11089   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11090   TPM_RC rc = TPM_RC_SUCCESS;
11091   std::string buffer(response);
11092   TPM_ST tag;
11093   std::string tag_bytes;
11094   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11095   if (rc != TPM_RC_SUCCESS) {
11096     return rc;
11097   }
11098   UINT32 response_size;
11099   std::string response_size_bytes;
11100   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11101   if (rc != TPM_RC_SUCCESS) {
11102     return rc;
11103   }
11104   TPM_RC response_code;
11105   std::string response_code_bytes;
11106   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11107   if (rc != TPM_RC_SUCCESS) {
11108     return rc;
11109   }
11110   if (response_size != response.size()) {
11111     return TPM_RC_SIZE;
11112   }
11113   if (response_code != TPM_RC_SUCCESS) {
11114     return response_code;
11115   }
11116   TPM_CC command_code = TPM_CC_MakeCredential;
11117   std::string command_code_bytes;
11118   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11119   if (rc != TPM_RC_SUCCESS) {
11120     return rc;
11121   }
11122   std::string authorization_section_bytes;
11123   if (tag == TPM_ST_SESSIONS) {
11124     UINT32 parameter_section_size = buffer.size();
11125     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11126     if (rc != TPM_RC_SUCCESS) {
11127       return rc;
11128     }
11129     if (parameter_section_size > buffer.size()) {
11130       return TPM_RC_INSUFFICIENT;
11131     }
11132     authorization_section_bytes = buffer.substr(parameter_section_size);
11133     // Keep the parameter section in |buffer|.
11134     buffer.erase(parameter_section_size);
11135   }
11136   std::unique_ptr<crypto::SecureHash> hash(
11137       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11138   hash->Update(response_code_bytes.data(), response_code_bytes.size());
11139   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11140   hash->Update(buffer.data(), buffer.size());
11141   std::string response_hash(32, 0);
11142   hash->Finish(std::data(response_hash), response_hash.size());
11143   if (tag == TPM_ST_SESSIONS) {
11144     if (!authorization_delegate)
11145       return TRUNKS_RC_AUTHORIZATION_FAILED;
11146     if (!authorization_delegate->CheckResponseAuthorization(
11147             response_hash, authorization_section_bytes)) {
11148       return TRUNKS_RC_AUTHORIZATION_FAILED;
11149     }
11150   }
11151   if (tag == TPM_ST_SESSIONS) {
11152     if (!authorization_delegate)
11153       return TRUNKS_RC_AUTHORIZATION_FAILED;
11154 
11155     // Parse the encrypted parameter size.
11156     UINT16 size;
11157     std::string size_buffer = buffer.substr(0, 2);
11158     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11159       return result;
11160     }
11161     if (buffer.size() < 2 + size) {
11162       return TPM_RC_INSUFFICIENT;
11163     }
11164 
11165     // Decrypt just the parameter data, not the size.
11166     std::string decrypted_data = buffer.substr(2, size);
11167     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11168       return TRUNKS_RC_ENCRYPTION_FAILED;
11169     }
11170     buffer.replace(2, size, decrypted_data);
11171   }
11172   std::string credential_blob_bytes;
11173   rc = Parse_TPM2B_ID_OBJECT(&buffer, credential_blob, &credential_blob_bytes);
11174   if (rc != TPM_RC_SUCCESS) {
11175     return rc;
11176   }
11177   std::string secret_bytes;
11178   rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, secret, &secret_bytes);
11179   if (rc != TPM_RC_SUCCESS) {
11180     return rc;
11181   }
11182   return TPM_RC_SUCCESS;
11183 }
11184 
MakeCredentialErrorCallback(Tpm::MakeCredentialResponse callback,TPM_RC response_code)11185 void MakeCredentialErrorCallback(Tpm::MakeCredentialResponse callback,
11186                                  TPM_RC response_code) {
11187   VLOG(1) << __func__;
11188   std::move(callback).Run(response_code, TPM2B_ID_OBJECT(),
11189                           TPM2B_ENCRYPTED_SECRET());
11190 }
11191 
MakeCredentialResponseParser(Tpm::MakeCredentialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11192 void MakeCredentialResponseParser(Tpm::MakeCredentialResponse callback,
11193                                   AuthorizationDelegate* authorization_delegate,
11194                                   const std::string& response) {
11195   VLOG(1) << __func__;
11196   TPM2B_ID_OBJECT credential_blob;
11197   TPM2B_ENCRYPTED_SECRET secret;
11198   TPM_RC rc = Tpm::ParseResponse_MakeCredential(
11199       response, &credential_blob, &secret, authorization_delegate);
11200   if (rc != TPM_RC_SUCCESS) {
11201     base::OnceCallback<void(TPM_RC)> error_reporter =
11202         base::BindOnce(MakeCredentialErrorCallback, std::move(callback));
11203     std::move(error_reporter).Run(rc);
11204     return;
11205   }
11206   std::move(callback).Run(rc, credential_blob, secret);
11207 }
11208 
MakeCredential(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_DIGEST & credential,const TPM2B_NAME & object_name,AuthorizationDelegate * authorization_delegate,MakeCredentialResponse callback)11209 void Tpm::MakeCredential(const TPMI_DH_OBJECT& handle,
11210                          const std::string& handle_name,
11211                          const TPM2B_DIGEST& credential,
11212                          const TPM2B_NAME& object_name,
11213                          AuthorizationDelegate* authorization_delegate,
11214                          MakeCredentialResponse callback) {
11215   VLOG(1) << __func__;
11216   std::string command;
11217   TPM_RC rc = SerializeCommand_MakeCredential(handle, handle_name, credential,
11218                                               object_name, &command,
11219                                               authorization_delegate);
11220   if (rc != TPM_RC_SUCCESS) {
11221     base::OnceCallback<void(TPM_RC)> error_reporter =
11222         base::BindOnce(MakeCredentialErrorCallback, std::move(callback));
11223     std::move(error_reporter).Run(rc);
11224     return;
11225   }
11226   base::OnceCallback<void(const std::string&)> parser =
11227       base::BindOnce(MakeCredentialResponseParser, std::move(callback),
11228                      authorization_delegate);
11229   transceiver_->SendCommand(command, std::move(parser));
11230 }
11231 
MakeCredentialSync(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_DIGEST & credential,const TPM2B_NAME & object_name,TPM2B_ID_OBJECT * credential_blob,TPM2B_ENCRYPTED_SECRET * secret,AuthorizationDelegate * authorization_delegate)11232 TPM_RC Tpm::MakeCredentialSync(const TPMI_DH_OBJECT& handle,
11233                                const std::string& handle_name,
11234                                const TPM2B_DIGEST& credential,
11235                                const TPM2B_NAME& object_name,
11236                                TPM2B_ID_OBJECT* credential_blob,
11237                                TPM2B_ENCRYPTED_SECRET* secret,
11238                                AuthorizationDelegate* authorization_delegate) {
11239   VLOG(1) << __func__;
11240   std::string command;
11241   TPM_RC rc = SerializeCommand_MakeCredential(handle, handle_name, credential,
11242                                               object_name, &command,
11243                                               authorization_delegate);
11244   if (rc != TPM_RC_SUCCESS) {
11245     return rc;
11246   }
11247   std::string response = transceiver_->SendCommandAndWait(command);
11248   rc = ParseResponse_MakeCredential(response, credential_blob, secret,
11249                                     authorization_delegate);
11250   return rc;
11251 }
11252 
SerializeCommand_Unseal(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)11253 TPM_RC Tpm::SerializeCommand_Unseal(
11254     const TPMI_DH_OBJECT& item_handle,
11255     const std::string& item_handle_name,
11256     std::string* serialized_command,
11257     AuthorizationDelegate* authorization_delegate) {
11258   VLOG(3) << __func__;
11259   TPM_RC rc = TPM_RC_SUCCESS;
11260   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11261   UINT32 command_size = 10;  // Header size.
11262   std::string handle_section_bytes;
11263   std::string parameter_section_bytes;
11264   TPM_CC command_code = TPM_CC_Unseal;
11265   bool is_command_parameter_encryption_possible = false;
11266   bool is_response_parameter_encryption_possible = true;
11267   std::string command_code_bytes;
11268   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11269   if (rc != TPM_RC_SUCCESS) {
11270     return rc;
11271   }
11272   std::string item_handle_bytes;
11273   rc = Serialize_TPMI_DH_OBJECT(item_handle, &item_handle_bytes);
11274   if (rc != TPM_RC_SUCCESS) {
11275     return rc;
11276   }
11277   std::unique_ptr<crypto::SecureHash> hash(
11278       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11279   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11280   hash->Update(item_handle_name.data(), item_handle_name.size());
11281   handle_section_bytes += item_handle_bytes;
11282   command_size += item_handle_bytes.size();
11283   std::string command_hash(32, 0);
11284   hash->Finish(std::data(command_hash), command_hash.size());
11285   std::string authorization_section_bytes;
11286   std::string authorization_size_bytes;
11287   if (authorization_delegate) {
11288     if (!authorization_delegate->GetCommandAuthorization(
11289             command_hash, is_command_parameter_encryption_possible,
11290             is_response_parameter_encryption_possible,
11291             &authorization_section_bytes)) {
11292       return TRUNKS_RC_AUTHORIZATION_FAILED;
11293     }
11294     if (!authorization_section_bytes.empty()) {
11295       tag = TPM_ST_SESSIONS;
11296       std::string tmp;
11297       rc = Serialize_UINT32(authorization_section_bytes.size(),
11298                             &authorization_size_bytes);
11299       if (rc != TPM_RC_SUCCESS) {
11300         return rc;
11301       }
11302       command_size +=
11303           authorization_size_bytes.size() + authorization_section_bytes.size();
11304     }
11305   }
11306   std::string tag_bytes;
11307   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11308   if (rc != TPM_RC_SUCCESS) {
11309     return rc;
11310   }
11311   std::string command_size_bytes;
11312   rc = Serialize_UINT32(command_size, &command_size_bytes);
11313   if (rc != TPM_RC_SUCCESS) {
11314     return rc;
11315   }
11316   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11317                         handle_section_bytes + authorization_size_bytes +
11318                         authorization_section_bytes + parameter_section_bytes;
11319   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11320   VLOG(2) << "Command: "
11321           << base::HexEncode(serialized_command->data(),
11322                              serialized_command->size());
11323   return TPM_RC_SUCCESS;
11324 }
11325 
ParseResponse_Unseal(const std::string & response,TPM2B_SENSITIVE_DATA * out_data,AuthorizationDelegate * authorization_delegate)11326 TPM_RC Tpm::ParseResponse_Unseal(
11327     const std::string& response,
11328     TPM2B_SENSITIVE_DATA* out_data,
11329     AuthorizationDelegate* authorization_delegate) {
11330   VLOG(3) << __func__;
11331   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11332   TPM_RC rc = TPM_RC_SUCCESS;
11333   std::string buffer(response);
11334   TPM_ST tag;
11335   std::string tag_bytes;
11336   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11337   if (rc != TPM_RC_SUCCESS) {
11338     return rc;
11339   }
11340   UINT32 response_size;
11341   std::string response_size_bytes;
11342   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11343   if (rc != TPM_RC_SUCCESS) {
11344     return rc;
11345   }
11346   TPM_RC response_code;
11347   std::string response_code_bytes;
11348   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11349   if (rc != TPM_RC_SUCCESS) {
11350     return rc;
11351   }
11352   if (response_size != response.size()) {
11353     return TPM_RC_SIZE;
11354   }
11355   if (response_code != TPM_RC_SUCCESS) {
11356     return response_code;
11357   }
11358   TPM_CC command_code = TPM_CC_Unseal;
11359   std::string command_code_bytes;
11360   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11361   if (rc != TPM_RC_SUCCESS) {
11362     return rc;
11363   }
11364   std::string authorization_section_bytes;
11365   if (tag == TPM_ST_SESSIONS) {
11366     UINT32 parameter_section_size = buffer.size();
11367     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11368     if (rc != TPM_RC_SUCCESS) {
11369       return rc;
11370     }
11371     if (parameter_section_size > buffer.size()) {
11372       return TPM_RC_INSUFFICIENT;
11373     }
11374     authorization_section_bytes = buffer.substr(parameter_section_size);
11375     // Keep the parameter section in |buffer|.
11376     buffer.erase(parameter_section_size);
11377   }
11378   std::unique_ptr<crypto::SecureHash> hash(
11379       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11380   hash->Update(response_code_bytes.data(), response_code_bytes.size());
11381   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11382   hash->Update(buffer.data(), buffer.size());
11383   std::string response_hash(32, 0);
11384   hash->Finish(std::data(response_hash), response_hash.size());
11385   if (tag == TPM_ST_SESSIONS) {
11386     if (!authorization_delegate)
11387       return TRUNKS_RC_AUTHORIZATION_FAILED;
11388     if (!authorization_delegate->CheckResponseAuthorization(
11389             response_hash, authorization_section_bytes)) {
11390       return TRUNKS_RC_AUTHORIZATION_FAILED;
11391     }
11392   }
11393   if (tag == TPM_ST_SESSIONS) {
11394     if (!authorization_delegate)
11395       return TRUNKS_RC_AUTHORIZATION_FAILED;
11396 
11397     // Parse the encrypted parameter size.
11398     UINT16 size;
11399     std::string size_buffer = buffer.substr(0, 2);
11400     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11401       return result;
11402     }
11403     if (buffer.size() < 2 + size) {
11404       return TPM_RC_INSUFFICIENT;
11405     }
11406 
11407     // Decrypt just the parameter data, not the size.
11408     std::string decrypted_data = buffer.substr(2, size);
11409     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11410       return TRUNKS_RC_ENCRYPTION_FAILED;
11411     }
11412     buffer.replace(2, size, decrypted_data);
11413   }
11414   std::string out_data_bytes;
11415   rc = Parse_TPM2B_SENSITIVE_DATA(&buffer, out_data, &out_data_bytes);
11416   if (rc != TPM_RC_SUCCESS) {
11417     return rc;
11418   }
11419   return TPM_RC_SUCCESS;
11420 }
11421 
UnsealErrorCallback(Tpm::UnsealResponse callback,TPM_RC response_code)11422 void UnsealErrorCallback(Tpm::UnsealResponse callback, TPM_RC response_code) {
11423   VLOG(1) << __func__;
11424   std::move(callback).Run(response_code, TPM2B_SENSITIVE_DATA());
11425 }
11426 
UnsealResponseParser(Tpm::UnsealResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11427 void UnsealResponseParser(Tpm::UnsealResponse callback,
11428                           AuthorizationDelegate* authorization_delegate,
11429                           const std::string& response) {
11430   VLOG(1) << __func__;
11431   TPM2B_SENSITIVE_DATA out_data;
11432   TPM_RC rc =
11433       Tpm::ParseResponse_Unseal(response, &out_data, authorization_delegate);
11434   if (rc != TPM_RC_SUCCESS) {
11435     base::OnceCallback<void(TPM_RC)> error_reporter =
11436         base::BindOnce(UnsealErrorCallback, std::move(callback));
11437     std::move(error_reporter).Run(rc);
11438     return;
11439   }
11440   std::move(callback).Run(rc, out_data);
11441 }
11442 
Unseal(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,AuthorizationDelegate * authorization_delegate,UnsealResponse callback)11443 void Tpm::Unseal(const TPMI_DH_OBJECT& item_handle,
11444                  const std::string& item_handle_name,
11445                  AuthorizationDelegate* authorization_delegate,
11446                  UnsealResponse callback) {
11447   VLOG(1) << __func__;
11448   std::string command;
11449   TPM_RC rc = SerializeCommand_Unseal(item_handle, item_handle_name, &command,
11450                                       authorization_delegate);
11451   if (rc != TPM_RC_SUCCESS) {
11452     base::OnceCallback<void(TPM_RC)> error_reporter =
11453         base::BindOnce(UnsealErrorCallback, std::move(callback));
11454     std::move(error_reporter).Run(rc);
11455     return;
11456   }
11457   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
11458       UnsealResponseParser, std::move(callback), authorization_delegate);
11459   transceiver_->SendCommand(command, std::move(parser));
11460 }
11461 
UnsealSync(const TPMI_DH_OBJECT & item_handle,const std::string & item_handle_name,TPM2B_SENSITIVE_DATA * out_data,AuthorizationDelegate * authorization_delegate)11462 TPM_RC Tpm::UnsealSync(const TPMI_DH_OBJECT& item_handle,
11463                        const std::string& item_handle_name,
11464                        TPM2B_SENSITIVE_DATA* out_data,
11465                        AuthorizationDelegate* authorization_delegate) {
11466   VLOG(1) << __func__;
11467   std::string command;
11468   TPM_RC rc = SerializeCommand_Unseal(item_handle, item_handle_name, &command,
11469                                       authorization_delegate);
11470   if (rc != TPM_RC_SUCCESS) {
11471     return rc;
11472   }
11473   std::string response = transceiver_->SendCommandAndWait(command);
11474   rc = ParseResponse_Unseal(response, out_data, authorization_delegate);
11475   return rc;
11476 }
11477 
SerializeCommand_ObjectChangeAuth(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_AUTH & new_auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)11478 TPM_RC Tpm::SerializeCommand_ObjectChangeAuth(
11479     const TPMI_DH_OBJECT& object_handle,
11480     const std::string& object_handle_name,
11481     const TPMI_DH_OBJECT& parent_handle,
11482     const std::string& parent_handle_name,
11483     const TPM2B_AUTH& new_auth,
11484     std::string* serialized_command,
11485     AuthorizationDelegate* authorization_delegate) {
11486   VLOG(3) << __func__;
11487   TPM_RC rc = TPM_RC_SUCCESS;
11488   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11489   UINT32 command_size = 10;  // Header size.
11490   std::string handle_section_bytes;
11491   std::string parameter_section_bytes;
11492   TPM_CC command_code = TPM_CC_ObjectChangeAuth;
11493   bool is_command_parameter_encryption_possible = true;
11494   bool is_response_parameter_encryption_possible = true;
11495   std::string command_code_bytes;
11496   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11497   if (rc != TPM_RC_SUCCESS) {
11498     return rc;
11499   }
11500   std::string object_handle_bytes;
11501   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
11502   if (rc != TPM_RC_SUCCESS) {
11503     return rc;
11504   }
11505   std::string parent_handle_bytes;
11506   rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
11507   if (rc != TPM_RC_SUCCESS) {
11508     return rc;
11509   }
11510   std::string new_auth_bytes;
11511   rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
11512   if (rc != TPM_RC_SUCCESS) {
11513     return rc;
11514   }
11515   if (authorization_delegate) {
11516     // Encrypt just the parameter data, not the size.
11517     std::string tmp = new_auth_bytes.substr(2);
11518     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11519       return TRUNKS_RC_ENCRYPTION_FAILED;
11520     }
11521     new_auth_bytes.replace(2, std::string::npos, tmp);
11522   }
11523   std::unique_ptr<crypto::SecureHash> hash(
11524       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11525   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11526   hash->Update(object_handle_name.data(), object_handle_name.size());
11527   handle_section_bytes += object_handle_bytes;
11528   command_size += object_handle_bytes.size();
11529   hash->Update(parent_handle_name.data(), parent_handle_name.size());
11530   handle_section_bytes += parent_handle_bytes;
11531   command_size += parent_handle_bytes.size();
11532   hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
11533   parameter_section_bytes += new_auth_bytes;
11534   command_size += new_auth_bytes.size();
11535   std::string command_hash(32, 0);
11536   hash->Finish(std::data(command_hash), command_hash.size());
11537   std::string authorization_section_bytes;
11538   std::string authorization_size_bytes;
11539   if (authorization_delegate) {
11540     if (!authorization_delegate->GetCommandAuthorization(
11541             command_hash, is_command_parameter_encryption_possible,
11542             is_response_parameter_encryption_possible,
11543             &authorization_section_bytes)) {
11544       return TRUNKS_RC_AUTHORIZATION_FAILED;
11545     }
11546     if (!authorization_section_bytes.empty()) {
11547       tag = TPM_ST_SESSIONS;
11548       std::string tmp;
11549       rc = Serialize_UINT32(authorization_section_bytes.size(),
11550                             &authorization_size_bytes);
11551       if (rc != TPM_RC_SUCCESS) {
11552         return rc;
11553       }
11554       command_size +=
11555           authorization_size_bytes.size() + authorization_section_bytes.size();
11556     }
11557   }
11558   std::string tag_bytes;
11559   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11560   if (rc != TPM_RC_SUCCESS) {
11561     return rc;
11562   }
11563   std::string command_size_bytes;
11564   rc = Serialize_UINT32(command_size, &command_size_bytes);
11565   if (rc != TPM_RC_SUCCESS) {
11566     return rc;
11567   }
11568   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11569                         handle_section_bytes + authorization_size_bytes +
11570                         authorization_section_bytes + parameter_section_bytes;
11571   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11572   VLOG(2) << "Command: "
11573           << base::HexEncode(serialized_command->data(),
11574                              serialized_command->size());
11575   return TPM_RC_SUCCESS;
11576 }
11577 
ParseResponse_ObjectChangeAuth(const std::string & response,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)11578 TPM_RC Tpm::ParseResponse_ObjectChangeAuth(
11579     const std::string& response,
11580     TPM2B_PRIVATE* out_private,
11581     AuthorizationDelegate* authorization_delegate) {
11582   VLOG(3) << __func__;
11583   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11584   TPM_RC rc = TPM_RC_SUCCESS;
11585   std::string buffer(response);
11586   TPM_ST tag;
11587   std::string tag_bytes;
11588   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11589   if (rc != TPM_RC_SUCCESS) {
11590     return rc;
11591   }
11592   UINT32 response_size;
11593   std::string response_size_bytes;
11594   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11595   if (rc != TPM_RC_SUCCESS) {
11596     return rc;
11597   }
11598   TPM_RC response_code;
11599   std::string response_code_bytes;
11600   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11601   if (rc != TPM_RC_SUCCESS) {
11602     return rc;
11603   }
11604   if (response_size != response.size()) {
11605     return TPM_RC_SIZE;
11606   }
11607   if (response_code != TPM_RC_SUCCESS) {
11608     return response_code;
11609   }
11610   TPM_CC command_code = TPM_CC_ObjectChangeAuth;
11611   std::string command_code_bytes;
11612   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11613   if (rc != TPM_RC_SUCCESS) {
11614     return rc;
11615   }
11616   std::string authorization_section_bytes;
11617   if (tag == TPM_ST_SESSIONS) {
11618     UINT32 parameter_section_size = buffer.size();
11619     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11620     if (rc != TPM_RC_SUCCESS) {
11621       return rc;
11622     }
11623     if (parameter_section_size > buffer.size()) {
11624       return TPM_RC_INSUFFICIENT;
11625     }
11626     authorization_section_bytes = buffer.substr(parameter_section_size);
11627     // Keep the parameter section in |buffer|.
11628     buffer.erase(parameter_section_size);
11629   }
11630   std::unique_ptr<crypto::SecureHash> hash(
11631       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11632   hash->Update(response_code_bytes.data(), response_code_bytes.size());
11633   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11634   hash->Update(buffer.data(), buffer.size());
11635   std::string response_hash(32, 0);
11636   hash->Finish(std::data(response_hash), response_hash.size());
11637   if (tag == TPM_ST_SESSIONS) {
11638     if (!authorization_delegate)
11639       return TRUNKS_RC_AUTHORIZATION_FAILED;
11640     if (!authorization_delegate->CheckResponseAuthorization(
11641             response_hash, authorization_section_bytes)) {
11642       return TRUNKS_RC_AUTHORIZATION_FAILED;
11643     }
11644   }
11645   if (tag == TPM_ST_SESSIONS) {
11646     if (!authorization_delegate)
11647       return TRUNKS_RC_AUTHORIZATION_FAILED;
11648 
11649     // Parse the encrypted parameter size.
11650     UINT16 size;
11651     std::string size_buffer = buffer.substr(0, 2);
11652     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11653       return result;
11654     }
11655     if (buffer.size() < 2 + size) {
11656       return TPM_RC_INSUFFICIENT;
11657     }
11658 
11659     // Decrypt just the parameter data, not the size.
11660     std::string decrypted_data = buffer.substr(2, size);
11661     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11662       return TRUNKS_RC_ENCRYPTION_FAILED;
11663     }
11664     buffer.replace(2, size, decrypted_data);
11665   }
11666   std::string out_private_bytes;
11667   rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
11668   if (rc != TPM_RC_SUCCESS) {
11669     return rc;
11670   }
11671   return TPM_RC_SUCCESS;
11672 }
11673 
ObjectChangeAuthErrorCallback(Tpm::ObjectChangeAuthResponse callback,TPM_RC response_code)11674 void ObjectChangeAuthErrorCallback(Tpm::ObjectChangeAuthResponse callback,
11675                                    TPM_RC response_code) {
11676   VLOG(1) << __func__;
11677   std::move(callback).Run(response_code, TPM2B_PRIVATE());
11678 }
11679 
ObjectChangeAuthResponseParser(Tpm::ObjectChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11680 void ObjectChangeAuthResponseParser(
11681     Tpm::ObjectChangeAuthResponse callback,
11682     AuthorizationDelegate* authorization_delegate,
11683     const std::string& response) {
11684   VLOG(1) << __func__;
11685   TPM2B_PRIVATE out_private;
11686   TPM_RC rc = Tpm::ParseResponse_ObjectChangeAuth(response, &out_private,
11687                                                   authorization_delegate);
11688   if (rc != TPM_RC_SUCCESS) {
11689     base::OnceCallback<void(TPM_RC)> error_reporter =
11690         base::BindOnce(ObjectChangeAuthErrorCallback, std::move(callback));
11691     std::move(error_reporter).Run(rc);
11692     return;
11693   }
11694   std::move(callback).Run(rc, out_private);
11695 }
11696 
ObjectChangeAuth(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate,ObjectChangeAuthResponse callback)11697 void Tpm::ObjectChangeAuth(const TPMI_DH_OBJECT& object_handle,
11698                            const std::string& object_handle_name,
11699                            const TPMI_DH_OBJECT& parent_handle,
11700                            const std::string& parent_handle_name,
11701                            const TPM2B_AUTH& new_auth,
11702                            AuthorizationDelegate* authorization_delegate,
11703                            ObjectChangeAuthResponse callback) {
11704   VLOG(1) << __func__;
11705   std::string command;
11706   TPM_RC rc = SerializeCommand_ObjectChangeAuth(
11707       object_handle, object_handle_name, parent_handle, parent_handle_name,
11708       new_auth, &command, authorization_delegate);
11709   if (rc != TPM_RC_SUCCESS) {
11710     base::OnceCallback<void(TPM_RC)> error_reporter =
11711         base::BindOnce(ObjectChangeAuthErrorCallback, std::move(callback));
11712     std::move(error_reporter).Run(rc);
11713     return;
11714   }
11715   base::OnceCallback<void(const std::string&)> parser =
11716       base::BindOnce(ObjectChangeAuthResponseParser, std::move(callback),
11717                      authorization_delegate);
11718   transceiver_->SendCommand(command, std::move(parser));
11719 }
11720 
ObjectChangeAuthSync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_AUTH & new_auth,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)11721 TPM_RC Tpm::ObjectChangeAuthSync(
11722     const TPMI_DH_OBJECT& object_handle,
11723     const std::string& object_handle_name,
11724     const TPMI_DH_OBJECT& parent_handle,
11725     const std::string& parent_handle_name,
11726     const TPM2B_AUTH& new_auth,
11727     TPM2B_PRIVATE* out_private,
11728     AuthorizationDelegate* authorization_delegate) {
11729   VLOG(1) << __func__;
11730   std::string command;
11731   TPM_RC rc = SerializeCommand_ObjectChangeAuth(
11732       object_handle, object_handle_name, parent_handle, parent_handle_name,
11733       new_auth, &command, authorization_delegate);
11734   if (rc != TPM_RC_SUCCESS) {
11735     return rc;
11736   }
11737   std::string response = transceiver_->SendCommandAndWait(command);
11738   rc = ParseResponse_ObjectChangeAuth(response, out_private,
11739                                       authorization_delegate);
11740   return rc;
11741 }
11742 
SerializeCommand_Duplicate(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & new_parent_handle,const std::string & new_parent_handle_name,const TPM2B_DATA & encryption_key_in,const TPMT_SYM_DEF_OBJECT & symmetric_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)11743 TPM_RC Tpm::SerializeCommand_Duplicate(
11744     const TPMI_DH_OBJECT& object_handle,
11745     const std::string& object_handle_name,
11746     const TPMI_DH_OBJECT& new_parent_handle,
11747     const std::string& new_parent_handle_name,
11748     const TPM2B_DATA& encryption_key_in,
11749     const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11750     std::string* serialized_command,
11751     AuthorizationDelegate* authorization_delegate) {
11752   VLOG(3) << __func__;
11753   TPM_RC rc = TPM_RC_SUCCESS;
11754   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
11755   UINT32 command_size = 10;  // Header size.
11756   std::string handle_section_bytes;
11757   std::string parameter_section_bytes;
11758   TPM_CC command_code = TPM_CC_Duplicate;
11759   bool is_command_parameter_encryption_possible = true;
11760   bool is_response_parameter_encryption_possible = true;
11761   std::string command_code_bytes;
11762   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11763   if (rc != TPM_RC_SUCCESS) {
11764     return rc;
11765   }
11766   std::string object_handle_bytes;
11767   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
11768   if (rc != TPM_RC_SUCCESS) {
11769     return rc;
11770   }
11771   std::string new_parent_handle_bytes;
11772   rc = Serialize_TPMI_DH_OBJECT(new_parent_handle, &new_parent_handle_bytes);
11773   if (rc != TPM_RC_SUCCESS) {
11774     return rc;
11775   }
11776   std::string encryption_key_in_bytes;
11777   rc = Serialize_TPM2B_DATA(encryption_key_in, &encryption_key_in_bytes);
11778   if (rc != TPM_RC_SUCCESS) {
11779     return rc;
11780   }
11781   std::string symmetric_alg_bytes;
11782   rc = Serialize_TPMT_SYM_DEF_OBJECT(symmetric_alg, &symmetric_alg_bytes);
11783   if (rc != TPM_RC_SUCCESS) {
11784     return rc;
11785   }
11786   if (authorization_delegate) {
11787     // Encrypt just the parameter data, not the size.
11788     std::string tmp = encryption_key_in_bytes.substr(2);
11789     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
11790       return TRUNKS_RC_ENCRYPTION_FAILED;
11791     }
11792     encryption_key_in_bytes.replace(2, std::string::npos, tmp);
11793   }
11794   std::unique_ptr<crypto::SecureHash> hash(
11795       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11796   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11797   hash->Update(object_handle_name.data(), object_handle_name.size());
11798   handle_section_bytes += object_handle_bytes;
11799   command_size += object_handle_bytes.size();
11800   hash->Update(new_parent_handle_name.data(), new_parent_handle_name.size());
11801   handle_section_bytes += new_parent_handle_bytes;
11802   command_size += new_parent_handle_bytes.size();
11803   hash->Update(encryption_key_in_bytes.data(), encryption_key_in_bytes.size());
11804   parameter_section_bytes += encryption_key_in_bytes;
11805   command_size += encryption_key_in_bytes.size();
11806   hash->Update(symmetric_alg_bytes.data(), symmetric_alg_bytes.size());
11807   parameter_section_bytes += symmetric_alg_bytes;
11808   command_size += symmetric_alg_bytes.size();
11809   std::string command_hash(32, 0);
11810   hash->Finish(std::data(command_hash), command_hash.size());
11811   std::string authorization_section_bytes;
11812   std::string authorization_size_bytes;
11813   if (authorization_delegate) {
11814     if (!authorization_delegate->GetCommandAuthorization(
11815             command_hash, is_command_parameter_encryption_possible,
11816             is_response_parameter_encryption_possible,
11817             &authorization_section_bytes)) {
11818       return TRUNKS_RC_AUTHORIZATION_FAILED;
11819     }
11820     if (!authorization_section_bytes.empty()) {
11821       tag = TPM_ST_SESSIONS;
11822       std::string tmp;
11823       rc = Serialize_UINT32(authorization_section_bytes.size(),
11824                             &authorization_size_bytes);
11825       if (rc != TPM_RC_SUCCESS) {
11826         return rc;
11827       }
11828       command_size +=
11829           authorization_size_bytes.size() + authorization_section_bytes.size();
11830     }
11831   }
11832   std::string tag_bytes;
11833   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
11834   if (rc != TPM_RC_SUCCESS) {
11835     return rc;
11836   }
11837   std::string command_size_bytes;
11838   rc = Serialize_UINT32(command_size, &command_size_bytes);
11839   if (rc != TPM_RC_SUCCESS) {
11840     return rc;
11841   }
11842   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
11843                         handle_section_bytes + authorization_size_bytes +
11844                         authorization_section_bytes + parameter_section_bytes;
11845   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
11846   VLOG(2) << "Command: "
11847           << base::HexEncode(serialized_command->data(),
11848                              serialized_command->size());
11849   return TPM_RC_SUCCESS;
11850 }
11851 
ParseResponse_Duplicate(const std::string & response,TPM2B_DATA * encryption_key_out,TPM2B_PRIVATE * duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)11852 TPM_RC Tpm::ParseResponse_Duplicate(
11853     const std::string& response,
11854     TPM2B_DATA* encryption_key_out,
11855     TPM2B_PRIVATE* duplicate,
11856     TPM2B_ENCRYPTED_SECRET* out_sym_seed,
11857     AuthorizationDelegate* authorization_delegate) {
11858   VLOG(3) << __func__;
11859   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
11860   TPM_RC rc = TPM_RC_SUCCESS;
11861   std::string buffer(response);
11862   TPM_ST tag;
11863   std::string tag_bytes;
11864   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
11865   if (rc != TPM_RC_SUCCESS) {
11866     return rc;
11867   }
11868   UINT32 response_size;
11869   std::string response_size_bytes;
11870   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
11871   if (rc != TPM_RC_SUCCESS) {
11872     return rc;
11873   }
11874   TPM_RC response_code;
11875   std::string response_code_bytes;
11876   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
11877   if (rc != TPM_RC_SUCCESS) {
11878     return rc;
11879   }
11880   if (response_size != response.size()) {
11881     return TPM_RC_SIZE;
11882   }
11883   if (response_code != TPM_RC_SUCCESS) {
11884     return response_code;
11885   }
11886   TPM_CC command_code = TPM_CC_Duplicate;
11887   std::string command_code_bytes;
11888   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
11889   if (rc != TPM_RC_SUCCESS) {
11890     return rc;
11891   }
11892   std::string authorization_section_bytes;
11893   if (tag == TPM_ST_SESSIONS) {
11894     UINT32 parameter_section_size = buffer.size();
11895     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
11896     if (rc != TPM_RC_SUCCESS) {
11897       return rc;
11898     }
11899     if (parameter_section_size > buffer.size()) {
11900       return TPM_RC_INSUFFICIENT;
11901     }
11902     authorization_section_bytes = buffer.substr(parameter_section_size);
11903     // Keep the parameter section in |buffer|.
11904     buffer.erase(parameter_section_size);
11905   }
11906   std::unique_ptr<crypto::SecureHash> hash(
11907       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
11908   hash->Update(response_code_bytes.data(), response_code_bytes.size());
11909   hash->Update(command_code_bytes.data(), command_code_bytes.size());
11910   hash->Update(buffer.data(), buffer.size());
11911   std::string response_hash(32, 0);
11912   hash->Finish(std::data(response_hash), response_hash.size());
11913   if (tag == TPM_ST_SESSIONS) {
11914     if (!authorization_delegate)
11915       return TRUNKS_RC_AUTHORIZATION_FAILED;
11916     if (!authorization_delegate->CheckResponseAuthorization(
11917             response_hash, authorization_section_bytes)) {
11918       return TRUNKS_RC_AUTHORIZATION_FAILED;
11919     }
11920   }
11921   if (tag == TPM_ST_SESSIONS) {
11922     if (!authorization_delegate)
11923       return TRUNKS_RC_AUTHORIZATION_FAILED;
11924 
11925     // Parse the encrypted parameter size.
11926     UINT16 size;
11927     std::string size_buffer = buffer.substr(0, 2);
11928     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
11929       return result;
11930     }
11931     if (buffer.size() < 2 + size) {
11932       return TPM_RC_INSUFFICIENT;
11933     }
11934 
11935     // Decrypt just the parameter data, not the size.
11936     std::string decrypted_data = buffer.substr(2, size);
11937     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
11938       return TRUNKS_RC_ENCRYPTION_FAILED;
11939     }
11940     buffer.replace(2, size, decrypted_data);
11941   }
11942   std::string encryption_key_out_bytes;
11943   rc = Parse_TPM2B_DATA(&buffer, encryption_key_out, &encryption_key_out_bytes);
11944   if (rc != TPM_RC_SUCCESS) {
11945     return rc;
11946   }
11947   std::string duplicate_bytes;
11948   rc = Parse_TPM2B_PRIVATE(&buffer, duplicate, &duplicate_bytes);
11949   if (rc != TPM_RC_SUCCESS) {
11950     return rc;
11951   }
11952   std::string out_sym_seed_bytes;
11953   rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, out_sym_seed, &out_sym_seed_bytes);
11954   if (rc != TPM_RC_SUCCESS) {
11955     return rc;
11956   }
11957   return TPM_RC_SUCCESS;
11958 }
11959 
DuplicateErrorCallback(Tpm::DuplicateResponse callback,TPM_RC response_code)11960 void DuplicateErrorCallback(Tpm::DuplicateResponse callback,
11961                             TPM_RC response_code) {
11962   VLOG(1) << __func__;
11963   std::move(callback).Run(response_code, TPM2B_DATA(), TPM2B_PRIVATE(),
11964                           TPM2B_ENCRYPTED_SECRET());
11965 }
11966 
DuplicateResponseParser(Tpm::DuplicateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)11967 void DuplicateResponseParser(Tpm::DuplicateResponse callback,
11968                              AuthorizationDelegate* authorization_delegate,
11969                              const std::string& response) {
11970   VLOG(1) << __func__;
11971   TPM2B_DATA encryption_key_out;
11972   TPM2B_PRIVATE duplicate;
11973   TPM2B_ENCRYPTED_SECRET out_sym_seed;
11974   TPM_RC rc =
11975       Tpm::ParseResponse_Duplicate(response, &encryption_key_out, &duplicate,
11976                                    &out_sym_seed, authorization_delegate);
11977   if (rc != TPM_RC_SUCCESS) {
11978     base::OnceCallback<void(TPM_RC)> error_reporter =
11979         base::BindOnce(DuplicateErrorCallback, std::move(callback));
11980     std::move(error_reporter).Run(rc);
11981     return;
11982   }
11983   std::move(callback).Run(rc, encryption_key_out, duplicate, out_sym_seed);
11984 }
11985 
Duplicate(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & new_parent_handle,const std::string & new_parent_handle_name,const TPM2B_DATA & encryption_key_in,const TPMT_SYM_DEF_OBJECT & symmetric_alg,AuthorizationDelegate * authorization_delegate,DuplicateResponse callback)11986 void Tpm::Duplicate(const TPMI_DH_OBJECT& object_handle,
11987                     const std::string& object_handle_name,
11988                     const TPMI_DH_OBJECT& new_parent_handle,
11989                     const std::string& new_parent_handle_name,
11990                     const TPM2B_DATA& encryption_key_in,
11991                     const TPMT_SYM_DEF_OBJECT& symmetric_alg,
11992                     AuthorizationDelegate* authorization_delegate,
11993                     DuplicateResponse callback) {
11994   VLOG(1) << __func__;
11995   std::string command;
11996   TPM_RC rc = SerializeCommand_Duplicate(
11997       object_handle, object_handle_name, new_parent_handle,
11998       new_parent_handle_name, encryption_key_in, symmetric_alg, &command,
11999       authorization_delegate);
12000   if (rc != TPM_RC_SUCCESS) {
12001     base::OnceCallback<void(TPM_RC)> error_reporter =
12002         base::BindOnce(DuplicateErrorCallback, std::move(callback));
12003     std::move(error_reporter).Run(rc);
12004     return;
12005   }
12006   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12007       DuplicateResponseParser, std::move(callback), authorization_delegate);
12008   transceiver_->SendCommand(command, std::move(parser));
12009 }
12010 
DuplicateSync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & new_parent_handle,const std::string & new_parent_handle_name,const TPM2B_DATA & encryption_key_in,const TPMT_SYM_DEF_OBJECT & symmetric_alg,TPM2B_DATA * encryption_key_out,TPM2B_PRIVATE * duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)12011 TPM_RC Tpm::DuplicateSync(const TPMI_DH_OBJECT& object_handle,
12012                           const std::string& object_handle_name,
12013                           const TPMI_DH_OBJECT& new_parent_handle,
12014                           const std::string& new_parent_handle_name,
12015                           const TPM2B_DATA& encryption_key_in,
12016                           const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12017                           TPM2B_DATA* encryption_key_out,
12018                           TPM2B_PRIVATE* duplicate,
12019                           TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12020                           AuthorizationDelegate* authorization_delegate) {
12021   VLOG(1) << __func__;
12022   std::string command;
12023   TPM_RC rc = SerializeCommand_Duplicate(
12024       object_handle, object_handle_name, new_parent_handle,
12025       new_parent_handle_name, encryption_key_in, symmetric_alg, &command,
12026       authorization_delegate);
12027   if (rc != TPM_RC_SUCCESS) {
12028     return rc;
12029   }
12030   std::string response = transceiver_->SendCommandAndWait(command);
12031   rc = ParseResponse_Duplicate(response, encryption_key_out, duplicate,
12032                                out_sym_seed, authorization_delegate);
12033   return rc;
12034 }
12035 
SerializeCommand_Rewrap(const TPMI_DH_OBJECT & old_parent,const std::string & old_parent_name,const TPMI_DH_OBJECT & new_parent,const std::string & new_parent_name,const TPM2B_PRIVATE & in_duplicate,const TPM2B_NAME & name,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12036 TPM_RC Tpm::SerializeCommand_Rewrap(
12037     const TPMI_DH_OBJECT& old_parent,
12038     const std::string& old_parent_name,
12039     const TPMI_DH_OBJECT& new_parent,
12040     const std::string& new_parent_name,
12041     const TPM2B_PRIVATE& in_duplicate,
12042     const TPM2B_NAME& name,
12043     const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12044     std::string* serialized_command,
12045     AuthorizationDelegate* authorization_delegate) {
12046   VLOG(3) << __func__;
12047   TPM_RC rc = TPM_RC_SUCCESS;
12048   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12049   UINT32 command_size = 10;  // Header size.
12050   std::string handle_section_bytes;
12051   std::string parameter_section_bytes;
12052   TPM_CC command_code = TPM_CC_Rewrap;
12053   bool is_command_parameter_encryption_possible = true;
12054   bool is_response_parameter_encryption_possible = true;
12055   std::string command_code_bytes;
12056   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12057   if (rc != TPM_RC_SUCCESS) {
12058     return rc;
12059   }
12060   std::string old_parent_bytes;
12061   rc = Serialize_TPMI_DH_OBJECT(old_parent, &old_parent_bytes);
12062   if (rc != TPM_RC_SUCCESS) {
12063     return rc;
12064   }
12065   std::string new_parent_bytes;
12066   rc = Serialize_TPMI_DH_OBJECT(new_parent, &new_parent_bytes);
12067   if (rc != TPM_RC_SUCCESS) {
12068     return rc;
12069   }
12070   std::string in_duplicate_bytes;
12071   rc = Serialize_TPM2B_PRIVATE(in_duplicate, &in_duplicate_bytes);
12072   if (rc != TPM_RC_SUCCESS) {
12073     return rc;
12074   }
12075   std::string name_bytes;
12076   rc = Serialize_TPM2B_NAME(name, &name_bytes);
12077   if (rc != TPM_RC_SUCCESS) {
12078     return rc;
12079   }
12080   std::string in_sym_seed_bytes;
12081   rc = Serialize_TPM2B_ENCRYPTED_SECRET(in_sym_seed, &in_sym_seed_bytes);
12082   if (rc != TPM_RC_SUCCESS) {
12083     return rc;
12084   }
12085   if (authorization_delegate) {
12086     // Encrypt just the parameter data, not the size.
12087     std::string tmp = in_duplicate_bytes.substr(2);
12088     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12089       return TRUNKS_RC_ENCRYPTION_FAILED;
12090     }
12091     in_duplicate_bytes.replace(2, std::string::npos, tmp);
12092   }
12093   std::unique_ptr<crypto::SecureHash> hash(
12094       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12095   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12096   hash->Update(old_parent_name.data(), old_parent_name.size());
12097   handle_section_bytes += old_parent_bytes;
12098   command_size += old_parent_bytes.size();
12099   hash->Update(new_parent_name.data(), new_parent_name.size());
12100   handle_section_bytes += new_parent_bytes;
12101   command_size += new_parent_bytes.size();
12102   hash->Update(in_duplicate_bytes.data(), in_duplicate_bytes.size());
12103   parameter_section_bytes += in_duplicate_bytes;
12104   command_size += in_duplicate_bytes.size();
12105   hash->Update(name_bytes.data(), name_bytes.size());
12106   parameter_section_bytes += name_bytes;
12107   command_size += name_bytes.size();
12108   hash->Update(in_sym_seed_bytes.data(), in_sym_seed_bytes.size());
12109   parameter_section_bytes += in_sym_seed_bytes;
12110   command_size += in_sym_seed_bytes.size();
12111   std::string command_hash(32, 0);
12112   hash->Finish(std::data(command_hash), command_hash.size());
12113   std::string authorization_section_bytes;
12114   std::string authorization_size_bytes;
12115   if (authorization_delegate) {
12116     if (!authorization_delegate->GetCommandAuthorization(
12117             command_hash, is_command_parameter_encryption_possible,
12118             is_response_parameter_encryption_possible,
12119             &authorization_section_bytes)) {
12120       return TRUNKS_RC_AUTHORIZATION_FAILED;
12121     }
12122     if (!authorization_section_bytes.empty()) {
12123       tag = TPM_ST_SESSIONS;
12124       std::string tmp;
12125       rc = Serialize_UINT32(authorization_section_bytes.size(),
12126                             &authorization_size_bytes);
12127       if (rc != TPM_RC_SUCCESS) {
12128         return rc;
12129       }
12130       command_size +=
12131           authorization_size_bytes.size() + authorization_section_bytes.size();
12132     }
12133   }
12134   std::string tag_bytes;
12135   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12136   if (rc != TPM_RC_SUCCESS) {
12137     return rc;
12138   }
12139   std::string command_size_bytes;
12140   rc = Serialize_UINT32(command_size, &command_size_bytes);
12141   if (rc != TPM_RC_SUCCESS) {
12142     return rc;
12143   }
12144   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12145                         handle_section_bytes + authorization_size_bytes +
12146                         authorization_section_bytes + parameter_section_bytes;
12147   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12148   VLOG(2) << "Command: "
12149           << base::HexEncode(serialized_command->data(),
12150                              serialized_command->size());
12151   return TPM_RC_SUCCESS;
12152 }
12153 
ParseResponse_Rewrap(const std::string & response,TPM2B_PRIVATE * out_duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)12154 TPM_RC Tpm::ParseResponse_Rewrap(
12155     const std::string& response,
12156     TPM2B_PRIVATE* out_duplicate,
12157     TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12158     AuthorizationDelegate* authorization_delegate) {
12159   VLOG(3) << __func__;
12160   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12161   TPM_RC rc = TPM_RC_SUCCESS;
12162   std::string buffer(response);
12163   TPM_ST tag;
12164   std::string tag_bytes;
12165   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12166   if (rc != TPM_RC_SUCCESS) {
12167     return rc;
12168   }
12169   UINT32 response_size;
12170   std::string response_size_bytes;
12171   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12172   if (rc != TPM_RC_SUCCESS) {
12173     return rc;
12174   }
12175   TPM_RC response_code;
12176   std::string response_code_bytes;
12177   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12178   if (rc != TPM_RC_SUCCESS) {
12179     return rc;
12180   }
12181   if (response_size != response.size()) {
12182     return TPM_RC_SIZE;
12183   }
12184   if (response_code != TPM_RC_SUCCESS) {
12185     return response_code;
12186   }
12187   TPM_CC command_code = TPM_CC_Rewrap;
12188   std::string command_code_bytes;
12189   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12190   if (rc != TPM_RC_SUCCESS) {
12191     return rc;
12192   }
12193   std::string authorization_section_bytes;
12194   if (tag == TPM_ST_SESSIONS) {
12195     UINT32 parameter_section_size = buffer.size();
12196     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
12197     if (rc != TPM_RC_SUCCESS) {
12198       return rc;
12199     }
12200     if (parameter_section_size > buffer.size()) {
12201       return TPM_RC_INSUFFICIENT;
12202     }
12203     authorization_section_bytes = buffer.substr(parameter_section_size);
12204     // Keep the parameter section in |buffer|.
12205     buffer.erase(parameter_section_size);
12206   }
12207   std::unique_ptr<crypto::SecureHash> hash(
12208       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12209   hash->Update(response_code_bytes.data(), response_code_bytes.size());
12210   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12211   hash->Update(buffer.data(), buffer.size());
12212   std::string response_hash(32, 0);
12213   hash->Finish(std::data(response_hash), response_hash.size());
12214   if (tag == TPM_ST_SESSIONS) {
12215     if (!authorization_delegate)
12216       return TRUNKS_RC_AUTHORIZATION_FAILED;
12217     if (!authorization_delegate->CheckResponseAuthorization(
12218             response_hash, authorization_section_bytes)) {
12219       return TRUNKS_RC_AUTHORIZATION_FAILED;
12220     }
12221   }
12222   if (tag == TPM_ST_SESSIONS) {
12223     if (!authorization_delegate)
12224       return TRUNKS_RC_AUTHORIZATION_FAILED;
12225 
12226     // Parse the encrypted parameter size.
12227     UINT16 size;
12228     std::string size_buffer = buffer.substr(0, 2);
12229     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12230       return result;
12231     }
12232     if (buffer.size() < 2 + size) {
12233       return TPM_RC_INSUFFICIENT;
12234     }
12235 
12236     // Decrypt just the parameter data, not the size.
12237     std::string decrypted_data = buffer.substr(2, size);
12238     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12239       return TRUNKS_RC_ENCRYPTION_FAILED;
12240     }
12241     buffer.replace(2, size, decrypted_data);
12242   }
12243   std::string out_duplicate_bytes;
12244   rc = Parse_TPM2B_PRIVATE(&buffer, out_duplicate, &out_duplicate_bytes);
12245   if (rc != TPM_RC_SUCCESS) {
12246     return rc;
12247   }
12248   std::string out_sym_seed_bytes;
12249   rc = Parse_TPM2B_ENCRYPTED_SECRET(&buffer, out_sym_seed, &out_sym_seed_bytes);
12250   if (rc != TPM_RC_SUCCESS) {
12251     return rc;
12252   }
12253   return TPM_RC_SUCCESS;
12254 }
12255 
RewrapErrorCallback(Tpm::RewrapResponse callback,TPM_RC response_code)12256 void RewrapErrorCallback(Tpm::RewrapResponse callback, TPM_RC response_code) {
12257   VLOG(1) << __func__;
12258   std::move(callback).Run(response_code, TPM2B_PRIVATE(),
12259                           TPM2B_ENCRYPTED_SECRET());
12260 }
12261 
RewrapResponseParser(Tpm::RewrapResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12262 void RewrapResponseParser(Tpm::RewrapResponse callback,
12263                           AuthorizationDelegate* authorization_delegate,
12264                           const std::string& response) {
12265   VLOG(1) << __func__;
12266   TPM2B_PRIVATE out_duplicate;
12267   TPM2B_ENCRYPTED_SECRET out_sym_seed;
12268   TPM_RC rc = Tpm::ParseResponse_Rewrap(response, &out_duplicate, &out_sym_seed,
12269                                         authorization_delegate);
12270   if (rc != TPM_RC_SUCCESS) {
12271     base::OnceCallback<void(TPM_RC)> error_reporter =
12272         base::BindOnce(RewrapErrorCallback, std::move(callback));
12273     std::move(error_reporter).Run(rc);
12274     return;
12275   }
12276   std::move(callback).Run(rc, out_duplicate, out_sym_seed);
12277 }
12278 
Rewrap(const TPMI_DH_OBJECT & old_parent,const std::string & old_parent_name,const TPMI_DH_OBJECT & new_parent,const std::string & new_parent_name,const TPM2B_PRIVATE & in_duplicate,const TPM2B_NAME & name,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,AuthorizationDelegate * authorization_delegate,RewrapResponse callback)12279 void Tpm::Rewrap(const TPMI_DH_OBJECT& old_parent,
12280                  const std::string& old_parent_name,
12281                  const TPMI_DH_OBJECT& new_parent,
12282                  const std::string& new_parent_name,
12283                  const TPM2B_PRIVATE& in_duplicate,
12284                  const TPM2B_NAME& name,
12285                  const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12286                  AuthorizationDelegate* authorization_delegate,
12287                  RewrapResponse callback) {
12288   VLOG(1) << __func__;
12289   std::string command;
12290   TPM_RC rc = SerializeCommand_Rewrap(
12291       old_parent, old_parent_name, new_parent, new_parent_name, in_duplicate,
12292       name, in_sym_seed, &command, authorization_delegate);
12293   if (rc != TPM_RC_SUCCESS) {
12294     base::OnceCallback<void(TPM_RC)> error_reporter =
12295         base::BindOnce(RewrapErrorCallback, std::move(callback));
12296     std::move(error_reporter).Run(rc);
12297     return;
12298   }
12299   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12300       RewrapResponseParser, std::move(callback), authorization_delegate);
12301   transceiver_->SendCommand(command, std::move(parser));
12302 }
12303 
RewrapSync(const TPMI_DH_OBJECT & old_parent,const std::string & old_parent_name,const TPMI_DH_OBJECT & new_parent,const std::string & new_parent_name,const TPM2B_PRIVATE & in_duplicate,const TPM2B_NAME & name,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,TPM2B_PRIVATE * out_duplicate,TPM2B_ENCRYPTED_SECRET * out_sym_seed,AuthorizationDelegate * authorization_delegate)12304 TPM_RC Tpm::RewrapSync(const TPMI_DH_OBJECT& old_parent,
12305                        const std::string& old_parent_name,
12306                        const TPMI_DH_OBJECT& new_parent,
12307                        const std::string& new_parent_name,
12308                        const TPM2B_PRIVATE& in_duplicate,
12309                        const TPM2B_NAME& name,
12310                        const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12311                        TPM2B_PRIVATE* out_duplicate,
12312                        TPM2B_ENCRYPTED_SECRET* out_sym_seed,
12313                        AuthorizationDelegate* authorization_delegate) {
12314   VLOG(1) << __func__;
12315   std::string command;
12316   TPM_RC rc = SerializeCommand_Rewrap(
12317       old_parent, old_parent_name, new_parent, new_parent_name, in_duplicate,
12318       name, in_sym_seed, &command, authorization_delegate);
12319   if (rc != TPM_RC_SUCCESS) {
12320     return rc;
12321   }
12322   std::string response = transceiver_->SendCommandAndWait(command);
12323   rc = ParseResponse_Rewrap(response, out_duplicate, out_sym_seed,
12324                             authorization_delegate);
12325   return rc;
12326 }
12327 
SerializeCommand_Import(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_DATA & encryption_key,const TPM2B_PUBLIC & object_public,const TPM2B_PRIVATE & duplicate,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,const TPMT_SYM_DEF_OBJECT & symmetric_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12328 TPM_RC Tpm::SerializeCommand_Import(
12329     const TPMI_DH_OBJECT& parent_handle,
12330     const std::string& parent_handle_name,
12331     const TPM2B_DATA& encryption_key,
12332     const TPM2B_PUBLIC& object_public,
12333     const TPM2B_PRIVATE& duplicate,
12334     const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12335     const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12336     std::string* serialized_command,
12337     AuthorizationDelegate* authorization_delegate) {
12338   VLOG(3) << __func__;
12339   TPM_RC rc = TPM_RC_SUCCESS;
12340   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12341   UINT32 command_size = 10;  // Header size.
12342   std::string handle_section_bytes;
12343   std::string parameter_section_bytes;
12344   TPM_CC command_code = TPM_CC_Import;
12345   bool is_command_parameter_encryption_possible = true;
12346   bool is_response_parameter_encryption_possible = true;
12347   std::string command_code_bytes;
12348   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12349   if (rc != TPM_RC_SUCCESS) {
12350     return rc;
12351   }
12352   std::string parent_handle_bytes;
12353   rc = Serialize_TPMI_DH_OBJECT(parent_handle, &parent_handle_bytes);
12354   if (rc != TPM_RC_SUCCESS) {
12355     return rc;
12356   }
12357   std::string encryption_key_bytes;
12358   rc = Serialize_TPM2B_DATA(encryption_key, &encryption_key_bytes);
12359   if (rc != TPM_RC_SUCCESS) {
12360     return rc;
12361   }
12362   std::string object_public_bytes;
12363   rc = Serialize_TPM2B_PUBLIC(object_public, &object_public_bytes);
12364   if (rc != TPM_RC_SUCCESS) {
12365     return rc;
12366   }
12367   std::string duplicate_bytes;
12368   rc = Serialize_TPM2B_PRIVATE(duplicate, &duplicate_bytes);
12369   if (rc != TPM_RC_SUCCESS) {
12370     return rc;
12371   }
12372   std::string in_sym_seed_bytes;
12373   rc = Serialize_TPM2B_ENCRYPTED_SECRET(in_sym_seed, &in_sym_seed_bytes);
12374   if (rc != TPM_RC_SUCCESS) {
12375     return rc;
12376   }
12377   std::string symmetric_alg_bytes;
12378   rc = Serialize_TPMT_SYM_DEF_OBJECT(symmetric_alg, &symmetric_alg_bytes);
12379   if (rc != TPM_RC_SUCCESS) {
12380     return rc;
12381   }
12382   if (authorization_delegate) {
12383     // Encrypt just the parameter data, not the size.
12384     std::string tmp = encryption_key_bytes.substr(2);
12385     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12386       return TRUNKS_RC_ENCRYPTION_FAILED;
12387     }
12388     encryption_key_bytes.replace(2, std::string::npos, tmp);
12389   }
12390   std::unique_ptr<crypto::SecureHash> hash(
12391       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12392   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12393   hash->Update(parent_handle_name.data(), parent_handle_name.size());
12394   handle_section_bytes += parent_handle_bytes;
12395   command_size += parent_handle_bytes.size();
12396   hash->Update(encryption_key_bytes.data(), encryption_key_bytes.size());
12397   parameter_section_bytes += encryption_key_bytes;
12398   command_size += encryption_key_bytes.size();
12399   hash->Update(object_public_bytes.data(), object_public_bytes.size());
12400   parameter_section_bytes += object_public_bytes;
12401   command_size += object_public_bytes.size();
12402   hash->Update(duplicate_bytes.data(), duplicate_bytes.size());
12403   parameter_section_bytes += duplicate_bytes;
12404   command_size += duplicate_bytes.size();
12405   hash->Update(in_sym_seed_bytes.data(), in_sym_seed_bytes.size());
12406   parameter_section_bytes += in_sym_seed_bytes;
12407   command_size += in_sym_seed_bytes.size();
12408   hash->Update(symmetric_alg_bytes.data(), symmetric_alg_bytes.size());
12409   parameter_section_bytes += symmetric_alg_bytes;
12410   command_size += symmetric_alg_bytes.size();
12411   std::string command_hash(32, 0);
12412   hash->Finish(std::data(command_hash), command_hash.size());
12413   std::string authorization_section_bytes;
12414   std::string authorization_size_bytes;
12415   if (authorization_delegate) {
12416     if (!authorization_delegate->GetCommandAuthorization(
12417             command_hash, is_command_parameter_encryption_possible,
12418             is_response_parameter_encryption_possible,
12419             &authorization_section_bytes)) {
12420       return TRUNKS_RC_AUTHORIZATION_FAILED;
12421     }
12422     if (!authorization_section_bytes.empty()) {
12423       tag = TPM_ST_SESSIONS;
12424       std::string tmp;
12425       rc = Serialize_UINT32(authorization_section_bytes.size(),
12426                             &authorization_size_bytes);
12427       if (rc != TPM_RC_SUCCESS) {
12428         return rc;
12429       }
12430       command_size +=
12431           authorization_size_bytes.size() + authorization_section_bytes.size();
12432     }
12433   }
12434   std::string tag_bytes;
12435   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12436   if (rc != TPM_RC_SUCCESS) {
12437     return rc;
12438   }
12439   std::string command_size_bytes;
12440   rc = Serialize_UINT32(command_size, &command_size_bytes);
12441   if (rc != TPM_RC_SUCCESS) {
12442     return rc;
12443   }
12444   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12445                         handle_section_bytes + authorization_size_bytes +
12446                         authorization_section_bytes + parameter_section_bytes;
12447   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12448   VLOG(2) << "Command: "
12449           << base::HexEncode(serialized_command->data(),
12450                              serialized_command->size());
12451   return TPM_RC_SUCCESS;
12452 }
12453 
ParseResponse_Import(const std::string & response,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)12454 TPM_RC Tpm::ParseResponse_Import(
12455     const std::string& response,
12456     TPM2B_PRIVATE* out_private,
12457     AuthorizationDelegate* authorization_delegate) {
12458   VLOG(3) << __func__;
12459   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12460   TPM_RC rc = TPM_RC_SUCCESS;
12461   std::string buffer(response);
12462   TPM_ST tag;
12463   std::string tag_bytes;
12464   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12465   if (rc != TPM_RC_SUCCESS) {
12466     return rc;
12467   }
12468   UINT32 response_size;
12469   std::string response_size_bytes;
12470   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12471   if (rc != TPM_RC_SUCCESS) {
12472     return rc;
12473   }
12474   TPM_RC response_code;
12475   std::string response_code_bytes;
12476   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12477   if (rc != TPM_RC_SUCCESS) {
12478     return rc;
12479   }
12480   if (response_size != response.size()) {
12481     return TPM_RC_SIZE;
12482   }
12483   if (response_code != TPM_RC_SUCCESS) {
12484     return response_code;
12485   }
12486   TPM_CC command_code = TPM_CC_Import;
12487   std::string command_code_bytes;
12488   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12489   if (rc != TPM_RC_SUCCESS) {
12490     return rc;
12491   }
12492   std::string authorization_section_bytes;
12493   if (tag == TPM_ST_SESSIONS) {
12494     UINT32 parameter_section_size = buffer.size();
12495     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
12496     if (rc != TPM_RC_SUCCESS) {
12497       return rc;
12498     }
12499     if (parameter_section_size > buffer.size()) {
12500       return TPM_RC_INSUFFICIENT;
12501     }
12502     authorization_section_bytes = buffer.substr(parameter_section_size);
12503     // Keep the parameter section in |buffer|.
12504     buffer.erase(parameter_section_size);
12505   }
12506   std::unique_ptr<crypto::SecureHash> hash(
12507       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12508   hash->Update(response_code_bytes.data(), response_code_bytes.size());
12509   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12510   hash->Update(buffer.data(), buffer.size());
12511   std::string response_hash(32, 0);
12512   hash->Finish(std::data(response_hash), response_hash.size());
12513   if (tag == TPM_ST_SESSIONS) {
12514     if (!authorization_delegate)
12515       return TRUNKS_RC_AUTHORIZATION_FAILED;
12516     if (!authorization_delegate->CheckResponseAuthorization(
12517             response_hash, authorization_section_bytes)) {
12518       return TRUNKS_RC_AUTHORIZATION_FAILED;
12519     }
12520   }
12521   if (tag == TPM_ST_SESSIONS) {
12522     if (!authorization_delegate)
12523       return TRUNKS_RC_AUTHORIZATION_FAILED;
12524 
12525     // Parse the encrypted parameter size.
12526     UINT16 size;
12527     std::string size_buffer = buffer.substr(0, 2);
12528     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12529       return result;
12530     }
12531     if (buffer.size() < 2 + size) {
12532       return TPM_RC_INSUFFICIENT;
12533     }
12534 
12535     // Decrypt just the parameter data, not the size.
12536     std::string decrypted_data = buffer.substr(2, size);
12537     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12538       return TRUNKS_RC_ENCRYPTION_FAILED;
12539     }
12540     buffer.replace(2, size, decrypted_data);
12541   }
12542   std::string out_private_bytes;
12543   rc = Parse_TPM2B_PRIVATE(&buffer, out_private, &out_private_bytes);
12544   if (rc != TPM_RC_SUCCESS) {
12545     return rc;
12546   }
12547   return TPM_RC_SUCCESS;
12548 }
12549 
ImportErrorCallback(Tpm::ImportResponse callback,TPM_RC response_code)12550 void ImportErrorCallback(Tpm::ImportResponse callback, TPM_RC response_code) {
12551   VLOG(1) << __func__;
12552   std::move(callback).Run(response_code, TPM2B_PRIVATE());
12553 }
12554 
ImportResponseParser(Tpm::ImportResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12555 void ImportResponseParser(Tpm::ImportResponse callback,
12556                           AuthorizationDelegate* authorization_delegate,
12557                           const std::string& response) {
12558   VLOG(1) << __func__;
12559   TPM2B_PRIVATE out_private;
12560   TPM_RC rc =
12561       Tpm::ParseResponse_Import(response, &out_private, authorization_delegate);
12562   if (rc != TPM_RC_SUCCESS) {
12563     base::OnceCallback<void(TPM_RC)> error_reporter =
12564         base::BindOnce(ImportErrorCallback, std::move(callback));
12565     std::move(error_reporter).Run(rc);
12566     return;
12567   }
12568   std::move(callback).Run(rc, out_private);
12569 }
12570 
Import(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_DATA & encryption_key,const TPM2B_PUBLIC & object_public,const TPM2B_PRIVATE & duplicate,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,const TPMT_SYM_DEF_OBJECT & symmetric_alg,AuthorizationDelegate * authorization_delegate,ImportResponse callback)12571 void Tpm::Import(const TPMI_DH_OBJECT& parent_handle,
12572                  const std::string& parent_handle_name,
12573                  const TPM2B_DATA& encryption_key,
12574                  const TPM2B_PUBLIC& object_public,
12575                  const TPM2B_PRIVATE& duplicate,
12576                  const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12577                  const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12578                  AuthorizationDelegate* authorization_delegate,
12579                  ImportResponse callback) {
12580   VLOG(1) << __func__;
12581   std::string command;
12582   TPM_RC rc = SerializeCommand_Import(
12583       parent_handle, parent_handle_name, encryption_key, object_public,
12584       duplicate, in_sym_seed, symmetric_alg, &command, authorization_delegate);
12585   if (rc != TPM_RC_SUCCESS) {
12586     base::OnceCallback<void(TPM_RC)> error_reporter =
12587         base::BindOnce(ImportErrorCallback, std::move(callback));
12588     std::move(error_reporter).Run(rc);
12589     return;
12590   }
12591   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12592       ImportResponseParser, std::move(callback), authorization_delegate);
12593   transceiver_->SendCommand(command, std::move(parser));
12594 }
12595 
ImportSync(const TPMI_DH_OBJECT & parent_handle,const std::string & parent_handle_name,const TPM2B_DATA & encryption_key,const TPM2B_PUBLIC & object_public,const TPM2B_PRIVATE & duplicate,const TPM2B_ENCRYPTED_SECRET & in_sym_seed,const TPMT_SYM_DEF_OBJECT & symmetric_alg,TPM2B_PRIVATE * out_private,AuthorizationDelegate * authorization_delegate)12596 TPM_RC Tpm::ImportSync(const TPMI_DH_OBJECT& parent_handle,
12597                        const std::string& parent_handle_name,
12598                        const TPM2B_DATA& encryption_key,
12599                        const TPM2B_PUBLIC& object_public,
12600                        const TPM2B_PRIVATE& duplicate,
12601                        const TPM2B_ENCRYPTED_SECRET& in_sym_seed,
12602                        const TPMT_SYM_DEF_OBJECT& symmetric_alg,
12603                        TPM2B_PRIVATE* out_private,
12604                        AuthorizationDelegate* authorization_delegate) {
12605   VLOG(1) << __func__;
12606   std::string command;
12607   TPM_RC rc = SerializeCommand_Import(
12608       parent_handle, parent_handle_name, encryption_key, object_public,
12609       duplicate, in_sym_seed, symmetric_alg, &command, authorization_delegate);
12610   if (rc != TPM_RC_SUCCESS) {
12611     return rc;
12612   }
12613   std::string response = transceiver_->SendCommandAndWait(command);
12614   rc = ParseResponse_Import(response, out_private, authorization_delegate);
12615   return rc;
12616 }
12617 
SerializeCommand_RSA_Encrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & message,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12618 TPM_RC Tpm::SerializeCommand_RSA_Encrypt(
12619     const TPMI_DH_OBJECT& key_handle,
12620     const std::string& key_handle_name,
12621     const TPM2B_PUBLIC_KEY_RSA& message,
12622     const TPMT_RSA_DECRYPT& in_scheme,
12623     const TPM2B_DATA& label,
12624     std::string* serialized_command,
12625     AuthorizationDelegate* authorization_delegate) {
12626   VLOG(3) << __func__;
12627   TPM_RC rc = TPM_RC_SUCCESS;
12628   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12629   UINT32 command_size = 10;  // Header size.
12630   std::string handle_section_bytes;
12631   std::string parameter_section_bytes;
12632   TPM_CC command_code = TPM_CC_RSA_Encrypt;
12633   bool is_command_parameter_encryption_possible = true;
12634   bool is_response_parameter_encryption_possible = true;
12635   std::string command_code_bytes;
12636   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12637   if (rc != TPM_RC_SUCCESS) {
12638     return rc;
12639   }
12640   std::string key_handle_bytes;
12641   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
12642   if (rc != TPM_RC_SUCCESS) {
12643     return rc;
12644   }
12645   std::string message_bytes;
12646   rc = Serialize_TPM2B_PUBLIC_KEY_RSA(message, &message_bytes);
12647   if (rc != TPM_RC_SUCCESS) {
12648     return rc;
12649   }
12650   std::string in_scheme_bytes;
12651   rc = Serialize_TPMT_RSA_DECRYPT(in_scheme, &in_scheme_bytes);
12652   if (rc != TPM_RC_SUCCESS) {
12653     return rc;
12654   }
12655   std::string label_bytes;
12656   rc = Serialize_TPM2B_DATA(label, &label_bytes);
12657   if (rc != TPM_RC_SUCCESS) {
12658     return rc;
12659   }
12660   if (authorization_delegate) {
12661     // Encrypt just the parameter data, not the size.
12662     std::string tmp = message_bytes.substr(2);
12663     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12664       return TRUNKS_RC_ENCRYPTION_FAILED;
12665     }
12666     message_bytes.replace(2, std::string::npos, tmp);
12667   }
12668   std::unique_ptr<crypto::SecureHash> hash(
12669       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12670   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12671   hash->Update(key_handle_name.data(), key_handle_name.size());
12672   handle_section_bytes += key_handle_bytes;
12673   command_size += key_handle_bytes.size();
12674   hash->Update(message_bytes.data(), message_bytes.size());
12675   parameter_section_bytes += message_bytes;
12676   command_size += message_bytes.size();
12677   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
12678   parameter_section_bytes += in_scheme_bytes;
12679   command_size += in_scheme_bytes.size();
12680   hash->Update(label_bytes.data(), label_bytes.size());
12681   parameter_section_bytes += label_bytes;
12682   command_size += label_bytes.size();
12683   std::string command_hash(32, 0);
12684   hash->Finish(std::data(command_hash), command_hash.size());
12685   std::string authorization_section_bytes;
12686   std::string authorization_size_bytes;
12687   if (authorization_delegate) {
12688     if (!authorization_delegate->GetCommandAuthorization(
12689             command_hash, is_command_parameter_encryption_possible,
12690             is_response_parameter_encryption_possible,
12691             &authorization_section_bytes)) {
12692       return TRUNKS_RC_AUTHORIZATION_FAILED;
12693     }
12694     if (!authorization_section_bytes.empty()) {
12695       tag = TPM_ST_SESSIONS;
12696       std::string tmp;
12697       rc = Serialize_UINT32(authorization_section_bytes.size(),
12698                             &authorization_size_bytes);
12699       if (rc != TPM_RC_SUCCESS) {
12700         return rc;
12701       }
12702       command_size +=
12703           authorization_size_bytes.size() + authorization_section_bytes.size();
12704     }
12705   }
12706   std::string tag_bytes;
12707   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12708   if (rc != TPM_RC_SUCCESS) {
12709     return rc;
12710   }
12711   std::string command_size_bytes;
12712   rc = Serialize_UINT32(command_size, &command_size_bytes);
12713   if (rc != TPM_RC_SUCCESS) {
12714     return rc;
12715   }
12716   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12717                         handle_section_bytes + authorization_size_bytes +
12718                         authorization_section_bytes + parameter_section_bytes;
12719   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12720   VLOG(2) << "Command: "
12721           << base::HexEncode(serialized_command->data(),
12722                              serialized_command->size());
12723   return TPM_RC_SUCCESS;
12724 }
12725 
ParseResponse_RSA_Encrypt(const std::string & response,TPM2B_PUBLIC_KEY_RSA * out_data,AuthorizationDelegate * authorization_delegate)12726 TPM_RC Tpm::ParseResponse_RSA_Encrypt(
12727     const std::string& response,
12728     TPM2B_PUBLIC_KEY_RSA* out_data,
12729     AuthorizationDelegate* authorization_delegate) {
12730   VLOG(3) << __func__;
12731   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
12732   TPM_RC rc = TPM_RC_SUCCESS;
12733   std::string buffer(response);
12734   TPM_ST tag;
12735   std::string tag_bytes;
12736   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
12737   if (rc != TPM_RC_SUCCESS) {
12738     return rc;
12739   }
12740   UINT32 response_size;
12741   std::string response_size_bytes;
12742   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
12743   if (rc != TPM_RC_SUCCESS) {
12744     return rc;
12745   }
12746   TPM_RC response_code;
12747   std::string response_code_bytes;
12748   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
12749   if (rc != TPM_RC_SUCCESS) {
12750     return rc;
12751   }
12752   if (response_size != response.size()) {
12753     return TPM_RC_SIZE;
12754   }
12755   if (response_code != TPM_RC_SUCCESS) {
12756     return response_code;
12757   }
12758   TPM_CC command_code = TPM_CC_RSA_Encrypt;
12759   std::string command_code_bytes;
12760   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12761   if (rc != TPM_RC_SUCCESS) {
12762     return rc;
12763   }
12764   std::string authorization_section_bytes;
12765   if (tag == TPM_ST_SESSIONS) {
12766     UINT32 parameter_section_size = buffer.size();
12767     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
12768     if (rc != TPM_RC_SUCCESS) {
12769       return rc;
12770     }
12771     if (parameter_section_size > buffer.size()) {
12772       return TPM_RC_INSUFFICIENT;
12773     }
12774     authorization_section_bytes = buffer.substr(parameter_section_size);
12775     // Keep the parameter section in |buffer|.
12776     buffer.erase(parameter_section_size);
12777   }
12778   std::unique_ptr<crypto::SecureHash> hash(
12779       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12780   hash->Update(response_code_bytes.data(), response_code_bytes.size());
12781   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12782   hash->Update(buffer.data(), buffer.size());
12783   std::string response_hash(32, 0);
12784   hash->Finish(std::data(response_hash), response_hash.size());
12785   if (tag == TPM_ST_SESSIONS) {
12786     if (!authorization_delegate)
12787       return TRUNKS_RC_AUTHORIZATION_FAILED;
12788     if (!authorization_delegate->CheckResponseAuthorization(
12789             response_hash, authorization_section_bytes)) {
12790       return TRUNKS_RC_AUTHORIZATION_FAILED;
12791     }
12792   }
12793   if (tag == TPM_ST_SESSIONS) {
12794     if (!authorization_delegate)
12795       return TRUNKS_RC_AUTHORIZATION_FAILED;
12796 
12797     // Parse the encrypted parameter size.
12798     UINT16 size;
12799     std::string size_buffer = buffer.substr(0, 2);
12800     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
12801       return result;
12802     }
12803     if (buffer.size() < 2 + size) {
12804       return TPM_RC_INSUFFICIENT;
12805     }
12806 
12807     // Decrypt just the parameter data, not the size.
12808     std::string decrypted_data = buffer.substr(2, size);
12809     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
12810       return TRUNKS_RC_ENCRYPTION_FAILED;
12811     }
12812     buffer.replace(2, size, decrypted_data);
12813   }
12814   std::string out_data_bytes;
12815   rc = Parse_TPM2B_PUBLIC_KEY_RSA(&buffer, out_data, &out_data_bytes);
12816   if (rc != TPM_RC_SUCCESS) {
12817     return rc;
12818   }
12819   return TPM_RC_SUCCESS;
12820 }
12821 
RSA_EncryptErrorCallback(Tpm::RSA_EncryptResponse callback,TPM_RC response_code)12822 void RSA_EncryptErrorCallback(Tpm::RSA_EncryptResponse callback,
12823                               TPM_RC response_code) {
12824   VLOG(1) << __func__;
12825   std::move(callback).Run(response_code, TPM2B_PUBLIC_KEY_RSA());
12826 }
12827 
RSA_EncryptResponseParser(Tpm::RSA_EncryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)12828 void RSA_EncryptResponseParser(Tpm::RSA_EncryptResponse callback,
12829                                AuthorizationDelegate* authorization_delegate,
12830                                const std::string& response) {
12831   VLOG(1) << __func__;
12832   TPM2B_PUBLIC_KEY_RSA out_data;
12833   TPM_RC rc = Tpm::ParseResponse_RSA_Encrypt(response, &out_data,
12834                                              authorization_delegate);
12835   if (rc != TPM_RC_SUCCESS) {
12836     base::OnceCallback<void(TPM_RC)> error_reporter =
12837         base::BindOnce(RSA_EncryptErrorCallback, std::move(callback));
12838     std::move(error_reporter).Run(rc);
12839     return;
12840   }
12841   std::move(callback).Run(rc, out_data);
12842 }
12843 
RSA_Encrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & message,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,AuthorizationDelegate * authorization_delegate,RSA_EncryptResponse callback)12844 void Tpm::RSA_Encrypt(const TPMI_DH_OBJECT& key_handle,
12845                       const std::string& key_handle_name,
12846                       const TPM2B_PUBLIC_KEY_RSA& message,
12847                       const TPMT_RSA_DECRYPT& in_scheme,
12848                       const TPM2B_DATA& label,
12849                       AuthorizationDelegate* authorization_delegate,
12850                       RSA_EncryptResponse callback) {
12851   VLOG(1) << __func__;
12852   std::string command;
12853   TPM_RC rc = SerializeCommand_RSA_Encrypt(key_handle, key_handle_name, message,
12854                                            in_scheme, label, &command,
12855                                            authorization_delegate);
12856   if (rc != TPM_RC_SUCCESS) {
12857     base::OnceCallback<void(TPM_RC)> error_reporter =
12858         base::BindOnce(RSA_EncryptErrorCallback, std::move(callback));
12859     std::move(error_reporter).Run(rc);
12860     return;
12861   }
12862   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
12863       RSA_EncryptResponseParser, std::move(callback), authorization_delegate);
12864   transceiver_->SendCommand(command, std::move(parser));
12865 }
12866 
RSA_EncryptSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & message,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,TPM2B_PUBLIC_KEY_RSA * out_data,AuthorizationDelegate * authorization_delegate)12867 TPM_RC Tpm::RSA_EncryptSync(const TPMI_DH_OBJECT& key_handle,
12868                             const std::string& key_handle_name,
12869                             const TPM2B_PUBLIC_KEY_RSA& message,
12870                             const TPMT_RSA_DECRYPT& in_scheme,
12871                             const TPM2B_DATA& label,
12872                             TPM2B_PUBLIC_KEY_RSA* out_data,
12873                             AuthorizationDelegate* authorization_delegate) {
12874   VLOG(1) << __func__;
12875   std::string command;
12876   TPM_RC rc = SerializeCommand_RSA_Encrypt(key_handle, key_handle_name, message,
12877                                            in_scheme, label, &command,
12878                                            authorization_delegate);
12879   if (rc != TPM_RC_SUCCESS) {
12880     return rc;
12881   }
12882   std::string response = transceiver_->SendCommandAndWait(command);
12883   rc = ParseResponse_RSA_Encrypt(response, out_data, authorization_delegate);
12884   return rc;
12885 }
12886 
SerializeCommand_RSA_Decrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & cipher_text,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)12887 TPM_RC Tpm::SerializeCommand_RSA_Decrypt(
12888     const TPMI_DH_OBJECT& key_handle,
12889     const std::string& key_handle_name,
12890     const TPM2B_PUBLIC_KEY_RSA& cipher_text,
12891     const TPMT_RSA_DECRYPT& in_scheme,
12892     const TPM2B_DATA& label,
12893     std::string* serialized_command,
12894     AuthorizationDelegate* authorization_delegate) {
12895   VLOG(3) << __func__;
12896   TPM_RC rc = TPM_RC_SUCCESS;
12897   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
12898   UINT32 command_size = 10;  // Header size.
12899   std::string handle_section_bytes;
12900   std::string parameter_section_bytes;
12901   TPM_CC command_code = TPM_CC_RSA_Decrypt;
12902   bool is_command_parameter_encryption_possible = true;
12903   bool is_response_parameter_encryption_possible = true;
12904   std::string command_code_bytes;
12905   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
12906   if (rc != TPM_RC_SUCCESS) {
12907     return rc;
12908   }
12909   std::string key_handle_bytes;
12910   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
12911   if (rc != TPM_RC_SUCCESS) {
12912     return rc;
12913   }
12914   std::string cipher_text_bytes;
12915   rc = Serialize_TPM2B_PUBLIC_KEY_RSA(cipher_text, &cipher_text_bytes);
12916   if (rc != TPM_RC_SUCCESS) {
12917     return rc;
12918   }
12919   std::string in_scheme_bytes;
12920   rc = Serialize_TPMT_RSA_DECRYPT(in_scheme, &in_scheme_bytes);
12921   if (rc != TPM_RC_SUCCESS) {
12922     return rc;
12923   }
12924   std::string label_bytes;
12925   rc = Serialize_TPM2B_DATA(label, &label_bytes);
12926   if (rc != TPM_RC_SUCCESS) {
12927     return rc;
12928   }
12929   if (authorization_delegate) {
12930     // Encrypt just the parameter data, not the size.
12931     std::string tmp = cipher_text_bytes.substr(2);
12932     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
12933       return TRUNKS_RC_ENCRYPTION_FAILED;
12934     }
12935     cipher_text_bytes.replace(2, std::string::npos, tmp);
12936   }
12937   std::unique_ptr<crypto::SecureHash> hash(
12938       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
12939   hash->Update(command_code_bytes.data(), command_code_bytes.size());
12940   hash->Update(key_handle_name.data(), key_handle_name.size());
12941   handle_section_bytes += key_handle_bytes;
12942   command_size += key_handle_bytes.size();
12943   hash->Update(cipher_text_bytes.data(), cipher_text_bytes.size());
12944   parameter_section_bytes += cipher_text_bytes;
12945   command_size += cipher_text_bytes.size();
12946   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
12947   parameter_section_bytes += in_scheme_bytes;
12948   command_size += in_scheme_bytes.size();
12949   hash->Update(label_bytes.data(), label_bytes.size());
12950   parameter_section_bytes += label_bytes;
12951   command_size += label_bytes.size();
12952   std::string command_hash(32, 0);
12953   hash->Finish(std::data(command_hash), command_hash.size());
12954   std::string authorization_section_bytes;
12955   std::string authorization_size_bytes;
12956   if (authorization_delegate) {
12957     if (!authorization_delegate->GetCommandAuthorization(
12958             command_hash, is_command_parameter_encryption_possible,
12959             is_response_parameter_encryption_possible,
12960             &authorization_section_bytes)) {
12961       return TRUNKS_RC_AUTHORIZATION_FAILED;
12962     }
12963     if (!authorization_section_bytes.empty()) {
12964       tag = TPM_ST_SESSIONS;
12965       std::string tmp;
12966       rc = Serialize_UINT32(authorization_section_bytes.size(),
12967                             &authorization_size_bytes);
12968       if (rc != TPM_RC_SUCCESS) {
12969         return rc;
12970       }
12971       command_size +=
12972           authorization_size_bytes.size() + authorization_section_bytes.size();
12973     }
12974   }
12975   std::string tag_bytes;
12976   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
12977   if (rc != TPM_RC_SUCCESS) {
12978     return rc;
12979   }
12980   std::string command_size_bytes;
12981   rc = Serialize_UINT32(command_size, &command_size_bytes);
12982   if (rc != TPM_RC_SUCCESS) {
12983     return rc;
12984   }
12985   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
12986                         handle_section_bytes + authorization_size_bytes +
12987                         authorization_section_bytes + parameter_section_bytes;
12988   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
12989   VLOG(2) << "Command: "
12990           << base::HexEncode(serialized_command->data(),
12991                              serialized_command->size());
12992   return TPM_RC_SUCCESS;
12993 }
12994 
ParseResponse_RSA_Decrypt(const std::string & response,TPM2B_PUBLIC_KEY_RSA * message,AuthorizationDelegate * authorization_delegate)12995 TPM_RC Tpm::ParseResponse_RSA_Decrypt(
12996     const std::string& response,
12997     TPM2B_PUBLIC_KEY_RSA* message,
12998     AuthorizationDelegate* authorization_delegate) {
12999   VLOG(3) << __func__;
13000   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13001   TPM_RC rc = TPM_RC_SUCCESS;
13002   std::string buffer(response);
13003   TPM_ST tag;
13004   std::string tag_bytes;
13005   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13006   if (rc != TPM_RC_SUCCESS) {
13007     return rc;
13008   }
13009   UINT32 response_size;
13010   std::string response_size_bytes;
13011   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13012   if (rc != TPM_RC_SUCCESS) {
13013     return rc;
13014   }
13015   TPM_RC response_code;
13016   std::string response_code_bytes;
13017   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13018   if (rc != TPM_RC_SUCCESS) {
13019     return rc;
13020   }
13021   if (response_size != response.size()) {
13022     return TPM_RC_SIZE;
13023   }
13024   if (response_code != TPM_RC_SUCCESS) {
13025     return response_code;
13026   }
13027   TPM_CC command_code = TPM_CC_RSA_Decrypt;
13028   std::string command_code_bytes;
13029   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13030   if (rc != TPM_RC_SUCCESS) {
13031     return rc;
13032   }
13033   std::string authorization_section_bytes;
13034   if (tag == TPM_ST_SESSIONS) {
13035     UINT32 parameter_section_size = buffer.size();
13036     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13037     if (rc != TPM_RC_SUCCESS) {
13038       return rc;
13039     }
13040     if (parameter_section_size > buffer.size()) {
13041       return TPM_RC_INSUFFICIENT;
13042     }
13043     authorization_section_bytes = buffer.substr(parameter_section_size);
13044     // Keep the parameter section in |buffer|.
13045     buffer.erase(parameter_section_size);
13046   }
13047   std::unique_ptr<crypto::SecureHash> hash(
13048       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13049   hash->Update(response_code_bytes.data(), response_code_bytes.size());
13050   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13051   hash->Update(buffer.data(), buffer.size());
13052   std::string response_hash(32, 0);
13053   hash->Finish(std::data(response_hash), response_hash.size());
13054   if (tag == TPM_ST_SESSIONS) {
13055     if (!authorization_delegate)
13056       return TRUNKS_RC_AUTHORIZATION_FAILED;
13057     if (!authorization_delegate->CheckResponseAuthorization(
13058             response_hash, authorization_section_bytes)) {
13059       return TRUNKS_RC_AUTHORIZATION_FAILED;
13060     }
13061   }
13062   if (tag == TPM_ST_SESSIONS) {
13063     if (!authorization_delegate)
13064       return TRUNKS_RC_AUTHORIZATION_FAILED;
13065 
13066     // Parse the encrypted parameter size.
13067     UINT16 size;
13068     std::string size_buffer = buffer.substr(0, 2);
13069     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13070       return result;
13071     }
13072     if (buffer.size() < 2 + size) {
13073       return TPM_RC_INSUFFICIENT;
13074     }
13075 
13076     // Decrypt just the parameter data, not the size.
13077     std::string decrypted_data = buffer.substr(2, size);
13078     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13079       return TRUNKS_RC_ENCRYPTION_FAILED;
13080     }
13081     buffer.replace(2, size, decrypted_data);
13082   }
13083   std::string message_bytes;
13084   rc = Parse_TPM2B_PUBLIC_KEY_RSA(&buffer, message, &message_bytes);
13085   if (rc != TPM_RC_SUCCESS) {
13086     return rc;
13087   }
13088   return TPM_RC_SUCCESS;
13089 }
13090 
RSA_DecryptErrorCallback(Tpm::RSA_DecryptResponse callback,TPM_RC response_code)13091 void RSA_DecryptErrorCallback(Tpm::RSA_DecryptResponse callback,
13092                               TPM_RC response_code) {
13093   VLOG(1) << __func__;
13094   std::move(callback).Run(response_code, TPM2B_PUBLIC_KEY_RSA());
13095 }
13096 
RSA_DecryptResponseParser(Tpm::RSA_DecryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13097 void RSA_DecryptResponseParser(Tpm::RSA_DecryptResponse callback,
13098                                AuthorizationDelegate* authorization_delegate,
13099                                const std::string& response) {
13100   VLOG(1) << __func__;
13101   TPM2B_PUBLIC_KEY_RSA message;
13102   TPM_RC rc = Tpm::ParseResponse_RSA_Decrypt(response, &message,
13103                                              authorization_delegate);
13104   if (rc != TPM_RC_SUCCESS) {
13105     base::OnceCallback<void(TPM_RC)> error_reporter =
13106         base::BindOnce(RSA_DecryptErrorCallback, std::move(callback));
13107     std::move(error_reporter).Run(rc);
13108     return;
13109   }
13110   std::move(callback).Run(rc, message);
13111 }
13112 
RSA_Decrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & cipher_text,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,AuthorizationDelegate * authorization_delegate,RSA_DecryptResponse callback)13113 void Tpm::RSA_Decrypt(const TPMI_DH_OBJECT& key_handle,
13114                       const std::string& key_handle_name,
13115                       const TPM2B_PUBLIC_KEY_RSA& cipher_text,
13116                       const TPMT_RSA_DECRYPT& in_scheme,
13117                       const TPM2B_DATA& label,
13118                       AuthorizationDelegate* authorization_delegate,
13119                       RSA_DecryptResponse callback) {
13120   VLOG(1) << __func__;
13121   std::string command;
13122   TPM_RC rc = SerializeCommand_RSA_Decrypt(key_handle, key_handle_name,
13123                                            cipher_text, in_scheme, label,
13124                                            &command, authorization_delegate);
13125   if (rc != TPM_RC_SUCCESS) {
13126     base::OnceCallback<void(TPM_RC)> error_reporter =
13127         base::BindOnce(RSA_DecryptErrorCallback, std::move(callback));
13128     std::move(error_reporter).Run(rc);
13129     return;
13130   }
13131   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13132       RSA_DecryptResponseParser, std::move(callback), authorization_delegate);
13133   transceiver_->SendCommand(command, std::move(parser));
13134 }
13135 
RSA_DecryptSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_PUBLIC_KEY_RSA & cipher_text,const TPMT_RSA_DECRYPT & in_scheme,const TPM2B_DATA & label,TPM2B_PUBLIC_KEY_RSA * message,AuthorizationDelegate * authorization_delegate)13136 TPM_RC Tpm::RSA_DecryptSync(const TPMI_DH_OBJECT& key_handle,
13137                             const std::string& key_handle_name,
13138                             const TPM2B_PUBLIC_KEY_RSA& cipher_text,
13139                             const TPMT_RSA_DECRYPT& in_scheme,
13140                             const TPM2B_DATA& label,
13141                             TPM2B_PUBLIC_KEY_RSA* message,
13142                             AuthorizationDelegate* authorization_delegate) {
13143   VLOG(1) << __func__;
13144   std::string command;
13145   TPM_RC rc = SerializeCommand_RSA_Decrypt(key_handle, key_handle_name,
13146                                            cipher_text, in_scheme, label,
13147                                            &command, authorization_delegate);
13148   if (rc != TPM_RC_SUCCESS) {
13149     return rc;
13150   }
13151   std::string response = transceiver_->SendCommandAndWait(command);
13152   rc = ParseResponse_RSA_Decrypt(response, message, authorization_delegate);
13153   return rc;
13154 }
13155 
SerializeCommand_ECDH_KeyGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13156 TPM_RC Tpm::SerializeCommand_ECDH_KeyGen(
13157     const TPMI_DH_OBJECT& key_handle,
13158     const std::string& key_handle_name,
13159     std::string* serialized_command,
13160     AuthorizationDelegate* authorization_delegate) {
13161   VLOG(3) << __func__;
13162   TPM_RC rc = TPM_RC_SUCCESS;
13163   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13164   UINT32 command_size = 10;  // Header size.
13165   std::string handle_section_bytes;
13166   std::string parameter_section_bytes;
13167   TPM_CC command_code = TPM_CC_ECDH_KeyGen;
13168   bool is_command_parameter_encryption_possible = false;
13169   bool is_response_parameter_encryption_possible = true;
13170   std::string command_code_bytes;
13171   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13172   if (rc != TPM_RC_SUCCESS) {
13173     return rc;
13174   }
13175   std::string key_handle_bytes;
13176   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13177   if (rc != TPM_RC_SUCCESS) {
13178     return rc;
13179   }
13180   std::unique_ptr<crypto::SecureHash> hash(
13181       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13182   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13183   hash->Update(key_handle_name.data(), key_handle_name.size());
13184   handle_section_bytes += key_handle_bytes;
13185   command_size += key_handle_bytes.size();
13186   std::string command_hash(32, 0);
13187   hash->Finish(std::data(command_hash), command_hash.size());
13188   std::string authorization_section_bytes;
13189   std::string authorization_size_bytes;
13190   if (authorization_delegate) {
13191     if (!authorization_delegate->GetCommandAuthorization(
13192             command_hash, is_command_parameter_encryption_possible,
13193             is_response_parameter_encryption_possible,
13194             &authorization_section_bytes)) {
13195       return TRUNKS_RC_AUTHORIZATION_FAILED;
13196     }
13197     if (!authorization_section_bytes.empty()) {
13198       tag = TPM_ST_SESSIONS;
13199       std::string tmp;
13200       rc = Serialize_UINT32(authorization_section_bytes.size(),
13201                             &authorization_size_bytes);
13202       if (rc != TPM_RC_SUCCESS) {
13203         return rc;
13204       }
13205       command_size +=
13206           authorization_size_bytes.size() + authorization_section_bytes.size();
13207     }
13208   }
13209   std::string tag_bytes;
13210   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13211   if (rc != TPM_RC_SUCCESS) {
13212     return rc;
13213   }
13214   std::string command_size_bytes;
13215   rc = Serialize_UINT32(command_size, &command_size_bytes);
13216   if (rc != TPM_RC_SUCCESS) {
13217     return rc;
13218   }
13219   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13220                         handle_section_bytes + authorization_size_bytes +
13221                         authorization_section_bytes + parameter_section_bytes;
13222   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13223   VLOG(2) << "Command: "
13224           << base::HexEncode(serialized_command->data(),
13225                              serialized_command->size());
13226   return TPM_RC_SUCCESS;
13227 }
13228 
ParseResponse_ECDH_KeyGen(const std::string & response,TPM2B_ECC_POINT * z_point,TPM2B_ECC_POINT * pub_point,AuthorizationDelegate * authorization_delegate)13229 TPM_RC Tpm::ParseResponse_ECDH_KeyGen(
13230     const std::string& response,
13231     TPM2B_ECC_POINT* z_point,
13232     TPM2B_ECC_POINT* pub_point,
13233     AuthorizationDelegate* authorization_delegate) {
13234   VLOG(3) << __func__;
13235   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13236   TPM_RC rc = TPM_RC_SUCCESS;
13237   std::string buffer(response);
13238   TPM_ST tag;
13239   std::string tag_bytes;
13240   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13241   if (rc != TPM_RC_SUCCESS) {
13242     return rc;
13243   }
13244   UINT32 response_size;
13245   std::string response_size_bytes;
13246   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13247   if (rc != TPM_RC_SUCCESS) {
13248     return rc;
13249   }
13250   TPM_RC response_code;
13251   std::string response_code_bytes;
13252   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13253   if (rc != TPM_RC_SUCCESS) {
13254     return rc;
13255   }
13256   if (response_size != response.size()) {
13257     return TPM_RC_SIZE;
13258   }
13259   if (response_code != TPM_RC_SUCCESS) {
13260     return response_code;
13261   }
13262   TPM_CC command_code = TPM_CC_ECDH_KeyGen;
13263   std::string command_code_bytes;
13264   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13265   if (rc != TPM_RC_SUCCESS) {
13266     return rc;
13267   }
13268   std::string authorization_section_bytes;
13269   if (tag == TPM_ST_SESSIONS) {
13270     UINT32 parameter_section_size = buffer.size();
13271     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13272     if (rc != TPM_RC_SUCCESS) {
13273       return rc;
13274     }
13275     if (parameter_section_size > buffer.size()) {
13276       return TPM_RC_INSUFFICIENT;
13277     }
13278     authorization_section_bytes = buffer.substr(parameter_section_size);
13279     // Keep the parameter section in |buffer|.
13280     buffer.erase(parameter_section_size);
13281   }
13282   std::unique_ptr<crypto::SecureHash> hash(
13283       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13284   hash->Update(response_code_bytes.data(), response_code_bytes.size());
13285   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13286   hash->Update(buffer.data(), buffer.size());
13287   std::string response_hash(32, 0);
13288   hash->Finish(std::data(response_hash), response_hash.size());
13289   if (tag == TPM_ST_SESSIONS) {
13290     if (!authorization_delegate)
13291       return TRUNKS_RC_AUTHORIZATION_FAILED;
13292     if (!authorization_delegate->CheckResponseAuthorization(
13293             response_hash, authorization_section_bytes)) {
13294       return TRUNKS_RC_AUTHORIZATION_FAILED;
13295     }
13296   }
13297   if (tag == TPM_ST_SESSIONS) {
13298     if (!authorization_delegate)
13299       return TRUNKS_RC_AUTHORIZATION_FAILED;
13300 
13301     // Parse the encrypted parameter size.
13302     UINT16 size;
13303     std::string size_buffer = buffer.substr(0, 2);
13304     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13305       return result;
13306     }
13307     if (buffer.size() < 2 + size) {
13308       return TPM_RC_INSUFFICIENT;
13309     }
13310 
13311     // Decrypt just the parameter data, not the size.
13312     std::string decrypted_data = buffer.substr(2, size);
13313     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13314       return TRUNKS_RC_ENCRYPTION_FAILED;
13315     }
13316     buffer.replace(2, size, decrypted_data);
13317   }
13318   std::string z_point_bytes;
13319   rc = Parse_TPM2B_ECC_POINT(&buffer, z_point, &z_point_bytes);
13320   if (rc != TPM_RC_SUCCESS) {
13321     return rc;
13322   }
13323   std::string pub_point_bytes;
13324   rc = Parse_TPM2B_ECC_POINT(&buffer, pub_point, &pub_point_bytes);
13325   if (rc != TPM_RC_SUCCESS) {
13326     return rc;
13327   }
13328   return TPM_RC_SUCCESS;
13329 }
13330 
ECDH_KeyGenErrorCallback(Tpm::ECDH_KeyGenResponse callback,TPM_RC response_code)13331 void ECDH_KeyGenErrorCallback(Tpm::ECDH_KeyGenResponse callback,
13332                               TPM_RC response_code) {
13333   VLOG(1) << __func__;
13334   std::move(callback).Run(response_code, TPM2B_ECC_POINT(), TPM2B_ECC_POINT());
13335 }
13336 
ECDH_KeyGenResponseParser(Tpm::ECDH_KeyGenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13337 void ECDH_KeyGenResponseParser(Tpm::ECDH_KeyGenResponse callback,
13338                                AuthorizationDelegate* authorization_delegate,
13339                                const std::string& response) {
13340   VLOG(1) << __func__;
13341   TPM2B_ECC_POINT z_point;
13342   TPM2B_ECC_POINT pub_point;
13343   TPM_RC rc = Tpm::ParseResponse_ECDH_KeyGen(response, &z_point, &pub_point,
13344                                              authorization_delegate);
13345   if (rc != TPM_RC_SUCCESS) {
13346     base::OnceCallback<void(TPM_RC)> error_reporter =
13347         base::BindOnce(ECDH_KeyGenErrorCallback, std::move(callback));
13348     std::move(error_reporter).Run(rc);
13349     return;
13350   }
13351   std::move(callback).Run(rc, z_point, pub_point);
13352 }
13353 
ECDH_KeyGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,AuthorizationDelegate * authorization_delegate,ECDH_KeyGenResponse callback)13354 void Tpm::ECDH_KeyGen(const TPMI_DH_OBJECT& key_handle,
13355                       const std::string& key_handle_name,
13356                       AuthorizationDelegate* authorization_delegate,
13357                       ECDH_KeyGenResponse callback) {
13358   VLOG(1) << __func__;
13359   std::string command;
13360   TPM_RC rc = SerializeCommand_ECDH_KeyGen(key_handle, key_handle_name,
13361                                            &command, authorization_delegate);
13362   if (rc != TPM_RC_SUCCESS) {
13363     base::OnceCallback<void(TPM_RC)> error_reporter =
13364         base::BindOnce(ECDH_KeyGenErrorCallback, std::move(callback));
13365     std::move(error_reporter).Run(rc);
13366     return;
13367   }
13368   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13369       ECDH_KeyGenResponseParser, std::move(callback), authorization_delegate);
13370   transceiver_->SendCommand(command, std::move(parser));
13371 }
13372 
ECDH_KeyGenSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,TPM2B_ECC_POINT * z_point,TPM2B_ECC_POINT * pub_point,AuthorizationDelegate * authorization_delegate)13373 TPM_RC Tpm::ECDH_KeyGenSync(const TPMI_DH_OBJECT& key_handle,
13374                             const std::string& key_handle_name,
13375                             TPM2B_ECC_POINT* z_point,
13376                             TPM2B_ECC_POINT* pub_point,
13377                             AuthorizationDelegate* authorization_delegate) {
13378   VLOG(1) << __func__;
13379   std::string command;
13380   TPM_RC rc = SerializeCommand_ECDH_KeyGen(key_handle, key_handle_name,
13381                                            &command, authorization_delegate);
13382   if (rc != TPM_RC_SUCCESS) {
13383     return rc;
13384   }
13385   std::string response = transceiver_->SendCommandAndWait(command);
13386   rc = ParseResponse_ECDH_KeyGen(response, z_point, pub_point,
13387                                  authorization_delegate);
13388   return rc;
13389 }
13390 
SerializeCommand_ECDH_ZGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ECC_POINT & in_point,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13391 TPM_RC Tpm::SerializeCommand_ECDH_ZGen(
13392     const TPMI_DH_OBJECT& key_handle,
13393     const std::string& key_handle_name,
13394     const TPM2B_ECC_POINT& in_point,
13395     std::string* serialized_command,
13396     AuthorizationDelegate* authorization_delegate) {
13397   VLOG(3) << __func__;
13398   TPM_RC rc = TPM_RC_SUCCESS;
13399   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13400   UINT32 command_size = 10;  // Header size.
13401   std::string handle_section_bytes;
13402   std::string parameter_section_bytes;
13403   TPM_CC command_code = TPM_CC_ECDH_ZGen;
13404   bool is_command_parameter_encryption_possible = true;
13405   bool is_response_parameter_encryption_possible = true;
13406   std::string command_code_bytes;
13407   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13408   if (rc != TPM_RC_SUCCESS) {
13409     return rc;
13410   }
13411   std::string key_handle_bytes;
13412   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
13413   if (rc != TPM_RC_SUCCESS) {
13414     return rc;
13415   }
13416   std::string in_point_bytes;
13417   rc = Serialize_TPM2B_ECC_POINT(in_point, &in_point_bytes);
13418   if (rc != TPM_RC_SUCCESS) {
13419     return rc;
13420   }
13421   if (authorization_delegate) {
13422     // Encrypt just the parameter data, not the size.
13423     std::string tmp = in_point_bytes.substr(2);
13424     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
13425       return TRUNKS_RC_ENCRYPTION_FAILED;
13426     }
13427     in_point_bytes.replace(2, std::string::npos, tmp);
13428   }
13429   std::unique_ptr<crypto::SecureHash> hash(
13430       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13431   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13432   hash->Update(key_handle_name.data(), key_handle_name.size());
13433   handle_section_bytes += key_handle_bytes;
13434   command_size += key_handle_bytes.size();
13435   hash->Update(in_point_bytes.data(), in_point_bytes.size());
13436   parameter_section_bytes += in_point_bytes;
13437   command_size += in_point_bytes.size();
13438   std::string command_hash(32, 0);
13439   hash->Finish(std::data(command_hash), command_hash.size());
13440   std::string authorization_section_bytes;
13441   std::string authorization_size_bytes;
13442   if (authorization_delegate) {
13443     if (!authorization_delegate->GetCommandAuthorization(
13444             command_hash, is_command_parameter_encryption_possible,
13445             is_response_parameter_encryption_possible,
13446             &authorization_section_bytes)) {
13447       return TRUNKS_RC_AUTHORIZATION_FAILED;
13448     }
13449     if (!authorization_section_bytes.empty()) {
13450       tag = TPM_ST_SESSIONS;
13451       std::string tmp;
13452       rc = Serialize_UINT32(authorization_section_bytes.size(),
13453                             &authorization_size_bytes);
13454       if (rc != TPM_RC_SUCCESS) {
13455         return rc;
13456       }
13457       command_size +=
13458           authorization_size_bytes.size() + authorization_section_bytes.size();
13459     }
13460   }
13461   std::string tag_bytes;
13462   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13463   if (rc != TPM_RC_SUCCESS) {
13464     return rc;
13465   }
13466   std::string command_size_bytes;
13467   rc = Serialize_UINT32(command_size, &command_size_bytes);
13468   if (rc != TPM_RC_SUCCESS) {
13469     return rc;
13470   }
13471   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13472                         handle_section_bytes + authorization_size_bytes +
13473                         authorization_section_bytes + parameter_section_bytes;
13474   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13475   VLOG(2) << "Command: "
13476           << base::HexEncode(serialized_command->data(),
13477                              serialized_command->size());
13478   return TPM_RC_SUCCESS;
13479 }
13480 
ParseResponse_ECDH_ZGen(const std::string & response,TPM2B_ECC_POINT * out_point,AuthorizationDelegate * authorization_delegate)13481 TPM_RC Tpm::ParseResponse_ECDH_ZGen(
13482     const std::string& response,
13483     TPM2B_ECC_POINT* out_point,
13484     AuthorizationDelegate* authorization_delegate) {
13485   VLOG(3) << __func__;
13486   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13487   TPM_RC rc = TPM_RC_SUCCESS;
13488   std::string buffer(response);
13489   TPM_ST tag;
13490   std::string tag_bytes;
13491   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13492   if (rc != TPM_RC_SUCCESS) {
13493     return rc;
13494   }
13495   UINT32 response_size;
13496   std::string response_size_bytes;
13497   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13498   if (rc != TPM_RC_SUCCESS) {
13499     return rc;
13500   }
13501   TPM_RC response_code;
13502   std::string response_code_bytes;
13503   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13504   if (rc != TPM_RC_SUCCESS) {
13505     return rc;
13506   }
13507   if (response_size != response.size()) {
13508     return TPM_RC_SIZE;
13509   }
13510   if (response_code != TPM_RC_SUCCESS) {
13511     return response_code;
13512   }
13513   TPM_CC command_code = TPM_CC_ECDH_ZGen;
13514   std::string command_code_bytes;
13515   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13516   if (rc != TPM_RC_SUCCESS) {
13517     return rc;
13518   }
13519   std::string authorization_section_bytes;
13520   if (tag == TPM_ST_SESSIONS) {
13521     UINT32 parameter_section_size = buffer.size();
13522     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13523     if (rc != TPM_RC_SUCCESS) {
13524       return rc;
13525     }
13526     if (parameter_section_size > buffer.size()) {
13527       return TPM_RC_INSUFFICIENT;
13528     }
13529     authorization_section_bytes = buffer.substr(parameter_section_size);
13530     // Keep the parameter section in |buffer|.
13531     buffer.erase(parameter_section_size);
13532   }
13533   std::unique_ptr<crypto::SecureHash> hash(
13534       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13535   hash->Update(response_code_bytes.data(), response_code_bytes.size());
13536   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13537   hash->Update(buffer.data(), buffer.size());
13538   std::string response_hash(32, 0);
13539   hash->Finish(std::data(response_hash), response_hash.size());
13540   if (tag == TPM_ST_SESSIONS) {
13541     if (!authorization_delegate)
13542       return TRUNKS_RC_AUTHORIZATION_FAILED;
13543     if (!authorization_delegate->CheckResponseAuthorization(
13544             response_hash, authorization_section_bytes)) {
13545       return TRUNKS_RC_AUTHORIZATION_FAILED;
13546     }
13547   }
13548   if (tag == TPM_ST_SESSIONS) {
13549     if (!authorization_delegate)
13550       return TRUNKS_RC_AUTHORIZATION_FAILED;
13551 
13552     // Parse the encrypted parameter size.
13553     UINT16 size;
13554     std::string size_buffer = buffer.substr(0, 2);
13555     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
13556       return result;
13557     }
13558     if (buffer.size() < 2 + size) {
13559       return TPM_RC_INSUFFICIENT;
13560     }
13561 
13562     // Decrypt just the parameter data, not the size.
13563     std::string decrypted_data = buffer.substr(2, size);
13564     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
13565       return TRUNKS_RC_ENCRYPTION_FAILED;
13566     }
13567     buffer.replace(2, size, decrypted_data);
13568   }
13569   std::string out_point_bytes;
13570   rc = Parse_TPM2B_ECC_POINT(&buffer, out_point, &out_point_bytes);
13571   if (rc != TPM_RC_SUCCESS) {
13572     return rc;
13573   }
13574   return TPM_RC_SUCCESS;
13575 }
13576 
ECDH_ZGenErrorCallback(Tpm::ECDH_ZGenResponse callback,TPM_RC response_code)13577 void ECDH_ZGenErrorCallback(Tpm::ECDH_ZGenResponse callback,
13578                             TPM_RC response_code) {
13579   VLOG(1) << __func__;
13580   std::move(callback).Run(response_code, TPM2B_ECC_POINT());
13581 }
13582 
ECDH_ZGenResponseParser(Tpm::ECDH_ZGenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13583 void ECDH_ZGenResponseParser(Tpm::ECDH_ZGenResponse callback,
13584                              AuthorizationDelegate* authorization_delegate,
13585                              const std::string& response) {
13586   VLOG(1) << __func__;
13587   TPM2B_ECC_POINT out_point;
13588   TPM_RC rc = Tpm::ParseResponse_ECDH_ZGen(response, &out_point,
13589                                            authorization_delegate);
13590   if (rc != TPM_RC_SUCCESS) {
13591     base::OnceCallback<void(TPM_RC)> error_reporter =
13592         base::BindOnce(ECDH_ZGenErrorCallback, std::move(callback));
13593     std::move(error_reporter).Run(rc);
13594     return;
13595   }
13596   std::move(callback).Run(rc, out_point);
13597 }
13598 
ECDH_ZGen(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ECC_POINT & in_point,AuthorizationDelegate * authorization_delegate,ECDH_ZGenResponse callback)13599 void Tpm::ECDH_ZGen(const TPMI_DH_OBJECT& key_handle,
13600                     const std::string& key_handle_name,
13601                     const TPM2B_ECC_POINT& in_point,
13602                     AuthorizationDelegate* authorization_delegate,
13603                     ECDH_ZGenResponse callback) {
13604   VLOG(1) << __func__;
13605   std::string command;
13606   TPM_RC rc = SerializeCommand_ECDH_ZGen(key_handle, key_handle_name, in_point,
13607                                          &command, authorization_delegate);
13608   if (rc != TPM_RC_SUCCESS) {
13609     base::OnceCallback<void(TPM_RC)> error_reporter =
13610         base::BindOnce(ECDH_ZGenErrorCallback, std::move(callback));
13611     std::move(error_reporter).Run(rc);
13612     return;
13613   }
13614   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
13615       ECDH_ZGenResponseParser, std::move(callback), authorization_delegate);
13616   transceiver_->SendCommand(command, std::move(parser));
13617 }
13618 
ECDH_ZGenSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_ECC_POINT & in_point,TPM2B_ECC_POINT * out_point,AuthorizationDelegate * authorization_delegate)13619 TPM_RC Tpm::ECDH_ZGenSync(const TPMI_DH_OBJECT& key_handle,
13620                           const std::string& key_handle_name,
13621                           const TPM2B_ECC_POINT& in_point,
13622                           TPM2B_ECC_POINT* out_point,
13623                           AuthorizationDelegate* authorization_delegate) {
13624   VLOG(1) << __func__;
13625   std::string command;
13626   TPM_RC rc = SerializeCommand_ECDH_ZGen(key_handle, key_handle_name, in_point,
13627                                          &command, authorization_delegate);
13628   if (rc != TPM_RC_SUCCESS) {
13629     return rc;
13630   }
13631   std::string response = transceiver_->SendCommandAndWait(command);
13632   rc = ParseResponse_ECDH_ZGen(response, out_point, authorization_delegate);
13633   return rc;
13634 }
13635 
SerializeCommand_ECC_Parameters(const TPMI_ECC_CURVE & curve_id,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13636 TPM_RC Tpm::SerializeCommand_ECC_Parameters(
13637     const TPMI_ECC_CURVE& curve_id,
13638     std::string* serialized_command,
13639     AuthorizationDelegate* authorization_delegate) {
13640   VLOG(3) << __func__;
13641   TPM_RC rc = TPM_RC_SUCCESS;
13642   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13643   UINT32 command_size = 10;  // Header size.
13644   std::string handle_section_bytes;
13645   std::string parameter_section_bytes;
13646   TPM_CC command_code = TPM_CC_ECC_Parameters;
13647   bool is_command_parameter_encryption_possible = false;
13648   bool is_response_parameter_encryption_possible = false;
13649   std::string command_code_bytes;
13650   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13651   if (rc != TPM_RC_SUCCESS) {
13652     return rc;
13653   }
13654   std::string curve_id_bytes;
13655   rc = Serialize_TPMI_ECC_CURVE(curve_id, &curve_id_bytes);
13656   if (rc != TPM_RC_SUCCESS) {
13657     return rc;
13658   }
13659   std::unique_ptr<crypto::SecureHash> hash(
13660       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13661   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13662   hash->Update(curve_id_bytes.data(), curve_id_bytes.size());
13663   parameter_section_bytes += curve_id_bytes;
13664   command_size += curve_id_bytes.size();
13665   std::string command_hash(32, 0);
13666   hash->Finish(std::data(command_hash), command_hash.size());
13667   std::string authorization_section_bytes;
13668   std::string authorization_size_bytes;
13669   if (authorization_delegate) {
13670     if (!authorization_delegate->GetCommandAuthorization(
13671             command_hash, is_command_parameter_encryption_possible,
13672             is_response_parameter_encryption_possible,
13673             &authorization_section_bytes)) {
13674       return TRUNKS_RC_AUTHORIZATION_FAILED;
13675     }
13676     if (!authorization_section_bytes.empty()) {
13677       tag = TPM_ST_SESSIONS;
13678       std::string tmp;
13679       rc = Serialize_UINT32(authorization_section_bytes.size(),
13680                             &authorization_size_bytes);
13681       if (rc != TPM_RC_SUCCESS) {
13682         return rc;
13683       }
13684       command_size +=
13685           authorization_size_bytes.size() + authorization_section_bytes.size();
13686     }
13687   }
13688   std::string tag_bytes;
13689   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13690   if (rc != TPM_RC_SUCCESS) {
13691     return rc;
13692   }
13693   std::string command_size_bytes;
13694   rc = Serialize_UINT32(command_size, &command_size_bytes);
13695   if (rc != TPM_RC_SUCCESS) {
13696     return rc;
13697   }
13698   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13699                         handle_section_bytes + authorization_size_bytes +
13700                         authorization_section_bytes + parameter_section_bytes;
13701   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13702   VLOG(2) << "Command: "
13703           << base::HexEncode(serialized_command->data(),
13704                              serialized_command->size());
13705   return TPM_RC_SUCCESS;
13706 }
13707 
ParseResponse_ECC_Parameters(const std::string & response,TPMS_ALGORITHM_DETAIL_ECC * parameters,AuthorizationDelegate * authorization_delegate)13708 TPM_RC Tpm::ParseResponse_ECC_Parameters(
13709     const std::string& response,
13710     TPMS_ALGORITHM_DETAIL_ECC* parameters,
13711     AuthorizationDelegate* authorization_delegate) {
13712   VLOG(3) << __func__;
13713   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13714   TPM_RC rc = TPM_RC_SUCCESS;
13715   std::string buffer(response);
13716   TPM_ST tag;
13717   std::string tag_bytes;
13718   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13719   if (rc != TPM_RC_SUCCESS) {
13720     return rc;
13721   }
13722   UINT32 response_size;
13723   std::string response_size_bytes;
13724   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13725   if (rc != TPM_RC_SUCCESS) {
13726     return rc;
13727   }
13728   TPM_RC response_code;
13729   std::string response_code_bytes;
13730   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13731   if (rc != TPM_RC_SUCCESS) {
13732     return rc;
13733   }
13734   if (response_size != response.size()) {
13735     return TPM_RC_SIZE;
13736   }
13737   if (response_code != TPM_RC_SUCCESS) {
13738     return response_code;
13739   }
13740   TPM_CC command_code = TPM_CC_ECC_Parameters;
13741   std::string command_code_bytes;
13742   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13743   if (rc != TPM_RC_SUCCESS) {
13744     return rc;
13745   }
13746   std::string authorization_section_bytes;
13747   if (tag == TPM_ST_SESSIONS) {
13748     UINT32 parameter_section_size = buffer.size();
13749     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
13750     if (rc != TPM_RC_SUCCESS) {
13751       return rc;
13752     }
13753     if (parameter_section_size > buffer.size()) {
13754       return TPM_RC_INSUFFICIENT;
13755     }
13756     authorization_section_bytes = buffer.substr(parameter_section_size);
13757     // Keep the parameter section in |buffer|.
13758     buffer.erase(parameter_section_size);
13759   }
13760   std::unique_ptr<crypto::SecureHash> hash(
13761       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13762   hash->Update(response_code_bytes.data(), response_code_bytes.size());
13763   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13764   hash->Update(buffer.data(), buffer.size());
13765   std::string response_hash(32, 0);
13766   hash->Finish(std::data(response_hash), response_hash.size());
13767   if (tag == TPM_ST_SESSIONS) {
13768     if (!authorization_delegate)
13769       return TRUNKS_RC_AUTHORIZATION_FAILED;
13770     if (!authorization_delegate->CheckResponseAuthorization(
13771             response_hash, authorization_section_bytes)) {
13772       return TRUNKS_RC_AUTHORIZATION_FAILED;
13773     }
13774   }
13775   std::string parameters_bytes;
13776   rc = Parse_TPMS_ALGORITHM_DETAIL_ECC(&buffer, parameters, &parameters_bytes);
13777   if (rc != TPM_RC_SUCCESS) {
13778     return rc;
13779   }
13780   return TPM_RC_SUCCESS;
13781 }
13782 
ECC_ParametersErrorCallback(Tpm::ECC_ParametersResponse callback,TPM_RC response_code)13783 void ECC_ParametersErrorCallback(Tpm::ECC_ParametersResponse callback,
13784                                  TPM_RC response_code) {
13785   VLOG(1) << __func__;
13786   std::move(callback).Run(response_code, TPMS_ALGORITHM_DETAIL_ECC());
13787 }
13788 
ECC_ParametersResponseParser(Tpm::ECC_ParametersResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)13789 void ECC_ParametersResponseParser(Tpm::ECC_ParametersResponse callback,
13790                                   AuthorizationDelegate* authorization_delegate,
13791                                   const std::string& response) {
13792   VLOG(1) << __func__;
13793   TPMS_ALGORITHM_DETAIL_ECC parameters;
13794   TPM_RC rc = Tpm::ParseResponse_ECC_Parameters(response, &parameters,
13795                                                 authorization_delegate);
13796   if (rc != TPM_RC_SUCCESS) {
13797     base::OnceCallback<void(TPM_RC)> error_reporter =
13798         base::BindOnce(ECC_ParametersErrorCallback, std::move(callback));
13799     std::move(error_reporter).Run(rc);
13800     return;
13801   }
13802   std::move(callback).Run(rc, parameters);
13803 }
13804 
ECC_Parameters(const TPMI_ECC_CURVE & curve_id,AuthorizationDelegate * authorization_delegate,ECC_ParametersResponse callback)13805 void Tpm::ECC_Parameters(const TPMI_ECC_CURVE& curve_id,
13806                          AuthorizationDelegate* authorization_delegate,
13807                          ECC_ParametersResponse callback) {
13808   VLOG(1) << __func__;
13809   std::string command;
13810   TPM_RC rc = SerializeCommand_ECC_Parameters(curve_id, &command,
13811                                               authorization_delegate);
13812   if (rc != TPM_RC_SUCCESS) {
13813     base::OnceCallback<void(TPM_RC)> error_reporter =
13814         base::BindOnce(ECC_ParametersErrorCallback, std::move(callback));
13815     std::move(error_reporter).Run(rc);
13816     return;
13817   }
13818   base::OnceCallback<void(const std::string&)> parser =
13819       base::BindOnce(ECC_ParametersResponseParser, std::move(callback),
13820                      authorization_delegate);
13821   transceiver_->SendCommand(command, std::move(parser));
13822 }
13823 
ECC_ParametersSync(const TPMI_ECC_CURVE & curve_id,TPMS_ALGORITHM_DETAIL_ECC * parameters,AuthorizationDelegate * authorization_delegate)13824 TPM_RC Tpm::ECC_ParametersSync(const TPMI_ECC_CURVE& curve_id,
13825                                TPMS_ALGORITHM_DETAIL_ECC* parameters,
13826                                AuthorizationDelegate* authorization_delegate) {
13827   VLOG(1) << __func__;
13828   std::string command;
13829   TPM_RC rc = SerializeCommand_ECC_Parameters(curve_id, &command,
13830                                               authorization_delegate);
13831   if (rc != TPM_RC_SUCCESS) {
13832     return rc;
13833   }
13834   std::string response = transceiver_->SendCommandAndWait(command);
13835   rc = ParseResponse_ECC_Parameters(response, parameters,
13836                                     authorization_delegate);
13837   return rc;
13838 }
13839 
SerializeCommand_ZGen_2Phase(const TPMI_DH_OBJECT & key_a,const std::string & key_a_name,const TPM2B_ECC_POINT & in_qs_b,const TPM2B_ECC_POINT & in_qe_b,const TPMI_ECC_KEY_EXCHANGE & in_scheme,const UINT16 & counter,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)13840 TPM_RC Tpm::SerializeCommand_ZGen_2Phase(
13841     const TPMI_DH_OBJECT& key_a,
13842     const std::string& key_a_name,
13843     const TPM2B_ECC_POINT& in_qs_b,
13844     const TPM2B_ECC_POINT& in_qe_b,
13845     const TPMI_ECC_KEY_EXCHANGE& in_scheme,
13846     const UINT16& counter,
13847     std::string* serialized_command,
13848     AuthorizationDelegate* authorization_delegate) {
13849   VLOG(3) << __func__;
13850   TPM_RC rc = TPM_RC_SUCCESS;
13851   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
13852   UINT32 command_size = 10;  // Header size.
13853   std::string handle_section_bytes;
13854   std::string parameter_section_bytes;
13855   TPM_CC command_code = TPM_CC_ZGen_2Phase;
13856   bool is_command_parameter_encryption_possible = true;
13857   bool is_response_parameter_encryption_possible = true;
13858   std::string command_code_bytes;
13859   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13860   if (rc != TPM_RC_SUCCESS) {
13861     return rc;
13862   }
13863   std::string key_a_bytes;
13864   rc = Serialize_TPMI_DH_OBJECT(key_a, &key_a_bytes);
13865   if (rc != TPM_RC_SUCCESS) {
13866     return rc;
13867   }
13868   std::string in_qs_b_bytes;
13869   rc = Serialize_TPM2B_ECC_POINT(in_qs_b, &in_qs_b_bytes);
13870   if (rc != TPM_RC_SUCCESS) {
13871     return rc;
13872   }
13873   std::string in_qe_b_bytes;
13874   rc = Serialize_TPM2B_ECC_POINT(in_qe_b, &in_qe_b_bytes);
13875   if (rc != TPM_RC_SUCCESS) {
13876     return rc;
13877   }
13878   std::string in_scheme_bytes;
13879   rc = Serialize_TPMI_ECC_KEY_EXCHANGE(in_scheme, &in_scheme_bytes);
13880   if (rc != TPM_RC_SUCCESS) {
13881     return rc;
13882   }
13883   std::string counter_bytes;
13884   rc = Serialize_UINT16(counter, &counter_bytes);
13885   if (rc != TPM_RC_SUCCESS) {
13886     return rc;
13887   }
13888   if (authorization_delegate) {
13889     // Encrypt just the parameter data, not the size.
13890     std::string tmp = in_qs_b_bytes.substr(2);
13891     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
13892       return TRUNKS_RC_ENCRYPTION_FAILED;
13893     }
13894     in_qs_b_bytes.replace(2, std::string::npos, tmp);
13895   }
13896   std::unique_ptr<crypto::SecureHash> hash(
13897       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
13898   hash->Update(command_code_bytes.data(), command_code_bytes.size());
13899   hash->Update(key_a_name.data(), key_a_name.size());
13900   handle_section_bytes += key_a_bytes;
13901   command_size += key_a_bytes.size();
13902   hash->Update(in_qs_b_bytes.data(), in_qs_b_bytes.size());
13903   parameter_section_bytes += in_qs_b_bytes;
13904   command_size += in_qs_b_bytes.size();
13905   hash->Update(in_qe_b_bytes.data(), in_qe_b_bytes.size());
13906   parameter_section_bytes += in_qe_b_bytes;
13907   command_size += in_qe_b_bytes.size();
13908   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
13909   parameter_section_bytes += in_scheme_bytes;
13910   command_size += in_scheme_bytes.size();
13911   hash->Update(counter_bytes.data(), counter_bytes.size());
13912   parameter_section_bytes += counter_bytes;
13913   command_size += counter_bytes.size();
13914   std::string command_hash(32, 0);
13915   hash->Finish(std::data(command_hash), command_hash.size());
13916   std::string authorization_section_bytes;
13917   std::string authorization_size_bytes;
13918   if (authorization_delegate) {
13919     if (!authorization_delegate->GetCommandAuthorization(
13920             command_hash, is_command_parameter_encryption_possible,
13921             is_response_parameter_encryption_possible,
13922             &authorization_section_bytes)) {
13923       return TRUNKS_RC_AUTHORIZATION_FAILED;
13924     }
13925     if (!authorization_section_bytes.empty()) {
13926       tag = TPM_ST_SESSIONS;
13927       std::string tmp;
13928       rc = Serialize_UINT32(authorization_section_bytes.size(),
13929                             &authorization_size_bytes);
13930       if (rc != TPM_RC_SUCCESS) {
13931         return rc;
13932       }
13933       command_size +=
13934           authorization_size_bytes.size() + authorization_section_bytes.size();
13935     }
13936   }
13937   std::string tag_bytes;
13938   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
13939   if (rc != TPM_RC_SUCCESS) {
13940     return rc;
13941   }
13942   std::string command_size_bytes;
13943   rc = Serialize_UINT32(command_size, &command_size_bytes);
13944   if (rc != TPM_RC_SUCCESS) {
13945     return rc;
13946   }
13947   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
13948                         handle_section_bytes + authorization_size_bytes +
13949                         authorization_section_bytes + parameter_section_bytes;
13950   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
13951   VLOG(2) << "Command: "
13952           << base::HexEncode(serialized_command->data(),
13953                              serialized_command->size());
13954   return TPM_RC_SUCCESS;
13955 }
13956 
ParseResponse_ZGen_2Phase(const std::string & response,TPM2B_ECC_POINT * out_z1,TPM2B_ECC_POINT * out_z2,AuthorizationDelegate * authorization_delegate)13957 TPM_RC Tpm::ParseResponse_ZGen_2Phase(
13958     const std::string& response,
13959     TPM2B_ECC_POINT* out_z1,
13960     TPM2B_ECC_POINT* out_z2,
13961     AuthorizationDelegate* authorization_delegate) {
13962   VLOG(3) << __func__;
13963   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
13964   TPM_RC rc = TPM_RC_SUCCESS;
13965   std::string buffer(response);
13966   TPM_ST tag;
13967   std::string tag_bytes;
13968   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
13969   if (rc != TPM_RC_SUCCESS) {
13970     return rc;
13971   }
13972   UINT32 response_size;
13973   std::string response_size_bytes;
13974   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
13975   if (rc != TPM_RC_SUCCESS) {
13976     return rc;
13977   }
13978   TPM_RC response_code;
13979   std::string response_code_bytes;
13980   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
13981   if (rc != TPM_RC_SUCCESS) {
13982     return rc;
13983   }
13984   if (response_size != response.size()) {
13985     return TPM_RC_SIZE;
13986   }
13987   if (response_code != TPM_RC_SUCCESS) {
13988     return response_code;
13989   }
13990   TPM_CC command_code = TPM_CC_ZGen_2Phase;
13991   std::string command_code_bytes;
13992   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
13993   if (rc != TPM_RC_SUCCESS) {
13994     return rc;
13995   }
13996   std::string authorization_section_bytes;
13997   if (tag == TPM_ST_SESSIONS) {
13998     UINT32 parameter_section_size = buffer.size();
13999     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14000     if (rc != TPM_RC_SUCCESS) {
14001       return rc;
14002     }
14003     if (parameter_section_size > buffer.size()) {
14004       return TPM_RC_INSUFFICIENT;
14005     }
14006     authorization_section_bytes = buffer.substr(parameter_section_size);
14007     // Keep the parameter section in |buffer|.
14008     buffer.erase(parameter_section_size);
14009   }
14010   std::unique_ptr<crypto::SecureHash> hash(
14011       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14012   hash->Update(response_code_bytes.data(), response_code_bytes.size());
14013   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14014   hash->Update(buffer.data(), buffer.size());
14015   std::string response_hash(32, 0);
14016   hash->Finish(std::data(response_hash), response_hash.size());
14017   if (tag == TPM_ST_SESSIONS) {
14018     if (!authorization_delegate)
14019       return TRUNKS_RC_AUTHORIZATION_FAILED;
14020     if (!authorization_delegate->CheckResponseAuthorization(
14021             response_hash, authorization_section_bytes)) {
14022       return TRUNKS_RC_AUTHORIZATION_FAILED;
14023     }
14024   }
14025   if (tag == TPM_ST_SESSIONS) {
14026     if (!authorization_delegate)
14027       return TRUNKS_RC_AUTHORIZATION_FAILED;
14028 
14029     // Parse the encrypted parameter size.
14030     UINT16 size;
14031     std::string size_buffer = buffer.substr(0, 2);
14032     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14033       return result;
14034     }
14035     if (buffer.size() < 2 + size) {
14036       return TPM_RC_INSUFFICIENT;
14037     }
14038 
14039     // Decrypt just the parameter data, not the size.
14040     std::string decrypted_data = buffer.substr(2, size);
14041     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14042       return TRUNKS_RC_ENCRYPTION_FAILED;
14043     }
14044     buffer.replace(2, size, decrypted_data);
14045   }
14046   std::string out_z1_bytes;
14047   rc = Parse_TPM2B_ECC_POINT(&buffer, out_z1, &out_z1_bytes);
14048   if (rc != TPM_RC_SUCCESS) {
14049     return rc;
14050   }
14051   std::string out_z2_bytes;
14052   rc = Parse_TPM2B_ECC_POINT(&buffer, out_z2, &out_z2_bytes);
14053   if (rc != TPM_RC_SUCCESS) {
14054     return rc;
14055   }
14056   return TPM_RC_SUCCESS;
14057 }
14058 
ZGen_2PhaseErrorCallback(Tpm::ZGen_2PhaseResponse callback,TPM_RC response_code)14059 void ZGen_2PhaseErrorCallback(Tpm::ZGen_2PhaseResponse callback,
14060                               TPM_RC response_code) {
14061   VLOG(1) << __func__;
14062   std::move(callback).Run(response_code, TPM2B_ECC_POINT(), TPM2B_ECC_POINT());
14063 }
14064 
ZGen_2PhaseResponseParser(Tpm::ZGen_2PhaseResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14065 void ZGen_2PhaseResponseParser(Tpm::ZGen_2PhaseResponse callback,
14066                                AuthorizationDelegate* authorization_delegate,
14067                                const std::string& response) {
14068   VLOG(1) << __func__;
14069   TPM2B_ECC_POINT out_z1;
14070   TPM2B_ECC_POINT out_z2;
14071   TPM_RC rc = Tpm::ParseResponse_ZGen_2Phase(response, &out_z1, &out_z2,
14072                                              authorization_delegate);
14073   if (rc != TPM_RC_SUCCESS) {
14074     base::OnceCallback<void(TPM_RC)> error_reporter =
14075         base::BindOnce(ZGen_2PhaseErrorCallback, std::move(callback));
14076     std::move(error_reporter).Run(rc);
14077     return;
14078   }
14079   std::move(callback).Run(rc, out_z1, out_z2);
14080 }
14081 
ZGen_2Phase(const TPMI_DH_OBJECT & key_a,const std::string & key_a_name,const TPM2B_ECC_POINT & in_qs_b,const TPM2B_ECC_POINT & in_qe_b,const TPMI_ECC_KEY_EXCHANGE & in_scheme,const UINT16 & counter,AuthorizationDelegate * authorization_delegate,ZGen_2PhaseResponse callback)14082 void Tpm::ZGen_2Phase(const TPMI_DH_OBJECT& key_a,
14083                       const std::string& key_a_name,
14084                       const TPM2B_ECC_POINT& in_qs_b,
14085                       const TPM2B_ECC_POINT& in_qe_b,
14086                       const TPMI_ECC_KEY_EXCHANGE& in_scheme,
14087                       const UINT16& counter,
14088                       AuthorizationDelegate* authorization_delegate,
14089                       ZGen_2PhaseResponse callback) {
14090   VLOG(1) << __func__;
14091   std::string command;
14092   TPM_RC rc = SerializeCommand_ZGen_2Phase(key_a, key_a_name, in_qs_b, in_qe_b,
14093                                            in_scheme, counter, &command,
14094                                            authorization_delegate);
14095   if (rc != TPM_RC_SUCCESS) {
14096     base::OnceCallback<void(TPM_RC)> error_reporter =
14097         base::BindOnce(ZGen_2PhaseErrorCallback, std::move(callback));
14098     std::move(error_reporter).Run(rc);
14099     return;
14100   }
14101   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14102       ZGen_2PhaseResponseParser, std::move(callback), authorization_delegate);
14103   transceiver_->SendCommand(command, std::move(parser));
14104 }
14105 
ZGen_2PhaseSync(const TPMI_DH_OBJECT & key_a,const std::string & key_a_name,const TPM2B_ECC_POINT & in_qs_b,const TPM2B_ECC_POINT & in_qe_b,const TPMI_ECC_KEY_EXCHANGE & in_scheme,const UINT16 & counter,TPM2B_ECC_POINT * out_z1,TPM2B_ECC_POINT * out_z2,AuthorizationDelegate * authorization_delegate)14106 TPM_RC Tpm::ZGen_2PhaseSync(const TPMI_DH_OBJECT& key_a,
14107                             const std::string& key_a_name,
14108                             const TPM2B_ECC_POINT& in_qs_b,
14109                             const TPM2B_ECC_POINT& in_qe_b,
14110                             const TPMI_ECC_KEY_EXCHANGE& in_scheme,
14111                             const UINT16& counter,
14112                             TPM2B_ECC_POINT* out_z1,
14113                             TPM2B_ECC_POINT* out_z2,
14114                             AuthorizationDelegate* authorization_delegate) {
14115   VLOG(1) << __func__;
14116   std::string command;
14117   TPM_RC rc = SerializeCommand_ZGen_2Phase(key_a, key_a_name, in_qs_b, in_qe_b,
14118                                            in_scheme, counter, &command,
14119                                            authorization_delegate);
14120   if (rc != TPM_RC_SUCCESS) {
14121     return rc;
14122   }
14123   std::string response = transceiver_->SendCommandAndWait(command);
14124   rc = ParseResponse_ZGen_2Phase(response, out_z1, out_z2,
14125                                  authorization_delegate);
14126   return rc;
14127 }
14128 
SerializeCommand_EncryptDecrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPMI_YES_NO & decrypt,const TPMI_ALG_SYM_MODE & mode,const TPM2B_IV & iv_in,const TPM2B_MAX_BUFFER & in_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14129 TPM_RC Tpm::SerializeCommand_EncryptDecrypt(
14130     const TPMI_DH_OBJECT& key_handle,
14131     const std::string& key_handle_name,
14132     const TPMI_YES_NO& decrypt,
14133     const TPMI_ALG_SYM_MODE& mode,
14134     const TPM2B_IV& iv_in,
14135     const TPM2B_MAX_BUFFER& in_data,
14136     std::string* serialized_command,
14137     AuthorizationDelegate* authorization_delegate) {
14138   VLOG(3) << __func__;
14139   TPM_RC rc = TPM_RC_SUCCESS;
14140   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14141   UINT32 command_size = 10;  // Header size.
14142   std::string handle_section_bytes;
14143   std::string parameter_section_bytes;
14144   TPM_CC command_code = TPM_CC_EncryptDecrypt;
14145   bool is_command_parameter_encryption_possible = false;
14146   bool is_response_parameter_encryption_possible = true;
14147   std::string command_code_bytes;
14148   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14149   if (rc != TPM_RC_SUCCESS) {
14150     return rc;
14151   }
14152   std::string key_handle_bytes;
14153   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
14154   if (rc != TPM_RC_SUCCESS) {
14155     return rc;
14156   }
14157   std::string decrypt_bytes;
14158   rc = Serialize_TPMI_YES_NO(decrypt, &decrypt_bytes);
14159   if (rc != TPM_RC_SUCCESS) {
14160     return rc;
14161   }
14162   std::string mode_bytes;
14163   rc = Serialize_TPMI_ALG_SYM_MODE(mode, &mode_bytes);
14164   if (rc != TPM_RC_SUCCESS) {
14165     return rc;
14166   }
14167   std::string iv_in_bytes;
14168   rc = Serialize_TPM2B_IV(iv_in, &iv_in_bytes);
14169   if (rc != TPM_RC_SUCCESS) {
14170     return rc;
14171   }
14172   std::string in_data_bytes;
14173   rc = Serialize_TPM2B_MAX_BUFFER(in_data, &in_data_bytes);
14174   if (rc != TPM_RC_SUCCESS) {
14175     return rc;
14176   }
14177   std::unique_ptr<crypto::SecureHash> hash(
14178       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14179   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14180   hash->Update(key_handle_name.data(), key_handle_name.size());
14181   handle_section_bytes += key_handle_bytes;
14182   command_size += key_handle_bytes.size();
14183   hash->Update(decrypt_bytes.data(), decrypt_bytes.size());
14184   parameter_section_bytes += decrypt_bytes;
14185   command_size += decrypt_bytes.size();
14186   hash->Update(mode_bytes.data(), mode_bytes.size());
14187   parameter_section_bytes += mode_bytes;
14188   command_size += mode_bytes.size();
14189   hash->Update(iv_in_bytes.data(), iv_in_bytes.size());
14190   parameter_section_bytes += iv_in_bytes;
14191   command_size += iv_in_bytes.size();
14192   hash->Update(in_data_bytes.data(), in_data_bytes.size());
14193   parameter_section_bytes += in_data_bytes;
14194   command_size += in_data_bytes.size();
14195   std::string command_hash(32, 0);
14196   hash->Finish(std::data(command_hash), command_hash.size());
14197   std::string authorization_section_bytes;
14198   std::string authorization_size_bytes;
14199   if (authorization_delegate) {
14200     if (!authorization_delegate->GetCommandAuthorization(
14201             command_hash, is_command_parameter_encryption_possible,
14202             is_response_parameter_encryption_possible,
14203             &authorization_section_bytes)) {
14204       return TRUNKS_RC_AUTHORIZATION_FAILED;
14205     }
14206     if (!authorization_section_bytes.empty()) {
14207       tag = TPM_ST_SESSIONS;
14208       std::string tmp;
14209       rc = Serialize_UINT32(authorization_section_bytes.size(),
14210                             &authorization_size_bytes);
14211       if (rc != TPM_RC_SUCCESS) {
14212         return rc;
14213       }
14214       command_size +=
14215           authorization_size_bytes.size() + authorization_section_bytes.size();
14216     }
14217   }
14218   std::string tag_bytes;
14219   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14220   if (rc != TPM_RC_SUCCESS) {
14221     return rc;
14222   }
14223   std::string command_size_bytes;
14224   rc = Serialize_UINT32(command_size, &command_size_bytes);
14225   if (rc != TPM_RC_SUCCESS) {
14226     return rc;
14227   }
14228   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14229                         handle_section_bytes + authorization_size_bytes +
14230                         authorization_section_bytes + parameter_section_bytes;
14231   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14232   VLOG(2) << "Command: "
14233           << base::HexEncode(serialized_command->data(),
14234                              serialized_command->size());
14235   return TPM_RC_SUCCESS;
14236 }
14237 
ParseResponse_EncryptDecrypt(const std::string & response,TPM2B_MAX_BUFFER * out_data,TPM2B_IV * iv_out,AuthorizationDelegate * authorization_delegate)14238 TPM_RC Tpm::ParseResponse_EncryptDecrypt(
14239     const std::string& response,
14240     TPM2B_MAX_BUFFER* out_data,
14241     TPM2B_IV* iv_out,
14242     AuthorizationDelegate* authorization_delegate) {
14243   VLOG(3) << __func__;
14244   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14245   TPM_RC rc = TPM_RC_SUCCESS;
14246   std::string buffer(response);
14247   TPM_ST tag;
14248   std::string tag_bytes;
14249   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14250   if (rc != TPM_RC_SUCCESS) {
14251     return rc;
14252   }
14253   UINT32 response_size;
14254   std::string response_size_bytes;
14255   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14256   if (rc != TPM_RC_SUCCESS) {
14257     return rc;
14258   }
14259   TPM_RC response_code;
14260   std::string response_code_bytes;
14261   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14262   if (rc != TPM_RC_SUCCESS) {
14263     return rc;
14264   }
14265   if (response_size != response.size()) {
14266     return TPM_RC_SIZE;
14267   }
14268   if (response_code != TPM_RC_SUCCESS) {
14269     return response_code;
14270   }
14271   TPM_CC command_code = TPM_CC_EncryptDecrypt;
14272   std::string command_code_bytes;
14273   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14274   if (rc != TPM_RC_SUCCESS) {
14275     return rc;
14276   }
14277   std::string authorization_section_bytes;
14278   if (tag == TPM_ST_SESSIONS) {
14279     UINT32 parameter_section_size = buffer.size();
14280     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14281     if (rc != TPM_RC_SUCCESS) {
14282       return rc;
14283     }
14284     if (parameter_section_size > buffer.size()) {
14285       return TPM_RC_INSUFFICIENT;
14286     }
14287     authorization_section_bytes = buffer.substr(parameter_section_size);
14288     // Keep the parameter section in |buffer|.
14289     buffer.erase(parameter_section_size);
14290   }
14291   std::unique_ptr<crypto::SecureHash> hash(
14292       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14293   hash->Update(response_code_bytes.data(), response_code_bytes.size());
14294   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14295   hash->Update(buffer.data(), buffer.size());
14296   std::string response_hash(32, 0);
14297   hash->Finish(std::data(response_hash), response_hash.size());
14298   if (tag == TPM_ST_SESSIONS) {
14299     if (!authorization_delegate)
14300       return TRUNKS_RC_AUTHORIZATION_FAILED;
14301     if (!authorization_delegate->CheckResponseAuthorization(
14302             response_hash, authorization_section_bytes)) {
14303       return TRUNKS_RC_AUTHORIZATION_FAILED;
14304     }
14305   }
14306   if (tag == TPM_ST_SESSIONS) {
14307     if (!authorization_delegate)
14308       return TRUNKS_RC_AUTHORIZATION_FAILED;
14309 
14310     // Parse the encrypted parameter size.
14311     UINT16 size;
14312     std::string size_buffer = buffer.substr(0, 2);
14313     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14314       return result;
14315     }
14316     if (buffer.size() < 2 + size) {
14317       return TPM_RC_INSUFFICIENT;
14318     }
14319 
14320     // Decrypt just the parameter data, not the size.
14321     std::string decrypted_data = buffer.substr(2, size);
14322     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14323       return TRUNKS_RC_ENCRYPTION_FAILED;
14324     }
14325     buffer.replace(2, size, decrypted_data);
14326   }
14327   std::string out_data_bytes;
14328   rc = Parse_TPM2B_MAX_BUFFER(&buffer, out_data, &out_data_bytes);
14329   if (rc != TPM_RC_SUCCESS) {
14330     return rc;
14331   }
14332   std::string iv_out_bytes;
14333   rc = Parse_TPM2B_IV(&buffer, iv_out, &iv_out_bytes);
14334   if (rc != TPM_RC_SUCCESS) {
14335     return rc;
14336   }
14337   return TPM_RC_SUCCESS;
14338 }
14339 
EncryptDecryptErrorCallback(Tpm::EncryptDecryptResponse callback,TPM_RC response_code)14340 void EncryptDecryptErrorCallback(Tpm::EncryptDecryptResponse callback,
14341                                  TPM_RC response_code) {
14342   VLOG(1) << __func__;
14343   std::move(callback).Run(response_code, TPM2B_MAX_BUFFER(), TPM2B_IV());
14344 }
14345 
EncryptDecryptResponseParser(Tpm::EncryptDecryptResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14346 void EncryptDecryptResponseParser(Tpm::EncryptDecryptResponse callback,
14347                                   AuthorizationDelegate* authorization_delegate,
14348                                   const std::string& response) {
14349   VLOG(1) << __func__;
14350   TPM2B_MAX_BUFFER out_data;
14351   TPM2B_IV iv_out;
14352   TPM_RC rc = Tpm::ParseResponse_EncryptDecrypt(response, &out_data, &iv_out,
14353                                                 authorization_delegate);
14354   if (rc != TPM_RC_SUCCESS) {
14355     base::OnceCallback<void(TPM_RC)> error_reporter =
14356         base::BindOnce(EncryptDecryptErrorCallback, std::move(callback));
14357     std::move(error_reporter).Run(rc);
14358     return;
14359   }
14360   std::move(callback).Run(rc, out_data, iv_out);
14361 }
14362 
EncryptDecrypt(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPMI_YES_NO & decrypt,const TPMI_ALG_SYM_MODE & mode,const TPM2B_IV & iv_in,const TPM2B_MAX_BUFFER & in_data,AuthorizationDelegate * authorization_delegate,EncryptDecryptResponse callback)14363 void Tpm::EncryptDecrypt(const TPMI_DH_OBJECT& key_handle,
14364                          const std::string& key_handle_name,
14365                          const TPMI_YES_NO& decrypt,
14366                          const TPMI_ALG_SYM_MODE& mode,
14367                          const TPM2B_IV& iv_in,
14368                          const TPM2B_MAX_BUFFER& in_data,
14369                          AuthorizationDelegate* authorization_delegate,
14370                          EncryptDecryptResponse callback) {
14371   VLOG(1) << __func__;
14372   std::string command;
14373   TPM_RC rc = SerializeCommand_EncryptDecrypt(key_handle, key_handle_name,
14374                                               decrypt, mode, iv_in, in_data,
14375                                               &command, authorization_delegate);
14376   if (rc != TPM_RC_SUCCESS) {
14377     base::OnceCallback<void(TPM_RC)> error_reporter =
14378         base::BindOnce(EncryptDecryptErrorCallback, std::move(callback));
14379     std::move(error_reporter).Run(rc);
14380     return;
14381   }
14382   base::OnceCallback<void(const std::string&)> parser =
14383       base::BindOnce(EncryptDecryptResponseParser, std::move(callback),
14384                      authorization_delegate);
14385   transceiver_->SendCommand(command, std::move(parser));
14386 }
14387 
EncryptDecryptSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPMI_YES_NO & decrypt,const TPMI_ALG_SYM_MODE & mode,const TPM2B_IV & iv_in,const TPM2B_MAX_BUFFER & in_data,TPM2B_MAX_BUFFER * out_data,TPM2B_IV * iv_out,AuthorizationDelegate * authorization_delegate)14388 TPM_RC Tpm::EncryptDecryptSync(const TPMI_DH_OBJECT& key_handle,
14389                                const std::string& key_handle_name,
14390                                const TPMI_YES_NO& decrypt,
14391                                const TPMI_ALG_SYM_MODE& mode,
14392                                const TPM2B_IV& iv_in,
14393                                const TPM2B_MAX_BUFFER& in_data,
14394                                TPM2B_MAX_BUFFER* out_data,
14395                                TPM2B_IV* iv_out,
14396                                AuthorizationDelegate* authorization_delegate) {
14397   VLOG(1) << __func__;
14398   std::string command;
14399   TPM_RC rc = SerializeCommand_EncryptDecrypt(key_handle, key_handle_name,
14400                                               decrypt, mode, iv_in, in_data,
14401                                               &command, authorization_delegate);
14402   if (rc != TPM_RC_SUCCESS) {
14403     return rc;
14404   }
14405   std::string response = transceiver_->SendCommandAndWait(command);
14406   rc = ParseResponse_EncryptDecrypt(response, out_data, iv_out,
14407                                     authorization_delegate);
14408   return rc;
14409 }
14410 
SerializeCommand_Hash(const TPM2B_MAX_BUFFER & data,const TPMI_ALG_HASH & hash_alg,const TPMI_RH_HIERARCHY & hierarchy,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14411 TPM_RC Tpm::SerializeCommand_Hash(
14412     const TPM2B_MAX_BUFFER& data,
14413     const TPMI_ALG_HASH& hash_alg,
14414     const TPMI_RH_HIERARCHY& hierarchy,
14415     std::string* serialized_command,
14416     AuthorizationDelegate* authorization_delegate) {
14417   VLOG(3) << __func__;
14418   TPM_RC rc = TPM_RC_SUCCESS;
14419   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14420   UINT32 command_size = 10;  // Header size.
14421   std::string handle_section_bytes;
14422   std::string parameter_section_bytes;
14423   TPM_CC command_code = TPM_CC_Hash;
14424   bool is_command_parameter_encryption_possible = true;
14425   bool is_response_parameter_encryption_possible = true;
14426   std::string command_code_bytes;
14427   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14428   if (rc != TPM_RC_SUCCESS) {
14429     return rc;
14430   }
14431   std::string data_bytes;
14432   rc = Serialize_TPM2B_MAX_BUFFER(data, &data_bytes);
14433   if (rc != TPM_RC_SUCCESS) {
14434     return rc;
14435   }
14436   std::string hash_alg_bytes;
14437   rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
14438   if (rc != TPM_RC_SUCCESS) {
14439     return rc;
14440   }
14441   std::string hierarchy_bytes;
14442   rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
14443   if (rc != TPM_RC_SUCCESS) {
14444     return rc;
14445   }
14446   if (authorization_delegate) {
14447     // Encrypt just the parameter data, not the size.
14448     std::string tmp = data_bytes.substr(2);
14449     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14450       return TRUNKS_RC_ENCRYPTION_FAILED;
14451     }
14452     data_bytes.replace(2, std::string::npos, tmp);
14453   }
14454   std::unique_ptr<crypto::SecureHash> hash(
14455       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14456   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14457   hash->Update(data_bytes.data(), data_bytes.size());
14458   parameter_section_bytes += data_bytes;
14459   command_size += data_bytes.size();
14460   hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
14461   parameter_section_bytes += hash_alg_bytes;
14462   command_size += hash_alg_bytes.size();
14463   hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
14464   parameter_section_bytes += hierarchy_bytes;
14465   command_size += hierarchy_bytes.size();
14466   std::string command_hash(32, 0);
14467   hash->Finish(std::data(command_hash), command_hash.size());
14468   std::string authorization_section_bytes;
14469   std::string authorization_size_bytes;
14470   if (authorization_delegate) {
14471     if (!authorization_delegate->GetCommandAuthorization(
14472             command_hash, is_command_parameter_encryption_possible,
14473             is_response_parameter_encryption_possible,
14474             &authorization_section_bytes)) {
14475       return TRUNKS_RC_AUTHORIZATION_FAILED;
14476     }
14477     if (!authorization_section_bytes.empty()) {
14478       tag = TPM_ST_SESSIONS;
14479       std::string tmp;
14480       rc = Serialize_UINT32(authorization_section_bytes.size(),
14481                             &authorization_size_bytes);
14482       if (rc != TPM_RC_SUCCESS) {
14483         return rc;
14484       }
14485       command_size +=
14486           authorization_size_bytes.size() + authorization_section_bytes.size();
14487     }
14488   }
14489   std::string tag_bytes;
14490   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14491   if (rc != TPM_RC_SUCCESS) {
14492     return rc;
14493   }
14494   std::string command_size_bytes;
14495   rc = Serialize_UINT32(command_size, &command_size_bytes);
14496   if (rc != TPM_RC_SUCCESS) {
14497     return rc;
14498   }
14499   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14500                         handle_section_bytes + authorization_size_bytes +
14501                         authorization_section_bytes + parameter_section_bytes;
14502   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14503   VLOG(2) << "Command: "
14504           << base::HexEncode(serialized_command->data(),
14505                              serialized_command->size());
14506   return TPM_RC_SUCCESS;
14507 }
14508 
ParseResponse_Hash(const std::string & response,TPM2B_DIGEST * out_hash,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)14509 TPM_RC Tpm::ParseResponse_Hash(const std::string& response,
14510                                TPM2B_DIGEST* out_hash,
14511                                TPMT_TK_HASHCHECK* validation,
14512                                AuthorizationDelegate* authorization_delegate) {
14513   VLOG(3) << __func__;
14514   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14515   TPM_RC rc = TPM_RC_SUCCESS;
14516   std::string buffer(response);
14517   TPM_ST tag;
14518   std::string tag_bytes;
14519   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14520   if (rc != TPM_RC_SUCCESS) {
14521     return rc;
14522   }
14523   UINT32 response_size;
14524   std::string response_size_bytes;
14525   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14526   if (rc != TPM_RC_SUCCESS) {
14527     return rc;
14528   }
14529   TPM_RC response_code;
14530   std::string response_code_bytes;
14531   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14532   if (rc != TPM_RC_SUCCESS) {
14533     return rc;
14534   }
14535   if (response_size != response.size()) {
14536     return TPM_RC_SIZE;
14537   }
14538   if (response_code != TPM_RC_SUCCESS) {
14539     return response_code;
14540   }
14541   TPM_CC command_code = TPM_CC_Hash;
14542   std::string command_code_bytes;
14543   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14544   if (rc != TPM_RC_SUCCESS) {
14545     return rc;
14546   }
14547   std::string authorization_section_bytes;
14548   if (tag == TPM_ST_SESSIONS) {
14549     UINT32 parameter_section_size = buffer.size();
14550     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14551     if (rc != TPM_RC_SUCCESS) {
14552       return rc;
14553     }
14554     if (parameter_section_size > buffer.size()) {
14555       return TPM_RC_INSUFFICIENT;
14556     }
14557     authorization_section_bytes = buffer.substr(parameter_section_size);
14558     // Keep the parameter section in |buffer|.
14559     buffer.erase(parameter_section_size);
14560   }
14561   std::unique_ptr<crypto::SecureHash> hash(
14562       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14563   hash->Update(response_code_bytes.data(), response_code_bytes.size());
14564   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14565   hash->Update(buffer.data(), buffer.size());
14566   std::string response_hash(32, 0);
14567   hash->Finish(std::data(response_hash), response_hash.size());
14568   if (tag == TPM_ST_SESSIONS) {
14569     if (!authorization_delegate)
14570       return TRUNKS_RC_AUTHORIZATION_FAILED;
14571     if (!authorization_delegate->CheckResponseAuthorization(
14572             response_hash, authorization_section_bytes)) {
14573       return TRUNKS_RC_AUTHORIZATION_FAILED;
14574     }
14575   }
14576   if (tag == TPM_ST_SESSIONS) {
14577     if (!authorization_delegate)
14578       return TRUNKS_RC_AUTHORIZATION_FAILED;
14579 
14580     // Parse the encrypted parameter size.
14581     UINT16 size;
14582     std::string size_buffer = buffer.substr(0, 2);
14583     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14584       return result;
14585     }
14586     if (buffer.size() < 2 + size) {
14587       return TPM_RC_INSUFFICIENT;
14588     }
14589 
14590     // Decrypt just the parameter data, not the size.
14591     std::string decrypted_data = buffer.substr(2, size);
14592     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14593       return TRUNKS_RC_ENCRYPTION_FAILED;
14594     }
14595     buffer.replace(2, size, decrypted_data);
14596   }
14597   std::string out_hash_bytes;
14598   rc = Parse_TPM2B_DIGEST(&buffer, out_hash, &out_hash_bytes);
14599   if (rc != TPM_RC_SUCCESS) {
14600     return rc;
14601   }
14602   std::string validation_bytes;
14603   rc = Parse_TPMT_TK_HASHCHECK(&buffer, validation, &validation_bytes);
14604   if (rc != TPM_RC_SUCCESS) {
14605     return rc;
14606   }
14607   return TPM_RC_SUCCESS;
14608 }
14609 
HashErrorCallback(Tpm::HashResponse callback,TPM_RC response_code)14610 void HashErrorCallback(Tpm::HashResponse callback, TPM_RC response_code) {
14611   VLOG(1) << __func__;
14612   std::move(callback).Run(response_code, TPM2B_DIGEST(), TPMT_TK_HASHCHECK());
14613 }
14614 
HashResponseParser(Tpm::HashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14615 void HashResponseParser(Tpm::HashResponse callback,
14616                         AuthorizationDelegate* authorization_delegate,
14617                         const std::string& response) {
14618   VLOG(1) << __func__;
14619   TPM2B_DIGEST out_hash;
14620   TPMT_TK_HASHCHECK validation;
14621   TPM_RC rc = Tpm::ParseResponse_Hash(response, &out_hash, &validation,
14622                                       authorization_delegate);
14623   if (rc != TPM_RC_SUCCESS) {
14624     base::OnceCallback<void(TPM_RC)> error_reporter =
14625         base::BindOnce(HashErrorCallback, std::move(callback));
14626     std::move(error_reporter).Run(rc);
14627     return;
14628   }
14629   std::move(callback).Run(rc, out_hash, validation);
14630 }
14631 
Hash(const TPM2B_MAX_BUFFER & data,const TPMI_ALG_HASH & hash_alg,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,HashResponse callback)14632 void Tpm::Hash(const TPM2B_MAX_BUFFER& data,
14633                const TPMI_ALG_HASH& hash_alg,
14634                const TPMI_RH_HIERARCHY& hierarchy,
14635                AuthorizationDelegate* authorization_delegate,
14636                HashResponse callback) {
14637   VLOG(1) << __func__;
14638   std::string command;
14639   TPM_RC rc = SerializeCommand_Hash(data, hash_alg, hierarchy, &command,
14640                                     authorization_delegate);
14641   if (rc != TPM_RC_SUCCESS) {
14642     base::OnceCallback<void(TPM_RC)> error_reporter =
14643         base::BindOnce(HashErrorCallback, std::move(callback));
14644     std::move(error_reporter).Run(rc);
14645     return;
14646   }
14647   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14648       HashResponseParser, std::move(callback), authorization_delegate);
14649   transceiver_->SendCommand(command, std::move(parser));
14650 }
14651 
HashSync(const TPM2B_MAX_BUFFER & data,const TPMI_ALG_HASH & hash_alg,const TPMI_RH_HIERARCHY & hierarchy,TPM2B_DIGEST * out_hash,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)14652 TPM_RC Tpm::HashSync(const TPM2B_MAX_BUFFER& data,
14653                      const TPMI_ALG_HASH& hash_alg,
14654                      const TPMI_RH_HIERARCHY& hierarchy,
14655                      TPM2B_DIGEST* out_hash,
14656                      TPMT_TK_HASHCHECK* validation,
14657                      AuthorizationDelegate* authorization_delegate) {
14658   VLOG(1) << __func__;
14659   std::string command;
14660   TPM_RC rc = SerializeCommand_Hash(data, hash_alg, hierarchy, &command,
14661                                     authorization_delegate);
14662   if (rc != TPM_RC_SUCCESS) {
14663     return rc;
14664   }
14665   std::string response = transceiver_->SendCommandAndWait(command);
14666   rc = ParseResponse_Hash(response, out_hash, validation,
14667                           authorization_delegate);
14668   return rc;
14669 }
14670 
SerializeCommand_HMAC(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14671 TPM_RC Tpm::SerializeCommand_HMAC(
14672     const TPMI_DH_OBJECT& handle,
14673     const std::string& handle_name,
14674     const TPM2B_MAX_BUFFER& buffer,
14675     const TPMI_ALG_HASH& hash_alg,
14676     std::string* serialized_command,
14677     AuthorizationDelegate* authorization_delegate) {
14678   VLOG(3) << __func__;
14679   TPM_RC rc = TPM_RC_SUCCESS;
14680   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14681   UINT32 command_size = 10;  // Header size.
14682   std::string handle_section_bytes;
14683   std::string parameter_section_bytes;
14684   TPM_CC command_code = TPM_CC_HMAC;
14685   bool is_command_parameter_encryption_possible = true;
14686   bool is_response_parameter_encryption_possible = true;
14687   std::string command_code_bytes;
14688   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14689   if (rc != TPM_RC_SUCCESS) {
14690     return rc;
14691   }
14692   std::string handle_bytes;
14693   rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
14694   if (rc != TPM_RC_SUCCESS) {
14695     return rc;
14696   }
14697   std::string buffer_bytes;
14698   rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
14699   if (rc != TPM_RC_SUCCESS) {
14700     return rc;
14701   }
14702   std::string hash_alg_bytes;
14703   rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
14704   if (rc != TPM_RC_SUCCESS) {
14705     return rc;
14706   }
14707   if (authorization_delegate) {
14708     // Encrypt just the parameter data, not the size.
14709     std::string tmp = buffer_bytes.substr(2);
14710     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
14711       return TRUNKS_RC_ENCRYPTION_FAILED;
14712     }
14713     buffer_bytes.replace(2, std::string::npos, tmp);
14714   }
14715   std::unique_ptr<crypto::SecureHash> hash(
14716       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14717   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14718   hash->Update(handle_name.data(), handle_name.size());
14719   handle_section_bytes += handle_bytes;
14720   command_size += handle_bytes.size();
14721   hash->Update(buffer_bytes.data(), buffer_bytes.size());
14722   parameter_section_bytes += buffer_bytes;
14723   command_size += buffer_bytes.size();
14724   hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
14725   parameter_section_bytes += hash_alg_bytes;
14726   command_size += hash_alg_bytes.size();
14727   std::string command_hash(32, 0);
14728   hash->Finish(std::data(command_hash), command_hash.size());
14729   std::string authorization_section_bytes;
14730   std::string authorization_size_bytes;
14731   if (authorization_delegate) {
14732     if (!authorization_delegate->GetCommandAuthorization(
14733             command_hash, is_command_parameter_encryption_possible,
14734             is_response_parameter_encryption_possible,
14735             &authorization_section_bytes)) {
14736       return TRUNKS_RC_AUTHORIZATION_FAILED;
14737     }
14738     if (!authorization_section_bytes.empty()) {
14739       tag = TPM_ST_SESSIONS;
14740       std::string tmp;
14741       rc = Serialize_UINT32(authorization_section_bytes.size(),
14742                             &authorization_size_bytes);
14743       if (rc != TPM_RC_SUCCESS) {
14744         return rc;
14745       }
14746       command_size +=
14747           authorization_size_bytes.size() + authorization_section_bytes.size();
14748     }
14749   }
14750   std::string tag_bytes;
14751   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14752   if (rc != TPM_RC_SUCCESS) {
14753     return rc;
14754   }
14755   std::string command_size_bytes;
14756   rc = Serialize_UINT32(command_size, &command_size_bytes);
14757   if (rc != TPM_RC_SUCCESS) {
14758     return rc;
14759   }
14760   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14761                         handle_section_bytes + authorization_size_bytes +
14762                         authorization_section_bytes + parameter_section_bytes;
14763   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14764   VLOG(2) << "Command: "
14765           << base::HexEncode(serialized_command->data(),
14766                              serialized_command->size());
14767   return TPM_RC_SUCCESS;
14768 }
14769 
ParseResponse_HMAC(const std::string & response,TPM2B_DIGEST * out_hmac,AuthorizationDelegate * authorization_delegate)14770 TPM_RC Tpm::ParseResponse_HMAC(const std::string& response,
14771                                TPM2B_DIGEST* out_hmac,
14772                                AuthorizationDelegate* authorization_delegate) {
14773   VLOG(3) << __func__;
14774   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
14775   TPM_RC rc = TPM_RC_SUCCESS;
14776   std::string buffer(response);
14777   TPM_ST tag;
14778   std::string tag_bytes;
14779   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
14780   if (rc != TPM_RC_SUCCESS) {
14781     return rc;
14782   }
14783   UINT32 response_size;
14784   std::string response_size_bytes;
14785   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
14786   if (rc != TPM_RC_SUCCESS) {
14787     return rc;
14788   }
14789   TPM_RC response_code;
14790   std::string response_code_bytes;
14791   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
14792   if (rc != TPM_RC_SUCCESS) {
14793     return rc;
14794   }
14795   if (response_size != response.size()) {
14796     return TPM_RC_SIZE;
14797   }
14798   if (response_code != TPM_RC_SUCCESS) {
14799     return response_code;
14800   }
14801   TPM_CC command_code = TPM_CC_HMAC;
14802   std::string command_code_bytes;
14803   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14804   if (rc != TPM_RC_SUCCESS) {
14805     return rc;
14806   }
14807   std::string authorization_section_bytes;
14808   if (tag == TPM_ST_SESSIONS) {
14809     UINT32 parameter_section_size = buffer.size();
14810     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
14811     if (rc != TPM_RC_SUCCESS) {
14812       return rc;
14813     }
14814     if (parameter_section_size > buffer.size()) {
14815       return TPM_RC_INSUFFICIENT;
14816     }
14817     authorization_section_bytes = buffer.substr(parameter_section_size);
14818     // Keep the parameter section in |buffer|.
14819     buffer.erase(parameter_section_size);
14820   }
14821   std::unique_ptr<crypto::SecureHash> hash(
14822       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14823   hash->Update(response_code_bytes.data(), response_code_bytes.size());
14824   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14825   hash->Update(buffer.data(), buffer.size());
14826   std::string response_hash(32, 0);
14827   hash->Finish(std::data(response_hash), response_hash.size());
14828   if (tag == TPM_ST_SESSIONS) {
14829     if (!authorization_delegate)
14830       return TRUNKS_RC_AUTHORIZATION_FAILED;
14831     if (!authorization_delegate->CheckResponseAuthorization(
14832             response_hash, authorization_section_bytes)) {
14833       return TRUNKS_RC_AUTHORIZATION_FAILED;
14834     }
14835   }
14836   if (tag == TPM_ST_SESSIONS) {
14837     if (!authorization_delegate)
14838       return TRUNKS_RC_AUTHORIZATION_FAILED;
14839 
14840     // Parse the encrypted parameter size.
14841     UINT16 size;
14842     std::string size_buffer = buffer.substr(0, 2);
14843     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
14844       return result;
14845     }
14846     if (buffer.size() < 2 + size) {
14847       return TPM_RC_INSUFFICIENT;
14848     }
14849 
14850     // Decrypt just the parameter data, not the size.
14851     std::string decrypted_data = buffer.substr(2, size);
14852     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
14853       return TRUNKS_RC_ENCRYPTION_FAILED;
14854     }
14855     buffer.replace(2, size, decrypted_data);
14856   }
14857   std::string out_hmac_bytes;
14858   rc = Parse_TPM2B_DIGEST(&buffer, out_hmac, &out_hmac_bytes);
14859   if (rc != TPM_RC_SUCCESS) {
14860     return rc;
14861   }
14862   return TPM_RC_SUCCESS;
14863 }
14864 
HMACErrorCallback(Tpm::HMACResponse callback,TPM_RC response_code)14865 void HMACErrorCallback(Tpm::HMACResponse callback, TPM_RC response_code) {
14866   VLOG(1) << __func__;
14867   std::move(callback).Run(response_code, TPM2B_DIGEST());
14868 }
14869 
HMACResponseParser(Tpm::HMACResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)14870 void HMACResponseParser(Tpm::HMACResponse callback,
14871                         AuthorizationDelegate* authorization_delegate,
14872                         const std::string& response) {
14873   VLOG(1) << __func__;
14874   TPM2B_DIGEST out_hmac;
14875   TPM_RC rc =
14876       Tpm::ParseResponse_HMAC(response, &out_hmac, authorization_delegate);
14877   if (rc != TPM_RC_SUCCESS) {
14878     base::OnceCallback<void(TPM_RC)> error_reporter =
14879         base::BindOnce(HMACErrorCallback, std::move(callback));
14880     std::move(error_reporter).Run(rc);
14881     return;
14882   }
14883   std::move(callback).Run(rc, out_hmac);
14884 }
14885 
HMAC(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,HMACResponse callback)14886 void Tpm::HMAC(const TPMI_DH_OBJECT& handle,
14887                const std::string& handle_name,
14888                const TPM2B_MAX_BUFFER& buffer,
14889                const TPMI_ALG_HASH& hash_alg,
14890                AuthorizationDelegate* authorization_delegate,
14891                HMACResponse callback) {
14892   VLOG(1) << __func__;
14893   std::string command;
14894   TPM_RC rc = SerializeCommand_HMAC(handle, handle_name, buffer, hash_alg,
14895                                     &command, authorization_delegate);
14896   if (rc != TPM_RC_SUCCESS) {
14897     base::OnceCallback<void(TPM_RC)> error_reporter =
14898         base::BindOnce(HMACErrorCallback, std::move(callback));
14899     std::move(error_reporter).Run(rc);
14900     return;
14901   }
14902   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
14903       HMACResponseParser, std::move(callback), authorization_delegate);
14904   transceiver_->SendCommand(command, std::move(parser));
14905 }
14906 
HMACSync(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_ALG_HASH & hash_alg,TPM2B_DIGEST * out_hmac,AuthorizationDelegate * authorization_delegate)14907 TPM_RC Tpm::HMACSync(const TPMI_DH_OBJECT& handle,
14908                      const std::string& handle_name,
14909                      const TPM2B_MAX_BUFFER& buffer,
14910                      const TPMI_ALG_HASH& hash_alg,
14911                      TPM2B_DIGEST* out_hmac,
14912                      AuthorizationDelegate* authorization_delegate) {
14913   VLOG(1) << __func__;
14914   std::string command;
14915   TPM_RC rc = SerializeCommand_HMAC(handle, handle_name, buffer, hash_alg,
14916                                     &command, authorization_delegate);
14917   if (rc != TPM_RC_SUCCESS) {
14918     return rc;
14919   }
14920   std::string response = transceiver_->SendCommandAndWait(command);
14921   rc = ParseResponse_HMAC(response, out_hmac, authorization_delegate);
14922   return rc;
14923 }
14924 
SerializeCommand_GetRandom(const UINT16 & bytes_requested,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)14925 TPM_RC Tpm::SerializeCommand_GetRandom(
14926     const UINT16& bytes_requested,
14927     std::string* serialized_command,
14928     AuthorizationDelegate* authorization_delegate) {
14929   VLOG(3) << __func__;
14930   TPM_RC rc = TPM_RC_SUCCESS;
14931   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
14932   UINT32 command_size = 10;  // Header size.
14933   std::string handle_section_bytes;
14934   std::string parameter_section_bytes;
14935   TPM_CC command_code = TPM_CC_GetRandom;
14936   bool is_command_parameter_encryption_possible = false;
14937   bool is_response_parameter_encryption_possible = true;
14938   std::string command_code_bytes;
14939   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
14940   if (rc != TPM_RC_SUCCESS) {
14941     return rc;
14942   }
14943   std::string bytes_requested_bytes;
14944   rc = Serialize_UINT16(bytes_requested, &bytes_requested_bytes);
14945   if (rc != TPM_RC_SUCCESS) {
14946     return rc;
14947   }
14948   std::unique_ptr<crypto::SecureHash> hash(
14949       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
14950   hash->Update(command_code_bytes.data(), command_code_bytes.size());
14951   hash->Update(bytes_requested_bytes.data(), bytes_requested_bytes.size());
14952   parameter_section_bytes += bytes_requested_bytes;
14953   command_size += bytes_requested_bytes.size();
14954   std::string command_hash(32, 0);
14955   hash->Finish(std::data(command_hash), command_hash.size());
14956   std::string authorization_section_bytes;
14957   std::string authorization_size_bytes;
14958   if (authorization_delegate) {
14959     if (!authorization_delegate->GetCommandAuthorization(
14960             command_hash, is_command_parameter_encryption_possible,
14961             is_response_parameter_encryption_possible,
14962             &authorization_section_bytes)) {
14963       return TRUNKS_RC_AUTHORIZATION_FAILED;
14964     }
14965     if (!authorization_section_bytes.empty()) {
14966       tag = TPM_ST_SESSIONS;
14967       std::string tmp;
14968       rc = Serialize_UINT32(authorization_section_bytes.size(),
14969                             &authorization_size_bytes);
14970       if (rc != TPM_RC_SUCCESS) {
14971         return rc;
14972       }
14973       command_size +=
14974           authorization_size_bytes.size() + authorization_section_bytes.size();
14975     }
14976   }
14977   std::string tag_bytes;
14978   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
14979   if (rc != TPM_RC_SUCCESS) {
14980     return rc;
14981   }
14982   std::string command_size_bytes;
14983   rc = Serialize_UINT32(command_size, &command_size_bytes);
14984   if (rc != TPM_RC_SUCCESS) {
14985     return rc;
14986   }
14987   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
14988                         handle_section_bytes + authorization_size_bytes +
14989                         authorization_section_bytes + parameter_section_bytes;
14990   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
14991   VLOG(2) << "Command: "
14992           << base::HexEncode(serialized_command->data(),
14993                              serialized_command->size());
14994   return TPM_RC_SUCCESS;
14995 }
14996 
ParseResponse_GetRandom(const std::string & response,TPM2B_DIGEST * random_bytes,AuthorizationDelegate * authorization_delegate)14997 TPM_RC Tpm::ParseResponse_GetRandom(
14998     const std::string& response,
14999     TPM2B_DIGEST* random_bytes,
15000     AuthorizationDelegate* authorization_delegate) {
15001   VLOG(3) << __func__;
15002   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15003   TPM_RC rc = TPM_RC_SUCCESS;
15004   std::string buffer(response);
15005   TPM_ST tag;
15006   std::string tag_bytes;
15007   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15008   if (rc != TPM_RC_SUCCESS) {
15009     return rc;
15010   }
15011   UINT32 response_size;
15012   std::string response_size_bytes;
15013   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15014   if (rc != TPM_RC_SUCCESS) {
15015     return rc;
15016   }
15017   TPM_RC response_code;
15018   std::string response_code_bytes;
15019   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15020   if (rc != TPM_RC_SUCCESS) {
15021     return rc;
15022   }
15023   if (response_size != response.size()) {
15024     return TPM_RC_SIZE;
15025   }
15026   if (response_code != TPM_RC_SUCCESS) {
15027     return response_code;
15028   }
15029   TPM_CC command_code = TPM_CC_GetRandom;
15030   std::string command_code_bytes;
15031   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15032   if (rc != TPM_RC_SUCCESS) {
15033     return rc;
15034   }
15035   std::string authorization_section_bytes;
15036   if (tag == TPM_ST_SESSIONS) {
15037     UINT32 parameter_section_size = buffer.size();
15038     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15039     if (rc != TPM_RC_SUCCESS) {
15040       return rc;
15041     }
15042     if (parameter_section_size > buffer.size()) {
15043       return TPM_RC_INSUFFICIENT;
15044     }
15045     authorization_section_bytes = buffer.substr(parameter_section_size);
15046     // Keep the parameter section in |buffer|.
15047     buffer.erase(parameter_section_size);
15048   }
15049   std::unique_ptr<crypto::SecureHash> hash(
15050       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15051   hash->Update(response_code_bytes.data(), response_code_bytes.size());
15052   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15053   hash->Update(buffer.data(), buffer.size());
15054   std::string response_hash(32, 0);
15055   hash->Finish(std::data(response_hash), response_hash.size());
15056   if (tag == TPM_ST_SESSIONS) {
15057     if (!authorization_delegate)
15058       return TRUNKS_RC_AUTHORIZATION_FAILED;
15059     if (!authorization_delegate->CheckResponseAuthorization(
15060             response_hash, authorization_section_bytes)) {
15061       return TRUNKS_RC_AUTHORIZATION_FAILED;
15062     }
15063   }
15064   if (tag == TPM_ST_SESSIONS) {
15065     if (!authorization_delegate)
15066       return TRUNKS_RC_AUTHORIZATION_FAILED;
15067 
15068     // Parse the encrypted parameter size.
15069     UINT16 size;
15070     std::string size_buffer = buffer.substr(0, 2);
15071     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
15072       return result;
15073     }
15074     if (buffer.size() < 2 + size) {
15075       return TPM_RC_INSUFFICIENT;
15076     }
15077 
15078     // Decrypt just the parameter data, not the size.
15079     std::string decrypted_data = buffer.substr(2, size);
15080     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
15081       return TRUNKS_RC_ENCRYPTION_FAILED;
15082     }
15083     buffer.replace(2, size, decrypted_data);
15084   }
15085   std::string random_bytes_bytes;
15086   rc = Parse_TPM2B_DIGEST(&buffer, random_bytes, &random_bytes_bytes);
15087   if (rc != TPM_RC_SUCCESS) {
15088     return rc;
15089   }
15090   return TPM_RC_SUCCESS;
15091 }
15092 
GetRandomErrorCallback(Tpm::GetRandomResponse callback,TPM_RC response_code)15093 void GetRandomErrorCallback(Tpm::GetRandomResponse callback,
15094                             TPM_RC response_code) {
15095   VLOG(1) << __func__;
15096   std::move(callback).Run(response_code, TPM2B_DIGEST());
15097 }
15098 
GetRandomResponseParser(Tpm::GetRandomResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15099 void GetRandomResponseParser(Tpm::GetRandomResponse callback,
15100                              AuthorizationDelegate* authorization_delegate,
15101                              const std::string& response) {
15102   VLOG(1) << __func__;
15103   TPM2B_DIGEST random_bytes;
15104   TPM_RC rc = Tpm::ParseResponse_GetRandom(response, &random_bytes,
15105                                            authorization_delegate);
15106   if (rc != TPM_RC_SUCCESS) {
15107     base::OnceCallback<void(TPM_RC)> error_reporter =
15108         base::BindOnce(GetRandomErrorCallback, std::move(callback));
15109     std::move(error_reporter).Run(rc);
15110     return;
15111   }
15112   std::move(callback).Run(rc, random_bytes);
15113 }
15114 
GetRandom(const UINT16 & bytes_requested,AuthorizationDelegate * authorization_delegate,GetRandomResponse callback)15115 void Tpm::GetRandom(const UINT16& bytes_requested,
15116                     AuthorizationDelegate* authorization_delegate,
15117                     GetRandomResponse callback) {
15118   VLOG(1) << __func__;
15119   std::string command;
15120   TPM_RC rc = SerializeCommand_GetRandom(bytes_requested, &command,
15121                                          authorization_delegate);
15122   if (rc != TPM_RC_SUCCESS) {
15123     base::OnceCallback<void(TPM_RC)> error_reporter =
15124         base::BindOnce(GetRandomErrorCallback, std::move(callback));
15125     std::move(error_reporter).Run(rc);
15126     return;
15127   }
15128   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15129       GetRandomResponseParser, std::move(callback), authorization_delegate);
15130   transceiver_->SendCommand(command, std::move(parser));
15131 }
15132 
GetRandomSync(const UINT16 & bytes_requested,TPM2B_DIGEST * random_bytes,AuthorizationDelegate * authorization_delegate)15133 TPM_RC Tpm::GetRandomSync(const UINT16& bytes_requested,
15134                           TPM2B_DIGEST* random_bytes,
15135                           AuthorizationDelegate* authorization_delegate) {
15136   VLOG(1) << __func__;
15137   std::string command;
15138   TPM_RC rc = SerializeCommand_GetRandom(bytes_requested, &command,
15139                                          authorization_delegate);
15140   if (rc != TPM_RC_SUCCESS) {
15141     return rc;
15142   }
15143   std::string response = transceiver_->SendCommandAndWait(command);
15144   rc = ParseResponse_GetRandom(response, random_bytes, authorization_delegate);
15145   return rc;
15146 }
15147 
SerializeCommand_StirRandom(const TPM2B_SENSITIVE_DATA & in_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15148 TPM_RC Tpm::SerializeCommand_StirRandom(
15149     const TPM2B_SENSITIVE_DATA& in_data,
15150     std::string* serialized_command,
15151     AuthorizationDelegate* authorization_delegate) {
15152   VLOG(3) << __func__;
15153   TPM_RC rc = TPM_RC_SUCCESS;
15154   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15155   UINT32 command_size = 10;  // Header size.
15156   std::string handle_section_bytes;
15157   std::string parameter_section_bytes;
15158   TPM_CC command_code = TPM_CC_StirRandom;
15159   bool is_command_parameter_encryption_possible = true;
15160   bool is_response_parameter_encryption_possible = false;
15161   std::string command_code_bytes;
15162   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15163   if (rc != TPM_RC_SUCCESS) {
15164     return rc;
15165   }
15166   std::string in_data_bytes;
15167   rc = Serialize_TPM2B_SENSITIVE_DATA(in_data, &in_data_bytes);
15168   if (rc != TPM_RC_SUCCESS) {
15169     return rc;
15170   }
15171   if (authorization_delegate) {
15172     // Encrypt just the parameter data, not the size.
15173     std::string tmp = in_data_bytes.substr(2);
15174     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15175       return TRUNKS_RC_ENCRYPTION_FAILED;
15176     }
15177     in_data_bytes.replace(2, std::string::npos, tmp);
15178   }
15179   std::unique_ptr<crypto::SecureHash> hash(
15180       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15181   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15182   hash->Update(in_data_bytes.data(), in_data_bytes.size());
15183   parameter_section_bytes += in_data_bytes;
15184   command_size += in_data_bytes.size();
15185   std::string command_hash(32, 0);
15186   hash->Finish(std::data(command_hash), command_hash.size());
15187   std::string authorization_section_bytes;
15188   std::string authorization_size_bytes;
15189   if (authorization_delegate) {
15190     if (!authorization_delegate->GetCommandAuthorization(
15191             command_hash, is_command_parameter_encryption_possible,
15192             is_response_parameter_encryption_possible,
15193             &authorization_section_bytes)) {
15194       return TRUNKS_RC_AUTHORIZATION_FAILED;
15195     }
15196     if (!authorization_section_bytes.empty()) {
15197       tag = TPM_ST_SESSIONS;
15198       std::string tmp;
15199       rc = Serialize_UINT32(authorization_section_bytes.size(),
15200                             &authorization_size_bytes);
15201       if (rc != TPM_RC_SUCCESS) {
15202         return rc;
15203       }
15204       command_size +=
15205           authorization_size_bytes.size() + authorization_section_bytes.size();
15206     }
15207   }
15208   std::string tag_bytes;
15209   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15210   if (rc != TPM_RC_SUCCESS) {
15211     return rc;
15212   }
15213   std::string command_size_bytes;
15214   rc = Serialize_UINT32(command_size, &command_size_bytes);
15215   if (rc != TPM_RC_SUCCESS) {
15216     return rc;
15217   }
15218   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15219                         handle_section_bytes + authorization_size_bytes +
15220                         authorization_section_bytes + parameter_section_bytes;
15221   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15222   VLOG(2) << "Command: "
15223           << base::HexEncode(serialized_command->data(),
15224                              serialized_command->size());
15225   return TPM_RC_SUCCESS;
15226 }
15227 
ParseResponse_StirRandom(const std::string & response,AuthorizationDelegate * authorization_delegate)15228 TPM_RC Tpm::ParseResponse_StirRandom(
15229     const std::string& response,
15230     AuthorizationDelegate* authorization_delegate) {
15231   VLOG(3) << __func__;
15232   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15233   TPM_RC rc = TPM_RC_SUCCESS;
15234   std::string buffer(response);
15235   TPM_ST tag;
15236   std::string tag_bytes;
15237   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15238   if (rc != TPM_RC_SUCCESS) {
15239     return rc;
15240   }
15241   UINT32 response_size;
15242   std::string response_size_bytes;
15243   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15244   if (rc != TPM_RC_SUCCESS) {
15245     return rc;
15246   }
15247   TPM_RC response_code;
15248   std::string response_code_bytes;
15249   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15250   if (rc != TPM_RC_SUCCESS) {
15251     return rc;
15252   }
15253   if (response_size != response.size()) {
15254     return TPM_RC_SIZE;
15255   }
15256   if (response_code != TPM_RC_SUCCESS) {
15257     return response_code;
15258   }
15259   TPM_CC command_code = TPM_CC_StirRandom;
15260   std::string command_code_bytes;
15261   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15262   if (rc != TPM_RC_SUCCESS) {
15263     return rc;
15264   }
15265   std::string authorization_section_bytes;
15266   if (tag == TPM_ST_SESSIONS) {
15267     UINT32 parameter_section_size = buffer.size();
15268     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15269     if (rc != TPM_RC_SUCCESS) {
15270       return rc;
15271     }
15272     if (parameter_section_size > buffer.size()) {
15273       return TPM_RC_INSUFFICIENT;
15274     }
15275     authorization_section_bytes = buffer.substr(parameter_section_size);
15276     // Keep the parameter section in |buffer|.
15277     buffer.erase(parameter_section_size);
15278   }
15279   std::unique_ptr<crypto::SecureHash> hash(
15280       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15281   hash->Update(response_code_bytes.data(), response_code_bytes.size());
15282   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15283   hash->Update(buffer.data(), buffer.size());
15284   std::string response_hash(32, 0);
15285   hash->Finish(std::data(response_hash), response_hash.size());
15286   if (tag == TPM_ST_SESSIONS) {
15287     if (!authorization_delegate)
15288       return TRUNKS_RC_AUTHORIZATION_FAILED;
15289     if (!authorization_delegate->CheckResponseAuthorization(
15290             response_hash, authorization_section_bytes)) {
15291       return TRUNKS_RC_AUTHORIZATION_FAILED;
15292     }
15293   }
15294   return TPM_RC_SUCCESS;
15295 }
15296 
StirRandomErrorCallback(Tpm::StirRandomResponse callback,TPM_RC response_code)15297 void StirRandomErrorCallback(Tpm::StirRandomResponse callback,
15298                              TPM_RC response_code) {
15299   VLOG(1) << __func__;
15300   std::move(callback).Run(response_code);
15301 }
15302 
StirRandomResponseParser(Tpm::StirRandomResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15303 void StirRandomResponseParser(Tpm::StirRandomResponse callback,
15304                               AuthorizationDelegate* authorization_delegate,
15305                               const std::string& response) {
15306   VLOG(1) << __func__;
15307   TPM_RC rc = Tpm::ParseResponse_StirRandom(response, authorization_delegate);
15308   if (rc != TPM_RC_SUCCESS) {
15309     base::OnceCallback<void(TPM_RC)> error_reporter =
15310         base::BindOnce(StirRandomErrorCallback, std::move(callback));
15311     std::move(error_reporter).Run(rc);
15312     return;
15313   }
15314   std::move(callback).Run(rc);
15315 }
15316 
StirRandom(const TPM2B_SENSITIVE_DATA & in_data,AuthorizationDelegate * authorization_delegate,StirRandomResponse callback)15317 void Tpm::StirRandom(const TPM2B_SENSITIVE_DATA& in_data,
15318                      AuthorizationDelegate* authorization_delegate,
15319                      StirRandomResponse callback) {
15320   VLOG(1) << __func__;
15321   std::string command;
15322   TPM_RC rc =
15323       SerializeCommand_StirRandom(in_data, &command, authorization_delegate);
15324   if (rc != TPM_RC_SUCCESS) {
15325     base::OnceCallback<void(TPM_RC)> error_reporter =
15326         base::BindOnce(StirRandomErrorCallback, std::move(callback));
15327     std::move(error_reporter).Run(rc);
15328     return;
15329   }
15330   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15331       StirRandomResponseParser, std::move(callback), authorization_delegate);
15332   transceiver_->SendCommand(command, std::move(parser));
15333 }
15334 
StirRandomSync(const TPM2B_SENSITIVE_DATA & in_data,AuthorizationDelegate * authorization_delegate)15335 TPM_RC Tpm::StirRandomSync(const TPM2B_SENSITIVE_DATA& in_data,
15336                            AuthorizationDelegate* authorization_delegate) {
15337   VLOG(1) << __func__;
15338   std::string command;
15339   TPM_RC rc =
15340       SerializeCommand_StirRandom(in_data, &command, authorization_delegate);
15341   if (rc != TPM_RC_SUCCESS) {
15342     return rc;
15343   }
15344   std::string response = transceiver_->SendCommandAndWait(command);
15345   rc = ParseResponse_StirRandom(response, authorization_delegate);
15346   return rc;
15347 }
15348 
SerializeCommand_HMAC_Start(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15349 TPM_RC Tpm::SerializeCommand_HMAC_Start(
15350     const TPMI_DH_OBJECT& handle,
15351     const std::string& handle_name,
15352     const TPM2B_AUTH& auth,
15353     const TPMI_ALG_HASH& hash_alg,
15354     std::string* serialized_command,
15355     AuthorizationDelegate* authorization_delegate) {
15356   VLOG(3) << __func__;
15357   TPM_RC rc = TPM_RC_SUCCESS;
15358   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15359   UINT32 command_size = 10;  // Header size.
15360   std::string handle_section_bytes;
15361   std::string parameter_section_bytes;
15362   TPM_CC command_code = TPM_CC_HMAC_Start;
15363   bool is_command_parameter_encryption_possible = true;
15364   bool is_response_parameter_encryption_possible = false;
15365   std::string command_code_bytes;
15366   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15367   if (rc != TPM_RC_SUCCESS) {
15368     return rc;
15369   }
15370   std::string handle_bytes;
15371   rc = Serialize_TPMI_DH_OBJECT(handle, &handle_bytes);
15372   if (rc != TPM_RC_SUCCESS) {
15373     return rc;
15374   }
15375   std::string auth_bytes;
15376   rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
15377   if (rc != TPM_RC_SUCCESS) {
15378     return rc;
15379   }
15380   std::string hash_alg_bytes;
15381   rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
15382   if (rc != TPM_RC_SUCCESS) {
15383     return rc;
15384   }
15385   if (authorization_delegate) {
15386     // Encrypt just the parameter data, not the size.
15387     std::string tmp = auth_bytes.substr(2);
15388     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15389       return TRUNKS_RC_ENCRYPTION_FAILED;
15390     }
15391     auth_bytes.replace(2, std::string::npos, tmp);
15392   }
15393   std::unique_ptr<crypto::SecureHash> hash(
15394       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15395   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15396   hash->Update(handle_name.data(), handle_name.size());
15397   handle_section_bytes += handle_bytes;
15398   command_size += handle_bytes.size();
15399   hash->Update(auth_bytes.data(), auth_bytes.size());
15400   parameter_section_bytes += auth_bytes;
15401   command_size += auth_bytes.size();
15402   hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
15403   parameter_section_bytes += hash_alg_bytes;
15404   command_size += hash_alg_bytes.size();
15405   std::string command_hash(32, 0);
15406   hash->Finish(std::data(command_hash), command_hash.size());
15407   std::string authorization_section_bytes;
15408   std::string authorization_size_bytes;
15409   if (authorization_delegate) {
15410     if (!authorization_delegate->GetCommandAuthorization(
15411             command_hash, is_command_parameter_encryption_possible,
15412             is_response_parameter_encryption_possible,
15413             &authorization_section_bytes)) {
15414       return TRUNKS_RC_AUTHORIZATION_FAILED;
15415     }
15416     if (!authorization_section_bytes.empty()) {
15417       tag = TPM_ST_SESSIONS;
15418       std::string tmp;
15419       rc = Serialize_UINT32(authorization_section_bytes.size(),
15420                             &authorization_size_bytes);
15421       if (rc != TPM_RC_SUCCESS) {
15422         return rc;
15423       }
15424       command_size +=
15425           authorization_size_bytes.size() + authorization_section_bytes.size();
15426     }
15427   }
15428   std::string tag_bytes;
15429   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15430   if (rc != TPM_RC_SUCCESS) {
15431     return rc;
15432   }
15433   std::string command_size_bytes;
15434   rc = Serialize_UINT32(command_size, &command_size_bytes);
15435   if (rc != TPM_RC_SUCCESS) {
15436     return rc;
15437   }
15438   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15439                         handle_section_bytes + authorization_size_bytes +
15440                         authorization_section_bytes + parameter_section_bytes;
15441   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15442   VLOG(2) << "Command: "
15443           << base::HexEncode(serialized_command->data(),
15444                              serialized_command->size());
15445   return TPM_RC_SUCCESS;
15446 }
15447 
ParseResponse_HMAC_Start(const std::string & response,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15448 TPM_RC Tpm::ParseResponse_HMAC_Start(
15449     const std::string& response,
15450     TPMI_DH_OBJECT* sequence_handle,
15451     AuthorizationDelegate* authorization_delegate) {
15452   VLOG(3) << __func__;
15453   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15454   TPM_RC rc = TPM_RC_SUCCESS;
15455   std::string buffer(response);
15456   TPM_ST tag;
15457   std::string tag_bytes;
15458   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15459   if (rc != TPM_RC_SUCCESS) {
15460     return rc;
15461   }
15462   UINT32 response_size;
15463   std::string response_size_bytes;
15464   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15465   if (rc != TPM_RC_SUCCESS) {
15466     return rc;
15467   }
15468   TPM_RC response_code;
15469   std::string response_code_bytes;
15470   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15471   if (rc != TPM_RC_SUCCESS) {
15472     return rc;
15473   }
15474   if (response_size != response.size()) {
15475     return TPM_RC_SIZE;
15476   }
15477   if (response_code != TPM_RC_SUCCESS) {
15478     return response_code;
15479   }
15480   std::string sequence_handle_bytes;
15481   rc = Parse_TPMI_DH_OBJECT(&buffer, sequence_handle, &sequence_handle_bytes);
15482   if (rc != TPM_RC_SUCCESS) {
15483     return rc;
15484   }
15485   TPM_CC command_code = TPM_CC_HMAC_Start;
15486   std::string command_code_bytes;
15487   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15488   if (rc != TPM_RC_SUCCESS) {
15489     return rc;
15490   }
15491   std::string authorization_section_bytes;
15492   if (tag == TPM_ST_SESSIONS) {
15493     UINT32 parameter_section_size = buffer.size();
15494     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15495     if (rc != TPM_RC_SUCCESS) {
15496       return rc;
15497     }
15498     if (parameter_section_size > buffer.size()) {
15499       return TPM_RC_INSUFFICIENT;
15500     }
15501     authorization_section_bytes = buffer.substr(parameter_section_size);
15502     // Keep the parameter section in |buffer|.
15503     buffer.erase(parameter_section_size);
15504   }
15505   std::unique_ptr<crypto::SecureHash> hash(
15506       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15507   hash->Update(response_code_bytes.data(), response_code_bytes.size());
15508   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15509   hash->Update(buffer.data(), buffer.size());
15510   std::string response_hash(32, 0);
15511   hash->Finish(std::data(response_hash), response_hash.size());
15512   if (tag == TPM_ST_SESSIONS) {
15513     if (!authorization_delegate)
15514       return TRUNKS_RC_AUTHORIZATION_FAILED;
15515     if (!authorization_delegate->CheckResponseAuthorization(
15516             response_hash, authorization_section_bytes)) {
15517       return TRUNKS_RC_AUTHORIZATION_FAILED;
15518     }
15519   }
15520   return TPM_RC_SUCCESS;
15521 }
15522 
HMAC_StartErrorCallback(Tpm::HMAC_StartResponse callback,TPM_RC response_code)15523 void HMAC_StartErrorCallback(Tpm::HMAC_StartResponse callback,
15524                              TPM_RC response_code) {
15525   VLOG(1) << __func__;
15526   std::move(callback).Run(response_code, TPMI_DH_OBJECT());
15527 }
15528 
HMAC_StartResponseParser(Tpm::HMAC_StartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15529 void HMAC_StartResponseParser(Tpm::HMAC_StartResponse callback,
15530                               AuthorizationDelegate* authorization_delegate,
15531                               const std::string& response) {
15532   VLOG(1) << __func__;
15533   TPMI_DH_OBJECT sequence_handle;
15534   TPM_RC rc = Tpm::ParseResponse_HMAC_Start(response, &sequence_handle,
15535                                             authorization_delegate);
15536   if (rc != TPM_RC_SUCCESS) {
15537     base::OnceCallback<void(TPM_RC)> error_reporter =
15538         base::BindOnce(HMAC_StartErrorCallback, std::move(callback));
15539     std::move(error_reporter).Run(rc);
15540     return;
15541   }
15542   std::move(callback).Run(rc, sequence_handle);
15543 }
15544 
HMAC_Start(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,HMAC_StartResponse callback)15545 void Tpm::HMAC_Start(const TPMI_DH_OBJECT& handle,
15546                      const std::string& handle_name,
15547                      const TPM2B_AUTH& auth,
15548                      const TPMI_ALG_HASH& hash_alg,
15549                      AuthorizationDelegate* authorization_delegate,
15550                      HMAC_StartResponse callback) {
15551   VLOG(1) << __func__;
15552   std::string command;
15553   TPM_RC rc = SerializeCommand_HMAC_Start(handle, handle_name, auth, hash_alg,
15554                                           &command, authorization_delegate);
15555   if (rc != TPM_RC_SUCCESS) {
15556     base::OnceCallback<void(TPM_RC)> error_reporter =
15557         base::BindOnce(HMAC_StartErrorCallback, std::move(callback));
15558     std::move(error_reporter).Run(rc);
15559     return;
15560   }
15561   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
15562       HMAC_StartResponseParser, std::move(callback), authorization_delegate);
15563   transceiver_->SendCommand(command, std::move(parser));
15564 }
15565 
HMAC_StartSync(const TPMI_DH_OBJECT & handle,const std::string & handle_name,const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15566 TPM_RC Tpm::HMAC_StartSync(const TPMI_DH_OBJECT& handle,
15567                            const std::string& handle_name,
15568                            const TPM2B_AUTH& auth,
15569                            const TPMI_ALG_HASH& hash_alg,
15570                            TPMI_DH_OBJECT* sequence_handle,
15571                            AuthorizationDelegate* authorization_delegate) {
15572   VLOG(1) << __func__;
15573   std::string command;
15574   TPM_RC rc = SerializeCommand_HMAC_Start(handle, handle_name, auth, hash_alg,
15575                                           &command, authorization_delegate);
15576   if (rc != TPM_RC_SUCCESS) {
15577     return rc;
15578   }
15579   std::string response = transceiver_->SendCommandAndWait(command);
15580   rc = ParseResponse_HMAC_Start(response, sequence_handle,
15581                                 authorization_delegate);
15582   return rc;
15583 }
15584 
SerializeCommand_HashSequenceStart(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15585 TPM_RC Tpm::SerializeCommand_HashSequenceStart(
15586     const TPM2B_AUTH& auth,
15587     const TPMI_ALG_HASH& hash_alg,
15588     std::string* serialized_command,
15589     AuthorizationDelegate* authorization_delegate) {
15590   VLOG(3) << __func__;
15591   TPM_RC rc = TPM_RC_SUCCESS;
15592   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15593   UINT32 command_size = 10;  // Header size.
15594   std::string handle_section_bytes;
15595   std::string parameter_section_bytes;
15596   TPM_CC command_code = TPM_CC_HashSequenceStart;
15597   bool is_command_parameter_encryption_possible = true;
15598   bool is_response_parameter_encryption_possible = false;
15599   std::string command_code_bytes;
15600   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15601   if (rc != TPM_RC_SUCCESS) {
15602     return rc;
15603   }
15604   std::string auth_bytes;
15605   rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
15606   if (rc != TPM_RC_SUCCESS) {
15607     return rc;
15608   }
15609   std::string hash_alg_bytes;
15610   rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
15611   if (rc != TPM_RC_SUCCESS) {
15612     return rc;
15613   }
15614   if (authorization_delegate) {
15615     // Encrypt just the parameter data, not the size.
15616     std::string tmp = auth_bytes.substr(2);
15617     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15618       return TRUNKS_RC_ENCRYPTION_FAILED;
15619     }
15620     auth_bytes.replace(2, std::string::npos, tmp);
15621   }
15622   std::unique_ptr<crypto::SecureHash> hash(
15623       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15624   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15625   hash->Update(auth_bytes.data(), auth_bytes.size());
15626   parameter_section_bytes += auth_bytes;
15627   command_size += auth_bytes.size();
15628   hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
15629   parameter_section_bytes += hash_alg_bytes;
15630   command_size += hash_alg_bytes.size();
15631   std::string command_hash(32, 0);
15632   hash->Finish(std::data(command_hash), command_hash.size());
15633   std::string authorization_section_bytes;
15634   std::string authorization_size_bytes;
15635   if (authorization_delegate) {
15636     if (!authorization_delegate->GetCommandAuthorization(
15637             command_hash, is_command_parameter_encryption_possible,
15638             is_response_parameter_encryption_possible,
15639             &authorization_section_bytes)) {
15640       return TRUNKS_RC_AUTHORIZATION_FAILED;
15641     }
15642     if (!authorization_section_bytes.empty()) {
15643       tag = TPM_ST_SESSIONS;
15644       std::string tmp;
15645       rc = Serialize_UINT32(authorization_section_bytes.size(),
15646                             &authorization_size_bytes);
15647       if (rc != TPM_RC_SUCCESS) {
15648         return rc;
15649       }
15650       command_size +=
15651           authorization_size_bytes.size() + authorization_section_bytes.size();
15652     }
15653   }
15654   std::string tag_bytes;
15655   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15656   if (rc != TPM_RC_SUCCESS) {
15657     return rc;
15658   }
15659   std::string command_size_bytes;
15660   rc = Serialize_UINT32(command_size, &command_size_bytes);
15661   if (rc != TPM_RC_SUCCESS) {
15662     return rc;
15663   }
15664   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15665                         handle_section_bytes + authorization_size_bytes +
15666                         authorization_section_bytes + parameter_section_bytes;
15667   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15668   VLOG(2) << "Command: "
15669           << base::HexEncode(serialized_command->data(),
15670                              serialized_command->size());
15671   return TPM_RC_SUCCESS;
15672 }
15673 
ParseResponse_HashSequenceStart(const std::string & response,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15674 TPM_RC Tpm::ParseResponse_HashSequenceStart(
15675     const std::string& response,
15676     TPMI_DH_OBJECT* sequence_handle,
15677     AuthorizationDelegate* authorization_delegate) {
15678   VLOG(3) << __func__;
15679   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15680   TPM_RC rc = TPM_RC_SUCCESS;
15681   std::string buffer(response);
15682   TPM_ST tag;
15683   std::string tag_bytes;
15684   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15685   if (rc != TPM_RC_SUCCESS) {
15686     return rc;
15687   }
15688   UINT32 response_size;
15689   std::string response_size_bytes;
15690   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15691   if (rc != TPM_RC_SUCCESS) {
15692     return rc;
15693   }
15694   TPM_RC response_code;
15695   std::string response_code_bytes;
15696   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15697   if (rc != TPM_RC_SUCCESS) {
15698     return rc;
15699   }
15700   if (response_size != response.size()) {
15701     return TPM_RC_SIZE;
15702   }
15703   if (response_code != TPM_RC_SUCCESS) {
15704     return response_code;
15705   }
15706   std::string sequence_handle_bytes;
15707   rc = Parse_TPMI_DH_OBJECT(&buffer, sequence_handle, &sequence_handle_bytes);
15708   if (rc != TPM_RC_SUCCESS) {
15709     return rc;
15710   }
15711   TPM_CC command_code = TPM_CC_HashSequenceStart;
15712   std::string command_code_bytes;
15713   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15714   if (rc != TPM_RC_SUCCESS) {
15715     return rc;
15716   }
15717   std::string authorization_section_bytes;
15718   if (tag == TPM_ST_SESSIONS) {
15719     UINT32 parameter_section_size = buffer.size();
15720     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15721     if (rc != TPM_RC_SUCCESS) {
15722       return rc;
15723     }
15724     if (parameter_section_size > buffer.size()) {
15725       return TPM_RC_INSUFFICIENT;
15726     }
15727     authorization_section_bytes = buffer.substr(parameter_section_size);
15728     // Keep the parameter section in |buffer|.
15729     buffer.erase(parameter_section_size);
15730   }
15731   std::unique_ptr<crypto::SecureHash> hash(
15732       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15733   hash->Update(response_code_bytes.data(), response_code_bytes.size());
15734   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15735   hash->Update(buffer.data(), buffer.size());
15736   std::string response_hash(32, 0);
15737   hash->Finish(std::data(response_hash), response_hash.size());
15738   if (tag == TPM_ST_SESSIONS) {
15739     if (!authorization_delegate)
15740       return TRUNKS_RC_AUTHORIZATION_FAILED;
15741     if (!authorization_delegate->CheckResponseAuthorization(
15742             response_hash, authorization_section_bytes)) {
15743       return TRUNKS_RC_AUTHORIZATION_FAILED;
15744     }
15745   }
15746   return TPM_RC_SUCCESS;
15747 }
15748 
HashSequenceStartErrorCallback(Tpm::HashSequenceStartResponse callback,TPM_RC response_code)15749 void HashSequenceStartErrorCallback(Tpm::HashSequenceStartResponse callback,
15750                                     TPM_RC response_code) {
15751   VLOG(1) << __func__;
15752   std::move(callback).Run(response_code, TPMI_DH_OBJECT());
15753 }
15754 
HashSequenceStartResponseParser(Tpm::HashSequenceStartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15755 void HashSequenceStartResponseParser(
15756     Tpm::HashSequenceStartResponse callback,
15757     AuthorizationDelegate* authorization_delegate,
15758     const std::string& response) {
15759   VLOG(1) << __func__;
15760   TPMI_DH_OBJECT sequence_handle;
15761   TPM_RC rc = Tpm::ParseResponse_HashSequenceStart(response, &sequence_handle,
15762                                                    authorization_delegate);
15763   if (rc != TPM_RC_SUCCESS) {
15764     base::OnceCallback<void(TPM_RC)> error_reporter =
15765         base::BindOnce(HashSequenceStartErrorCallback, std::move(callback));
15766     std::move(error_reporter).Run(rc);
15767     return;
15768   }
15769   std::move(callback).Run(rc, sequence_handle);
15770 }
15771 
HashSequenceStart(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,HashSequenceStartResponse callback)15772 void Tpm::HashSequenceStart(const TPM2B_AUTH& auth,
15773                             const TPMI_ALG_HASH& hash_alg,
15774                             AuthorizationDelegate* authorization_delegate,
15775                             HashSequenceStartResponse callback) {
15776   VLOG(1) << __func__;
15777   std::string command;
15778   TPM_RC rc = SerializeCommand_HashSequenceStart(auth, hash_alg, &command,
15779                                                  authorization_delegate);
15780   if (rc != TPM_RC_SUCCESS) {
15781     base::OnceCallback<void(TPM_RC)> error_reporter =
15782         base::BindOnce(HashSequenceStartErrorCallback, std::move(callback));
15783     std::move(error_reporter).Run(rc);
15784     return;
15785   }
15786   base::OnceCallback<void(const std::string&)> parser =
15787       base::BindOnce(HashSequenceStartResponseParser, std::move(callback),
15788                      authorization_delegate);
15789   transceiver_->SendCommand(command, std::move(parser));
15790 }
15791 
HashSequenceStartSync(const TPM2B_AUTH & auth,const TPMI_ALG_HASH & hash_alg,TPMI_DH_OBJECT * sequence_handle,AuthorizationDelegate * authorization_delegate)15792 TPM_RC Tpm::HashSequenceStartSync(
15793     const TPM2B_AUTH& auth,
15794     const TPMI_ALG_HASH& hash_alg,
15795     TPMI_DH_OBJECT* sequence_handle,
15796     AuthorizationDelegate* authorization_delegate) {
15797   VLOG(1) << __func__;
15798   std::string command;
15799   TPM_RC rc = SerializeCommand_HashSequenceStart(auth, hash_alg, &command,
15800                                                  authorization_delegate);
15801   if (rc != TPM_RC_SUCCESS) {
15802     return rc;
15803   }
15804   std::string response = transceiver_->SendCommandAndWait(command);
15805   rc = ParseResponse_HashSequenceStart(response, sequence_handle,
15806                                        authorization_delegate);
15807   return rc;
15808 }
15809 
SerializeCommand_SequenceUpdate(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)15810 TPM_RC Tpm::SerializeCommand_SequenceUpdate(
15811     const TPMI_DH_OBJECT& sequence_handle,
15812     const std::string& sequence_handle_name,
15813     const TPM2B_MAX_BUFFER& buffer,
15814     std::string* serialized_command,
15815     AuthorizationDelegate* authorization_delegate) {
15816   VLOG(3) << __func__;
15817   TPM_RC rc = TPM_RC_SUCCESS;
15818   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
15819   UINT32 command_size = 10;  // Header size.
15820   std::string handle_section_bytes;
15821   std::string parameter_section_bytes;
15822   TPM_CC command_code = TPM_CC_SequenceUpdate;
15823   bool is_command_parameter_encryption_possible = true;
15824   bool is_response_parameter_encryption_possible = false;
15825   std::string command_code_bytes;
15826   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15827   if (rc != TPM_RC_SUCCESS) {
15828     return rc;
15829   }
15830   std::string sequence_handle_bytes;
15831   rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
15832   if (rc != TPM_RC_SUCCESS) {
15833     return rc;
15834   }
15835   std::string buffer_bytes;
15836   rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
15837   if (rc != TPM_RC_SUCCESS) {
15838     return rc;
15839   }
15840   if (authorization_delegate) {
15841     // Encrypt just the parameter data, not the size.
15842     std::string tmp = buffer_bytes.substr(2);
15843     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
15844       return TRUNKS_RC_ENCRYPTION_FAILED;
15845     }
15846     buffer_bytes.replace(2, std::string::npos, tmp);
15847   }
15848   std::unique_ptr<crypto::SecureHash> hash(
15849       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15850   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15851   hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
15852   handle_section_bytes += sequence_handle_bytes;
15853   command_size += sequence_handle_bytes.size();
15854   hash->Update(buffer_bytes.data(), buffer_bytes.size());
15855   parameter_section_bytes += buffer_bytes;
15856   command_size += buffer_bytes.size();
15857   std::string command_hash(32, 0);
15858   hash->Finish(std::data(command_hash), command_hash.size());
15859   std::string authorization_section_bytes;
15860   std::string authorization_size_bytes;
15861   if (authorization_delegate) {
15862     if (!authorization_delegate->GetCommandAuthorization(
15863             command_hash, is_command_parameter_encryption_possible,
15864             is_response_parameter_encryption_possible,
15865             &authorization_section_bytes)) {
15866       return TRUNKS_RC_AUTHORIZATION_FAILED;
15867     }
15868     if (!authorization_section_bytes.empty()) {
15869       tag = TPM_ST_SESSIONS;
15870       std::string tmp;
15871       rc = Serialize_UINT32(authorization_section_bytes.size(),
15872                             &authorization_size_bytes);
15873       if (rc != TPM_RC_SUCCESS) {
15874         return rc;
15875       }
15876       command_size +=
15877           authorization_size_bytes.size() + authorization_section_bytes.size();
15878     }
15879   }
15880   std::string tag_bytes;
15881   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
15882   if (rc != TPM_RC_SUCCESS) {
15883     return rc;
15884   }
15885   std::string command_size_bytes;
15886   rc = Serialize_UINT32(command_size, &command_size_bytes);
15887   if (rc != TPM_RC_SUCCESS) {
15888     return rc;
15889   }
15890   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
15891                         handle_section_bytes + authorization_size_bytes +
15892                         authorization_section_bytes + parameter_section_bytes;
15893   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
15894   VLOG(2) << "Command: "
15895           << base::HexEncode(serialized_command->data(),
15896                              serialized_command->size());
15897   return TPM_RC_SUCCESS;
15898 }
15899 
ParseResponse_SequenceUpdate(const std::string & response,AuthorizationDelegate * authorization_delegate)15900 TPM_RC Tpm::ParseResponse_SequenceUpdate(
15901     const std::string& response,
15902     AuthorizationDelegate* authorization_delegate) {
15903   VLOG(3) << __func__;
15904   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
15905   TPM_RC rc = TPM_RC_SUCCESS;
15906   std::string buffer(response);
15907   TPM_ST tag;
15908   std::string tag_bytes;
15909   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
15910   if (rc != TPM_RC_SUCCESS) {
15911     return rc;
15912   }
15913   UINT32 response_size;
15914   std::string response_size_bytes;
15915   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
15916   if (rc != TPM_RC_SUCCESS) {
15917     return rc;
15918   }
15919   TPM_RC response_code;
15920   std::string response_code_bytes;
15921   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
15922   if (rc != TPM_RC_SUCCESS) {
15923     return rc;
15924   }
15925   if (response_size != response.size()) {
15926     return TPM_RC_SIZE;
15927   }
15928   if (response_code != TPM_RC_SUCCESS) {
15929     return response_code;
15930   }
15931   TPM_CC command_code = TPM_CC_SequenceUpdate;
15932   std::string command_code_bytes;
15933   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
15934   if (rc != TPM_RC_SUCCESS) {
15935     return rc;
15936   }
15937   std::string authorization_section_bytes;
15938   if (tag == TPM_ST_SESSIONS) {
15939     UINT32 parameter_section_size = buffer.size();
15940     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
15941     if (rc != TPM_RC_SUCCESS) {
15942       return rc;
15943     }
15944     if (parameter_section_size > buffer.size()) {
15945       return TPM_RC_INSUFFICIENT;
15946     }
15947     authorization_section_bytes = buffer.substr(parameter_section_size);
15948     // Keep the parameter section in |buffer|.
15949     buffer.erase(parameter_section_size);
15950   }
15951   std::unique_ptr<crypto::SecureHash> hash(
15952       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
15953   hash->Update(response_code_bytes.data(), response_code_bytes.size());
15954   hash->Update(command_code_bytes.data(), command_code_bytes.size());
15955   hash->Update(buffer.data(), buffer.size());
15956   std::string response_hash(32, 0);
15957   hash->Finish(std::data(response_hash), response_hash.size());
15958   if (tag == TPM_ST_SESSIONS) {
15959     if (!authorization_delegate)
15960       return TRUNKS_RC_AUTHORIZATION_FAILED;
15961     if (!authorization_delegate->CheckResponseAuthorization(
15962             response_hash, authorization_section_bytes)) {
15963       return TRUNKS_RC_AUTHORIZATION_FAILED;
15964     }
15965   }
15966   return TPM_RC_SUCCESS;
15967 }
15968 
SequenceUpdateErrorCallback(Tpm::SequenceUpdateResponse callback,TPM_RC response_code)15969 void SequenceUpdateErrorCallback(Tpm::SequenceUpdateResponse callback,
15970                                  TPM_RC response_code) {
15971   VLOG(1) << __func__;
15972   std::move(callback).Run(response_code);
15973 }
15974 
SequenceUpdateResponseParser(Tpm::SequenceUpdateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)15975 void SequenceUpdateResponseParser(Tpm::SequenceUpdateResponse callback,
15976                                   AuthorizationDelegate* authorization_delegate,
15977                                   const std::string& response) {
15978   VLOG(1) << __func__;
15979   TPM_RC rc =
15980       Tpm::ParseResponse_SequenceUpdate(response, authorization_delegate);
15981   if (rc != TPM_RC_SUCCESS) {
15982     base::OnceCallback<void(TPM_RC)> error_reporter =
15983         base::BindOnce(SequenceUpdateErrorCallback, std::move(callback));
15984     std::move(error_reporter).Run(rc);
15985     return;
15986   }
15987   std::move(callback).Run(rc);
15988 }
15989 
SequenceUpdate(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate,SequenceUpdateResponse callback)15990 void Tpm::SequenceUpdate(const TPMI_DH_OBJECT& sequence_handle,
15991                          const std::string& sequence_handle_name,
15992                          const TPM2B_MAX_BUFFER& buffer,
15993                          AuthorizationDelegate* authorization_delegate,
15994                          SequenceUpdateResponse callback) {
15995   VLOG(1) << __func__;
15996   std::string command;
15997   TPM_RC rc =
15998       SerializeCommand_SequenceUpdate(sequence_handle, sequence_handle_name,
15999                                       buffer, &command, authorization_delegate);
16000   if (rc != TPM_RC_SUCCESS) {
16001     base::OnceCallback<void(TPM_RC)> error_reporter =
16002         base::BindOnce(SequenceUpdateErrorCallback, std::move(callback));
16003     std::move(error_reporter).Run(rc);
16004     return;
16005   }
16006   base::OnceCallback<void(const std::string&)> parser =
16007       base::BindOnce(SequenceUpdateResponseParser, std::move(callback),
16008                      authorization_delegate);
16009   transceiver_->SendCommand(command, std::move(parser));
16010 }
16011 
SequenceUpdateSync(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate)16012 TPM_RC Tpm::SequenceUpdateSync(const TPMI_DH_OBJECT& sequence_handle,
16013                                const std::string& sequence_handle_name,
16014                                const TPM2B_MAX_BUFFER& buffer,
16015                                AuthorizationDelegate* authorization_delegate) {
16016   VLOG(1) << __func__;
16017   std::string command;
16018   TPM_RC rc =
16019       SerializeCommand_SequenceUpdate(sequence_handle, sequence_handle_name,
16020                                       buffer, &command, authorization_delegate);
16021   if (rc != TPM_RC_SUCCESS) {
16022     return rc;
16023   }
16024   std::string response = transceiver_->SendCommandAndWait(command);
16025   rc = ParseResponse_SequenceUpdate(response, authorization_delegate);
16026   return rc;
16027 }
16028 
SerializeCommand_SequenceComplete(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_RH_HIERARCHY & hierarchy,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16029 TPM_RC Tpm::SerializeCommand_SequenceComplete(
16030     const TPMI_DH_OBJECT& sequence_handle,
16031     const std::string& sequence_handle_name,
16032     const TPM2B_MAX_BUFFER& buffer,
16033     const TPMI_RH_HIERARCHY& hierarchy,
16034     std::string* serialized_command,
16035     AuthorizationDelegate* authorization_delegate) {
16036   VLOG(3) << __func__;
16037   TPM_RC rc = TPM_RC_SUCCESS;
16038   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16039   UINT32 command_size = 10;  // Header size.
16040   std::string handle_section_bytes;
16041   std::string parameter_section_bytes;
16042   TPM_CC command_code = TPM_CC_SequenceComplete;
16043   bool is_command_parameter_encryption_possible = true;
16044   bool is_response_parameter_encryption_possible = true;
16045   std::string command_code_bytes;
16046   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16047   if (rc != TPM_RC_SUCCESS) {
16048     return rc;
16049   }
16050   std::string sequence_handle_bytes;
16051   rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
16052   if (rc != TPM_RC_SUCCESS) {
16053     return rc;
16054   }
16055   std::string buffer_bytes;
16056   rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
16057   if (rc != TPM_RC_SUCCESS) {
16058     return rc;
16059   }
16060   std::string hierarchy_bytes;
16061   rc = Serialize_TPMI_RH_HIERARCHY(hierarchy, &hierarchy_bytes);
16062   if (rc != TPM_RC_SUCCESS) {
16063     return rc;
16064   }
16065   if (authorization_delegate) {
16066     // Encrypt just the parameter data, not the size.
16067     std::string tmp = buffer_bytes.substr(2);
16068     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16069       return TRUNKS_RC_ENCRYPTION_FAILED;
16070     }
16071     buffer_bytes.replace(2, std::string::npos, tmp);
16072   }
16073   std::unique_ptr<crypto::SecureHash> hash(
16074       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16075   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16076   hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
16077   handle_section_bytes += sequence_handle_bytes;
16078   command_size += sequence_handle_bytes.size();
16079   hash->Update(buffer_bytes.data(), buffer_bytes.size());
16080   parameter_section_bytes += buffer_bytes;
16081   command_size += buffer_bytes.size();
16082   hash->Update(hierarchy_bytes.data(), hierarchy_bytes.size());
16083   parameter_section_bytes += hierarchy_bytes;
16084   command_size += hierarchy_bytes.size();
16085   std::string command_hash(32, 0);
16086   hash->Finish(std::data(command_hash), command_hash.size());
16087   std::string authorization_section_bytes;
16088   std::string authorization_size_bytes;
16089   if (authorization_delegate) {
16090     if (!authorization_delegate->GetCommandAuthorization(
16091             command_hash, is_command_parameter_encryption_possible,
16092             is_response_parameter_encryption_possible,
16093             &authorization_section_bytes)) {
16094       return TRUNKS_RC_AUTHORIZATION_FAILED;
16095     }
16096     if (!authorization_section_bytes.empty()) {
16097       tag = TPM_ST_SESSIONS;
16098       std::string tmp;
16099       rc = Serialize_UINT32(authorization_section_bytes.size(),
16100                             &authorization_size_bytes);
16101       if (rc != TPM_RC_SUCCESS) {
16102         return rc;
16103       }
16104       command_size +=
16105           authorization_size_bytes.size() + authorization_section_bytes.size();
16106     }
16107   }
16108   std::string tag_bytes;
16109   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16110   if (rc != TPM_RC_SUCCESS) {
16111     return rc;
16112   }
16113   std::string command_size_bytes;
16114   rc = Serialize_UINT32(command_size, &command_size_bytes);
16115   if (rc != TPM_RC_SUCCESS) {
16116     return rc;
16117   }
16118   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16119                         handle_section_bytes + authorization_size_bytes +
16120                         authorization_section_bytes + parameter_section_bytes;
16121   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16122   VLOG(2) << "Command: "
16123           << base::HexEncode(serialized_command->data(),
16124                              serialized_command->size());
16125   return TPM_RC_SUCCESS;
16126 }
16127 
ParseResponse_SequenceComplete(const std::string & response,TPM2B_DIGEST * result,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)16128 TPM_RC Tpm::ParseResponse_SequenceComplete(
16129     const std::string& response,
16130     TPM2B_DIGEST* result,
16131     TPMT_TK_HASHCHECK* validation,
16132     AuthorizationDelegate* authorization_delegate) {
16133   VLOG(3) << __func__;
16134   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16135   TPM_RC rc = TPM_RC_SUCCESS;
16136   std::string buffer(response);
16137   TPM_ST tag;
16138   std::string tag_bytes;
16139   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16140   if (rc != TPM_RC_SUCCESS) {
16141     return rc;
16142   }
16143   UINT32 response_size;
16144   std::string response_size_bytes;
16145   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16146   if (rc != TPM_RC_SUCCESS) {
16147     return rc;
16148   }
16149   TPM_RC response_code;
16150   std::string response_code_bytes;
16151   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16152   if (rc != TPM_RC_SUCCESS) {
16153     return rc;
16154   }
16155   if (response_size != response.size()) {
16156     return TPM_RC_SIZE;
16157   }
16158   if (response_code != TPM_RC_SUCCESS) {
16159     return response_code;
16160   }
16161   TPM_CC command_code = TPM_CC_SequenceComplete;
16162   std::string command_code_bytes;
16163   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16164   if (rc != TPM_RC_SUCCESS) {
16165     return rc;
16166   }
16167   std::string authorization_section_bytes;
16168   if (tag == TPM_ST_SESSIONS) {
16169     UINT32 parameter_section_size = buffer.size();
16170     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16171     if (rc != TPM_RC_SUCCESS) {
16172       return rc;
16173     }
16174     if (parameter_section_size > buffer.size()) {
16175       return TPM_RC_INSUFFICIENT;
16176     }
16177     authorization_section_bytes = buffer.substr(parameter_section_size);
16178     // Keep the parameter section in |buffer|.
16179     buffer.erase(parameter_section_size);
16180   }
16181   std::unique_ptr<crypto::SecureHash> hash(
16182       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16183   hash->Update(response_code_bytes.data(), response_code_bytes.size());
16184   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16185   hash->Update(buffer.data(), buffer.size());
16186   std::string response_hash(32, 0);
16187   hash->Finish(std::data(response_hash), response_hash.size());
16188   if (tag == TPM_ST_SESSIONS) {
16189     if (!authorization_delegate)
16190       return TRUNKS_RC_AUTHORIZATION_FAILED;
16191     if (!authorization_delegate->CheckResponseAuthorization(
16192             response_hash, authorization_section_bytes)) {
16193       return TRUNKS_RC_AUTHORIZATION_FAILED;
16194     }
16195   }
16196   if (tag == TPM_ST_SESSIONS) {
16197     if (!authorization_delegate)
16198       return TRUNKS_RC_AUTHORIZATION_FAILED;
16199 
16200     // Parse the encrypted parameter size.
16201     UINT16 size;
16202     std::string size_buffer = buffer.substr(0, 2);
16203     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
16204       return result;
16205     }
16206     if (buffer.size() < 2 + size) {
16207       return TPM_RC_INSUFFICIENT;
16208     }
16209 
16210     // Decrypt just the parameter data, not the size.
16211     std::string decrypted_data = buffer.substr(2, size);
16212     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
16213       return TRUNKS_RC_ENCRYPTION_FAILED;
16214     }
16215     buffer.replace(2, size, decrypted_data);
16216   }
16217   std::string result_bytes;
16218   rc = Parse_TPM2B_DIGEST(&buffer, result, &result_bytes);
16219   if (rc != TPM_RC_SUCCESS) {
16220     return rc;
16221   }
16222   std::string validation_bytes;
16223   rc = Parse_TPMT_TK_HASHCHECK(&buffer, validation, &validation_bytes);
16224   if (rc != TPM_RC_SUCCESS) {
16225     return rc;
16226   }
16227   return TPM_RC_SUCCESS;
16228 }
16229 
SequenceCompleteErrorCallback(Tpm::SequenceCompleteResponse callback,TPM_RC response_code)16230 void SequenceCompleteErrorCallback(Tpm::SequenceCompleteResponse callback,
16231                                    TPM_RC response_code) {
16232   VLOG(1) << __func__;
16233   std::move(callback).Run(response_code, TPM2B_DIGEST(), TPMT_TK_HASHCHECK());
16234 }
16235 
SequenceCompleteResponseParser(Tpm::SequenceCompleteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16236 void SequenceCompleteResponseParser(
16237     Tpm::SequenceCompleteResponse callback,
16238     AuthorizationDelegate* authorization_delegate,
16239     const std::string& response) {
16240   VLOG(1) << __func__;
16241   TPM2B_DIGEST result;
16242   TPMT_TK_HASHCHECK validation;
16243   TPM_RC rc = Tpm::ParseResponse_SequenceComplete(
16244       response, &result, &validation, authorization_delegate);
16245   if (rc != TPM_RC_SUCCESS) {
16246     base::OnceCallback<void(TPM_RC)> error_reporter =
16247         base::BindOnce(SequenceCompleteErrorCallback, std::move(callback));
16248     std::move(error_reporter).Run(rc);
16249     return;
16250   }
16251   std::move(callback).Run(rc, result, validation);
16252 }
16253 
SequenceComplete(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_RH_HIERARCHY & hierarchy,AuthorizationDelegate * authorization_delegate,SequenceCompleteResponse callback)16254 void Tpm::SequenceComplete(const TPMI_DH_OBJECT& sequence_handle,
16255                            const std::string& sequence_handle_name,
16256                            const TPM2B_MAX_BUFFER& buffer,
16257                            const TPMI_RH_HIERARCHY& hierarchy,
16258                            AuthorizationDelegate* authorization_delegate,
16259                            SequenceCompleteResponse callback) {
16260   VLOG(1) << __func__;
16261   std::string command;
16262   TPM_RC rc = SerializeCommand_SequenceComplete(
16263       sequence_handle, sequence_handle_name, buffer, hierarchy, &command,
16264       authorization_delegate);
16265   if (rc != TPM_RC_SUCCESS) {
16266     base::OnceCallback<void(TPM_RC)> error_reporter =
16267         base::BindOnce(SequenceCompleteErrorCallback, std::move(callback));
16268     std::move(error_reporter).Run(rc);
16269     return;
16270   }
16271   base::OnceCallback<void(const std::string&)> parser =
16272       base::BindOnce(SequenceCompleteResponseParser, std::move(callback),
16273                      authorization_delegate);
16274   transceiver_->SendCommand(command, std::move(parser));
16275 }
16276 
SequenceCompleteSync(const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,const TPMI_RH_HIERARCHY & hierarchy,TPM2B_DIGEST * result,TPMT_TK_HASHCHECK * validation,AuthorizationDelegate * authorization_delegate)16277 TPM_RC Tpm::SequenceCompleteSync(
16278     const TPMI_DH_OBJECT& sequence_handle,
16279     const std::string& sequence_handle_name,
16280     const TPM2B_MAX_BUFFER& buffer,
16281     const TPMI_RH_HIERARCHY& hierarchy,
16282     TPM2B_DIGEST* result,
16283     TPMT_TK_HASHCHECK* validation,
16284     AuthorizationDelegate* authorization_delegate) {
16285   VLOG(1) << __func__;
16286   std::string command;
16287   TPM_RC rc = SerializeCommand_SequenceComplete(
16288       sequence_handle, sequence_handle_name, buffer, hierarchy, &command,
16289       authorization_delegate);
16290   if (rc != TPM_RC_SUCCESS) {
16291     return rc;
16292   }
16293   std::string response = transceiver_->SendCommandAndWait(command);
16294   rc = ParseResponse_SequenceComplete(response, result, validation,
16295                                       authorization_delegate);
16296   return rc;
16297 }
16298 
SerializeCommand_EventSequenceComplete(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16299 TPM_RC Tpm::SerializeCommand_EventSequenceComplete(
16300     const TPMI_DH_PCR& pcr_handle,
16301     const std::string& pcr_handle_name,
16302     const TPMI_DH_OBJECT& sequence_handle,
16303     const std::string& sequence_handle_name,
16304     const TPM2B_MAX_BUFFER& buffer,
16305     std::string* serialized_command,
16306     AuthorizationDelegate* authorization_delegate) {
16307   VLOG(3) << __func__;
16308   TPM_RC rc = TPM_RC_SUCCESS;
16309   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16310   UINT32 command_size = 10;  // Header size.
16311   std::string handle_section_bytes;
16312   std::string parameter_section_bytes;
16313   TPM_CC command_code = TPM_CC_EventSequenceComplete;
16314   bool is_command_parameter_encryption_possible = true;
16315   bool is_response_parameter_encryption_possible = false;
16316   std::string command_code_bytes;
16317   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16318   if (rc != TPM_RC_SUCCESS) {
16319     return rc;
16320   }
16321   std::string pcr_handle_bytes;
16322   rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
16323   if (rc != TPM_RC_SUCCESS) {
16324     return rc;
16325   }
16326   std::string sequence_handle_bytes;
16327   rc = Serialize_TPMI_DH_OBJECT(sequence_handle, &sequence_handle_bytes);
16328   if (rc != TPM_RC_SUCCESS) {
16329     return rc;
16330   }
16331   std::string buffer_bytes;
16332   rc = Serialize_TPM2B_MAX_BUFFER(buffer, &buffer_bytes);
16333   if (rc != TPM_RC_SUCCESS) {
16334     return rc;
16335   }
16336   if (authorization_delegate) {
16337     // Encrypt just the parameter data, not the size.
16338     std::string tmp = buffer_bytes.substr(2);
16339     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16340       return TRUNKS_RC_ENCRYPTION_FAILED;
16341     }
16342     buffer_bytes.replace(2, std::string::npos, tmp);
16343   }
16344   std::unique_ptr<crypto::SecureHash> hash(
16345       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16346   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16347   hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
16348   handle_section_bytes += pcr_handle_bytes;
16349   command_size += pcr_handle_bytes.size();
16350   hash->Update(sequence_handle_name.data(), sequence_handle_name.size());
16351   handle_section_bytes += sequence_handle_bytes;
16352   command_size += sequence_handle_bytes.size();
16353   hash->Update(buffer_bytes.data(), buffer_bytes.size());
16354   parameter_section_bytes += buffer_bytes;
16355   command_size += buffer_bytes.size();
16356   std::string command_hash(32, 0);
16357   hash->Finish(std::data(command_hash), command_hash.size());
16358   std::string authorization_section_bytes;
16359   std::string authorization_size_bytes;
16360   if (authorization_delegate) {
16361     if (!authorization_delegate->GetCommandAuthorization(
16362             command_hash, is_command_parameter_encryption_possible,
16363             is_response_parameter_encryption_possible,
16364             &authorization_section_bytes)) {
16365       return TRUNKS_RC_AUTHORIZATION_FAILED;
16366     }
16367     if (!authorization_section_bytes.empty()) {
16368       tag = TPM_ST_SESSIONS;
16369       std::string tmp;
16370       rc = Serialize_UINT32(authorization_section_bytes.size(),
16371                             &authorization_size_bytes);
16372       if (rc != TPM_RC_SUCCESS) {
16373         return rc;
16374       }
16375       command_size +=
16376           authorization_size_bytes.size() + authorization_section_bytes.size();
16377     }
16378   }
16379   std::string tag_bytes;
16380   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16381   if (rc != TPM_RC_SUCCESS) {
16382     return rc;
16383   }
16384   std::string command_size_bytes;
16385   rc = Serialize_UINT32(command_size, &command_size_bytes);
16386   if (rc != TPM_RC_SUCCESS) {
16387     return rc;
16388   }
16389   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16390                         handle_section_bytes + authorization_size_bytes +
16391                         authorization_section_bytes + parameter_section_bytes;
16392   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16393   VLOG(2) << "Command: "
16394           << base::HexEncode(serialized_command->data(),
16395                              serialized_command->size());
16396   return TPM_RC_SUCCESS;
16397 }
16398 
ParseResponse_EventSequenceComplete(const std::string & response,TPML_DIGEST_VALUES * results,AuthorizationDelegate * authorization_delegate)16399 TPM_RC Tpm::ParseResponse_EventSequenceComplete(
16400     const std::string& response,
16401     TPML_DIGEST_VALUES* results,
16402     AuthorizationDelegate* authorization_delegate) {
16403   VLOG(3) << __func__;
16404   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16405   TPM_RC rc = TPM_RC_SUCCESS;
16406   std::string buffer(response);
16407   TPM_ST tag;
16408   std::string tag_bytes;
16409   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16410   if (rc != TPM_RC_SUCCESS) {
16411     return rc;
16412   }
16413   UINT32 response_size;
16414   std::string response_size_bytes;
16415   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16416   if (rc != TPM_RC_SUCCESS) {
16417     return rc;
16418   }
16419   TPM_RC response_code;
16420   std::string response_code_bytes;
16421   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16422   if (rc != TPM_RC_SUCCESS) {
16423     return rc;
16424   }
16425   if (response_size != response.size()) {
16426     return TPM_RC_SIZE;
16427   }
16428   if (response_code != TPM_RC_SUCCESS) {
16429     return response_code;
16430   }
16431   TPM_CC command_code = TPM_CC_EventSequenceComplete;
16432   std::string command_code_bytes;
16433   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16434   if (rc != TPM_RC_SUCCESS) {
16435     return rc;
16436   }
16437   std::string authorization_section_bytes;
16438   if (tag == TPM_ST_SESSIONS) {
16439     UINT32 parameter_section_size = buffer.size();
16440     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16441     if (rc != TPM_RC_SUCCESS) {
16442       return rc;
16443     }
16444     if (parameter_section_size > buffer.size()) {
16445       return TPM_RC_INSUFFICIENT;
16446     }
16447     authorization_section_bytes = buffer.substr(parameter_section_size);
16448     // Keep the parameter section in |buffer|.
16449     buffer.erase(parameter_section_size);
16450   }
16451   std::unique_ptr<crypto::SecureHash> hash(
16452       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16453   hash->Update(response_code_bytes.data(), response_code_bytes.size());
16454   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16455   hash->Update(buffer.data(), buffer.size());
16456   std::string response_hash(32, 0);
16457   hash->Finish(std::data(response_hash), response_hash.size());
16458   if (tag == TPM_ST_SESSIONS) {
16459     if (!authorization_delegate)
16460       return TRUNKS_RC_AUTHORIZATION_FAILED;
16461     if (!authorization_delegate->CheckResponseAuthorization(
16462             response_hash, authorization_section_bytes)) {
16463       return TRUNKS_RC_AUTHORIZATION_FAILED;
16464     }
16465   }
16466   std::string results_bytes;
16467   rc = Parse_TPML_DIGEST_VALUES(&buffer, results, &results_bytes);
16468   if (rc != TPM_RC_SUCCESS) {
16469     return rc;
16470   }
16471   return TPM_RC_SUCCESS;
16472 }
16473 
EventSequenceCompleteErrorCallback(Tpm::EventSequenceCompleteResponse callback,TPM_RC response_code)16474 void EventSequenceCompleteErrorCallback(
16475     Tpm::EventSequenceCompleteResponse callback, TPM_RC response_code) {
16476   VLOG(1) << __func__;
16477   std::move(callback).Run(response_code, TPML_DIGEST_VALUES());
16478 }
16479 
EventSequenceCompleteResponseParser(Tpm::EventSequenceCompleteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16480 void EventSequenceCompleteResponseParser(
16481     Tpm::EventSequenceCompleteResponse callback,
16482     AuthorizationDelegate* authorization_delegate,
16483     const std::string& response) {
16484   VLOG(1) << __func__;
16485   TPML_DIGEST_VALUES results;
16486   TPM_RC rc = Tpm::ParseResponse_EventSequenceComplete(response, &results,
16487                                                        authorization_delegate);
16488   if (rc != TPM_RC_SUCCESS) {
16489     base::OnceCallback<void(TPM_RC)> error_reporter =
16490         base::BindOnce(EventSequenceCompleteErrorCallback, std::move(callback));
16491     std::move(error_reporter).Run(rc);
16492     return;
16493   }
16494   std::move(callback).Run(rc, results);
16495 }
16496 
EventSequenceComplete(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,AuthorizationDelegate * authorization_delegate,EventSequenceCompleteResponse callback)16497 void Tpm::EventSequenceComplete(const TPMI_DH_PCR& pcr_handle,
16498                                 const std::string& pcr_handle_name,
16499                                 const TPMI_DH_OBJECT& sequence_handle,
16500                                 const std::string& sequence_handle_name,
16501                                 const TPM2B_MAX_BUFFER& buffer,
16502                                 AuthorizationDelegate* authorization_delegate,
16503                                 EventSequenceCompleteResponse callback) {
16504   VLOG(1) << __func__;
16505   std::string command;
16506   TPM_RC rc = SerializeCommand_EventSequenceComplete(
16507       pcr_handle, pcr_handle_name, sequence_handle, sequence_handle_name,
16508       buffer, &command, authorization_delegate);
16509   if (rc != TPM_RC_SUCCESS) {
16510     base::OnceCallback<void(TPM_RC)> error_reporter =
16511         base::BindOnce(EventSequenceCompleteErrorCallback, std::move(callback));
16512     std::move(error_reporter).Run(rc);
16513     return;
16514   }
16515   base::OnceCallback<void(const std::string&)> parser =
16516       base::BindOnce(EventSequenceCompleteResponseParser, std::move(callback),
16517                      authorization_delegate);
16518   transceiver_->SendCommand(command, std::move(parser));
16519 }
16520 
EventSequenceCompleteSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPMI_DH_OBJECT & sequence_handle,const std::string & sequence_handle_name,const TPM2B_MAX_BUFFER & buffer,TPML_DIGEST_VALUES * results,AuthorizationDelegate * authorization_delegate)16521 TPM_RC Tpm::EventSequenceCompleteSync(
16522     const TPMI_DH_PCR& pcr_handle,
16523     const std::string& pcr_handle_name,
16524     const TPMI_DH_OBJECT& sequence_handle,
16525     const std::string& sequence_handle_name,
16526     const TPM2B_MAX_BUFFER& buffer,
16527     TPML_DIGEST_VALUES* results,
16528     AuthorizationDelegate* authorization_delegate) {
16529   VLOG(1) << __func__;
16530   std::string command;
16531   TPM_RC rc = SerializeCommand_EventSequenceComplete(
16532       pcr_handle, pcr_handle_name, sequence_handle, sequence_handle_name,
16533       buffer, &command, authorization_delegate);
16534   if (rc != TPM_RC_SUCCESS) {
16535     return rc;
16536   }
16537   std::string response = transceiver_->SendCommandAndWait(command);
16538   rc = ParseResponse_EventSequenceComplete(response, results,
16539                                            authorization_delegate);
16540   return rc;
16541 }
16542 
SerializeCommand_Certify(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16543 TPM_RC Tpm::SerializeCommand_Certify(
16544     const TPMI_DH_OBJECT& object_handle,
16545     const std::string& object_handle_name,
16546     const TPMI_DH_OBJECT& sign_handle,
16547     const std::string& sign_handle_name,
16548     const TPM2B_DATA& qualifying_data,
16549     const TPMT_SIG_SCHEME& in_scheme,
16550     std::string* serialized_command,
16551     AuthorizationDelegate* authorization_delegate) {
16552   VLOG(3) << __func__;
16553   TPM_RC rc = TPM_RC_SUCCESS;
16554   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16555   UINT32 command_size = 10;  // Header size.
16556   std::string handle_section_bytes;
16557   std::string parameter_section_bytes;
16558   TPM_CC command_code = TPM_CC_Certify;
16559   bool is_command_parameter_encryption_possible = true;
16560   bool is_response_parameter_encryption_possible = true;
16561   std::string command_code_bytes;
16562   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16563   if (rc != TPM_RC_SUCCESS) {
16564     return rc;
16565   }
16566   std::string object_handle_bytes;
16567   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
16568   if (rc != TPM_RC_SUCCESS) {
16569     return rc;
16570   }
16571   std::string sign_handle_bytes;
16572   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16573   if (rc != TPM_RC_SUCCESS) {
16574     return rc;
16575   }
16576   std::string qualifying_data_bytes;
16577   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16578   if (rc != TPM_RC_SUCCESS) {
16579     return rc;
16580   }
16581   std::string in_scheme_bytes;
16582   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16583   if (rc != TPM_RC_SUCCESS) {
16584     return rc;
16585   }
16586   if (authorization_delegate) {
16587     // Encrypt just the parameter data, not the size.
16588     std::string tmp = qualifying_data_bytes.substr(2);
16589     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16590       return TRUNKS_RC_ENCRYPTION_FAILED;
16591     }
16592     qualifying_data_bytes.replace(2, std::string::npos, tmp);
16593   }
16594   std::unique_ptr<crypto::SecureHash> hash(
16595       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16596   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16597   hash->Update(object_handle_name.data(), object_handle_name.size());
16598   handle_section_bytes += object_handle_bytes;
16599   command_size += object_handle_bytes.size();
16600   hash->Update(sign_handle_name.data(), sign_handle_name.size());
16601   handle_section_bytes += sign_handle_bytes;
16602   command_size += sign_handle_bytes.size();
16603   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16604   parameter_section_bytes += qualifying_data_bytes;
16605   command_size += qualifying_data_bytes.size();
16606   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16607   parameter_section_bytes += in_scheme_bytes;
16608   command_size += in_scheme_bytes.size();
16609   std::string command_hash(32, 0);
16610   hash->Finish(std::data(command_hash), command_hash.size());
16611   std::string authorization_section_bytes;
16612   std::string authorization_size_bytes;
16613   if (authorization_delegate) {
16614     if (!authorization_delegate->GetCommandAuthorization(
16615             command_hash, is_command_parameter_encryption_possible,
16616             is_response_parameter_encryption_possible,
16617             &authorization_section_bytes)) {
16618       return TRUNKS_RC_AUTHORIZATION_FAILED;
16619     }
16620     if (!authorization_section_bytes.empty()) {
16621       tag = TPM_ST_SESSIONS;
16622       std::string tmp;
16623       rc = Serialize_UINT32(authorization_section_bytes.size(),
16624                             &authorization_size_bytes);
16625       if (rc != TPM_RC_SUCCESS) {
16626         return rc;
16627       }
16628       command_size +=
16629           authorization_size_bytes.size() + authorization_section_bytes.size();
16630     }
16631   }
16632   std::string tag_bytes;
16633   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16634   if (rc != TPM_RC_SUCCESS) {
16635     return rc;
16636   }
16637   std::string command_size_bytes;
16638   rc = Serialize_UINT32(command_size, &command_size_bytes);
16639   if (rc != TPM_RC_SUCCESS) {
16640     return rc;
16641   }
16642   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16643                         handle_section_bytes + authorization_size_bytes +
16644                         authorization_section_bytes + parameter_section_bytes;
16645   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16646   VLOG(2) << "Command: "
16647           << base::HexEncode(serialized_command->data(),
16648                              serialized_command->size());
16649   return TPM_RC_SUCCESS;
16650 }
16651 
ParseResponse_Certify(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16652 TPM_RC Tpm::ParseResponse_Certify(
16653     const std::string& response,
16654     TPM2B_ATTEST* certify_info,
16655     TPMT_SIGNATURE* signature,
16656     AuthorizationDelegate* authorization_delegate) {
16657   VLOG(3) << __func__;
16658   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16659   TPM_RC rc = TPM_RC_SUCCESS;
16660   std::string buffer(response);
16661   TPM_ST tag;
16662   std::string tag_bytes;
16663   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16664   if (rc != TPM_RC_SUCCESS) {
16665     return rc;
16666   }
16667   UINT32 response_size;
16668   std::string response_size_bytes;
16669   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16670   if (rc != TPM_RC_SUCCESS) {
16671     return rc;
16672   }
16673   TPM_RC response_code;
16674   std::string response_code_bytes;
16675   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16676   if (rc != TPM_RC_SUCCESS) {
16677     return rc;
16678   }
16679   if (response_size != response.size()) {
16680     return TPM_RC_SIZE;
16681   }
16682   if (response_code != TPM_RC_SUCCESS) {
16683     return response_code;
16684   }
16685   TPM_CC command_code = TPM_CC_Certify;
16686   std::string command_code_bytes;
16687   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16688   if (rc != TPM_RC_SUCCESS) {
16689     return rc;
16690   }
16691   std::string authorization_section_bytes;
16692   if (tag == TPM_ST_SESSIONS) {
16693     UINT32 parameter_section_size = buffer.size();
16694     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16695     if (rc != TPM_RC_SUCCESS) {
16696       return rc;
16697     }
16698     if (parameter_section_size > buffer.size()) {
16699       return TPM_RC_INSUFFICIENT;
16700     }
16701     authorization_section_bytes = buffer.substr(parameter_section_size);
16702     // Keep the parameter section in |buffer|.
16703     buffer.erase(parameter_section_size);
16704   }
16705   std::unique_ptr<crypto::SecureHash> hash(
16706       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16707   hash->Update(response_code_bytes.data(), response_code_bytes.size());
16708   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16709   hash->Update(buffer.data(), buffer.size());
16710   std::string response_hash(32, 0);
16711   hash->Finish(std::data(response_hash), response_hash.size());
16712   if (tag == TPM_ST_SESSIONS) {
16713     if (!authorization_delegate)
16714       return TRUNKS_RC_AUTHORIZATION_FAILED;
16715     if (!authorization_delegate->CheckResponseAuthorization(
16716             response_hash, authorization_section_bytes)) {
16717       return TRUNKS_RC_AUTHORIZATION_FAILED;
16718     }
16719   }
16720   if (tag == TPM_ST_SESSIONS) {
16721     if (!authorization_delegate)
16722       return TRUNKS_RC_AUTHORIZATION_FAILED;
16723 
16724     // Parse the encrypted parameter size.
16725     UINT16 size;
16726     std::string size_buffer = buffer.substr(0, 2);
16727     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
16728       return result;
16729     }
16730     if (buffer.size() < 2 + size) {
16731       return TPM_RC_INSUFFICIENT;
16732     }
16733 
16734     // Decrypt just the parameter data, not the size.
16735     std::string decrypted_data = buffer.substr(2, size);
16736     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
16737       return TRUNKS_RC_ENCRYPTION_FAILED;
16738     }
16739     buffer.replace(2, size, decrypted_data);
16740   }
16741   std::string certify_info_bytes;
16742   rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
16743   if (rc != TPM_RC_SUCCESS) {
16744     return rc;
16745   }
16746   std::string signature_bytes;
16747   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
16748   if (rc != TPM_RC_SUCCESS) {
16749     return rc;
16750   }
16751   return TPM_RC_SUCCESS;
16752 }
16753 
CertifyErrorCallback(Tpm::CertifyResponse callback,TPM_RC response_code)16754 void CertifyErrorCallback(Tpm::CertifyResponse callback, TPM_RC response_code) {
16755   VLOG(1) << __func__;
16756   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
16757 }
16758 
CertifyResponseParser(Tpm::CertifyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)16759 void CertifyResponseParser(Tpm::CertifyResponse callback,
16760                            AuthorizationDelegate* authorization_delegate,
16761                            const std::string& response) {
16762   VLOG(1) << __func__;
16763   TPM2B_ATTEST certify_info;
16764   TPMT_SIGNATURE signature;
16765   TPM_RC rc = Tpm::ParseResponse_Certify(response, &certify_info, &signature,
16766                                          authorization_delegate);
16767   if (rc != TPM_RC_SUCCESS) {
16768     base::OnceCallback<void(TPM_RC)> error_reporter =
16769         base::BindOnce(CertifyErrorCallback, std::move(callback));
16770     std::move(error_reporter).Run(rc);
16771     return;
16772   }
16773   std::move(callback).Run(rc, certify_info, signature);
16774 }
16775 
Certify(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,CertifyResponse callback)16776 void Tpm::Certify(const TPMI_DH_OBJECT& object_handle,
16777                   const std::string& object_handle_name,
16778                   const TPMI_DH_OBJECT& sign_handle,
16779                   const std::string& sign_handle_name,
16780                   const TPM2B_DATA& qualifying_data,
16781                   const TPMT_SIG_SCHEME& in_scheme,
16782                   AuthorizationDelegate* authorization_delegate,
16783                   CertifyResponse callback) {
16784   VLOG(1) << __func__;
16785   std::string command;
16786   TPM_RC rc = SerializeCommand_Certify(
16787       object_handle, object_handle_name, sign_handle, sign_handle_name,
16788       qualifying_data, in_scheme, &command, authorization_delegate);
16789   if (rc != TPM_RC_SUCCESS) {
16790     base::OnceCallback<void(TPM_RC)> error_reporter =
16791         base::BindOnce(CertifyErrorCallback, std::move(callback));
16792     std::move(error_reporter).Run(rc);
16793     return;
16794   }
16795   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
16796       CertifyResponseParser, std::move(callback), authorization_delegate);
16797   transceiver_->SendCommand(command, std::move(parser));
16798 }
16799 
CertifySync(const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16800 TPM_RC Tpm::CertifySync(const TPMI_DH_OBJECT& object_handle,
16801                         const std::string& object_handle_name,
16802                         const TPMI_DH_OBJECT& sign_handle,
16803                         const std::string& sign_handle_name,
16804                         const TPM2B_DATA& qualifying_data,
16805                         const TPMT_SIG_SCHEME& in_scheme,
16806                         TPM2B_ATTEST* certify_info,
16807                         TPMT_SIGNATURE* signature,
16808                         AuthorizationDelegate* authorization_delegate) {
16809   VLOG(1) << __func__;
16810   std::string command;
16811   TPM_RC rc = SerializeCommand_Certify(
16812       object_handle, object_handle_name, sign_handle, sign_handle_name,
16813       qualifying_data, in_scheme, &command, authorization_delegate);
16814   if (rc != TPM_RC_SUCCESS) {
16815     return rc;
16816   }
16817   std::string response = transceiver_->SendCommandAndWait(command);
16818   rc = ParseResponse_Certify(response, certify_info, signature,
16819                              authorization_delegate);
16820   return rc;
16821 }
16822 
SerializeCommand_CertifyCreation(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPM2B_DATA & qualifying_data,const TPM2B_DIGEST & creation_hash,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_CREATION & creation_ticket,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)16823 TPM_RC Tpm::SerializeCommand_CertifyCreation(
16824     const TPMI_DH_OBJECT& sign_handle,
16825     const std::string& sign_handle_name,
16826     const TPMI_DH_OBJECT& object_handle,
16827     const std::string& object_handle_name,
16828     const TPM2B_DATA& qualifying_data,
16829     const TPM2B_DIGEST& creation_hash,
16830     const TPMT_SIG_SCHEME& in_scheme,
16831     const TPMT_TK_CREATION& creation_ticket,
16832     std::string* serialized_command,
16833     AuthorizationDelegate* authorization_delegate) {
16834   VLOG(3) << __func__;
16835   TPM_RC rc = TPM_RC_SUCCESS;
16836   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
16837   UINT32 command_size = 10;  // Header size.
16838   std::string handle_section_bytes;
16839   std::string parameter_section_bytes;
16840   TPM_CC command_code = TPM_CC_CertifyCreation;
16841   bool is_command_parameter_encryption_possible = true;
16842   bool is_response_parameter_encryption_possible = true;
16843   std::string command_code_bytes;
16844   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16845   if (rc != TPM_RC_SUCCESS) {
16846     return rc;
16847   }
16848   std::string sign_handle_bytes;
16849   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
16850   if (rc != TPM_RC_SUCCESS) {
16851     return rc;
16852   }
16853   std::string object_handle_bytes;
16854   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
16855   if (rc != TPM_RC_SUCCESS) {
16856     return rc;
16857   }
16858   std::string qualifying_data_bytes;
16859   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
16860   if (rc != TPM_RC_SUCCESS) {
16861     return rc;
16862   }
16863   std::string creation_hash_bytes;
16864   rc = Serialize_TPM2B_DIGEST(creation_hash, &creation_hash_bytes);
16865   if (rc != TPM_RC_SUCCESS) {
16866     return rc;
16867   }
16868   std::string in_scheme_bytes;
16869   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
16870   if (rc != TPM_RC_SUCCESS) {
16871     return rc;
16872   }
16873   std::string creation_ticket_bytes;
16874   rc = Serialize_TPMT_TK_CREATION(creation_ticket, &creation_ticket_bytes);
16875   if (rc != TPM_RC_SUCCESS) {
16876     return rc;
16877   }
16878   if (authorization_delegate) {
16879     // Encrypt just the parameter data, not the size.
16880     std::string tmp = qualifying_data_bytes.substr(2);
16881     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
16882       return TRUNKS_RC_ENCRYPTION_FAILED;
16883     }
16884     qualifying_data_bytes.replace(2, std::string::npos, tmp);
16885   }
16886   std::unique_ptr<crypto::SecureHash> hash(
16887       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
16888   hash->Update(command_code_bytes.data(), command_code_bytes.size());
16889   hash->Update(sign_handle_name.data(), sign_handle_name.size());
16890   handle_section_bytes += sign_handle_bytes;
16891   command_size += sign_handle_bytes.size();
16892   hash->Update(object_handle_name.data(), object_handle_name.size());
16893   handle_section_bytes += object_handle_bytes;
16894   command_size += object_handle_bytes.size();
16895   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
16896   parameter_section_bytes += qualifying_data_bytes;
16897   command_size += qualifying_data_bytes.size();
16898   hash->Update(creation_hash_bytes.data(), creation_hash_bytes.size());
16899   parameter_section_bytes += creation_hash_bytes;
16900   command_size += creation_hash_bytes.size();
16901   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
16902   parameter_section_bytes += in_scheme_bytes;
16903   command_size += in_scheme_bytes.size();
16904   hash->Update(creation_ticket_bytes.data(), creation_ticket_bytes.size());
16905   parameter_section_bytes += creation_ticket_bytes;
16906   command_size += creation_ticket_bytes.size();
16907   std::string command_hash(32, 0);
16908   hash->Finish(std::data(command_hash), command_hash.size());
16909   std::string authorization_section_bytes;
16910   std::string authorization_size_bytes;
16911   if (authorization_delegate) {
16912     if (!authorization_delegate->GetCommandAuthorization(
16913             command_hash, is_command_parameter_encryption_possible,
16914             is_response_parameter_encryption_possible,
16915             &authorization_section_bytes)) {
16916       return TRUNKS_RC_AUTHORIZATION_FAILED;
16917     }
16918     if (!authorization_section_bytes.empty()) {
16919       tag = TPM_ST_SESSIONS;
16920       std::string tmp;
16921       rc = Serialize_UINT32(authorization_section_bytes.size(),
16922                             &authorization_size_bytes);
16923       if (rc != TPM_RC_SUCCESS) {
16924         return rc;
16925       }
16926       command_size +=
16927           authorization_size_bytes.size() + authorization_section_bytes.size();
16928     }
16929   }
16930   std::string tag_bytes;
16931   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
16932   if (rc != TPM_RC_SUCCESS) {
16933     return rc;
16934   }
16935   std::string command_size_bytes;
16936   rc = Serialize_UINT32(command_size, &command_size_bytes);
16937   if (rc != TPM_RC_SUCCESS) {
16938     return rc;
16939   }
16940   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
16941                         handle_section_bytes + authorization_size_bytes +
16942                         authorization_section_bytes + parameter_section_bytes;
16943   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
16944   VLOG(2) << "Command: "
16945           << base::HexEncode(serialized_command->data(),
16946                              serialized_command->size());
16947   return TPM_RC_SUCCESS;
16948 }
16949 
ParseResponse_CertifyCreation(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)16950 TPM_RC Tpm::ParseResponse_CertifyCreation(
16951     const std::string& response,
16952     TPM2B_ATTEST* certify_info,
16953     TPMT_SIGNATURE* signature,
16954     AuthorizationDelegate* authorization_delegate) {
16955   VLOG(3) << __func__;
16956   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
16957   TPM_RC rc = TPM_RC_SUCCESS;
16958   std::string buffer(response);
16959   TPM_ST tag;
16960   std::string tag_bytes;
16961   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
16962   if (rc != TPM_RC_SUCCESS) {
16963     return rc;
16964   }
16965   UINT32 response_size;
16966   std::string response_size_bytes;
16967   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
16968   if (rc != TPM_RC_SUCCESS) {
16969     return rc;
16970   }
16971   TPM_RC response_code;
16972   std::string response_code_bytes;
16973   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
16974   if (rc != TPM_RC_SUCCESS) {
16975     return rc;
16976   }
16977   if (response_size != response.size()) {
16978     return TPM_RC_SIZE;
16979   }
16980   if (response_code != TPM_RC_SUCCESS) {
16981     return response_code;
16982   }
16983   TPM_CC command_code = TPM_CC_CertifyCreation;
16984   std::string command_code_bytes;
16985   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
16986   if (rc != TPM_RC_SUCCESS) {
16987     return rc;
16988   }
16989   std::string authorization_section_bytes;
16990   if (tag == TPM_ST_SESSIONS) {
16991     UINT32 parameter_section_size = buffer.size();
16992     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
16993     if (rc != TPM_RC_SUCCESS) {
16994       return rc;
16995     }
16996     if (parameter_section_size > buffer.size()) {
16997       return TPM_RC_INSUFFICIENT;
16998     }
16999     authorization_section_bytes = buffer.substr(parameter_section_size);
17000     // Keep the parameter section in |buffer|.
17001     buffer.erase(parameter_section_size);
17002   }
17003   std::unique_ptr<crypto::SecureHash> hash(
17004       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17005   hash->Update(response_code_bytes.data(), response_code_bytes.size());
17006   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17007   hash->Update(buffer.data(), buffer.size());
17008   std::string response_hash(32, 0);
17009   hash->Finish(std::data(response_hash), response_hash.size());
17010   if (tag == TPM_ST_SESSIONS) {
17011     if (!authorization_delegate)
17012       return TRUNKS_RC_AUTHORIZATION_FAILED;
17013     if (!authorization_delegate->CheckResponseAuthorization(
17014             response_hash, authorization_section_bytes)) {
17015       return TRUNKS_RC_AUTHORIZATION_FAILED;
17016     }
17017   }
17018   if (tag == TPM_ST_SESSIONS) {
17019     if (!authorization_delegate)
17020       return TRUNKS_RC_AUTHORIZATION_FAILED;
17021 
17022     // Parse the encrypted parameter size.
17023     UINT16 size;
17024     std::string size_buffer = buffer.substr(0, 2);
17025     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17026       return result;
17027     }
17028     if (buffer.size() < 2 + size) {
17029       return TPM_RC_INSUFFICIENT;
17030     }
17031 
17032     // Decrypt just the parameter data, not the size.
17033     std::string decrypted_data = buffer.substr(2, size);
17034     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17035       return TRUNKS_RC_ENCRYPTION_FAILED;
17036     }
17037     buffer.replace(2, size, decrypted_data);
17038   }
17039   std::string certify_info_bytes;
17040   rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
17041   if (rc != TPM_RC_SUCCESS) {
17042     return rc;
17043   }
17044   std::string signature_bytes;
17045   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17046   if (rc != TPM_RC_SUCCESS) {
17047     return rc;
17048   }
17049   return TPM_RC_SUCCESS;
17050 }
17051 
CertifyCreationErrorCallback(Tpm::CertifyCreationResponse callback,TPM_RC response_code)17052 void CertifyCreationErrorCallback(Tpm::CertifyCreationResponse callback,
17053                                   TPM_RC response_code) {
17054   VLOG(1) << __func__;
17055   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17056 }
17057 
CertifyCreationResponseParser(Tpm::CertifyCreationResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17058 void CertifyCreationResponseParser(
17059     Tpm::CertifyCreationResponse callback,
17060     AuthorizationDelegate* authorization_delegate,
17061     const std::string& response) {
17062   VLOG(1) << __func__;
17063   TPM2B_ATTEST certify_info;
17064   TPMT_SIGNATURE signature;
17065   TPM_RC rc = Tpm::ParseResponse_CertifyCreation(
17066       response, &certify_info, &signature, authorization_delegate);
17067   if (rc != TPM_RC_SUCCESS) {
17068     base::OnceCallback<void(TPM_RC)> error_reporter =
17069         base::BindOnce(CertifyCreationErrorCallback, std::move(callback));
17070     std::move(error_reporter).Run(rc);
17071     return;
17072   }
17073   std::move(callback).Run(rc, certify_info, signature);
17074 }
17075 
CertifyCreation(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPM2B_DATA & qualifying_data,const TPM2B_DIGEST & creation_hash,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_CREATION & creation_ticket,AuthorizationDelegate * authorization_delegate,CertifyCreationResponse callback)17076 void Tpm::CertifyCreation(const TPMI_DH_OBJECT& sign_handle,
17077                           const std::string& sign_handle_name,
17078                           const TPMI_DH_OBJECT& object_handle,
17079                           const std::string& object_handle_name,
17080                           const TPM2B_DATA& qualifying_data,
17081                           const TPM2B_DIGEST& creation_hash,
17082                           const TPMT_SIG_SCHEME& in_scheme,
17083                           const TPMT_TK_CREATION& creation_ticket,
17084                           AuthorizationDelegate* authorization_delegate,
17085                           CertifyCreationResponse callback) {
17086   VLOG(1) << __func__;
17087   std::string command;
17088   TPM_RC rc = SerializeCommand_CertifyCreation(
17089       sign_handle, sign_handle_name, object_handle, object_handle_name,
17090       qualifying_data, creation_hash, in_scheme, creation_ticket, &command,
17091       authorization_delegate);
17092   if (rc != TPM_RC_SUCCESS) {
17093     base::OnceCallback<void(TPM_RC)> error_reporter =
17094         base::BindOnce(CertifyCreationErrorCallback, std::move(callback));
17095     std::move(error_reporter).Run(rc);
17096     return;
17097   }
17098   base::OnceCallback<void(const std::string&)> parser =
17099       base::BindOnce(CertifyCreationResponseParser, std::move(callback),
17100                      authorization_delegate);
17101   transceiver_->SendCommand(command, std::move(parser));
17102 }
17103 
CertifyCreationSync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPM2B_DATA & qualifying_data,const TPM2B_DIGEST & creation_hash,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_CREATION & creation_ticket,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17104 TPM_RC Tpm::CertifyCreationSync(const TPMI_DH_OBJECT& sign_handle,
17105                                 const std::string& sign_handle_name,
17106                                 const TPMI_DH_OBJECT& object_handle,
17107                                 const std::string& object_handle_name,
17108                                 const TPM2B_DATA& qualifying_data,
17109                                 const TPM2B_DIGEST& creation_hash,
17110                                 const TPMT_SIG_SCHEME& in_scheme,
17111                                 const TPMT_TK_CREATION& creation_ticket,
17112                                 TPM2B_ATTEST* certify_info,
17113                                 TPMT_SIGNATURE* signature,
17114                                 AuthorizationDelegate* authorization_delegate) {
17115   VLOG(1) << __func__;
17116   std::string command;
17117   TPM_RC rc = SerializeCommand_CertifyCreation(
17118       sign_handle, sign_handle_name, object_handle, object_handle_name,
17119       qualifying_data, creation_hash, in_scheme, creation_ticket, &command,
17120       authorization_delegate);
17121   if (rc != TPM_RC_SUCCESS) {
17122     return rc;
17123   }
17124   std::string response = transceiver_->SendCommandAndWait(command);
17125   rc = ParseResponse_CertifyCreation(response, certify_info, signature,
17126                                      authorization_delegate);
17127   return rc;
17128 }
17129 
SerializeCommand_Quote(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const TPML_PCR_SELECTION & pcrselect,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17130 TPM_RC Tpm::SerializeCommand_Quote(
17131     const TPMI_DH_OBJECT& sign_handle,
17132     const std::string& sign_handle_name,
17133     const TPM2B_DATA& qualifying_data,
17134     const TPMT_SIG_SCHEME& in_scheme,
17135     const TPML_PCR_SELECTION& pcrselect,
17136     std::string* serialized_command,
17137     AuthorizationDelegate* authorization_delegate) {
17138   VLOG(3) << __func__;
17139   TPM_RC rc = TPM_RC_SUCCESS;
17140   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17141   UINT32 command_size = 10;  // Header size.
17142   std::string handle_section_bytes;
17143   std::string parameter_section_bytes;
17144   TPM_CC command_code = TPM_CC_Quote;
17145   bool is_command_parameter_encryption_possible = true;
17146   bool is_response_parameter_encryption_possible = true;
17147   std::string command_code_bytes;
17148   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17149   if (rc != TPM_RC_SUCCESS) {
17150     return rc;
17151   }
17152   std::string sign_handle_bytes;
17153   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17154   if (rc != TPM_RC_SUCCESS) {
17155     return rc;
17156   }
17157   std::string qualifying_data_bytes;
17158   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17159   if (rc != TPM_RC_SUCCESS) {
17160     return rc;
17161   }
17162   std::string in_scheme_bytes;
17163   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17164   if (rc != TPM_RC_SUCCESS) {
17165     return rc;
17166   }
17167   std::string pcrselect_bytes;
17168   rc = Serialize_TPML_PCR_SELECTION(pcrselect, &pcrselect_bytes);
17169   if (rc != TPM_RC_SUCCESS) {
17170     return rc;
17171   }
17172   if (authorization_delegate) {
17173     // Encrypt just the parameter data, not the size.
17174     std::string tmp = qualifying_data_bytes.substr(2);
17175     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17176       return TRUNKS_RC_ENCRYPTION_FAILED;
17177     }
17178     qualifying_data_bytes.replace(2, std::string::npos, tmp);
17179   }
17180   std::unique_ptr<crypto::SecureHash> hash(
17181       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17182   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17183   hash->Update(sign_handle_name.data(), sign_handle_name.size());
17184   handle_section_bytes += sign_handle_bytes;
17185   command_size += sign_handle_bytes.size();
17186   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17187   parameter_section_bytes += qualifying_data_bytes;
17188   command_size += qualifying_data_bytes.size();
17189   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17190   parameter_section_bytes += in_scheme_bytes;
17191   command_size += in_scheme_bytes.size();
17192   hash->Update(pcrselect_bytes.data(), pcrselect_bytes.size());
17193   parameter_section_bytes += pcrselect_bytes;
17194   command_size += pcrselect_bytes.size();
17195   std::string command_hash(32, 0);
17196   hash->Finish(std::data(command_hash), command_hash.size());
17197   std::string authorization_section_bytes;
17198   std::string authorization_size_bytes;
17199   if (authorization_delegate) {
17200     if (!authorization_delegate->GetCommandAuthorization(
17201             command_hash, is_command_parameter_encryption_possible,
17202             is_response_parameter_encryption_possible,
17203             &authorization_section_bytes)) {
17204       return TRUNKS_RC_AUTHORIZATION_FAILED;
17205     }
17206     if (!authorization_section_bytes.empty()) {
17207       tag = TPM_ST_SESSIONS;
17208       std::string tmp;
17209       rc = Serialize_UINT32(authorization_section_bytes.size(),
17210                             &authorization_size_bytes);
17211       if (rc != TPM_RC_SUCCESS) {
17212         return rc;
17213       }
17214       command_size +=
17215           authorization_size_bytes.size() + authorization_section_bytes.size();
17216     }
17217   }
17218   std::string tag_bytes;
17219   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17220   if (rc != TPM_RC_SUCCESS) {
17221     return rc;
17222   }
17223   std::string command_size_bytes;
17224   rc = Serialize_UINT32(command_size, &command_size_bytes);
17225   if (rc != TPM_RC_SUCCESS) {
17226     return rc;
17227   }
17228   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17229                         handle_section_bytes + authorization_size_bytes +
17230                         authorization_section_bytes + parameter_section_bytes;
17231   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17232   VLOG(2) << "Command: "
17233           << base::HexEncode(serialized_command->data(),
17234                              serialized_command->size());
17235   return TPM_RC_SUCCESS;
17236 }
17237 
ParseResponse_Quote(const std::string & response,TPM2B_ATTEST * quoted,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17238 TPM_RC Tpm::ParseResponse_Quote(const std::string& response,
17239                                 TPM2B_ATTEST* quoted,
17240                                 TPMT_SIGNATURE* signature,
17241                                 AuthorizationDelegate* authorization_delegate) {
17242   VLOG(3) << __func__;
17243   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17244   TPM_RC rc = TPM_RC_SUCCESS;
17245   std::string buffer(response);
17246   TPM_ST tag;
17247   std::string tag_bytes;
17248   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17249   if (rc != TPM_RC_SUCCESS) {
17250     return rc;
17251   }
17252   UINT32 response_size;
17253   std::string response_size_bytes;
17254   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17255   if (rc != TPM_RC_SUCCESS) {
17256     return rc;
17257   }
17258   TPM_RC response_code;
17259   std::string response_code_bytes;
17260   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17261   if (rc != TPM_RC_SUCCESS) {
17262     return rc;
17263   }
17264   if (response_size != response.size()) {
17265     return TPM_RC_SIZE;
17266   }
17267   if (response_code != TPM_RC_SUCCESS) {
17268     return response_code;
17269   }
17270   TPM_CC command_code = TPM_CC_Quote;
17271   std::string command_code_bytes;
17272   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17273   if (rc != TPM_RC_SUCCESS) {
17274     return rc;
17275   }
17276   std::string authorization_section_bytes;
17277   if (tag == TPM_ST_SESSIONS) {
17278     UINT32 parameter_section_size = buffer.size();
17279     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
17280     if (rc != TPM_RC_SUCCESS) {
17281       return rc;
17282     }
17283     if (parameter_section_size > buffer.size()) {
17284       return TPM_RC_INSUFFICIENT;
17285     }
17286     authorization_section_bytes = buffer.substr(parameter_section_size);
17287     // Keep the parameter section in |buffer|.
17288     buffer.erase(parameter_section_size);
17289   }
17290   std::unique_ptr<crypto::SecureHash> hash(
17291       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17292   hash->Update(response_code_bytes.data(), response_code_bytes.size());
17293   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17294   hash->Update(buffer.data(), buffer.size());
17295   std::string response_hash(32, 0);
17296   hash->Finish(std::data(response_hash), response_hash.size());
17297   if (tag == TPM_ST_SESSIONS) {
17298     if (!authorization_delegate)
17299       return TRUNKS_RC_AUTHORIZATION_FAILED;
17300     if (!authorization_delegate->CheckResponseAuthorization(
17301             response_hash, authorization_section_bytes)) {
17302       return TRUNKS_RC_AUTHORIZATION_FAILED;
17303     }
17304   }
17305   if (tag == TPM_ST_SESSIONS) {
17306     if (!authorization_delegate)
17307       return TRUNKS_RC_AUTHORIZATION_FAILED;
17308 
17309     // Parse the encrypted parameter size.
17310     UINT16 size;
17311     std::string size_buffer = buffer.substr(0, 2);
17312     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17313       return result;
17314     }
17315     if (buffer.size() < 2 + size) {
17316       return TPM_RC_INSUFFICIENT;
17317     }
17318 
17319     // Decrypt just the parameter data, not the size.
17320     std::string decrypted_data = buffer.substr(2, size);
17321     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17322       return TRUNKS_RC_ENCRYPTION_FAILED;
17323     }
17324     buffer.replace(2, size, decrypted_data);
17325   }
17326   std::string quoted_bytes;
17327   rc = Parse_TPM2B_ATTEST(&buffer, quoted, &quoted_bytes);
17328   if (rc != TPM_RC_SUCCESS) {
17329     return rc;
17330   }
17331   std::string signature_bytes;
17332   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17333   if (rc != TPM_RC_SUCCESS) {
17334     return rc;
17335   }
17336   return TPM_RC_SUCCESS;
17337 }
17338 
QuoteErrorCallback(Tpm::QuoteResponse callback,TPM_RC response_code)17339 void QuoteErrorCallback(Tpm::QuoteResponse callback, TPM_RC response_code) {
17340   VLOG(1) << __func__;
17341   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17342 }
17343 
QuoteResponseParser(Tpm::QuoteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17344 void QuoteResponseParser(Tpm::QuoteResponse callback,
17345                          AuthorizationDelegate* authorization_delegate,
17346                          const std::string& response) {
17347   VLOG(1) << __func__;
17348   TPM2B_ATTEST quoted;
17349   TPMT_SIGNATURE signature;
17350   TPM_RC rc = Tpm::ParseResponse_Quote(response, &quoted, &signature,
17351                                        authorization_delegate);
17352   if (rc != TPM_RC_SUCCESS) {
17353     base::OnceCallback<void(TPM_RC)> error_reporter =
17354         base::BindOnce(QuoteErrorCallback, std::move(callback));
17355     std::move(error_reporter).Run(rc);
17356     return;
17357   }
17358   std::move(callback).Run(rc, quoted, signature);
17359 }
17360 
Quote(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const TPML_PCR_SELECTION & pcrselect,AuthorizationDelegate * authorization_delegate,QuoteResponse callback)17361 void Tpm::Quote(const TPMI_DH_OBJECT& sign_handle,
17362                 const std::string& sign_handle_name,
17363                 const TPM2B_DATA& qualifying_data,
17364                 const TPMT_SIG_SCHEME& in_scheme,
17365                 const TPML_PCR_SELECTION& pcrselect,
17366                 AuthorizationDelegate* authorization_delegate,
17367                 QuoteResponse callback) {
17368   VLOG(1) << __func__;
17369   std::string command;
17370   TPM_RC rc = SerializeCommand_Quote(sign_handle, sign_handle_name,
17371                                      qualifying_data, in_scheme, pcrselect,
17372                                      &command, authorization_delegate);
17373   if (rc != TPM_RC_SUCCESS) {
17374     base::OnceCallback<void(TPM_RC)> error_reporter =
17375         base::BindOnce(QuoteErrorCallback, std::move(callback));
17376     std::move(error_reporter).Run(rc);
17377     return;
17378   }
17379   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
17380       QuoteResponseParser, std::move(callback), authorization_delegate);
17381   transceiver_->SendCommand(command, std::move(parser));
17382 }
17383 
QuoteSync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const TPML_PCR_SELECTION & pcrselect,TPM2B_ATTEST * quoted,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17384 TPM_RC Tpm::QuoteSync(const TPMI_DH_OBJECT& sign_handle,
17385                       const std::string& sign_handle_name,
17386                       const TPM2B_DATA& qualifying_data,
17387                       const TPMT_SIG_SCHEME& in_scheme,
17388                       const TPML_PCR_SELECTION& pcrselect,
17389                       TPM2B_ATTEST* quoted,
17390                       TPMT_SIGNATURE* signature,
17391                       AuthorizationDelegate* authorization_delegate) {
17392   VLOG(1) << __func__;
17393   std::string command;
17394   TPM_RC rc = SerializeCommand_Quote(sign_handle, sign_handle_name,
17395                                      qualifying_data, in_scheme, pcrselect,
17396                                      &command, authorization_delegate);
17397   if (rc != TPM_RC_SUCCESS) {
17398     return rc;
17399   }
17400   std::string response = transceiver_->SendCommandAndWait(command);
17401   rc = ParseResponse_Quote(response, quoted, signature, authorization_delegate);
17402   return rc;
17403 }
17404 
SerializeCommand_GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_SH_HMAC & session_handle,const std::string & session_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17405 TPM_RC Tpm::SerializeCommand_GetSessionAuditDigest(
17406     const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17407     const std::string& privacy_admin_handle_name,
17408     const TPMI_DH_OBJECT& sign_handle,
17409     const std::string& sign_handle_name,
17410     const TPMI_SH_HMAC& session_handle,
17411     const std::string& session_handle_name,
17412     const TPM2B_DATA& qualifying_data,
17413     const TPMT_SIG_SCHEME& in_scheme,
17414     std::string* serialized_command,
17415     AuthorizationDelegate* authorization_delegate) {
17416   VLOG(3) << __func__;
17417   TPM_RC rc = TPM_RC_SUCCESS;
17418   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17419   UINT32 command_size = 10;  // Header size.
17420   std::string handle_section_bytes;
17421   std::string parameter_section_bytes;
17422   TPM_CC command_code = TPM_CC_GetSessionAuditDigest;
17423   bool is_command_parameter_encryption_possible = true;
17424   bool is_response_parameter_encryption_possible = true;
17425   std::string command_code_bytes;
17426   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17427   if (rc != TPM_RC_SUCCESS) {
17428     return rc;
17429   }
17430   std::string privacy_admin_handle_bytes;
17431   rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_admin_handle,
17432                                      &privacy_admin_handle_bytes);
17433   if (rc != TPM_RC_SUCCESS) {
17434     return rc;
17435   }
17436   std::string sign_handle_bytes;
17437   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17438   if (rc != TPM_RC_SUCCESS) {
17439     return rc;
17440   }
17441   std::string session_handle_bytes;
17442   rc = Serialize_TPMI_SH_HMAC(session_handle, &session_handle_bytes);
17443   if (rc != TPM_RC_SUCCESS) {
17444     return rc;
17445   }
17446   std::string qualifying_data_bytes;
17447   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17448   if (rc != TPM_RC_SUCCESS) {
17449     return rc;
17450   }
17451   std::string in_scheme_bytes;
17452   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17453   if (rc != TPM_RC_SUCCESS) {
17454     return rc;
17455   }
17456   if (authorization_delegate) {
17457     // Encrypt just the parameter data, not the size.
17458     std::string tmp = qualifying_data_bytes.substr(2);
17459     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17460       return TRUNKS_RC_ENCRYPTION_FAILED;
17461     }
17462     qualifying_data_bytes.replace(2, std::string::npos, tmp);
17463   }
17464   std::unique_ptr<crypto::SecureHash> hash(
17465       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17466   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17467   hash->Update(privacy_admin_handle_name.data(),
17468                privacy_admin_handle_name.size());
17469   handle_section_bytes += privacy_admin_handle_bytes;
17470   command_size += privacy_admin_handle_bytes.size();
17471   hash->Update(sign_handle_name.data(), sign_handle_name.size());
17472   handle_section_bytes += sign_handle_bytes;
17473   command_size += sign_handle_bytes.size();
17474   hash->Update(session_handle_name.data(), session_handle_name.size());
17475   handle_section_bytes += session_handle_bytes;
17476   command_size += session_handle_bytes.size();
17477   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17478   parameter_section_bytes += qualifying_data_bytes;
17479   command_size += qualifying_data_bytes.size();
17480   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17481   parameter_section_bytes += in_scheme_bytes;
17482   command_size += in_scheme_bytes.size();
17483   std::string command_hash(32, 0);
17484   hash->Finish(std::data(command_hash), command_hash.size());
17485   std::string authorization_section_bytes;
17486   std::string authorization_size_bytes;
17487   if (authorization_delegate) {
17488     if (!authorization_delegate->GetCommandAuthorization(
17489             command_hash, is_command_parameter_encryption_possible,
17490             is_response_parameter_encryption_possible,
17491             &authorization_section_bytes)) {
17492       return TRUNKS_RC_AUTHORIZATION_FAILED;
17493     }
17494     if (!authorization_section_bytes.empty()) {
17495       tag = TPM_ST_SESSIONS;
17496       std::string tmp;
17497       rc = Serialize_UINT32(authorization_section_bytes.size(),
17498                             &authorization_size_bytes);
17499       if (rc != TPM_RC_SUCCESS) {
17500         return rc;
17501       }
17502       command_size +=
17503           authorization_size_bytes.size() + authorization_section_bytes.size();
17504     }
17505   }
17506   std::string tag_bytes;
17507   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17508   if (rc != TPM_RC_SUCCESS) {
17509     return rc;
17510   }
17511   std::string command_size_bytes;
17512   rc = Serialize_UINT32(command_size, &command_size_bytes);
17513   if (rc != TPM_RC_SUCCESS) {
17514     return rc;
17515   }
17516   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17517                         handle_section_bytes + authorization_size_bytes +
17518                         authorization_section_bytes + parameter_section_bytes;
17519   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17520   VLOG(2) << "Command: "
17521           << base::HexEncode(serialized_command->data(),
17522                              serialized_command->size());
17523   return TPM_RC_SUCCESS;
17524 }
17525 
ParseResponse_GetSessionAuditDigest(const std::string & response,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17526 TPM_RC Tpm::ParseResponse_GetSessionAuditDigest(
17527     const std::string& response,
17528     TPM2B_ATTEST* audit_info,
17529     TPMT_SIGNATURE* signature,
17530     AuthorizationDelegate* authorization_delegate) {
17531   VLOG(3) << __func__;
17532   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17533   TPM_RC rc = TPM_RC_SUCCESS;
17534   std::string buffer(response);
17535   TPM_ST tag;
17536   std::string tag_bytes;
17537   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17538   if (rc != TPM_RC_SUCCESS) {
17539     return rc;
17540   }
17541   UINT32 response_size;
17542   std::string response_size_bytes;
17543   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17544   if (rc != TPM_RC_SUCCESS) {
17545     return rc;
17546   }
17547   TPM_RC response_code;
17548   std::string response_code_bytes;
17549   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17550   if (rc != TPM_RC_SUCCESS) {
17551     return rc;
17552   }
17553   if (response_size != response.size()) {
17554     return TPM_RC_SIZE;
17555   }
17556   if (response_code != TPM_RC_SUCCESS) {
17557     return response_code;
17558   }
17559   TPM_CC command_code = TPM_CC_GetSessionAuditDigest;
17560   std::string command_code_bytes;
17561   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17562   if (rc != TPM_RC_SUCCESS) {
17563     return rc;
17564   }
17565   std::string authorization_section_bytes;
17566   if (tag == TPM_ST_SESSIONS) {
17567     UINT32 parameter_section_size = buffer.size();
17568     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
17569     if (rc != TPM_RC_SUCCESS) {
17570       return rc;
17571     }
17572     if (parameter_section_size > buffer.size()) {
17573       return TPM_RC_INSUFFICIENT;
17574     }
17575     authorization_section_bytes = buffer.substr(parameter_section_size);
17576     // Keep the parameter section in |buffer|.
17577     buffer.erase(parameter_section_size);
17578   }
17579   std::unique_ptr<crypto::SecureHash> hash(
17580       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17581   hash->Update(response_code_bytes.data(), response_code_bytes.size());
17582   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17583   hash->Update(buffer.data(), buffer.size());
17584   std::string response_hash(32, 0);
17585   hash->Finish(std::data(response_hash), response_hash.size());
17586   if (tag == TPM_ST_SESSIONS) {
17587     if (!authorization_delegate)
17588       return TRUNKS_RC_AUTHORIZATION_FAILED;
17589     if (!authorization_delegate->CheckResponseAuthorization(
17590             response_hash, authorization_section_bytes)) {
17591       return TRUNKS_RC_AUTHORIZATION_FAILED;
17592     }
17593   }
17594   if (tag == TPM_ST_SESSIONS) {
17595     if (!authorization_delegate)
17596       return TRUNKS_RC_AUTHORIZATION_FAILED;
17597 
17598     // Parse the encrypted parameter size.
17599     UINT16 size;
17600     std::string size_buffer = buffer.substr(0, 2);
17601     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17602       return result;
17603     }
17604     if (buffer.size() < 2 + size) {
17605       return TPM_RC_INSUFFICIENT;
17606     }
17607 
17608     // Decrypt just the parameter data, not the size.
17609     std::string decrypted_data = buffer.substr(2, size);
17610     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17611       return TRUNKS_RC_ENCRYPTION_FAILED;
17612     }
17613     buffer.replace(2, size, decrypted_data);
17614   }
17615   std::string audit_info_bytes;
17616   rc = Parse_TPM2B_ATTEST(&buffer, audit_info, &audit_info_bytes);
17617   if (rc != TPM_RC_SUCCESS) {
17618     return rc;
17619   }
17620   std::string signature_bytes;
17621   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17622   if (rc != TPM_RC_SUCCESS) {
17623     return rc;
17624   }
17625   return TPM_RC_SUCCESS;
17626 }
17627 
GetSessionAuditDigestErrorCallback(Tpm::GetSessionAuditDigestResponse callback,TPM_RC response_code)17628 void GetSessionAuditDigestErrorCallback(
17629     Tpm::GetSessionAuditDigestResponse callback, TPM_RC response_code) {
17630   VLOG(1) << __func__;
17631   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17632 }
17633 
GetSessionAuditDigestResponseParser(Tpm::GetSessionAuditDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17634 void GetSessionAuditDigestResponseParser(
17635     Tpm::GetSessionAuditDigestResponse callback,
17636     AuthorizationDelegate* authorization_delegate,
17637     const std::string& response) {
17638   VLOG(1) << __func__;
17639   TPM2B_ATTEST audit_info;
17640   TPMT_SIGNATURE signature;
17641   TPM_RC rc = Tpm::ParseResponse_GetSessionAuditDigest(
17642       response, &audit_info, &signature, authorization_delegate);
17643   if (rc != TPM_RC_SUCCESS) {
17644     base::OnceCallback<void(TPM_RC)> error_reporter =
17645         base::BindOnce(GetSessionAuditDigestErrorCallback, std::move(callback));
17646     std::move(error_reporter).Run(rc);
17647     return;
17648   }
17649   std::move(callback).Run(rc, audit_info, signature);
17650 }
17651 
GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_SH_HMAC & session_handle,const std::string & session_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,GetSessionAuditDigestResponse callback)17652 void Tpm::GetSessionAuditDigest(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17653                                 const std::string& privacy_admin_handle_name,
17654                                 const TPMI_DH_OBJECT& sign_handle,
17655                                 const std::string& sign_handle_name,
17656                                 const TPMI_SH_HMAC& session_handle,
17657                                 const std::string& session_handle_name,
17658                                 const TPM2B_DATA& qualifying_data,
17659                                 const TPMT_SIG_SCHEME& in_scheme,
17660                                 AuthorizationDelegate* authorization_delegate,
17661                                 GetSessionAuditDigestResponse callback) {
17662   VLOG(1) << __func__;
17663   std::string command;
17664   TPM_RC rc = SerializeCommand_GetSessionAuditDigest(
17665       privacy_admin_handle, privacy_admin_handle_name, sign_handle,
17666       sign_handle_name, session_handle, session_handle_name, qualifying_data,
17667       in_scheme, &command, authorization_delegate);
17668   if (rc != TPM_RC_SUCCESS) {
17669     base::OnceCallback<void(TPM_RC)> error_reporter =
17670         base::BindOnce(GetSessionAuditDigestErrorCallback, std::move(callback));
17671     std::move(error_reporter).Run(rc);
17672     return;
17673   }
17674   base::OnceCallback<void(const std::string&)> parser =
17675       base::BindOnce(GetSessionAuditDigestResponseParser, std::move(callback),
17676                      authorization_delegate);
17677   transceiver_->SendCommand(command, std::move(parser));
17678 }
17679 
GetSessionAuditDigestSync(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_SH_HMAC & session_handle,const std::string & session_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17680 TPM_RC Tpm::GetSessionAuditDigestSync(
17681     const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17682     const std::string& privacy_admin_handle_name,
17683     const TPMI_DH_OBJECT& sign_handle,
17684     const std::string& sign_handle_name,
17685     const TPMI_SH_HMAC& session_handle,
17686     const std::string& session_handle_name,
17687     const TPM2B_DATA& qualifying_data,
17688     const TPMT_SIG_SCHEME& in_scheme,
17689     TPM2B_ATTEST* audit_info,
17690     TPMT_SIGNATURE* signature,
17691     AuthorizationDelegate* authorization_delegate) {
17692   VLOG(1) << __func__;
17693   std::string command;
17694   TPM_RC rc = SerializeCommand_GetSessionAuditDigest(
17695       privacy_admin_handle, privacy_admin_handle_name, sign_handle,
17696       sign_handle_name, session_handle, session_handle_name, qualifying_data,
17697       in_scheme, &command, authorization_delegate);
17698   if (rc != TPM_RC_SUCCESS) {
17699     return rc;
17700   }
17701   std::string response = transceiver_->SendCommandAndWait(command);
17702   rc = ParseResponse_GetSessionAuditDigest(response, audit_info, signature,
17703                                            authorization_delegate);
17704   return rc;
17705 }
17706 
SerializeCommand_GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_handle,const std::string & privacy_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17707 TPM_RC Tpm::SerializeCommand_GetCommandAuditDigest(
17708     const TPMI_RH_ENDORSEMENT& privacy_handle,
17709     const std::string& privacy_handle_name,
17710     const TPMI_DH_OBJECT& sign_handle,
17711     const std::string& sign_handle_name,
17712     const TPM2B_DATA& qualifying_data,
17713     const TPMT_SIG_SCHEME& in_scheme,
17714     std::string* serialized_command,
17715     AuthorizationDelegate* authorization_delegate) {
17716   VLOG(3) << __func__;
17717   TPM_RC rc = TPM_RC_SUCCESS;
17718   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
17719   UINT32 command_size = 10;  // Header size.
17720   std::string handle_section_bytes;
17721   std::string parameter_section_bytes;
17722   TPM_CC command_code = TPM_CC_GetCommandAuditDigest;
17723   bool is_command_parameter_encryption_possible = true;
17724   bool is_response_parameter_encryption_possible = true;
17725   std::string command_code_bytes;
17726   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17727   if (rc != TPM_RC_SUCCESS) {
17728     return rc;
17729   }
17730   std::string privacy_handle_bytes;
17731   rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_handle, &privacy_handle_bytes);
17732   if (rc != TPM_RC_SUCCESS) {
17733     return rc;
17734   }
17735   std::string sign_handle_bytes;
17736   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
17737   if (rc != TPM_RC_SUCCESS) {
17738     return rc;
17739   }
17740   std::string qualifying_data_bytes;
17741   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
17742   if (rc != TPM_RC_SUCCESS) {
17743     return rc;
17744   }
17745   std::string in_scheme_bytes;
17746   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
17747   if (rc != TPM_RC_SUCCESS) {
17748     return rc;
17749   }
17750   if (authorization_delegate) {
17751     // Encrypt just the parameter data, not the size.
17752     std::string tmp = qualifying_data_bytes.substr(2);
17753     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
17754       return TRUNKS_RC_ENCRYPTION_FAILED;
17755     }
17756     qualifying_data_bytes.replace(2, std::string::npos, tmp);
17757   }
17758   std::unique_ptr<crypto::SecureHash> hash(
17759       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17760   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17761   hash->Update(privacy_handle_name.data(), privacy_handle_name.size());
17762   handle_section_bytes += privacy_handle_bytes;
17763   command_size += privacy_handle_bytes.size();
17764   hash->Update(sign_handle_name.data(), sign_handle_name.size());
17765   handle_section_bytes += sign_handle_bytes;
17766   command_size += sign_handle_bytes.size();
17767   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
17768   parameter_section_bytes += qualifying_data_bytes;
17769   command_size += qualifying_data_bytes.size();
17770   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
17771   parameter_section_bytes += in_scheme_bytes;
17772   command_size += in_scheme_bytes.size();
17773   std::string command_hash(32, 0);
17774   hash->Finish(std::data(command_hash), command_hash.size());
17775   std::string authorization_section_bytes;
17776   std::string authorization_size_bytes;
17777   if (authorization_delegate) {
17778     if (!authorization_delegate->GetCommandAuthorization(
17779             command_hash, is_command_parameter_encryption_possible,
17780             is_response_parameter_encryption_possible,
17781             &authorization_section_bytes)) {
17782       return TRUNKS_RC_AUTHORIZATION_FAILED;
17783     }
17784     if (!authorization_section_bytes.empty()) {
17785       tag = TPM_ST_SESSIONS;
17786       std::string tmp;
17787       rc = Serialize_UINT32(authorization_section_bytes.size(),
17788                             &authorization_size_bytes);
17789       if (rc != TPM_RC_SUCCESS) {
17790         return rc;
17791       }
17792       command_size +=
17793           authorization_size_bytes.size() + authorization_section_bytes.size();
17794     }
17795   }
17796   std::string tag_bytes;
17797   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
17798   if (rc != TPM_RC_SUCCESS) {
17799     return rc;
17800   }
17801   std::string command_size_bytes;
17802   rc = Serialize_UINT32(command_size, &command_size_bytes);
17803   if (rc != TPM_RC_SUCCESS) {
17804     return rc;
17805   }
17806   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
17807                         handle_section_bytes + authorization_size_bytes +
17808                         authorization_section_bytes + parameter_section_bytes;
17809   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
17810   VLOG(2) << "Command: "
17811           << base::HexEncode(serialized_command->data(),
17812                              serialized_command->size());
17813   return TPM_RC_SUCCESS;
17814 }
17815 
ParseResponse_GetCommandAuditDigest(const std::string & response,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17816 TPM_RC Tpm::ParseResponse_GetCommandAuditDigest(
17817     const std::string& response,
17818     TPM2B_ATTEST* audit_info,
17819     TPMT_SIGNATURE* signature,
17820     AuthorizationDelegate* authorization_delegate) {
17821   VLOG(3) << __func__;
17822   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
17823   TPM_RC rc = TPM_RC_SUCCESS;
17824   std::string buffer(response);
17825   TPM_ST tag;
17826   std::string tag_bytes;
17827   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
17828   if (rc != TPM_RC_SUCCESS) {
17829     return rc;
17830   }
17831   UINT32 response_size;
17832   std::string response_size_bytes;
17833   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
17834   if (rc != TPM_RC_SUCCESS) {
17835     return rc;
17836   }
17837   TPM_RC response_code;
17838   std::string response_code_bytes;
17839   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
17840   if (rc != TPM_RC_SUCCESS) {
17841     return rc;
17842   }
17843   if (response_size != response.size()) {
17844     return TPM_RC_SIZE;
17845   }
17846   if (response_code != TPM_RC_SUCCESS) {
17847     return response_code;
17848   }
17849   TPM_CC command_code = TPM_CC_GetCommandAuditDigest;
17850   std::string command_code_bytes;
17851   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
17852   if (rc != TPM_RC_SUCCESS) {
17853     return rc;
17854   }
17855   std::string authorization_section_bytes;
17856   if (tag == TPM_ST_SESSIONS) {
17857     UINT32 parameter_section_size = buffer.size();
17858     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
17859     if (rc != TPM_RC_SUCCESS) {
17860       return rc;
17861     }
17862     if (parameter_section_size > buffer.size()) {
17863       return TPM_RC_INSUFFICIENT;
17864     }
17865     authorization_section_bytes = buffer.substr(parameter_section_size);
17866     // Keep the parameter section in |buffer|.
17867     buffer.erase(parameter_section_size);
17868   }
17869   std::unique_ptr<crypto::SecureHash> hash(
17870       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
17871   hash->Update(response_code_bytes.data(), response_code_bytes.size());
17872   hash->Update(command_code_bytes.data(), command_code_bytes.size());
17873   hash->Update(buffer.data(), buffer.size());
17874   std::string response_hash(32, 0);
17875   hash->Finish(std::data(response_hash), response_hash.size());
17876   if (tag == TPM_ST_SESSIONS) {
17877     if (!authorization_delegate)
17878       return TRUNKS_RC_AUTHORIZATION_FAILED;
17879     if (!authorization_delegate->CheckResponseAuthorization(
17880             response_hash, authorization_section_bytes)) {
17881       return TRUNKS_RC_AUTHORIZATION_FAILED;
17882     }
17883   }
17884   if (tag == TPM_ST_SESSIONS) {
17885     if (!authorization_delegate)
17886       return TRUNKS_RC_AUTHORIZATION_FAILED;
17887 
17888     // Parse the encrypted parameter size.
17889     UINT16 size;
17890     std::string size_buffer = buffer.substr(0, 2);
17891     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
17892       return result;
17893     }
17894     if (buffer.size() < 2 + size) {
17895       return TPM_RC_INSUFFICIENT;
17896     }
17897 
17898     // Decrypt just the parameter data, not the size.
17899     std::string decrypted_data = buffer.substr(2, size);
17900     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
17901       return TRUNKS_RC_ENCRYPTION_FAILED;
17902     }
17903     buffer.replace(2, size, decrypted_data);
17904   }
17905   std::string audit_info_bytes;
17906   rc = Parse_TPM2B_ATTEST(&buffer, audit_info, &audit_info_bytes);
17907   if (rc != TPM_RC_SUCCESS) {
17908     return rc;
17909   }
17910   std::string signature_bytes;
17911   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
17912   if (rc != TPM_RC_SUCCESS) {
17913     return rc;
17914   }
17915   return TPM_RC_SUCCESS;
17916 }
17917 
GetCommandAuditDigestErrorCallback(Tpm::GetCommandAuditDigestResponse callback,TPM_RC response_code)17918 void GetCommandAuditDigestErrorCallback(
17919     Tpm::GetCommandAuditDigestResponse callback, TPM_RC response_code) {
17920   VLOG(1) << __func__;
17921   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
17922 }
17923 
GetCommandAuditDigestResponseParser(Tpm::GetCommandAuditDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)17924 void GetCommandAuditDigestResponseParser(
17925     Tpm::GetCommandAuditDigestResponse callback,
17926     AuthorizationDelegate* authorization_delegate,
17927     const std::string& response) {
17928   VLOG(1) << __func__;
17929   TPM2B_ATTEST audit_info;
17930   TPMT_SIGNATURE signature;
17931   TPM_RC rc = Tpm::ParseResponse_GetCommandAuditDigest(
17932       response, &audit_info, &signature, authorization_delegate);
17933   if (rc != TPM_RC_SUCCESS) {
17934     base::OnceCallback<void(TPM_RC)> error_reporter =
17935         base::BindOnce(GetCommandAuditDigestErrorCallback, std::move(callback));
17936     std::move(error_reporter).Run(rc);
17937     return;
17938   }
17939   std::move(callback).Run(rc, audit_info, signature);
17940 }
17941 
GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT & privacy_handle,const std::string & privacy_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,GetCommandAuditDigestResponse callback)17942 void Tpm::GetCommandAuditDigest(const TPMI_RH_ENDORSEMENT& privacy_handle,
17943                                 const std::string& privacy_handle_name,
17944                                 const TPMI_DH_OBJECT& sign_handle,
17945                                 const std::string& sign_handle_name,
17946                                 const TPM2B_DATA& qualifying_data,
17947                                 const TPMT_SIG_SCHEME& in_scheme,
17948                                 AuthorizationDelegate* authorization_delegate,
17949                                 GetCommandAuditDigestResponse callback) {
17950   VLOG(1) << __func__;
17951   std::string command;
17952   TPM_RC rc = SerializeCommand_GetCommandAuditDigest(
17953       privacy_handle, privacy_handle_name, sign_handle, sign_handle_name,
17954       qualifying_data, in_scheme, &command, authorization_delegate);
17955   if (rc != TPM_RC_SUCCESS) {
17956     base::OnceCallback<void(TPM_RC)> error_reporter =
17957         base::BindOnce(GetCommandAuditDigestErrorCallback, std::move(callback));
17958     std::move(error_reporter).Run(rc);
17959     return;
17960   }
17961   base::OnceCallback<void(const std::string&)> parser =
17962       base::BindOnce(GetCommandAuditDigestResponseParser, std::move(callback),
17963                      authorization_delegate);
17964   transceiver_->SendCommand(command, std::move(parser));
17965 }
17966 
GetCommandAuditDigestSync(const TPMI_RH_ENDORSEMENT & privacy_handle,const std::string & privacy_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * audit_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)17967 TPM_RC Tpm::GetCommandAuditDigestSync(
17968     const TPMI_RH_ENDORSEMENT& privacy_handle,
17969     const std::string& privacy_handle_name,
17970     const TPMI_DH_OBJECT& sign_handle,
17971     const std::string& sign_handle_name,
17972     const TPM2B_DATA& qualifying_data,
17973     const TPMT_SIG_SCHEME& in_scheme,
17974     TPM2B_ATTEST* audit_info,
17975     TPMT_SIGNATURE* signature,
17976     AuthorizationDelegate* authorization_delegate) {
17977   VLOG(1) << __func__;
17978   std::string command;
17979   TPM_RC rc = SerializeCommand_GetCommandAuditDigest(
17980       privacy_handle, privacy_handle_name, sign_handle, sign_handle_name,
17981       qualifying_data, in_scheme, &command, authorization_delegate);
17982   if (rc != TPM_RC_SUCCESS) {
17983     return rc;
17984   }
17985   std::string response = transceiver_->SendCommandAndWait(command);
17986   rc = ParseResponse_GetCommandAuditDigest(response, audit_info, signature,
17987                                            authorization_delegate);
17988   return rc;
17989 }
17990 
SerializeCommand_GetTime(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)17991 TPM_RC Tpm::SerializeCommand_GetTime(
17992     const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
17993     const std::string& privacy_admin_handle_name,
17994     const TPMI_DH_OBJECT& sign_handle,
17995     const std::string& sign_handle_name,
17996     const TPM2B_DATA& qualifying_data,
17997     const TPMT_SIG_SCHEME& in_scheme,
17998     std::string* serialized_command,
17999     AuthorizationDelegate* authorization_delegate) {
18000   VLOG(3) << __func__;
18001   TPM_RC rc = TPM_RC_SUCCESS;
18002   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18003   UINT32 command_size = 10;  // Header size.
18004   std::string handle_section_bytes;
18005   std::string parameter_section_bytes;
18006   TPM_CC command_code = TPM_CC_GetTime;
18007   bool is_command_parameter_encryption_possible = true;
18008   bool is_response_parameter_encryption_possible = true;
18009   std::string command_code_bytes;
18010   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18011   if (rc != TPM_RC_SUCCESS) {
18012     return rc;
18013   }
18014   std::string privacy_admin_handle_bytes;
18015   rc = Serialize_TPMI_RH_ENDORSEMENT(privacy_admin_handle,
18016                                      &privacy_admin_handle_bytes);
18017   if (rc != TPM_RC_SUCCESS) {
18018     return rc;
18019   }
18020   std::string sign_handle_bytes;
18021   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
18022   if (rc != TPM_RC_SUCCESS) {
18023     return rc;
18024   }
18025   std::string qualifying_data_bytes;
18026   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
18027   if (rc != TPM_RC_SUCCESS) {
18028     return rc;
18029   }
18030   std::string in_scheme_bytes;
18031   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
18032   if (rc != TPM_RC_SUCCESS) {
18033     return rc;
18034   }
18035   if (authorization_delegate) {
18036     // Encrypt just the parameter data, not the size.
18037     std::string tmp = qualifying_data_bytes.substr(2);
18038     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
18039       return TRUNKS_RC_ENCRYPTION_FAILED;
18040     }
18041     qualifying_data_bytes.replace(2, std::string::npos, tmp);
18042   }
18043   std::unique_ptr<crypto::SecureHash> hash(
18044       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18045   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18046   hash->Update(privacy_admin_handle_name.data(),
18047                privacy_admin_handle_name.size());
18048   handle_section_bytes += privacy_admin_handle_bytes;
18049   command_size += privacy_admin_handle_bytes.size();
18050   hash->Update(sign_handle_name.data(), sign_handle_name.size());
18051   handle_section_bytes += sign_handle_bytes;
18052   command_size += sign_handle_bytes.size();
18053   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
18054   parameter_section_bytes += qualifying_data_bytes;
18055   command_size += qualifying_data_bytes.size();
18056   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
18057   parameter_section_bytes += in_scheme_bytes;
18058   command_size += in_scheme_bytes.size();
18059   std::string command_hash(32, 0);
18060   hash->Finish(std::data(command_hash), command_hash.size());
18061   std::string authorization_section_bytes;
18062   std::string authorization_size_bytes;
18063   if (authorization_delegate) {
18064     if (!authorization_delegate->GetCommandAuthorization(
18065             command_hash, is_command_parameter_encryption_possible,
18066             is_response_parameter_encryption_possible,
18067             &authorization_section_bytes)) {
18068       return TRUNKS_RC_AUTHORIZATION_FAILED;
18069     }
18070     if (!authorization_section_bytes.empty()) {
18071       tag = TPM_ST_SESSIONS;
18072       std::string tmp;
18073       rc = Serialize_UINT32(authorization_section_bytes.size(),
18074                             &authorization_size_bytes);
18075       if (rc != TPM_RC_SUCCESS) {
18076         return rc;
18077       }
18078       command_size +=
18079           authorization_size_bytes.size() + authorization_section_bytes.size();
18080     }
18081   }
18082   std::string tag_bytes;
18083   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18084   if (rc != TPM_RC_SUCCESS) {
18085     return rc;
18086   }
18087   std::string command_size_bytes;
18088   rc = Serialize_UINT32(command_size, &command_size_bytes);
18089   if (rc != TPM_RC_SUCCESS) {
18090     return rc;
18091   }
18092   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18093                         handle_section_bytes + authorization_size_bytes +
18094                         authorization_section_bytes + parameter_section_bytes;
18095   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18096   VLOG(2) << "Command: "
18097           << base::HexEncode(serialized_command->data(),
18098                              serialized_command->size());
18099   return TPM_RC_SUCCESS;
18100 }
18101 
ParseResponse_GetTime(const std::string & response,TPM2B_ATTEST * time_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)18102 TPM_RC Tpm::ParseResponse_GetTime(
18103     const std::string& response,
18104     TPM2B_ATTEST* time_info,
18105     TPMT_SIGNATURE* signature,
18106     AuthorizationDelegate* authorization_delegate) {
18107   VLOG(3) << __func__;
18108   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18109   TPM_RC rc = TPM_RC_SUCCESS;
18110   std::string buffer(response);
18111   TPM_ST tag;
18112   std::string tag_bytes;
18113   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18114   if (rc != TPM_RC_SUCCESS) {
18115     return rc;
18116   }
18117   UINT32 response_size;
18118   std::string response_size_bytes;
18119   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18120   if (rc != TPM_RC_SUCCESS) {
18121     return rc;
18122   }
18123   TPM_RC response_code;
18124   std::string response_code_bytes;
18125   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18126   if (rc != TPM_RC_SUCCESS) {
18127     return rc;
18128   }
18129   if (response_size != response.size()) {
18130     return TPM_RC_SIZE;
18131   }
18132   if (response_code != TPM_RC_SUCCESS) {
18133     return response_code;
18134   }
18135   TPM_CC command_code = TPM_CC_GetTime;
18136   std::string command_code_bytes;
18137   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18138   if (rc != TPM_RC_SUCCESS) {
18139     return rc;
18140   }
18141   std::string authorization_section_bytes;
18142   if (tag == TPM_ST_SESSIONS) {
18143     UINT32 parameter_section_size = buffer.size();
18144     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18145     if (rc != TPM_RC_SUCCESS) {
18146       return rc;
18147     }
18148     if (parameter_section_size > buffer.size()) {
18149       return TPM_RC_INSUFFICIENT;
18150     }
18151     authorization_section_bytes = buffer.substr(parameter_section_size);
18152     // Keep the parameter section in |buffer|.
18153     buffer.erase(parameter_section_size);
18154   }
18155   std::unique_ptr<crypto::SecureHash> hash(
18156       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18157   hash->Update(response_code_bytes.data(), response_code_bytes.size());
18158   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18159   hash->Update(buffer.data(), buffer.size());
18160   std::string response_hash(32, 0);
18161   hash->Finish(std::data(response_hash), response_hash.size());
18162   if (tag == TPM_ST_SESSIONS) {
18163     if (!authorization_delegate)
18164       return TRUNKS_RC_AUTHORIZATION_FAILED;
18165     if (!authorization_delegate->CheckResponseAuthorization(
18166             response_hash, authorization_section_bytes)) {
18167       return TRUNKS_RC_AUTHORIZATION_FAILED;
18168     }
18169   }
18170   if (tag == TPM_ST_SESSIONS) {
18171     if (!authorization_delegate)
18172       return TRUNKS_RC_AUTHORIZATION_FAILED;
18173 
18174     // Parse the encrypted parameter size.
18175     UINT16 size;
18176     std::string size_buffer = buffer.substr(0, 2);
18177     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
18178       return result;
18179     }
18180     if (buffer.size() < 2 + size) {
18181       return TPM_RC_INSUFFICIENT;
18182     }
18183 
18184     // Decrypt just the parameter data, not the size.
18185     std::string decrypted_data = buffer.substr(2, size);
18186     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
18187       return TRUNKS_RC_ENCRYPTION_FAILED;
18188     }
18189     buffer.replace(2, size, decrypted_data);
18190   }
18191   std::string time_info_bytes;
18192   rc = Parse_TPM2B_ATTEST(&buffer, time_info, &time_info_bytes);
18193   if (rc != TPM_RC_SUCCESS) {
18194     return rc;
18195   }
18196   std::string signature_bytes;
18197   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
18198   if (rc != TPM_RC_SUCCESS) {
18199     return rc;
18200   }
18201   return TPM_RC_SUCCESS;
18202 }
18203 
GetTimeErrorCallback(Tpm::GetTimeResponse callback,TPM_RC response_code)18204 void GetTimeErrorCallback(Tpm::GetTimeResponse callback, TPM_RC response_code) {
18205   VLOG(1) << __func__;
18206   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
18207 }
18208 
GetTimeResponseParser(Tpm::GetTimeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18209 void GetTimeResponseParser(Tpm::GetTimeResponse callback,
18210                            AuthorizationDelegate* authorization_delegate,
18211                            const std::string& response) {
18212   VLOG(1) << __func__;
18213   TPM2B_ATTEST time_info;
18214   TPMT_SIGNATURE signature;
18215   TPM_RC rc = Tpm::ParseResponse_GetTime(response, &time_info, &signature,
18216                                          authorization_delegate);
18217   if (rc != TPM_RC_SUCCESS) {
18218     base::OnceCallback<void(TPM_RC)> error_reporter =
18219         base::BindOnce(GetTimeErrorCallback, std::move(callback));
18220     std::move(error_reporter).Run(rc);
18221     return;
18222   }
18223   std::move(callback).Run(rc, time_info, signature);
18224 }
18225 
GetTime(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,AuthorizationDelegate * authorization_delegate,GetTimeResponse callback)18226 void Tpm::GetTime(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
18227                   const std::string& privacy_admin_handle_name,
18228                   const TPMI_DH_OBJECT& sign_handle,
18229                   const std::string& sign_handle_name,
18230                   const TPM2B_DATA& qualifying_data,
18231                   const TPMT_SIG_SCHEME& in_scheme,
18232                   AuthorizationDelegate* authorization_delegate,
18233                   GetTimeResponse callback) {
18234   VLOG(1) << __func__;
18235   std::string command;
18236   TPM_RC rc =
18237       SerializeCommand_GetTime(privacy_admin_handle, privacy_admin_handle_name,
18238                                sign_handle, sign_handle_name, qualifying_data,
18239                                in_scheme, &command, authorization_delegate);
18240   if (rc != TPM_RC_SUCCESS) {
18241     base::OnceCallback<void(TPM_RC)> error_reporter =
18242         base::BindOnce(GetTimeErrorCallback, std::move(callback));
18243     std::move(error_reporter).Run(rc);
18244     return;
18245   }
18246   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18247       GetTimeResponseParser, std::move(callback), authorization_delegate);
18248   transceiver_->SendCommand(command, std::move(parser));
18249 }
18250 
GetTimeSync(const TPMI_RH_ENDORSEMENT & privacy_admin_handle,const std::string & privacy_admin_handle_name,const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,TPM2B_ATTEST * time_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)18251 TPM_RC Tpm::GetTimeSync(const TPMI_RH_ENDORSEMENT& privacy_admin_handle,
18252                         const std::string& privacy_admin_handle_name,
18253                         const TPMI_DH_OBJECT& sign_handle,
18254                         const std::string& sign_handle_name,
18255                         const TPM2B_DATA& qualifying_data,
18256                         const TPMT_SIG_SCHEME& in_scheme,
18257                         TPM2B_ATTEST* time_info,
18258                         TPMT_SIGNATURE* signature,
18259                         AuthorizationDelegate* authorization_delegate) {
18260   VLOG(1) << __func__;
18261   std::string command;
18262   TPM_RC rc =
18263       SerializeCommand_GetTime(privacy_admin_handle, privacy_admin_handle_name,
18264                                sign_handle, sign_handle_name, qualifying_data,
18265                                in_scheme, &command, authorization_delegate);
18266   if (rc != TPM_RC_SUCCESS) {
18267     return rc;
18268   }
18269   std::string response = transceiver_->SendCommandAndWait(command);
18270   rc = ParseResponse_GetTime(response, time_info, signature,
18271                              authorization_delegate);
18272   return rc;
18273 }
18274 
SerializeCommand_Commit(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const UINT32 & param_size,const TPM2B_ECC_POINT & p1,const TPM2B_SENSITIVE_DATA & s2,const TPM2B_ECC_PARAMETER & y2,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)18275 TPM_RC Tpm::SerializeCommand_Commit(
18276     const TPMI_DH_OBJECT& sign_handle,
18277     const std::string& sign_handle_name,
18278     const UINT32& param_size,
18279     const TPM2B_ECC_POINT& p1,
18280     const TPM2B_SENSITIVE_DATA& s2,
18281     const TPM2B_ECC_PARAMETER& y2,
18282     std::string* serialized_command,
18283     AuthorizationDelegate* authorization_delegate) {
18284   VLOG(3) << __func__;
18285   TPM_RC rc = TPM_RC_SUCCESS;
18286   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18287   UINT32 command_size = 10;  // Header size.
18288   std::string handle_section_bytes;
18289   std::string parameter_section_bytes;
18290   TPM_CC command_code = TPM_CC_Commit;
18291   bool is_command_parameter_encryption_possible = false;
18292   bool is_response_parameter_encryption_possible = false;
18293   std::string command_code_bytes;
18294   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18295   if (rc != TPM_RC_SUCCESS) {
18296     return rc;
18297   }
18298   std::string param_size_bytes;
18299   rc = Serialize_UINT32(param_size, &param_size_bytes);
18300   if (rc != TPM_RC_SUCCESS) {
18301     return rc;
18302   }
18303   std::string sign_handle_bytes;
18304   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
18305   if (rc != TPM_RC_SUCCESS) {
18306     return rc;
18307   }
18308   std::string p1_bytes;
18309   rc = Serialize_TPM2B_ECC_POINT(p1, &p1_bytes);
18310   if (rc != TPM_RC_SUCCESS) {
18311     return rc;
18312   }
18313   std::string s2_bytes;
18314   rc = Serialize_TPM2B_SENSITIVE_DATA(s2, &s2_bytes);
18315   if (rc != TPM_RC_SUCCESS) {
18316     return rc;
18317   }
18318   std::string y2_bytes;
18319   rc = Serialize_TPM2B_ECC_PARAMETER(y2, &y2_bytes);
18320   if (rc != TPM_RC_SUCCESS) {
18321     return rc;
18322   }
18323   std::unique_ptr<crypto::SecureHash> hash(
18324       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18325   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18326   hash->Update(sign_handle_name.data(), sign_handle_name.size());
18327   handle_section_bytes += sign_handle_bytes;
18328   command_size += sign_handle_bytes.size();
18329   hash->Update(param_size_bytes.data(), param_size_bytes.size());
18330   parameter_section_bytes += param_size_bytes;
18331   command_size += param_size_bytes.size();
18332   hash->Update(p1_bytes.data(), p1_bytes.size());
18333   parameter_section_bytes += p1_bytes;
18334   command_size += p1_bytes.size();
18335   hash->Update(s2_bytes.data(), s2_bytes.size());
18336   parameter_section_bytes += s2_bytes;
18337   command_size += s2_bytes.size();
18338   hash->Update(y2_bytes.data(), y2_bytes.size());
18339   parameter_section_bytes += y2_bytes;
18340   command_size += y2_bytes.size();
18341   std::string command_hash(32, 0);
18342   hash->Finish(std::data(command_hash), command_hash.size());
18343   std::string authorization_section_bytes;
18344   std::string authorization_size_bytes;
18345   if (authorization_delegate) {
18346     if (!authorization_delegate->GetCommandAuthorization(
18347             command_hash, is_command_parameter_encryption_possible,
18348             is_response_parameter_encryption_possible,
18349             &authorization_section_bytes)) {
18350       return TRUNKS_RC_AUTHORIZATION_FAILED;
18351     }
18352     if (!authorization_section_bytes.empty()) {
18353       tag = TPM_ST_SESSIONS;
18354       std::string tmp;
18355       rc = Serialize_UINT32(authorization_section_bytes.size(),
18356                             &authorization_size_bytes);
18357       if (rc != TPM_RC_SUCCESS) {
18358         return rc;
18359       }
18360       command_size +=
18361           authorization_size_bytes.size() + authorization_section_bytes.size();
18362     }
18363   }
18364   std::string tag_bytes;
18365   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18366   if (rc != TPM_RC_SUCCESS) {
18367     return rc;
18368   }
18369   std::string command_size_bytes;
18370   rc = Serialize_UINT32(command_size, &command_size_bytes);
18371   if (rc != TPM_RC_SUCCESS) {
18372     return rc;
18373   }
18374   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18375                         handle_section_bytes + authorization_size_bytes +
18376                         authorization_section_bytes + parameter_section_bytes;
18377   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18378   VLOG(2) << "Command: "
18379           << base::HexEncode(serialized_command->data(),
18380                              serialized_command->size());
18381   return TPM_RC_SUCCESS;
18382 }
18383 
ParseResponse_Commit(const std::string & response,UINT32 * param_size_out,TPM2B_ECC_POINT * k,TPM2B_ECC_POINT * l,TPM2B_ECC_POINT * e,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18384 TPM_RC Tpm::ParseResponse_Commit(
18385     const std::string& response,
18386     UINT32* param_size_out,
18387     TPM2B_ECC_POINT* k,
18388     TPM2B_ECC_POINT* l,
18389     TPM2B_ECC_POINT* e,
18390     UINT16* counter,
18391     AuthorizationDelegate* authorization_delegate) {
18392   VLOG(3) << __func__;
18393   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18394   TPM_RC rc = TPM_RC_SUCCESS;
18395   std::string buffer(response);
18396   TPM_ST tag;
18397   std::string tag_bytes;
18398   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18399   if (rc != TPM_RC_SUCCESS) {
18400     return rc;
18401   }
18402   UINT32 response_size;
18403   std::string response_size_bytes;
18404   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18405   if (rc != TPM_RC_SUCCESS) {
18406     return rc;
18407   }
18408   TPM_RC response_code;
18409   std::string response_code_bytes;
18410   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18411   if (rc != TPM_RC_SUCCESS) {
18412     return rc;
18413   }
18414   if (response_size != response.size()) {
18415     return TPM_RC_SIZE;
18416   }
18417   if (response_code != TPM_RC_SUCCESS) {
18418     return response_code;
18419   }
18420   TPM_CC command_code = TPM_CC_Commit;
18421   std::string command_code_bytes;
18422   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18423   if (rc != TPM_RC_SUCCESS) {
18424     return rc;
18425   }
18426   std::string authorization_section_bytes;
18427   if (tag == TPM_ST_SESSIONS) {
18428     UINT32 parameter_section_size = buffer.size();
18429     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18430     if (rc != TPM_RC_SUCCESS) {
18431       return rc;
18432     }
18433     if (parameter_section_size > buffer.size()) {
18434       return TPM_RC_INSUFFICIENT;
18435     }
18436     authorization_section_bytes = buffer.substr(parameter_section_size);
18437     // Keep the parameter section in |buffer|.
18438     buffer.erase(parameter_section_size);
18439   }
18440   std::unique_ptr<crypto::SecureHash> hash(
18441       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18442   hash->Update(response_code_bytes.data(), response_code_bytes.size());
18443   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18444   hash->Update(buffer.data(), buffer.size());
18445   std::string response_hash(32, 0);
18446   hash->Finish(std::data(response_hash), response_hash.size());
18447   if (tag == TPM_ST_SESSIONS) {
18448     if (!authorization_delegate)
18449       return TRUNKS_RC_AUTHORIZATION_FAILED;
18450     if (!authorization_delegate->CheckResponseAuthorization(
18451             response_hash, authorization_section_bytes)) {
18452       return TRUNKS_RC_AUTHORIZATION_FAILED;
18453     }
18454   }
18455   std::string param_size_out_bytes;
18456   rc = Parse_UINT32(&buffer, param_size_out, &param_size_out_bytes);
18457   if (rc != TPM_RC_SUCCESS) {
18458     return rc;
18459   }
18460   std::string k_bytes;
18461   rc = Parse_TPM2B_ECC_POINT(&buffer, k, &k_bytes);
18462   if (rc != TPM_RC_SUCCESS) {
18463     return rc;
18464   }
18465   std::string l_bytes;
18466   rc = Parse_TPM2B_ECC_POINT(&buffer, l, &l_bytes);
18467   if (rc != TPM_RC_SUCCESS) {
18468     return rc;
18469   }
18470   std::string e_bytes;
18471   rc = Parse_TPM2B_ECC_POINT(&buffer, e, &e_bytes);
18472   if (rc != TPM_RC_SUCCESS) {
18473     return rc;
18474   }
18475   std::string counter_bytes;
18476   rc = Parse_UINT16(&buffer, counter, &counter_bytes);
18477   if (rc != TPM_RC_SUCCESS) {
18478     return rc;
18479   }
18480   return TPM_RC_SUCCESS;
18481 }
18482 
CommitErrorCallback(Tpm::CommitResponse callback,TPM_RC response_code)18483 void CommitErrorCallback(Tpm::CommitResponse callback, TPM_RC response_code) {
18484   VLOG(1) << __func__;
18485   std::move(callback).Run(response_code, UINT32(), TPM2B_ECC_POINT(),
18486                           TPM2B_ECC_POINT(), TPM2B_ECC_POINT(), UINT16());
18487 }
18488 
CommitResponseParser(Tpm::CommitResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18489 void CommitResponseParser(Tpm::CommitResponse callback,
18490                           AuthorizationDelegate* authorization_delegate,
18491                           const std::string& response) {
18492   VLOG(1) << __func__;
18493   UINT32 param_size_out;
18494   TPM2B_ECC_POINT k;
18495   TPM2B_ECC_POINT l;
18496   TPM2B_ECC_POINT e;
18497   UINT16 counter;
18498   TPM_RC rc = Tpm::ParseResponse_Commit(response, &param_size_out, &k, &l, &e,
18499                                         &counter, authorization_delegate);
18500   if (rc != TPM_RC_SUCCESS) {
18501     base::OnceCallback<void(TPM_RC)> error_reporter =
18502         base::BindOnce(CommitErrorCallback, std::move(callback));
18503     std::move(error_reporter).Run(rc);
18504     return;
18505   }
18506   std::move(callback).Run(rc, param_size_out, k, l, e, counter);
18507 }
18508 
Commit(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const UINT32 & param_size,const TPM2B_ECC_POINT & p1,const TPM2B_SENSITIVE_DATA & s2,const TPM2B_ECC_PARAMETER & y2,AuthorizationDelegate * authorization_delegate,CommitResponse callback)18509 void Tpm::Commit(const TPMI_DH_OBJECT& sign_handle,
18510                  const std::string& sign_handle_name,
18511                  const UINT32& param_size,
18512                  const TPM2B_ECC_POINT& p1,
18513                  const TPM2B_SENSITIVE_DATA& s2,
18514                  const TPM2B_ECC_PARAMETER& y2,
18515                  AuthorizationDelegate* authorization_delegate,
18516                  CommitResponse callback) {
18517   VLOG(1) << __func__;
18518   std::string command;
18519   TPM_RC rc =
18520       SerializeCommand_Commit(sign_handle, sign_handle_name, param_size, p1, s2,
18521                               y2, &command, authorization_delegate);
18522   if (rc != TPM_RC_SUCCESS) {
18523     base::OnceCallback<void(TPM_RC)> error_reporter =
18524         base::BindOnce(CommitErrorCallback, std::move(callback));
18525     std::move(error_reporter).Run(rc);
18526     return;
18527   }
18528   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18529       CommitResponseParser, std::move(callback), authorization_delegate);
18530   transceiver_->SendCommand(command, std::move(parser));
18531 }
18532 
CommitSync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const UINT32 & param_size,const TPM2B_ECC_POINT & p1,const TPM2B_SENSITIVE_DATA & s2,const TPM2B_ECC_PARAMETER & y2,UINT32 * param_size_out,TPM2B_ECC_POINT * k,TPM2B_ECC_POINT * l,TPM2B_ECC_POINT * e,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18533 TPM_RC Tpm::CommitSync(const TPMI_DH_OBJECT& sign_handle,
18534                        const std::string& sign_handle_name,
18535                        const UINT32& param_size,
18536                        const TPM2B_ECC_POINT& p1,
18537                        const TPM2B_SENSITIVE_DATA& s2,
18538                        const TPM2B_ECC_PARAMETER& y2,
18539                        UINT32* param_size_out,
18540                        TPM2B_ECC_POINT* k,
18541                        TPM2B_ECC_POINT* l,
18542                        TPM2B_ECC_POINT* e,
18543                        UINT16* counter,
18544                        AuthorizationDelegate* authorization_delegate) {
18545   VLOG(1) << __func__;
18546   std::string command;
18547   TPM_RC rc =
18548       SerializeCommand_Commit(sign_handle, sign_handle_name, param_size, p1, s2,
18549                               y2, &command, authorization_delegate);
18550   if (rc != TPM_RC_SUCCESS) {
18551     return rc;
18552   }
18553   std::string response = transceiver_->SendCommandAndWait(command);
18554   rc = ParseResponse_Commit(response, param_size_out, k, l, e, counter,
18555                             authorization_delegate);
18556   return rc;
18557 }
18558 
SerializeCommand_EC_Ephemeral(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)18559 TPM_RC Tpm::SerializeCommand_EC_Ephemeral(
18560     const UINT32& param_size,
18561     const TPMI_ECC_CURVE& curve_id,
18562     std::string* serialized_command,
18563     AuthorizationDelegate* authorization_delegate) {
18564   VLOG(3) << __func__;
18565   TPM_RC rc = TPM_RC_SUCCESS;
18566   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18567   UINT32 command_size = 10;  // Header size.
18568   std::string handle_section_bytes;
18569   std::string parameter_section_bytes;
18570   TPM_CC command_code = TPM_CC_EC_Ephemeral;
18571   bool is_command_parameter_encryption_possible = false;
18572   bool is_response_parameter_encryption_possible = false;
18573   std::string command_code_bytes;
18574   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18575   if (rc != TPM_RC_SUCCESS) {
18576     return rc;
18577   }
18578   std::string param_size_bytes;
18579   rc = Serialize_UINT32(param_size, &param_size_bytes);
18580   if (rc != TPM_RC_SUCCESS) {
18581     return rc;
18582   }
18583   std::string curve_id_bytes;
18584   rc = Serialize_TPMI_ECC_CURVE(curve_id, &curve_id_bytes);
18585   if (rc != TPM_RC_SUCCESS) {
18586     return rc;
18587   }
18588   std::unique_ptr<crypto::SecureHash> hash(
18589       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18590   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18591   hash->Update(param_size_bytes.data(), param_size_bytes.size());
18592   parameter_section_bytes += param_size_bytes;
18593   command_size += param_size_bytes.size();
18594   hash->Update(curve_id_bytes.data(), curve_id_bytes.size());
18595   parameter_section_bytes += curve_id_bytes;
18596   command_size += curve_id_bytes.size();
18597   std::string command_hash(32, 0);
18598   hash->Finish(std::data(command_hash), command_hash.size());
18599   std::string authorization_section_bytes;
18600   std::string authorization_size_bytes;
18601   if (authorization_delegate) {
18602     if (!authorization_delegate->GetCommandAuthorization(
18603             command_hash, is_command_parameter_encryption_possible,
18604             is_response_parameter_encryption_possible,
18605             &authorization_section_bytes)) {
18606       return TRUNKS_RC_AUTHORIZATION_FAILED;
18607     }
18608     if (!authorization_section_bytes.empty()) {
18609       tag = TPM_ST_SESSIONS;
18610       std::string tmp;
18611       rc = Serialize_UINT32(authorization_section_bytes.size(),
18612                             &authorization_size_bytes);
18613       if (rc != TPM_RC_SUCCESS) {
18614         return rc;
18615       }
18616       command_size +=
18617           authorization_size_bytes.size() + authorization_section_bytes.size();
18618     }
18619   }
18620   std::string tag_bytes;
18621   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18622   if (rc != TPM_RC_SUCCESS) {
18623     return rc;
18624   }
18625   std::string command_size_bytes;
18626   rc = Serialize_UINT32(command_size, &command_size_bytes);
18627   if (rc != TPM_RC_SUCCESS) {
18628     return rc;
18629   }
18630   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18631                         handle_section_bytes + authorization_size_bytes +
18632                         authorization_section_bytes + parameter_section_bytes;
18633   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18634   VLOG(2) << "Command: "
18635           << base::HexEncode(serialized_command->data(),
18636                              serialized_command->size());
18637   return TPM_RC_SUCCESS;
18638 }
18639 
ParseResponse_EC_Ephemeral(const std::string & response,UINT32 * param_size_out,TPM2B_ECC_POINT * q,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18640 TPM_RC Tpm::ParseResponse_EC_Ephemeral(
18641     const std::string& response,
18642     UINT32* param_size_out,
18643     TPM2B_ECC_POINT* q,
18644     UINT16* counter,
18645     AuthorizationDelegate* authorization_delegate) {
18646   VLOG(3) << __func__;
18647   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18648   TPM_RC rc = TPM_RC_SUCCESS;
18649   std::string buffer(response);
18650   TPM_ST tag;
18651   std::string tag_bytes;
18652   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18653   if (rc != TPM_RC_SUCCESS) {
18654     return rc;
18655   }
18656   UINT32 response_size;
18657   std::string response_size_bytes;
18658   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18659   if (rc != TPM_RC_SUCCESS) {
18660     return rc;
18661   }
18662   TPM_RC response_code;
18663   std::string response_code_bytes;
18664   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18665   if (rc != TPM_RC_SUCCESS) {
18666     return rc;
18667   }
18668   if (response_size != response.size()) {
18669     return TPM_RC_SIZE;
18670   }
18671   if (response_code != TPM_RC_SUCCESS) {
18672     return response_code;
18673   }
18674   TPM_CC command_code = TPM_CC_EC_Ephemeral;
18675   std::string command_code_bytes;
18676   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18677   if (rc != TPM_RC_SUCCESS) {
18678     return rc;
18679   }
18680   std::string authorization_section_bytes;
18681   if (tag == TPM_ST_SESSIONS) {
18682     UINT32 parameter_section_size = buffer.size();
18683     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18684     if (rc != TPM_RC_SUCCESS) {
18685       return rc;
18686     }
18687     if (parameter_section_size > buffer.size()) {
18688       return TPM_RC_INSUFFICIENT;
18689     }
18690     authorization_section_bytes = buffer.substr(parameter_section_size);
18691     // Keep the parameter section in |buffer|.
18692     buffer.erase(parameter_section_size);
18693   }
18694   std::unique_ptr<crypto::SecureHash> hash(
18695       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18696   hash->Update(response_code_bytes.data(), response_code_bytes.size());
18697   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18698   hash->Update(buffer.data(), buffer.size());
18699   std::string response_hash(32, 0);
18700   hash->Finish(std::data(response_hash), response_hash.size());
18701   if (tag == TPM_ST_SESSIONS) {
18702     if (!authorization_delegate)
18703       return TRUNKS_RC_AUTHORIZATION_FAILED;
18704     if (!authorization_delegate->CheckResponseAuthorization(
18705             response_hash, authorization_section_bytes)) {
18706       return TRUNKS_RC_AUTHORIZATION_FAILED;
18707     }
18708   }
18709   std::string param_size_out_bytes;
18710   rc = Parse_UINT32(&buffer, param_size_out, &param_size_out_bytes);
18711   if (rc != TPM_RC_SUCCESS) {
18712     return rc;
18713   }
18714   std::string q_bytes;
18715   rc = Parse_TPM2B_ECC_POINT(&buffer, q, &q_bytes);
18716   if (rc != TPM_RC_SUCCESS) {
18717     return rc;
18718   }
18719   std::string counter_bytes;
18720   rc = Parse_UINT16(&buffer, counter, &counter_bytes);
18721   if (rc != TPM_RC_SUCCESS) {
18722     return rc;
18723   }
18724   return TPM_RC_SUCCESS;
18725 }
18726 
EC_EphemeralErrorCallback(Tpm::EC_EphemeralResponse callback,TPM_RC response_code)18727 void EC_EphemeralErrorCallback(Tpm::EC_EphemeralResponse callback,
18728                                TPM_RC response_code) {
18729   VLOG(1) << __func__;
18730   std::move(callback).Run(response_code, UINT32(), TPM2B_ECC_POINT(), UINT16());
18731 }
18732 
EC_EphemeralResponseParser(Tpm::EC_EphemeralResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18733 void EC_EphemeralResponseParser(Tpm::EC_EphemeralResponse callback,
18734                                 AuthorizationDelegate* authorization_delegate,
18735                                 const std::string& response) {
18736   VLOG(1) << __func__;
18737   UINT32 param_size_out;
18738   TPM2B_ECC_POINT q;
18739   UINT16 counter;
18740   TPM_RC rc = Tpm::ParseResponse_EC_Ephemeral(response, &param_size_out, &q,
18741                                               &counter, authorization_delegate);
18742   if (rc != TPM_RC_SUCCESS) {
18743     base::OnceCallback<void(TPM_RC)> error_reporter =
18744         base::BindOnce(EC_EphemeralErrorCallback, std::move(callback));
18745     std::move(error_reporter).Run(rc);
18746     return;
18747   }
18748   std::move(callback).Run(rc, param_size_out, q, counter);
18749 }
18750 
EC_Ephemeral(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,AuthorizationDelegate * authorization_delegate,EC_EphemeralResponse callback)18751 void Tpm::EC_Ephemeral(const UINT32& param_size,
18752                        const TPMI_ECC_CURVE& curve_id,
18753                        AuthorizationDelegate* authorization_delegate,
18754                        EC_EphemeralResponse callback) {
18755   VLOG(1) << __func__;
18756   std::string command;
18757   TPM_RC rc = SerializeCommand_EC_Ephemeral(param_size, curve_id, &command,
18758                                             authorization_delegate);
18759   if (rc != TPM_RC_SUCCESS) {
18760     base::OnceCallback<void(TPM_RC)> error_reporter =
18761         base::BindOnce(EC_EphemeralErrorCallback, std::move(callback));
18762     std::move(error_reporter).Run(rc);
18763     return;
18764   }
18765   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
18766       EC_EphemeralResponseParser, std::move(callback), authorization_delegate);
18767   transceiver_->SendCommand(command, std::move(parser));
18768 }
18769 
EC_EphemeralSync(const UINT32 & param_size,const TPMI_ECC_CURVE & curve_id,UINT32 * param_size_out,TPM2B_ECC_POINT * q,UINT16 * counter,AuthorizationDelegate * authorization_delegate)18770 TPM_RC Tpm::EC_EphemeralSync(const UINT32& param_size,
18771                              const TPMI_ECC_CURVE& curve_id,
18772                              UINT32* param_size_out,
18773                              TPM2B_ECC_POINT* q,
18774                              UINT16* counter,
18775                              AuthorizationDelegate* authorization_delegate) {
18776   VLOG(1) << __func__;
18777   std::string command;
18778   TPM_RC rc = SerializeCommand_EC_Ephemeral(param_size, curve_id, &command,
18779                                             authorization_delegate);
18780   if (rc != TPM_RC_SUCCESS) {
18781     return rc;
18782   }
18783   std::string response = transceiver_->SendCommandAndWait(command);
18784   rc = ParseResponse_EC_Ephemeral(response, param_size_out, q, counter,
18785                                   authorization_delegate);
18786   return rc;
18787 }
18788 
SerializeCommand_VerifySignature(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIGNATURE & signature,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)18789 TPM_RC Tpm::SerializeCommand_VerifySignature(
18790     const TPMI_DH_OBJECT& key_handle,
18791     const std::string& key_handle_name,
18792     const TPM2B_DIGEST& digest,
18793     const TPMT_SIGNATURE& signature,
18794     std::string* serialized_command,
18795     AuthorizationDelegate* authorization_delegate) {
18796   VLOG(3) << __func__;
18797   TPM_RC rc = TPM_RC_SUCCESS;
18798   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
18799   UINT32 command_size = 10;  // Header size.
18800   std::string handle_section_bytes;
18801   std::string parameter_section_bytes;
18802   TPM_CC command_code = TPM_CC_VerifySignature;
18803   bool is_command_parameter_encryption_possible = true;
18804   bool is_response_parameter_encryption_possible = false;
18805   std::string command_code_bytes;
18806   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18807   if (rc != TPM_RC_SUCCESS) {
18808     return rc;
18809   }
18810   std::string key_handle_bytes;
18811   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
18812   if (rc != TPM_RC_SUCCESS) {
18813     return rc;
18814   }
18815   std::string digest_bytes;
18816   rc = Serialize_TPM2B_DIGEST(digest, &digest_bytes);
18817   if (rc != TPM_RC_SUCCESS) {
18818     return rc;
18819   }
18820   std::string signature_bytes;
18821   rc = Serialize_TPMT_SIGNATURE(signature, &signature_bytes);
18822   if (rc != TPM_RC_SUCCESS) {
18823     return rc;
18824   }
18825   if (authorization_delegate) {
18826     // Encrypt just the parameter data, not the size.
18827     std::string tmp = digest_bytes.substr(2);
18828     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
18829       return TRUNKS_RC_ENCRYPTION_FAILED;
18830     }
18831     digest_bytes.replace(2, std::string::npos, tmp);
18832   }
18833   std::unique_ptr<crypto::SecureHash> hash(
18834       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18835   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18836   hash->Update(key_handle_name.data(), key_handle_name.size());
18837   handle_section_bytes += key_handle_bytes;
18838   command_size += key_handle_bytes.size();
18839   hash->Update(digest_bytes.data(), digest_bytes.size());
18840   parameter_section_bytes += digest_bytes;
18841   command_size += digest_bytes.size();
18842   hash->Update(signature_bytes.data(), signature_bytes.size());
18843   parameter_section_bytes += signature_bytes;
18844   command_size += signature_bytes.size();
18845   std::string command_hash(32, 0);
18846   hash->Finish(std::data(command_hash), command_hash.size());
18847   std::string authorization_section_bytes;
18848   std::string authorization_size_bytes;
18849   if (authorization_delegate) {
18850     if (!authorization_delegate->GetCommandAuthorization(
18851             command_hash, is_command_parameter_encryption_possible,
18852             is_response_parameter_encryption_possible,
18853             &authorization_section_bytes)) {
18854       return TRUNKS_RC_AUTHORIZATION_FAILED;
18855     }
18856     if (!authorization_section_bytes.empty()) {
18857       tag = TPM_ST_SESSIONS;
18858       std::string tmp;
18859       rc = Serialize_UINT32(authorization_section_bytes.size(),
18860                             &authorization_size_bytes);
18861       if (rc != TPM_RC_SUCCESS) {
18862         return rc;
18863       }
18864       command_size +=
18865           authorization_size_bytes.size() + authorization_section_bytes.size();
18866     }
18867   }
18868   std::string tag_bytes;
18869   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
18870   if (rc != TPM_RC_SUCCESS) {
18871     return rc;
18872   }
18873   std::string command_size_bytes;
18874   rc = Serialize_UINT32(command_size, &command_size_bytes);
18875   if (rc != TPM_RC_SUCCESS) {
18876     return rc;
18877   }
18878   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
18879                         handle_section_bytes + authorization_size_bytes +
18880                         authorization_section_bytes + parameter_section_bytes;
18881   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
18882   VLOG(2) << "Command: "
18883           << base::HexEncode(serialized_command->data(),
18884                              serialized_command->size());
18885   return TPM_RC_SUCCESS;
18886 }
18887 
ParseResponse_VerifySignature(const std::string & response,TPMT_TK_VERIFIED * validation,AuthorizationDelegate * authorization_delegate)18888 TPM_RC Tpm::ParseResponse_VerifySignature(
18889     const std::string& response,
18890     TPMT_TK_VERIFIED* validation,
18891     AuthorizationDelegate* authorization_delegate) {
18892   VLOG(3) << __func__;
18893   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
18894   TPM_RC rc = TPM_RC_SUCCESS;
18895   std::string buffer(response);
18896   TPM_ST tag;
18897   std::string tag_bytes;
18898   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
18899   if (rc != TPM_RC_SUCCESS) {
18900     return rc;
18901   }
18902   UINT32 response_size;
18903   std::string response_size_bytes;
18904   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
18905   if (rc != TPM_RC_SUCCESS) {
18906     return rc;
18907   }
18908   TPM_RC response_code;
18909   std::string response_code_bytes;
18910   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
18911   if (rc != TPM_RC_SUCCESS) {
18912     return rc;
18913   }
18914   if (response_size != response.size()) {
18915     return TPM_RC_SIZE;
18916   }
18917   if (response_code != TPM_RC_SUCCESS) {
18918     return response_code;
18919   }
18920   TPM_CC command_code = TPM_CC_VerifySignature;
18921   std::string command_code_bytes;
18922   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
18923   if (rc != TPM_RC_SUCCESS) {
18924     return rc;
18925   }
18926   std::string authorization_section_bytes;
18927   if (tag == TPM_ST_SESSIONS) {
18928     UINT32 parameter_section_size = buffer.size();
18929     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
18930     if (rc != TPM_RC_SUCCESS) {
18931       return rc;
18932     }
18933     if (parameter_section_size > buffer.size()) {
18934       return TPM_RC_INSUFFICIENT;
18935     }
18936     authorization_section_bytes = buffer.substr(parameter_section_size);
18937     // Keep the parameter section in |buffer|.
18938     buffer.erase(parameter_section_size);
18939   }
18940   std::unique_ptr<crypto::SecureHash> hash(
18941       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
18942   hash->Update(response_code_bytes.data(), response_code_bytes.size());
18943   hash->Update(command_code_bytes.data(), command_code_bytes.size());
18944   hash->Update(buffer.data(), buffer.size());
18945   std::string response_hash(32, 0);
18946   hash->Finish(std::data(response_hash), response_hash.size());
18947   if (tag == TPM_ST_SESSIONS) {
18948     if (!authorization_delegate)
18949       return TRUNKS_RC_AUTHORIZATION_FAILED;
18950     if (!authorization_delegate->CheckResponseAuthorization(
18951             response_hash, authorization_section_bytes)) {
18952       return TRUNKS_RC_AUTHORIZATION_FAILED;
18953     }
18954   }
18955   std::string validation_bytes;
18956   rc = Parse_TPMT_TK_VERIFIED(&buffer, validation, &validation_bytes);
18957   if (rc != TPM_RC_SUCCESS) {
18958     return rc;
18959   }
18960   return TPM_RC_SUCCESS;
18961 }
18962 
VerifySignatureErrorCallback(Tpm::VerifySignatureResponse callback,TPM_RC response_code)18963 void VerifySignatureErrorCallback(Tpm::VerifySignatureResponse callback,
18964                                   TPM_RC response_code) {
18965   VLOG(1) << __func__;
18966   std::move(callback).Run(response_code, TPMT_TK_VERIFIED());
18967 }
18968 
VerifySignatureResponseParser(Tpm::VerifySignatureResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)18969 void VerifySignatureResponseParser(
18970     Tpm::VerifySignatureResponse callback,
18971     AuthorizationDelegate* authorization_delegate,
18972     const std::string& response) {
18973   VLOG(1) << __func__;
18974   TPMT_TK_VERIFIED validation;
18975   TPM_RC rc = Tpm::ParseResponse_VerifySignature(response, &validation,
18976                                                  authorization_delegate);
18977   if (rc != TPM_RC_SUCCESS) {
18978     base::OnceCallback<void(TPM_RC)> error_reporter =
18979         base::BindOnce(VerifySignatureErrorCallback, std::move(callback));
18980     std::move(error_reporter).Run(rc);
18981     return;
18982   }
18983   std::move(callback).Run(rc, validation);
18984 }
18985 
VerifySignature(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIGNATURE & signature,AuthorizationDelegate * authorization_delegate,VerifySignatureResponse callback)18986 void Tpm::VerifySignature(const TPMI_DH_OBJECT& key_handle,
18987                           const std::string& key_handle_name,
18988                           const TPM2B_DIGEST& digest,
18989                           const TPMT_SIGNATURE& signature,
18990                           AuthorizationDelegate* authorization_delegate,
18991                           VerifySignatureResponse callback) {
18992   VLOG(1) << __func__;
18993   std::string command;
18994   TPM_RC rc = SerializeCommand_VerifySignature(key_handle, key_handle_name,
18995                                                digest, signature, &command,
18996                                                authorization_delegate);
18997   if (rc != TPM_RC_SUCCESS) {
18998     base::OnceCallback<void(TPM_RC)> error_reporter =
18999         base::BindOnce(VerifySignatureErrorCallback, std::move(callback));
19000     std::move(error_reporter).Run(rc);
19001     return;
19002   }
19003   base::OnceCallback<void(const std::string&)> parser =
19004       base::BindOnce(VerifySignatureResponseParser, std::move(callback),
19005                      authorization_delegate);
19006   transceiver_->SendCommand(command, std::move(parser));
19007 }
19008 
VerifySignatureSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIGNATURE & signature,TPMT_TK_VERIFIED * validation,AuthorizationDelegate * authorization_delegate)19009 TPM_RC Tpm::VerifySignatureSync(const TPMI_DH_OBJECT& key_handle,
19010                                 const std::string& key_handle_name,
19011                                 const TPM2B_DIGEST& digest,
19012                                 const TPMT_SIGNATURE& signature,
19013                                 TPMT_TK_VERIFIED* validation,
19014                                 AuthorizationDelegate* authorization_delegate) {
19015   VLOG(1) << __func__;
19016   std::string command;
19017   TPM_RC rc = SerializeCommand_VerifySignature(key_handle, key_handle_name,
19018                                                digest, signature, &command,
19019                                                authorization_delegate);
19020   if (rc != TPM_RC_SUCCESS) {
19021     return rc;
19022   }
19023   std::string response = transceiver_->SendCommandAndWait(command);
19024   rc = ParseResponse_VerifySignature(response, validation,
19025                                      authorization_delegate);
19026   return rc;
19027 }
19028 
SerializeCommand_Sign(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_HASHCHECK & validation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19029 TPM_RC Tpm::SerializeCommand_Sign(
19030     const TPMI_DH_OBJECT& key_handle,
19031     const std::string& key_handle_name,
19032     const TPM2B_DIGEST& digest,
19033     const TPMT_SIG_SCHEME& in_scheme,
19034     const TPMT_TK_HASHCHECK& validation,
19035     std::string* serialized_command,
19036     AuthorizationDelegate* authorization_delegate) {
19037   VLOG(3) << __func__;
19038   TPM_RC rc = TPM_RC_SUCCESS;
19039   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19040   UINT32 command_size = 10;  // Header size.
19041   std::string handle_section_bytes;
19042   std::string parameter_section_bytes;
19043   TPM_CC command_code = TPM_CC_Sign;
19044   bool is_command_parameter_encryption_possible = true;
19045   bool is_response_parameter_encryption_possible = false;
19046   std::string command_code_bytes;
19047   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19048   if (rc != TPM_RC_SUCCESS) {
19049     return rc;
19050   }
19051   std::string key_handle_bytes;
19052   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
19053   if (rc != TPM_RC_SUCCESS) {
19054     return rc;
19055   }
19056   std::string digest_bytes;
19057   rc = Serialize_TPM2B_DIGEST(digest, &digest_bytes);
19058   if (rc != TPM_RC_SUCCESS) {
19059     return rc;
19060   }
19061   std::string in_scheme_bytes;
19062   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
19063   if (rc != TPM_RC_SUCCESS) {
19064     return rc;
19065   }
19066   std::string validation_bytes;
19067   rc = Serialize_TPMT_TK_HASHCHECK(validation, &validation_bytes);
19068   if (rc != TPM_RC_SUCCESS) {
19069     return rc;
19070   }
19071   if (authorization_delegate) {
19072     // Encrypt just the parameter data, not the size.
19073     std::string tmp = digest_bytes.substr(2);
19074     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
19075       return TRUNKS_RC_ENCRYPTION_FAILED;
19076     }
19077     digest_bytes.replace(2, std::string::npos, tmp);
19078   }
19079   std::unique_ptr<crypto::SecureHash> hash(
19080       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19081   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19082   hash->Update(key_handle_name.data(), key_handle_name.size());
19083   handle_section_bytes += key_handle_bytes;
19084   command_size += key_handle_bytes.size();
19085   hash->Update(digest_bytes.data(), digest_bytes.size());
19086   parameter_section_bytes += digest_bytes;
19087   command_size += digest_bytes.size();
19088   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
19089   parameter_section_bytes += in_scheme_bytes;
19090   command_size += in_scheme_bytes.size();
19091   hash->Update(validation_bytes.data(), validation_bytes.size());
19092   parameter_section_bytes += validation_bytes;
19093   command_size += validation_bytes.size();
19094   std::string command_hash(32, 0);
19095   hash->Finish(std::data(command_hash), command_hash.size());
19096   std::string authorization_section_bytes;
19097   std::string authorization_size_bytes;
19098   if (authorization_delegate) {
19099     if (!authorization_delegate->GetCommandAuthorization(
19100             command_hash, is_command_parameter_encryption_possible,
19101             is_response_parameter_encryption_possible,
19102             &authorization_section_bytes)) {
19103       return TRUNKS_RC_AUTHORIZATION_FAILED;
19104     }
19105     if (!authorization_section_bytes.empty()) {
19106       tag = TPM_ST_SESSIONS;
19107       std::string tmp;
19108       rc = Serialize_UINT32(authorization_section_bytes.size(),
19109                             &authorization_size_bytes);
19110       if (rc != TPM_RC_SUCCESS) {
19111         return rc;
19112       }
19113       command_size +=
19114           authorization_size_bytes.size() + authorization_section_bytes.size();
19115     }
19116   }
19117   std::string tag_bytes;
19118   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19119   if (rc != TPM_RC_SUCCESS) {
19120     return rc;
19121   }
19122   std::string command_size_bytes;
19123   rc = Serialize_UINT32(command_size, &command_size_bytes);
19124   if (rc != TPM_RC_SUCCESS) {
19125     return rc;
19126   }
19127   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19128                         handle_section_bytes + authorization_size_bytes +
19129                         authorization_section_bytes + parameter_section_bytes;
19130   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19131   VLOG(2) << "Command: "
19132           << base::HexEncode(serialized_command->data(),
19133                              serialized_command->size());
19134   return TPM_RC_SUCCESS;
19135 }
19136 
ParseResponse_Sign(const std::string & response,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)19137 TPM_RC Tpm::ParseResponse_Sign(const std::string& response,
19138                                TPMT_SIGNATURE* signature,
19139                                AuthorizationDelegate* authorization_delegate) {
19140   VLOG(3) << __func__;
19141   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19142   TPM_RC rc = TPM_RC_SUCCESS;
19143   std::string buffer(response);
19144   TPM_ST tag;
19145   std::string tag_bytes;
19146   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19147   if (rc != TPM_RC_SUCCESS) {
19148     return rc;
19149   }
19150   UINT32 response_size;
19151   std::string response_size_bytes;
19152   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19153   if (rc != TPM_RC_SUCCESS) {
19154     return rc;
19155   }
19156   TPM_RC response_code;
19157   std::string response_code_bytes;
19158   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19159   if (rc != TPM_RC_SUCCESS) {
19160     return rc;
19161   }
19162   if (response_size != response.size()) {
19163     return TPM_RC_SIZE;
19164   }
19165   if (response_code != TPM_RC_SUCCESS) {
19166     return response_code;
19167   }
19168   TPM_CC command_code = TPM_CC_Sign;
19169   std::string command_code_bytes;
19170   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19171   if (rc != TPM_RC_SUCCESS) {
19172     return rc;
19173   }
19174   std::string authorization_section_bytes;
19175   if (tag == TPM_ST_SESSIONS) {
19176     UINT32 parameter_section_size = buffer.size();
19177     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19178     if (rc != TPM_RC_SUCCESS) {
19179       return rc;
19180     }
19181     if (parameter_section_size > buffer.size()) {
19182       return TPM_RC_INSUFFICIENT;
19183     }
19184     authorization_section_bytes = buffer.substr(parameter_section_size);
19185     // Keep the parameter section in |buffer|.
19186     buffer.erase(parameter_section_size);
19187   }
19188   std::unique_ptr<crypto::SecureHash> hash(
19189       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19190   hash->Update(response_code_bytes.data(), response_code_bytes.size());
19191   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19192   hash->Update(buffer.data(), buffer.size());
19193   std::string response_hash(32, 0);
19194   hash->Finish(std::data(response_hash), response_hash.size());
19195   if (tag == TPM_ST_SESSIONS) {
19196     if (!authorization_delegate)
19197       return TRUNKS_RC_AUTHORIZATION_FAILED;
19198     if (!authorization_delegate->CheckResponseAuthorization(
19199             response_hash, authorization_section_bytes)) {
19200       return TRUNKS_RC_AUTHORIZATION_FAILED;
19201     }
19202   }
19203   std::string signature_bytes;
19204   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
19205   if (rc != TPM_RC_SUCCESS) {
19206     return rc;
19207   }
19208   return TPM_RC_SUCCESS;
19209 }
19210 
SignErrorCallback(Tpm::SignResponse callback,TPM_RC response_code)19211 void SignErrorCallback(Tpm::SignResponse callback, TPM_RC response_code) {
19212   VLOG(1) << __func__;
19213   std::move(callback).Run(response_code, TPMT_SIGNATURE());
19214 }
19215 
SignResponseParser(Tpm::SignResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19216 void SignResponseParser(Tpm::SignResponse callback,
19217                         AuthorizationDelegate* authorization_delegate,
19218                         const std::string& response) {
19219   VLOG(1) << __func__;
19220   TPMT_SIGNATURE signature;
19221   TPM_RC rc =
19222       Tpm::ParseResponse_Sign(response, &signature, authorization_delegate);
19223   if (rc != TPM_RC_SUCCESS) {
19224     base::OnceCallback<void(TPM_RC)> error_reporter =
19225         base::BindOnce(SignErrorCallback, std::move(callback));
19226     std::move(error_reporter).Run(rc);
19227     return;
19228   }
19229   std::move(callback).Run(rc, signature);
19230 }
19231 
Sign(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_HASHCHECK & validation,AuthorizationDelegate * authorization_delegate,SignResponse callback)19232 void Tpm::Sign(const TPMI_DH_OBJECT& key_handle,
19233                const std::string& key_handle_name,
19234                const TPM2B_DIGEST& digest,
19235                const TPMT_SIG_SCHEME& in_scheme,
19236                const TPMT_TK_HASHCHECK& validation,
19237                AuthorizationDelegate* authorization_delegate,
19238                SignResponse callback) {
19239   VLOG(1) << __func__;
19240   std::string command;
19241   TPM_RC rc =
19242       SerializeCommand_Sign(key_handle, key_handle_name, digest, in_scheme,
19243                             validation, &command, authorization_delegate);
19244   if (rc != TPM_RC_SUCCESS) {
19245     base::OnceCallback<void(TPM_RC)> error_reporter =
19246         base::BindOnce(SignErrorCallback, std::move(callback));
19247     std::move(error_reporter).Run(rc);
19248     return;
19249   }
19250   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19251       SignResponseParser, std::move(callback), authorization_delegate);
19252   transceiver_->SendCommand(command, std::move(parser));
19253 }
19254 
SignSync(const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & digest,const TPMT_SIG_SCHEME & in_scheme,const TPMT_TK_HASHCHECK & validation,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)19255 TPM_RC Tpm::SignSync(const TPMI_DH_OBJECT& key_handle,
19256                      const std::string& key_handle_name,
19257                      const TPM2B_DIGEST& digest,
19258                      const TPMT_SIG_SCHEME& in_scheme,
19259                      const TPMT_TK_HASHCHECK& validation,
19260                      TPMT_SIGNATURE* signature,
19261                      AuthorizationDelegate* authorization_delegate) {
19262   VLOG(1) << __func__;
19263   std::string command;
19264   TPM_RC rc =
19265       SerializeCommand_Sign(key_handle, key_handle_name, digest, in_scheme,
19266                             validation, &command, authorization_delegate);
19267   if (rc != TPM_RC_SUCCESS) {
19268     return rc;
19269   }
19270   std::string response = transceiver_->SendCommandAndWait(command);
19271   rc = ParseResponse_Sign(response, signature, authorization_delegate);
19272   return rc;
19273 }
19274 
SerializeCommand_SetCommandCodeAuditStatus(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_ALG_HASH & audit_alg,const TPML_CC & set_list,const TPML_CC & clear_list,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19275 TPM_RC Tpm::SerializeCommand_SetCommandCodeAuditStatus(
19276     const TPMI_RH_PROVISION& auth,
19277     const std::string& auth_name,
19278     const TPMI_ALG_HASH& audit_alg,
19279     const TPML_CC& set_list,
19280     const TPML_CC& clear_list,
19281     std::string* serialized_command,
19282     AuthorizationDelegate* authorization_delegate) {
19283   VLOG(3) << __func__;
19284   TPM_RC rc = TPM_RC_SUCCESS;
19285   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19286   UINT32 command_size = 10;  // Header size.
19287   std::string handle_section_bytes;
19288   std::string parameter_section_bytes;
19289   TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus;
19290   bool is_command_parameter_encryption_possible = false;
19291   bool is_response_parameter_encryption_possible = false;
19292   std::string command_code_bytes;
19293   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19294   if (rc != TPM_RC_SUCCESS) {
19295     return rc;
19296   }
19297   std::string auth_bytes;
19298   rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
19299   if (rc != TPM_RC_SUCCESS) {
19300     return rc;
19301   }
19302   std::string audit_alg_bytes;
19303   rc = Serialize_TPMI_ALG_HASH(audit_alg, &audit_alg_bytes);
19304   if (rc != TPM_RC_SUCCESS) {
19305     return rc;
19306   }
19307   std::string set_list_bytes;
19308   rc = Serialize_TPML_CC(set_list, &set_list_bytes);
19309   if (rc != TPM_RC_SUCCESS) {
19310     return rc;
19311   }
19312   std::string clear_list_bytes;
19313   rc = Serialize_TPML_CC(clear_list, &clear_list_bytes);
19314   if (rc != TPM_RC_SUCCESS) {
19315     return rc;
19316   }
19317   std::unique_ptr<crypto::SecureHash> hash(
19318       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19319   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19320   hash->Update(auth_name.data(), auth_name.size());
19321   handle_section_bytes += auth_bytes;
19322   command_size += auth_bytes.size();
19323   hash->Update(audit_alg_bytes.data(), audit_alg_bytes.size());
19324   parameter_section_bytes += audit_alg_bytes;
19325   command_size += audit_alg_bytes.size();
19326   hash->Update(set_list_bytes.data(), set_list_bytes.size());
19327   parameter_section_bytes += set_list_bytes;
19328   command_size += set_list_bytes.size();
19329   hash->Update(clear_list_bytes.data(), clear_list_bytes.size());
19330   parameter_section_bytes += clear_list_bytes;
19331   command_size += clear_list_bytes.size();
19332   std::string command_hash(32, 0);
19333   hash->Finish(std::data(command_hash), command_hash.size());
19334   std::string authorization_section_bytes;
19335   std::string authorization_size_bytes;
19336   if (authorization_delegate) {
19337     if (!authorization_delegate->GetCommandAuthorization(
19338             command_hash, is_command_parameter_encryption_possible,
19339             is_response_parameter_encryption_possible,
19340             &authorization_section_bytes)) {
19341       return TRUNKS_RC_AUTHORIZATION_FAILED;
19342     }
19343     if (!authorization_section_bytes.empty()) {
19344       tag = TPM_ST_SESSIONS;
19345       std::string tmp;
19346       rc = Serialize_UINT32(authorization_section_bytes.size(),
19347                             &authorization_size_bytes);
19348       if (rc != TPM_RC_SUCCESS) {
19349         return rc;
19350       }
19351       command_size +=
19352           authorization_size_bytes.size() + authorization_section_bytes.size();
19353     }
19354   }
19355   std::string tag_bytes;
19356   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19357   if (rc != TPM_RC_SUCCESS) {
19358     return rc;
19359   }
19360   std::string command_size_bytes;
19361   rc = Serialize_UINT32(command_size, &command_size_bytes);
19362   if (rc != TPM_RC_SUCCESS) {
19363     return rc;
19364   }
19365   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19366                         handle_section_bytes + authorization_size_bytes +
19367                         authorization_section_bytes + parameter_section_bytes;
19368   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19369   VLOG(2) << "Command: "
19370           << base::HexEncode(serialized_command->data(),
19371                              serialized_command->size());
19372   return TPM_RC_SUCCESS;
19373 }
19374 
ParseResponse_SetCommandCodeAuditStatus(const std::string & response,AuthorizationDelegate * authorization_delegate)19375 TPM_RC Tpm::ParseResponse_SetCommandCodeAuditStatus(
19376     const std::string& response,
19377     AuthorizationDelegate* authorization_delegate) {
19378   VLOG(3) << __func__;
19379   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19380   TPM_RC rc = TPM_RC_SUCCESS;
19381   std::string buffer(response);
19382   TPM_ST tag;
19383   std::string tag_bytes;
19384   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19385   if (rc != TPM_RC_SUCCESS) {
19386     return rc;
19387   }
19388   UINT32 response_size;
19389   std::string response_size_bytes;
19390   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19391   if (rc != TPM_RC_SUCCESS) {
19392     return rc;
19393   }
19394   TPM_RC response_code;
19395   std::string response_code_bytes;
19396   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19397   if (rc != TPM_RC_SUCCESS) {
19398     return rc;
19399   }
19400   if (response_size != response.size()) {
19401     return TPM_RC_SIZE;
19402   }
19403   if (response_code != TPM_RC_SUCCESS) {
19404     return response_code;
19405   }
19406   TPM_CC command_code = TPM_CC_SetCommandCodeAuditStatus;
19407   std::string command_code_bytes;
19408   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19409   if (rc != TPM_RC_SUCCESS) {
19410     return rc;
19411   }
19412   std::string authorization_section_bytes;
19413   if (tag == TPM_ST_SESSIONS) {
19414     UINT32 parameter_section_size = buffer.size();
19415     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19416     if (rc != TPM_RC_SUCCESS) {
19417       return rc;
19418     }
19419     if (parameter_section_size > buffer.size()) {
19420       return TPM_RC_INSUFFICIENT;
19421     }
19422     authorization_section_bytes = buffer.substr(parameter_section_size);
19423     // Keep the parameter section in |buffer|.
19424     buffer.erase(parameter_section_size);
19425   }
19426   std::unique_ptr<crypto::SecureHash> hash(
19427       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19428   hash->Update(response_code_bytes.data(), response_code_bytes.size());
19429   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19430   hash->Update(buffer.data(), buffer.size());
19431   std::string response_hash(32, 0);
19432   hash->Finish(std::data(response_hash), response_hash.size());
19433   if (tag == TPM_ST_SESSIONS) {
19434     if (!authorization_delegate)
19435       return TRUNKS_RC_AUTHORIZATION_FAILED;
19436     if (!authorization_delegate->CheckResponseAuthorization(
19437             response_hash, authorization_section_bytes)) {
19438       return TRUNKS_RC_AUTHORIZATION_FAILED;
19439     }
19440   }
19441   return TPM_RC_SUCCESS;
19442 }
19443 
SetCommandCodeAuditStatusErrorCallback(Tpm::SetCommandCodeAuditStatusResponse callback,TPM_RC response_code)19444 void SetCommandCodeAuditStatusErrorCallback(
19445     Tpm::SetCommandCodeAuditStatusResponse callback, TPM_RC response_code) {
19446   VLOG(1) << __func__;
19447   std::move(callback).Run(response_code);
19448 }
19449 
SetCommandCodeAuditStatusResponseParser(Tpm::SetCommandCodeAuditStatusResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19450 void SetCommandCodeAuditStatusResponseParser(
19451     Tpm::SetCommandCodeAuditStatusResponse callback,
19452     AuthorizationDelegate* authorization_delegate,
19453     const std::string& response) {
19454   VLOG(1) << __func__;
19455   TPM_RC rc = Tpm::ParseResponse_SetCommandCodeAuditStatus(
19456       response, authorization_delegate);
19457   if (rc != TPM_RC_SUCCESS) {
19458     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
19459         SetCommandCodeAuditStatusErrorCallback, std::move(callback));
19460     std::move(error_reporter).Run(rc);
19461     return;
19462   }
19463   std::move(callback).Run(rc);
19464 }
19465 
SetCommandCodeAuditStatus(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_ALG_HASH & audit_alg,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate,SetCommandCodeAuditStatusResponse callback)19466 void Tpm::SetCommandCodeAuditStatus(
19467     const TPMI_RH_PROVISION& auth,
19468     const std::string& auth_name,
19469     const TPMI_ALG_HASH& audit_alg,
19470     const TPML_CC& set_list,
19471     const TPML_CC& clear_list,
19472     AuthorizationDelegate* authorization_delegate,
19473     SetCommandCodeAuditStatusResponse callback) {
19474   VLOG(1) << __func__;
19475   std::string command;
19476   TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus(
19477       auth, auth_name, audit_alg, set_list, clear_list, &command,
19478       authorization_delegate);
19479   if (rc != TPM_RC_SUCCESS) {
19480     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
19481         SetCommandCodeAuditStatusErrorCallback, std::move(callback));
19482     std::move(error_reporter).Run(rc);
19483     return;
19484   }
19485   base::OnceCallback<void(const std::string&)> parser =
19486       base::BindOnce(SetCommandCodeAuditStatusResponseParser,
19487                      std::move(callback), authorization_delegate);
19488   transceiver_->SendCommand(command, std::move(parser));
19489 }
19490 
SetCommandCodeAuditStatusSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_ALG_HASH & audit_alg,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate)19491 TPM_RC Tpm::SetCommandCodeAuditStatusSync(
19492     const TPMI_RH_PROVISION& auth,
19493     const std::string& auth_name,
19494     const TPMI_ALG_HASH& audit_alg,
19495     const TPML_CC& set_list,
19496     const TPML_CC& clear_list,
19497     AuthorizationDelegate* authorization_delegate) {
19498   VLOG(1) << __func__;
19499   std::string command;
19500   TPM_RC rc = SerializeCommand_SetCommandCodeAuditStatus(
19501       auth, auth_name, audit_alg, set_list, clear_list, &command,
19502       authorization_delegate);
19503   if (rc != TPM_RC_SUCCESS) {
19504     return rc;
19505   }
19506   std::string response = transceiver_->SendCommandAndWait(command);
19507   rc =
19508       ParseResponse_SetCommandCodeAuditStatus(response, authorization_delegate);
19509   return rc;
19510 }
19511 
SerializeCommand_PCR_Extend(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPML_DIGEST_VALUES & digests,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19512 TPM_RC Tpm::SerializeCommand_PCR_Extend(
19513     const TPMI_DH_PCR& pcr_handle,
19514     const std::string& pcr_handle_name,
19515     const TPML_DIGEST_VALUES& digests,
19516     std::string* serialized_command,
19517     AuthorizationDelegate* authorization_delegate) {
19518   VLOG(3) << __func__;
19519   TPM_RC rc = TPM_RC_SUCCESS;
19520   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19521   UINT32 command_size = 10;  // Header size.
19522   std::string handle_section_bytes;
19523   std::string parameter_section_bytes;
19524   TPM_CC command_code = TPM_CC_PCR_Extend;
19525   bool is_command_parameter_encryption_possible = false;
19526   bool is_response_parameter_encryption_possible = false;
19527   std::string command_code_bytes;
19528   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19529   if (rc != TPM_RC_SUCCESS) {
19530     return rc;
19531   }
19532   std::string pcr_handle_bytes;
19533   rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
19534   if (rc != TPM_RC_SUCCESS) {
19535     return rc;
19536   }
19537   std::string digests_bytes;
19538   rc = Serialize_TPML_DIGEST_VALUES(digests, &digests_bytes);
19539   if (rc != TPM_RC_SUCCESS) {
19540     return rc;
19541   }
19542   std::unique_ptr<crypto::SecureHash> hash(
19543       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19544   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19545   hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
19546   handle_section_bytes += pcr_handle_bytes;
19547   command_size += pcr_handle_bytes.size();
19548   hash->Update(digests_bytes.data(), digests_bytes.size());
19549   parameter_section_bytes += digests_bytes;
19550   command_size += digests_bytes.size();
19551   std::string command_hash(32, 0);
19552   hash->Finish(std::data(command_hash), command_hash.size());
19553   std::string authorization_section_bytes;
19554   std::string authorization_size_bytes;
19555   if (authorization_delegate) {
19556     if (!authorization_delegate->GetCommandAuthorization(
19557             command_hash, is_command_parameter_encryption_possible,
19558             is_response_parameter_encryption_possible,
19559             &authorization_section_bytes)) {
19560       return TRUNKS_RC_AUTHORIZATION_FAILED;
19561     }
19562     if (!authorization_section_bytes.empty()) {
19563       tag = TPM_ST_SESSIONS;
19564       std::string tmp;
19565       rc = Serialize_UINT32(authorization_section_bytes.size(),
19566                             &authorization_size_bytes);
19567       if (rc != TPM_RC_SUCCESS) {
19568         return rc;
19569       }
19570       command_size +=
19571           authorization_size_bytes.size() + authorization_section_bytes.size();
19572     }
19573   }
19574   std::string tag_bytes;
19575   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19576   if (rc != TPM_RC_SUCCESS) {
19577     return rc;
19578   }
19579   std::string command_size_bytes;
19580   rc = Serialize_UINT32(command_size, &command_size_bytes);
19581   if (rc != TPM_RC_SUCCESS) {
19582     return rc;
19583   }
19584   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19585                         handle_section_bytes + authorization_size_bytes +
19586                         authorization_section_bytes + parameter_section_bytes;
19587   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19588   VLOG(2) << "Command: "
19589           << base::HexEncode(serialized_command->data(),
19590                              serialized_command->size());
19591   return TPM_RC_SUCCESS;
19592 }
19593 
ParseResponse_PCR_Extend(const std::string & response,AuthorizationDelegate * authorization_delegate)19594 TPM_RC Tpm::ParseResponse_PCR_Extend(
19595     const std::string& response,
19596     AuthorizationDelegate* authorization_delegate) {
19597   VLOG(3) << __func__;
19598   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19599   TPM_RC rc = TPM_RC_SUCCESS;
19600   std::string buffer(response);
19601   TPM_ST tag;
19602   std::string tag_bytes;
19603   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19604   if (rc != TPM_RC_SUCCESS) {
19605     return rc;
19606   }
19607   UINT32 response_size;
19608   std::string response_size_bytes;
19609   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19610   if (rc != TPM_RC_SUCCESS) {
19611     return rc;
19612   }
19613   TPM_RC response_code;
19614   std::string response_code_bytes;
19615   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19616   if (rc != TPM_RC_SUCCESS) {
19617     return rc;
19618   }
19619   if (response_size != response.size()) {
19620     return TPM_RC_SIZE;
19621   }
19622   if (response_code != TPM_RC_SUCCESS) {
19623     return response_code;
19624   }
19625   TPM_CC command_code = TPM_CC_PCR_Extend;
19626   std::string command_code_bytes;
19627   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19628   if (rc != TPM_RC_SUCCESS) {
19629     return rc;
19630   }
19631   std::string authorization_section_bytes;
19632   if (tag == TPM_ST_SESSIONS) {
19633     UINT32 parameter_section_size = buffer.size();
19634     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19635     if (rc != TPM_RC_SUCCESS) {
19636       return rc;
19637     }
19638     if (parameter_section_size > buffer.size()) {
19639       return TPM_RC_INSUFFICIENT;
19640     }
19641     authorization_section_bytes = buffer.substr(parameter_section_size);
19642     // Keep the parameter section in |buffer|.
19643     buffer.erase(parameter_section_size);
19644   }
19645   std::unique_ptr<crypto::SecureHash> hash(
19646       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19647   hash->Update(response_code_bytes.data(), response_code_bytes.size());
19648   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19649   hash->Update(buffer.data(), buffer.size());
19650   std::string response_hash(32, 0);
19651   hash->Finish(std::data(response_hash), response_hash.size());
19652   if (tag == TPM_ST_SESSIONS) {
19653     if (!authorization_delegate)
19654       return TRUNKS_RC_AUTHORIZATION_FAILED;
19655     if (!authorization_delegate->CheckResponseAuthorization(
19656             response_hash, authorization_section_bytes)) {
19657       return TRUNKS_RC_AUTHORIZATION_FAILED;
19658     }
19659   }
19660   return TPM_RC_SUCCESS;
19661 }
19662 
PCR_ExtendErrorCallback(Tpm::PCR_ExtendResponse callback,TPM_RC response_code)19663 void PCR_ExtendErrorCallback(Tpm::PCR_ExtendResponse callback,
19664                              TPM_RC response_code) {
19665   VLOG(1) << __func__;
19666   std::move(callback).Run(response_code);
19667 }
19668 
PCR_ExtendResponseParser(Tpm::PCR_ExtendResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19669 void PCR_ExtendResponseParser(Tpm::PCR_ExtendResponse callback,
19670                               AuthorizationDelegate* authorization_delegate,
19671                               const std::string& response) {
19672   VLOG(1) << __func__;
19673   TPM_RC rc = Tpm::ParseResponse_PCR_Extend(response, authorization_delegate);
19674   if (rc != TPM_RC_SUCCESS) {
19675     base::OnceCallback<void(TPM_RC)> error_reporter =
19676         base::BindOnce(PCR_ExtendErrorCallback, std::move(callback));
19677     std::move(error_reporter).Run(rc);
19678     return;
19679   }
19680   std::move(callback).Run(rc);
19681 }
19682 
PCR_Extend(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPML_DIGEST_VALUES & digests,AuthorizationDelegate * authorization_delegate,PCR_ExtendResponse callback)19683 void Tpm::PCR_Extend(const TPMI_DH_PCR& pcr_handle,
19684                      const std::string& pcr_handle_name,
19685                      const TPML_DIGEST_VALUES& digests,
19686                      AuthorizationDelegate* authorization_delegate,
19687                      PCR_ExtendResponse callback) {
19688   VLOG(1) << __func__;
19689   std::string command;
19690   TPM_RC rc = SerializeCommand_PCR_Extend(pcr_handle, pcr_handle_name, digests,
19691                                           &command, authorization_delegate);
19692   if (rc != TPM_RC_SUCCESS) {
19693     base::OnceCallback<void(TPM_RC)> error_reporter =
19694         base::BindOnce(PCR_ExtendErrorCallback, std::move(callback));
19695     std::move(error_reporter).Run(rc);
19696     return;
19697   }
19698   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19699       PCR_ExtendResponseParser, std::move(callback), authorization_delegate);
19700   transceiver_->SendCommand(command, std::move(parser));
19701 }
19702 
PCR_ExtendSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPML_DIGEST_VALUES & digests,AuthorizationDelegate * authorization_delegate)19703 TPM_RC Tpm::PCR_ExtendSync(const TPMI_DH_PCR& pcr_handle,
19704                            const std::string& pcr_handle_name,
19705                            const TPML_DIGEST_VALUES& digests,
19706                            AuthorizationDelegate* authorization_delegate) {
19707   VLOG(1) << __func__;
19708   std::string command;
19709   TPM_RC rc = SerializeCommand_PCR_Extend(pcr_handle, pcr_handle_name, digests,
19710                                           &command, authorization_delegate);
19711   if (rc != TPM_RC_SUCCESS) {
19712     return rc;
19713   }
19714   std::string response = transceiver_->SendCommandAndWait(command);
19715   rc = ParseResponse_PCR_Extend(response, authorization_delegate);
19716   return rc;
19717 }
19718 
SerializeCommand_PCR_Event(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_EVENT & event_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19719 TPM_RC Tpm::SerializeCommand_PCR_Event(
19720     const TPMI_DH_PCR& pcr_handle,
19721     const std::string& pcr_handle_name,
19722     const TPM2B_EVENT& event_data,
19723     std::string* serialized_command,
19724     AuthorizationDelegate* authorization_delegate) {
19725   VLOG(3) << __func__;
19726   TPM_RC rc = TPM_RC_SUCCESS;
19727   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19728   UINT32 command_size = 10;  // Header size.
19729   std::string handle_section_bytes;
19730   std::string parameter_section_bytes;
19731   TPM_CC command_code = TPM_CC_PCR_Event;
19732   bool is_command_parameter_encryption_possible = true;
19733   bool is_response_parameter_encryption_possible = false;
19734   std::string command_code_bytes;
19735   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19736   if (rc != TPM_RC_SUCCESS) {
19737     return rc;
19738   }
19739   std::string pcr_handle_bytes;
19740   rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
19741   if (rc != TPM_RC_SUCCESS) {
19742     return rc;
19743   }
19744   std::string event_data_bytes;
19745   rc = Serialize_TPM2B_EVENT(event_data, &event_data_bytes);
19746   if (rc != TPM_RC_SUCCESS) {
19747     return rc;
19748   }
19749   if (authorization_delegate) {
19750     // Encrypt just the parameter data, not the size.
19751     std::string tmp = event_data_bytes.substr(2);
19752     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
19753       return TRUNKS_RC_ENCRYPTION_FAILED;
19754     }
19755     event_data_bytes.replace(2, std::string::npos, tmp);
19756   }
19757   std::unique_ptr<crypto::SecureHash> hash(
19758       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19759   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19760   hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
19761   handle_section_bytes += pcr_handle_bytes;
19762   command_size += pcr_handle_bytes.size();
19763   hash->Update(event_data_bytes.data(), event_data_bytes.size());
19764   parameter_section_bytes += event_data_bytes;
19765   command_size += event_data_bytes.size();
19766   std::string command_hash(32, 0);
19767   hash->Finish(std::data(command_hash), command_hash.size());
19768   std::string authorization_section_bytes;
19769   std::string authorization_size_bytes;
19770   if (authorization_delegate) {
19771     if (!authorization_delegate->GetCommandAuthorization(
19772             command_hash, is_command_parameter_encryption_possible,
19773             is_response_parameter_encryption_possible,
19774             &authorization_section_bytes)) {
19775       return TRUNKS_RC_AUTHORIZATION_FAILED;
19776     }
19777     if (!authorization_section_bytes.empty()) {
19778       tag = TPM_ST_SESSIONS;
19779       std::string tmp;
19780       rc = Serialize_UINT32(authorization_section_bytes.size(),
19781                             &authorization_size_bytes);
19782       if (rc != TPM_RC_SUCCESS) {
19783         return rc;
19784       }
19785       command_size +=
19786           authorization_size_bytes.size() + authorization_section_bytes.size();
19787     }
19788   }
19789   std::string tag_bytes;
19790   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19791   if (rc != TPM_RC_SUCCESS) {
19792     return rc;
19793   }
19794   std::string command_size_bytes;
19795   rc = Serialize_UINT32(command_size, &command_size_bytes);
19796   if (rc != TPM_RC_SUCCESS) {
19797     return rc;
19798   }
19799   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
19800                         handle_section_bytes + authorization_size_bytes +
19801                         authorization_section_bytes + parameter_section_bytes;
19802   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
19803   VLOG(2) << "Command: "
19804           << base::HexEncode(serialized_command->data(),
19805                              serialized_command->size());
19806   return TPM_RC_SUCCESS;
19807 }
19808 
ParseResponse_PCR_Event(const std::string & response,TPML_DIGEST_VALUES * digests,AuthorizationDelegate * authorization_delegate)19809 TPM_RC Tpm::ParseResponse_PCR_Event(
19810     const std::string& response,
19811     TPML_DIGEST_VALUES* digests,
19812     AuthorizationDelegate* authorization_delegate) {
19813   VLOG(3) << __func__;
19814   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
19815   TPM_RC rc = TPM_RC_SUCCESS;
19816   std::string buffer(response);
19817   TPM_ST tag;
19818   std::string tag_bytes;
19819   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
19820   if (rc != TPM_RC_SUCCESS) {
19821     return rc;
19822   }
19823   UINT32 response_size;
19824   std::string response_size_bytes;
19825   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
19826   if (rc != TPM_RC_SUCCESS) {
19827     return rc;
19828   }
19829   TPM_RC response_code;
19830   std::string response_code_bytes;
19831   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
19832   if (rc != TPM_RC_SUCCESS) {
19833     return rc;
19834   }
19835   if (response_size != response.size()) {
19836     return TPM_RC_SIZE;
19837   }
19838   if (response_code != TPM_RC_SUCCESS) {
19839     return response_code;
19840   }
19841   TPM_CC command_code = TPM_CC_PCR_Event;
19842   std::string command_code_bytes;
19843   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19844   if (rc != TPM_RC_SUCCESS) {
19845     return rc;
19846   }
19847   std::string authorization_section_bytes;
19848   if (tag == TPM_ST_SESSIONS) {
19849     UINT32 parameter_section_size = buffer.size();
19850     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
19851     if (rc != TPM_RC_SUCCESS) {
19852       return rc;
19853     }
19854     if (parameter_section_size > buffer.size()) {
19855       return TPM_RC_INSUFFICIENT;
19856     }
19857     authorization_section_bytes = buffer.substr(parameter_section_size);
19858     // Keep the parameter section in |buffer|.
19859     buffer.erase(parameter_section_size);
19860   }
19861   std::unique_ptr<crypto::SecureHash> hash(
19862       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19863   hash->Update(response_code_bytes.data(), response_code_bytes.size());
19864   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19865   hash->Update(buffer.data(), buffer.size());
19866   std::string response_hash(32, 0);
19867   hash->Finish(std::data(response_hash), response_hash.size());
19868   if (tag == TPM_ST_SESSIONS) {
19869     if (!authorization_delegate)
19870       return TRUNKS_RC_AUTHORIZATION_FAILED;
19871     if (!authorization_delegate->CheckResponseAuthorization(
19872             response_hash, authorization_section_bytes)) {
19873       return TRUNKS_RC_AUTHORIZATION_FAILED;
19874     }
19875   }
19876   std::string digests_bytes;
19877   rc = Parse_TPML_DIGEST_VALUES(&buffer, digests, &digests_bytes);
19878   if (rc != TPM_RC_SUCCESS) {
19879     return rc;
19880   }
19881   return TPM_RC_SUCCESS;
19882 }
19883 
PCR_EventErrorCallback(Tpm::PCR_EventResponse callback,TPM_RC response_code)19884 void PCR_EventErrorCallback(Tpm::PCR_EventResponse callback,
19885                             TPM_RC response_code) {
19886   VLOG(1) << __func__;
19887   std::move(callback).Run(response_code, TPML_DIGEST_VALUES());
19888 }
19889 
PCR_EventResponseParser(Tpm::PCR_EventResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)19890 void PCR_EventResponseParser(Tpm::PCR_EventResponse callback,
19891                              AuthorizationDelegate* authorization_delegate,
19892                              const std::string& response) {
19893   VLOG(1) << __func__;
19894   TPML_DIGEST_VALUES digests;
19895   TPM_RC rc =
19896       Tpm::ParseResponse_PCR_Event(response, &digests, authorization_delegate);
19897   if (rc != TPM_RC_SUCCESS) {
19898     base::OnceCallback<void(TPM_RC)> error_reporter =
19899         base::BindOnce(PCR_EventErrorCallback, std::move(callback));
19900     std::move(error_reporter).Run(rc);
19901     return;
19902   }
19903   std::move(callback).Run(rc, digests);
19904 }
19905 
PCR_Event(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_EVENT & event_data,AuthorizationDelegate * authorization_delegate,PCR_EventResponse callback)19906 void Tpm::PCR_Event(const TPMI_DH_PCR& pcr_handle,
19907                     const std::string& pcr_handle_name,
19908                     const TPM2B_EVENT& event_data,
19909                     AuthorizationDelegate* authorization_delegate,
19910                     PCR_EventResponse callback) {
19911   VLOG(1) << __func__;
19912   std::string command;
19913   TPM_RC rc =
19914       SerializeCommand_PCR_Event(pcr_handle, pcr_handle_name, event_data,
19915                                  &command, authorization_delegate);
19916   if (rc != TPM_RC_SUCCESS) {
19917     base::OnceCallback<void(TPM_RC)> error_reporter =
19918         base::BindOnce(PCR_EventErrorCallback, std::move(callback));
19919     std::move(error_reporter).Run(rc);
19920     return;
19921   }
19922   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
19923       PCR_EventResponseParser, std::move(callback), authorization_delegate);
19924   transceiver_->SendCommand(command, std::move(parser));
19925 }
19926 
PCR_EventSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_EVENT & event_data,TPML_DIGEST_VALUES * digests,AuthorizationDelegate * authorization_delegate)19927 TPM_RC Tpm::PCR_EventSync(const TPMI_DH_PCR& pcr_handle,
19928                           const std::string& pcr_handle_name,
19929                           const TPM2B_EVENT& event_data,
19930                           TPML_DIGEST_VALUES* digests,
19931                           AuthorizationDelegate* authorization_delegate) {
19932   VLOG(1) << __func__;
19933   std::string command;
19934   TPM_RC rc =
19935       SerializeCommand_PCR_Event(pcr_handle, pcr_handle_name, event_data,
19936                                  &command, authorization_delegate);
19937   if (rc != TPM_RC_SUCCESS) {
19938     return rc;
19939   }
19940   std::string response = transceiver_->SendCommandAndWait(command);
19941   rc = ParseResponse_PCR_Event(response, digests, authorization_delegate);
19942   return rc;
19943 }
19944 
SerializeCommand_PCR_Read(const TPML_PCR_SELECTION & pcr_selection_in,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)19945 TPM_RC Tpm::SerializeCommand_PCR_Read(
19946     const TPML_PCR_SELECTION& pcr_selection_in,
19947     std::string* serialized_command,
19948     AuthorizationDelegate* authorization_delegate) {
19949   VLOG(3) << __func__;
19950   TPM_RC rc = TPM_RC_SUCCESS;
19951   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
19952   UINT32 command_size = 10;  // Header size.
19953   std::string handle_section_bytes;
19954   std::string parameter_section_bytes;
19955   TPM_CC command_code = TPM_CC_PCR_Read;
19956   bool is_command_parameter_encryption_possible = false;
19957   bool is_response_parameter_encryption_possible = false;
19958   std::string command_code_bytes;
19959   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
19960   if (rc != TPM_RC_SUCCESS) {
19961     return rc;
19962   }
19963   std::string pcr_selection_in_bytes;
19964   rc = Serialize_TPML_PCR_SELECTION(pcr_selection_in, &pcr_selection_in_bytes);
19965   if (rc != TPM_RC_SUCCESS) {
19966     return rc;
19967   }
19968   std::unique_ptr<crypto::SecureHash> hash(
19969       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
19970   hash->Update(command_code_bytes.data(), command_code_bytes.size());
19971   hash->Update(pcr_selection_in_bytes.data(), pcr_selection_in_bytes.size());
19972   parameter_section_bytes += pcr_selection_in_bytes;
19973   command_size += pcr_selection_in_bytes.size();
19974   std::string command_hash(32, 0);
19975   hash->Finish(std::data(command_hash), command_hash.size());
19976   std::string authorization_section_bytes;
19977   std::string authorization_size_bytes;
19978   if (authorization_delegate) {
19979     if (!authorization_delegate->GetCommandAuthorization(
19980             command_hash, is_command_parameter_encryption_possible,
19981             is_response_parameter_encryption_possible,
19982             &authorization_section_bytes)) {
19983       return TRUNKS_RC_AUTHORIZATION_FAILED;
19984     }
19985     if (!authorization_section_bytes.empty()) {
19986       tag = TPM_ST_SESSIONS;
19987       std::string tmp;
19988       rc = Serialize_UINT32(authorization_section_bytes.size(),
19989                             &authorization_size_bytes);
19990       if (rc != TPM_RC_SUCCESS) {
19991         return rc;
19992       }
19993       command_size +=
19994           authorization_size_bytes.size() + authorization_section_bytes.size();
19995     }
19996   }
19997   std::string tag_bytes;
19998   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
19999   if (rc != TPM_RC_SUCCESS) {
20000     return rc;
20001   }
20002   std::string command_size_bytes;
20003   rc = Serialize_UINT32(command_size, &command_size_bytes);
20004   if (rc != TPM_RC_SUCCESS) {
20005     return rc;
20006   }
20007   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20008                         handle_section_bytes + authorization_size_bytes +
20009                         authorization_section_bytes + parameter_section_bytes;
20010   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20011   VLOG(2) << "Command: "
20012           << base::HexEncode(serialized_command->data(),
20013                              serialized_command->size());
20014   return TPM_RC_SUCCESS;
20015 }
20016 
ParseResponse_PCR_Read(const std::string & response,UINT32 * pcr_update_counter,TPML_PCR_SELECTION * pcr_selection_out,TPML_DIGEST * pcr_values,AuthorizationDelegate * authorization_delegate)20017 TPM_RC Tpm::ParseResponse_PCR_Read(
20018     const std::string& response,
20019     UINT32* pcr_update_counter,
20020     TPML_PCR_SELECTION* pcr_selection_out,
20021     TPML_DIGEST* pcr_values,
20022     AuthorizationDelegate* authorization_delegate) {
20023   VLOG(3) << __func__;
20024   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20025   TPM_RC rc = TPM_RC_SUCCESS;
20026   std::string buffer(response);
20027   TPM_ST tag;
20028   std::string tag_bytes;
20029   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20030   if (rc != TPM_RC_SUCCESS) {
20031     return rc;
20032   }
20033   UINT32 response_size;
20034   std::string response_size_bytes;
20035   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20036   if (rc != TPM_RC_SUCCESS) {
20037     return rc;
20038   }
20039   TPM_RC response_code;
20040   std::string response_code_bytes;
20041   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20042   if (rc != TPM_RC_SUCCESS) {
20043     return rc;
20044   }
20045   if (response_size != response.size()) {
20046     return TPM_RC_SIZE;
20047   }
20048   if (response_code != TPM_RC_SUCCESS) {
20049     return response_code;
20050   }
20051   TPM_CC command_code = TPM_CC_PCR_Read;
20052   std::string command_code_bytes;
20053   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20054   if (rc != TPM_RC_SUCCESS) {
20055     return rc;
20056   }
20057   std::string authorization_section_bytes;
20058   if (tag == TPM_ST_SESSIONS) {
20059     UINT32 parameter_section_size = buffer.size();
20060     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20061     if (rc != TPM_RC_SUCCESS) {
20062       return rc;
20063     }
20064     if (parameter_section_size > buffer.size()) {
20065       return TPM_RC_INSUFFICIENT;
20066     }
20067     authorization_section_bytes = buffer.substr(parameter_section_size);
20068     // Keep the parameter section in |buffer|.
20069     buffer.erase(parameter_section_size);
20070   }
20071   std::unique_ptr<crypto::SecureHash> hash(
20072       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20073   hash->Update(response_code_bytes.data(), response_code_bytes.size());
20074   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20075   hash->Update(buffer.data(), buffer.size());
20076   std::string response_hash(32, 0);
20077   hash->Finish(std::data(response_hash), response_hash.size());
20078   if (tag == TPM_ST_SESSIONS) {
20079     if (!authorization_delegate)
20080       return TRUNKS_RC_AUTHORIZATION_FAILED;
20081     if (!authorization_delegate->CheckResponseAuthorization(
20082             response_hash, authorization_section_bytes)) {
20083       return TRUNKS_RC_AUTHORIZATION_FAILED;
20084     }
20085   }
20086   std::string pcr_update_counter_bytes;
20087   rc = Parse_UINT32(&buffer, pcr_update_counter, &pcr_update_counter_bytes);
20088   if (rc != TPM_RC_SUCCESS) {
20089     return rc;
20090   }
20091   std::string pcr_selection_out_bytes;
20092   rc = Parse_TPML_PCR_SELECTION(&buffer, pcr_selection_out,
20093                                 &pcr_selection_out_bytes);
20094   if (rc != TPM_RC_SUCCESS) {
20095     return rc;
20096   }
20097   std::string pcr_values_bytes;
20098   rc = Parse_TPML_DIGEST(&buffer, pcr_values, &pcr_values_bytes);
20099   if (rc != TPM_RC_SUCCESS) {
20100     return rc;
20101   }
20102   return TPM_RC_SUCCESS;
20103 }
20104 
PCR_ReadErrorCallback(Tpm::PCR_ReadResponse callback,TPM_RC response_code)20105 void PCR_ReadErrorCallback(Tpm::PCR_ReadResponse callback,
20106                            TPM_RC response_code) {
20107   VLOG(1) << __func__;
20108   std::move(callback).Run(response_code, UINT32(), TPML_PCR_SELECTION(),
20109                           TPML_DIGEST());
20110 }
20111 
PCR_ReadResponseParser(Tpm::PCR_ReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20112 void PCR_ReadResponseParser(Tpm::PCR_ReadResponse callback,
20113                             AuthorizationDelegate* authorization_delegate,
20114                             const std::string& response) {
20115   VLOG(1) << __func__;
20116   UINT32 pcr_update_counter;
20117   TPML_PCR_SELECTION pcr_selection_out;
20118   TPML_DIGEST pcr_values;
20119   TPM_RC rc = Tpm::ParseResponse_PCR_Read(response, &pcr_update_counter,
20120                                           &pcr_selection_out, &pcr_values,
20121                                           authorization_delegate);
20122   if (rc != TPM_RC_SUCCESS) {
20123     base::OnceCallback<void(TPM_RC)> error_reporter =
20124         base::BindOnce(PCR_ReadErrorCallback, std::move(callback));
20125     std::move(error_reporter).Run(rc);
20126     return;
20127   }
20128   std::move(callback).Run(rc, pcr_update_counter, pcr_selection_out,
20129                           pcr_values);
20130 }
20131 
PCR_Read(const TPML_PCR_SELECTION & pcr_selection_in,AuthorizationDelegate * authorization_delegate,PCR_ReadResponse callback)20132 void Tpm::PCR_Read(const TPML_PCR_SELECTION& pcr_selection_in,
20133                    AuthorizationDelegate* authorization_delegate,
20134                    PCR_ReadResponse callback) {
20135   VLOG(1) << __func__;
20136   std::string command;
20137   TPM_RC rc = SerializeCommand_PCR_Read(pcr_selection_in, &command,
20138                                         authorization_delegate);
20139   if (rc != TPM_RC_SUCCESS) {
20140     base::OnceCallback<void(TPM_RC)> error_reporter =
20141         base::BindOnce(PCR_ReadErrorCallback, std::move(callback));
20142     std::move(error_reporter).Run(rc);
20143     return;
20144   }
20145   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
20146       PCR_ReadResponseParser, std::move(callback), authorization_delegate);
20147   transceiver_->SendCommand(command, std::move(parser));
20148 }
20149 
PCR_ReadSync(const TPML_PCR_SELECTION & pcr_selection_in,UINT32 * pcr_update_counter,TPML_PCR_SELECTION * pcr_selection_out,TPML_DIGEST * pcr_values,AuthorizationDelegate * authorization_delegate)20150 TPM_RC Tpm::PCR_ReadSync(const TPML_PCR_SELECTION& pcr_selection_in,
20151                          UINT32* pcr_update_counter,
20152                          TPML_PCR_SELECTION* pcr_selection_out,
20153                          TPML_DIGEST* pcr_values,
20154                          AuthorizationDelegate* authorization_delegate) {
20155   VLOG(1) << __func__;
20156   std::string command;
20157   TPM_RC rc = SerializeCommand_PCR_Read(pcr_selection_in, &command,
20158                                         authorization_delegate);
20159   if (rc != TPM_RC_SUCCESS) {
20160     return rc;
20161   }
20162   std::string response = transceiver_->SendCommandAndWait(command);
20163   rc = ParseResponse_PCR_Read(response, pcr_update_counter, pcr_selection_out,
20164                               pcr_values, authorization_delegate);
20165   return rc;
20166 }
20167 
SerializeCommand_PCR_Allocate(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPML_PCR_SELECTION & pcr_allocation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20168 TPM_RC Tpm::SerializeCommand_PCR_Allocate(
20169     const TPMI_RH_PLATFORM& auth_handle,
20170     const std::string& auth_handle_name,
20171     const TPML_PCR_SELECTION& pcr_allocation,
20172     std::string* serialized_command,
20173     AuthorizationDelegate* authorization_delegate) {
20174   VLOG(3) << __func__;
20175   TPM_RC rc = TPM_RC_SUCCESS;
20176   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20177   UINT32 command_size = 10;  // Header size.
20178   std::string handle_section_bytes;
20179   std::string parameter_section_bytes;
20180   TPM_CC command_code = TPM_CC_PCR_Allocate;
20181   bool is_command_parameter_encryption_possible = false;
20182   bool is_response_parameter_encryption_possible = false;
20183   std::string command_code_bytes;
20184   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20185   if (rc != TPM_RC_SUCCESS) {
20186     return rc;
20187   }
20188   std::string auth_handle_bytes;
20189   rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
20190   if (rc != TPM_RC_SUCCESS) {
20191     return rc;
20192   }
20193   std::string pcr_allocation_bytes;
20194   rc = Serialize_TPML_PCR_SELECTION(pcr_allocation, &pcr_allocation_bytes);
20195   if (rc != TPM_RC_SUCCESS) {
20196     return rc;
20197   }
20198   std::unique_ptr<crypto::SecureHash> hash(
20199       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20200   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20201   hash->Update(auth_handle_name.data(), auth_handle_name.size());
20202   handle_section_bytes += auth_handle_bytes;
20203   command_size += auth_handle_bytes.size();
20204   hash->Update(pcr_allocation_bytes.data(), pcr_allocation_bytes.size());
20205   parameter_section_bytes += pcr_allocation_bytes;
20206   command_size += pcr_allocation_bytes.size();
20207   std::string command_hash(32, 0);
20208   hash->Finish(std::data(command_hash), command_hash.size());
20209   std::string authorization_section_bytes;
20210   std::string authorization_size_bytes;
20211   if (authorization_delegate) {
20212     if (!authorization_delegate->GetCommandAuthorization(
20213             command_hash, is_command_parameter_encryption_possible,
20214             is_response_parameter_encryption_possible,
20215             &authorization_section_bytes)) {
20216       return TRUNKS_RC_AUTHORIZATION_FAILED;
20217     }
20218     if (!authorization_section_bytes.empty()) {
20219       tag = TPM_ST_SESSIONS;
20220       std::string tmp;
20221       rc = Serialize_UINT32(authorization_section_bytes.size(),
20222                             &authorization_size_bytes);
20223       if (rc != TPM_RC_SUCCESS) {
20224         return rc;
20225       }
20226       command_size +=
20227           authorization_size_bytes.size() + authorization_section_bytes.size();
20228     }
20229   }
20230   std::string tag_bytes;
20231   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20232   if (rc != TPM_RC_SUCCESS) {
20233     return rc;
20234   }
20235   std::string command_size_bytes;
20236   rc = Serialize_UINT32(command_size, &command_size_bytes);
20237   if (rc != TPM_RC_SUCCESS) {
20238     return rc;
20239   }
20240   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20241                         handle_section_bytes + authorization_size_bytes +
20242                         authorization_section_bytes + parameter_section_bytes;
20243   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20244   VLOG(2) << "Command: "
20245           << base::HexEncode(serialized_command->data(),
20246                              serialized_command->size());
20247   return TPM_RC_SUCCESS;
20248 }
20249 
ParseResponse_PCR_Allocate(const std::string & response,TPMI_YES_NO * allocation_success,UINT32 * max_pcr,UINT32 * size_needed,UINT32 * size_available,AuthorizationDelegate * authorization_delegate)20250 TPM_RC Tpm::ParseResponse_PCR_Allocate(
20251     const std::string& response,
20252     TPMI_YES_NO* allocation_success,
20253     UINT32* max_pcr,
20254     UINT32* size_needed,
20255     UINT32* size_available,
20256     AuthorizationDelegate* authorization_delegate) {
20257   VLOG(3) << __func__;
20258   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20259   TPM_RC rc = TPM_RC_SUCCESS;
20260   std::string buffer(response);
20261   TPM_ST tag;
20262   std::string tag_bytes;
20263   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20264   if (rc != TPM_RC_SUCCESS) {
20265     return rc;
20266   }
20267   UINT32 response_size;
20268   std::string response_size_bytes;
20269   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20270   if (rc != TPM_RC_SUCCESS) {
20271     return rc;
20272   }
20273   TPM_RC response_code;
20274   std::string response_code_bytes;
20275   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20276   if (rc != TPM_RC_SUCCESS) {
20277     return rc;
20278   }
20279   if (response_size != response.size()) {
20280     return TPM_RC_SIZE;
20281   }
20282   if (response_code != TPM_RC_SUCCESS) {
20283     return response_code;
20284   }
20285   TPM_CC command_code = TPM_CC_PCR_Allocate;
20286   std::string command_code_bytes;
20287   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20288   if (rc != TPM_RC_SUCCESS) {
20289     return rc;
20290   }
20291   std::string authorization_section_bytes;
20292   if (tag == TPM_ST_SESSIONS) {
20293     UINT32 parameter_section_size = buffer.size();
20294     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20295     if (rc != TPM_RC_SUCCESS) {
20296       return rc;
20297     }
20298     if (parameter_section_size > buffer.size()) {
20299       return TPM_RC_INSUFFICIENT;
20300     }
20301     authorization_section_bytes = buffer.substr(parameter_section_size);
20302     // Keep the parameter section in |buffer|.
20303     buffer.erase(parameter_section_size);
20304   }
20305   std::unique_ptr<crypto::SecureHash> hash(
20306       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20307   hash->Update(response_code_bytes.data(), response_code_bytes.size());
20308   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20309   hash->Update(buffer.data(), buffer.size());
20310   std::string response_hash(32, 0);
20311   hash->Finish(std::data(response_hash), response_hash.size());
20312   if (tag == TPM_ST_SESSIONS) {
20313     if (!authorization_delegate)
20314       return TRUNKS_RC_AUTHORIZATION_FAILED;
20315     if (!authorization_delegate->CheckResponseAuthorization(
20316             response_hash, authorization_section_bytes)) {
20317       return TRUNKS_RC_AUTHORIZATION_FAILED;
20318     }
20319   }
20320   std::string allocation_success_bytes;
20321   rc =
20322       Parse_TPMI_YES_NO(&buffer, allocation_success, &allocation_success_bytes);
20323   if (rc != TPM_RC_SUCCESS) {
20324     return rc;
20325   }
20326   std::string max_pcr_bytes;
20327   rc = Parse_UINT32(&buffer, max_pcr, &max_pcr_bytes);
20328   if (rc != TPM_RC_SUCCESS) {
20329     return rc;
20330   }
20331   std::string size_needed_bytes;
20332   rc = Parse_UINT32(&buffer, size_needed, &size_needed_bytes);
20333   if (rc != TPM_RC_SUCCESS) {
20334     return rc;
20335   }
20336   std::string size_available_bytes;
20337   rc = Parse_UINT32(&buffer, size_available, &size_available_bytes);
20338   if (rc != TPM_RC_SUCCESS) {
20339     return rc;
20340   }
20341   return TPM_RC_SUCCESS;
20342 }
20343 
PCR_AllocateErrorCallback(Tpm::PCR_AllocateResponse callback,TPM_RC response_code)20344 void PCR_AllocateErrorCallback(Tpm::PCR_AllocateResponse callback,
20345                                TPM_RC response_code) {
20346   VLOG(1) << __func__;
20347   std::move(callback).Run(response_code, TPMI_YES_NO(), UINT32(), UINT32(),
20348                           UINT32());
20349 }
20350 
PCR_AllocateResponseParser(Tpm::PCR_AllocateResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20351 void PCR_AllocateResponseParser(Tpm::PCR_AllocateResponse callback,
20352                                 AuthorizationDelegate* authorization_delegate,
20353                                 const std::string& response) {
20354   VLOG(1) << __func__;
20355   TPMI_YES_NO allocation_success;
20356   UINT32 max_pcr;
20357   UINT32 size_needed;
20358   UINT32 size_available;
20359   TPM_RC rc = Tpm::ParseResponse_PCR_Allocate(
20360       response, &allocation_success, &max_pcr, &size_needed, &size_available,
20361       authorization_delegate);
20362   if (rc != TPM_RC_SUCCESS) {
20363     base::OnceCallback<void(TPM_RC)> error_reporter =
20364         base::BindOnce(PCR_AllocateErrorCallback, std::move(callback));
20365     std::move(error_reporter).Run(rc);
20366     return;
20367   }
20368   std::move(callback).Run(rc, allocation_success, max_pcr, size_needed,
20369                           size_available);
20370 }
20371 
PCR_Allocate(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPML_PCR_SELECTION & pcr_allocation,AuthorizationDelegate * authorization_delegate,PCR_AllocateResponse callback)20372 void Tpm::PCR_Allocate(const TPMI_RH_PLATFORM& auth_handle,
20373                        const std::string& auth_handle_name,
20374                        const TPML_PCR_SELECTION& pcr_allocation,
20375                        AuthorizationDelegate* authorization_delegate,
20376                        PCR_AllocateResponse callback) {
20377   VLOG(1) << __func__;
20378   std::string command;
20379   TPM_RC rc = SerializeCommand_PCR_Allocate(auth_handle, auth_handle_name,
20380                                             pcr_allocation, &command,
20381                                             authorization_delegate);
20382   if (rc != TPM_RC_SUCCESS) {
20383     base::OnceCallback<void(TPM_RC)> error_reporter =
20384         base::BindOnce(PCR_AllocateErrorCallback, std::move(callback));
20385     std::move(error_reporter).Run(rc);
20386     return;
20387   }
20388   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
20389       PCR_AllocateResponseParser, std::move(callback), authorization_delegate);
20390   transceiver_->SendCommand(command, std::move(parser));
20391 }
20392 
PCR_AllocateSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPML_PCR_SELECTION & pcr_allocation,TPMI_YES_NO * allocation_success,UINT32 * max_pcr,UINT32 * size_needed,UINT32 * size_available,AuthorizationDelegate * authorization_delegate)20393 TPM_RC Tpm::PCR_AllocateSync(const TPMI_RH_PLATFORM& auth_handle,
20394                              const std::string& auth_handle_name,
20395                              const TPML_PCR_SELECTION& pcr_allocation,
20396                              TPMI_YES_NO* allocation_success,
20397                              UINT32* max_pcr,
20398                              UINT32* size_needed,
20399                              UINT32* size_available,
20400                              AuthorizationDelegate* authorization_delegate) {
20401   VLOG(1) << __func__;
20402   std::string command;
20403   TPM_RC rc = SerializeCommand_PCR_Allocate(auth_handle, auth_handle_name,
20404                                             pcr_allocation, &command,
20405                                             authorization_delegate);
20406   if (rc != TPM_RC_SUCCESS) {
20407     return rc;
20408   }
20409   std::string response = transceiver_->SendCommandAndWait(command);
20410   rc = ParseResponse_PCR_Allocate(response, allocation_success, max_pcr,
20411                                   size_needed, size_available,
20412                                   authorization_delegate);
20413   return rc;
20414 }
20415 
SerializeCommand_PCR_SetAuthPolicy(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPMI_DH_PCR & pcr_num,const std::string & pcr_num_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & policy_digest,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20416 TPM_RC Tpm::SerializeCommand_PCR_SetAuthPolicy(
20417     const TPMI_RH_PLATFORM& auth_handle,
20418     const std::string& auth_handle_name,
20419     const TPMI_DH_PCR& pcr_num,
20420     const std::string& pcr_num_name,
20421     const TPM2B_DIGEST& auth_policy,
20422     const TPMI_ALG_HASH& policy_digest,
20423     std::string* serialized_command,
20424     AuthorizationDelegate* authorization_delegate) {
20425   VLOG(3) << __func__;
20426   TPM_RC rc = TPM_RC_SUCCESS;
20427   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20428   UINT32 command_size = 10;  // Header size.
20429   std::string handle_section_bytes;
20430   std::string parameter_section_bytes;
20431   TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy;
20432   bool is_command_parameter_encryption_possible = true;
20433   bool is_response_parameter_encryption_possible = false;
20434   std::string command_code_bytes;
20435   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20436   if (rc != TPM_RC_SUCCESS) {
20437     return rc;
20438   }
20439   std::string auth_handle_bytes;
20440   rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
20441   if (rc != TPM_RC_SUCCESS) {
20442     return rc;
20443   }
20444   std::string auth_policy_bytes;
20445   rc = Serialize_TPM2B_DIGEST(auth_policy, &auth_policy_bytes);
20446   if (rc != TPM_RC_SUCCESS) {
20447     return rc;
20448   }
20449   std::string policy_digest_bytes;
20450   rc = Serialize_TPMI_ALG_HASH(policy_digest, &policy_digest_bytes);
20451   if (rc != TPM_RC_SUCCESS) {
20452     return rc;
20453   }
20454   std::string pcr_num_bytes;
20455   rc = Serialize_TPMI_DH_PCR(pcr_num, &pcr_num_bytes);
20456   if (rc != TPM_RC_SUCCESS) {
20457     return rc;
20458   }
20459   if (authorization_delegate) {
20460     // Encrypt just the parameter data, not the size.
20461     std::string tmp = auth_policy_bytes.substr(2);
20462     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20463       return TRUNKS_RC_ENCRYPTION_FAILED;
20464     }
20465     auth_policy_bytes.replace(2, std::string::npos, tmp);
20466   }
20467   std::unique_ptr<crypto::SecureHash> hash(
20468       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20469   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20470   hash->Update(auth_handle_name.data(), auth_handle_name.size());
20471   handle_section_bytes += auth_handle_bytes;
20472   command_size += auth_handle_bytes.size();
20473   hash->Update(pcr_num_name.data(), pcr_num_name.size());
20474   handle_section_bytes += pcr_num_bytes;
20475   command_size += pcr_num_bytes.size();
20476   hash->Update(auth_policy_bytes.data(), auth_policy_bytes.size());
20477   parameter_section_bytes += auth_policy_bytes;
20478   command_size += auth_policy_bytes.size();
20479   hash->Update(policy_digest_bytes.data(), policy_digest_bytes.size());
20480   parameter_section_bytes += policy_digest_bytes;
20481   command_size += policy_digest_bytes.size();
20482   std::string command_hash(32, 0);
20483   hash->Finish(std::data(command_hash), command_hash.size());
20484   std::string authorization_section_bytes;
20485   std::string authorization_size_bytes;
20486   if (authorization_delegate) {
20487     if (!authorization_delegate->GetCommandAuthorization(
20488             command_hash, is_command_parameter_encryption_possible,
20489             is_response_parameter_encryption_possible,
20490             &authorization_section_bytes)) {
20491       return TRUNKS_RC_AUTHORIZATION_FAILED;
20492     }
20493     if (!authorization_section_bytes.empty()) {
20494       tag = TPM_ST_SESSIONS;
20495       std::string tmp;
20496       rc = Serialize_UINT32(authorization_section_bytes.size(),
20497                             &authorization_size_bytes);
20498       if (rc != TPM_RC_SUCCESS) {
20499         return rc;
20500       }
20501       command_size +=
20502           authorization_size_bytes.size() + authorization_section_bytes.size();
20503     }
20504   }
20505   std::string tag_bytes;
20506   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20507   if (rc != TPM_RC_SUCCESS) {
20508     return rc;
20509   }
20510   std::string command_size_bytes;
20511   rc = Serialize_UINT32(command_size, &command_size_bytes);
20512   if (rc != TPM_RC_SUCCESS) {
20513     return rc;
20514   }
20515   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20516                         handle_section_bytes + authorization_size_bytes +
20517                         authorization_section_bytes + parameter_section_bytes;
20518   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20519   VLOG(2) << "Command: "
20520           << base::HexEncode(serialized_command->data(),
20521                              serialized_command->size());
20522   return TPM_RC_SUCCESS;
20523 }
20524 
ParseResponse_PCR_SetAuthPolicy(const std::string & response,AuthorizationDelegate * authorization_delegate)20525 TPM_RC Tpm::ParseResponse_PCR_SetAuthPolicy(
20526     const std::string& response,
20527     AuthorizationDelegate* authorization_delegate) {
20528   VLOG(3) << __func__;
20529   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20530   TPM_RC rc = TPM_RC_SUCCESS;
20531   std::string buffer(response);
20532   TPM_ST tag;
20533   std::string tag_bytes;
20534   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20535   if (rc != TPM_RC_SUCCESS) {
20536     return rc;
20537   }
20538   UINT32 response_size;
20539   std::string response_size_bytes;
20540   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20541   if (rc != TPM_RC_SUCCESS) {
20542     return rc;
20543   }
20544   TPM_RC response_code;
20545   std::string response_code_bytes;
20546   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20547   if (rc != TPM_RC_SUCCESS) {
20548     return rc;
20549   }
20550   if (response_size != response.size()) {
20551     return TPM_RC_SIZE;
20552   }
20553   if (response_code != TPM_RC_SUCCESS) {
20554     return response_code;
20555   }
20556   TPM_CC command_code = TPM_CC_PCR_SetAuthPolicy;
20557   std::string command_code_bytes;
20558   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20559   if (rc != TPM_RC_SUCCESS) {
20560     return rc;
20561   }
20562   std::string authorization_section_bytes;
20563   if (tag == TPM_ST_SESSIONS) {
20564     UINT32 parameter_section_size = buffer.size();
20565     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20566     if (rc != TPM_RC_SUCCESS) {
20567       return rc;
20568     }
20569     if (parameter_section_size > buffer.size()) {
20570       return TPM_RC_INSUFFICIENT;
20571     }
20572     authorization_section_bytes = buffer.substr(parameter_section_size);
20573     // Keep the parameter section in |buffer|.
20574     buffer.erase(parameter_section_size);
20575   }
20576   std::unique_ptr<crypto::SecureHash> hash(
20577       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20578   hash->Update(response_code_bytes.data(), response_code_bytes.size());
20579   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20580   hash->Update(buffer.data(), buffer.size());
20581   std::string response_hash(32, 0);
20582   hash->Finish(std::data(response_hash), response_hash.size());
20583   if (tag == TPM_ST_SESSIONS) {
20584     if (!authorization_delegate)
20585       return TRUNKS_RC_AUTHORIZATION_FAILED;
20586     if (!authorization_delegate->CheckResponseAuthorization(
20587             response_hash, authorization_section_bytes)) {
20588       return TRUNKS_RC_AUTHORIZATION_FAILED;
20589     }
20590   }
20591   return TPM_RC_SUCCESS;
20592 }
20593 
PCR_SetAuthPolicyErrorCallback(Tpm::PCR_SetAuthPolicyResponse callback,TPM_RC response_code)20594 void PCR_SetAuthPolicyErrorCallback(Tpm::PCR_SetAuthPolicyResponse callback,
20595                                     TPM_RC response_code) {
20596   VLOG(1) << __func__;
20597   std::move(callback).Run(response_code);
20598 }
20599 
PCR_SetAuthPolicyResponseParser(Tpm::PCR_SetAuthPolicyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20600 void PCR_SetAuthPolicyResponseParser(
20601     Tpm::PCR_SetAuthPolicyResponse callback,
20602     AuthorizationDelegate* authorization_delegate,
20603     const std::string& response) {
20604   VLOG(1) << __func__;
20605   TPM_RC rc =
20606       Tpm::ParseResponse_PCR_SetAuthPolicy(response, authorization_delegate);
20607   if (rc != TPM_RC_SUCCESS) {
20608     base::OnceCallback<void(TPM_RC)> error_reporter =
20609         base::BindOnce(PCR_SetAuthPolicyErrorCallback, std::move(callback));
20610     std::move(error_reporter).Run(rc);
20611     return;
20612   }
20613   std::move(callback).Run(rc);
20614 }
20615 
PCR_SetAuthPolicy(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPMI_DH_PCR & pcr_num,const std::string & pcr_num_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & policy_digest,AuthorizationDelegate * authorization_delegate,PCR_SetAuthPolicyResponse callback)20616 void Tpm::PCR_SetAuthPolicy(const TPMI_RH_PLATFORM& auth_handle,
20617                             const std::string& auth_handle_name,
20618                             const TPMI_DH_PCR& pcr_num,
20619                             const std::string& pcr_num_name,
20620                             const TPM2B_DIGEST& auth_policy,
20621                             const TPMI_ALG_HASH& policy_digest,
20622                             AuthorizationDelegate* authorization_delegate,
20623                             PCR_SetAuthPolicyResponse callback) {
20624   VLOG(1) << __func__;
20625   std::string command;
20626   TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy(
20627       auth_handle, auth_handle_name, pcr_num, pcr_num_name, auth_policy,
20628       policy_digest, &command, authorization_delegate);
20629   if (rc != TPM_RC_SUCCESS) {
20630     base::OnceCallback<void(TPM_RC)> error_reporter =
20631         base::BindOnce(PCR_SetAuthPolicyErrorCallback, std::move(callback));
20632     std::move(error_reporter).Run(rc);
20633     return;
20634   }
20635   base::OnceCallback<void(const std::string&)> parser =
20636       base::BindOnce(PCR_SetAuthPolicyResponseParser, std::move(callback),
20637                      authorization_delegate);
20638   transceiver_->SendCommand(command, std::move(parser));
20639 }
20640 
PCR_SetAuthPolicySync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const TPMI_DH_PCR & pcr_num,const std::string & pcr_num_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & policy_digest,AuthorizationDelegate * authorization_delegate)20641 TPM_RC Tpm::PCR_SetAuthPolicySync(
20642     const TPMI_RH_PLATFORM& auth_handle,
20643     const std::string& auth_handle_name,
20644     const TPMI_DH_PCR& pcr_num,
20645     const std::string& pcr_num_name,
20646     const TPM2B_DIGEST& auth_policy,
20647     const TPMI_ALG_HASH& policy_digest,
20648     AuthorizationDelegate* authorization_delegate) {
20649   VLOG(1) << __func__;
20650   std::string command;
20651   TPM_RC rc = SerializeCommand_PCR_SetAuthPolicy(
20652       auth_handle, auth_handle_name, pcr_num, pcr_num_name, auth_policy,
20653       policy_digest, &command, authorization_delegate);
20654   if (rc != TPM_RC_SUCCESS) {
20655     return rc;
20656   }
20657   std::string response = transceiver_->SendCommandAndWait(command);
20658   rc = ParseResponse_PCR_SetAuthPolicy(response, authorization_delegate);
20659   return rc;
20660 }
20661 
SerializeCommand_PCR_SetAuthValue(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20662 TPM_RC Tpm::SerializeCommand_PCR_SetAuthValue(
20663     const TPMI_DH_PCR& pcr_handle,
20664     const std::string& pcr_handle_name,
20665     const TPM2B_DIGEST& auth,
20666     std::string* serialized_command,
20667     AuthorizationDelegate* authorization_delegate) {
20668   VLOG(3) << __func__;
20669   TPM_RC rc = TPM_RC_SUCCESS;
20670   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20671   UINT32 command_size = 10;  // Header size.
20672   std::string handle_section_bytes;
20673   std::string parameter_section_bytes;
20674   TPM_CC command_code = TPM_CC_PCR_SetAuthValue;
20675   bool is_command_parameter_encryption_possible = true;
20676   bool is_response_parameter_encryption_possible = false;
20677   std::string command_code_bytes;
20678   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20679   if (rc != TPM_RC_SUCCESS) {
20680     return rc;
20681   }
20682   std::string pcr_handle_bytes;
20683   rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
20684   if (rc != TPM_RC_SUCCESS) {
20685     return rc;
20686   }
20687   std::string auth_bytes;
20688   rc = Serialize_TPM2B_DIGEST(auth, &auth_bytes);
20689   if (rc != TPM_RC_SUCCESS) {
20690     return rc;
20691   }
20692   if (authorization_delegate) {
20693     // Encrypt just the parameter data, not the size.
20694     std::string tmp = auth_bytes.substr(2);
20695     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
20696       return TRUNKS_RC_ENCRYPTION_FAILED;
20697     }
20698     auth_bytes.replace(2, std::string::npos, tmp);
20699   }
20700   std::unique_ptr<crypto::SecureHash> hash(
20701       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20702   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20703   hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
20704   handle_section_bytes += pcr_handle_bytes;
20705   command_size += pcr_handle_bytes.size();
20706   hash->Update(auth_bytes.data(), auth_bytes.size());
20707   parameter_section_bytes += auth_bytes;
20708   command_size += auth_bytes.size();
20709   std::string command_hash(32, 0);
20710   hash->Finish(std::data(command_hash), command_hash.size());
20711   std::string authorization_section_bytes;
20712   std::string authorization_size_bytes;
20713   if (authorization_delegate) {
20714     if (!authorization_delegate->GetCommandAuthorization(
20715             command_hash, is_command_parameter_encryption_possible,
20716             is_response_parameter_encryption_possible,
20717             &authorization_section_bytes)) {
20718       return TRUNKS_RC_AUTHORIZATION_FAILED;
20719     }
20720     if (!authorization_section_bytes.empty()) {
20721       tag = TPM_ST_SESSIONS;
20722       std::string tmp;
20723       rc = Serialize_UINT32(authorization_section_bytes.size(),
20724                             &authorization_size_bytes);
20725       if (rc != TPM_RC_SUCCESS) {
20726         return rc;
20727       }
20728       command_size +=
20729           authorization_size_bytes.size() + authorization_section_bytes.size();
20730     }
20731   }
20732   std::string tag_bytes;
20733   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20734   if (rc != TPM_RC_SUCCESS) {
20735     return rc;
20736   }
20737   std::string command_size_bytes;
20738   rc = Serialize_UINT32(command_size, &command_size_bytes);
20739   if (rc != TPM_RC_SUCCESS) {
20740     return rc;
20741   }
20742   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20743                         handle_section_bytes + authorization_size_bytes +
20744                         authorization_section_bytes + parameter_section_bytes;
20745   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20746   VLOG(2) << "Command: "
20747           << base::HexEncode(serialized_command->data(),
20748                              serialized_command->size());
20749   return TPM_RC_SUCCESS;
20750 }
20751 
ParseResponse_PCR_SetAuthValue(const std::string & response,AuthorizationDelegate * authorization_delegate)20752 TPM_RC Tpm::ParseResponse_PCR_SetAuthValue(
20753     const std::string& response,
20754     AuthorizationDelegate* authorization_delegate) {
20755   VLOG(3) << __func__;
20756   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20757   TPM_RC rc = TPM_RC_SUCCESS;
20758   std::string buffer(response);
20759   TPM_ST tag;
20760   std::string tag_bytes;
20761   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20762   if (rc != TPM_RC_SUCCESS) {
20763     return rc;
20764   }
20765   UINT32 response_size;
20766   std::string response_size_bytes;
20767   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20768   if (rc != TPM_RC_SUCCESS) {
20769     return rc;
20770   }
20771   TPM_RC response_code;
20772   std::string response_code_bytes;
20773   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20774   if (rc != TPM_RC_SUCCESS) {
20775     return rc;
20776   }
20777   if (response_size != response.size()) {
20778     return TPM_RC_SIZE;
20779   }
20780   if (response_code != TPM_RC_SUCCESS) {
20781     return response_code;
20782   }
20783   TPM_CC command_code = TPM_CC_PCR_SetAuthValue;
20784   std::string command_code_bytes;
20785   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20786   if (rc != TPM_RC_SUCCESS) {
20787     return rc;
20788   }
20789   std::string authorization_section_bytes;
20790   if (tag == TPM_ST_SESSIONS) {
20791     UINT32 parameter_section_size = buffer.size();
20792     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20793     if (rc != TPM_RC_SUCCESS) {
20794       return rc;
20795     }
20796     if (parameter_section_size > buffer.size()) {
20797       return TPM_RC_INSUFFICIENT;
20798     }
20799     authorization_section_bytes = buffer.substr(parameter_section_size);
20800     // Keep the parameter section in |buffer|.
20801     buffer.erase(parameter_section_size);
20802   }
20803   std::unique_ptr<crypto::SecureHash> hash(
20804       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20805   hash->Update(response_code_bytes.data(), response_code_bytes.size());
20806   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20807   hash->Update(buffer.data(), buffer.size());
20808   std::string response_hash(32, 0);
20809   hash->Finish(std::data(response_hash), response_hash.size());
20810   if (tag == TPM_ST_SESSIONS) {
20811     if (!authorization_delegate)
20812       return TRUNKS_RC_AUTHORIZATION_FAILED;
20813     if (!authorization_delegate->CheckResponseAuthorization(
20814             response_hash, authorization_section_bytes)) {
20815       return TRUNKS_RC_AUTHORIZATION_FAILED;
20816     }
20817   }
20818   return TPM_RC_SUCCESS;
20819 }
20820 
PCR_SetAuthValueErrorCallback(Tpm::PCR_SetAuthValueResponse callback,TPM_RC response_code)20821 void PCR_SetAuthValueErrorCallback(Tpm::PCR_SetAuthValueResponse callback,
20822                                    TPM_RC response_code) {
20823   VLOG(1) << __func__;
20824   std::move(callback).Run(response_code);
20825 }
20826 
PCR_SetAuthValueResponseParser(Tpm::PCR_SetAuthValueResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)20827 void PCR_SetAuthValueResponseParser(
20828     Tpm::PCR_SetAuthValueResponse callback,
20829     AuthorizationDelegate* authorization_delegate,
20830     const std::string& response) {
20831   VLOG(1) << __func__;
20832   TPM_RC rc =
20833       Tpm::ParseResponse_PCR_SetAuthValue(response, authorization_delegate);
20834   if (rc != TPM_RC_SUCCESS) {
20835     base::OnceCallback<void(TPM_RC)> error_reporter =
20836         base::BindOnce(PCR_SetAuthValueErrorCallback, std::move(callback));
20837     std::move(error_reporter).Run(rc);
20838     return;
20839   }
20840   std::move(callback).Run(rc);
20841 }
20842 
PCR_SetAuthValue(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,AuthorizationDelegate * authorization_delegate,PCR_SetAuthValueResponse callback)20843 void Tpm::PCR_SetAuthValue(const TPMI_DH_PCR& pcr_handle,
20844                            const std::string& pcr_handle_name,
20845                            const TPM2B_DIGEST& auth,
20846                            AuthorizationDelegate* authorization_delegate,
20847                            PCR_SetAuthValueResponse callback) {
20848   VLOG(1) << __func__;
20849   std::string command;
20850   TPM_RC rc = SerializeCommand_PCR_SetAuthValue(
20851       pcr_handle, pcr_handle_name, auth, &command, authorization_delegate);
20852   if (rc != TPM_RC_SUCCESS) {
20853     base::OnceCallback<void(TPM_RC)> error_reporter =
20854         base::BindOnce(PCR_SetAuthValueErrorCallback, std::move(callback));
20855     std::move(error_reporter).Run(rc);
20856     return;
20857   }
20858   base::OnceCallback<void(const std::string&)> parser =
20859       base::BindOnce(PCR_SetAuthValueResponseParser, std::move(callback),
20860                      authorization_delegate);
20861   transceiver_->SendCommand(command, std::move(parser));
20862 }
20863 
PCR_SetAuthValueSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,const TPM2B_DIGEST & auth,AuthorizationDelegate * authorization_delegate)20864 TPM_RC Tpm::PCR_SetAuthValueSync(
20865     const TPMI_DH_PCR& pcr_handle,
20866     const std::string& pcr_handle_name,
20867     const TPM2B_DIGEST& auth,
20868     AuthorizationDelegate* authorization_delegate) {
20869   VLOG(1) << __func__;
20870   std::string command;
20871   TPM_RC rc = SerializeCommand_PCR_SetAuthValue(
20872       pcr_handle, pcr_handle_name, auth, &command, authorization_delegate);
20873   if (rc != TPM_RC_SUCCESS) {
20874     return rc;
20875   }
20876   std::string response = transceiver_->SendCommandAndWait(command);
20877   rc = ParseResponse_PCR_SetAuthValue(response, authorization_delegate);
20878   return rc;
20879 }
20880 
SerializeCommand_PCR_Reset(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)20881 TPM_RC Tpm::SerializeCommand_PCR_Reset(
20882     const TPMI_DH_PCR& pcr_handle,
20883     const std::string& pcr_handle_name,
20884     std::string* serialized_command,
20885     AuthorizationDelegate* authorization_delegate) {
20886   VLOG(3) << __func__;
20887   TPM_RC rc = TPM_RC_SUCCESS;
20888   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
20889   UINT32 command_size = 10;  // Header size.
20890   std::string handle_section_bytes;
20891   std::string parameter_section_bytes;
20892   TPM_CC command_code = TPM_CC_PCR_Reset;
20893   bool is_command_parameter_encryption_possible = false;
20894   bool is_response_parameter_encryption_possible = false;
20895   std::string command_code_bytes;
20896   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20897   if (rc != TPM_RC_SUCCESS) {
20898     return rc;
20899   }
20900   std::string pcr_handle_bytes;
20901   rc = Serialize_TPMI_DH_PCR(pcr_handle, &pcr_handle_bytes);
20902   if (rc != TPM_RC_SUCCESS) {
20903     return rc;
20904   }
20905   std::unique_ptr<crypto::SecureHash> hash(
20906       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
20907   hash->Update(command_code_bytes.data(), command_code_bytes.size());
20908   hash->Update(pcr_handle_name.data(), pcr_handle_name.size());
20909   handle_section_bytes += pcr_handle_bytes;
20910   command_size += pcr_handle_bytes.size();
20911   std::string command_hash(32, 0);
20912   hash->Finish(std::data(command_hash), command_hash.size());
20913   std::string authorization_section_bytes;
20914   std::string authorization_size_bytes;
20915   if (authorization_delegate) {
20916     if (!authorization_delegate->GetCommandAuthorization(
20917             command_hash, is_command_parameter_encryption_possible,
20918             is_response_parameter_encryption_possible,
20919             &authorization_section_bytes)) {
20920       return TRUNKS_RC_AUTHORIZATION_FAILED;
20921     }
20922     if (!authorization_section_bytes.empty()) {
20923       tag = TPM_ST_SESSIONS;
20924       std::string tmp;
20925       rc = Serialize_UINT32(authorization_section_bytes.size(),
20926                             &authorization_size_bytes);
20927       if (rc != TPM_RC_SUCCESS) {
20928         return rc;
20929       }
20930       command_size +=
20931           authorization_size_bytes.size() + authorization_section_bytes.size();
20932     }
20933   }
20934   std::string tag_bytes;
20935   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
20936   if (rc != TPM_RC_SUCCESS) {
20937     return rc;
20938   }
20939   std::string command_size_bytes;
20940   rc = Serialize_UINT32(command_size, &command_size_bytes);
20941   if (rc != TPM_RC_SUCCESS) {
20942     return rc;
20943   }
20944   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
20945                         handle_section_bytes + authorization_size_bytes +
20946                         authorization_section_bytes + parameter_section_bytes;
20947   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
20948   VLOG(2) << "Command: "
20949           << base::HexEncode(serialized_command->data(),
20950                              serialized_command->size());
20951   return TPM_RC_SUCCESS;
20952 }
20953 
ParseResponse_PCR_Reset(const std::string & response,AuthorizationDelegate * authorization_delegate)20954 TPM_RC Tpm::ParseResponse_PCR_Reset(
20955     const std::string& response,
20956     AuthorizationDelegate* authorization_delegate) {
20957   VLOG(3) << __func__;
20958   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
20959   TPM_RC rc = TPM_RC_SUCCESS;
20960   std::string buffer(response);
20961   TPM_ST tag;
20962   std::string tag_bytes;
20963   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
20964   if (rc != TPM_RC_SUCCESS) {
20965     return rc;
20966   }
20967   UINT32 response_size;
20968   std::string response_size_bytes;
20969   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
20970   if (rc != TPM_RC_SUCCESS) {
20971     return rc;
20972   }
20973   TPM_RC response_code;
20974   std::string response_code_bytes;
20975   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
20976   if (rc != TPM_RC_SUCCESS) {
20977     return rc;
20978   }
20979   if (response_size != response.size()) {
20980     return TPM_RC_SIZE;
20981   }
20982   if (response_code != TPM_RC_SUCCESS) {
20983     return response_code;
20984   }
20985   TPM_CC command_code = TPM_CC_PCR_Reset;
20986   std::string command_code_bytes;
20987   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
20988   if (rc != TPM_RC_SUCCESS) {
20989     return rc;
20990   }
20991   std::string authorization_section_bytes;
20992   if (tag == TPM_ST_SESSIONS) {
20993     UINT32 parameter_section_size = buffer.size();
20994     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
20995     if (rc != TPM_RC_SUCCESS) {
20996       return rc;
20997     }
20998     if (parameter_section_size > buffer.size()) {
20999       return TPM_RC_INSUFFICIENT;
21000     }
21001     authorization_section_bytes = buffer.substr(parameter_section_size);
21002     // Keep the parameter section in |buffer|.
21003     buffer.erase(parameter_section_size);
21004   }
21005   std::unique_ptr<crypto::SecureHash> hash(
21006       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21007   hash->Update(response_code_bytes.data(), response_code_bytes.size());
21008   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21009   hash->Update(buffer.data(), buffer.size());
21010   std::string response_hash(32, 0);
21011   hash->Finish(std::data(response_hash), response_hash.size());
21012   if (tag == TPM_ST_SESSIONS) {
21013     if (!authorization_delegate)
21014       return TRUNKS_RC_AUTHORIZATION_FAILED;
21015     if (!authorization_delegate->CheckResponseAuthorization(
21016             response_hash, authorization_section_bytes)) {
21017       return TRUNKS_RC_AUTHORIZATION_FAILED;
21018     }
21019   }
21020   return TPM_RC_SUCCESS;
21021 }
21022 
PCR_ResetErrorCallback(Tpm::PCR_ResetResponse callback,TPM_RC response_code)21023 void PCR_ResetErrorCallback(Tpm::PCR_ResetResponse callback,
21024                             TPM_RC response_code) {
21025   VLOG(1) << __func__;
21026   std::move(callback).Run(response_code);
21027 }
21028 
PCR_ResetResponseParser(Tpm::PCR_ResetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21029 void PCR_ResetResponseParser(Tpm::PCR_ResetResponse callback,
21030                              AuthorizationDelegate* authorization_delegate,
21031                              const std::string& response) {
21032   VLOG(1) << __func__;
21033   TPM_RC rc = Tpm::ParseResponse_PCR_Reset(response, authorization_delegate);
21034   if (rc != TPM_RC_SUCCESS) {
21035     base::OnceCallback<void(TPM_RC)> error_reporter =
21036         base::BindOnce(PCR_ResetErrorCallback, std::move(callback));
21037     std::move(error_reporter).Run(rc);
21038     return;
21039   }
21040   std::move(callback).Run(rc);
21041 }
21042 
PCR_Reset(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,AuthorizationDelegate * authorization_delegate,PCR_ResetResponse callback)21043 void Tpm::PCR_Reset(const TPMI_DH_PCR& pcr_handle,
21044                     const std::string& pcr_handle_name,
21045                     AuthorizationDelegate* authorization_delegate,
21046                     PCR_ResetResponse callback) {
21047   VLOG(1) << __func__;
21048   std::string command;
21049   TPM_RC rc = SerializeCommand_PCR_Reset(pcr_handle, pcr_handle_name, &command,
21050                                          authorization_delegate);
21051   if (rc != TPM_RC_SUCCESS) {
21052     base::OnceCallback<void(TPM_RC)> error_reporter =
21053         base::BindOnce(PCR_ResetErrorCallback, std::move(callback));
21054     std::move(error_reporter).Run(rc);
21055     return;
21056   }
21057   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21058       PCR_ResetResponseParser, std::move(callback), authorization_delegate);
21059   transceiver_->SendCommand(command, std::move(parser));
21060 }
21061 
PCR_ResetSync(const TPMI_DH_PCR & pcr_handle,const std::string & pcr_handle_name,AuthorizationDelegate * authorization_delegate)21062 TPM_RC Tpm::PCR_ResetSync(const TPMI_DH_PCR& pcr_handle,
21063                           const std::string& pcr_handle_name,
21064                           AuthorizationDelegate* authorization_delegate) {
21065   VLOG(1) << __func__;
21066   std::string command;
21067   TPM_RC rc = SerializeCommand_PCR_Reset(pcr_handle, pcr_handle_name, &command,
21068                                          authorization_delegate);
21069   if (rc != TPM_RC_SUCCESS) {
21070     return rc;
21071   }
21072   std::string response = transceiver_->SendCommandAndWait(command);
21073   rc = ParseResponse_PCR_Reset(response, authorization_delegate);
21074   return rc;
21075 }
21076 
SerializeCommand_PolicySigned(const TPMI_DH_OBJECT & auth_object,const std::string & auth_object_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,const TPMT_SIGNATURE & auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21077 TPM_RC Tpm::SerializeCommand_PolicySigned(
21078     const TPMI_DH_OBJECT& auth_object,
21079     const std::string& auth_object_name,
21080     const TPMI_SH_POLICY& policy_session,
21081     const std::string& policy_session_name,
21082     const TPM2B_NONCE& nonce_tpm,
21083     const TPM2B_DIGEST& cp_hash_a,
21084     const TPM2B_NONCE& policy_ref,
21085     const INT32& expiration,
21086     const TPMT_SIGNATURE& auth,
21087     std::string* serialized_command,
21088     AuthorizationDelegate* authorization_delegate) {
21089   VLOG(3) << __func__;
21090   TPM_RC rc = TPM_RC_SUCCESS;
21091   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21092   UINT32 command_size = 10;  // Header size.
21093   std::string handle_section_bytes;
21094   std::string parameter_section_bytes;
21095   TPM_CC command_code = TPM_CC_PolicySigned;
21096   bool is_command_parameter_encryption_possible = true;
21097   bool is_response_parameter_encryption_possible = true;
21098   std::string command_code_bytes;
21099   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21100   if (rc != TPM_RC_SUCCESS) {
21101     return rc;
21102   }
21103   std::string auth_object_bytes;
21104   rc = Serialize_TPMI_DH_OBJECT(auth_object, &auth_object_bytes);
21105   if (rc != TPM_RC_SUCCESS) {
21106     return rc;
21107   }
21108   std::string policy_session_bytes;
21109   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21110   if (rc != TPM_RC_SUCCESS) {
21111     return rc;
21112   }
21113   std::string nonce_tpm_bytes;
21114   rc = Serialize_TPM2B_NONCE(nonce_tpm, &nonce_tpm_bytes);
21115   if (rc != TPM_RC_SUCCESS) {
21116     return rc;
21117   }
21118   std::string cp_hash_a_bytes;
21119   rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21120   if (rc != TPM_RC_SUCCESS) {
21121     return rc;
21122   }
21123   std::string policy_ref_bytes;
21124   rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21125   if (rc != TPM_RC_SUCCESS) {
21126     return rc;
21127   }
21128   std::string expiration_bytes;
21129   rc = Serialize_INT32(expiration, &expiration_bytes);
21130   if (rc != TPM_RC_SUCCESS) {
21131     return rc;
21132   }
21133   std::string auth_bytes;
21134   rc = Serialize_TPMT_SIGNATURE(auth, &auth_bytes);
21135   if (rc != TPM_RC_SUCCESS) {
21136     return rc;
21137   }
21138   if (authorization_delegate) {
21139     // Encrypt just the parameter data, not the size.
21140     std::string tmp = nonce_tpm_bytes.substr(2);
21141     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21142       return TRUNKS_RC_ENCRYPTION_FAILED;
21143     }
21144     nonce_tpm_bytes.replace(2, std::string::npos, tmp);
21145   }
21146   std::unique_ptr<crypto::SecureHash> hash(
21147       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21148   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21149   hash->Update(auth_object_name.data(), auth_object_name.size());
21150   handle_section_bytes += auth_object_bytes;
21151   command_size += auth_object_bytes.size();
21152   hash->Update(policy_session_name.data(), policy_session_name.size());
21153   handle_section_bytes += policy_session_bytes;
21154   command_size += policy_session_bytes.size();
21155   hash->Update(nonce_tpm_bytes.data(), nonce_tpm_bytes.size());
21156   parameter_section_bytes += nonce_tpm_bytes;
21157   command_size += nonce_tpm_bytes.size();
21158   hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21159   parameter_section_bytes += cp_hash_a_bytes;
21160   command_size += cp_hash_a_bytes.size();
21161   hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21162   parameter_section_bytes += policy_ref_bytes;
21163   command_size += policy_ref_bytes.size();
21164   hash->Update(expiration_bytes.data(), expiration_bytes.size());
21165   parameter_section_bytes += expiration_bytes;
21166   command_size += expiration_bytes.size();
21167   hash->Update(auth_bytes.data(), auth_bytes.size());
21168   parameter_section_bytes += auth_bytes;
21169   command_size += auth_bytes.size();
21170   std::string command_hash(32, 0);
21171   hash->Finish(std::data(command_hash), command_hash.size());
21172   std::string authorization_section_bytes;
21173   std::string authorization_size_bytes;
21174   if (authorization_delegate) {
21175     if (!authorization_delegate->GetCommandAuthorization(
21176             command_hash, is_command_parameter_encryption_possible,
21177             is_response_parameter_encryption_possible,
21178             &authorization_section_bytes)) {
21179       return TRUNKS_RC_AUTHORIZATION_FAILED;
21180     }
21181     if (!authorization_section_bytes.empty()) {
21182       tag = TPM_ST_SESSIONS;
21183       std::string tmp;
21184       rc = Serialize_UINT32(authorization_section_bytes.size(),
21185                             &authorization_size_bytes);
21186       if (rc != TPM_RC_SUCCESS) {
21187         return rc;
21188       }
21189       command_size +=
21190           authorization_size_bytes.size() + authorization_section_bytes.size();
21191     }
21192   }
21193   std::string tag_bytes;
21194   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21195   if (rc != TPM_RC_SUCCESS) {
21196     return rc;
21197   }
21198   std::string command_size_bytes;
21199   rc = Serialize_UINT32(command_size, &command_size_bytes);
21200   if (rc != TPM_RC_SUCCESS) {
21201     return rc;
21202   }
21203   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21204                         handle_section_bytes + authorization_size_bytes +
21205                         authorization_section_bytes + parameter_section_bytes;
21206   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21207   VLOG(2) << "Command: "
21208           << base::HexEncode(serialized_command->data(),
21209                              serialized_command->size());
21210   return TPM_RC_SUCCESS;
21211 }
21212 
ParseResponse_PolicySigned(const std::string & response,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21213 TPM_RC Tpm::ParseResponse_PolicySigned(
21214     const std::string& response,
21215     TPM2B_TIMEOUT* timeout,
21216     TPMT_TK_AUTH* policy_ticket,
21217     AuthorizationDelegate* authorization_delegate) {
21218   VLOG(3) << __func__;
21219   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21220   TPM_RC rc = TPM_RC_SUCCESS;
21221   std::string buffer(response);
21222   TPM_ST tag;
21223   std::string tag_bytes;
21224   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21225   if (rc != TPM_RC_SUCCESS) {
21226     return rc;
21227   }
21228   UINT32 response_size;
21229   std::string response_size_bytes;
21230   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21231   if (rc != TPM_RC_SUCCESS) {
21232     return rc;
21233   }
21234   TPM_RC response_code;
21235   std::string response_code_bytes;
21236   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21237   if (rc != TPM_RC_SUCCESS) {
21238     return rc;
21239   }
21240   if (response_size != response.size()) {
21241     return TPM_RC_SIZE;
21242   }
21243   if (response_code != TPM_RC_SUCCESS) {
21244     return response_code;
21245   }
21246   TPM_CC command_code = TPM_CC_PolicySigned;
21247   std::string command_code_bytes;
21248   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21249   if (rc != TPM_RC_SUCCESS) {
21250     return rc;
21251   }
21252   std::string authorization_section_bytes;
21253   if (tag == TPM_ST_SESSIONS) {
21254     UINT32 parameter_section_size = buffer.size();
21255     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
21256     if (rc != TPM_RC_SUCCESS) {
21257       return rc;
21258     }
21259     if (parameter_section_size > buffer.size()) {
21260       return TPM_RC_INSUFFICIENT;
21261     }
21262     authorization_section_bytes = buffer.substr(parameter_section_size);
21263     // Keep the parameter section in |buffer|.
21264     buffer.erase(parameter_section_size);
21265   }
21266   std::unique_ptr<crypto::SecureHash> hash(
21267       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21268   hash->Update(response_code_bytes.data(), response_code_bytes.size());
21269   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21270   hash->Update(buffer.data(), buffer.size());
21271   std::string response_hash(32, 0);
21272   hash->Finish(std::data(response_hash), response_hash.size());
21273   if (tag == TPM_ST_SESSIONS) {
21274     if (!authorization_delegate)
21275       return TRUNKS_RC_AUTHORIZATION_FAILED;
21276     if (!authorization_delegate->CheckResponseAuthorization(
21277             response_hash, authorization_section_bytes)) {
21278       return TRUNKS_RC_AUTHORIZATION_FAILED;
21279     }
21280   }
21281   if (tag == TPM_ST_SESSIONS) {
21282     if (!authorization_delegate)
21283       return TRUNKS_RC_AUTHORIZATION_FAILED;
21284 
21285     // Parse the encrypted parameter size.
21286     UINT16 size;
21287     std::string size_buffer = buffer.substr(0, 2);
21288     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
21289       return result;
21290     }
21291     if (buffer.size() < 2 + size) {
21292       return TPM_RC_INSUFFICIENT;
21293     }
21294 
21295     // Decrypt just the parameter data, not the size.
21296     std::string decrypted_data = buffer.substr(2, size);
21297     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
21298       return TRUNKS_RC_ENCRYPTION_FAILED;
21299     }
21300     buffer.replace(2, size, decrypted_data);
21301   }
21302   std::string timeout_bytes;
21303   rc = Parse_TPM2B_TIMEOUT(&buffer, timeout, &timeout_bytes);
21304   if (rc != TPM_RC_SUCCESS) {
21305     return rc;
21306   }
21307   std::string policy_ticket_bytes;
21308   rc = Parse_TPMT_TK_AUTH(&buffer, policy_ticket, &policy_ticket_bytes);
21309   if (rc != TPM_RC_SUCCESS) {
21310     return rc;
21311   }
21312   return TPM_RC_SUCCESS;
21313 }
21314 
PolicySignedErrorCallback(Tpm::PolicySignedResponse callback,TPM_RC response_code)21315 void PolicySignedErrorCallback(Tpm::PolicySignedResponse callback,
21316                                TPM_RC response_code) {
21317   VLOG(1) << __func__;
21318   std::move(callback).Run(response_code, TPM2B_TIMEOUT(), TPMT_TK_AUTH());
21319 }
21320 
PolicySignedResponseParser(Tpm::PolicySignedResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21321 void PolicySignedResponseParser(Tpm::PolicySignedResponse callback,
21322                                 AuthorizationDelegate* authorization_delegate,
21323                                 const std::string& response) {
21324   VLOG(1) << __func__;
21325   TPM2B_TIMEOUT timeout;
21326   TPMT_TK_AUTH policy_ticket;
21327   TPM_RC rc = Tpm::ParseResponse_PolicySigned(
21328       response, &timeout, &policy_ticket, authorization_delegate);
21329   if (rc != TPM_RC_SUCCESS) {
21330     base::OnceCallback<void(TPM_RC)> error_reporter =
21331         base::BindOnce(PolicySignedErrorCallback, std::move(callback));
21332     std::move(error_reporter).Run(rc);
21333     return;
21334   }
21335   std::move(callback).Run(rc, timeout, policy_ticket);
21336 }
21337 
PolicySigned(const TPMI_DH_OBJECT & auth_object,const std::string & auth_object_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,const TPMT_SIGNATURE & auth,AuthorizationDelegate * authorization_delegate,PolicySignedResponse callback)21338 void Tpm::PolicySigned(const TPMI_DH_OBJECT& auth_object,
21339                        const std::string& auth_object_name,
21340                        const TPMI_SH_POLICY& policy_session,
21341                        const std::string& policy_session_name,
21342                        const TPM2B_NONCE& nonce_tpm,
21343                        const TPM2B_DIGEST& cp_hash_a,
21344                        const TPM2B_NONCE& policy_ref,
21345                        const INT32& expiration,
21346                        const TPMT_SIGNATURE& auth,
21347                        AuthorizationDelegate* authorization_delegate,
21348                        PolicySignedResponse callback) {
21349   VLOG(1) << __func__;
21350   std::string command;
21351   TPM_RC rc = SerializeCommand_PolicySigned(
21352       auth_object, auth_object_name, policy_session, policy_session_name,
21353       nonce_tpm, cp_hash_a, policy_ref, expiration, auth, &command,
21354       authorization_delegate);
21355   if (rc != TPM_RC_SUCCESS) {
21356     base::OnceCallback<void(TPM_RC)> error_reporter =
21357         base::BindOnce(PolicySignedErrorCallback, std::move(callback));
21358     std::move(error_reporter).Run(rc);
21359     return;
21360   }
21361   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21362       PolicySignedResponseParser, std::move(callback), authorization_delegate);
21363   transceiver_->SendCommand(command, std::move(parser));
21364 }
21365 
PolicySignedSync(const TPMI_DH_OBJECT & auth_object,const std::string & auth_object_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,const TPMT_SIGNATURE & auth,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21366 TPM_RC Tpm::PolicySignedSync(const TPMI_DH_OBJECT& auth_object,
21367                              const std::string& auth_object_name,
21368                              const TPMI_SH_POLICY& policy_session,
21369                              const std::string& policy_session_name,
21370                              const TPM2B_NONCE& nonce_tpm,
21371                              const TPM2B_DIGEST& cp_hash_a,
21372                              const TPM2B_NONCE& policy_ref,
21373                              const INT32& expiration,
21374                              const TPMT_SIGNATURE& auth,
21375                              TPM2B_TIMEOUT* timeout,
21376                              TPMT_TK_AUTH* policy_ticket,
21377                              AuthorizationDelegate* authorization_delegate) {
21378   VLOG(1) << __func__;
21379   std::string command;
21380   TPM_RC rc = SerializeCommand_PolicySigned(
21381       auth_object, auth_object_name, policy_session, policy_session_name,
21382       nonce_tpm, cp_hash_a, policy_ref, expiration, auth, &command,
21383       authorization_delegate);
21384   if (rc != TPM_RC_SUCCESS) {
21385     return rc;
21386   }
21387   std::string response = transceiver_->SendCommandAndWait(command);
21388   rc = ParseResponse_PolicySigned(response, timeout, policy_ticket,
21389                                   authorization_delegate);
21390   return rc;
21391 }
21392 
SerializeCommand_PolicySecret(const TPMI_DH_ENTITY & auth_handle,const std::string & auth_handle_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21393 TPM_RC Tpm::SerializeCommand_PolicySecret(
21394     const TPMI_DH_ENTITY& auth_handle,
21395     const std::string& auth_handle_name,
21396     const TPMI_SH_POLICY& policy_session,
21397     const std::string& policy_session_name,
21398     const TPM2B_NONCE& nonce_tpm,
21399     const TPM2B_DIGEST& cp_hash_a,
21400     const TPM2B_NONCE& policy_ref,
21401     const INT32& expiration,
21402     std::string* serialized_command,
21403     AuthorizationDelegate* authorization_delegate) {
21404   VLOG(3) << __func__;
21405   TPM_RC rc = TPM_RC_SUCCESS;
21406   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21407   UINT32 command_size = 10;  // Header size.
21408   std::string handle_section_bytes;
21409   std::string parameter_section_bytes;
21410   TPM_CC command_code = TPM_CC_PolicySecret;
21411   bool is_command_parameter_encryption_possible = true;
21412   bool is_response_parameter_encryption_possible = true;
21413   std::string command_code_bytes;
21414   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21415   if (rc != TPM_RC_SUCCESS) {
21416     return rc;
21417   }
21418   std::string auth_handle_bytes;
21419   rc = Serialize_TPMI_DH_ENTITY(auth_handle, &auth_handle_bytes);
21420   if (rc != TPM_RC_SUCCESS) {
21421     return rc;
21422   }
21423   std::string policy_session_bytes;
21424   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21425   if (rc != TPM_RC_SUCCESS) {
21426     return rc;
21427   }
21428   std::string nonce_tpm_bytes;
21429   rc = Serialize_TPM2B_NONCE(nonce_tpm, &nonce_tpm_bytes);
21430   if (rc != TPM_RC_SUCCESS) {
21431     return rc;
21432   }
21433   std::string cp_hash_a_bytes;
21434   rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21435   if (rc != TPM_RC_SUCCESS) {
21436     return rc;
21437   }
21438   std::string policy_ref_bytes;
21439   rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21440   if (rc != TPM_RC_SUCCESS) {
21441     return rc;
21442   }
21443   std::string expiration_bytes;
21444   rc = Serialize_INT32(expiration, &expiration_bytes);
21445   if (rc != TPM_RC_SUCCESS) {
21446     return rc;
21447   }
21448   if (authorization_delegate) {
21449     // Encrypt just the parameter data, not the size.
21450     std::string tmp = nonce_tpm_bytes.substr(2);
21451     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21452       return TRUNKS_RC_ENCRYPTION_FAILED;
21453     }
21454     nonce_tpm_bytes.replace(2, std::string::npos, tmp);
21455   }
21456   std::unique_ptr<crypto::SecureHash> hash(
21457       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21458   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21459   hash->Update(auth_handle_name.data(), auth_handle_name.size());
21460   handle_section_bytes += auth_handle_bytes;
21461   command_size += auth_handle_bytes.size();
21462   hash->Update(policy_session_name.data(), policy_session_name.size());
21463   handle_section_bytes += policy_session_bytes;
21464   command_size += policy_session_bytes.size();
21465   hash->Update(nonce_tpm_bytes.data(), nonce_tpm_bytes.size());
21466   parameter_section_bytes += nonce_tpm_bytes;
21467   command_size += nonce_tpm_bytes.size();
21468   hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21469   parameter_section_bytes += cp_hash_a_bytes;
21470   command_size += cp_hash_a_bytes.size();
21471   hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21472   parameter_section_bytes += policy_ref_bytes;
21473   command_size += policy_ref_bytes.size();
21474   hash->Update(expiration_bytes.data(), expiration_bytes.size());
21475   parameter_section_bytes += expiration_bytes;
21476   command_size += expiration_bytes.size();
21477   std::string command_hash(32, 0);
21478   hash->Finish(std::data(command_hash), command_hash.size());
21479   std::string authorization_section_bytes;
21480   std::string authorization_size_bytes;
21481   if (authorization_delegate) {
21482     if (!authorization_delegate->GetCommandAuthorization(
21483             command_hash, is_command_parameter_encryption_possible,
21484             is_response_parameter_encryption_possible,
21485             &authorization_section_bytes)) {
21486       return TRUNKS_RC_AUTHORIZATION_FAILED;
21487     }
21488     if (!authorization_section_bytes.empty()) {
21489       tag = TPM_ST_SESSIONS;
21490       std::string tmp;
21491       rc = Serialize_UINT32(authorization_section_bytes.size(),
21492                             &authorization_size_bytes);
21493       if (rc != TPM_RC_SUCCESS) {
21494         return rc;
21495       }
21496       command_size +=
21497           authorization_size_bytes.size() + authorization_section_bytes.size();
21498     }
21499   }
21500   std::string tag_bytes;
21501   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21502   if (rc != TPM_RC_SUCCESS) {
21503     return rc;
21504   }
21505   std::string command_size_bytes;
21506   rc = Serialize_UINT32(command_size, &command_size_bytes);
21507   if (rc != TPM_RC_SUCCESS) {
21508     return rc;
21509   }
21510   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21511                         handle_section_bytes + authorization_size_bytes +
21512                         authorization_section_bytes + parameter_section_bytes;
21513   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21514   VLOG(2) << "Command: "
21515           << base::HexEncode(serialized_command->data(),
21516                              serialized_command->size());
21517   return TPM_RC_SUCCESS;
21518 }
21519 
ParseResponse_PolicySecret(const std::string & response,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21520 TPM_RC Tpm::ParseResponse_PolicySecret(
21521     const std::string& response,
21522     TPM2B_TIMEOUT* timeout,
21523     TPMT_TK_AUTH* policy_ticket,
21524     AuthorizationDelegate* authorization_delegate) {
21525   VLOG(3) << __func__;
21526   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21527   TPM_RC rc = TPM_RC_SUCCESS;
21528   std::string buffer(response);
21529   TPM_ST tag;
21530   std::string tag_bytes;
21531   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21532   if (rc != TPM_RC_SUCCESS) {
21533     return rc;
21534   }
21535   UINT32 response_size;
21536   std::string response_size_bytes;
21537   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21538   if (rc != TPM_RC_SUCCESS) {
21539     return rc;
21540   }
21541   TPM_RC response_code;
21542   std::string response_code_bytes;
21543   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21544   if (rc != TPM_RC_SUCCESS) {
21545     return rc;
21546   }
21547   if (response_size != response.size()) {
21548     return TPM_RC_SIZE;
21549   }
21550   if (response_code != TPM_RC_SUCCESS) {
21551     return response_code;
21552   }
21553   TPM_CC command_code = TPM_CC_PolicySecret;
21554   std::string command_code_bytes;
21555   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21556   if (rc != TPM_RC_SUCCESS) {
21557     return rc;
21558   }
21559   std::string authorization_section_bytes;
21560   if (tag == TPM_ST_SESSIONS) {
21561     UINT32 parameter_section_size = buffer.size();
21562     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
21563     if (rc != TPM_RC_SUCCESS) {
21564       return rc;
21565     }
21566     if (parameter_section_size > buffer.size()) {
21567       return TPM_RC_INSUFFICIENT;
21568     }
21569     authorization_section_bytes = buffer.substr(parameter_section_size);
21570     // Keep the parameter section in |buffer|.
21571     buffer.erase(parameter_section_size);
21572   }
21573   std::unique_ptr<crypto::SecureHash> hash(
21574       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21575   hash->Update(response_code_bytes.data(), response_code_bytes.size());
21576   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21577   hash->Update(buffer.data(), buffer.size());
21578   std::string response_hash(32, 0);
21579   hash->Finish(std::data(response_hash), response_hash.size());
21580   if (tag == TPM_ST_SESSIONS) {
21581     if (!authorization_delegate)
21582       return TRUNKS_RC_AUTHORIZATION_FAILED;
21583     if (!authorization_delegate->CheckResponseAuthorization(
21584             response_hash, authorization_section_bytes)) {
21585       return TRUNKS_RC_AUTHORIZATION_FAILED;
21586     }
21587   }
21588   if (tag == TPM_ST_SESSIONS) {
21589     if (!authorization_delegate)
21590       return TRUNKS_RC_AUTHORIZATION_FAILED;
21591 
21592     // Parse the encrypted parameter size.
21593     UINT16 size;
21594     std::string size_buffer = buffer.substr(0, 2);
21595     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
21596       return result;
21597     }
21598     if (buffer.size() < 2 + size) {
21599       return TPM_RC_INSUFFICIENT;
21600     }
21601 
21602     // Decrypt just the parameter data, not the size.
21603     std::string decrypted_data = buffer.substr(2, size);
21604     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
21605       return TRUNKS_RC_ENCRYPTION_FAILED;
21606     }
21607     buffer.replace(2, size, decrypted_data);
21608   }
21609   std::string timeout_bytes;
21610   rc = Parse_TPM2B_TIMEOUT(&buffer, timeout, &timeout_bytes);
21611   if (rc != TPM_RC_SUCCESS) {
21612     return rc;
21613   }
21614   std::string policy_ticket_bytes;
21615   rc = Parse_TPMT_TK_AUTH(&buffer, policy_ticket, &policy_ticket_bytes);
21616   if (rc != TPM_RC_SUCCESS) {
21617     return rc;
21618   }
21619   return TPM_RC_SUCCESS;
21620 }
21621 
PolicySecretErrorCallback(Tpm::PolicySecretResponse callback,TPM_RC response_code)21622 void PolicySecretErrorCallback(Tpm::PolicySecretResponse callback,
21623                                TPM_RC response_code) {
21624   VLOG(1) << __func__;
21625   std::move(callback).Run(response_code, TPM2B_TIMEOUT(), TPMT_TK_AUTH());
21626 }
21627 
PolicySecretResponseParser(Tpm::PolicySecretResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21628 void PolicySecretResponseParser(Tpm::PolicySecretResponse callback,
21629                                 AuthorizationDelegate* authorization_delegate,
21630                                 const std::string& response) {
21631   VLOG(1) << __func__;
21632   TPM2B_TIMEOUT timeout;
21633   TPMT_TK_AUTH policy_ticket;
21634   TPM_RC rc = Tpm::ParseResponse_PolicySecret(
21635       response, &timeout, &policy_ticket, authorization_delegate);
21636   if (rc != TPM_RC_SUCCESS) {
21637     base::OnceCallback<void(TPM_RC)> error_reporter =
21638         base::BindOnce(PolicySecretErrorCallback, std::move(callback));
21639     std::move(error_reporter).Run(rc);
21640     return;
21641   }
21642   std::move(callback).Run(rc, timeout, policy_ticket);
21643 }
21644 
PolicySecret(const TPMI_DH_ENTITY & auth_handle,const std::string & auth_handle_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,AuthorizationDelegate * authorization_delegate,PolicySecretResponse callback)21645 void Tpm::PolicySecret(const TPMI_DH_ENTITY& auth_handle,
21646                        const std::string& auth_handle_name,
21647                        const TPMI_SH_POLICY& policy_session,
21648                        const std::string& policy_session_name,
21649                        const TPM2B_NONCE& nonce_tpm,
21650                        const TPM2B_DIGEST& cp_hash_a,
21651                        const TPM2B_NONCE& policy_ref,
21652                        const INT32& expiration,
21653                        AuthorizationDelegate* authorization_delegate,
21654                        PolicySecretResponse callback) {
21655   VLOG(1) << __func__;
21656   std::string command;
21657   TPM_RC rc = SerializeCommand_PolicySecret(
21658       auth_handle, auth_handle_name, policy_session, policy_session_name,
21659       nonce_tpm, cp_hash_a, policy_ref, expiration, &command,
21660       authorization_delegate);
21661   if (rc != TPM_RC_SUCCESS) {
21662     base::OnceCallback<void(TPM_RC)> error_reporter =
21663         base::BindOnce(PolicySecretErrorCallback, std::move(callback));
21664     std::move(error_reporter).Run(rc);
21665     return;
21666   }
21667   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21668       PolicySecretResponseParser, std::move(callback), authorization_delegate);
21669   transceiver_->SendCommand(command, std::move(parser));
21670 }
21671 
PolicySecretSync(const TPMI_DH_ENTITY & auth_handle,const std::string & auth_handle_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NONCE & nonce_tpm,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const INT32 & expiration,TPM2B_TIMEOUT * timeout,TPMT_TK_AUTH * policy_ticket,AuthorizationDelegate * authorization_delegate)21672 TPM_RC Tpm::PolicySecretSync(const TPMI_DH_ENTITY& auth_handle,
21673                              const std::string& auth_handle_name,
21674                              const TPMI_SH_POLICY& policy_session,
21675                              const std::string& policy_session_name,
21676                              const TPM2B_NONCE& nonce_tpm,
21677                              const TPM2B_DIGEST& cp_hash_a,
21678                              const TPM2B_NONCE& policy_ref,
21679                              const INT32& expiration,
21680                              TPM2B_TIMEOUT* timeout,
21681                              TPMT_TK_AUTH* policy_ticket,
21682                              AuthorizationDelegate* authorization_delegate) {
21683   VLOG(1) << __func__;
21684   std::string command;
21685   TPM_RC rc = SerializeCommand_PolicySecret(
21686       auth_handle, auth_handle_name, policy_session, policy_session_name,
21687       nonce_tpm, cp_hash_a, policy_ref, expiration, &command,
21688       authorization_delegate);
21689   if (rc != TPM_RC_SUCCESS) {
21690     return rc;
21691   }
21692   std::string response = transceiver_->SendCommandAndWait(command);
21693   rc = ParseResponse_PolicySecret(response, timeout, policy_ticket,
21694                                   authorization_delegate);
21695   return rc;
21696 }
21697 
SerializeCommand_PolicyTicket(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_TIMEOUT & timeout,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & auth_name,const TPMT_TK_AUTH & ticket,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21698 TPM_RC Tpm::SerializeCommand_PolicyTicket(
21699     const TPMI_SH_POLICY& policy_session,
21700     const std::string& policy_session_name,
21701     const TPM2B_TIMEOUT& timeout,
21702     const TPM2B_DIGEST& cp_hash_a,
21703     const TPM2B_NONCE& policy_ref,
21704     const TPM2B_NAME& auth_name,
21705     const TPMT_TK_AUTH& ticket,
21706     std::string* serialized_command,
21707     AuthorizationDelegate* authorization_delegate) {
21708   VLOG(3) << __func__;
21709   TPM_RC rc = TPM_RC_SUCCESS;
21710   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21711   UINT32 command_size = 10;  // Header size.
21712   std::string handle_section_bytes;
21713   std::string parameter_section_bytes;
21714   TPM_CC command_code = TPM_CC_PolicyTicket;
21715   bool is_command_parameter_encryption_possible = true;
21716   bool is_response_parameter_encryption_possible = false;
21717   std::string command_code_bytes;
21718   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21719   if (rc != TPM_RC_SUCCESS) {
21720     return rc;
21721   }
21722   std::string policy_session_bytes;
21723   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21724   if (rc != TPM_RC_SUCCESS) {
21725     return rc;
21726   }
21727   std::string timeout_bytes;
21728   rc = Serialize_TPM2B_TIMEOUT(timeout, &timeout_bytes);
21729   if (rc != TPM_RC_SUCCESS) {
21730     return rc;
21731   }
21732   std::string cp_hash_a_bytes;
21733   rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
21734   if (rc != TPM_RC_SUCCESS) {
21735     return rc;
21736   }
21737   std::string policy_ref_bytes;
21738   rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
21739   if (rc != TPM_RC_SUCCESS) {
21740     return rc;
21741   }
21742   std::string auth_name_bytes;
21743   rc = Serialize_TPM2B_NAME(auth_name, &auth_name_bytes);
21744   if (rc != TPM_RC_SUCCESS) {
21745     return rc;
21746   }
21747   std::string ticket_bytes;
21748   rc = Serialize_TPMT_TK_AUTH(ticket, &ticket_bytes);
21749   if (rc != TPM_RC_SUCCESS) {
21750     return rc;
21751   }
21752   if (authorization_delegate) {
21753     // Encrypt just the parameter data, not the size.
21754     std::string tmp = timeout_bytes.substr(2);
21755     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
21756       return TRUNKS_RC_ENCRYPTION_FAILED;
21757     }
21758     timeout_bytes.replace(2, std::string::npos, tmp);
21759   }
21760   std::unique_ptr<crypto::SecureHash> hash(
21761       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21762   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21763   hash->Update(policy_session_name.data(), policy_session_name.size());
21764   handle_section_bytes += policy_session_bytes;
21765   command_size += policy_session_bytes.size();
21766   hash->Update(timeout_bytes.data(), timeout_bytes.size());
21767   parameter_section_bytes += timeout_bytes;
21768   command_size += timeout_bytes.size();
21769   hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
21770   parameter_section_bytes += cp_hash_a_bytes;
21771   command_size += cp_hash_a_bytes.size();
21772   hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
21773   parameter_section_bytes += policy_ref_bytes;
21774   command_size += policy_ref_bytes.size();
21775   hash->Update(auth_name_bytes.data(), auth_name_bytes.size());
21776   parameter_section_bytes += auth_name_bytes;
21777   command_size += auth_name_bytes.size();
21778   hash->Update(ticket_bytes.data(), ticket_bytes.size());
21779   parameter_section_bytes += ticket_bytes;
21780   command_size += ticket_bytes.size();
21781   std::string command_hash(32, 0);
21782   hash->Finish(std::data(command_hash), command_hash.size());
21783   std::string authorization_section_bytes;
21784   std::string authorization_size_bytes;
21785   if (authorization_delegate) {
21786     if (!authorization_delegate->GetCommandAuthorization(
21787             command_hash, is_command_parameter_encryption_possible,
21788             is_response_parameter_encryption_possible,
21789             &authorization_section_bytes)) {
21790       return TRUNKS_RC_AUTHORIZATION_FAILED;
21791     }
21792     if (!authorization_section_bytes.empty()) {
21793       tag = TPM_ST_SESSIONS;
21794       std::string tmp;
21795       rc = Serialize_UINT32(authorization_section_bytes.size(),
21796                             &authorization_size_bytes);
21797       if (rc != TPM_RC_SUCCESS) {
21798         return rc;
21799       }
21800       command_size +=
21801           authorization_size_bytes.size() + authorization_section_bytes.size();
21802     }
21803   }
21804   std::string tag_bytes;
21805   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
21806   if (rc != TPM_RC_SUCCESS) {
21807     return rc;
21808   }
21809   std::string command_size_bytes;
21810   rc = Serialize_UINT32(command_size, &command_size_bytes);
21811   if (rc != TPM_RC_SUCCESS) {
21812     return rc;
21813   }
21814   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
21815                         handle_section_bytes + authorization_size_bytes +
21816                         authorization_section_bytes + parameter_section_bytes;
21817   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
21818   VLOG(2) << "Command: "
21819           << base::HexEncode(serialized_command->data(),
21820                              serialized_command->size());
21821   return TPM_RC_SUCCESS;
21822 }
21823 
ParseResponse_PolicyTicket(const std::string & response,AuthorizationDelegate * authorization_delegate)21824 TPM_RC Tpm::ParseResponse_PolicyTicket(
21825     const std::string& response,
21826     AuthorizationDelegate* authorization_delegate) {
21827   VLOG(3) << __func__;
21828   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
21829   TPM_RC rc = TPM_RC_SUCCESS;
21830   std::string buffer(response);
21831   TPM_ST tag;
21832   std::string tag_bytes;
21833   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
21834   if (rc != TPM_RC_SUCCESS) {
21835     return rc;
21836   }
21837   UINT32 response_size;
21838   std::string response_size_bytes;
21839   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
21840   if (rc != TPM_RC_SUCCESS) {
21841     return rc;
21842   }
21843   TPM_RC response_code;
21844   std::string response_code_bytes;
21845   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
21846   if (rc != TPM_RC_SUCCESS) {
21847     return rc;
21848   }
21849   if (response_size != response.size()) {
21850     return TPM_RC_SIZE;
21851   }
21852   if (response_code != TPM_RC_SUCCESS) {
21853     return response_code;
21854   }
21855   TPM_CC command_code = TPM_CC_PolicyTicket;
21856   std::string command_code_bytes;
21857   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21858   if (rc != TPM_RC_SUCCESS) {
21859     return rc;
21860   }
21861   std::string authorization_section_bytes;
21862   if (tag == TPM_ST_SESSIONS) {
21863     UINT32 parameter_section_size = buffer.size();
21864     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
21865     if (rc != TPM_RC_SUCCESS) {
21866       return rc;
21867     }
21868     if (parameter_section_size > buffer.size()) {
21869       return TPM_RC_INSUFFICIENT;
21870     }
21871     authorization_section_bytes = buffer.substr(parameter_section_size);
21872     // Keep the parameter section in |buffer|.
21873     buffer.erase(parameter_section_size);
21874   }
21875   std::unique_ptr<crypto::SecureHash> hash(
21876       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21877   hash->Update(response_code_bytes.data(), response_code_bytes.size());
21878   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21879   hash->Update(buffer.data(), buffer.size());
21880   std::string response_hash(32, 0);
21881   hash->Finish(std::data(response_hash), response_hash.size());
21882   if (tag == TPM_ST_SESSIONS) {
21883     if (!authorization_delegate)
21884       return TRUNKS_RC_AUTHORIZATION_FAILED;
21885     if (!authorization_delegate->CheckResponseAuthorization(
21886             response_hash, authorization_section_bytes)) {
21887       return TRUNKS_RC_AUTHORIZATION_FAILED;
21888     }
21889   }
21890   return TPM_RC_SUCCESS;
21891 }
21892 
PolicyTicketErrorCallback(Tpm::PolicyTicketResponse callback,TPM_RC response_code)21893 void PolicyTicketErrorCallback(Tpm::PolicyTicketResponse callback,
21894                                TPM_RC response_code) {
21895   VLOG(1) << __func__;
21896   std::move(callback).Run(response_code);
21897 }
21898 
PolicyTicketResponseParser(Tpm::PolicyTicketResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)21899 void PolicyTicketResponseParser(Tpm::PolicyTicketResponse callback,
21900                                 AuthorizationDelegate* authorization_delegate,
21901                                 const std::string& response) {
21902   VLOG(1) << __func__;
21903   TPM_RC rc = Tpm::ParseResponse_PolicyTicket(response, authorization_delegate);
21904   if (rc != TPM_RC_SUCCESS) {
21905     base::OnceCallback<void(TPM_RC)> error_reporter =
21906         base::BindOnce(PolicyTicketErrorCallback, std::move(callback));
21907     std::move(error_reporter).Run(rc);
21908     return;
21909   }
21910   std::move(callback).Run(rc);
21911 }
21912 
PolicyTicket(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_TIMEOUT & timeout,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & auth_name,const TPMT_TK_AUTH & ticket,AuthorizationDelegate * authorization_delegate,PolicyTicketResponse callback)21913 void Tpm::PolicyTicket(const TPMI_SH_POLICY& policy_session,
21914                        const std::string& policy_session_name,
21915                        const TPM2B_TIMEOUT& timeout,
21916                        const TPM2B_DIGEST& cp_hash_a,
21917                        const TPM2B_NONCE& policy_ref,
21918                        const TPM2B_NAME& auth_name,
21919                        const TPMT_TK_AUTH& ticket,
21920                        AuthorizationDelegate* authorization_delegate,
21921                        PolicyTicketResponse callback) {
21922   VLOG(1) << __func__;
21923   std::string command;
21924   TPM_RC rc = SerializeCommand_PolicyTicket(
21925       policy_session, policy_session_name, timeout, cp_hash_a, policy_ref,
21926       auth_name, ticket, &command, authorization_delegate);
21927   if (rc != TPM_RC_SUCCESS) {
21928     base::OnceCallback<void(TPM_RC)> error_reporter =
21929         base::BindOnce(PolicyTicketErrorCallback, std::move(callback));
21930     std::move(error_reporter).Run(rc);
21931     return;
21932   }
21933   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
21934       PolicyTicketResponseParser, std::move(callback), authorization_delegate);
21935   transceiver_->SendCommand(command, std::move(parser));
21936 }
21937 
PolicyTicketSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_TIMEOUT & timeout,const TPM2B_DIGEST & cp_hash_a,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & auth_name,const TPMT_TK_AUTH & ticket,AuthorizationDelegate * authorization_delegate)21938 TPM_RC Tpm::PolicyTicketSync(const TPMI_SH_POLICY& policy_session,
21939                              const std::string& policy_session_name,
21940                              const TPM2B_TIMEOUT& timeout,
21941                              const TPM2B_DIGEST& cp_hash_a,
21942                              const TPM2B_NONCE& policy_ref,
21943                              const TPM2B_NAME& auth_name,
21944                              const TPMT_TK_AUTH& ticket,
21945                              AuthorizationDelegate* authorization_delegate) {
21946   VLOG(1) << __func__;
21947   std::string command;
21948   TPM_RC rc = SerializeCommand_PolicyTicket(
21949       policy_session, policy_session_name, timeout, cp_hash_a, policy_ref,
21950       auth_name, ticket, &command, authorization_delegate);
21951   if (rc != TPM_RC_SUCCESS) {
21952     return rc;
21953   }
21954   std::string response = transceiver_->SendCommandAndWait(command);
21955   rc = ParseResponse_PolicyTicket(response, authorization_delegate);
21956   return rc;
21957 }
21958 
SerializeCommand_PolicyOR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)21959 TPM_RC Tpm::SerializeCommand_PolicyOR(
21960     const TPMI_SH_POLICY& policy_session,
21961     const std::string& policy_session_name,
21962     const TPML_DIGEST& p_hash_list,
21963     std::string* serialized_command,
21964     AuthorizationDelegate* authorization_delegate) {
21965   VLOG(3) << __func__;
21966   TPM_RC rc = TPM_RC_SUCCESS;
21967   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
21968   UINT32 command_size = 10;  // Header size.
21969   std::string handle_section_bytes;
21970   std::string parameter_section_bytes;
21971   TPM_CC command_code = TPM_CC_PolicyOR;
21972   bool is_command_parameter_encryption_possible = false;
21973   bool is_response_parameter_encryption_possible = false;
21974   std::string command_code_bytes;
21975   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
21976   if (rc != TPM_RC_SUCCESS) {
21977     return rc;
21978   }
21979   std::string policy_session_bytes;
21980   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
21981   if (rc != TPM_RC_SUCCESS) {
21982     return rc;
21983   }
21984   std::string p_hash_list_bytes;
21985   rc = Serialize_TPML_DIGEST(p_hash_list, &p_hash_list_bytes);
21986   if (rc != TPM_RC_SUCCESS) {
21987     return rc;
21988   }
21989   std::unique_ptr<crypto::SecureHash> hash(
21990       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
21991   hash->Update(command_code_bytes.data(), command_code_bytes.size());
21992   hash->Update(policy_session_name.data(), policy_session_name.size());
21993   handle_section_bytes += policy_session_bytes;
21994   command_size += policy_session_bytes.size();
21995   hash->Update(p_hash_list_bytes.data(), p_hash_list_bytes.size());
21996   parameter_section_bytes += p_hash_list_bytes;
21997   command_size += p_hash_list_bytes.size();
21998   std::string command_hash(32, 0);
21999   hash->Finish(std::data(command_hash), command_hash.size());
22000   std::string authorization_section_bytes;
22001   std::string authorization_size_bytes;
22002   if (authorization_delegate) {
22003     if (!authorization_delegate->GetCommandAuthorization(
22004             command_hash, is_command_parameter_encryption_possible,
22005             is_response_parameter_encryption_possible,
22006             &authorization_section_bytes)) {
22007       return TRUNKS_RC_AUTHORIZATION_FAILED;
22008     }
22009     if (!authorization_section_bytes.empty()) {
22010       tag = TPM_ST_SESSIONS;
22011       std::string tmp;
22012       rc = Serialize_UINT32(authorization_section_bytes.size(),
22013                             &authorization_size_bytes);
22014       if (rc != TPM_RC_SUCCESS) {
22015         return rc;
22016       }
22017       command_size +=
22018           authorization_size_bytes.size() + authorization_section_bytes.size();
22019     }
22020   }
22021   std::string tag_bytes;
22022   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22023   if (rc != TPM_RC_SUCCESS) {
22024     return rc;
22025   }
22026   std::string command_size_bytes;
22027   rc = Serialize_UINT32(command_size, &command_size_bytes);
22028   if (rc != TPM_RC_SUCCESS) {
22029     return rc;
22030   }
22031   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22032                         handle_section_bytes + authorization_size_bytes +
22033                         authorization_section_bytes + parameter_section_bytes;
22034   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22035   VLOG(2) << "Command: "
22036           << base::HexEncode(serialized_command->data(),
22037                              serialized_command->size());
22038   return TPM_RC_SUCCESS;
22039 }
22040 
ParseResponse_PolicyOR(const std::string & response,AuthorizationDelegate * authorization_delegate)22041 TPM_RC Tpm::ParseResponse_PolicyOR(
22042     const std::string& response,
22043     AuthorizationDelegate* authorization_delegate) {
22044   VLOG(3) << __func__;
22045   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22046   TPM_RC rc = TPM_RC_SUCCESS;
22047   std::string buffer(response);
22048   TPM_ST tag;
22049   std::string tag_bytes;
22050   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22051   if (rc != TPM_RC_SUCCESS) {
22052     return rc;
22053   }
22054   UINT32 response_size;
22055   std::string response_size_bytes;
22056   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22057   if (rc != TPM_RC_SUCCESS) {
22058     return rc;
22059   }
22060   TPM_RC response_code;
22061   std::string response_code_bytes;
22062   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22063   if (rc != TPM_RC_SUCCESS) {
22064     return rc;
22065   }
22066   if (response_size != response.size()) {
22067     return TPM_RC_SIZE;
22068   }
22069   if (response_code != TPM_RC_SUCCESS) {
22070     return response_code;
22071   }
22072   TPM_CC command_code = TPM_CC_PolicyOR;
22073   std::string command_code_bytes;
22074   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22075   if (rc != TPM_RC_SUCCESS) {
22076     return rc;
22077   }
22078   std::string authorization_section_bytes;
22079   if (tag == TPM_ST_SESSIONS) {
22080     UINT32 parameter_section_size = buffer.size();
22081     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22082     if (rc != TPM_RC_SUCCESS) {
22083       return rc;
22084     }
22085     if (parameter_section_size > buffer.size()) {
22086       return TPM_RC_INSUFFICIENT;
22087     }
22088     authorization_section_bytes = buffer.substr(parameter_section_size);
22089     // Keep the parameter section in |buffer|.
22090     buffer.erase(parameter_section_size);
22091   }
22092   std::unique_ptr<crypto::SecureHash> hash(
22093       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22094   hash->Update(response_code_bytes.data(), response_code_bytes.size());
22095   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22096   hash->Update(buffer.data(), buffer.size());
22097   std::string response_hash(32, 0);
22098   hash->Finish(std::data(response_hash), response_hash.size());
22099   if (tag == TPM_ST_SESSIONS) {
22100     if (!authorization_delegate)
22101       return TRUNKS_RC_AUTHORIZATION_FAILED;
22102     if (!authorization_delegate->CheckResponseAuthorization(
22103             response_hash, authorization_section_bytes)) {
22104       return TRUNKS_RC_AUTHORIZATION_FAILED;
22105     }
22106   }
22107   return TPM_RC_SUCCESS;
22108 }
22109 
PolicyORErrorCallback(Tpm::PolicyORResponse callback,TPM_RC response_code)22110 void PolicyORErrorCallback(Tpm::PolicyORResponse callback,
22111                            TPM_RC response_code) {
22112   VLOG(1) << __func__;
22113   std::move(callback).Run(response_code);
22114 }
22115 
PolicyORResponseParser(Tpm::PolicyORResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22116 void PolicyORResponseParser(Tpm::PolicyORResponse callback,
22117                             AuthorizationDelegate* authorization_delegate,
22118                             const std::string& response) {
22119   VLOG(1) << __func__;
22120   TPM_RC rc = Tpm::ParseResponse_PolicyOR(response, authorization_delegate);
22121   if (rc != TPM_RC_SUCCESS) {
22122     base::OnceCallback<void(TPM_RC)> error_reporter =
22123         base::BindOnce(PolicyORErrorCallback, std::move(callback));
22124     std::move(error_reporter).Run(rc);
22125     return;
22126   }
22127   std::move(callback).Run(rc);
22128 }
22129 
PolicyOR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,AuthorizationDelegate * authorization_delegate,PolicyORResponse callback)22130 void Tpm::PolicyOR(const TPMI_SH_POLICY& policy_session,
22131                    const std::string& policy_session_name,
22132                    const TPML_DIGEST& p_hash_list,
22133                    AuthorizationDelegate* authorization_delegate,
22134                    PolicyORResponse callback) {
22135   VLOG(1) << __func__;
22136   std::string command;
22137   TPM_RC rc =
22138       SerializeCommand_PolicyOR(policy_session, policy_session_name,
22139                                 p_hash_list, &command, authorization_delegate);
22140   if (rc != TPM_RC_SUCCESS) {
22141     base::OnceCallback<void(TPM_RC)> error_reporter =
22142         base::BindOnce(PolicyORErrorCallback, std::move(callback));
22143     std::move(error_reporter).Run(rc);
22144     return;
22145   }
22146   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22147       PolicyORResponseParser, std::move(callback), authorization_delegate);
22148   transceiver_->SendCommand(command, std::move(parser));
22149 }
22150 
PolicyORSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPML_DIGEST & p_hash_list,AuthorizationDelegate * authorization_delegate)22151 TPM_RC Tpm::PolicyORSync(const TPMI_SH_POLICY& policy_session,
22152                          const std::string& policy_session_name,
22153                          const TPML_DIGEST& p_hash_list,
22154                          AuthorizationDelegate* authorization_delegate) {
22155   VLOG(1) << __func__;
22156   std::string command;
22157   TPM_RC rc =
22158       SerializeCommand_PolicyOR(policy_session, policy_session_name,
22159                                 p_hash_list, &command, authorization_delegate);
22160   if (rc != TPM_RC_SUCCESS) {
22161     return rc;
22162   }
22163   std::string response = transceiver_->SendCommandAndWait(command);
22164   rc = ParseResponse_PolicyOR(response, authorization_delegate);
22165   return rc;
22166 }
22167 
SerializeCommand_PolicyPCR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & pcr_digest,const TPML_PCR_SELECTION & pcrs,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22168 TPM_RC Tpm::SerializeCommand_PolicyPCR(
22169     const TPMI_SH_POLICY& policy_session,
22170     const std::string& policy_session_name,
22171     const TPM2B_DIGEST& pcr_digest,
22172     const TPML_PCR_SELECTION& pcrs,
22173     std::string* serialized_command,
22174     AuthorizationDelegate* authorization_delegate) {
22175   VLOG(3) << __func__;
22176   TPM_RC rc = TPM_RC_SUCCESS;
22177   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22178   UINT32 command_size = 10;  // Header size.
22179   std::string handle_section_bytes;
22180   std::string parameter_section_bytes;
22181   TPM_CC command_code = TPM_CC_PolicyPCR;
22182   bool is_command_parameter_encryption_possible = true;
22183   bool is_response_parameter_encryption_possible = false;
22184   std::string command_code_bytes;
22185   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22186   if (rc != TPM_RC_SUCCESS) {
22187     return rc;
22188   }
22189   std::string policy_session_bytes;
22190   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22191   if (rc != TPM_RC_SUCCESS) {
22192     return rc;
22193   }
22194   std::string pcr_digest_bytes;
22195   rc = Serialize_TPM2B_DIGEST(pcr_digest, &pcr_digest_bytes);
22196   if (rc != TPM_RC_SUCCESS) {
22197     return rc;
22198   }
22199   std::string pcrs_bytes;
22200   rc = Serialize_TPML_PCR_SELECTION(pcrs, &pcrs_bytes);
22201   if (rc != TPM_RC_SUCCESS) {
22202     return rc;
22203   }
22204   if (authorization_delegate) {
22205     // Encrypt just the parameter data, not the size.
22206     std::string tmp = pcr_digest_bytes.substr(2);
22207     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22208       return TRUNKS_RC_ENCRYPTION_FAILED;
22209     }
22210     pcr_digest_bytes.replace(2, std::string::npos, tmp);
22211   }
22212   std::unique_ptr<crypto::SecureHash> hash(
22213       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22214   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22215   hash->Update(policy_session_name.data(), policy_session_name.size());
22216   handle_section_bytes += policy_session_bytes;
22217   command_size += policy_session_bytes.size();
22218   hash->Update(pcr_digest_bytes.data(), pcr_digest_bytes.size());
22219   parameter_section_bytes += pcr_digest_bytes;
22220   command_size += pcr_digest_bytes.size();
22221   hash->Update(pcrs_bytes.data(), pcrs_bytes.size());
22222   parameter_section_bytes += pcrs_bytes;
22223   command_size += pcrs_bytes.size();
22224   std::string command_hash(32, 0);
22225   hash->Finish(std::data(command_hash), command_hash.size());
22226   std::string authorization_section_bytes;
22227   std::string authorization_size_bytes;
22228   if (authorization_delegate) {
22229     if (!authorization_delegate->GetCommandAuthorization(
22230             command_hash, is_command_parameter_encryption_possible,
22231             is_response_parameter_encryption_possible,
22232             &authorization_section_bytes)) {
22233       return TRUNKS_RC_AUTHORIZATION_FAILED;
22234     }
22235     if (!authorization_section_bytes.empty()) {
22236       tag = TPM_ST_SESSIONS;
22237       std::string tmp;
22238       rc = Serialize_UINT32(authorization_section_bytes.size(),
22239                             &authorization_size_bytes);
22240       if (rc != TPM_RC_SUCCESS) {
22241         return rc;
22242       }
22243       command_size +=
22244           authorization_size_bytes.size() + authorization_section_bytes.size();
22245     }
22246   }
22247   std::string tag_bytes;
22248   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22249   if (rc != TPM_RC_SUCCESS) {
22250     return rc;
22251   }
22252   std::string command_size_bytes;
22253   rc = Serialize_UINT32(command_size, &command_size_bytes);
22254   if (rc != TPM_RC_SUCCESS) {
22255     return rc;
22256   }
22257   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22258                         handle_section_bytes + authorization_size_bytes +
22259                         authorization_section_bytes + parameter_section_bytes;
22260   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22261   VLOG(2) << "Command: "
22262           << base::HexEncode(serialized_command->data(),
22263                              serialized_command->size());
22264   return TPM_RC_SUCCESS;
22265 }
22266 
ParseResponse_PolicyPCR(const std::string & response,AuthorizationDelegate * authorization_delegate)22267 TPM_RC Tpm::ParseResponse_PolicyPCR(
22268     const std::string& response,
22269     AuthorizationDelegate* authorization_delegate) {
22270   VLOG(3) << __func__;
22271   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22272   TPM_RC rc = TPM_RC_SUCCESS;
22273   std::string buffer(response);
22274   TPM_ST tag;
22275   std::string tag_bytes;
22276   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22277   if (rc != TPM_RC_SUCCESS) {
22278     return rc;
22279   }
22280   UINT32 response_size;
22281   std::string response_size_bytes;
22282   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22283   if (rc != TPM_RC_SUCCESS) {
22284     return rc;
22285   }
22286   TPM_RC response_code;
22287   std::string response_code_bytes;
22288   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22289   if (rc != TPM_RC_SUCCESS) {
22290     return rc;
22291   }
22292   if (response_size != response.size()) {
22293     return TPM_RC_SIZE;
22294   }
22295   if (response_code != TPM_RC_SUCCESS) {
22296     return response_code;
22297   }
22298   TPM_CC command_code = TPM_CC_PolicyPCR;
22299   std::string command_code_bytes;
22300   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22301   if (rc != TPM_RC_SUCCESS) {
22302     return rc;
22303   }
22304   std::string authorization_section_bytes;
22305   if (tag == TPM_ST_SESSIONS) {
22306     UINT32 parameter_section_size = buffer.size();
22307     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22308     if (rc != TPM_RC_SUCCESS) {
22309       return rc;
22310     }
22311     if (parameter_section_size > buffer.size()) {
22312       return TPM_RC_INSUFFICIENT;
22313     }
22314     authorization_section_bytes = buffer.substr(parameter_section_size);
22315     // Keep the parameter section in |buffer|.
22316     buffer.erase(parameter_section_size);
22317   }
22318   std::unique_ptr<crypto::SecureHash> hash(
22319       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22320   hash->Update(response_code_bytes.data(), response_code_bytes.size());
22321   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22322   hash->Update(buffer.data(), buffer.size());
22323   std::string response_hash(32, 0);
22324   hash->Finish(std::data(response_hash), response_hash.size());
22325   if (tag == TPM_ST_SESSIONS) {
22326     if (!authorization_delegate)
22327       return TRUNKS_RC_AUTHORIZATION_FAILED;
22328     if (!authorization_delegate->CheckResponseAuthorization(
22329             response_hash, authorization_section_bytes)) {
22330       return TRUNKS_RC_AUTHORIZATION_FAILED;
22331     }
22332   }
22333   return TPM_RC_SUCCESS;
22334 }
22335 
PolicyPCRErrorCallback(Tpm::PolicyPCRResponse callback,TPM_RC response_code)22336 void PolicyPCRErrorCallback(Tpm::PolicyPCRResponse callback,
22337                             TPM_RC response_code) {
22338   VLOG(1) << __func__;
22339   std::move(callback).Run(response_code);
22340 }
22341 
PolicyPCRResponseParser(Tpm::PolicyPCRResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22342 void PolicyPCRResponseParser(Tpm::PolicyPCRResponse callback,
22343                              AuthorizationDelegate* authorization_delegate,
22344                              const std::string& response) {
22345   VLOG(1) << __func__;
22346   TPM_RC rc = Tpm::ParseResponse_PolicyPCR(response, authorization_delegate);
22347   if (rc != TPM_RC_SUCCESS) {
22348     base::OnceCallback<void(TPM_RC)> error_reporter =
22349         base::BindOnce(PolicyPCRErrorCallback, std::move(callback));
22350     std::move(error_reporter).Run(rc);
22351     return;
22352   }
22353   std::move(callback).Run(rc);
22354 }
22355 
PolicyPCR(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & pcr_digest,const TPML_PCR_SELECTION & pcrs,AuthorizationDelegate * authorization_delegate,PolicyPCRResponse callback)22356 void Tpm::PolicyPCR(const TPMI_SH_POLICY& policy_session,
22357                     const std::string& policy_session_name,
22358                     const TPM2B_DIGEST& pcr_digest,
22359                     const TPML_PCR_SELECTION& pcrs,
22360                     AuthorizationDelegate* authorization_delegate,
22361                     PolicyPCRResponse callback) {
22362   VLOG(1) << __func__;
22363   std::string command;
22364   TPM_RC rc = SerializeCommand_PolicyPCR(policy_session, policy_session_name,
22365                                          pcr_digest, pcrs, &command,
22366                                          authorization_delegate);
22367   if (rc != TPM_RC_SUCCESS) {
22368     base::OnceCallback<void(TPM_RC)> error_reporter =
22369         base::BindOnce(PolicyPCRErrorCallback, std::move(callback));
22370     std::move(error_reporter).Run(rc);
22371     return;
22372   }
22373   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22374       PolicyPCRResponseParser, std::move(callback), authorization_delegate);
22375   transceiver_->SendCommand(command, std::move(parser));
22376 }
22377 
PolicyPCRSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & pcr_digest,const TPML_PCR_SELECTION & pcrs,AuthorizationDelegate * authorization_delegate)22378 TPM_RC Tpm::PolicyPCRSync(const TPMI_SH_POLICY& policy_session,
22379                           const std::string& policy_session_name,
22380                           const TPM2B_DIGEST& pcr_digest,
22381                           const TPML_PCR_SELECTION& pcrs,
22382                           AuthorizationDelegate* authorization_delegate) {
22383   VLOG(1) << __func__;
22384   std::string command;
22385   TPM_RC rc = SerializeCommand_PolicyPCR(policy_session, policy_session_name,
22386                                          pcr_digest, pcrs, &command,
22387                                          authorization_delegate);
22388   if (rc != TPM_RC_SUCCESS) {
22389     return rc;
22390   }
22391   std::string response = transceiver_->SendCommandAndWait(command);
22392   rc = ParseResponse_PolicyPCR(response, authorization_delegate);
22393   return rc;
22394 }
22395 
SerializeCommand_PolicyLocality(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22396 TPM_RC Tpm::SerializeCommand_PolicyLocality(
22397     const TPMI_SH_POLICY& policy_session,
22398     const std::string& policy_session_name,
22399     const TPMA_LOCALITY& locality,
22400     std::string* serialized_command,
22401     AuthorizationDelegate* authorization_delegate) {
22402   VLOG(3) << __func__;
22403   TPM_RC rc = TPM_RC_SUCCESS;
22404   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22405   UINT32 command_size = 10;  // Header size.
22406   std::string handle_section_bytes;
22407   std::string parameter_section_bytes;
22408   TPM_CC command_code = TPM_CC_PolicyLocality;
22409   bool is_command_parameter_encryption_possible = false;
22410   bool is_response_parameter_encryption_possible = false;
22411   std::string command_code_bytes;
22412   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22413   if (rc != TPM_RC_SUCCESS) {
22414     return rc;
22415   }
22416   std::string policy_session_bytes;
22417   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22418   if (rc != TPM_RC_SUCCESS) {
22419     return rc;
22420   }
22421   std::string locality_bytes;
22422   rc = Serialize_TPMA_LOCALITY(locality, &locality_bytes);
22423   if (rc != TPM_RC_SUCCESS) {
22424     return rc;
22425   }
22426   std::unique_ptr<crypto::SecureHash> hash(
22427       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22428   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22429   hash->Update(policy_session_name.data(), policy_session_name.size());
22430   handle_section_bytes += policy_session_bytes;
22431   command_size += policy_session_bytes.size();
22432   hash->Update(locality_bytes.data(), locality_bytes.size());
22433   parameter_section_bytes += locality_bytes;
22434   command_size += locality_bytes.size();
22435   std::string command_hash(32, 0);
22436   hash->Finish(std::data(command_hash), command_hash.size());
22437   std::string authorization_section_bytes;
22438   std::string authorization_size_bytes;
22439   if (authorization_delegate) {
22440     if (!authorization_delegate->GetCommandAuthorization(
22441             command_hash, is_command_parameter_encryption_possible,
22442             is_response_parameter_encryption_possible,
22443             &authorization_section_bytes)) {
22444       return TRUNKS_RC_AUTHORIZATION_FAILED;
22445     }
22446     if (!authorization_section_bytes.empty()) {
22447       tag = TPM_ST_SESSIONS;
22448       std::string tmp;
22449       rc = Serialize_UINT32(authorization_section_bytes.size(),
22450                             &authorization_size_bytes);
22451       if (rc != TPM_RC_SUCCESS) {
22452         return rc;
22453       }
22454       command_size +=
22455           authorization_size_bytes.size() + authorization_section_bytes.size();
22456     }
22457   }
22458   std::string tag_bytes;
22459   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22460   if (rc != TPM_RC_SUCCESS) {
22461     return rc;
22462   }
22463   std::string command_size_bytes;
22464   rc = Serialize_UINT32(command_size, &command_size_bytes);
22465   if (rc != TPM_RC_SUCCESS) {
22466     return rc;
22467   }
22468   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22469                         handle_section_bytes + authorization_size_bytes +
22470                         authorization_section_bytes + parameter_section_bytes;
22471   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22472   VLOG(2) << "Command: "
22473           << base::HexEncode(serialized_command->data(),
22474                              serialized_command->size());
22475   return TPM_RC_SUCCESS;
22476 }
22477 
ParseResponse_PolicyLocality(const std::string & response,AuthorizationDelegate * authorization_delegate)22478 TPM_RC Tpm::ParseResponse_PolicyLocality(
22479     const std::string& response,
22480     AuthorizationDelegate* authorization_delegate) {
22481   VLOG(3) << __func__;
22482   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22483   TPM_RC rc = TPM_RC_SUCCESS;
22484   std::string buffer(response);
22485   TPM_ST tag;
22486   std::string tag_bytes;
22487   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22488   if (rc != TPM_RC_SUCCESS) {
22489     return rc;
22490   }
22491   UINT32 response_size;
22492   std::string response_size_bytes;
22493   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22494   if (rc != TPM_RC_SUCCESS) {
22495     return rc;
22496   }
22497   TPM_RC response_code;
22498   std::string response_code_bytes;
22499   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22500   if (rc != TPM_RC_SUCCESS) {
22501     return rc;
22502   }
22503   if (response_size != response.size()) {
22504     return TPM_RC_SIZE;
22505   }
22506   if (response_code != TPM_RC_SUCCESS) {
22507     return response_code;
22508   }
22509   TPM_CC command_code = TPM_CC_PolicyLocality;
22510   std::string command_code_bytes;
22511   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22512   if (rc != TPM_RC_SUCCESS) {
22513     return rc;
22514   }
22515   std::string authorization_section_bytes;
22516   if (tag == TPM_ST_SESSIONS) {
22517     UINT32 parameter_section_size = buffer.size();
22518     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22519     if (rc != TPM_RC_SUCCESS) {
22520       return rc;
22521     }
22522     if (parameter_section_size > buffer.size()) {
22523       return TPM_RC_INSUFFICIENT;
22524     }
22525     authorization_section_bytes = buffer.substr(parameter_section_size);
22526     // Keep the parameter section in |buffer|.
22527     buffer.erase(parameter_section_size);
22528   }
22529   std::unique_ptr<crypto::SecureHash> hash(
22530       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22531   hash->Update(response_code_bytes.data(), response_code_bytes.size());
22532   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22533   hash->Update(buffer.data(), buffer.size());
22534   std::string response_hash(32, 0);
22535   hash->Finish(std::data(response_hash), response_hash.size());
22536   if (tag == TPM_ST_SESSIONS) {
22537     if (!authorization_delegate)
22538       return TRUNKS_RC_AUTHORIZATION_FAILED;
22539     if (!authorization_delegate->CheckResponseAuthorization(
22540             response_hash, authorization_section_bytes)) {
22541       return TRUNKS_RC_AUTHORIZATION_FAILED;
22542     }
22543   }
22544   return TPM_RC_SUCCESS;
22545 }
22546 
PolicyLocalityErrorCallback(Tpm::PolicyLocalityResponse callback,TPM_RC response_code)22547 void PolicyLocalityErrorCallback(Tpm::PolicyLocalityResponse callback,
22548                                  TPM_RC response_code) {
22549   VLOG(1) << __func__;
22550   std::move(callback).Run(response_code);
22551 }
22552 
PolicyLocalityResponseParser(Tpm::PolicyLocalityResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22553 void PolicyLocalityResponseParser(Tpm::PolicyLocalityResponse callback,
22554                                   AuthorizationDelegate* authorization_delegate,
22555                                   const std::string& response) {
22556   VLOG(1) << __func__;
22557   TPM_RC rc =
22558       Tpm::ParseResponse_PolicyLocality(response, authorization_delegate);
22559   if (rc != TPM_RC_SUCCESS) {
22560     base::OnceCallback<void(TPM_RC)> error_reporter =
22561         base::BindOnce(PolicyLocalityErrorCallback, std::move(callback));
22562     std::move(error_reporter).Run(rc);
22563     return;
22564   }
22565   std::move(callback).Run(rc);
22566 }
22567 
PolicyLocality(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,AuthorizationDelegate * authorization_delegate,PolicyLocalityResponse callback)22568 void Tpm::PolicyLocality(const TPMI_SH_POLICY& policy_session,
22569                          const std::string& policy_session_name,
22570                          const TPMA_LOCALITY& locality,
22571                          AuthorizationDelegate* authorization_delegate,
22572                          PolicyLocalityResponse callback) {
22573   VLOG(1) << __func__;
22574   std::string command;
22575   TPM_RC rc = SerializeCommand_PolicyLocality(policy_session,
22576                                               policy_session_name, locality,
22577                                               &command, authorization_delegate);
22578   if (rc != TPM_RC_SUCCESS) {
22579     base::OnceCallback<void(TPM_RC)> error_reporter =
22580         base::BindOnce(PolicyLocalityErrorCallback, std::move(callback));
22581     std::move(error_reporter).Run(rc);
22582     return;
22583   }
22584   base::OnceCallback<void(const std::string&)> parser =
22585       base::BindOnce(PolicyLocalityResponseParser, std::move(callback),
22586                      authorization_delegate);
22587   transceiver_->SendCommand(command, std::move(parser));
22588 }
22589 
PolicyLocalitySync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMA_LOCALITY & locality,AuthorizationDelegate * authorization_delegate)22590 TPM_RC Tpm::PolicyLocalitySync(const TPMI_SH_POLICY& policy_session,
22591                                const std::string& policy_session_name,
22592                                const TPMA_LOCALITY& locality,
22593                                AuthorizationDelegate* authorization_delegate) {
22594   VLOG(1) << __func__;
22595   std::string command;
22596   TPM_RC rc = SerializeCommand_PolicyLocality(policy_session,
22597                                               policy_session_name, locality,
22598                                               &command, authorization_delegate);
22599   if (rc != TPM_RC_SUCCESS) {
22600     return rc;
22601   }
22602   std::string response = transceiver_->SendCommandAndWait(command);
22603   rc = ParseResponse_PolicyLocality(response, authorization_delegate);
22604   return rc;
22605 }
22606 
SerializeCommand_PolicyNV(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22607 TPM_RC Tpm::SerializeCommand_PolicyNV(
22608     const TPMI_RH_NV_AUTH& auth_handle,
22609     const std::string& auth_handle_name,
22610     const TPMI_RH_NV_INDEX& nv_index,
22611     const std::string& nv_index_name,
22612     const TPMI_SH_POLICY& policy_session,
22613     const std::string& policy_session_name,
22614     const TPM2B_OPERAND& operand_b,
22615     const UINT16& offset,
22616     const TPM_EO& operation,
22617     std::string* serialized_command,
22618     AuthorizationDelegate* authorization_delegate) {
22619   VLOG(3) << __func__;
22620   TPM_RC rc = TPM_RC_SUCCESS;
22621   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22622   UINT32 command_size = 10;  // Header size.
22623   std::string handle_section_bytes;
22624   std::string parameter_section_bytes;
22625   TPM_CC command_code = TPM_CC_PolicyNV;
22626   bool is_command_parameter_encryption_possible = true;
22627   bool is_response_parameter_encryption_possible = false;
22628   std::string command_code_bytes;
22629   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22630   if (rc != TPM_RC_SUCCESS) {
22631     return rc;
22632   }
22633   std::string auth_handle_bytes;
22634   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
22635   if (rc != TPM_RC_SUCCESS) {
22636     return rc;
22637   }
22638   std::string nv_index_bytes;
22639   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
22640   if (rc != TPM_RC_SUCCESS) {
22641     return rc;
22642   }
22643   std::string policy_session_bytes;
22644   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22645   if (rc != TPM_RC_SUCCESS) {
22646     return rc;
22647   }
22648   std::string operand_b_bytes;
22649   rc = Serialize_TPM2B_OPERAND(operand_b, &operand_b_bytes);
22650   if (rc != TPM_RC_SUCCESS) {
22651     return rc;
22652   }
22653   std::string offset_bytes;
22654   rc = Serialize_UINT16(offset, &offset_bytes);
22655   if (rc != TPM_RC_SUCCESS) {
22656     return rc;
22657   }
22658   std::string operation_bytes;
22659   rc = Serialize_TPM_EO(operation, &operation_bytes);
22660   if (rc != TPM_RC_SUCCESS) {
22661     return rc;
22662   }
22663   if (authorization_delegate) {
22664     // Encrypt just the parameter data, not the size.
22665     std::string tmp = operand_b_bytes.substr(2);
22666     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22667       return TRUNKS_RC_ENCRYPTION_FAILED;
22668     }
22669     operand_b_bytes.replace(2, std::string::npos, tmp);
22670   }
22671   std::unique_ptr<crypto::SecureHash> hash(
22672       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22673   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22674   hash->Update(auth_handle_name.data(), auth_handle_name.size());
22675   handle_section_bytes += auth_handle_bytes;
22676   command_size += auth_handle_bytes.size();
22677   hash->Update(nv_index_name.data(), nv_index_name.size());
22678   handle_section_bytes += nv_index_bytes;
22679   command_size += nv_index_bytes.size();
22680   hash->Update(policy_session_name.data(), policy_session_name.size());
22681   handle_section_bytes += policy_session_bytes;
22682   command_size += policy_session_bytes.size();
22683   hash->Update(operand_b_bytes.data(), operand_b_bytes.size());
22684   parameter_section_bytes += operand_b_bytes;
22685   command_size += operand_b_bytes.size();
22686   hash->Update(offset_bytes.data(), offset_bytes.size());
22687   parameter_section_bytes += offset_bytes;
22688   command_size += offset_bytes.size();
22689   hash->Update(operation_bytes.data(), operation_bytes.size());
22690   parameter_section_bytes += operation_bytes;
22691   command_size += operation_bytes.size();
22692   std::string command_hash(32, 0);
22693   hash->Finish(std::data(command_hash), command_hash.size());
22694   std::string authorization_section_bytes;
22695   std::string authorization_size_bytes;
22696   if (authorization_delegate) {
22697     if (!authorization_delegate->GetCommandAuthorization(
22698             command_hash, is_command_parameter_encryption_possible,
22699             is_response_parameter_encryption_possible,
22700             &authorization_section_bytes)) {
22701       return TRUNKS_RC_AUTHORIZATION_FAILED;
22702     }
22703     if (!authorization_section_bytes.empty()) {
22704       tag = TPM_ST_SESSIONS;
22705       std::string tmp;
22706       rc = Serialize_UINT32(authorization_section_bytes.size(),
22707                             &authorization_size_bytes);
22708       if (rc != TPM_RC_SUCCESS) {
22709         return rc;
22710       }
22711       command_size +=
22712           authorization_size_bytes.size() + authorization_section_bytes.size();
22713     }
22714   }
22715   std::string tag_bytes;
22716   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22717   if (rc != TPM_RC_SUCCESS) {
22718     return rc;
22719   }
22720   std::string command_size_bytes;
22721   rc = Serialize_UINT32(command_size, &command_size_bytes);
22722   if (rc != TPM_RC_SUCCESS) {
22723     return rc;
22724   }
22725   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22726                         handle_section_bytes + authorization_size_bytes +
22727                         authorization_section_bytes + parameter_section_bytes;
22728   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22729   VLOG(2) << "Command: "
22730           << base::HexEncode(serialized_command->data(),
22731                              serialized_command->size());
22732   return TPM_RC_SUCCESS;
22733 }
22734 
ParseResponse_PolicyNV(const std::string & response,AuthorizationDelegate * authorization_delegate)22735 TPM_RC Tpm::ParseResponse_PolicyNV(
22736     const std::string& response,
22737     AuthorizationDelegate* authorization_delegate) {
22738   VLOG(3) << __func__;
22739   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22740   TPM_RC rc = TPM_RC_SUCCESS;
22741   std::string buffer(response);
22742   TPM_ST tag;
22743   std::string tag_bytes;
22744   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22745   if (rc != TPM_RC_SUCCESS) {
22746     return rc;
22747   }
22748   UINT32 response_size;
22749   std::string response_size_bytes;
22750   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
22751   if (rc != TPM_RC_SUCCESS) {
22752     return rc;
22753   }
22754   TPM_RC response_code;
22755   std::string response_code_bytes;
22756   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
22757   if (rc != TPM_RC_SUCCESS) {
22758     return rc;
22759   }
22760   if (response_size != response.size()) {
22761     return TPM_RC_SIZE;
22762   }
22763   if (response_code != TPM_RC_SUCCESS) {
22764     return response_code;
22765   }
22766   TPM_CC command_code = TPM_CC_PolicyNV;
22767   std::string command_code_bytes;
22768   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22769   if (rc != TPM_RC_SUCCESS) {
22770     return rc;
22771   }
22772   std::string authorization_section_bytes;
22773   if (tag == TPM_ST_SESSIONS) {
22774     UINT32 parameter_section_size = buffer.size();
22775     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
22776     if (rc != TPM_RC_SUCCESS) {
22777       return rc;
22778     }
22779     if (parameter_section_size > buffer.size()) {
22780       return TPM_RC_INSUFFICIENT;
22781     }
22782     authorization_section_bytes = buffer.substr(parameter_section_size);
22783     // Keep the parameter section in |buffer|.
22784     buffer.erase(parameter_section_size);
22785   }
22786   std::unique_ptr<crypto::SecureHash> hash(
22787       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22788   hash->Update(response_code_bytes.data(), response_code_bytes.size());
22789   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22790   hash->Update(buffer.data(), buffer.size());
22791   std::string response_hash(32, 0);
22792   hash->Finish(std::data(response_hash), response_hash.size());
22793   if (tag == TPM_ST_SESSIONS) {
22794     if (!authorization_delegate)
22795       return TRUNKS_RC_AUTHORIZATION_FAILED;
22796     if (!authorization_delegate->CheckResponseAuthorization(
22797             response_hash, authorization_section_bytes)) {
22798       return TRUNKS_RC_AUTHORIZATION_FAILED;
22799     }
22800   }
22801   return TPM_RC_SUCCESS;
22802 }
22803 
PolicyNVErrorCallback(Tpm::PolicyNVResponse callback,TPM_RC response_code)22804 void PolicyNVErrorCallback(Tpm::PolicyNVResponse callback,
22805                            TPM_RC response_code) {
22806   VLOG(1) << __func__;
22807   std::move(callback).Run(response_code);
22808 }
22809 
PolicyNVResponseParser(Tpm::PolicyNVResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)22810 void PolicyNVResponseParser(Tpm::PolicyNVResponse callback,
22811                             AuthorizationDelegate* authorization_delegate,
22812                             const std::string& response) {
22813   VLOG(1) << __func__;
22814   TPM_RC rc = Tpm::ParseResponse_PolicyNV(response, authorization_delegate);
22815   if (rc != TPM_RC_SUCCESS) {
22816     base::OnceCallback<void(TPM_RC)> error_reporter =
22817         base::BindOnce(PolicyNVErrorCallback, std::move(callback));
22818     std::move(error_reporter).Run(rc);
22819     return;
22820   }
22821   std::move(callback).Run(rc);
22822 }
22823 
PolicyNV(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate,PolicyNVResponse callback)22824 void Tpm::PolicyNV(const TPMI_RH_NV_AUTH& auth_handle,
22825                    const std::string& auth_handle_name,
22826                    const TPMI_RH_NV_INDEX& nv_index,
22827                    const std::string& nv_index_name,
22828                    const TPMI_SH_POLICY& policy_session,
22829                    const std::string& policy_session_name,
22830                    const TPM2B_OPERAND& operand_b,
22831                    const UINT16& offset,
22832                    const TPM_EO& operation,
22833                    AuthorizationDelegate* authorization_delegate,
22834                    PolicyNVResponse callback) {
22835   VLOG(1) << __func__;
22836   std::string command;
22837   TPM_RC rc = SerializeCommand_PolicyNV(
22838       auth_handle, auth_handle_name, nv_index, nv_index_name, policy_session,
22839       policy_session_name, operand_b, offset, operation, &command,
22840       authorization_delegate);
22841   if (rc != TPM_RC_SUCCESS) {
22842     base::OnceCallback<void(TPM_RC)> error_reporter =
22843         base::BindOnce(PolicyNVErrorCallback, std::move(callback));
22844     std::move(error_reporter).Run(rc);
22845     return;
22846   }
22847   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
22848       PolicyNVResponseParser, std::move(callback), authorization_delegate);
22849   transceiver_->SendCommand(command, std::move(parser));
22850 }
22851 
PolicyNVSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate)22852 TPM_RC Tpm::PolicyNVSync(const TPMI_RH_NV_AUTH& auth_handle,
22853                          const std::string& auth_handle_name,
22854                          const TPMI_RH_NV_INDEX& nv_index,
22855                          const std::string& nv_index_name,
22856                          const TPMI_SH_POLICY& policy_session,
22857                          const std::string& policy_session_name,
22858                          const TPM2B_OPERAND& operand_b,
22859                          const UINT16& offset,
22860                          const TPM_EO& operation,
22861                          AuthorizationDelegate* authorization_delegate) {
22862   VLOG(1) << __func__;
22863   std::string command;
22864   TPM_RC rc = SerializeCommand_PolicyNV(
22865       auth_handle, auth_handle_name, nv_index, nv_index_name, policy_session,
22866       policy_session_name, operand_b, offset, operation, &command,
22867       authorization_delegate);
22868   if (rc != TPM_RC_SUCCESS) {
22869     return rc;
22870   }
22871   std::string response = transceiver_->SendCommandAndWait(command);
22872   rc = ParseResponse_PolicyNV(response, authorization_delegate);
22873   return rc;
22874 }
22875 
SerializeCommand_PolicyCounterTimer(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)22876 TPM_RC Tpm::SerializeCommand_PolicyCounterTimer(
22877     const TPMI_SH_POLICY& policy_session,
22878     const std::string& policy_session_name,
22879     const TPM2B_OPERAND& operand_b,
22880     const UINT16& offset,
22881     const TPM_EO& operation,
22882     std::string* serialized_command,
22883     AuthorizationDelegate* authorization_delegate) {
22884   VLOG(3) << __func__;
22885   TPM_RC rc = TPM_RC_SUCCESS;
22886   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
22887   UINT32 command_size = 10;  // Header size.
22888   std::string handle_section_bytes;
22889   std::string parameter_section_bytes;
22890   TPM_CC command_code = TPM_CC_PolicyCounterTimer;
22891   bool is_command_parameter_encryption_possible = true;
22892   bool is_response_parameter_encryption_possible = false;
22893   std::string command_code_bytes;
22894   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
22895   if (rc != TPM_RC_SUCCESS) {
22896     return rc;
22897   }
22898   std::string policy_session_bytes;
22899   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
22900   if (rc != TPM_RC_SUCCESS) {
22901     return rc;
22902   }
22903   std::string operand_b_bytes;
22904   rc = Serialize_TPM2B_OPERAND(operand_b, &operand_b_bytes);
22905   if (rc != TPM_RC_SUCCESS) {
22906     return rc;
22907   }
22908   std::string offset_bytes;
22909   rc = Serialize_UINT16(offset, &offset_bytes);
22910   if (rc != TPM_RC_SUCCESS) {
22911     return rc;
22912   }
22913   std::string operation_bytes;
22914   rc = Serialize_TPM_EO(operation, &operation_bytes);
22915   if (rc != TPM_RC_SUCCESS) {
22916     return rc;
22917   }
22918   if (authorization_delegate) {
22919     // Encrypt just the parameter data, not the size.
22920     std::string tmp = operand_b_bytes.substr(2);
22921     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
22922       return TRUNKS_RC_ENCRYPTION_FAILED;
22923     }
22924     operand_b_bytes.replace(2, std::string::npos, tmp);
22925   }
22926   std::unique_ptr<crypto::SecureHash> hash(
22927       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
22928   hash->Update(command_code_bytes.data(), command_code_bytes.size());
22929   hash->Update(policy_session_name.data(), policy_session_name.size());
22930   handle_section_bytes += policy_session_bytes;
22931   command_size += policy_session_bytes.size();
22932   hash->Update(operand_b_bytes.data(), operand_b_bytes.size());
22933   parameter_section_bytes += operand_b_bytes;
22934   command_size += operand_b_bytes.size();
22935   hash->Update(offset_bytes.data(), offset_bytes.size());
22936   parameter_section_bytes += offset_bytes;
22937   command_size += offset_bytes.size();
22938   hash->Update(operation_bytes.data(), operation_bytes.size());
22939   parameter_section_bytes += operation_bytes;
22940   command_size += operation_bytes.size();
22941   std::string command_hash(32, 0);
22942   hash->Finish(std::data(command_hash), command_hash.size());
22943   std::string authorization_section_bytes;
22944   std::string authorization_size_bytes;
22945   if (authorization_delegate) {
22946     if (!authorization_delegate->GetCommandAuthorization(
22947             command_hash, is_command_parameter_encryption_possible,
22948             is_response_parameter_encryption_possible,
22949             &authorization_section_bytes)) {
22950       return TRUNKS_RC_AUTHORIZATION_FAILED;
22951     }
22952     if (!authorization_section_bytes.empty()) {
22953       tag = TPM_ST_SESSIONS;
22954       std::string tmp;
22955       rc = Serialize_UINT32(authorization_section_bytes.size(),
22956                             &authorization_size_bytes);
22957       if (rc != TPM_RC_SUCCESS) {
22958         return rc;
22959       }
22960       command_size +=
22961           authorization_size_bytes.size() + authorization_section_bytes.size();
22962     }
22963   }
22964   std::string tag_bytes;
22965   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
22966   if (rc != TPM_RC_SUCCESS) {
22967     return rc;
22968   }
22969   std::string command_size_bytes;
22970   rc = Serialize_UINT32(command_size, &command_size_bytes);
22971   if (rc != TPM_RC_SUCCESS) {
22972     return rc;
22973   }
22974   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
22975                         handle_section_bytes + authorization_size_bytes +
22976                         authorization_section_bytes + parameter_section_bytes;
22977   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
22978   VLOG(2) << "Command: "
22979           << base::HexEncode(serialized_command->data(),
22980                              serialized_command->size());
22981   return TPM_RC_SUCCESS;
22982 }
22983 
ParseResponse_PolicyCounterTimer(const std::string & response,AuthorizationDelegate * authorization_delegate)22984 TPM_RC Tpm::ParseResponse_PolicyCounterTimer(
22985     const std::string& response,
22986     AuthorizationDelegate* authorization_delegate) {
22987   VLOG(3) << __func__;
22988   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
22989   TPM_RC rc = TPM_RC_SUCCESS;
22990   std::string buffer(response);
22991   TPM_ST tag;
22992   std::string tag_bytes;
22993   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
22994   if (rc != TPM_RC_SUCCESS) {
22995     return rc;
22996   }
22997   UINT32 response_size;
22998   std::string response_size_bytes;
22999   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23000   if (rc != TPM_RC_SUCCESS) {
23001     return rc;
23002   }
23003   TPM_RC response_code;
23004   std::string response_code_bytes;
23005   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23006   if (rc != TPM_RC_SUCCESS) {
23007     return rc;
23008   }
23009   if (response_size != response.size()) {
23010     return TPM_RC_SIZE;
23011   }
23012   if (response_code != TPM_RC_SUCCESS) {
23013     return response_code;
23014   }
23015   TPM_CC command_code = TPM_CC_PolicyCounterTimer;
23016   std::string command_code_bytes;
23017   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23018   if (rc != TPM_RC_SUCCESS) {
23019     return rc;
23020   }
23021   std::string authorization_section_bytes;
23022   if (tag == TPM_ST_SESSIONS) {
23023     UINT32 parameter_section_size = buffer.size();
23024     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23025     if (rc != TPM_RC_SUCCESS) {
23026       return rc;
23027     }
23028     if (parameter_section_size > buffer.size()) {
23029       return TPM_RC_INSUFFICIENT;
23030     }
23031     authorization_section_bytes = buffer.substr(parameter_section_size);
23032     // Keep the parameter section in |buffer|.
23033     buffer.erase(parameter_section_size);
23034   }
23035   std::unique_ptr<crypto::SecureHash> hash(
23036       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23037   hash->Update(response_code_bytes.data(), response_code_bytes.size());
23038   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23039   hash->Update(buffer.data(), buffer.size());
23040   std::string response_hash(32, 0);
23041   hash->Finish(std::data(response_hash), response_hash.size());
23042   if (tag == TPM_ST_SESSIONS) {
23043     if (!authorization_delegate)
23044       return TRUNKS_RC_AUTHORIZATION_FAILED;
23045     if (!authorization_delegate->CheckResponseAuthorization(
23046             response_hash, authorization_section_bytes)) {
23047       return TRUNKS_RC_AUTHORIZATION_FAILED;
23048     }
23049   }
23050   return TPM_RC_SUCCESS;
23051 }
23052 
PolicyCounterTimerErrorCallback(Tpm::PolicyCounterTimerResponse callback,TPM_RC response_code)23053 void PolicyCounterTimerErrorCallback(Tpm::PolicyCounterTimerResponse callback,
23054                                      TPM_RC response_code) {
23055   VLOG(1) << __func__;
23056   std::move(callback).Run(response_code);
23057 }
23058 
PolicyCounterTimerResponseParser(Tpm::PolicyCounterTimerResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23059 void PolicyCounterTimerResponseParser(
23060     Tpm::PolicyCounterTimerResponse callback,
23061     AuthorizationDelegate* authorization_delegate,
23062     const std::string& response) {
23063   VLOG(1) << __func__;
23064   TPM_RC rc =
23065       Tpm::ParseResponse_PolicyCounterTimer(response, authorization_delegate);
23066   if (rc != TPM_RC_SUCCESS) {
23067     base::OnceCallback<void(TPM_RC)> error_reporter =
23068         base::BindOnce(PolicyCounterTimerErrorCallback, std::move(callback));
23069     std::move(error_reporter).Run(rc);
23070     return;
23071   }
23072   std::move(callback).Run(rc);
23073 }
23074 
PolicyCounterTimer(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate,PolicyCounterTimerResponse callback)23075 void Tpm::PolicyCounterTimer(const TPMI_SH_POLICY& policy_session,
23076                              const std::string& policy_session_name,
23077                              const TPM2B_OPERAND& operand_b,
23078                              const UINT16& offset,
23079                              const TPM_EO& operation,
23080                              AuthorizationDelegate* authorization_delegate,
23081                              PolicyCounterTimerResponse callback) {
23082   VLOG(1) << __func__;
23083   std::string command;
23084   TPM_RC rc = SerializeCommand_PolicyCounterTimer(
23085       policy_session, policy_session_name, operand_b, offset, operation,
23086       &command, authorization_delegate);
23087   if (rc != TPM_RC_SUCCESS) {
23088     base::OnceCallback<void(TPM_RC)> error_reporter =
23089         base::BindOnce(PolicyCounterTimerErrorCallback, std::move(callback));
23090     std::move(error_reporter).Run(rc);
23091     return;
23092   }
23093   base::OnceCallback<void(const std::string&)> parser =
23094       base::BindOnce(PolicyCounterTimerResponseParser, std::move(callback),
23095                      authorization_delegate);
23096   transceiver_->SendCommand(command, std::move(parser));
23097 }
23098 
PolicyCounterTimerSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_OPERAND & operand_b,const UINT16 & offset,const TPM_EO & operation,AuthorizationDelegate * authorization_delegate)23099 TPM_RC Tpm::PolicyCounterTimerSync(
23100     const TPMI_SH_POLICY& policy_session,
23101     const std::string& policy_session_name,
23102     const TPM2B_OPERAND& operand_b,
23103     const UINT16& offset,
23104     const TPM_EO& operation,
23105     AuthorizationDelegate* authorization_delegate) {
23106   VLOG(1) << __func__;
23107   std::string command;
23108   TPM_RC rc = SerializeCommand_PolicyCounterTimer(
23109       policy_session, policy_session_name, operand_b, offset, operation,
23110       &command, authorization_delegate);
23111   if (rc != TPM_RC_SUCCESS) {
23112     return rc;
23113   }
23114   std::string response = transceiver_->SendCommandAndWait(command);
23115   rc = ParseResponse_PolicyCounterTimer(response, authorization_delegate);
23116   return rc;
23117 }
23118 
SerializeCommand_PolicyCommandCode(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23119 TPM_RC Tpm::SerializeCommand_PolicyCommandCode(
23120     const TPMI_SH_POLICY& policy_session,
23121     const std::string& policy_session_name,
23122     const TPM_CC& code,
23123     std::string* serialized_command,
23124     AuthorizationDelegate* authorization_delegate) {
23125   VLOG(3) << __func__;
23126   TPM_RC rc = TPM_RC_SUCCESS;
23127   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23128   UINT32 command_size = 10;  // Header size.
23129   std::string handle_section_bytes;
23130   std::string parameter_section_bytes;
23131   TPM_CC command_code = TPM_CC_PolicyCommandCode;
23132   bool is_command_parameter_encryption_possible = false;
23133   bool is_response_parameter_encryption_possible = false;
23134   std::string command_code_bytes;
23135   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23136   if (rc != TPM_RC_SUCCESS) {
23137     return rc;
23138   }
23139   std::string policy_session_bytes;
23140   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23141   if (rc != TPM_RC_SUCCESS) {
23142     return rc;
23143   }
23144   std::string code_bytes;
23145   rc = Serialize_TPM_CC(code, &code_bytes);
23146   if (rc != TPM_RC_SUCCESS) {
23147     return rc;
23148   }
23149   std::unique_ptr<crypto::SecureHash> hash(
23150       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23151   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23152   hash->Update(policy_session_name.data(), policy_session_name.size());
23153   handle_section_bytes += policy_session_bytes;
23154   command_size += policy_session_bytes.size();
23155   hash->Update(code_bytes.data(), code_bytes.size());
23156   parameter_section_bytes += code_bytes;
23157   command_size += code_bytes.size();
23158   std::string command_hash(32, 0);
23159   hash->Finish(std::data(command_hash), command_hash.size());
23160   std::string authorization_section_bytes;
23161   std::string authorization_size_bytes;
23162   if (authorization_delegate) {
23163     if (!authorization_delegate->GetCommandAuthorization(
23164             command_hash, is_command_parameter_encryption_possible,
23165             is_response_parameter_encryption_possible,
23166             &authorization_section_bytes)) {
23167       return TRUNKS_RC_AUTHORIZATION_FAILED;
23168     }
23169     if (!authorization_section_bytes.empty()) {
23170       tag = TPM_ST_SESSIONS;
23171       std::string tmp;
23172       rc = Serialize_UINT32(authorization_section_bytes.size(),
23173                             &authorization_size_bytes);
23174       if (rc != TPM_RC_SUCCESS) {
23175         return rc;
23176       }
23177       command_size +=
23178           authorization_size_bytes.size() + authorization_section_bytes.size();
23179     }
23180   }
23181   std::string tag_bytes;
23182   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23183   if (rc != TPM_RC_SUCCESS) {
23184     return rc;
23185   }
23186   std::string command_size_bytes;
23187   rc = Serialize_UINT32(command_size, &command_size_bytes);
23188   if (rc != TPM_RC_SUCCESS) {
23189     return rc;
23190   }
23191   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23192                         handle_section_bytes + authorization_size_bytes +
23193                         authorization_section_bytes + parameter_section_bytes;
23194   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23195   VLOG(2) << "Command: "
23196           << base::HexEncode(serialized_command->data(),
23197                              serialized_command->size());
23198   return TPM_RC_SUCCESS;
23199 }
23200 
ParseResponse_PolicyCommandCode(const std::string & response,AuthorizationDelegate * authorization_delegate)23201 TPM_RC Tpm::ParseResponse_PolicyCommandCode(
23202     const std::string& response,
23203     AuthorizationDelegate* authorization_delegate) {
23204   VLOG(3) << __func__;
23205   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23206   TPM_RC rc = TPM_RC_SUCCESS;
23207   std::string buffer(response);
23208   TPM_ST tag;
23209   std::string tag_bytes;
23210   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23211   if (rc != TPM_RC_SUCCESS) {
23212     return rc;
23213   }
23214   UINT32 response_size;
23215   std::string response_size_bytes;
23216   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23217   if (rc != TPM_RC_SUCCESS) {
23218     return rc;
23219   }
23220   TPM_RC response_code;
23221   std::string response_code_bytes;
23222   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23223   if (rc != TPM_RC_SUCCESS) {
23224     return rc;
23225   }
23226   if (response_size != response.size()) {
23227     return TPM_RC_SIZE;
23228   }
23229   if (response_code != TPM_RC_SUCCESS) {
23230     return response_code;
23231   }
23232   TPM_CC command_code = TPM_CC_PolicyCommandCode;
23233   std::string command_code_bytes;
23234   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23235   if (rc != TPM_RC_SUCCESS) {
23236     return rc;
23237   }
23238   std::string authorization_section_bytes;
23239   if (tag == TPM_ST_SESSIONS) {
23240     UINT32 parameter_section_size = buffer.size();
23241     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23242     if (rc != TPM_RC_SUCCESS) {
23243       return rc;
23244     }
23245     if (parameter_section_size > buffer.size()) {
23246       return TPM_RC_INSUFFICIENT;
23247     }
23248     authorization_section_bytes = buffer.substr(parameter_section_size);
23249     // Keep the parameter section in |buffer|.
23250     buffer.erase(parameter_section_size);
23251   }
23252   std::unique_ptr<crypto::SecureHash> hash(
23253       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23254   hash->Update(response_code_bytes.data(), response_code_bytes.size());
23255   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23256   hash->Update(buffer.data(), buffer.size());
23257   std::string response_hash(32, 0);
23258   hash->Finish(std::data(response_hash), response_hash.size());
23259   if (tag == TPM_ST_SESSIONS) {
23260     if (!authorization_delegate)
23261       return TRUNKS_RC_AUTHORIZATION_FAILED;
23262     if (!authorization_delegate->CheckResponseAuthorization(
23263             response_hash, authorization_section_bytes)) {
23264       return TRUNKS_RC_AUTHORIZATION_FAILED;
23265     }
23266   }
23267   return TPM_RC_SUCCESS;
23268 }
23269 
PolicyCommandCodeErrorCallback(Tpm::PolicyCommandCodeResponse callback,TPM_RC response_code)23270 void PolicyCommandCodeErrorCallback(Tpm::PolicyCommandCodeResponse callback,
23271                                     TPM_RC response_code) {
23272   VLOG(1) << __func__;
23273   std::move(callback).Run(response_code);
23274 }
23275 
PolicyCommandCodeResponseParser(Tpm::PolicyCommandCodeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23276 void PolicyCommandCodeResponseParser(
23277     Tpm::PolicyCommandCodeResponse callback,
23278     AuthorizationDelegate* authorization_delegate,
23279     const std::string& response) {
23280   VLOG(1) << __func__;
23281   TPM_RC rc =
23282       Tpm::ParseResponse_PolicyCommandCode(response, authorization_delegate);
23283   if (rc != TPM_RC_SUCCESS) {
23284     base::OnceCallback<void(TPM_RC)> error_reporter =
23285         base::BindOnce(PolicyCommandCodeErrorCallback, std::move(callback));
23286     std::move(error_reporter).Run(rc);
23287     return;
23288   }
23289   std::move(callback).Run(rc);
23290 }
23291 
PolicyCommandCode(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,AuthorizationDelegate * authorization_delegate,PolicyCommandCodeResponse callback)23292 void Tpm::PolicyCommandCode(const TPMI_SH_POLICY& policy_session,
23293                             const std::string& policy_session_name,
23294                             const TPM_CC& code,
23295                             AuthorizationDelegate* authorization_delegate,
23296                             PolicyCommandCodeResponse callback) {
23297   VLOG(1) << __func__;
23298   std::string command;
23299   TPM_RC rc = SerializeCommand_PolicyCommandCode(
23300       policy_session, policy_session_name, code, &command,
23301       authorization_delegate);
23302   if (rc != TPM_RC_SUCCESS) {
23303     base::OnceCallback<void(TPM_RC)> error_reporter =
23304         base::BindOnce(PolicyCommandCodeErrorCallback, std::move(callback));
23305     std::move(error_reporter).Run(rc);
23306     return;
23307   }
23308   base::OnceCallback<void(const std::string&)> parser =
23309       base::BindOnce(PolicyCommandCodeResponseParser, std::move(callback),
23310                      authorization_delegate);
23311   transceiver_->SendCommand(command, std::move(parser));
23312 }
23313 
PolicyCommandCodeSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM_CC & code,AuthorizationDelegate * authorization_delegate)23314 TPM_RC Tpm::PolicyCommandCodeSync(
23315     const TPMI_SH_POLICY& policy_session,
23316     const std::string& policy_session_name,
23317     const TPM_CC& code,
23318     AuthorizationDelegate* authorization_delegate) {
23319   VLOG(1) << __func__;
23320   std::string command;
23321   TPM_RC rc = SerializeCommand_PolicyCommandCode(
23322       policy_session, policy_session_name, code, &command,
23323       authorization_delegate);
23324   if (rc != TPM_RC_SUCCESS) {
23325     return rc;
23326   }
23327   std::string response = transceiver_->SendCommandAndWait(command);
23328   rc = ParseResponse_PolicyCommandCode(response, authorization_delegate);
23329   return rc;
23330 }
23331 
SerializeCommand_PolicyPhysicalPresence(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23332 TPM_RC Tpm::SerializeCommand_PolicyPhysicalPresence(
23333     const TPMI_SH_POLICY& policy_session,
23334     const std::string& policy_session_name,
23335     std::string* serialized_command,
23336     AuthorizationDelegate* authorization_delegate) {
23337   VLOG(3) << __func__;
23338   TPM_RC rc = TPM_RC_SUCCESS;
23339   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23340   UINT32 command_size = 10;  // Header size.
23341   std::string handle_section_bytes;
23342   std::string parameter_section_bytes;
23343   TPM_CC command_code = TPM_CC_PolicyPhysicalPresence;
23344   bool is_command_parameter_encryption_possible = false;
23345   bool is_response_parameter_encryption_possible = false;
23346   std::string command_code_bytes;
23347   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23348   if (rc != TPM_RC_SUCCESS) {
23349     return rc;
23350   }
23351   std::string policy_session_bytes;
23352   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23353   if (rc != TPM_RC_SUCCESS) {
23354     return rc;
23355   }
23356   std::unique_ptr<crypto::SecureHash> hash(
23357       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23358   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23359   hash->Update(policy_session_name.data(), policy_session_name.size());
23360   handle_section_bytes += policy_session_bytes;
23361   command_size += policy_session_bytes.size();
23362   std::string command_hash(32, 0);
23363   hash->Finish(std::data(command_hash), command_hash.size());
23364   std::string authorization_section_bytes;
23365   std::string authorization_size_bytes;
23366   if (authorization_delegate) {
23367     if (!authorization_delegate->GetCommandAuthorization(
23368             command_hash, is_command_parameter_encryption_possible,
23369             is_response_parameter_encryption_possible,
23370             &authorization_section_bytes)) {
23371       return TRUNKS_RC_AUTHORIZATION_FAILED;
23372     }
23373     if (!authorization_section_bytes.empty()) {
23374       tag = TPM_ST_SESSIONS;
23375       std::string tmp;
23376       rc = Serialize_UINT32(authorization_section_bytes.size(),
23377                             &authorization_size_bytes);
23378       if (rc != TPM_RC_SUCCESS) {
23379         return rc;
23380       }
23381       command_size +=
23382           authorization_size_bytes.size() + authorization_section_bytes.size();
23383     }
23384   }
23385   std::string tag_bytes;
23386   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23387   if (rc != TPM_RC_SUCCESS) {
23388     return rc;
23389   }
23390   std::string command_size_bytes;
23391   rc = Serialize_UINT32(command_size, &command_size_bytes);
23392   if (rc != TPM_RC_SUCCESS) {
23393     return rc;
23394   }
23395   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23396                         handle_section_bytes + authorization_size_bytes +
23397                         authorization_section_bytes + parameter_section_bytes;
23398   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23399   VLOG(2) << "Command: "
23400           << base::HexEncode(serialized_command->data(),
23401                              serialized_command->size());
23402   return TPM_RC_SUCCESS;
23403 }
23404 
ParseResponse_PolicyPhysicalPresence(const std::string & response,AuthorizationDelegate * authorization_delegate)23405 TPM_RC Tpm::ParseResponse_PolicyPhysicalPresence(
23406     const std::string& response,
23407     AuthorizationDelegate* authorization_delegate) {
23408   VLOG(3) << __func__;
23409   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23410   TPM_RC rc = TPM_RC_SUCCESS;
23411   std::string buffer(response);
23412   TPM_ST tag;
23413   std::string tag_bytes;
23414   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23415   if (rc != TPM_RC_SUCCESS) {
23416     return rc;
23417   }
23418   UINT32 response_size;
23419   std::string response_size_bytes;
23420   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23421   if (rc != TPM_RC_SUCCESS) {
23422     return rc;
23423   }
23424   TPM_RC response_code;
23425   std::string response_code_bytes;
23426   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23427   if (rc != TPM_RC_SUCCESS) {
23428     return rc;
23429   }
23430   if (response_size != response.size()) {
23431     return TPM_RC_SIZE;
23432   }
23433   if (response_code != TPM_RC_SUCCESS) {
23434     return response_code;
23435   }
23436   TPM_CC command_code = TPM_CC_PolicyPhysicalPresence;
23437   std::string command_code_bytes;
23438   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23439   if (rc != TPM_RC_SUCCESS) {
23440     return rc;
23441   }
23442   std::string authorization_section_bytes;
23443   if (tag == TPM_ST_SESSIONS) {
23444     UINT32 parameter_section_size = buffer.size();
23445     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23446     if (rc != TPM_RC_SUCCESS) {
23447       return rc;
23448     }
23449     if (parameter_section_size > buffer.size()) {
23450       return TPM_RC_INSUFFICIENT;
23451     }
23452     authorization_section_bytes = buffer.substr(parameter_section_size);
23453     // Keep the parameter section in |buffer|.
23454     buffer.erase(parameter_section_size);
23455   }
23456   std::unique_ptr<crypto::SecureHash> hash(
23457       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23458   hash->Update(response_code_bytes.data(), response_code_bytes.size());
23459   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23460   hash->Update(buffer.data(), buffer.size());
23461   std::string response_hash(32, 0);
23462   hash->Finish(std::data(response_hash), response_hash.size());
23463   if (tag == TPM_ST_SESSIONS) {
23464     if (!authorization_delegate)
23465       return TRUNKS_RC_AUTHORIZATION_FAILED;
23466     if (!authorization_delegate->CheckResponseAuthorization(
23467             response_hash, authorization_section_bytes)) {
23468       return TRUNKS_RC_AUTHORIZATION_FAILED;
23469     }
23470   }
23471   return TPM_RC_SUCCESS;
23472 }
23473 
PolicyPhysicalPresenceErrorCallback(Tpm::PolicyPhysicalPresenceResponse callback,TPM_RC response_code)23474 void PolicyPhysicalPresenceErrorCallback(
23475     Tpm::PolicyPhysicalPresenceResponse callback, TPM_RC response_code) {
23476   VLOG(1) << __func__;
23477   std::move(callback).Run(response_code);
23478 }
23479 
PolicyPhysicalPresenceResponseParser(Tpm::PolicyPhysicalPresenceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23480 void PolicyPhysicalPresenceResponseParser(
23481     Tpm::PolicyPhysicalPresenceResponse callback,
23482     AuthorizationDelegate* authorization_delegate,
23483     const std::string& response) {
23484   VLOG(1) << __func__;
23485   TPM_RC rc = Tpm::ParseResponse_PolicyPhysicalPresence(response,
23486                                                         authorization_delegate);
23487   if (rc != TPM_RC_SUCCESS) {
23488     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
23489         PolicyPhysicalPresenceErrorCallback, std::move(callback));
23490     std::move(error_reporter).Run(rc);
23491     return;
23492   }
23493   std::move(callback).Run(rc);
23494 }
23495 
PolicyPhysicalPresence(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyPhysicalPresenceResponse callback)23496 void Tpm::PolicyPhysicalPresence(const TPMI_SH_POLICY& policy_session,
23497                                  const std::string& policy_session_name,
23498                                  AuthorizationDelegate* authorization_delegate,
23499                                  PolicyPhysicalPresenceResponse callback) {
23500   VLOG(1) << __func__;
23501   std::string command;
23502   TPM_RC rc = SerializeCommand_PolicyPhysicalPresence(
23503       policy_session, policy_session_name, &command, authorization_delegate);
23504   if (rc != TPM_RC_SUCCESS) {
23505     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
23506         PolicyPhysicalPresenceErrorCallback, std::move(callback));
23507     std::move(error_reporter).Run(rc);
23508     return;
23509   }
23510   base::OnceCallback<void(const std::string&)> parser =
23511       base::BindOnce(PolicyPhysicalPresenceResponseParser, std::move(callback),
23512                      authorization_delegate);
23513   transceiver_->SendCommand(command, std::move(parser));
23514 }
23515 
PolicyPhysicalPresenceSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)23516 TPM_RC Tpm::PolicyPhysicalPresenceSync(
23517     const TPMI_SH_POLICY& policy_session,
23518     const std::string& policy_session_name,
23519     AuthorizationDelegate* authorization_delegate) {
23520   VLOG(1) << __func__;
23521   std::string command;
23522   TPM_RC rc = SerializeCommand_PolicyPhysicalPresence(
23523       policy_session, policy_session_name, &command, authorization_delegate);
23524   if (rc != TPM_RC_SUCCESS) {
23525     return rc;
23526   }
23527   std::string response = transceiver_->SendCommandAndWait(command);
23528   rc = ParseResponse_PolicyPhysicalPresence(response, authorization_delegate);
23529   return rc;
23530 }
23531 
SerializeCommand_PolicyCpHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23532 TPM_RC Tpm::SerializeCommand_PolicyCpHash(
23533     const TPMI_SH_POLICY& policy_session,
23534     const std::string& policy_session_name,
23535     const TPM2B_DIGEST& cp_hash_a,
23536     std::string* serialized_command,
23537     AuthorizationDelegate* authorization_delegate) {
23538   VLOG(3) << __func__;
23539   TPM_RC rc = TPM_RC_SUCCESS;
23540   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23541   UINT32 command_size = 10;  // Header size.
23542   std::string handle_section_bytes;
23543   std::string parameter_section_bytes;
23544   TPM_CC command_code = TPM_CC_PolicyCpHash;
23545   bool is_command_parameter_encryption_possible = true;
23546   bool is_response_parameter_encryption_possible = false;
23547   std::string command_code_bytes;
23548   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23549   if (rc != TPM_RC_SUCCESS) {
23550     return rc;
23551   }
23552   std::string policy_session_bytes;
23553   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23554   if (rc != TPM_RC_SUCCESS) {
23555     return rc;
23556   }
23557   std::string cp_hash_a_bytes;
23558   rc = Serialize_TPM2B_DIGEST(cp_hash_a, &cp_hash_a_bytes);
23559   if (rc != TPM_RC_SUCCESS) {
23560     return rc;
23561   }
23562   if (authorization_delegate) {
23563     // Encrypt just the parameter data, not the size.
23564     std::string tmp = cp_hash_a_bytes.substr(2);
23565     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23566       return TRUNKS_RC_ENCRYPTION_FAILED;
23567     }
23568     cp_hash_a_bytes.replace(2, std::string::npos, tmp);
23569   }
23570   std::unique_ptr<crypto::SecureHash> hash(
23571       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23572   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23573   hash->Update(policy_session_name.data(), policy_session_name.size());
23574   handle_section_bytes += policy_session_bytes;
23575   command_size += policy_session_bytes.size();
23576   hash->Update(cp_hash_a_bytes.data(), cp_hash_a_bytes.size());
23577   parameter_section_bytes += cp_hash_a_bytes;
23578   command_size += cp_hash_a_bytes.size();
23579   std::string command_hash(32, 0);
23580   hash->Finish(std::data(command_hash), command_hash.size());
23581   std::string authorization_section_bytes;
23582   std::string authorization_size_bytes;
23583   if (authorization_delegate) {
23584     if (!authorization_delegate->GetCommandAuthorization(
23585             command_hash, is_command_parameter_encryption_possible,
23586             is_response_parameter_encryption_possible,
23587             &authorization_section_bytes)) {
23588       return TRUNKS_RC_AUTHORIZATION_FAILED;
23589     }
23590     if (!authorization_section_bytes.empty()) {
23591       tag = TPM_ST_SESSIONS;
23592       std::string tmp;
23593       rc = Serialize_UINT32(authorization_section_bytes.size(),
23594                             &authorization_size_bytes);
23595       if (rc != TPM_RC_SUCCESS) {
23596         return rc;
23597       }
23598       command_size +=
23599           authorization_size_bytes.size() + authorization_section_bytes.size();
23600     }
23601   }
23602   std::string tag_bytes;
23603   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23604   if (rc != TPM_RC_SUCCESS) {
23605     return rc;
23606   }
23607   std::string command_size_bytes;
23608   rc = Serialize_UINT32(command_size, &command_size_bytes);
23609   if (rc != TPM_RC_SUCCESS) {
23610     return rc;
23611   }
23612   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23613                         handle_section_bytes + authorization_size_bytes +
23614                         authorization_section_bytes + parameter_section_bytes;
23615   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23616   VLOG(2) << "Command: "
23617           << base::HexEncode(serialized_command->data(),
23618                              serialized_command->size());
23619   return TPM_RC_SUCCESS;
23620 }
23621 
ParseResponse_PolicyCpHash(const std::string & response,AuthorizationDelegate * authorization_delegate)23622 TPM_RC Tpm::ParseResponse_PolicyCpHash(
23623     const std::string& response,
23624     AuthorizationDelegate* authorization_delegate) {
23625   VLOG(3) << __func__;
23626   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23627   TPM_RC rc = TPM_RC_SUCCESS;
23628   std::string buffer(response);
23629   TPM_ST tag;
23630   std::string tag_bytes;
23631   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23632   if (rc != TPM_RC_SUCCESS) {
23633     return rc;
23634   }
23635   UINT32 response_size;
23636   std::string response_size_bytes;
23637   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23638   if (rc != TPM_RC_SUCCESS) {
23639     return rc;
23640   }
23641   TPM_RC response_code;
23642   std::string response_code_bytes;
23643   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23644   if (rc != TPM_RC_SUCCESS) {
23645     return rc;
23646   }
23647   if (response_size != response.size()) {
23648     return TPM_RC_SIZE;
23649   }
23650   if (response_code != TPM_RC_SUCCESS) {
23651     return response_code;
23652   }
23653   TPM_CC command_code = TPM_CC_PolicyCpHash;
23654   std::string command_code_bytes;
23655   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23656   if (rc != TPM_RC_SUCCESS) {
23657     return rc;
23658   }
23659   std::string authorization_section_bytes;
23660   if (tag == TPM_ST_SESSIONS) {
23661     UINT32 parameter_section_size = buffer.size();
23662     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23663     if (rc != TPM_RC_SUCCESS) {
23664       return rc;
23665     }
23666     if (parameter_section_size > buffer.size()) {
23667       return TPM_RC_INSUFFICIENT;
23668     }
23669     authorization_section_bytes = buffer.substr(parameter_section_size);
23670     // Keep the parameter section in |buffer|.
23671     buffer.erase(parameter_section_size);
23672   }
23673   std::unique_ptr<crypto::SecureHash> hash(
23674       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23675   hash->Update(response_code_bytes.data(), response_code_bytes.size());
23676   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23677   hash->Update(buffer.data(), buffer.size());
23678   std::string response_hash(32, 0);
23679   hash->Finish(std::data(response_hash), response_hash.size());
23680   if (tag == TPM_ST_SESSIONS) {
23681     if (!authorization_delegate)
23682       return TRUNKS_RC_AUTHORIZATION_FAILED;
23683     if (!authorization_delegate->CheckResponseAuthorization(
23684             response_hash, authorization_section_bytes)) {
23685       return TRUNKS_RC_AUTHORIZATION_FAILED;
23686     }
23687   }
23688   return TPM_RC_SUCCESS;
23689 }
23690 
PolicyCpHashErrorCallback(Tpm::PolicyCpHashResponse callback,TPM_RC response_code)23691 void PolicyCpHashErrorCallback(Tpm::PolicyCpHashResponse callback,
23692                                TPM_RC response_code) {
23693   VLOG(1) << __func__;
23694   std::move(callback).Run(response_code);
23695 }
23696 
PolicyCpHashResponseParser(Tpm::PolicyCpHashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23697 void PolicyCpHashResponseParser(Tpm::PolicyCpHashResponse callback,
23698                                 AuthorizationDelegate* authorization_delegate,
23699                                 const std::string& response) {
23700   VLOG(1) << __func__;
23701   TPM_RC rc = Tpm::ParseResponse_PolicyCpHash(response, authorization_delegate);
23702   if (rc != TPM_RC_SUCCESS) {
23703     base::OnceCallback<void(TPM_RC)> error_reporter =
23704         base::BindOnce(PolicyCpHashErrorCallback, std::move(callback));
23705     std::move(error_reporter).Run(rc);
23706     return;
23707   }
23708   std::move(callback).Run(rc);
23709 }
23710 
PolicyCpHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,AuthorizationDelegate * authorization_delegate,PolicyCpHashResponse callback)23711 void Tpm::PolicyCpHash(const TPMI_SH_POLICY& policy_session,
23712                        const std::string& policy_session_name,
23713                        const TPM2B_DIGEST& cp_hash_a,
23714                        AuthorizationDelegate* authorization_delegate,
23715                        PolicyCpHashResponse callback) {
23716   VLOG(1) << __func__;
23717   std::string command;
23718   TPM_RC rc = SerializeCommand_PolicyCpHash(policy_session, policy_session_name,
23719                                             cp_hash_a, &command,
23720                                             authorization_delegate);
23721   if (rc != TPM_RC_SUCCESS) {
23722     base::OnceCallback<void(TPM_RC)> error_reporter =
23723         base::BindOnce(PolicyCpHashErrorCallback, std::move(callback));
23724     std::move(error_reporter).Run(rc);
23725     return;
23726   }
23727   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
23728       PolicyCpHashResponseParser, std::move(callback), authorization_delegate);
23729   transceiver_->SendCommand(command, std::move(parser));
23730 }
23731 
PolicyCpHashSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & cp_hash_a,AuthorizationDelegate * authorization_delegate)23732 TPM_RC Tpm::PolicyCpHashSync(const TPMI_SH_POLICY& policy_session,
23733                              const std::string& policy_session_name,
23734                              const TPM2B_DIGEST& cp_hash_a,
23735                              AuthorizationDelegate* authorization_delegate) {
23736   VLOG(1) << __func__;
23737   std::string command;
23738   TPM_RC rc = SerializeCommand_PolicyCpHash(policy_session, policy_session_name,
23739                                             cp_hash_a, &command,
23740                                             authorization_delegate);
23741   if (rc != TPM_RC_SUCCESS) {
23742     return rc;
23743   }
23744   std::string response = transceiver_->SendCommandAndWait(command);
23745   rc = ParseResponse_PolicyCpHash(response, authorization_delegate);
23746   return rc;
23747 }
23748 
SerializeCommand_PolicyNameHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23749 TPM_RC Tpm::SerializeCommand_PolicyNameHash(
23750     const TPMI_SH_POLICY& policy_session,
23751     const std::string& policy_session_name,
23752     const TPM2B_DIGEST& name_hash,
23753     std::string* serialized_command,
23754     AuthorizationDelegate* authorization_delegate) {
23755   VLOG(3) << __func__;
23756   TPM_RC rc = TPM_RC_SUCCESS;
23757   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23758   UINT32 command_size = 10;  // Header size.
23759   std::string handle_section_bytes;
23760   std::string parameter_section_bytes;
23761   TPM_CC command_code = TPM_CC_PolicyNameHash;
23762   bool is_command_parameter_encryption_possible = true;
23763   bool is_response_parameter_encryption_possible = false;
23764   std::string command_code_bytes;
23765   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23766   if (rc != TPM_RC_SUCCESS) {
23767     return rc;
23768   }
23769   std::string policy_session_bytes;
23770   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23771   if (rc != TPM_RC_SUCCESS) {
23772     return rc;
23773   }
23774   std::string name_hash_bytes;
23775   rc = Serialize_TPM2B_DIGEST(name_hash, &name_hash_bytes);
23776   if (rc != TPM_RC_SUCCESS) {
23777     return rc;
23778   }
23779   if (authorization_delegate) {
23780     // Encrypt just the parameter data, not the size.
23781     std::string tmp = name_hash_bytes.substr(2);
23782     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
23783       return TRUNKS_RC_ENCRYPTION_FAILED;
23784     }
23785     name_hash_bytes.replace(2, std::string::npos, tmp);
23786   }
23787   std::unique_ptr<crypto::SecureHash> hash(
23788       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23789   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23790   hash->Update(policy_session_name.data(), policy_session_name.size());
23791   handle_section_bytes += policy_session_bytes;
23792   command_size += policy_session_bytes.size();
23793   hash->Update(name_hash_bytes.data(), name_hash_bytes.size());
23794   parameter_section_bytes += name_hash_bytes;
23795   command_size += name_hash_bytes.size();
23796   std::string command_hash(32, 0);
23797   hash->Finish(std::data(command_hash), command_hash.size());
23798   std::string authorization_section_bytes;
23799   std::string authorization_size_bytes;
23800   if (authorization_delegate) {
23801     if (!authorization_delegate->GetCommandAuthorization(
23802             command_hash, is_command_parameter_encryption_possible,
23803             is_response_parameter_encryption_possible,
23804             &authorization_section_bytes)) {
23805       return TRUNKS_RC_AUTHORIZATION_FAILED;
23806     }
23807     if (!authorization_section_bytes.empty()) {
23808       tag = TPM_ST_SESSIONS;
23809       std::string tmp;
23810       rc = Serialize_UINT32(authorization_section_bytes.size(),
23811                             &authorization_size_bytes);
23812       if (rc != TPM_RC_SUCCESS) {
23813         return rc;
23814       }
23815       command_size +=
23816           authorization_size_bytes.size() + authorization_section_bytes.size();
23817     }
23818   }
23819   std::string tag_bytes;
23820   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
23821   if (rc != TPM_RC_SUCCESS) {
23822     return rc;
23823   }
23824   std::string command_size_bytes;
23825   rc = Serialize_UINT32(command_size, &command_size_bytes);
23826   if (rc != TPM_RC_SUCCESS) {
23827     return rc;
23828   }
23829   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
23830                         handle_section_bytes + authorization_size_bytes +
23831                         authorization_section_bytes + parameter_section_bytes;
23832   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
23833   VLOG(2) << "Command: "
23834           << base::HexEncode(serialized_command->data(),
23835                              serialized_command->size());
23836   return TPM_RC_SUCCESS;
23837 }
23838 
ParseResponse_PolicyNameHash(const std::string & response,AuthorizationDelegate * authorization_delegate)23839 TPM_RC Tpm::ParseResponse_PolicyNameHash(
23840     const std::string& response,
23841     AuthorizationDelegate* authorization_delegate) {
23842   VLOG(3) << __func__;
23843   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
23844   TPM_RC rc = TPM_RC_SUCCESS;
23845   std::string buffer(response);
23846   TPM_ST tag;
23847   std::string tag_bytes;
23848   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
23849   if (rc != TPM_RC_SUCCESS) {
23850     return rc;
23851   }
23852   UINT32 response_size;
23853   std::string response_size_bytes;
23854   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
23855   if (rc != TPM_RC_SUCCESS) {
23856     return rc;
23857   }
23858   TPM_RC response_code;
23859   std::string response_code_bytes;
23860   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
23861   if (rc != TPM_RC_SUCCESS) {
23862     return rc;
23863   }
23864   if (response_size != response.size()) {
23865     return TPM_RC_SIZE;
23866   }
23867   if (response_code != TPM_RC_SUCCESS) {
23868     return response_code;
23869   }
23870   TPM_CC command_code = TPM_CC_PolicyNameHash;
23871   std::string command_code_bytes;
23872   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23873   if (rc != TPM_RC_SUCCESS) {
23874     return rc;
23875   }
23876   std::string authorization_section_bytes;
23877   if (tag == TPM_ST_SESSIONS) {
23878     UINT32 parameter_section_size = buffer.size();
23879     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
23880     if (rc != TPM_RC_SUCCESS) {
23881       return rc;
23882     }
23883     if (parameter_section_size > buffer.size()) {
23884       return TPM_RC_INSUFFICIENT;
23885     }
23886     authorization_section_bytes = buffer.substr(parameter_section_size);
23887     // Keep the parameter section in |buffer|.
23888     buffer.erase(parameter_section_size);
23889   }
23890   std::unique_ptr<crypto::SecureHash> hash(
23891       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
23892   hash->Update(response_code_bytes.data(), response_code_bytes.size());
23893   hash->Update(command_code_bytes.data(), command_code_bytes.size());
23894   hash->Update(buffer.data(), buffer.size());
23895   std::string response_hash(32, 0);
23896   hash->Finish(std::data(response_hash), response_hash.size());
23897   if (tag == TPM_ST_SESSIONS) {
23898     if (!authorization_delegate)
23899       return TRUNKS_RC_AUTHORIZATION_FAILED;
23900     if (!authorization_delegate->CheckResponseAuthorization(
23901             response_hash, authorization_section_bytes)) {
23902       return TRUNKS_RC_AUTHORIZATION_FAILED;
23903     }
23904   }
23905   return TPM_RC_SUCCESS;
23906 }
23907 
PolicyNameHashErrorCallback(Tpm::PolicyNameHashResponse callback,TPM_RC response_code)23908 void PolicyNameHashErrorCallback(Tpm::PolicyNameHashResponse callback,
23909                                  TPM_RC response_code) {
23910   VLOG(1) << __func__;
23911   std::move(callback).Run(response_code);
23912 }
23913 
PolicyNameHashResponseParser(Tpm::PolicyNameHashResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)23914 void PolicyNameHashResponseParser(Tpm::PolicyNameHashResponse callback,
23915                                   AuthorizationDelegate* authorization_delegate,
23916                                   const std::string& response) {
23917   VLOG(1) << __func__;
23918   TPM_RC rc =
23919       Tpm::ParseResponse_PolicyNameHash(response, authorization_delegate);
23920   if (rc != TPM_RC_SUCCESS) {
23921     base::OnceCallback<void(TPM_RC)> error_reporter =
23922         base::BindOnce(PolicyNameHashErrorCallback, std::move(callback));
23923     std::move(error_reporter).Run(rc);
23924     return;
23925   }
23926   std::move(callback).Run(rc);
23927 }
23928 
PolicyNameHash(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,AuthorizationDelegate * authorization_delegate,PolicyNameHashResponse callback)23929 void Tpm::PolicyNameHash(const TPMI_SH_POLICY& policy_session,
23930                          const std::string& policy_session_name,
23931                          const TPM2B_DIGEST& name_hash,
23932                          AuthorizationDelegate* authorization_delegate,
23933                          PolicyNameHashResponse callback) {
23934   VLOG(1) << __func__;
23935   std::string command;
23936   TPM_RC rc = SerializeCommand_PolicyNameHash(policy_session,
23937                                               policy_session_name, name_hash,
23938                                               &command, authorization_delegate);
23939   if (rc != TPM_RC_SUCCESS) {
23940     base::OnceCallback<void(TPM_RC)> error_reporter =
23941         base::BindOnce(PolicyNameHashErrorCallback, std::move(callback));
23942     std::move(error_reporter).Run(rc);
23943     return;
23944   }
23945   base::OnceCallback<void(const std::string&)> parser =
23946       base::BindOnce(PolicyNameHashResponseParser, std::move(callback),
23947                      authorization_delegate);
23948   transceiver_->SendCommand(command, std::move(parser));
23949 }
23950 
PolicyNameHashSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & name_hash,AuthorizationDelegate * authorization_delegate)23951 TPM_RC Tpm::PolicyNameHashSync(const TPMI_SH_POLICY& policy_session,
23952                                const std::string& policy_session_name,
23953                                const TPM2B_DIGEST& name_hash,
23954                                AuthorizationDelegate* authorization_delegate) {
23955   VLOG(1) << __func__;
23956   std::string command;
23957   TPM_RC rc = SerializeCommand_PolicyNameHash(policy_session,
23958                                               policy_session_name, name_hash,
23959                                               &command, authorization_delegate);
23960   if (rc != TPM_RC_SUCCESS) {
23961     return rc;
23962   }
23963   std::string response = transceiver_->SendCommandAndWait(command);
23964   rc = ParseResponse_PolicyNameHash(response, authorization_delegate);
23965   return rc;
23966 }
23967 
SerializeCommand_PolicyDuplicationSelect(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NAME & object_name,const TPM2B_NAME & new_parent_name,const TPMI_YES_NO & include_object,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)23968 TPM_RC Tpm::SerializeCommand_PolicyDuplicationSelect(
23969     const TPMI_SH_POLICY& policy_session,
23970     const std::string& policy_session_name,
23971     const TPM2B_NAME& object_name,
23972     const TPM2B_NAME& new_parent_name,
23973     const TPMI_YES_NO& include_object,
23974     std::string* serialized_command,
23975     AuthorizationDelegate* authorization_delegate) {
23976   VLOG(3) << __func__;
23977   TPM_RC rc = TPM_RC_SUCCESS;
23978   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
23979   UINT32 command_size = 10;  // Header size.
23980   std::string handle_section_bytes;
23981   std::string parameter_section_bytes;
23982   TPM_CC command_code = TPM_CC_PolicyDuplicationSelect;
23983   bool is_command_parameter_encryption_possible = true;
23984   bool is_response_parameter_encryption_possible = false;
23985   std::string command_code_bytes;
23986   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
23987   if (rc != TPM_RC_SUCCESS) {
23988     return rc;
23989   }
23990   std::string policy_session_bytes;
23991   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
23992   if (rc != TPM_RC_SUCCESS) {
23993     return rc;
23994   }
23995   std::string object_name_bytes;
23996   rc = Serialize_TPM2B_NAME(object_name, &object_name_bytes);
23997   if (rc != TPM_RC_SUCCESS) {
23998     return rc;
23999   }
24000   std::string new_parent_name_bytes;
24001   rc = Serialize_TPM2B_NAME(new_parent_name, &new_parent_name_bytes);
24002   if (rc != TPM_RC_SUCCESS) {
24003     return rc;
24004   }
24005   std::string include_object_bytes;
24006   rc = Serialize_TPMI_YES_NO(include_object, &include_object_bytes);
24007   if (rc != TPM_RC_SUCCESS) {
24008     return rc;
24009   }
24010   if (authorization_delegate) {
24011     // Encrypt just the parameter data, not the size.
24012     std::string tmp = object_name_bytes.substr(2);
24013     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
24014       return TRUNKS_RC_ENCRYPTION_FAILED;
24015     }
24016     object_name_bytes.replace(2, std::string::npos, tmp);
24017   }
24018   std::unique_ptr<crypto::SecureHash> hash(
24019       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24020   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24021   hash->Update(policy_session_name.data(), policy_session_name.size());
24022   handle_section_bytes += policy_session_bytes;
24023   command_size += policy_session_bytes.size();
24024   hash->Update(object_name_bytes.data(), object_name_bytes.size());
24025   parameter_section_bytes += object_name_bytes;
24026   command_size += object_name_bytes.size();
24027   hash->Update(new_parent_name_bytes.data(), new_parent_name_bytes.size());
24028   parameter_section_bytes += new_parent_name_bytes;
24029   command_size += new_parent_name_bytes.size();
24030   hash->Update(include_object_bytes.data(), include_object_bytes.size());
24031   parameter_section_bytes += include_object_bytes;
24032   command_size += include_object_bytes.size();
24033   std::string command_hash(32, 0);
24034   hash->Finish(std::data(command_hash), command_hash.size());
24035   std::string authorization_section_bytes;
24036   std::string authorization_size_bytes;
24037   if (authorization_delegate) {
24038     if (!authorization_delegate->GetCommandAuthorization(
24039             command_hash, is_command_parameter_encryption_possible,
24040             is_response_parameter_encryption_possible,
24041             &authorization_section_bytes)) {
24042       return TRUNKS_RC_AUTHORIZATION_FAILED;
24043     }
24044     if (!authorization_section_bytes.empty()) {
24045       tag = TPM_ST_SESSIONS;
24046       std::string tmp;
24047       rc = Serialize_UINT32(authorization_section_bytes.size(),
24048                             &authorization_size_bytes);
24049       if (rc != TPM_RC_SUCCESS) {
24050         return rc;
24051       }
24052       command_size +=
24053           authorization_size_bytes.size() + authorization_section_bytes.size();
24054     }
24055   }
24056   std::string tag_bytes;
24057   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24058   if (rc != TPM_RC_SUCCESS) {
24059     return rc;
24060   }
24061   std::string command_size_bytes;
24062   rc = Serialize_UINT32(command_size, &command_size_bytes);
24063   if (rc != TPM_RC_SUCCESS) {
24064     return rc;
24065   }
24066   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24067                         handle_section_bytes + authorization_size_bytes +
24068                         authorization_section_bytes + parameter_section_bytes;
24069   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24070   VLOG(2) << "Command: "
24071           << base::HexEncode(serialized_command->data(),
24072                              serialized_command->size());
24073   return TPM_RC_SUCCESS;
24074 }
24075 
ParseResponse_PolicyDuplicationSelect(const std::string & response,AuthorizationDelegate * authorization_delegate)24076 TPM_RC Tpm::ParseResponse_PolicyDuplicationSelect(
24077     const std::string& response,
24078     AuthorizationDelegate* authorization_delegate) {
24079   VLOG(3) << __func__;
24080   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24081   TPM_RC rc = TPM_RC_SUCCESS;
24082   std::string buffer(response);
24083   TPM_ST tag;
24084   std::string tag_bytes;
24085   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24086   if (rc != TPM_RC_SUCCESS) {
24087     return rc;
24088   }
24089   UINT32 response_size;
24090   std::string response_size_bytes;
24091   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24092   if (rc != TPM_RC_SUCCESS) {
24093     return rc;
24094   }
24095   TPM_RC response_code;
24096   std::string response_code_bytes;
24097   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24098   if (rc != TPM_RC_SUCCESS) {
24099     return rc;
24100   }
24101   if (response_size != response.size()) {
24102     return TPM_RC_SIZE;
24103   }
24104   if (response_code != TPM_RC_SUCCESS) {
24105     return response_code;
24106   }
24107   TPM_CC command_code = TPM_CC_PolicyDuplicationSelect;
24108   std::string command_code_bytes;
24109   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24110   if (rc != TPM_RC_SUCCESS) {
24111     return rc;
24112   }
24113   std::string authorization_section_bytes;
24114   if (tag == TPM_ST_SESSIONS) {
24115     UINT32 parameter_section_size = buffer.size();
24116     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24117     if (rc != TPM_RC_SUCCESS) {
24118       return rc;
24119     }
24120     if (parameter_section_size > buffer.size()) {
24121       return TPM_RC_INSUFFICIENT;
24122     }
24123     authorization_section_bytes = buffer.substr(parameter_section_size);
24124     // Keep the parameter section in |buffer|.
24125     buffer.erase(parameter_section_size);
24126   }
24127   std::unique_ptr<crypto::SecureHash> hash(
24128       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24129   hash->Update(response_code_bytes.data(), response_code_bytes.size());
24130   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24131   hash->Update(buffer.data(), buffer.size());
24132   std::string response_hash(32, 0);
24133   hash->Finish(std::data(response_hash), response_hash.size());
24134   if (tag == TPM_ST_SESSIONS) {
24135     if (!authorization_delegate)
24136       return TRUNKS_RC_AUTHORIZATION_FAILED;
24137     if (!authorization_delegate->CheckResponseAuthorization(
24138             response_hash, authorization_section_bytes)) {
24139       return TRUNKS_RC_AUTHORIZATION_FAILED;
24140     }
24141   }
24142   return TPM_RC_SUCCESS;
24143 }
24144 
PolicyDuplicationSelectErrorCallback(Tpm::PolicyDuplicationSelectResponse callback,TPM_RC response_code)24145 void PolicyDuplicationSelectErrorCallback(
24146     Tpm::PolicyDuplicationSelectResponse callback, TPM_RC response_code) {
24147   VLOG(1) << __func__;
24148   std::move(callback).Run(response_code);
24149 }
24150 
PolicyDuplicationSelectResponseParser(Tpm::PolicyDuplicationSelectResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24151 void PolicyDuplicationSelectResponseParser(
24152     Tpm::PolicyDuplicationSelectResponse callback,
24153     AuthorizationDelegate* authorization_delegate,
24154     const std::string& response) {
24155   VLOG(1) << __func__;
24156   TPM_RC rc = Tpm::ParseResponse_PolicyDuplicationSelect(
24157       response, authorization_delegate);
24158   if (rc != TPM_RC_SUCCESS) {
24159     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
24160         PolicyDuplicationSelectErrorCallback, std::move(callback));
24161     std::move(error_reporter).Run(rc);
24162     return;
24163   }
24164   std::move(callback).Run(rc);
24165 }
24166 
PolicyDuplicationSelect(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NAME & object_name,const TPM2B_NAME & new_parent_name,const TPMI_YES_NO & include_object,AuthorizationDelegate * authorization_delegate,PolicyDuplicationSelectResponse callback)24167 void Tpm::PolicyDuplicationSelect(const TPMI_SH_POLICY& policy_session,
24168                                   const std::string& policy_session_name,
24169                                   const TPM2B_NAME& object_name,
24170                                   const TPM2B_NAME& new_parent_name,
24171                                   const TPMI_YES_NO& include_object,
24172                                   AuthorizationDelegate* authorization_delegate,
24173                                   PolicyDuplicationSelectResponse callback) {
24174   VLOG(1) << __func__;
24175   std::string command;
24176   TPM_RC rc = SerializeCommand_PolicyDuplicationSelect(
24177       policy_session, policy_session_name, object_name, new_parent_name,
24178       include_object, &command, authorization_delegate);
24179   if (rc != TPM_RC_SUCCESS) {
24180     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
24181         PolicyDuplicationSelectErrorCallback, std::move(callback));
24182     std::move(error_reporter).Run(rc);
24183     return;
24184   }
24185   base::OnceCallback<void(const std::string&)> parser =
24186       base::BindOnce(PolicyDuplicationSelectResponseParser, std::move(callback),
24187                      authorization_delegate);
24188   transceiver_->SendCommand(command, std::move(parser));
24189 }
24190 
PolicyDuplicationSelectSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_NAME & object_name,const TPM2B_NAME & new_parent_name,const TPMI_YES_NO & include_object,AuthorizationDelegate * authorization_delegate)24191 TPM_RC Tpm::PolicyDuplicationSelectSync(
24192     const TPMI_SH_POLICY& policy_session,
24193     const std::string& policy_session_name,
24194     const TPM2B_NAME& object_name,
24195     const TPM2B_NAME& new_parent_name,
24196     const TPMI_YES_NO& include_object,
24197     AuthorizationDelegate* authorization_delegate) {
24198   VLOG(1) << __func__;
24199   std::string command;
24200   TPM_RC rc = SerializeCommand_PolicyDuplicationSelect(
24201       policy_session, policy_session_name, object_name, new_parent_name,
24202       include_object, &command, authorization_delegate);
24203   if (rc != TPM_RC_SUCCESS) {
24204     return rc;
24205   }
24206   std::string response = transceiver_->SendCommandAndWait(command);
24207   rc = ParseResponse_PolicyDuplicationSelect(response, authorization_delegate);
24208   return rc;
24209 }
24210 
SerializeCommand_PolicyAuthorize(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & approved_policy,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & key_sign,const TPMT_TK_VERIFIED & check_ticket,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24211 TPM_RC Tpm::SerializeCommand_PolicyAuthorize(
24212     const TPMI_SH_POLICY& policy_session,
24213     const std::string& policy_session_name,
24214     const TPM2B_DIGEST& approved_policy,
24215     const TPM2B_NONCE& policy_ref,
24216     const TPM2B_NAME& key_sign,
24217     const TPMT_TK_VERIFIED& check_ticket,
24218     std::string* serialized_command,
24219     AuthorizationDelegate* authorization_delegate) {
24220   VLOG(3) << __func__;
24221   TPM_RC rc = TPM_RC_SUCCESS;
24222   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24223   UINT32 command_size = 10;  // Header size.
24224   std::string handle_section_bytes;
24225   std::string parameter_section_bytes;
24226   TPM_CC command_code = TPM_CC_PolicyAuthorize;
24227   bool is_command_parameter_encryption_possible = true;
24228   bool is_response_parameter_encryption_possible = false;
24229   std::string command_code_bytes;
24230   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24231   if (rc != TPM_RC_SUCCESS) {
24232     return rc;
24233   }
24234   std::string policy_session_bytes;
24235   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24236   if (rc != TPM_RC_SUCCESS) {
24237     return rc;
24238   }
24239   std::string approved_policy_bytes;
24240   rc = Serialize_TPM2B_DIGEST(approved_policy, &approved_policy_bytes);
24241   if (rc != TPM_RC_SUCCESS) {
24242     return rc;
24243   }
24244   std::string policy_ref_bytes;
24245   rc = Serialize_TPM2B_NONCE(policy_ref, &policy_ref_bytes);
24246   if (rc != TPM_RC_SUCCESS) {
24247     return rc;
24248   }
24249   std::string key_sign_bytes;
24250   rc = Serialize_TPM2B_NAME(key_sign, &key_sign_bytes);
24251   if (rc != TPM_RC_SUCCESS) {
24252     return rc;
24253   }
24254   std::string check_ticket_bytes;
24255   rc = Serialize_TPMT_TK_VERIFIED(check_ticket, &check_ticket_bytes);
24256   if (rc != TPM_RC_SUCCESS) {
24257     return rc;
24258   }
24259   if (authorization_delegate) {
24260     // Encrypt just the parameter data, not the size.
24261     std::string tmp = approved_policy_bytes.substr(2);
24262     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
24263       return TRUNKS_RC_ENCRYPTION_FAILED;
24264     }
24265     approved_policy_bytes.replace(2, std::string::npos, tmp);
24266   }
24267   std::unique_ptr<crypto::SecureHash> hash(
24268       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24269   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24270   hash->Update(policy_session_name.data(), policy_session_name.size());
24271   handle_section_bytes += policy_session_bytes;
24272   command_size += policy_session_bytes.size();
24273   hash->Update(approved_policy_bytes.data(), approved_policy_bytes.size());
24274   parameter_section_bytes += approved_policy_bytes;
24275   command_size += approved_policy_bytes.size();
24276   hash->Update(policy_ref_bytes.data(), policy_ref_bytes.size());
24277   parameter_section_bytes += policy_ref_bytes;
24278   command_size += policy_ref_bytes.size();
24279   hash->Update(key_sign_bytes.data(), key_sign_bytes.size());
24280   parameter_section_bytes += key_sign_bytes;
24281   command_size += key_sign_bytes.size();
24282   hash->Update(check_ticket_bytes.data(), check_ticket_bytes.size());
24283   parameter_section_bytes += check_ticket_bytes;
24284   command_size += check_ticket_bytes.size();
24285   std::string command_hash(32, 0);
24286   hash->Finish(std::data(command_hash), command_hash.size());
24287   std::string authorization_section_bytes;
24288   std::string authorization_size_bytes;
24289   if (authorization_delegate) {
24290     if (!authorization_delegate->GetCommandAuthorization(
24291             command_hash, is_command_parameter_encryption_possible,
24292             is_response_parameter_encryption_possible,
24293             &authorization_section_bytes)) {
24294       return TRUNKS_RC_AUTHORIZATION_FAILED;
24295     }
24296     if (!authorization_section_bytes.empty()) {
24297       tag = TPM_ST_SESSIONS;
24298       std::string tmp;
24299       rc = Serialize_UINT32(authorization_section_bytes.size(),
24300                             &authorization_size_bytes);
24301       if (rc != TPM_RC_SUCCESS) {
24302         return rc;
24303       }
24304       command_size +=
24305           authorization_size_bytes.size() + authorization_section_bytes.size();
24306     }
24307   }
24308   std::string tag_bytes;
24309   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24310   if (rc != TPM_RC_SUCCESS) {
24311     return rc;
24312   }
24313   std::string command_size_bytes;
24314   rc = Serialize_UINT32(command_size, &command_size_bytes);
24315   if (rc != TPM_RC_SUCCESS) {
24316     return rc;
24317   }
24318   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24319                         handle_section_bytes + authorization_size_bytes +
24320                         authorization_section_bytes + parameter_section_bytes;
24321   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24322   VLOG(2) << "Command: "
24323           << base::HexEncode(serialized_command->data(),
24324                              serialized_command->size());
24325   return TPM_RC_SUCCESS;
24326 }
24327 
ParseResponse_PolicyAuthorize(const std::string & response,AuthorizationDelegate * authorization_delegate)24328 TPM_RC Tpm::ParseResponse_PolicyAuthorize(
24329     const std::string& response,
24330     AuthorizationDelegate* authorization_delegate) {
24331   VLOG(3) << __func__;
24332   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24333   TPM_RC rc = TPM_RC_SUCCESS;
24334   std::string buffer(response);
24335   TPM_ST tag;
24336   std::string tag_bytes;
24337   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24338   if (rc != TPM_RC_SUCCESS) {
24339     return rc;
24340   }
24341   UINT32 response_size;
24342   std::string response_size_bytes;
24343   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24344   if (rc != TPM_RC_SUCCESS) {
24345     return rc;
24346   }
24347   TPM_RC response_code;
24348   std::string response_code_bytes;
24349   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24350   if (rc != TPM_RC_SUCCESS) {
24351     return rc;
24352   }
24353   if (response_size != response.size()) {
24354     return TPM_RC_SIZE;
24355   }
24356   if (response_code != TPM_RC_SUCCESS) {
24357     return response_code;
24358   }
24359   TPM_CC command_code = TPM_CC_PolicyAuthorize;
24360   std::string command_code_bytes;
24361   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24362   if (rc != TPM_RC_SUCCESS) {
24363     return rc;
24364   }
24365   std::string authorization_section_bytes;
24366   if (tag == TPM_ST_SESSIONS) {
24367     UINT32 parameter_section_size = buffer.size();
24368     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24369     if (rc != TPM_RC_SUCCESS) {
24370       return rc;
24371     }
24372     if (parameter_section_size > buffer.size()) {
24373       return TPM_RC_INSUFFICIENT;
24374     }
24375     authorization_section_bytes = buffer.substr(parameter_section_size);
24376     // Keep the parameter section in |buffer|.
24377     buffer.erase(parameter_section_size);
24378   }
24379   std::unique_ptr<crypto::SecureHash> hash(
24380       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24381   hash->Update(response_code_bytes.data(), response_code_bytes.size());
24382   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24383   hash->Update(buffer.data(), buffer.size());
24384   std::string response_hash(32, 0);
24385   hash->Finish(std::data(response_hash), response_hash.size());
24386   if (tag == TPM_ST_SESSIONS) {
24387     if (!authorization_delegate)
24388       return TRUNKS_RC_AUTHORIZATION_FAILED;
24389     if (!authorization_delegate->CheckResponseAuthorization(
24390             response_hash, authorization_section_bytes)) {
24391       return TRUNKS_RC_AUTHORIZATION_FAILED;
24392     }
24393   }
24394   return TPM_RC_SUCCESS;
24395 }
24396 
PolicyAuthorizeErrorCallback(Tpm::PolicyAuthorizeResponse callback,TPM_RC response_code)24397 void PolicyAuthorizeErrorCallback(Tpm::PolicyAuthorizeResponse callback,
24398                                   TPM_RC response_code) {
24399   VLOG(1) << __func__;
24400   std::move(callback).Run(response_code);
24401 }
24402 
PolicyAuthorizeResponseParser(Tpm::PolicyAuthorizeResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24403 void PolicyAuthorizeResponseParser(
24404     Tpm::PolicyAuthorizeResponse callback,
24405     AuthorizationDelegate* authorization_delegate,
24406     const std::string& response) {
24407   VLOG(1) << __func__;
24408   TPM_RC rc =
24409       Tpm::ParseResponse_PolicyAuthorize(response, authorization_delegate);
24410   if (rc != TPM_RC_SUCCESS) {
24411     base::OnceCallback<void(TPM_RC)> error_reporter =
24412         base::BindOnce(PolicyAuthorizeErrorCallback, std::move(callback));
24413     std::move(error_reporter).Run(rc);
24414     return;
24415   }
24416   std::move(callback).Run(rc);
24417 }
24418 
PolicyAuthorize(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & approved_policy,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & key_sign,const TPMT_TK_VERIFIED & check_ticket,AuthorizationDelegate * authorization_delegate,PolicyAuthorizeResponse callback)24419 void Tpm::PolicyAuthorize(const TPMI_SH_POLICY& policy_session,
24420                           const std::string& policy_session_name,
24421                           const TPM2B_DIGEST& approved_policy,
24422                           const TPM2B_NONCE& policy_ref,
24423                           const TPM2B_NAME& key_sign,
24424                           const TPMT_TK_VERIFIED& check_ticket,
24425                           AuthorizationDelegate* authorization_delegate,
24426                           PolicyAuthorizeResponse callback) {
24427   VLOG(1) << __func__;
24428   std::string command;
24429   TPM_RC rc = SerializeCommand_PolicyAuthorize(
24430       policy_session, policy_session_name, approved_policy, policy_ref,
24431       key_sign, check_ticket, &command, authorization_delegate);
24432   if (rc != TPM_RC_SUCCESS) {
24433     base::OnceCallback<void(TPM_RC)> error_reporter =
24434         base::BindOnce(PolicyAuthorizeErrorCallback, std::move(callback));
24435     std::move(error_reporter).Run(rc);
24436     return;
24437   }
24438   base::OnceCallback<void(const std::string&)> parser =
24439       base::BindOnce(PolicyAuthorizeResponseParser, std::move(callback),
24440                      authorization_delegate);
24441   transceiver_->SendCommand(command, std::move(parser));
24442 }
24443 
PolicyAuthorizeSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPM2B_DIGEST & approved_policy,const TPM2B_NONCE & policy_ref,const TPM2B_NAME & key_sign,const TPMT_TK_VERIFIED & check_ticket,AuthorizationDelegate * authorization_delegate)24444 TPM_RC Tpm::PolicyAuthorizeSync(const TPMI_SH_POLICY& policy_session,
24445                                 const std::string& policy_session_name,
24446                                 const TPM2B_DIGEST& approved_policy,
24447                                 const TPM2B_NONCE& policy_ref,
24448                                 const TPM2B_NAME& key_sign,
24449                                 const TPMT_TK_VERIFIED& check_ticket,
24450                                 AuthorizationDelegate* authorization_delegate) {
24451   VLOG(1) << __func__;
24452   std::string command;
24453   TPM_RC rc = SerializeCommand_PolicyAuthorize(
24454       policy_session, policy_session_name, approved_policy, policy_ref,
24455       key_sign, check_ticket, &command, authorization_delegate);
24456   if (rc != TPM_RC_SUCCESS) {
24457     return rc;
24458   }
24459   std::string response = transceiver_->SendCommandAndWait(command);
24460   rc = ParseResponse_PolicyAuthorize(response, authorization_delegate);
24461   return rc;
24462 }
24463 
SerializeCommand_PolicyAuthValue(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24464 TPM_RC Tpm::SerializeCommand_PolicyAuthValue(
24465     const TPMI_SH_POLICY& policy_session,
24466     const std::string& policy_session_name,
24467     std::string* serialized_command,
24468     AuthorizationDelegate* authorization_delegate) {
24469   VLOG(3) << __func__;
24470   TPM_RC rc = TPM_RC_SUCCESS;
24471   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24472   UINT32 command_size = 10;  // Header size.
24473   std::string handle_section_bytes;
24474   std::string parameter_section_bytes;
24475   TPM_CC command_code = TPM_CC_PolicyAuthValue;
24476   bool is_command_parameter_encryption_possible = false;
24477   bool is_response_parameter_encryption_possible = false;
24478   std::string command_code_bytes;
24479   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24480   if (rc != TPM_RC_SUCCESS) {
24481     return rc;
24482   }
24483   std::string policy_session_bytes;
24484   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24485   if (rc != TPM_RC_SUCCESS) {
24486     return rc;
24487   }
24488   std::unique_ptr<crypto::SecureHash> hash(
24489       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24490   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24491   hash->Update(policy_session_name.data(), policy_session_name.size());
24492   handle_section_bytes += policy_session_bytes;
24493   command_size += policy_session_bytes.size();
24494   std::string command_hash(32, 0);
24495   hash->Finish(std::data(command_hash), command_hash.size());
24496   std::string authorization_section_bytes;
24497   std::string authorization_size_bytes;
24498   if (authorization_delegate) {
24499     if (!authorization_delegate->GetCommandAuthorization(
24500             command_hash, is_command_parameter_encryption_possible,
24501             is_response_parameter_encryption_possible,
24502             &authorization_section_bytes)) {
24503       return TRUNKS_RC_AUTHORIZATION_FAILED;
24504     }
24505     if (!authorization_section_bytes.empty()) {
24506       tag = TPM_ST_SESSIONS;
24507       std::string tmp;
24508       rc = Serialize_UINT32(authorization_section_bytes.size(),
24509                             &authorization_size_bytes);
24510       if (rc != TPM_RC_SUCCESS) {
24511         return rc;
24512       }
24513       command_size +=
24514           authorization_size_bytes.size() + authorization_section_bytes.size();
24515     }
24516   }
24517   std::string tag_bytes;
24518   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24519   if (rc != TPM_RC_SUCCESS) {
24520     return rc;
24521   }
24522   std::string command_size_bytes;
24523   rc = Serialize_UINT32(command_size, &command_size_bytes);
24524   if (rc != TPM_RC_SUCCESS) {
24525     return rc;
24526   }
24527   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24528                         handle_section_bytes + authorization_size_bytes +
24529                         authorization_section_bytes + parameter_section_bytes;
24530   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24531   VLOG(2) << "Command: "
24532           << base::HexEncode(serialized_command->data(),
24533                              serialized_command->size());
24534   return TPM_RC_SUCCESS;
24535 }
24536 
ParseResponse_PolicyAuthValue(const std::string & response,AuthorizationDelegate * authorization_delegate)24537 TPM_RC Tpm::ParseResponse_PolicyAuthValue(
24538     const std::string& response,
24539     AuthorizationDelegate* authorization_delegate) {
24540   VLOG(3) << __func__;
24541   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24542   TPM_RC rc = TPM_RC_SUCCESS;
24543   std::string buffer(response);
24544   TPM_ST tag;
24545   std::string tag_bytes;
24546   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24547   if (rc != TPM_RC_SUCCESS) {
24548     return rc;
24549   }
24550   UINT32 response_size;
24551   std::string response_size_bytes;
24552   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24553   if (rc != TPM_RC_SUCCESS) {
24554     return rc;
24555   }
24556   TPM_RC response_code;
24557   std::string response_code_bytes;
24558   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24559   if (rc != TPM_RC_SUCCESS) {
24560     return rc;
24561   }
24562   if (response_size != response.size()) {
24563     return TPM_RC_SIZE;
24564   }
24565   if (response_code != TPM_RC_SUCCESS) {
24566     return response_code;
24567   }
24568   TPM_CC command_code = TPM_CC_PolicyAuthValue;
24569   std::string command_code_bytes;
24570   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24571   if (rc != TPM_RC_SUCCESS) {
24572     return rc;
24573   }
24574   std::string authorization_section_bytes;
24575   if (tag == TPM_ST_SESSIONS) {
24576     UINT32 parameter_section_size = buffer.size();
24577     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24578     if (rc != TPM_RC_SUCCESS) {
24579       return rc;
24580     }
24581     if (parameter_section_size > buffer.size()) {
24582       return TPM_RC_INSUFFICIENT;
24583     }
24584     authorization_section_bytes = buffer.substr(parameter_section_size);
24585     // Keep the parameter section in |buffer|.
24586     buffer.erase(parameter_section_size);
24587   }
24588   std::unique_ptr<crypto::SecureHash> hash(
24589       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24590   hash->Update(response_code_bytes.data(), response_code_bytes.size());
24591   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24592   hash->Update(buffer.data(), buffer.size());
24593   std::string response_hash(32, 0);
24594   hash->Finish(std::data(response_hash), response_hash.size());
24595   if (tag == TPM_ST_SESSIONS) {
24596     if (!authorization_delegate)
24597       return TRUNKS_RC_AUTHORIZATION_FAILED;
24598     if (!authorization_delegate->CheckResponseAuthorization(
24599             response_hash, authorization_section_bytes)) {
24600       return TRUNKS_RC_AUTHORIZATION_FAILED;
24601     }
24602   }
24603   return TPM_RC_SUCCESS;
24604 }
24605 
PolicyAuthValueErrorCallback(Tpm::PolicyAuthValueResponse callback,TPM_RC response_code)24606 void PolicyAuthValueErrorCallback(Tpm::PolicyAuthValueResponse callback,
24607                                   TPM_RC response_code) {
24608   VLOG(1) << __func__;
24609   std::move(callback).Run(response_code);
24610 }
24611 
PolicyAuthValueResponseParser(Tpm::PolicyAuthValueResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24612 void PolicyAuthValueResponseParser(
24613     Tpm::PolicyAuthValueResponse callback,
24614     AuthorizationDelegate* authorization_delegate,
24615     const std::string& response) {
24616   VLOG(1) << __func__;
24617   TPM_RC rc =
24618       Tpm::ParseResponse_PolicyAuthValue(response, authorization_delegate);
24619   if (rc != TPM_RC_SUCCESS) {
24620     base::OnceCallback<void(TPM_RC)> error_reporter =
24621         base::BindOnce(PolicyAuthValueErrorCallback, std::move(callback));
24622     std::move(error_reporter).Run(rc);
24623     return;
24624   }
24625   std::move(callback).Run(rc);
24626 }
24627 
PolicyAuthValue(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyAuthValueResponse callback)24628 void Tpm::PolicyAuthValue(const TPMI_SH_POLICY& policy_session,
24629                           const std::string& policy_session_name,
24630                           AuthorizationDelegate* authorization_delegate,
24631                           PolicyAuthValueResponse callback) {
24632   VLOG(1) << __func__;
24633   std::string command;
24634   TPM_RC rc = SerializeCommand_PolicyAuthValue(
24635       policy_session, policy_session_name, &command, authorization_delegate);
24636   if (rc != TPM_RC_SUCCESS) {
24637     base::OnceCallback<void(TPM_RC)> error_reporter =
24638         base::BindOnce(PolicyAuthValueErrorCallback, std::move(callback));
24639     std::move(error_reporter).Run(rc);
24640     return;
24641   }
24642   base::OnceCallback<void(const std::string&)> parser =
24643       base::BindOnce(PolicyAuthValueResponseParser, std::move(callback),
24644                      authorization_delegate);
24645   transceiver_->SendCommand(command, std::move(parser));
24646 }
24647 
PolicyAuthValueSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)24648 TPM_RC Tpm::PolicyAuthValueSync(const TPMI_SH_POLICY& policy_session,
24649                                 const std::string& policy_session_name,
24650                                 AuthorizationDelegate* authorization_delegate) {
24651   VLOG(1) << __func__;
24652   std::string command;
24653   TPM_RC rc = SerializeCommand_PolicyAuthValue(
24654       policy_session, policy_session_name, &command, authorization_delegate);
24655   if (rc != TPM_RC_SUCCESS) {
24656     return rc;
24657   }
24658   std::string response = transceiver_->SendCommandAndWait(command);
24659   rc = ParseResponse_PolicyAuthValue(response, authorization_delegate);
24660   return rc;
24661 }
24662 
SerializeCommand_PolicyPassword(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24663 TPM_RC Tpm::SerializeCommand_PolicyPassword(
24664     const TPMI_SH_POLICY& policy_session,
24665     const std::string& policy_session_name,
24666     std::string* serialized_command,
24667     AuthorizationDelegate* authorization_delegate) {
24668   VLOG(3) << __func__;
24669   TPM_RC rc = TPM_RC_SUCCESS;
24670   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24671   UINT32 command_size = 10;  // Header size.
24672   std::string handle_section_bytes;
24673   std::string parameter_section_bytes;
24674   TPM_CC command_code = TPM_CC_PolicyPassword;
24675   bool is_command_parameter_encryption_possible = false;
24676   bool is_response_parameter_encryption_possible = false;
24677   std::string command_code_bytes;
24678   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24679   if (rc != TPM_RC_SUCCESS) {
24680     return rc;
24681   }
24682   std::string policy_session_bytes;
24683   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24684   if (rc != TPM_RC_SUCCESS) {
24685     return rc;
24686   }
24687   std::unique_ptr<crypto::SecureHash> hash(
24688       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24689   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24690   hash->Update(policy_session_name.data(), policy_session_name.size());
24691   handle_section_bytes += policy_session_bytes;
24692   command_size += policy_session_bytes.size();
24693   std::string command_hash(32, 0);
24694   hash->Finish(std::data(command_hash), command_hash.size());
24695   std::string authorization_section_bytes;
24696   std::string authorization_size_bytes;
24697   if (authorization_delegate) {
24698     if (!authorization_delegate->GetCommandAuthorization(
24699             command_hash, is_command_parameter_encryption_possible,
24700             is_response_parameter_encryption_possible,
24701             &authorization_section_bytes)) {
24702       return TRUNKS_RC_AUTHORIZATION_FAILED;
24703     }
24704     if (!authorization_section_bytes.empty()) {
24705       tag = TPM_ST_SESSIONS;
24706       std::string tmp;
24707       rc = Serialize_UINT32(authorization_section_bytes.size(),
24708                             &authorization_size_bytes);
24709       if (rc != TPM_RC_SUCCESS) {
24710         return rc;
24711       }
24712       command_size +=
24713           authorization_size_bytes.size() + authorization_section_bytes.size();
24714     }
24715   }
24716   std::string tag_bytes;
24717   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24718   if (rc != TPM_RC_SUCCESS) {
24719     return rc;
24720   }
24721   std::string command_size_bytes;
24722   rc = Serialize_UINT32(command_size, &command_size_bytes);
24723   if (rc != TPM_RC_SUCCESS) {
24724     return rc;
24725   }
24726   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24727                         handle_section_bytes + authorization_size_bytes +
24728                         authorization_section_bytes + parameter_section_bytes;
24729   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24730   VLOG(2) << "Command: "
24731           << base::HexEncode(serialized_command->data(),
24732                              serialized_command->size());
24733   return TPM_RC_SUCCESS;
24734 }
24735 
ParseResponse_PolicyPassword(const std::string & response,AuthorizationDelegate * authorization_delegate)24736 TPM_RC Tpm::ParseResponse_PolicyPassword(
24737     const std::string& response,
24738     AuthorizationDelegate* authorization_delegate) {
24739   VLOG(3) << __func__;
24740   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24741   TPM_RC rc = TPM_RC_SUCCESS;
24742   std::string buffer(response);
24743   TPM_ST tag;
24744   std::string tag_bytes;
24745   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24746   if (rc != TPM_RC_SUCCESS) {
24747     return rc;
24748   }
24749   UINT32 response_size;
24750   std::string response_size_bytes;
24751   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24752   if (rc != TPM_RC_SUCCESS) {
24753     return rc;
24754   }
24755   TPM_RC response_code;
24756   std::string response_code_bytes;
24757   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24758   if (rc != TPM_RC_SUCCESS) {
24759     return rc;
24760   }
24761   if (response_size != response.size()) {
24762     return TPM_RC_SIZE;
24763   }
24764   if (response_code != TPM_RC_SUCCESS) {
24765     return response_code;
24766   }
24767   TPM_CC command_code = TPM_CC_PolicyPassword;
24768   std::string command_code_bytes;
24769   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24770   if (rc != TPM_RC_SUCCESS) {
24771     return rc;
24772   }
24773   std::string authorization_section_bytes;
24774   if (tag == TPM_ST_SESSIONS) {
24775     UINT32 parameter_section_size = buffer.size();
24776     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24777     if (rc != TPM_RC_SUCCESS) {
24778       return rc;
24779     }
24780     if (parameter_section_size > buffer.size()) {
24781       return TPM_RC_INSUFFICIENT;
24782     }
24783     authorization_section_bytes = buffer.substr(parameter_section_size);
24784     // Keep the parameter section in |buffer|.
24785     buffer.erase(parameter_section_size);
24786   }
24787   std::unique_ptr<crypto::SecureHash> hash(
24788       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24789   hash->Update(response_code_bytes.data(), response_code_bytes.size());
24790   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24791   hash->Update(buffer.data(), buffer.size());
24792   std::string response_hash(32, 0);
24793   hash->Finish(std::data(response_hash), response_hash.size());
24794   if (tag == TPM_ST_SESSIONS) {
24795     if (!authorization_delegate)
24796       return TRUNKS_RC_AUTHORIZATION_FAILED;
24797     if (!authorization_delegate->CheckResponseAuthorization(
24798             response_hash, authorization_section_bytes)) {
24799       return TRUNKS_RC_AUTHORIZATION_FAILED;
24800     }
24801   }
24802   return TPM_RC_SUCCESS;
24803 }
24804 
PolicyPasswordErrorCallback(Tpm::PolicyPasswordResponse callback,TPM_RC response_code)24805 void PolicyPasswordErrorCallback(Tpm::PolicyPasswordResponse callback,
24806                                  TPM_RC response_code) {
24807   VLOG(1) << __func__;
24808   std::move(callback).Run(response_code);
24809 }
24810 
PolicyPasswordResponseParser(Tpm::PolicyPasswordResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)24811 void PolicyPasswordResponseParser(Tpm::PolicyPasswordResponse callback,
24812                                   AuthorizationDelegate* authorization_delegate,
24813                                   const std::string& response) {
24814   VLOG(1) << __func__;
24815   TPM_RC rc =
24816       Tpm::ParseResponse_PolicyPassword(response, authorization_delegate);
24817   if (rc != TPM_RC_SUCCESS) {
24818     base::OnceCallback<void(TPM_RC)> error_reporter =
24819         base::BindOnce(PolicyPasswordErrorCallback, std::move(callback));
24820     std::move(error_reporter).Run(rc);
24821     return;
24822   }
24823   std::move(callback).Run(rc);
24824 }
24825 
PolicyPassword(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyPasswordResponse callback)24826 void Tpm::PolicyPassword(const TPMI_SH_POLICY& policy_session,
24827                          const std::string& policy_session_name,
24828                          AuthorizationDelegate* authorization_delegate,
24829                          PolicyPasswordResponse callback) {
24830   VLOG(1) << __func__;
24831   std::string command;
24832   TPM_RC rc = SerializeCommand_PolicyPassword(
24833       policy_session, policy_session_name, &command, authorization_delegate);
24834   if (rc != TPM_RC_SUCCESS) {
24835     base::OnceCallback<void(TPM_RC)> error_reporter =
24836         base::BindOnce(PolicyPasswordErrorCallback, std::move(callback));
24837     std::move(error_reporter).Run(rc);
24838     return;
24839   }
24840   base::OnceCallback<void(const std::string&)> parser =
24841       base::BindOnce(PolicyPasswordResponseParser, std::move(callback),
24842                      authorization_delegate);
24843   transceiver_->SendCommand(command, std::move(parser));
24844 }
24845 
PolicyPasswordSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate)24846 TPM_RC Tpm::PolicyPasswordSync(const TPMI_SH_POLICY& policy_session,
24847                                const std::string& policy_session_name,
24848                                AuthorizationDelegate* authorization_delegate) {
24849   VLOG(1) << __func__;
24850   std::string command;
24851   TPM_RC rc = SerializeCommand_PolicyPassword(
24852       policy_session, policy_session_name, &command, authorization_delegate);
24853   if (rc != TPM_RC_SUCCESS) {
24854     return rc;
24855   }
24856   std::string response = transceiver_->SendCommandAndWait(command);
24857   rc = ParseResponse_PolicyPassword(response, authorization_delegate);
24858   return rc;
24859 }
24860 
SerializeCommand_PolicyGetDigest(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)24861 TPM_RC Tpm::SerializeCommand_PolicyGetDigest(
24862     const TPMI_SH_POLICY& policy_session,
24863     const std::string& policy_session_name,
24864     std::string* serialized_command,
24865     AuthorizationDelegate* authorization_delegate) {
24866   VLOG(3) << __func__;
24867   TPM_RC rc = TPM_RC_SUCCESS;
24868   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
24869   UINT32 command_size = 10;  // Header size.
24870   std::string handle_section_bytes;
24871   std::string parameter_section_bytes;
24872   TPM_CC command_code = TPM_CC_PolicyGetDigest;
24873   bool is_command_parameter_encryption_possible = false;
24874   bool is_response_parameter_encryption_possible = true;
24875   std::string command_code_bytes;
24876   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24877   if (rc != TPM_RC_SUCCESS) {
24878     return rc;
24879   }
24880   std::string policy_session_bytes;
24881   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
24882   if (rc != TPM_RC_SUCCESS) {
24883     return rc;
24884   }
24885   std::unique_ptr<crypto::SecureHash> hash(
24886       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24887   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24888   hash->Update(policy_session_name.data(), policy_session_name.size());
24889   handle_section_bytes += policy_session_bytes;
24890   command_size += policy_session_bytes.size();
24891   std::string command_hash(32, 0);
24892   hash->Finish(std::data(command_hash), command_hash.size());
24893   std::string authorization_section_bytes;
24894   std::string authorization_size_bytes;
24895   if (authorization_delegate) {
24896     if (!authorization_delegate->GetCommandAuthorization(
24897             command_hash, is_command_parameter_encryption_possible,
24898             is_response_parameter_encryption_possible,
24899             &authorization_section_bytes)) {
24900       return TRUNKS_RC_AUTHORIZATION_FAILED;
24901     }
24902     if (!authorization_section_bytes.empty()) {
24903       tag = TPM_ST_SESSIONS;
24904       std::string tmp;
24905       rc = Serialize_UINT32(authorization_section_bytes.size(),
24906                             &authorization_size_bytes);
24907       if (rc != TPM_RC_SUCCESS) {
24908         return rc;
24909       }
24910       command_size +=
24911           authorization_size_bytes.size() + authorization_section_bytes.size();
24912     }
24913   }
24914   std::string tag_bytes;
24915   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
24916   if (rc != TPM_RC_SUCCESS) {
24917     return rc;
24918   }
24919   std::string command_size_bytes;
24920   rc = Serialize_UINT32(command_size, &command_size_bytes);
24921   if (rc != TPM_RC_SUCCESS) {
24922     return rc;
24923   }
24924   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
24925                         handle_section_bytes + authorization_size_bytes +
24926                         authorization_section_bytes + parameter_section_bytes;
24927   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
24928   VLOG(2) << "Command: "
24929           << base::HexEncode(serialized_command->data(),
24930                              serialized_command->size());
24931   return TPM_RC_SUCCESS;
24932 }
24933 
ParseResponse_PolicyGetDigest(const std::string & response,TPM2B_DIGEST * policy_digest,AuthorizationDelegate * authorization_delegate)24934 TPM_RC Tpm::ParseResponse_PolicyGetDigest(
24935     const std::string& response,
24936     TPM2B_DIGEST* policy_digest,
24937     AuthorizationDelegate* authorization_delegate) {
24938   VLOG(3) << __func__;
24939   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
24940   TPM_RC rc = TPM_RC_SUCCESS;
24941   std::string buffer(response);
24942   TPM_ST tag;
24943   std::string tag_bytes;
24944   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
24945   if (rc != TPM_RC_SUCCESS) {
24946     return rc;
24947   }
24948   UINT32 response_size;
24949   std::string response_size_bytes;
24950   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
24951   if (rc != TPM_RC_SUCCESS) {
24952     return rc;
24953   }
24954   TPM_RC response_code;
24955   std::string response_code_bytes;
24956   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
24957   if (rc != TPM_RC_SUCCESS) {
24958     return rc;
24959   }
24960   if (response_size != response.size()) {
24961     return TPM_RC_SIZE;
24962   }
24963   if (response_code != TPM_RC_SUCCESS) {
24964     return response_code;
24965   }
24966   TPM_CC command_code = TPM_CC_PolicyGetDigest;
24967   std::string command_code_bytes;
24968   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
24969   if (rc != TPM_RC_SUCCESS) {
24970     return rc;
24971   }
24972   std::string authorization_section_bytes;
24973   if (tag == TPM_ST_SESSIONS) {
24974     UINT32 parameter_section_size = buffer.size();
24975     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
24976     if (rc != TPM_RC_SUCCESS) {
24977       return rc;
24978     }
24979     if (parameter_section_size > buffer.size()) {
24980       return TPM_RC_INSUFFICIENT;
24981     }
24982     authorization_section_bytes = buffer.substr(parameter_section_size);
24983     // Keep the parameter section in |buffer|.
24984     buffer.erase(parameter_section_size);
24985   }
24986   std::unique_ptr<crypto::SecureHash> hash(
24987       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
24988   hash->Update(response_code_bytes.data(), response_code_bytes.size());
24989   hash->Update(command_code_bytes.data(), command_code_bytes.size());
24990   hash->Update(buffer.data(), buffer.size());
24991   std::string response_hash(32, 0);
24992   hash->Finish(std::data(response_hash), response_hash.size());
24993   if (tag == TPM_ST_SESSIONS) {
24994     if (!authorization_delegate)
24995       return TRUNKS_RC_AUTHORIZATION_FAILED;
24996     if (!authorization_delegate->CheckResponseAuthorization(
24997             response_hash, authorization_section_bytes)) {
24998       return TRUNKS_RC_AUTHORIZATION_FAILED;
24999     }
25000   }
25001   if (tag == TPM_ST_SESSIONS) {
25002     if (!authorization_delegate)
25003       return TRUNKS_RC_AUTHORIZATION_FAILED;
25004 
25005     // Parse the encrypted parameter size.
25006     UINT16 size;
25007     std::string size_buffer = buffer.substr(0, 2);
25008     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
25009       return result;
25010     }
25011     if (buffer.size() < 2 + size) {
25012       return TPM_RC_INSUFFICIENT;
25013     }
25014 
25015     // Decrypt just the parameter data, not the size.
25016     std::string decrypted_data = buffer.substr(2, size);
25017     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
25018       return TRUNKS_RC_ENCRYPTION_FAILED;
25019     }
25020     buffer.replace(2, size, decrypted_data);
25021   }
25022   std::string policy_digest_bytes;
25023   rc = Parse_TPM2B_DIGEST(&buffer, policy_digest, &policy_digest_bytes);
25024   if (rc != TPM_RC_SUCCESS) {
25025     return rc;
25026   }
25027   return TPM_RC_SUCCESS;
25028 }
25029 
PolicyGetDigestErrorCallback(Tpm::PolicyGetDigestResponse callback,TPM_RC response_code)25030 void PolicyGetDigestErrorCallback(Tpm::PolicyGetDigestResponse callback,
25031                                   TPM_RC response_code) {
25032   VLOG(1) << __func__;
25033   std::move(callback).Run(response_code, TPM2B_DIGEST());
25034 }
25035 
PolicyGetDigestResponseParser(Tpm::PolicyGetDigestResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25036 void PolicyGetDigestResponseParser(
25037     Tpm::PolicyGetDigestResponse callback,
25038     AuthorizationDelegate* authorization_delegate,
25039     const std::string& response) {
25040   VLOG(1) << __func__;
25041   TPM2B_DIGEST policy_digest;
25042   TPM_RC rc = Tpm::ParseResponse_PolicyGetDigest(response, &policy_digest,
25043                                                  authorization_delegate);
25044   if (rc != TPM_RC_SUCCESS) {
25045     base::OnceCallback<void(TPM_RC)> error_reporter =
25046         base::BindOnce(PolicyGetDigestErrorCallback, std::move(callback));
25047     std::move(error_reporter).Run(rc);
25048     return;
25049   }
25050   std::move(callback).Run(rc, policy_digest);
25051 }
25052 
PolicyGetDigest(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,AuthorizationDelegate * authorization_delegate,PolicyGetDigestResponse callback)25053 void Tpm::PolicyGetDigest(const TPMI_SH_POLICY& policy_session,
25054                           const std::string& policy_session_name,
25055                           AuthorizationDelegate* authorization_delegate,
25056                           PolicyGetDigestResponse callback) {
25057   VLOG(1) << __func__;
25058   std::string command;
25059   TPM_RC rc = SerializeCommand_PolicyGetDigest(
25060       policy_session, policy_session_name, &command, authorization_delegate);
25061   if (rc != TPM_RC_SUCCESS) {
25062     base::OnceCallback<void(TPM_RC)> error_reporter =
25063         base::BindOnce(PolicyGetDigestErrorCallback, std::move(callback));
25064     std::move(error_reporter).Run(rc);
25065     return;
25066   }
25067   base::OnceCallback<void(const std::string&)> parser =
25068       base::BindOnce(PolicyGetDigestResponseParser, std::move(callback),
25069                      authorization_delegate);
25070   transceiver_->SendCommand(command, std::move(parser));
25071 }
25072 
PolicyGetDigestSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,TPM2B_DIGEST * policy_digest,AuthorizationDelegate * authorization_delegate)25073 TPM_RC Tpm::PolicyGetDigestSync(const TPMI_SH_POLICY& policy_session,
25074                                 const std::string& policy_session_name,
25075                                 TPM2B_DIGEST* policy_digest,
25076                                 AuthorizationDelegate* authorization_delegate) {
25077   VLOG(1) << __func__;
25078   std::string command;
25079   TPM_RC rc = SerializeCommand_PolicyGetDigest(
25080       policy_session, policy_session_name, &command, authorization_delegate);
25081   if (rc != TPM_RC_SUCCESS) {
25082     return rc;
25083   }
25084   std::string response = transceiver_->SendCommandAndWait(command);
25085   rc = ParseResponse_PolicyGetDigest(response, policy_digest,
25086                                      authorization_delegate);
25087   return rc;
25088 }
25089 
SerializeCommand_PolicyNvWritten(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25090 TPM_RC Tpm::SerializeCommand_PolicyNvWritten(
25091     const TPMI_SH_POLICY& policy_session,
25092     const std::string& policy_session_name,
25093     const TPMI_YES_NO& written_set,
25094     std::string* serialized_command,
25095     AuthorizationDelegate* authorization_delegate) {
25096   VLOG(3) << __func__;
25097   TPM_RC rc = TPM_RC_SUCCESS;
25098   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25099   UINT32 command_size = 10;  // Header size.
25100   std::string handle_section_bytes;
25101   std::string parameter_section_bytes;
25102   TPM_CC command_code = TPM_CC_PolicyNvWritten;
25103   bool is_command_parameter_encryption_possible = false;
25104   bool is_response_parameter_encryption_possible = false;
25105   std::string command_code_bytes;
25106   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25107   if (rc != TPM_RC_SUCCESS) {
25108     return rc;
25109   }
25110   std::string policy_session_bytes;
25111   rc = Serialize_TPMI_SH_POLICY(policy_session, &policy_session_bytes);
25112   if (rc != TPM_RC_SUCCESS) {
25113     return rc;
25114   }
25115   std::string written_set_bytes;
25116   rc = Serialize_TPMI_YES_NO(written_set, &written_set_bytes);
25117   if (rc != TPM_RC_SUCCESS) {
25118     return rc;
25119   }
25120   std::unique_ptr<crypto::SecureHash> hash(
25121       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25122   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25123   hash->Update(policy_session_name.data(), policy_session_name.size());
25124   handle_section_bytes += policy_session_bytes;
25125   command_size += policy_session_bytes.size();
25126   hash->Update(written_set_bytes.data(), written_set_bytes.size());
25127   parameter_section_bytes += written_set_bytes;
25128   command_size += written_set_bytes.size();
25129   std::string command_hash(32, 0);
25130   hash->Finish(std::data(command_hash), command_hash.size());
25131   std::string authorization_section_bytes;
25132   std::string authorization_size_bytes;
25133   if (authorization_delegate) {
25134     if (!authorization_delegate->GetCommandAuthorization(
25135             command_hash, is_command_parameter_encryption_possible,
25136             is_response_parameter_encryption_possible,
25137             &authorization_section_bytes)) {
25138       return TRUNKS_RC_AUTHORIZATION_FAILED;
25139     }
25140     if (!authorization_section_bytes.empty()) {
25141       tag = TPM_ST_SESSIONS;
25142       std::string tmp;
25143       rc = Serialize_UINT32(authorization_section_bytes.size(),
25144                             &authorization_size_bytes);
25145       if (rc != TPM_RC_SUCCESS) {
25146         return rc;
25147       }
25148       command_size +=
25149           authorization_size_bytes.size() + authorization_section_bytes.size();
25150     }
25151   }
25152   std::string tag_bytes;
25153   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25154   if (rc != TPM_RC_SUCCESS) {
25155     return rc;
25156   }
25157   std::string command_size_bytes;
25158   rc = Serialize_UINT32(command_size, &command_size_bytes);
25159   if (rc != TPM_RC_SUCCESS) {
25160     return rc;
25161   }
25162   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25163                         handle_section_bytes + authorization_size_bytes +
25164                         authorization_section_bytes + parameter_section_bytes;
25165   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25166   VLOG(2) << "Command: "
25167           << base::HexEncode(serialized_command->data(),
25168                              serialized_command->size());
25169   return TPM_RC_SUCCESS;
25170 }
25171 
ParseResponse_PolicyNvWritten(const std::string & response,AuthorizationDelegate * authorization_delegate)25172 TPM_RC Tpm::ParseResponse_PolicyNvWritten(
25173     const std::string& response,
25174     AuthorizationDelegate* authorization_delegate) {
25175   VLOG(3) << __func__;
25176   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25177   TPM_RC rc = TPM_RC_SUCCESS;
25178   std::string buffer(response);
25179   TPM_ST tag;
25180   std::string tag_bytes;
25181   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25182   if (rc != TPM_RC_SUCCESS) {
25183     return rc;
25184   }
25185   UINT32 response_size;
25186   std::string response_size_bytes;
25187   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25188   if (rc != TPM_RC_SUCCESS) {
25189     return rc;
25190   }
25191   TPM_RC response_code;
25192   std::string response_code_bytes;
25193   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25194   if (rc != TPM_RC_SUCCESS) {
25195     return rc;
25196   }
25197   if (response_size != response.size()) {
25198     return TPM_RC_SIZE;
25199   }
25200   if (response_code != TPM_RC_SUCCESS) {
25201     return response_code;
25202   }
25203   TPM_CC command_code = TPM_CC_PolicyNvWritten;
25204   std::string command_code_bytes;
25205   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25206   if (rc != TPM_RC_SUCCESS) {
25207     return rc;
25208   }
25209   std::string authorization_section_bytes;
25210   if (tag == TPM_ST_SESSIONS) {
25211     UINT32 parameter_section_size = buffer.size();
25212     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25213     if (rc != TPM_RC_SUCCESS) {
25214       return rc;
25215     }
25216     if (parameter_section_size > buffer.size()) {
25217       return TPM_RC_INSUFFICIENT;
25218     }
25219     authorization_section_bytes = buffer.substr(parameter_section_size);
25220     // Keep the parameter section in |buffer|.
25221     buffer.erase(parameter_section_size);
25222   }
25223   std::unique_ptr<crypto::SecureHash> hash(
25224       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25225   hash->Update(response_code_bytes.data(), response_code_bytes.size());
25226   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25227   hash->Update(buffer.data(), buffer.size());
25228   std::string response_hash(32, 0);
25229   hash->Finish(std::data(response_hash), response_hash.size());
25230   if (tag == TPM_ST_SESSIONS) {
25231     if (!authorization_delegate)
25232       return TRUNKS_RC_AUTHORIZATION_FAILED;
25233     if (!authorization_delegate->CheckResponseAuthorization(
25234             response_hash, authorization_section_bytes)) {
25235       return TRUNKS_RC_AUTHORIZATION_FAILED;
25236     }
25237   }
25238   return TPM_RC_SUCCESS;
25239 }
25240 
PolicyNvWrittenErrorCallback(Tpm::PolicyNvWrittenResponse callback,TPM_RC response_code)25241 void PolicyNvWrittenErrorCallback(Tpm::PolicyNvWrittenResponse callback,
25242                                   TPM_RC response_code) {
25243   VLOG(1) << __func__;
25244   std::move(callback).Run(response_code);
25245 }
25246 
PolicyNvWrittenResponseParser(Tpm::PolicyNvWrittenResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25247 void PolicyNvWrittenResponseParser(
25248     Tpm::PolicyNvWrittenResponse callback,
25249     AuthorizationDelegate* authorization_delegate,
25250     const std::string& response) {
25251   VLOG(1) << __func__;
25252   TPM_RC rc =
25253       Tpm::ParseResponse_PolicyNvWritten(response, authorization_delegate);
25254   if (rc != TPM_RC_SUCCESS) {
25255     base::OnceCallback<void(TPM_RC)> error_reporter =
25256         base::BindOnce(PolicyNvWrittenErrorCallback, std::move(callback));
25257     std::move(error_reporter).Run(rc);
25258     return;
25259   }
25260   std::move(callback).Run(rc);
25261 }
25262 
PolicyNvWritten(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,AuthorizationDelegate * authorization_delegate,PolicyNvWrittenResponse callback)25263 void Tpm::PolicyNvWritten(const TPMI_SH_POLICY& policy_session,
25264                           const std::string& policy_session_name,
25265                           const TPMI_YES_NO& written_set,
25266                           AuthorizationDelegate* authorization_delegate,
25267                           PolicyNvWrittenResponse callback) {
25268   VLOG(1) << __func__;
25269   std::string command;
25270   TPM_RC rc = SerializeCommand_PolicyNvWritten(
25271       policy_session, policy_session_name, written_set, &command,
25272       authorization_delegate);
25273   if (rc != TPM_RC_SUCCESS) {
25274     base::OnceCallback<void(TPM_RC)> error_reporter =
25275         base::BindOnce(PolicyNvWrittenErrorCallback, std::move(callback));
25276     std::move(error_reporter).Run(rc);
25277     return;
25278   }
25279   base::OnceCallback<void(const std::string&)> parser =
25280       base::BindOnce(PolicyNvWrittenResponseParser, std::move(callback),
25281                      authorization_delegate);
25282   transceiver_->SendCommand(command, std::move(parser));
25283 }
25284 
PolicyNvWrittenSync(const TPMI_SH_POLICY & policy_session,const std::string & policy_session_name,const TPMI_YES_NO & written_set,AuthorizationDelegate * authorization_delegate)25285 TPM_RC Tpm::PolicyNvWrittenSync(const TPMI_SH_POLICY& policy_session,
25286                                 const std::string& policy_session_name,
25287                                 const TPMI_YES_NO& written_set,
25288                                 AuthorizationDelegate* authorization_delegate) {
25289   VLOG(1) << __func__;
25290   std::string command;
25291   TPM_RC rc = SerializeCommand_PolicyNvWritten(
25292       policy_session, policy_session_name, written_set, &command,
25293       authorization_delegate);
25294   if (rc != TPM_RC_SUCCESS) {
25295     return rc;
25296   }
25297   std::string response = transceiver_->SendCommandAndWait(command);
25298   rc = ParseResponse_PolicyNvWritten(response, authorization_delegate);
25299   return rc;
25300 }
25301 
SerializeCommand_CreatePrimary(const TPMI_RH_HIERARCHY & primary_handle,const std::string & primary_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25302 TPM_RC Tpm::SerializeCommand_CreatePrimary(
25303     const TPMI_RH_HIERARCHY& primary_handle,
25304     const std::string& primary_handle_name,
25305     const TPM2B_SENSITIVE_CREATE& in_sensitive,
25306     const TPM2B_PUBLIC& in_public,
25307     const TPM2B_DATA& outside_info,
25308     const TPML_PCR_SELECTION& creation_pcr,
25309     std::string* serialized_command,
25310     AuthorizationDelegate* authorization_delegate) {
25311   VLOG(3) << __func__;
25312   TPM_RC rc = TPM_RC_SUCCESS;
25313   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25314   UINT32 command_size = 10;  // Header size.
25315   std::string handle_section_bytes;
25316   std::string parameter_section_bytes;
25317   TPM_CC command_code = TPM_CC_CreatePrimary;
25318   bool is_command_parameter_encryption_possible = true;
25319   bool is_response_parameter_encryption_possible = true;
25320   std::string command_code_bytes;
25321   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25322   if (rc != TPM_RC_SUCCESS) {
25323     return rc;
25324   }
25325   std::string primary_handle_bytes;
25326   rc = Serialize_TPMI_RH_HIERARCHY(primary_handle, &primary_handle_bytes);
25327   if (rc != TPM_RC_SUCCESS) {
25328     return rc;
25329   }
25330   std::string in_sensitive_bytes;
25331   rc = Serialize_TPM2B_SENSITIVE_CREATE(in_sensitive, &in_sensitive_bytes);
25332   if (rc != TPM_RC_SUCCESS) {
25333     return rc;
25334   }
25335   std::string in_public_bytes;
25336   rc = Serialize_TPM2B_PUBLIC(in_public, &in_public_bytes);
25337   if (rc != TPM_RC_SUCCESS) {
25338     return rc;
25339   }
25340   std::string outside_info_bytes;
25341   rc = Serialize_TPM2B_DATA(outside_info, &outside_info_bytes);
25342   if (rc != TPM_RC_SUCCESS) {
25343     return rc;
25344   }
25345   std::string creation_pcr_bytes;
25346   rc = Serialize_TPML_PCR_SELECTION(creation_pcr, &creation_pcr_bytes);
25347   if (rc != TPM_RC_SUCCESS) {
25348     return rc;
25349   }
25350   if (authorization_delegate) {
25351     // Encrypt just the parameter data, not the size.
25352     std::string tmp = in_sensitive_bytes.substr(2);
25353     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
25354       return TRUNKS_RC_ENCRYPTION_FAILED;
25355     }
25356     in_sensitive_bytes.replace(2, std::string::npos, tmp);
25357   }
25358   std::unique_ptr<crypto::SecureHash> hash(
25359       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25360   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25361   hash->Update(primary_handle_name.data(), primary_handle_name.size());
25362   handle_section_bytes += primary_handle_bytes;
25363   command_size += primary_handle_bytes.size();
25364   hash->Update(in_sensitive_bytes.data(), in_sensitive_bytes.size());
25365   parameter_section_bytes += in_sensitive_bytes;
25366   command_size += in_sensitive_bytes.size();
25367   hash->Update(in_public_bytes.data(), in_public_bytes.size());
25368   parameter_section_bytes += in_public_bytes;
25369   command_size += in_public_bytes.size();
25370   hash->Update(outside_info_bytes.data(), outside_info_bytes.size());
25371   parameter_section_bytes += outside_info_bytes;
25372   command_size += outside_info_bytes.size();
25373   hash->Update(creation_pcr_bytes.data(), creation_pcr_bytes.size());
25374   parameter_section_bytes += creation_pcr_bytes;
25375   command_size += creation_pcr_bytes.size();
25376   std::string command_hash(32, 0);
25377   hash->Finish(std::data(command_hash), command_hash.size());
25378   std::string authorization_section_bytes;
25379   std::string authorization_size_bytes;
25380   if (authorization_delegate) {
25381     if (!authorization_delegate->GetCommandAuthorization(
25382             command_hash, is_command_parameter_encryption_possible,
25383             is_response_parameter_encryption_possible,
25384             &authorization_section_bytes)) {
25385       return TRUNKS_RC_AUTHORIZATION_FAILED;
25386     }
25387     if (!authorization_section_bytes.empty()) {
25388       tag = TPM_ST_SESSIONS;
25389       std::string tmp;
25390       rc = Serialize_UINT32(authorization_section_bytes.size(),
25391                             &authorization_size_bytes);
25392       if (rc != TPM_RC_SUCCESS) {
25393         return rc;
25394       }
25395       command_size +=
25396           authorization_size_bytes.size() + authorization_section_bytes.size();
25397     }
25398   }
25399   std::string tag_bytes;
25400   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25401   if (rc != TPM_RC_SUCCESS) {
25402     return rc;
25403   }
25404   std::string command_size_bytes;
25405   rc = Serialize_UINT32(command_size, &command_size_bytes);
25406   if (rc != TPM_RC_SUCCESS) {
25407     return rc;
25408   }
25409   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25410                         handle_section_bytes + authorization_size_bytes +
25411                         authorization_section_bytes + parameter_section_bytes;
25412   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25413   VLOG(2) << "Command: "
25414           << base::HexEncode(serialized_command->data(),
25415                              serialized_command->size());
25416   return TPM_RC_SUCCESS;
25417 }
25418 
ParseResponse_CreatePrimary(const std::string & response,TPM_HANDLE * object_handle,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)25419 TPM_RC Tpm::ParseResponse_CreatePrimary(
25420     const std::string& response,
25421     TPM_HANDLE* object_handle,
25422     TPM2B_PUBLIC* out_public,
25423     TPM2B_CREATION_DATA* creation_data,
25424     TPM2B_DIGEST* creation_hash,
25425     TPMT_TK_CREATION* creation_ticket,
25426     TPM2B_NAME* name,
25427     AuthorizationDelegate* authorization_delegate) {
25428   VLOG(3) << __func__;
25429   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25430   TPM_RC rc = TPM_RC_SUCCESS;
25431   std::string buffer(response);
25432   TPM_ST tag;
25433   std::string tag_bytes;
25434   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25435   if (rc != TPM_RC_SUCCESS) {
25436     return rc;
25437   }
25438   UINT32 response_size;
25439   std::string response_size_bytes;
25440   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25441   if (rc != TPM_RC_SUCCESS) {
25442     return rc;
25443   }
25444   TPM_RC response_code;
25445   std::string response_code_bytes;
25446   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25447   if (rc != TPM_RC_SUCCESS) {
25448     return rc;
25449   }
25450   if (response_size != response.size()) {
25451     return TPM_RC_SIZE;
25452   }
25453   if (response_code != TPM_RC_SUCCESS) {
25454     return response_code;
25455   }
25456   std::string object_handle_bytes;
25457   rc = Parse_TPM_HANDLE(&buffer, object_handle, &object_handle_bytes);
25458   if (rc != TPM_RC_SUCCESS) {
25459     return rc;
25460   }
25461   TPM_CC command_code = TPM_CC_CreatePrimary;
25462   std::string command_code_bytes;
25463   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25464   if (rc != TPM_RC_SUCCESS) {
25465     return rc;
25466   }
25467   std::string authorization_section_bytes;
25468   if (tag == TPM_ST_SESSIONS) {
25469     UINT32 parameter_section_size = buffer.size();
25470     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25471     if (rc != TPM_RC_SUCCESS) {
25472       return rc;
25473     }
25474     if (parameter_section_size > buffer.size()) {
25475       return TPM_RC_INSUFFICIENT;
25476     }
25477     authorization_section_bytes = buffer.substr(parameter_section_size);
25478     // Keep the parameter section in |buffer|.
25479     buffer.erase(parameter_section_size);
25480   }
25481   std::unique_ptr<crypto::SecureHash> hash(
25482       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25483   hash->Update(response_code_bytes.data(), response_code_bytes.size());
25484   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25485   hash->Update(buffer.data(), buffer.size());
25486   std::string response_hash(32, 0);
25487   hash->Finish(std::data(response_hash), response_hash.size());
25488   if (tag == TPM_ST_SESSIONS) {
25489     if (!authorization_delegate)
25490       return TRUNKS_RC_AUTHORIZATION_FAILED;
25491     if (!authorization_delegate->CheckResponseAuthorization(
25492             response_hash, authorization_section_bytes)) {
25493       return TRUNKS_RC_AUTHORIZATION_FAILED;
25494     }
25495   }
25496   if (tag == TPM_ST_SESSIONS) {
25497     if (!authorization_delegate)
25498       return TRUNKS_RC_AUTHORIZATION_FAILED;
25499 
25500     // Parse the encrypted parameter size.
25501     UINT16 size;
25502     std::string size_buffer = buffer.substr(0, 2);
25503     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
25504       return result;
25505     }
25506     if (buffer.size() < 2 + size) {
25507       return TPM_RC_INSUFFICIENT;
25508     }
25509 
25510     // Decrypt just the parameter data, not the size.
25511     std::string decrypted_data = buffer.substr(2, size);
25512     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
25513       return TRUNKS_RC_ENCRYPTION_FAILED;
25514     }
25515     buffer.replace(2, size, decrypted_data);
25516   }
25517   std::string out_public_bytes;
25518   rc = Parse_TPM2B_PUBLIC(&buffer, out_public, &out_public_bytes);
25519   if (rc != TPM_RC_SUCCESS) {
25520     return rc;
25521   }
25522   std::string creation_data_bytes;
25523   rc = Parse_TPM2B_CREATION_DATA(&buffer, creation_data, &creation_data_bytes);
25524   if (rc != TPM_RC_SUCCESS) {
25525     return rc;
25526   }
25527   std::string creation_hash_bytes;
25528   rc = Parse_TPM2B_DIGEST(&buffer, creation_hash, &creation_hash_bytes);
25529   if (rc != TPM_RC_SUCCESS) {
25530     return rc;
25531   }
25532   std::string creation_ticket_bytes;
25533   rc = Parse_TPMT_TK_CREATION(&buffer, creation_ticket, &creation_ticket_bytes);
25534   if (rc != TPM_RC_SUCCESS) {
25535     return rc;
25536   }
25537   std::string name_bytes;
25538   rc = Parse_TPM2B_NAME(&buffer, name, &name_bytes);
25539   if (rc != TPM_RC_SUCCESS) {
25540     return rc;
25541   }
25542   return TPM_RC_SUCCESS;
25543 }
25544 
CreatePrimaryErrorCallback(Tpm::CreatePrimaryResponse callback,TPM_RC response_code)25545 void CreatePrimaryErrorCallback(Tpm::CreatePrimaryResponse callback,
25546                                 TPM_RC response_code) {
25547   VLOG(1) << __func__;
25548   std::move(callback).Run(response_code, TPM_HANDLE(), TPM2B_PUBLIC(),
25549                           TPM2B_CREATION_DATA(), TPM2B_DIGEST(),
25550                           TPMT_TK_CREATION(), TPM2B_NAME());
25551 }
25552 
CreatePrimaryResponseParser(Tpm::CreatePrimaryResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25553 void CreatePrimaryResponseParser(Tpm::CreatePrimaryResponse callback,
25554                                  AuthorizationDelegate* authorization_delegate,
25555                                  const std::string& response) {
25556   VLOG(1) << __func__;
25557   TPM_HANDLE object_handle;
25558   TPM2B_PUBLIC out_public;
25559   TPM2B_CREATION_DATA creation_data;
25560   TPM2B_DIGEST creation_hash;
25561   TPMT_TK_CREATION creation_ticket;
25562   TPM2B_NAME name;
25563   TPM_RC rc = Tpm::ParseResponse_CreatePrimary(
25564       response, &object_handle, &out_public, &creation_data, &creation_hash,
25565       &creation_ticket, &name, authorization_delegate);
25566   if (rc != TPM_RC_SUCCESS) {
25567     base::OnceCallback<void(TPM_RC)> error_reporter =
25568         base::BindOnce(CreatePrimaryErrorCallback, std::move(callback));
25569     std::move(error_reporter).Run(rc);
25570     return;
25571   }
25572   std::move(callback).Run(rc, object_handle, out_public, creation_data,
25573                           creation_hash, creation_ticket, name);
25574 }
25575 
CreatePrimary(const TPMI_RH_HIERARCHY & primary_handle,const std::string & primary_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,AuthorizationDelegate * authorization_delegate,CreatePrimaryResponse callback)25576 void Tpm::CreatePrimary(const TPMI_RH_HIERARCHY& primary_handle,
25577                         const std::string& primary_handle_name,
25578                         const TPM2B_SENSITIVE_CREATE& in_sensitive,
25579                         const TPM2B_PUBLIC& in_public,
25580                         const TPM2B_DATA& outside_info,
25581                         const TPML_PCR_SELECTION& creation_pcr,
25582                         AuthorizationDelegate* authorization_delegate,
25583                         CreatePrimaryResponse callback) {
25584   VLOG(1) << __func__;
25585   std::string command;
25586   TPM_RC rc = SerializeCommand_CreatePrimary(
25587       primary_handle, primary_handle_name, in_sensitive, in_public,
25588       outside_info, creation_pcr, &command, authorization_delegate);
25589   if (rc != TPM_RC_SUCCESS) {
25590     base::OnceCallback<void(TPM_RC)> error_reporter =
25591         base::BindOnce(CreatePrimaryErrorCallback, std::move(callback));
25592     std::move(error_reporter).Run(rc);
25593     return;
25594   }
25595   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
25596       CreatePrimaryResponseParser, std::move(callback), authorization_delegate);
25597   transceiver_->SendCommand(command, std::move(parser));
25598 }
25599 
CreatePrimarySync(const TPMI_RH_HIERARCHY & primary_handle,const std::string & primary_handle_name,const TPM2B_SENSITIVE_CREATE & in_sensitive,const TPM2B_PUBLIC & in_public,const TPM2B_DATA & outside_info,const TPML_PCR_SELECTION & creation_pcr,TPM_HANDLE * object_handle,TPM2B_PUBLIC * out_public,TPM2B_CREATION_DATA * creation_data,TPM2B_DIGEST * creation_hash,TPMT_TK_CREATION * creation_ticket,TPM2B_NAME * name,AuthorizationDelegate * authorization_delegate)25600 TPM_RC Tpm::CreatePrimarySync(const TPMI_RH_HIERARCHY& primary_handle,
25601                               const std::string& primary_handle_name,
25602                               const TPM2B_SENSITIVE_CREATE& in_sensitive,
25603                               const TPM2B_PUBLIC& in_public,
25604                               const TPM2B_DATA& outside_info,
25605                               const TPML_PCR_SELECTION& creation_pcr,
25606                               TPM_HANDLE* object_handle,
25607                               TPM2B_PUBLIC* out_public,
25608                               TPM2B_CREATION_DATA* creation_data,
25609                               TPM2B_DIGEST* creation_hash,
25610                               TPMT_TK_CREATION* creation_ticket,
25611                               TPM2B_NAME* name,
25612                               AuthorizationDelegate* authorization_delegate) {
25613   VLOG(1) << __func__;
25614   std::string command;
25615   TPM_RC rc = SerializeCommand_CreatePrimary(
25616       primary_handle, primary_handle_name, in_sensitive, in_public,
25617       outside_info, creation_pcr, &command, authorization_delegate);
25618   if (rc != TPM_RC_SUCCESS) {
25619     return rc;
25620   }
25621   std::string response = transceiver_->SendCommandAndWait(command);
25622   rc = ParseResponse_CreatePrimary(
25623       response, object_handle, out_public, creation_data, creation_hash,
25624       creation_ticket, name, authorization_delegate);
25625   return rc;
25626 }
25627 
SerializeCommand_HierarchyControl(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPMI_RH_ENABLES & enable,const TPMI_YES_NO & state,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25628 TPM_RC Tpm::SerializeCommand_HierarchyControl(
25629     const TPMI_RH_HIERARCHY& auth_handle,
25630     const std::string& auth_handle_name,
25631     const TPMI_RH_ENABLES& enable,
25632     const TPMI_YES_NO& state,
25633     std::string* serialized_command,
25634     AuthorizationDelegate* authorization_delegate) {
25635   VLOG(3) << __func__;
25636   TPM_RC rc = TPM_RC_SUCCESS;
25637   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25638   UINT32 command_size = 10;  // Header size.
25639   std::string handle_section_bytes;
25640   std::string parameter_section_bytes;
25641   TPM_CC command_code = TPM_CC_HierarchyControl;
25642   bool is_command_parameter_encryption_possible = false;
25643   bool is_response_parameter_encryption_possible = false;
25644   std::string command_code_bytes;
25645   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25646   if (rc != TPM_RC_SUCCESS) {
25647     return rc;
25648   }
25649   std::string auth_handle_bytes;
25650   rc = Serialize_TPMI_RH_HIERARCHY(auth_handle, &auth_handle_bytes);
25651   if (rc != TPM_RC_SUCCESS) {
25652     return rc;
25653   }
25654   std::string enable_bytes;
25655   rc = Serialize_TPMI_RH_ENABLES(enable, &enable_bytes);
25656   if (rc != TPM_RC_SUCCESS) {
25657     return rc;
25658   }
25659   std::string state_bytes;
25660   rc = Serialize_TPMI_YES_NO(state, &state_bytes);
25661   if (rc != TPM_RC_SUCCESS) {
25662     return rc;
25663   }
25664   std::unique_ptr<crypto::SecureHash> hash(
25665       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25666   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25667   hash->Update(auth_handle_name.data(), auth_handle_name.size());
25668   handle_section_bytes += auth_handle_bytes;
25669   command_size += auth_handle_bytes.size();
25670   hash->Update(enable_bytes.data(), enable_bytes.size());
25671   parameter_section_bytes += enable_bytes;
25672   command_size += enable_bytes.size();
25673   hash->Update(state_bytes.data(), state_bytes.size());
25674   parameter_section_bytes += state_bytes;
25675   command_size += state_bytes.size();
25676   std::string command_hash(32, 0);
25677   hash->Finish(std::data(command_hash), command_hash.size());
25678   std::string authorization_section_bytes;
25679   std::string authorization_size_bytes;
25680   if (authorization_delegate) {
25681     if (!authorization_delegate->GetCommandAuthorization(
25682             command_hash, is_command_parameter_encryption_possible,
25683             is_response_parameter_encryption_possible,
25684             &authorization_section_bytes)) {
25685       return TRUNKS_RC_AUTHORIZATION_FAILED;
25686     }
25687     if (!authorization_section_bytes.empty()) {
25688       tag = TPM_ST_SESSIONS;
25689       std::string tmp;
25690       rc = Serialize_UINT32(authorization_section_bytes.size(),
25691                             &authorization_size_bytes);
25692       if (rc != TPM_RC_SUCCESS) {
25693         return rc;
25694       }
25695       command_size +=
25696           authorization_size_bytes.size() + authorization_section_bytes.size();
25697     }
25698   }
25699   std::string tag_bytes;
25700   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25701   if (rc != TPM_RC_SUCCESS) {
25702     return rc;
25703   }
25704   std::string command_size_bytes;
25705   rc = Serialize_UINT32(command_size, &command_size_bytes);
25706   if (rc != TPM_RC_SUCCESS) {
25707     return rc;
25708   }
25709   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25710                         handle_section_bytes + authorization_size_bytes +
25711                         authorization_section_bytes + parameter_section_bytes;
25712   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25713   VLOG(2) << "Command: "
25714           << base::HexEncode(serialized_command->data(),
25715                              serialized_command->size());
25716   return TPM_RC_SUCCESS;
25717 }
25718 
ParseResponse_HierarchyControl(const std::string & response,AuthorizationDelegate * authorization_delegate)25719 TPM_RC Tpm::ParseResponse_HierarchyControl(
25720     const std::string& response,
25721     AuthorizationDelegate* authorization_delegate) {
25722   VLOG(3) << __func__;
25723   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25724   TPM_RC rc = TPM_RC_SUCCESS;
25725   std::string buffer(response);
25726   TPM_ST tag;
25727   std::string tag_bytes;
25728   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25729   if (rc != TPM_RC_SUCCESS) {
25730     return rc;
25731   }
25732   UINT32 response_size;
25733   std::string response_size_bytes;
25734   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25735   if (rc != TPM_RC_SUCCESS) {
25736     return rc;
25737   }
25738   TPM_RC response_code;
25739   std::string response_code_bytes;
25740   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25741   if (rc != TPM_RC_SUCCESS) {
25742     return rc;
25743   }
25744   if (response_size != response.size()) {
25745     return TPM_RC_SIZE;
25746   }
25747   if (response_code != TPM_RC_SUCCESS) {
25748     return response_code;
25749   }
25750   TPM_CC command_code = TPM_CC_HierarchyControl;
25751   std::string command_code_bytes;
25752   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25753   if (rc != TPM_RC_SUCCESS) {
25754     return rc;
25755   }
25756   std::string authorization_section_bytes;
25757   if (tag == TPM_ST_SESSIONS) {
25758     UINT32 parameter_section_size = buffer.size();
25759     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25760     if (rc != TPM_RC_SUCCESS) {
25761       return rc;
25762     }
25763     if (parameter_section_size > buffer.size()) {
25764       return TPM_RC_INSUFFICIENT;
25765     }
25766     authorization_section_bytes = buffer.substr(parameter_section_size);
25767     // Keep the parameter section in |buffer|.
25768     buffer.erase(parameter_section_size);
25769   }
25770   std::unique_ptr<crypto::SecureHash> hash(
25771       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25772   hash->Update(response_code_bytes.data(), response_code_bytes.size());
25773   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25774   hash->Update(buffer.data(), buffer.size());
25775   std::string response_hash(32, 0);
25776   hash->Finish(std::data(response_hash), response_hash.size());
25777   if (tag == TPM_ST_SESSIONS) {
25778     if (!authorization_delegate)
25779       return TRUNKS_RC_AUTHORIZATION_FAILED;
25780     if (!authorization_delegate->CheckResponseAuthorization(
25781             response_hash, authorization_section_bytes)) {
25782       return TRUNKS_RC_AUTHORIZATION_FAILED;
25783     }
25784   }
25785   return TPM_RC_SUCCESS;
25786 }
25787 
HierarchyControlErrorCallback(Tpm::HierarchyControlResponse callback,TPM_RC response_code)25788 void HierarchyControlErrorCallback(Tpm::HierarchyControlResponse callback,
25789                                    TPM_RC response_code) {
25790   VLOG(1) << __func__;
25791   std::move(callback).Run(response_code);
25792 }
25793 
HierarchyControlResponseParser(Tpm::HierarchyControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)25794 void HierarchyControlResponseParser(
25795     Tpm::HierarchyControlResponse callback,
25796     AuthorizationDelegate* authorization_delegate,
25797     const std::string& response) {
25798   VLOG(1) << __func__;
25799   TPM_RC rc =
25800       Tpm::ParseResponse_HierarchyControl(response, authorization_delegate);
25801   if (rc != TPM_RC_SUCCESS) {
25802     base::OnceCallback<void(TPM_RC)> error_reporter =
25803         base::BindOnce(HierarchyControlErrorCallback, std::move(callback));
25804     std::move(error_reporter).Run(rc);
25805     return;
25806   }
25807   std::move(callback).Run(rc);
25808 }
25809 
HierarchyControl(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPMI_RH_ENABLES & enable,const TPMI_YES_NO & state,AuthorizationDelegate * authorization_delegate,HierarchyControlResponse callback)25810 void Tpm::HierarchyControl(const TPMI_RH_HIERARCHY& auth_handle,
25811                            const std::string& auth_handle_name,
25812                            const TPMI_RH_ENABLES& enable,
25813                            const TPMI_YES_NO& state,
25814                            AuthorizationDelegate* authorization_delegate,
25815                            HierarchyControlResponse callback) {
25816   VLOG(1) << __func__;
25817   std::string command;
25818   TPM_RC rc = SerializeCommand_HierarchyControl(auth_handle, auth_handle_name,
25819                                                 enable, state, &command,
25820                                                 authorization_delegate);
25821   if (rc != TPM_RC_SUCCESS) {
25822     base::OnceCallback<void(TPM_RC)> error_reporter =
25823         base::BindOnce(HierarchyControlErrorCallback, std::move(callback));
25824     std::move(error_reporter).Run(rc);
25825     return;
25826   }
25827   base::OnceCallback<void(const std::string&)> parser =
25828       base::BindOnce(HierarchyControlResponseParser, std::move(callback),
25829                      authorization_delegate);
25830   transceiver_->SendCommand(command, std::move(parser));
25831 }
25832 
HierarchyControlSync(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPMI_RH_ENABLES & enable,const TPMI_YES_NO & state,AuthorizationDelegate * authorization_delegate)25833 TPM_RC Tpm::HierarchyControlSync(
25834     const TPMI_RH_HIERARCHY& auth_handle,
25835     const std::string& auth_handle_name,
25836     const TPMI_RH_ENABLES& enable,
25837     const TPMI_YES_NO& state,
25838     AuthorizationDelegate* authorization_delegate) {
25839   VLOG(1) << __func__;
25840   std::string command;
25841   TPM_RC rc = SerializeCommand_HierarchyControl(auth_handle, auth_handle_name,
25842                                                 enable, state, &command,
25843                                                 authorization_delegate);
25844   if (rc != TPM_RC_SUCCESS) {
25845     return rc;
25846   }
25847   std::string response = transceiver_->SendCommandAndWait(command);
25848   rc = ParseResponse_HierarchyControl(response, authorization_delegate);
25849   return rc;
25850 }
25851 
SerializeCommand_SetPrimaryPolicy(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & hash_alg,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)25852 TPM_RC Tpm::SerializeCommand_SetPrimaryPolicy(
25853     const TPMI_RH_HIERARCHY& auth_handle,
25854     const std::string& auth_handle_name,
25855     const TPM2B_DIGEST& auth_policy,
25856     const TPMI_ALG_HASH& hash_alg,
25857     std::string* serialized_command,
25858     AuthorizationDelegate* authorization_delegate) {
25859   VLOG(3) << __func__;
25860   TPM_RC rc = TPM_RC_SUCCESS;
25861   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
25862   UINT32 command_size = 10;  // Header size.
25863   std::string handle_section_bytes;
25864   std::string parameter_section_bytes;
25865   TPM_CC command_code = TPM_CC_SetPrimaryPolicy;
25866   bool is_command_parameter_encryption_possible = true;
25867   bool is_response_parameter_encryption_possible = false;
25868   std::string command_code_bytes;
25869   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25870   if (rc != TPM_RC_SUCCESS) {
25871     return rc;
25872   }
25873   std::string auth_handle_bytes;
25874   rc = Serialize_TPMI_RH_HIERARCHY(auth_handle, &auth_handle_bytes);
25875   if (rc != TPM_RC_SUCCESS) {
25876     return rc;
25877   }
25878   std::string auth_policy_bytes;
25879   rc = Serialize_TPM2B_DIGEST(auth_policy, &auth_policy_bytes);
25880   if (rc != TPM_RC_SUCCESS) {
25881     return rc;
25882   }
25883   std::string hash_alg_bytes;
25884   rc = Serialize_TPMI_ALG_HASH(hash_alg, &hash_alg_bytes);
25885   if (rc != TPM_RC_SUCCESS) {
25886     return rc;
25887   }
25888   if (authorization_delegate) {
25889     // Encrypt just the parameter data, not the size.
25890     std::string tmp = auth_policy_bytes.substr(2);
25891     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
25892       return TRUNKS_RC_ENCRYPTION_FAILED;
25893     }
25894     auth_policy_bytes.replace(2, std::string::npos, tmp);
25895   }
25896   std::unique_ptr<crypto::SecureHash> hash(
25897       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
25898   hash->Update(command_code_bytes.data(), command_code_bytes.size());
25899   hash->Update(auth_handle_name.data(), auth_handle_name.size());
25900   handle_section_bytes += auth_handle_bytes;
25901   command_size += auth_handle_bytes.size();
25902   hash->Update(auth_policy_bytes.data(), auth_policy_bytes.size());
25903   parameter_section_bytes += auth_policy_bytes;
25904   command_size += auth_policy_bytes.size();
25905   hash->Update(hash_alg_bytes.data(), hash_alg_bytes.size());
25906   parameter_section_bytes += hash_alg_bytes;
25907   command_size += hash_alg_bytes.size();
25908   std::string command_hash(32, 0);
25909   hash->Finish(std::data(command_hash), command_hash.size());
25910   std::string authorization_section_bytes;
25911   std::string authorization_size_bytes;
25912   if (authorization_delegate) {
25913     if (!authorization_delegate->GetCommandAuthorization(
25914             command_hash, is_command_parameter_encryption_possible,
25915             is_response_parameter_encryption_possible,
25916             &authorization_section_bytes)) {
25917       return TRUNKS_RC_AUTHORIZATION_FAILED;
25918     }
25919     if (!authorization_section_bytes.empty()) {
25920       tag = TPM_ST_SESSIONS;
25921       std::string tmp;
25922       rc = Serialize_UINT32(authorization_section_bytes.size(),
25923                             &authorization_size_bytes);
25924       if (rc != TPM_RC_SUCCESS) {
25925         return rc;
25926       }
25927       command_size +=
25928           authorization_size_bytes.size() + authorization_section_bytes.size();
25929     }
25930   }
25931   std::string tag_bytes;
25932   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
25933   if (rc != TPM_RC_SUCCESS) {
25934     return rc;
25935   }
25936   std::string command_size_bytes;
25937   rc = Serialize_UINT32(command_size, &command_size_bytes);
25938   if (rc != TPM_RC_SUCCESS) {
25939     return rc;
25940   }
25941   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
25942                         handle_section_bytes + authorization_size_bytes +
25943                         authorization_section_bytes + parameter_section_bytes;
25944   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
25945   VLOG(2) << "Command: "
25946           << base::HexEncode(serialized_command->data(),
25947                              serialized_command->size());
25948   return TPM_RC_SUCCESS;
25949 }
25950 
ParseResponse_SetPrimaryPolicy(const std::string & response,AuthorizationDelegate * authorization_delegate)25951 TPM_RC Tpm::ParseResponse_SetPrimaryPolicy(
25952     const std::string& response,
25953     AuthorizationDelegate* authorization_delegate) {
25954   VLOG(3) << __func__;
25955   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
25956   TPM_RC rc = TPM_RC_SUCCESS;
25957   std::string buffer(response);
25958   TPM_ST tag;
25959   std::string tag_bytes;
25960   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
25961   if (rc != TPM_RC_SUCCESS) {
25962     return rc;
25963   }
25964   UINT32 response_size;
25965   std::string response_size_bytes;
25966   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
25967   if (rc != TPM_RC_SUCCESS) {
25968     return rc;
25969   }
25970   TPM_RC response_code;
25971   std::string response_code_bytes;
25972   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
25973   if (rc != TPM_RC_SUCCESS) {
25974     return rc;
25975   }
25976   if (response_size != response.size()) {
25977     return TPM_RC_SIZE;
25978   }
25979   if (response_code != TPM_RC_SUCCESS) {
25980     return response_code;
25981   }
25982   TPM_CC command_code = TPM_CC_SetPrimaryPolicy;
25983   std::string command_code_bytes;
25984   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
25985   if (rc != TPM_RC_SUCCESS) {
25986     return rc;
25987   }
25988   std::string authorization_section_bytes;
25989   if (tag == TPM_ST_SESSIONS) {
25990     UINT32 parameter_section_size = buffer.size();
25991     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
25992     if (rc != TPM_RC_SUCCESS) {
25993       return rc;
25994     }
25995     if (parameter_section_size > buffer.size()) {
25996       return TPM_RC_INSUFFICIENT;
25997     }
25998     authorization_section_bytes = buffer.substr(parameter_section_size);
25999     // Keep the parameter section in |buffer|.
26000     buffer.erase(parameter_section_size);
26001   }
26002   std::unique_ptr<crypto::SecureHash> hash(
26003       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26004   hash->Update(response_code_bytes.data(), response_code_bytes.size());
26005   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26006   hash->Update(buffer.data(), buffer.size());
26007   std::string response_hash(32, 0);
26008   hash->Finish(std::data(response_hash), response_hash.size());
26009   if (tag == TPM_ST_SESSIONS) {
26010     if (!authorization_delegate)
26011       return TRUNKS_RC_AUTHORIZATION_FAILED;
26012     if (!authorization_delegate->CheckResponseAuthorization(
26013             response_hash, authorization_section_bytes)) {
26014       return TRUNKS_RC_AUTHORIZATION_FAILED;
26015     }
26016   }
26017   return TPM_RC_SUCCESS;
26018 }
26019 
SetPrimaryPolicyErrorCallback(Tpm::SetPrimaryPolicyResponse callback,TPM_RC response_code)26020 void SetPrimaryPolicyErrorCallback(Tpm::SetPrimaryPolicyResponse callback,
26021                                    TPM_RC response_code) {
26022   VLOG(1) << __func__;
26023   std::move(callback).Run(response_code);
26024 }
26025 
SetPrimaryPolicyResponseParser(Tpm::SetPrimaryPolicyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26026 void SetPrimaryPolicyResponseParser(
26027     Tpm::SetPrimaryPolicyResponse callback,
26028     AuthorizationDelegate* authorization_delegate,
26029     const std::string& response) {
26030   VLOG(1) << __func__;
26031   TPM_RC rc =
26032       Tpm::ParseResponse_SetPrimaryPolicy(response, authorization_delegate);
26033   if (rc != TPM_RC_SUCCESS) {
26034     base::OnceCallback<void(TPM_RC)> error_reporter =
26035         base::BindOnce(SetPrimaryPolicyErrorCallback, std::move(callback));
26036     std::move(error_reporter).Run(rc);
26037     return;
26038   }
26039   std::move(callback).Run(rc);
26040 }
26041 
SetPrimaryPolicy(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate,SetPrimaryPolicyResponse callback)26042 void Tpm::SetPrimaryPolicy(const TPMI_RH_HIERARCHY& auth_handle,
26043                            const std::string& auth_handle_name,
26044                            const TPM2B_DIGEST& auth_policy,
26045                            const TPMI_ALG_HASH& hash_alg,
26046                            AuthorizationDelegate* authorization_delegate,
26047                            SetPrimaryPolicyResponse callback) {
26048   VLOG(1) << __func__;
26049   std::string command;
26050   TPM_RC rc = SerializeCommand_SetPrimaryPolicy(auth_handle, auth_handle_name,
26051                                                 auth_policy, hash_alg, &command,
26052                                                 authorization_delegate);
26053   if (rc != TPM_RC_SUCCESS) {
26054     base::OnceCallback<void(TPM_RC)> error_reporter =
26055         base::BindOnce(SetPrimaryPolicyErrorCallback, std::move(callback));
26056     std::move(error_reporter).Run(rc);
26057     return;
26058   }
26059   base::OnceCallback<void(const std::string&)> parser =
26060       base::BindOnce(SetPrimaryPolicyResponseParser, std::move(callback),
26061                      authorization_delegate);
26062   transceiver_->SendCommand(command, std::move(parser));
26063 }
26064 
SetPrimaryPolicySync(const TPMI_RH_HIERARCHY & auth_handle,const std::string & auth_handle_name,const TPM2B_DIGEST & auth_policy,const TPMI_ALG_HASH & hash_alg,AuthorizationDelegate * authorization_delegate)26065 TPM_RC Tpm::SetPrimaryPolicySync(
26066     const TPMI_RH_HIERARCHY& auth_handle,
26067     const std::string& auth_handle_name,
26068     const TPM2B_DIGEST& auth_policy,
26069     const TPMI_ALG_HASH& hash_alg,
26070     AuthorizationDelegate* authorization_delegate) {
26071   VLOG(1) << __func__;
26072   std::string command;
26073   TPM_RC rc = SerializeCommand_SetPrimaryPolicy(auth_handle, auth_handle_name,
26074                                                 auth_policy, hash_alg, &command,
26075                                                 authorization_delegate);
26076   if (rc != TPM_RC_SUCCESS) {
26077     return rc;
26078   }
26079   std::string response = transceiver_->SendCommandAndWait(command);
26080   rc = ParseResponse_SetPrimaryPolicy(response, authorization_delegate);
26081   return rc;
26082 }
26083 
SerializeCommand_ChangePPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26084 TPM_RC Tpm::SerializeCommand_ChangePPS(
26085     const TPMI_RH_PLATFORM& auth_handle,
26086     const std::string& auth_handle_name,
26087     std::string* serialized_command,
26088     AuthorizationDelegate* authorization_delegate) {
26089   VLOG(3) << __func__;
26090   TPM_RC rc = TPM_RC_SUCCESS;
26091   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26092   UINT32 command_size = 10;  // Header size.
26093   std::string handle_section_bytes;
26094   std::string parameter_section_bytes;
26095   TPM_CC command_code = TPM_CC_ChangePPS;
26096   bool is_command_parameter_encryption_possible = false;
26097   bool is_response_parameter_encryption_possible = false;
26098   std::string command_code_bytes;
26099   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26100   if (rc != TPM_RC_SUCCESS) {
26101     return rc;
26102   }
26103   std::string auth_handle_bytes;
26104   rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
26105   if (rc != TPM_RC_SUCCESS) {
26106     return rc;
26107   }
26108   std::unique_ptr<crypto::SecureHash> hash(
26109       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26110   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26111   hash->Update(auth_handle_name.data(), auth_handle_name.size());
26112   handle_section_bytes += auth_handle_bytes;
26113   command_size += auth_handle_bytes.size();
26114   std::string command_hash(32, 0);
26115   hash->Finish(std::data(command_hash), command_hash.size());
26116   std::string authorization_section_bytes;
26117   std::string authorization_size_bytes;
26118   if (authorization_delegate) {
26119     if (!authorization_delegate->GetCommandAuthorization(
26120             command_hash, is_command_parameter_encryption_possible,
26121             is_response_parameter_encryption_possible,
26122             &authorization_section_bytes)) {
26123       return TRUNKS_RC_AUTHORIZATION_FAILED;
26124     }
26125     if (!authorization_section_bytes.empty()) {
26126       tag = TPM_ST_SESSIONS;
26127       std::string tmp;
26128       rc = Serialize_UINT32(authorization_section_bytes.size(),
26129                             &authorization_size_bytes);
26130       if (rc != TPM_RC_SUCCESS) {
26131         return rc;
26132       }
26133       command_size +=
26134           authorization_size_bytes.size() + authorization_section_bytes.size();
26135     }
26136   }
26137   std::string tag_bytes;
26138   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26139   if (rc != TPM_RC_SUCCESS) {
26140     return rc;
26141   }
26142   std::string command_size_bytes;
26143   rc = Serialize_UINT32(command_size, &command_size_bytes);
26144   if (rc != TPM_RC_SUCCESS) {
26145     return rc;
26146   }
26147   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26148                         handle_section_bytes + authorization_size_bytes +
26149                         authorization_section_bytes + parameter_section_bytes;
26150   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26151   VLOG(2) << "Command: "
26152           << base::HexEncode(serialized_command->data(),
26153                              serialized_command->size());
26154   return TPM_RC_SUCCESS;
26155 }
26156 
ParseResponse_ChangePPS(const std::string & response,AuthorizationDelegate * authorization_delegate)26157 TPM_RC Tpm::ParseResponse_ChangePPS(
26158     const std::string& response,
26159     AuthorizationDelegate* authorization_delegate) {
26160   VLOG(3) << __func__;
26161   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26162   TPM_RC rc = TPM_RC_SUCCESS;
26163   std::string buffer(response);
26164   TPM_ST tag;
26165   std::string tag_bytes;
26166   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26167   if (rc != TPM_RC_SUCCESS) {
26168     return rc;
26169   }
26170   UINT32 response_size;
26171   std::string response_size_bytes;
26172   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26173   if (rc != TPM_RC_SUCCESS) {
26174     return rc;
26175   }
26176   TPM_RC response_code;
26177   std::string response_code_bytes;
26178   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26179   if (rc != TPM_RC_SUCCESS) {
26180     return rc;
26181   }
26182   if (response_size != response.size()) {
26183     return TPM_RC_SIZE;
26184   }
26185   if (response_code != TPM_RC_SUCCESS) {
26186     return response_code;
26187   }
26188   TPM_CC command_code = TPM_CC_ChangePPS;
26189   std::string command_code_bytes;
26190   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26191   if (rc != TPM_RC_SUCCESS) {
26192     return rc;
26193   }
26194   std::string authorization_section_bytes;
26195   if (tag == TPM_ST_SESSIONS) {
26196     UINT32 parameter_section_size = buffer.size();
26197     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26198     if (rc != TPM_RC_SUCCESS) {
26199       return rc;
26200     }
26201     if (parameter_section_size > buffer.size()) {
26202       return TPM_RC_INSUFFICIENT;
26203     }
26204     authorization_section_bytes = buffer.substr(parameter_section_size);
26205     // Keep the parameter section in |buffer|.
26206     buffer.erase(parameter_section_size);
26207   }
26208   std::unique_ptr<crypto::SecureHash> hash(
26209       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26210   hash->Update(response_code_bytes.data(), response_code_bytes.size());
26211   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26212   hash->Update(buffer.data(), buffer.size());
26213   std::string response_hash(32, 0);
26214   hash->Finish(std::data(response_hash), response_hash.size());
26215   if (tag == TPM_ST_SESSIONS) {
26216     if (!authorization_delegate)
26217       return TRUNKS_RC_AUTHORIZATION_FAILED;
26218     if (!authorization_delegate->CheckResponseAuthorization(
26219             response_hash, authorization_section_bytes)) {
26220       return TRUNKS_RC_AUTHORIZATION_FAILED;
26221     }
26222   }
26223   return TPM_RC_SUCCESS;
26224 }
26225 
ChangePPSErrorCallback(Tpm::ChangePPSResponse callback,TPM_RC response_code)26226 void ChangePPSErrorCallback(Tpm::ChangePPSResponse callback,
26227                             TPM_RC response_code) {
26228   VLOG(1) << __func__;
26229   std::move(callback).Run(response_code);
26230 }
26231 
ChangePPSResponseParser(Tpm::ChangePPSResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26232 void ChangePPSResponseParser(Tpm::ChangePPSResponse callback,
26233                              AuthorizationDelegate* authorization_delegate,
26234                              const std::string& response) {
26235   VLOG(1) << __func__;
26236   TPM_RC rc = Tpm::ParseResponse_ChangePPS(response, authorization_delegate);
26237   if (rc != TPM_RC_SUCCESS) {
26238     base::OnceCallback<void(TPM_RC)> error_reporter =
26239         base::BindOnce(ChangePPSErrorCallback, std::move(callback));
26240     std::move(error_reporter).Run(rc);
26241     return;
26242   }
26243   std::move(callback).Run(rc);
26244 }
26245 
ChangePPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ChangePPSResponse callback)26246 void Tpm::ChangePPS(const TPMI_RH_PLATFORM& auth_handle,
26247                     const std::string& auth_handle_name,
26248                     AuthorizationDelegate* authorization_delegate,
26249                     ChangePPSResponse callback) {
26250   VLOG(1) << __func__;
26251   std::string command;
26252   TPM_RC rc = SerializeCommand_ChangePPS(auth_handle, auth_handle_name,
26253                                          &command, authorization_delegate);
26254   if (rc != TPM_RC_SUCCESS) {
26255     base::OnceCallback<void(TPM_RC)> error_reporter =
26256         base::BindOnce(ChangePPSErrorCallback, std::move(callback));
26257     std::move(error_reporter).Run(rc);
26258     return;
26259   }
26260   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26261       ChangePPSResponseParser, std::move(callback), authorization_delegate);
26262   transceiver_->SendCommand(command, std::move(parser));
26263 }
26264 
ChangePPSSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26265 TPM_RC Tpm::ChangePPSSync(const TPMI_RH_PLATFORM& auth_handle,
26266                           const std::string& auth_handle_name,
26267                           AuthorizationDelegate* authorization_delegate) {
26268   VLOG(1) << __func__;
26269   std::string command;
26270   TPM_RC rc = SerializeCommand_ChangePPS(auth_handle, auth_handle_name,
26271                                          &command, authorization_delegate);
26272   if (rc != TPM_RC_SUCCESS) {
26273     return rc;
26274   }
26275   std::string response = transceiver_->SendCommandAndWait(command);
26276   rc = ParseResponse_ChangePPS(response, authorization_delegate);
26277   return rc;
26278 }
26279 
SerializeCommand_ChangeEPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26280 TPM_RC Tpm::SerializeCommand_ChangeEPS(
26281     const TPMI_RH_PLATFORM& auth_handle,
26282     const std::string& auth_handle_name,
26283     std::string* serialized_command,
26284     AuthorizationDelegate* authorization_delegate) {
26285   VLOG(3) << __func__;
26286   TPM_RC rc = TPM_RC_SUCCESS;
26287   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26288   UINT32 command_size = 10;  // Header size.
26289   std::string handle_section_bytes;
26290   std::string parameter_section_bytes;
26291   TPM_CC command_code = TPM_CC_ChangeEPS;
26292   bool is_command_parameter_encryption_possible = false;
26293   bool is_response_parameter_encryption_possible = false;
26294   std::string command_code_bytes;
26295   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26296   if (rc != TPM_RC_SUCCESS) {
26297     return rc;
26298   }
26299   std::string auth_handle_bytes;
26300   rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
26301   if (rc != TPM_RC_SUCCESS) {
26302     return rc;
26303   }
26304   std::unique_ptr<crypto::SecureHash> hash(
26305       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26306   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26307   hash->Update(auth_handle_name.data(), auth_handle_name.size());
26308   handle_section_bytes += auth_handle_bytes;
26309   command_size += auth_handle_bytes.size();
26310   std::string command_hash(32, 0);
26311   hash->Finish(std::data(command_hash), command_hash.size());
26312   std::string authorization_section_bytes;
26313   std::string authorization_size_bytes;
26314   if (authorization_delegate) {
26315     if (!authorization_delegate->GetCommandAuthorization(
26316             command_hash, is_command_parameter_encryption_possible,
26317             is_response_parameter_encryption_possible,
26318             &authorization_section_bytes)) {
26319       return TRUNKS_RC_AUTHORIZATION_FAILED;
26320     }
26321     if (!authorization_section_bytes.empty()) {
26322       tag = TPM_ST_SESSIONS;
26323       std::string tmp;
26324       rc = Serialize_UINT32(authorization_section_bytes.size(),
26325                             &authorization_size_bytes);
26326       if (rc != TPM_RC_SUCCESS) {
26327         return rc;
26328       }
26329       command_size +=
26330           authorization_size_bytes.size() + authorization_section_bytes.size();
26331     }
26332   }
26333   std::string tag_bytes;
26334   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26335   if (rc != TPM_RC_SUCCESS) {
26336     return rc;
26337   }
26338   std::string command_size_bytes;
26339   rc = Serialize_UINT32(command_size, &command_size_bytes);
26340   if (rc != TPM_RC_SUCCESS) {
26341     return rc;
26342   }
26343   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26344                         handle_section_bytes + authorization_size_bytes +
26345                         authorization_section_bytes + parameter_section_bytes;
26346   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26347   VLOG(2) << "Command: "
26348           << base::HexEncode(serialized_command->data(),
26349                              serialized_command->size());
26350   return TPM_RC_SUCCESS;
26351 }
26352 
ParseResponse_ChangeEPS(const std::string & response,AuthorizationDelegate * authorization_delegate)26353 TPM_RC Tpm::ParseResponse_ChangeEPS(
26354     const std::string& response,
26355     AuthorizationDelegate* authorization_delegate) {
26356   VLOG(3) << __func__;
26357   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26358   TPM_RC rc = TPM_RC_SUCCESS;
26359   std::string buffer(response);
26360   TPM_ST tag;
26361   std::string tag_bytes;
26362   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26363   if (rc != TPM_RC_SUCCESS) {
26364     return rc;
26365   }
26366   UINT32 response_size;
26367   std::string response_size_bytes;
26368   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26369   if (rc != TPM_RC_SUCCESS) {
26370     return rc;
26371   }
26372   TPM_RC response_code;
26373   std::string response_code_bytes;
26374   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26375   if (rc != TPM_RC_SUCCESS) {
26376     return rc;
26377   }
26378   if (response_size != response.size()) {
26379     return TPM_RC_SIZE;
26380   }
26381   if (response_code != TPM_RC_SUCCESS) {
26382     return response_code;
26383   }
26384   TPM_CC command_code = TPM_CC_ChangeEPS;
26385   std::string command_code_bytes;
26386   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26387   if (rc != TPM_RC_SUCCESS) {
26388     return rc;
26389   }
26390   std::string authorization_section_bytes;
26391   if (tag == TPM_ST_SESSIONS) {
26392     UINT32 parameter_section_size = buffer.size();
26393     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26394     if (rc != TPM_RC_SUCCESS) {
26395       return rc;
26396     }
26397     if (parameter_section_size > buffer.size()) {
26398       return TPM_RC_INSUFFICIENT;
26399     }
26400     authorization_section_bytes = buffer.substr(parameter_section_size);
26401     // Keep the parameter section in |buffer|.
26402     buffer.erase(parameter_section_size);
26403   }
26404   std::unique_ptr<crypto::SecureHash> hash(
26405       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26406   hash->Update(response_code_bytes.data(), response_code_bytes.size());
26407   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26408   hash->Update(buffer.data(), buffer.size());
26409   std::string response_hash(32, 0);
26410   hash->Finish(std::data(response_hash), response_hash.size());
26411   if (tag == TPM_ST_SESSIONS) {
26412     if (!authorization_delegate)
26413       return TRUNKS_RC_AUTHORIZATION_FAILED;
26414     if (!authorization_delegate->CheckResponseAuthorization(
26415             response_hash, authorization_section_bytes)) {
26416       return TRUNKS_RC_AUTHORIZATION_FAILED;
26417     }
26418   }
26419   return TPM_RC_SUCCESS;
26420 }
26421 
ChangeEPSErrorCallback(Tpm::ChangeEPSResponse callback,TPM_RC response_code)26422 void ChangeEPSErrorCallback(Tpm::ChangeEPSResponse callback,
26423                             TPM_RC response_code) {
26424   VLOG(1) << __func__;
26425   std::move(callback).Run(response_code);
26426 }
26427 
ChangeEPSResponseParser(Tpm::ChangeEPSResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26428 void ChangeEPSResponseParser(Tpm::ChangeEPSResponse callback,
26429                              AuthorizationDelegate* authorization_delegate,
26430                              const std::string& response) {
26431   VLOG(1) << __func__;
26432   TPM_RC rc = Tpm::ParseResponse_ChangeEPS(response, authorization_delegate);
26433   if (rc != TPM_RC_SUCCESS) {
26434     base::OnceCallback<void(TPM_RC)> error_reporter =
26435         base::BindOnce(ChangeEPSErrorCallback, std::move(callback));
26436     std::move(error_reporter).Run(rc);
26437     return;
26438   }
26439   std::move(callback).Run(rc);
26440 }
26441 
ChangeEPS(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ChangeEPSResponse callback)26442 void Tpm::ChangeEPS(const TPMI_RH_PLATFORM& auth_handle,
26443                     const std::string& auth_handle_name,
26444                     AuthorizationDelegate* authorization_delegate,
26445                     ChangeEPSResponse callback) {
26446   VLOG(1) << __func__;
26447   std::string command;
26448   TPM_RC rc = SerializeCommand_ChangeEPS(auth_handle, auth_handle_name,
26449                                          &command, authorization_delegate);
26450   if (rc != TPM_RC_SUCCESS) {
26451     base::OnceCallback<void(TPM_RC)> error_reporter =
26452         base::BindOnce(ChangeEPSErrorCallback, std::move(callback));
26453     std::move(error_reporter).Run(rc);
26454     return;
26455   }
26456   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26457       ChangeEPSResponseParser, std::move(callback), authorization_delegate);
26458   transceiver_->SendCommand(command, std::move(parser));
26459 }
26460 
ChangeEPSSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26461 TPM_RC Tpm::ChangeEPSSync(const TPMI_RH_PLATFORM& auth_handle,
26462                           const std::string& auth_handle_name,
26463                           AuthorizationDelegate* authorization_delegate) {
26464   VLOG(1) << __func__;
26465   std::string command;
26466   TPM_RC rc = SerializeCommand_ChangeEPS(auth_handle, auth_handle_name,
26467                                          &command, authorization_delegate);
26468   if (rc != TPM_RC_SUCCESS) {
26469     return rc;
26470   }
26471   std::string response = transceiver_->SendCommandAndWait(command);
26472   rc = ParseResponse_ChangeEPS(response, authorization_delegate);
26473   return rc;
26474 }
26475 
SerializeCommand_Clear(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26476 TPM_RC Tpm::SerializeCommand_Clear(
26477     const TPMI_RH_CLEAR& auth_handle,
26478     const std::string& auth_handle_name,
26479     std::string* serialized_command,
26480     AuthorizationDelegate* authorization_delegate) {
26481   VLOG(3) << __func__;
26482   TPM_RC rc = TPM_RC_SUCCESS;
26483   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26484   UINT32 command_size = 10;  // Header size.
26485   std::string handle_section_bytes;
26486   std::string parameter_section_bytes;
26487   TPM_CC command_code = TPM_CC_Clear;
26488   bool is_command_parameter_encryption_possible = false;
26489   bool is_response_parameter_encryption_possible = false;
26490   std::string command_code_bytes;
26491   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26492   if (rc != TPM_RC_SUCCESS) {
26493     return rc;
26494   }
26495   std::string auth_handle_bytes;
26496   rc = Serialize_TPMI_RH_CLEAR(auth_handle, &auth_handle_bytes);
26497   if (rc != TPM_RC_SUCCESS) {
26498     return rc;
26499   }
26500   std::unique_ptr<crypto::SecureHash> hash(
26501       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26502   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26503   hash->Update(auth_handle_name.data(), auth_handle_name.size());
26504   handle_section_bytes += auth_handle_bytes;
26505   command_size += auth_handle_bytes.size();
26506   std::string command_hash(32, 0);
26507   hash->Finish(std::data(command_hash), command_hash.size());
26508   std::string authorization_section_bytes;
26509   std::string authorization_size_bytes;
26510   if (authorization_delegate) {
26511     if (!authorization_delegate->GetCommandAuthorization(
26512             command_hash, is_command_parameter_encryption_possible,
26513             is_response_parameter_encryption_possible,
26514             &authorization_section_bytes)) {
26515       return TRUNKS_RC_AUTHORIZATION_FAILED;
26516     }
26517     if (!authorization_section_bytes.empty()) {
26518       tag = TPM_ST_SESSIONS;
26519       std::string tmp;
26520       rc = Serialize_UINT32(authorization_section_bytes.size(),
26521                             &authorization_size_bytes);
26522       if (rc != TPM_RC_SUCCESS) {
26523         return rc;
26524       }
26525       command_size +=
26526           authorization_size_bytes.size() + authorization_section_bytes.size();
26527     }
26528   }
26529   std::string tag_bytes;
26530   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26531   if (rc != TPM_RC_SUCCESS) {
26532     return rc;
26533   }
26534   std::string command_size_bytes;
26535   rc = Serialize_UINT32(command_size, &command_size_bytes);
26536   if (rc != TPM_RC_SUCCESS) {
26537     return rc;
26538   }
26539   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26540                         handle_section_bytes + authorization_size_bytes +
26541                         authorization_section_bytes + parameter_section_bytes;
26542   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26543   VLOG(2) << "Command: "
26544           << base::HexEncode(serialized_command->data(),
26545                              serialized_command->size());
26546   return TPM_RC_SUCCESS;
26547 }
26548 
ParseResponse_Clear(const std::string & response,AuthorizationDelegate * authorization_delegate)26549 TPM_RC Tpm::ParseResponse_Clear(const std::string& response,
26550                                 AuthorizationDelegate* authorization_delegate) {
26551   VLOG(3) << __func__;
26552   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26553   TPM_RC rc = TPM_RC_SUCCESS;
26554   std::string buffer(response);
26555   TPM_ST tag;
26556   std::string tag_bytes;
26557   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26558   if (rc != TPM_RC_SUCCESS) {
26559     return rc;
26560   }
26561   UINT32 response_size;
26562   std::string response_size_bytes;
26563   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26564   if (rc != TPM_RC_SUCCESS) {
26565     return rc;
26566   }
26567   TPM_RC response_code;
26568   std::string response_code_bytes;
26569   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26570   if (rc != TPM_RC_SUCCESS) {
26571     return rc;
26572   }
26573   if (response_size != response.size()) {
26574     return TPM_RC_SIZE;
26575   }
26576   if (response_code != TPM_RC_SUCCESS) {
26577     return response_code;
26578   }
26579   TPM_CC command_code = TPM_CC_Clear;
26580   std::string command_code_bytes;
26581   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26582   if (rc != TPM_RC_SUCCESS) {
26583     return rc;
26584   }
26585   std::string authorization_section_bytes;
26586   if (tag == TPM_ST_SESSIONS) {
26587     UINT32 parameter_section_size = buffer.size();
26588     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26589     if (rc != TPM_RC_SUCCESS) {
26590       return rc;
26591     }
26592     if (parameter_section_size > buffer.size()) {
26593       return TPM_RC_INSUFFICIENT;
26594     }
26595     authorization_section_bytes = buffer.substr(parameter_section_size);
26596     // Keep the parameter section in |buffer|.
26597     buffer.erase(parameter_section_size);
26598   }
26599   std::unique_ptr<crypto::SecureHash> hash(
26600       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26601   hash->Update(response_code_bytes.data(), response_code_bytes.size());
26602   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26603   hash->Update(buffer.data(), buffer.size());
26604   std::string response_hash(32, 0);
26605   hash->Finish(std::data(response_hash), response_hash.size());
26606   if (tag == TPM_ST_SESSIONS) {
26607     if (!authorization_delegate)
26608       return TRUNKS_RC_AUTHORIZATION_FAILED;
26609     if (!authorization_delegate->CheckResponseAuthorization(
26610             response_hash, authorization_section_bytes)) {
26611       return TRUNKS_RC_AUTHORIZATION_FAILED;
26612     }
26613   }
26614   return TPM_RC_SUCCESS;
26615 }
26616 
ClearErrorCallback(Tpm::ClearResponse callback,TPM_RC response_code)26617 void ClearErrorCallback(Tpm::ClearResponse callback, TPM_RC response_code) {
26618   VLOG(1) << __func__;
26619   std::move(callback).Run(response_code);
26620 }
26621 
ClearResponseParser(Tpm::ClearResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26622 void ClearResponseParser(Tpm::ClearResponse callback,
26623                          AuthorizationDelegate* authorization_delegate,
26624                          const std::string& response) {
26625   VLOG(1) << __func__;
26626   TPM_RC rc = Tpm::ParseResponse_Clear(response, authorization_delegate);
26627   if (rc != TPM_RC_SUCCESS) {
26628     base::OnceCallback<void(TPM_RC)> error_reporter =
26629         base::BindOnce(ClearErrorCallback, std::move(callback));
26630     std::move(error_reporter).Run(rc);
26631     return;
26632   }
26633   std::move(callback).Run(rc);
26634 }
26635 
Clear(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,ClearResponse callback)26636 void Tpm::Clear(const TPMI_RH_CLEAR& auth_handle,
26637                 const std::string& auth_handle_name,
26638                 AuthorizationDelegate* authorization_delegate,
26639                 ClearResponse callback) {
26640   VLOG(1) << __func__;
26641   std::string command;
26642   TPM_RC rc = SerializeCommand_Clear(auth_handle, auth_handle_name, &command,
26643                                      authorization_delegate);
26644   if (rc != TPM_RC_SUCCESS) {
26645     base::OnceCallback<void(TPM_RC)> error_reporter =
26646         base::BindOnce(ClearErrorCallback, std::move(callback));
26647     std::move(error_reporter).Run(rc);
26648     return;
26649   }
26650   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26651       ClearResponseParser, std::move(callback), authorization_delegate);
26652   transceiver_->SendCommand(command, std::move(parser));
26653 }
26654 
ClearSync(const TPMI_RH_CLEAR & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)26655 TPM_RC Tpm::ClearSync(const TPMI_RH_CLEAR& auth_handle,
26656                       const std::string& auth_handle_name,
26657                       AuthorizationDelegate* authorization_delegate) {
26658   VLOG(1) << __func__;
26659   std::string command;
26660   TPM_RC rc = SerializeCommand_Clear(auth_handle, auth_handle_name, &command,
26661                                      authorization_delegate);
26662   if (rc != TPM_RC_SUCCESS) {
26663     return rc;
26664   }
26665   std::string response = transceiver_->SendCommandAndWait(command);
26666   rc = ParseResponse_Clear(response, authorization_delegate);
26667   return rc;
26668 }
26669 
SerializeCommand_ClearControl(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26670 TPM_RC Tpm::SerializeCommand_ClearControl(
26671     const TPMI_RH_CLEAR& auth,
26672     const std::string& auth_name,
26673     const TPMI_YES_NO& disable,
26674     std::string* serialized_command,
26675     AuthorizationDelegate* authorization_delegate) {
26676   VLOG(3) << __func__;
26677   TPM_RC rc = TPM_RC_SUCCESS;
26678   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26679   UINT32 command_size = 10;  // Header size.
26680   std::string handle_section_bytes;
26681   std::string parameter_section_bytes;
26682   TPM_CC command_code = TPM_CC_ClearControl;
26683   bool is_command_parameter_encryption_possible = false;
26684   bool is_response_parameter_encryption_possible = false;
26685   std::string command_code_bytes;
26686   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26687   if (rc != TPM_RC_SUCCESS) {
26688     return rc;
26689   }
26690   std::string auth_bytes;
26691   rc = Serialize_TPMI_RH_CLEAR(auth, &auth_bytes);
26692   if (rc != TPM_RC_SUCCESS) {
26693     return rc;
26694   }
26695   std::string disable_bytes;
26696   rc = Serialize_TPMI_YES_NO(disable, &disable_bytes);
26697   if (rc != TPM_RC_SUCCESS) {
26698     return rc;
26699   }
26700   std::unique_ptr<crypto::SecureHash> hash(
26701       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26702   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26703   hash->Update(auth_name.data(), auth_name.size());
26704   handle_section_bytes += auth_bytes;
26705   command_size += auth_bytes.size();
26706   hash->Update(disable_bytes.data(), disable_bytes.size());
26707   parameter_section_bytes += disable_bytes;
26708   command_size += disable_bytes.size();
26709   std::string command_hash(32, 0);
26710   hash->Finish(std::data(command_hash), command_hash.size());
26711   std::string authorization_section_bytes;
26712   std::string authorization_size_bytes;
26713   if (authorization_delegate) {
26714     if (!authorization_delegate->GetCommandAuthorization(
26715             command_hash, is_command_parameter_encryption_possible,
26716             is_response_parameter_encryption_possible,
26717             &authorization_section_bytes)) {
26718       return TRUNKS_RC_AUTHORIZATION_FAILED;
26719     }
26720     if (!authorization_section_bytes.empty()) {
26721       tag = TPM_ST_SESSIONS;
26722       std::string tmp;
26723       rc = Serialize_UINT32(authorization_section_bytes.size(),
26724                             &authorization_size_bytes);
26725       if (rc != TPM_RC_SUCCESS) {
26726         return rc;
26727       }
26728       command_size +=
26729           authorization_size_bytes.size() + authorization_section_bytes.size();
26730     }
26731   }
26732   std::string tag_bytes;
26733   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26734   if (rc != TPM_RC_SUCCESS) {
26735     return rc;
26736   }
26737   std::string command_size_bytes;
26738   rc = Serialize_UINT32(command_size, &command_size_bytes);
26739   if (rc != TPM_RC_SUCCESS) {
26740     return rc;
26741   }
26742   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26743                         handle_section_bytes + authorization_size_bytes +
26744                         authorization_section_bytes + parameter_section_bytes;
26745   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26746   VLOG(2) << "Command: "
26747           << base::HexEncode(serialized_command->data(),
26748                              serialized_command->size());
26749   return TPM_RC_SUCCESS;
26750 }
26751 
ParseResponse_ClearControl(const std::string & response,AuthorizationDelegate * authorization_delegate)26752 TPM_RC Tpm::ParseResponse_ClearControl(
26753     const std::string& response,
26754     AuthorizationDelegate* authorization_delegate) {
26755   VLOG(3) << __func__;
26756   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26757   TPM_RC rc = TPM_RC_SUCCESS;
26758   std::string buffer(response);
26759   TPM_ST tag;
26760   std::string tag_bytes;
26761   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26762   if (rc != TPM_RC_SUCCESS) {
26763     return rc;
26764   }
26765   UINT32 response_size;
26766   std::string response_size_bytes;
26767   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26768   if (rc != TPM_RC_SUCCESS) {
26769     return rc;
26770   }
26771   TPM_RC response_code;
26772   std::string response_code_bytes;
26773   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26774   if (rc != TPM_RC_SUCCESS) {
26775     return rc;
26776   }
26777   if (response_size != response.size()) {
26778     return TPM_RC_SIZE;
26779   }
26780   if (response_code != TPM_RC_SUCCESS) {
26781     return response_code;
26782   }
26783   TPM_CC command_code = TPM_CC_ClearControl;
26784   std::string command_code_bytes;
26785   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26786   if (rc != TPM_RC_SUCCESS) {
26787     return rc;
26788   }
26789   std::string authorization_section_bytes;
26790   if (tag == TPM_ST_SESSIONS) {
26791     UINT32 parameter_section_size = buffer.size();
26792     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
26793     if (rc != TPM_RC_SUCCESS) {
26794       return rc;
26795     }
26796     if (parameter_section_size > buffer.size()) {
26797       return TPM_RC_INSUFFICIENT;
26798     }
26799     authorization_section_bytes = buffer.substr(parameter_section_size);
26800     // Keep the parameter section in |buffer|.
26801     buffer.erase(parameter_section_size);
26802   }
26803   std::unique_ptr<crypto::SecureHash> hash(
26804       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26805   hash->Update(response_code_bytes.data(), response_code_bytes.size());
26806   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26807   hash->Update(buffer.data(), buffer.size());
26808   std::string response_hash(32, 0);
26809   hash->Finish(std::data(response_hash), response_hash.size());
26810   if (tag == TPM_ST_SESSIONS) {
26811     if (!authorization_delegate)
26812       return TRUNKS_RC_AUTHORIZATION_FAILED;
26813     if (!authorization_delegate->CheckResponseAuthorization(
26814             response_hash, authorization_section_bytes)) {
26815       return TRUNKS_RC_AUTHORIZATION_FAILED;
26816     }
26817   }
26818   return TPM_RC_SUCCESS;
26819 }
26820 
ClearControlErrorCallback(Tpm::ClearControlResponse callback,TPM_RC response_code)26821 void ClearControlErrorCallback(Tpm::ClearControlResponse callback,
26822                                TPM_RC response_code) {
26823   VLOG(1) << __func__;
26824   std::move(callback).Run(response_code);
26825 }
26826 
ClearControlResponseParser(Tpm::ClearControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)26827 void ClearControlResponseParser(Tpm::ClearControlResponse callback,
26828                                 AuthorizationDelegate* authorization_delegate,
26829                                 const std::string& response) {
26830   VLOG(1) << __func__;
26831   TPM_RC rc = Tpm::ParseResponse_ClearControl(response, authorization_delegate);
26832   if (rc != TPM_RC_SUCCESS) {
26833     base::OnceCallback<void(TPM_RC)> error_reporter =
26834         base::BindOnce(ClearControlErrorCallback, std::move(callback));
26835     std::move(error_reporter).Run(rc);
26836     return;
26837   }
26838   std::move(callback).Run(rc);
26839 }
26840 
ClearControl(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,AuthorizationDelegate * authorization_delegate,ClearControlResponse callback)26841 void Tpm::ClearControl(const TPMI_RH_CLEAR& auth,
26842                        const std::string& auth_name,
26843                        const TPMI_YES_NO& disable,
26844                        AuthorizationDelegate* authorization_delegate,
26845                        ClearControlResponse callback) {
26846   VLOG(1) << __func__;
26847   std::string command;
26848   TPM_RC rc = SerializeCommand_ClearControl(auth, auth_name, disable, &command,
26849                                             authorization_delegate);
26850   if (rc != TPM_RC_SUCCESS) {
26851     base::OnceCallback<void(TPM_RC)> error_reporter =
26852         base::BindOnce(ClearControlErrorCallback, std::move(callback));
26853     std::move(error_reporter).Run(rc);
26854     return;
26855   }
26856   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
26857       ClearControlResponseParser, std::move(callback), authorization_delegate);
26858   transceiver_->SendCommand(command, std::move(parser));
26859 }
26860 
ClearControlSync(const TPMI_RH_CLEAR & auth,const std::string & auth_name,const TPMI_YES_NO & disable,AuthorizationDelegate * authorization_delegate)26861 TPM_RC Tpm::ClearControlSync(const TPMI_RH_CLEAR& auth,
26862                              const std::string& auth_name,
26863                              const TPMI_YES_NO& disable,
26864                              AuthorizationDelegate* authorization_delegate) {
26865   VLOG(1) << __func__;
26866   std::string command;
26867   TPM_RC rc = SerializeCommand_ClearControl(auth, auth_name, disable, &command,
26868                                             authorization_delegate);
26869   if (rc != TPM_RC_SUCCESS) {
26870     return rc;
26871   }
26872   std::string response = transceiver_->SendCommandAndWait(command);
26873   rc = ParseResponse_ClearControl(response, authorization_delegate);
26874   return rc;
26875 }
26876 
SerializeCommand_HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)26877 TPM_RC Tpm::SerializeCommand_HierarchyChangeAuth(
26878     const TPMI_RH_HIERARCHY_AUTH& auth_handle,
26879     const std::string& auth_handle_name,
26880     const TPM2B_AUTH& new_auth,
26881     std::string* serialized_command,
26882     AuthorizationDelegate* authorization_delegate) {
26883   VLOG(3) << __func__;
26884   TPM_RC rc = TPM_RC_SUCCESS;
26885   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
26886   UINT32 command_size = 10;  // Header size.
26887   std::string handle_section_bytes;
26888   std::string parameter_section_bytes;
26889   TPM_CC command_code = TPM_CC_HierarchyChangeAuth;
26890   bool is_command_parameter_encryption_possible = true;
26891   bool is_response_parameter_encryption_possible = false;
26892   std::string command_code_bytes;
26893   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
26894   if (rc != TPM_RC_SUCCESS) {
26895     return rc;
26896   }
26897   std::string auth_handle_bytes;
26898   rc = Serialize_TPMI_RH_HIERARCHY_AUTH(auth_handle, &auth_handle_bytes);
26899   if (rc != TPM_RC_SUCCESS) {
26900     return rc;
26901   }
26902   std::string new_auth_bytes;
26903   rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
26904   if (rc != TPM_RC_SUCCESS) {
26905     return rc;
26906   }
26907   if (authorization_delegate) {
26908     // Encrypt just the parameter data, not the size.
26909     std::string tmp = new_auth_bytes.substr(2);
26910     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
26911       return TRUNKS_RC_ENCRYPTION_FAILED;
26912     }
26913     new_auth_bytes.replace(2, std::string::npos, tmp);
26914   }
26915   std::unique_ptr<crypto::SecureHash> hash(
26916       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
26917   hash->Update(command_code_bytes.data(), command_code_bytes.size());
26918   hash->Update(auth_handle_name.data(), auth_handle_name.size());
26919   handle_section_bytes += auth_handle_bytes;
26920   command_size += auth_handle_bytes.size();
26921   hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
26922   parameter_section_bytes += new_auth_bytes;
26923   command_size += new_auth_bytes.size();
26924   std::string command_hash(32, 0);
26925   hash->Finish(std::data(command_hash), command_hash.size());
26926   std::string authorization_section_bytes;
26927   std::string authorization_size_bytes;
26928   if (authorization_delegate) {
26929     if (!authorization_delegate->GetCommandAuthorization(
26930             command_hash, is_command_parameter_encryption_possible,
26931             is_response_parameter_encryption_possible,
26932             &authorization_section_bytes)) {
26933       return TRUNKS_RC_AUTHORIZATION_FAILED;
26934     }
26935     if (!authorization_section_bytes.empty()) {
26936       tag = TPM_ST_SESSIONS;
26937       std::string tmp;
26938       rc = Serialize_UINT32(authorization_section_bytes.size(),
26939                             &authorization_size_bytes);
26940       if (rc != TPM_RC_SUCCESS) {
26941         return rc;
26942       }
26943       command_size +=
26944           authorization_size_bytes.size() + authorization_section_bytes.size();
26945     }
26946   }
26947   std::string tag_bytes;
26948   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
26949   if (rc != TPM_RC_SUCCESS) {
26950     return rc;
26951   }
26952   std::string command_size_bytes;
26953   rc = Serialize_UINT32(command_size, &command_size_bytes);
26954   if (rc != TPM_RC_SUCCESS) {
26955     return rc;
26956   }
26957   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
26958                         handle_section_bytes + authorization_size_bytes +
26959                         authorization_section_bytes + parameter_section_bytes;
26960   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
26961   VLOG(2) << "Command: "
26962           << base::HexEncode(serialized_command->data(),
26963                              serialized_command->size());
26964   return TPM_RC_SUCCESS;
26965 }
26966 
ParseResponse_HierarchyChangeAuth(const std::string & response,AuthorizationDelegate * authorization_delegate)26967 TPM_RC Tpm::ParseResponse_HierarchyChangeAuth(
26968     const std::string& response,
26969     AuthorizationDelegate* authorization_delegate) {
26970   VLOG(3) << __func__;
26971   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
26972   TPM_RC rc = TPM_RC_SUCCESS;
26973   std::string buffer(response);
26974   TPM_ST tag;
26975   std::string tag_bytes;
26976   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
26977   if (rc != TPM_RC_SUCCESS) {
26978     return rc;
26979   }
26980   UINT32 response_size;
26981   std::string response_size_bytes;
26982   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
26983   if (rc != TPM_RC_SUCCESS) {
26984     return rc;
26985   }
26986   TPM_RC response_code;
26987   std::string response_code_bytes;
26988   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
26989   if (rc != TPM_RC_SUCCESS) {
26990     return rc;
26991   }
26992   if (response_size != response.size()) {
26993     return TPM_RC_SIZE;
26994   }
26995   if (response_code != TPM_RC_SUCCESS) {
26996     return response_code;
26997   }
26998   TPM_CC command_code = TPM_CC_HierarchyChangeAuth;
26999   std::string command_code_bytes;
27000   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27001   if (rc != TPM_RC_SUCCESS) {
27002     return rc;
27003   }
27004   std::string authorization_section_bytes;
27005   if (tag == TPM_ST_SESSIONS) {
27006     UINT32 parameter_section_size = buffer.size();
27007     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27008     if (rc != TPM_RC_SUCCESS) {
27009       return rc;
27010     }
27011     if (parameter_section_size > buffer.size()) {
27012       return TPM_RC_INSUFFICIENT;
27013     }
27014     authorization_section_bytes = buffer.substr(parameter_section_size);
27015     // Keep the parameter section in |buffer|.
27016     buffer.erase(parameter_section_size);
27017   }
27018   std::unique_ptr<crypto::SecureHash> hash(
27019       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27020   hash->Update(response_code_bytes.data(), response_code_bytes.size());
27021   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27022   hash->Update(buffer.data(), buffer.size());
27023   std::string response_hash(32, 0);
27024   hash->Finish(std::data(response_hash), response_hash.size());
27025   if (tag == TPM_ST_SESSIONS) {
27026     if (!authorization_delegate)
27027       return TRUNKS_RC_AUTHORIZATION_FAILED;
27028     if (!authorization_delegate->CheckResponseAuthorization(
27029             response_hash, authorization_section_bytes)) {
27030       return TRUNKS_RC_AUTHORIZATION_FAILED;
27031     }
27032   }
27033   return TPM_RC_SUCCESS;
27034 }
27035 
HierarchyChangeAuthErrorCallback(Tpm::HierarchyChangeAuthResponse callback,TPM_RC response_code)27036 void HierarchyChangeAuthErrorCallback(Tpm::HierarchyChangeAuthResponse callback,
27037                                       TPM_RC response_code) {
27038   VLOG(1) << __func__;
27039   std::move(callback).Run(response_code);
27040 }
27041 
HierarchyChangeAuthResponseParser(Tpm::HierarchyChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27042 void HierarchyChangeAuthResponseParser(
27043     Tpm::HierarchyChangeAuthResponse callback,
27044     AuthorizationDelegate* authorization_delegate,
27045     const std::string& response) {
27046   VLOG(1) << __func__;
27047   TPM_RC rc =
27048       Tpm::ParseResponse_HierarchyChangeAuth(response, authorization_delegate);
27049   if (rc != TPM_RC_SUCCESS) {
27050     base::OnceCallback<void(TPM_RC)> error_reporter =
27051         base::BindOnce(HierarchyChangeAuthErrorCallback, std::move(callback));
27052     std::move(error_reporter).Run(rc);
27053     return;
27054   }
27055   std::move(callback).Run(rc);
27056 }
27057 
HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate,HierarchyChangeAuthResponse callback)27058 void Tpm::HierarchyChangeAuth(const TPMI_RH_HIERARCHY_AUTH& auth_handle,
27059                               const std::string& auth_handle_name,
27060                               const TPM2B_AUTH& new_auth,
27061                               AuthorizationDelegate* authorization_delegate,
27062                               HierarchyChangeAuthResponse callback) {
27063   VLOG(1) << __func__;
27064   std::string command;
27065   TPM_RC rc = SerializeCommand_HierarchyChangeAuth(
27066       auth_handle, auth_handle_name, new_auth, &command,
27067       authorization_delegate);
27068   if (rc != TPM_RC_SUCCESS) {
27069     base::OnceCallback<void(TPM_RC)> error_reporter =
27070         base::BindOnce(HierarchyChangeAuthErrorCallback, std::move(callback));
27071     std::move(error_reporter).Run(rc);
27072     return;
27073   }
27074   base::OnceCallback<void(const std::string&)> parser =
27075       base::BindOnce(HierarchyChangeAuthResponseParser, std::move(callback),
27076                      authorization_delegate);
27077   transceiver_->SendCommand(command, std::move(parser));
27078 }
27079 
HierarchyChangeAuthSync(const TPMI_RH_HIERARCHY_AUTH & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate)27080 TPM_RC Tpm::HierarchyChangeAuthSync(
27081     const TPMI_RH_HIERARCHY_AUTH& auth_handle,
27082     const std::string& auth_handle_name,
27083     const TPM2B_AUTH& new_auth,
27084     AuthorizationDelegate* authorization_delegate) {
27085   VLOG(1) << __func__;
27086   std::string command;
27087   TPM_RC rc = SerializeCommand_HierarchyChangeAuth(
27088       auth_handle, auth_handle_name, new_auth, &command,
27089       authorization_delegate);
27090   if (rc != TPM_RC_SUCCESS) {
27091     return rc;
27092   }
27093   std::string response = transceiver_->SendCommandAndWait(command);
27094   rc = ParseResponse_HierarchyChangeAuth(response, authorization_delegate);
27095   return rc;
27096 }
27097 
SerializeCommand_DictionaryAttackLockReset(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27098 TPM_RC Tpm::SerializeCommand_DictionaryAttackLockReset(
27099     const TPMI_RH_LOCKOUT& lock_handle,
27100     const std::string& lock_handle_name,
27101     std::string* serialized_command,
27102     AuthorizationDelegate* authorization_delegate) {
27103   VLOG(3) << __func__;
27104   TPM_RC rc = TPM_RC_SUCCESS;
27105   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27106   UINT32 command_size = 10;  // Header size.
27107   std::string handle_section_bytes;
27108   std::string parameter_section_bytes;
27109   TPM_CC command_code = TPM_CC_DictionaryAttackLockReset;
27110   bool is_command_parameter_encryption_possible = false;
27111   bool is_response_parameter_encryption_possible = false;
27112   std::string command_code_bytes;
27113   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27114   if (rc != TPM_RC_SUCCESS) {
27115     return rc;
27116   }
27117   std::string lock_handle_bytes;
27118   rc = Serialize_TPMI_RH_LOCKOUT(lock_handle, &lock_handle_bytes);
27119   if (rc != TPM_RC_SUCCESS) {
27120     return rc;
27121   }
27122   std::unique_ptr<crypto::SecureHash> hash(
27123       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27124   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27125   hash->Update(lock_handle_name.data(), lock_handle_name.size());
27126   handle_section_bytes += lock_handle_bytes;
27127   command_size += lock_handle_bytes.size();
27128   std::string command_hash(32, 0);
27129   hash->Finish(std::data(command_hash), command_hash.size());
27130   std::string authorization_section_bytes;
27131   std::string authorization_size_bytes;
27132   if (authorization_delegate) {
27133     if (!authorization_delegate->GetCommandAuthorization(
27134             command_hash, is_command_parameter_encryption_possible,
27135             is_response_parameter_encryption_possible,
27136             &authorization_section_bytes)) {
27137       return TRUNKS_RC_AUTHORIZATION_FAILED;
27138     }
27139     if (!authorization_section_bytes.empty()) {
27140       tag = TPM_ST_SESSIONS;
27141       std::string tmp;
27142       rc = Serialize_UINT32(authorization_section_bytes.size(),
27143                             &authorization_size_bytes);
27144       if (rc != TPM_RC_SUCCESS) {
27145         return rc;
27146       }
27147       command_size +=
27148           authorization_size_bytes.size() + authorization_section_bytes.size();
27149     }
27150   }
27151   std::string tag_bytes;
27152   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27153   if (rc != TPM_RC_SUCCESS) {
27154     return rc;
27155   }
27156   std::string command_size_bytes;
27157   rc = Serialize_UINT32(command_size, &command_size_bytes);
27158   if (rc != TPM_RC_SUCCESS) {
27159     return rc;
27160   }
27161   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27162                         handle_section_bytes + authorization_size_bytes +
27163                         authorization_section_bytes + parameter_section_bytes;
27164   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27165   VLOG(2) << "Command: "
27166           << base::HexEncode(serialized_command->data(),
27167                              serialized_command->size());
27168   return TPM_RC_SUCCESS;
27169 }
27170 
ParseResponse_DictionaryAttackLockReset(const std::string & response,AuthorizationDelegate * authorization_delegate)27171 TPM_RC Tpm::ParseResponse_DictionaryAttackLockReset(
27172     const std::string& response,
27173     AuthorizationDelegate* authorization_delegate) {
27174   VLOG(3) << __func__;
27175   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27176   TPM_RC rc = TPM_RC_SUCCESS;
27177   std::string buffer(response);
27178   TPM_ST tag;
27179   std::string tag_bytes;
27180   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27181   if (rc != TPM_RC_SUCCESS) {
27182     return rc;
27183   }
27184   UINT32 response_size;
27185   std::string response_size_bytes;
27186   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27187   if (rc != TPM_RC_SUCCESS) {
27188     return rc;
27189   }
27190   TPM_RC response_code;
27191   std::string response_code_bytes;
27192   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27193   if (rc != TPM_RC_SUCCESS) {
27194     return rc;
27195   }
27196   if (response_size != response.size()) {
27197     return TPM_RC_SIZE;
27198   }
27199   if (response_code != TPM_RC_SUCCESS) {
27200     return response_code;
27201   }
27202   TPM_CC command_code = TPM_CC_DictionaryAttackLockReset;
27203   std::string command_code_bytes;
27204   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27205   if (rc != TPM_RC_SUCCESS) {
27206     return rc;
27207   }
27208   std::string authorization_section_bytes;
27209   if (tag == TPM_ST_SESSIONS) {
27210     UINT32 parameter_section_size = buffer.size();
27211     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27212     if (rc != TPM_RC_SUCCESS) {
27213       return rc;
27214     }
27215     if (parameter_section_size > buffer.size()) {
27216       return TPM_RC_INSUFFICIENT;
27217     }
27218     authorization_section_bytes = buffer.substr(parameter_section_size);
27219     // Keep the parameter section in |buffer|.
27220     buffer.erase(parameter_section_size);
27221   }
27222   std::unique_ptr<crypto::SecureHash> hash(
27223       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27224   hash->Update(response_code_bytes.data(), response_code_bytes.size());
27225   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27226   hash->Update(buffer.data(), buffer.size());
27227   std::string response_hash(32, 0);
27228   hash->Finish(std::data(response_hash), response_hash.size());
27229   if (tag == TPM_ST_SESSIONS) {
27230     if (!authorization_delegate)
27231       return TRUNKS_RC_AUTHORIZATION_FAILED;
27232     if (!authorization_delegate->CheckResponseAuthorization(
27233             response_hash, authorization_section_bytes)) {
27234       return TRUNKS_RC_AUTHORIZATION_FAILED;
27235     }
27236   }
27237   return TPM_RC_SUCCESS;
27238 }
27239 
DictionaryAttackLockResetErrorCallback(Tpm::DictionaryAttackLockResetResponse callback,TPM_RC response_code)27240 void DictionaryAttackLockResetErrorCallback(
27241     Tpm::DictionaryAttackLockResetResponse callback, TPM_RC response_code) {
27242   VLOG(1) << __func__;
27243   std::move(callback).Run(response_code);
27244 }
27245 
DictionaryAttackLockResetResponseParser(Tpm::DictionaryAttackLockResetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27246 void DictionaryAttackLockResetResponseParser(
27247     Tpm::DictionaryAttackLockResetResponse callback,
27248     AuthorizationDelegate* authorization_delegate,
27249     const std::string& response) {
27250   VLOG(1) << __func__;
27251   TPM_RC rc = Tpm::ParseResponse_DictionaryAttackLockReset(
27252       response, authorization_delegate);
27253   if (rc != TPM_RC_SUCCESS) {
27254     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27255         DictionaryAttackLockResetErrorCallback, std::move(callback));
27256     std::move(error_reporter).Run(rc);
27257     return;
27258   }
27259   std::move(callback).Run(rc);
27260 }
27261 
DictionaryAttackLockReset(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,AuthorizationDelegate * authorization_delegate,DictionaryAttackLockResetResponse callback)27262 void Tpm::DictionaryAttackLockReset(
27263     const TPMI_RH_LOCKOUT& lock_handle,
27264     const std::string& lock_handle_name,
27265     AuthorizationDelegate* authorization_delegate,
27266     DictionaryAttackLockResetResponse callback) {
27267   VLOG(1) << __func__;
27268   std::string command;
27269   TPM_RC rc = SerializeCommand_DictionaryAttackLockReset(
27270       lock_handle, lock_handle_name, &command, authorization_delegate);
27271   if (rc != TPM_RC_SUCCESS) {
27272     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27273         DictionaryAttackLockResetErrorCallback, std::move(callback));
27274     std::move(error_reporter).Run(rc);
27275     return;
27276   }
27277   base::OnceCallback<void(const std::string&)> parser =
27278       base::BindOnce(DictionaryAttackLockResetResponseParser,
27279                      std::move(callback), authorization_delegate);
27280   transceiver_->SendCommand(command, std::move(parser));
27281 }
27282 
DictionaryAttackLockResetSync(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,AuthorizationDelegate * authorization_delegate)27283 TPM_RC Tpm::DictionaryAttackLockResetSync(
27284     const TPMI_RH_LOCKOUT& lock_handle,
27285     const std::string& lock_handle_name,
27286     AuthorizationDelegate* authorization_delegate) {
27287   VLOG(1) << __func__;
27288   std::string command;
27289   TPM_RC rc = SerializeCommand_DictionaryAttackLockReset(
27290       lock_handle, lock_handle_name, &command, authorization_delegate);
27291   if (rc != TPM_RC_SUCCESS) {
27292     return rc;
27293   }
27294   std::string response = transceiver_->SendCommandAndWait(command);
27295   rc =
27296       ParseResponse_DictionaryAttackLockReset(response, authorization_delegate);
27297   return rc;
27298 }
27299 
SerializeCommand_DictionaryAttackParameters(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,const UINT32 & new_max_tries,const UINT32 & new_recovery_time,const UINT32 & lockout_recovery,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27300 TPM_RC Tpm::SerializeCommand_DictionaryAttackParameters(
27301     const TPMI_RH_LOCKOUT& lock_handle,
27302     const std::string& lock_handle_name,
27303     const UINT32& new_max_tries,
27304     const UINT32& new_recovery_time,
27305     const UINT32& lockout_recovery,
27306     std::string* serialized_command,
27307     AuthorizationDelegate* authorization_delegate) {
27308   VLOG(3) << __func__;
27309   TPM_RC rc = TPM_RC_SUCCESS;
27310   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27311   UINT32 command_size = 10;  // Header size.
27312   std::string handle_section_bytes;
27313   std::string parameter_section_bytes;
27314   TPM_CC command_code = TPM_CC_DictionaryAttackParameters;
27315   bool is_command_parameter_encryption_possible = false;
27316   bool is_response_parameter_encryption_possible = false;
27317   std::string command_code_bytes;
27318   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27319   if (rc != TPM_RC_SUCCESS) {
27320     return rc;
27321   }
27322   std::string lock_handle_bytes;
27323   rc = Serialize_TPMI_RH_LOCKOUT(lock_handle, &lock_handle_bytes);
27324   if (rc != TPM_RC_SUCCESS) {
27325     return rc;
27326   }
27327   std::string new_max_tries_bytes;
27328   rc = Serialize_UINT32(new_max_tries, &new_max_tries_bytes);
27329   if (rc != TPM_RC_SUCCESS) {
27330     return rc;
27331   }
27332   std::string new_recovery_time_bytes;
27333   rc = Serialize_UINT32(new_recovery_time, &new_recovery_time_bytes);
27334   if (rc != TPM_RC_SUCCESS) {
27335     return rc;
27336   }
27337   std::string lockout_recovery_bytes;
27338   rc = Serialize_UINT32(lockout_recovery, &lockout_recovery_bytes);
27339   if (rc != TPM_RC_SUCCESS) {
27340     return rc;
27341   }
27342   std::unique_ptr<crypto::SecureHash> hash(
27343       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27344   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27345   hash->Update(lock_handle_name.data(), lock_handle_name.size());
27346   handle_section_bytes += lock_handle_bytes;
27347   command_size += lock_handle_bytes.size();
27348   hash->Update(new_max_tries_bytes.data(), new_max_tries_bytes.size());
27349   parameter_section_bytes += new_max_tries_bytes;
27350   command_size += new_max_tries_bytes.size();
27351   hash->Update(new_recovery_time_bytes.data(), new_recovery_time_bytes.size());
27352   parameter_section_bytes += new_recovery_time_bytes;
27353   command_size += new_recovery_time_bytes.size();
27354   hash->Update(lockout_recovery_bytes.data(), lockout_recovery_bytes.size());
27355   parameter_section_bytes += lockout_recovery_bytes;
27356   command_size += lockout_recovery_bytes.size();
27357   std::string command_hash(32, 0);
27358   hash->Finish(std::data(command_hash), command_hash.size());
27359   std::string authorization_section_bytes;
27360   std::string authorization_size_bytes;
27361   if (authorization_delegate) {
27362     if (!authorization_delegate->GetCommandAuthorization(
27363             command_hash, is_command_parameter_encryption_possible,
27364             is_response_parameter_encryption_possible,
27365             &authorization_section_bytes)) {
27366       return TRUNKS_RC_AUTHORIZATION_FAILED;
27367     }
27368     if (!authorization_section_bytes.empty()) {
27369       tag = TPM_ST_SESSIONS;
27370       std::string tmp;
27371       rc = Serialize_UINT32(authorization_section_bytes.size(),
27372                             &authorization_size_bytes);
27373       if (rc != TPM_RC_SUCCESS) {
27374         return rc;
27375       }
27376       command_size +=
27377           authorization_size_bytes.size() + authorization_section_bytes.size();
27378     }
27379   }
27380   std::string tag_bytes;
27381   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27382   if (rc != TPM_RC_SUCCESS) {
27383     return rc;
27384   }
27385   std::string command_size_bytes;
27386   rc = Serialize_UINT32(command_size, &command_size_bytes);
27387   if (rc != TPM_RC_SUCCESS) {
27388     return rc;
27389   }
27390   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27391                         handle_section_bytes + authorization_size_bytes +
27392                         authorization_section_bytes + parameter_section_bytes;
27393   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27394   VLOG(2) << "Command: "
27395           << base::HexEncode(serialized_command->data(),
27396                              serialized_command->size());
27397   return TPM_RC_SUCCESS;
27398 }
27399 
ParseResponse_DictionaryAttackParameters(const std::string & response,AuthorizationDelegate * authorization_delegate)27400 TPM_RC Tpm::ParseResponse_DictionaryAttackParameters(
27401     const std::string& response,
27402     AuthorizationDelegate* authorization_delegate) {
27403   VLOG(3) << __func__;
27404   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27405   TPM_RC rc = TPM_RC_SUCCESS;
27406   std::string buffer(response);
27407   TPM_ST tag;
27408   std::string tag_bytes;
27409   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27410   if (rc != TPM_RC_SUCCESS) {
27411     return rc;
27412   }
27413   UINT32 response_size;
27414   std::string response_size_bytes;
27415   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27416   if (rc != TPM_RC_SUCCESS) {
27417     return rc;
27418   }
27419   TPM_RC response_code;
27420   std::string response_code_bytes;
27421   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27422   if (rc != TPM_RC_SUCCESS) {
27423     return rc;
27424   }
27425   if (response_size != response.size()) {
27426     return TPM_RC_SIZE;
27427   }
27428   if (response_code != TPM_RC_SUCCESS) {
27429     return response_code;
27430   }
27431   TPM_CC command_code = TPM_CC_DictionaryAttackParameters;
27432   std::string command_code_bytes;
27433   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27434   if (rc != TPM_RC_SUCCESS) {
27435     return rc;
27436   }
27437   std::string authorization_section_bytes;
27438   if (tag == TPM_ST_SESSIONS) {
27439     UINT32 parameter_section_size = buffer.size();
27440     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27441     if (rc != TPM_RC_SUCCESS) {
27442       return rc;
27443     }
27444     if (parameter_section_size > buffer.size()) {
27445       return TPM_RC_INSUFFICIENT;
27446     }
27447     authorization_section_bytes = buffer.substr(parameter_section_size);
27448     // Keep the parameter section in |buffer|.
27449     buffer.erase(parameter_section_size);
27450   }
27451   std::unique_ptr<crypto::SecureHash> hash(
27452       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27453   hash->Update(response_code_bytes.data(), response_code_bytes.size());
27454   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27455   hash->Update(buffer.data(), buffer.size());
27456   std::string response_hash(32, 0);
27457   hash->Finish(std::data(response_hash), response_hash.size());
27458   if (tag == TPM_ST_SESSIONS) {
27459     if (!authorization_delegate)
27460       return TRUNKS_RC_AUTHORIZATION_FAILED;
27461     if (!authorization_delegate->CheckResponseAuthorization(
27462             response_hash, authorization_section_bytes)) {
27463       return TRUNKS_RC_AUTHORIZATION_FAILED;
27464     }
27465   }
27466   return TPM_RC_SUCCESS;
27467 }
27468 
DictionaryAttackParametersErrorCallback(Tpm::DictionaryAttackParametersResponse callback,TPM_RC response_code)27469 void DictionaryAttackParametersErrorCallback(
27470     Tpm::DictionaryAttackParametersResponse callback, TPM_RC response_code) {
27471   VLOG(1) << __func__;
27472   std::move(callback).Run(response_code);
27473 }
27474 
DictionaryAttackParametersResponseParser(Tpm::DictionaryAttackParametersResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27475 void DictionaryAttackParametersResponseParser(
27476     Tpm::DictionaryAttackParametersResponse callback,
27477     AuthorizationDelegate* authorization_delegate,
27478     const std::string& response) {
27479   VLOG(1) << __func__;
27480   TPM_RC rc = Tpm::ParseResponse_DictionaryAttackParameters(
27481       response, authorization_delegate);
27482   if (rc != TPM_RC_SUCCESS) {
27483     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27484         DictionaryAttackParametersErrorCallback, std::move(callback));
27485     std::move(error_reporter).Run(rc);
27486     return;
27487   }
27488   std::move(callback).Run(rc);
27489 }
27490 
DictionaryAttackParameters(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,const UINT32 & new_max_tries,const UINT32 & new_recovery_time,const UINT32 & lockout_recovery,AuthorizationDelegate * authorization_delegate,DictionaryAttackParametersResponse callback)27491 void Tpm::DictionaryAttackParameters(
27492     const TPMI_RH_LOCKOUT& lock_handle,
27493     const std::string& lock_handle_name,
27494     const UINT32& new_max_tries,
27495     const UINT32& new_recovery_time,
27496     const UINT32& lockout_recovery,
27497     AuthorizationDelegate* authorization_delegate,
27498     DictionaryAttackParametersResponse callback) {
27499   VLOG(1) << __func__;
27500   std::string command;
27501   TPM_RC rc = SerializeCommand_DictionaryAttackParameters(
27502       lock_handle, lock_handle_name, new_max_tries, new_recovery_time,
27503       lockout_recovery, &command, authorization_delegate);
27504   if (rc != TPM_RC_SUCCESS) {
27505     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
27506         DictionaryAttackParametersErrorCallback, std::move(callback));
27507     std::move(error_reporter).Run(rc);
27508     return;
27509   }
27510   base::OnceCallback<void(const std::string&)> parser =
27511       base::BindOnce(DictionaryAttackParametersResponseParser,
27512                      std::move(callback), authorization_delegate);
27513   transceiver_->SendCommand(command, std::move(parser));
27514 }
27515 
DictionaryAttackParametersSync(const TPMI_RH_LOCKOUT & lock_handle,const std::string & lock_handle_name,const UINT32 & new_max_tries,const UINT32 & new_recovery_time,const UINT32 & lockout_recovery,AuthorizationDelegate * authorization_delegate)27516 TPM_RC Tpm::DictionaryAttackParametersSync(
27517     const TPMI_RH_LOCKOUT& lock_handle,
27518     const std::string& lock_handle_name,
27519     const UINT32& new_max_tries,
27520     const UINT32& new_recovery_time,
27521     const UINT32& lockout_recovery,
27522     AuthorizationDelegate* authorization_delegate) {
27523   VLOG(1) << __func__;
27524   std::string command;
27525   TPM_RC rc = SerializeCommand_DictionaryAttackParameters(
27526       lock_handle, lock_handle_name, new_max_tries, new_recovery_time,
27527       lockout_recovery, &command, authorization_delegate);
27528   if (rc != TPM_RC_SUCCESS) {
27529     return rc;
27530   }
27531   std::string response = transceiver_->SendCommandAndWait(command);
27532   rc = ParseResponse_DictionaryAttackParameters(response,
27533                                                 authorization_delegate);
27534   return rc;
27535 }
27536 
SerializeCommand_PP_Commands(const TPMI_RH_PLATFORM & auth,const std::string & auth_name,const TPML_CC & set_list,const TPML_CC & clear_list,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27537 TPM_RC Tpm::SerializeCommand_PP_Commands(
27538     const TPMI_RH_PLATFORM& auth,
27539     const std::string& auth_name,
27540     const TPML_CC& set_list,
27541     const TPML_CC& clear_list,
27542     std::string* serialized_command,
27543     AuthorizationDelegate* authorization_delegate) {
27544   VLOG(3) << __func__;
27545   TPM_RC rc = TPM_RC_SUCCESS;
27546   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27547   UINT32 command_size = 10;  // Header size.
27548   std::string handle_section_bytes;
27549   std::string parameter_section_bytes;
27550   TPM_CC command_code = TPM_CC_PP_Commands;
27551   bool is_command_parameter_encryption_possible = false;
27552   bool is_response_parameter_encryption_possible = false;
27553   std::string command_code_bytes;
27554   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27555   if (rc != TPM_RC_SUCCESS) {
27556     return rc;
27557   }
27558   std::string auth_bytes;
27559   rc = Serialize_TPMI_RH_PLATFORM(auth, &auth_bytes);
27560   if (rc != TPM_RC_SUCCESS) {
27561     return rc;
27562   }
27563   std::string set_list_bytes;
27564   rc = Serialize_TPML_CC(set_list, &set_list_bytes);
27565   if (rc != TPM_RC_SUCCESS) {
27566     return rc;
27567   }
27568   std::string clear_list_bytes;
27569   rc = Serialize_TPML_CC(clear_list, &clear_list_bytes);
27570   if (rc != TPM_RC_SUCCESS) {
27571     return rc;
27572   }
27573   std::unique_ptr<crypto::SecureHash> hash(
27574       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27575   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27576   hash->Update(auth_name.data(), auth_name.size());
27577   handle_section_bytes += auth_bytes;
27578   command_size += auth_bytes.size();
27579   hash->Update(set_list_bytes.data(), set_list_bytes.size());
27580   parameter_section_bytes += set_list_bytes;
27581   command_size += set_list_bytes.size();
27582   hash->Update(clear_list_bytes.data(), clear_list_bytes.size());
27583   parameter_section_bytes += clear_list_bytes;
27584   command_size += clear_list_bytes.size();
27585   std::string command_hash(32, 0);
27586   hash->Finish(std::data(command_hash), command_hash.size());
27587   std::string authorization_section_bytes;
27588   std::string authorization_size_bytes;
27589   if (authorization_delegate) {
27590     if (!authorization_delegate->GetCommandAuthorization(
27591             command_hash, is_command_parameter_encryption_possible,
27592             is_response_parameter_encryption_possible,
27593             &authorization_section_bytes)) {
27594       return TRUNKS_RC_AUTHORIZATION_FAILED;
27595     }
27596     if (!authorization_section_bytes.empty()) {
27597       tag = TPM_ST_SESSIONS;
27598       std::string tmp;
27599       rc = Serialize_UINT32(authorization_section_bytes.size(),
27600                             &authorization_size_bytes);
27601       if (rc != TPM_RC_SUCCESS) {
27602         return rc;
27603       }
27604       command_size +=
27605           authorization_size_bytes.size() + authorization_section_bytes.size();
27606     }
27607   }
27608   std::string tag_bytes;
27609   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27610   if (rc != TPM_RC_SUCCESS) {
27611     return rc;
27612   }
27613   std::string command_size_bytes;
27614   rc = Serialize_UINT32(command_size, &command_size_bytes);
27615   if (rc != TPM_RC_SUCCESS) {
27616     return rc;
27617   }
27618   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27619                         handle_section_bytes + authorization_size_bytes +
27620                         authorization_section_bytes + parameter_section_bytes;
27621   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27622   VLOG(2) << "Command: "
27623           << base::HexEncode(serialized_command->data(),
27624                              serialized_command->size());
27625   return TPM_RC_SUCCESS;
27626 }
27627 
ParseResponse_PP_Commands(const std::string & response,AuthorizationDelegate * authorization_delegate)27628 TPM_RC Tpm::ParseResponse_PP_Commands(
27629     const std::string& response,
27630     AuthorizationDelegate* authorization_delegate) {
27631   VLOG(3) << __func__;
27632   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27633   TPM_RC rc = TPM_RC_SUCCESS;
27634   std::string buffer(response);
27635   TPM_ST tag;
27636   std::string tag_bytes;
27637   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27638   if (rc != TPM_RC_SUCCESS) {
27639     return rc;
27640   }
27641   UINT32 response_size;
27642   std::string response_size_bytes;
27643   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27644   if (rc != TPM_RC_SUCCESS) {
27645     return rc;
27646   }
27647   TPM_RC response_code;
27648   std::string response_code_bytes;
27649   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27650   if (rc != TPM_RC_SUCCESS) {
27651     return rc;
27652   }
27653   if (response_size != response.size()) {
27654     return TPM_RC_SIZE;
27655   }
27656   if (response_code != TPM_RC_SUCCESS) {
27657     return response_code;
27658   }
27659   TPM_CC command_code = TPM_CC_PP_Commands;
27660   std::string command_code_bytes;
27661   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27662   if (rc != TPM_RC_SUCCESS) {
27663     return rc;
27664   }
27665   std::string authorization_section_bytes;
27666   if (tag == TPM_ST_SESSIONS) {
27667     UINT32 parameter_section_size = buffer.size();
27668     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27669     if (rc != TPM_RC_SUCCESS) {
27670       return rc;
27671     }
27672     if (parameter_section_size > buffer.size()) {
27673       return TPM_RC_INSUFFICIENT;
27674     }
27675     authorization_section_bytes = buffer.substr(parameter_section_size);
27676     // Keep the parameter section in |buffer|.
27677     buffer.erase(parameter_section_size);
27678   }
27679   std::unique_ptr<crypto::SecureHash> hash(
27680       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27681   hash->Update(response_code_bytes.data(), response_code_bytes.size());
27682   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27683   hash->Update(buffer.data(), buffer.size());
27684   std::string response_hash(32, 0);
27685   hash->Finish(std::data(response_hash), response_hash.size());
27686   if (tag == TPM_ST_SESSIONS) {
27687     if (!authorization_delegate)
27688       return TRUNKS_RC_AUTHORIZATION_FAILED;
27689     if (!authorization_delegate->CheckResponseAuthorization(
27690             response_hash, authorization_section_bytes)) {
27691       return TRUNKS_RC_AUTHORIZATION_FAILED;
27692     }
27693   }
27694   return TPM_RC_SUCCESS;
27695 }
27696 
PP_CommandsErrorCallback(Tpm::PP_CommandsResponse callback,TPM_RC response_code)27697 void PP_CommandsErrorCallback(Tpm::PP_CommandsResponse callback,
27698                               TPM_RC response_code) {
27699   VLOG(1) << __func__;
27700   std::move(callback).Run(response_code);
27701 }
27702 
PP_CommandsResponseParser(Tpm::PP_CommandsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27703 void PP_CommandsResponseParser(Tpm::PP_CommandsResponse callback,
27704                                AuthorizationDelegate* authorization_delegate,
27705                                const std::string& response) {
27706   VLOG(1) << __func__;
27707   TPM_RC rc = Tpm::ParseResponse_PP_Commands(response, authorization_delegate);
27708   if (rc != TPM_RC_SUCCESS) {
27709     base::OnceCallback<void(TPM_RC)> error_reporter =
27710         base::BindOnce(PP_CommandsErrorCallback, std::move(callback));
27711     std::move(error_reporter).Run(rc);
27712     return;
27713   }
27714   std::move(callback).Run(rc);
27715 }
27716 
PP_Commands(const TPMI_RH_PLATFORM & auth,const std::string & auth_name,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate,PP_CommandsResponse callback)27717 void Tpm::PP_Commands(const TPMI_RH_PLATFORM& auth,
27718                       const std::string& auth_name,
27719                       const TPML_CC& set_list,
27720                       const TPML_CC& clear_list,
27721                       AuthorizationDelegate* authorization_delegate,
27722                       PP_CommandsResponse callback) {
27723   VLOG(1) << __func__;
27724   std::string command;
27725   TPM_RC rc = SerializeCommand_PP_Commands(
27726       auth, auth_name, set_list, clear_list, &command, authorization_delegate);
27727   if (rc != TPM_RC_SUCCESS) {
27728     base::OnceCallback<void(TPM_RC)> error_reporter =
27729         base::BindOnce(PP_CommandsErrorCallback, std::move(callback));
27730     std::move(error_reporter).Run(rc);
27731     return;
27732   }
27733   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
27734       PP_CommandsResponseParser, std::move(callback), authorization_delegate);
27735   transceiver_->SendCommand(command, std::move(parser));
27736 }
27737 
PP_CommandsSync(const TPMI_RH_PLATFORM & auth,const std::string & auth_name,const TPML_CC & set_list,const TPML_CC & clear_list,AuthorizationDelegate * authorization_delegate)27738 TPM_RC Tpm::PP_CommandsSync(const TPMI_RH_PLATFORM& auth,
27739                             const std::string& auth_name,
27740                             const TPML_CC& set_list,
27741                             const TPML_CC& clear_list,
27742                             AuthorizationDelegate* authorization_delegate) {
27743   VLOG(1) << __func__;
27744   std::string command;
27745   TPM_RC rc = SerializeCommand_PP_Commands(
27746       auth, auth_name, set_list, clear_list, &command, authorization_delegate);
27747   if (rc != TPM_RC_SUCCESS) {
27748     return rc;
27749   }
27750   std::string response = transceiver_->SendCommandAndWait(command);
27751   rc = ParseResponse_PP_Commands(response, authorization_delegate);
27752   return rc;
27753 }
27754 
SerializeCommand_SetAlgorithmSet(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27755 TPM_RC Tpm::SerializeCommand_SetAlgorithmSet(
27756     const TPMI_RH_PLATFORM& auth_handle,
27757     const std::string& auth_handle_name,
27758     const UINT32& algorithm_set,
27759     std::string* serialized_command,
27760     AuthorizationDelegate* authorization_delegate) {
27761   VLOG(3) << __func__;
27762   TPM_RC rc = TPM_RC_SUCCESS;
27763   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27764   UINT32 command_size = 10;  // Header size.
27765   std::string handle_section_bytes;
27766   std::string parameter_section_bytes;
27767   TPM_CC command_code = TPM_CC_SetAlgorithmSet;
27768   bool is_command_parameter_encryption_possible = false;
27769   bool is_response_parameter_encryption_possible = false;
27770   std::string command_code_bytes;
27771   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27772   if (rc != TPM_RC_SUCCESS) {
27773     return rc;
27774   }
27775   std::string auth_handle_bytes;
27776   rc = Serialize_TPMI_RH_PLATFORM(auth_handle, &auth_handle_bytes);
27777   if (rc != TPM_RC_SUCCESS) {
27778     return rc;
27779   }
27780   std::string algorithm_set_bytes;
27781   rc = Serialize_UINT32(algorithm_set, &algorithm_set_bytes);
27782   if (rc != TPM_RC_SUCCESS) {
27783     return rc;
27784   }
27785   std::unique_ptr<crypto::SecureHash> hash(
27786       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27787   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27788   hash->Update(auth_handle_name.data(), auth_handle_name.size());
27789   handle_section_bytes += auth_handle_bytes;
27790   command_size += auth_handle_bytes.size();
27791   hash->Update(algorithm_set_bytes.data(), algorithm_set_bytes.size());
27792   parameter_section_bytes += algorithm_set_bytes;
27793   command_size += algorithm_set_bytes.size();
27794   std::string command_hash(32, 0);
27795   hash->Finish(std::data(command_hash), command_hash.size());
27796   std::string authorization_section_bytes;
27797   std::string authorization_size_bytes;
27798   if (authorization_delegate) {
27799     if (!authorization_delegate->GetCommandAuthorization(
27800             command_hash, is_command_parameter_encryption_possible,
27801             is_response_parameter_encryption_possible,
27802             &authorization_section_bytes)) {
27803       return TRUNKS_RC_AUTHORIZATION_FAILED;
27804     }
27805     if (!authorization_section_bytes.empty()) {
27806       tag = TPM_ST_SESSIONS;
27807       std::string tmp;
27808       rc = Serialize_UINT32(authorization_section_bytes.size(),
27809                             &authorization_size_bytes);
27810       if (rc != TPM_RC_SUCCESS) {
27811         return rc;
27812       }
27813       command_size +=
27814           authorization_size_bytes.size() + authorization_section_bytes.size();
27815     }
27816   }
27817   std::string tag_bytes;
27818   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
27819   if (rc != TPM_RC_SUCCESS) {
27820     return rc;
27821   }
27822   std::string command_size_bytes;
27823   rc = Serialize_UINT32(command_size, &command_size_bytes);
27824   if (rc != TPM_RC_SUCCESS) {
27825     return rc;
27826   }
27827   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
27828                         handle_section_bytes + authorization_size_bytes +
27829                         authorization_section_bytes + parameter_section_bytes;
27830   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
27831   VLOG(2) << "Command: "
27832           << base::HexEncode(serialized_command->data(),
27833                              serialized_command->size());
27834   return TPM_RC_SUCCESS;
27835 }
27836 
ParseResponse_SetAlgorithmSet(const std::string & response,AuthorizationDelegate * authorization_delegate)27837 TPM_RC Tpm::ParseResponse_SetAlgorithmSet(
27838     const std::string& response,
27839     AuthorizationDelegate* authorization_delegate) {
27840   VLOG(3) << __func__;
27841   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
27842   TPM_RC rc = TPM_RC_SUCCESS;
27843   std::string buffer(response);
27844   TPM_ST tag;
27845   std::string tag_bytes;
27846   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
27847   if (rc != TPM_RC_SUCCESS) {
27848     return rc;
27849   }
27850   UINT32 response_size;
27851   std::string response_size_bytes;
27852   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
27853   if (rc != TPM_RC_SUCCESS) {
27854     return rc;
27855   }
27856   TPM_RC response_code;
27857   std::string response_code_bytes;
27858   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
27859   if (rc != TPM_RC_SUCCESS) {
27860     return rc;
27861   }
27862   if (response_size != response.size()) {
27863     return TPM_RC_SIZE;
27864   }
27865   if (response_code != TPM_RC_SUCCESS) {
27866     return response_code;
27867   }
27868   TPM_CC command_code = TPM_CC_SetAlgorithmSet;
27869   std::string command_code_bytes;
27870   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27871   if (rc != TPM_RC_SUCCESS) {
27872     return rc;
27873   }
27874   std::string authorization_section_bytes;
27875   if (tag == TPM_ST_SESSIONS) {
27876     UINT32 parameter_section_size = buffer.size();
27877     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
27878     if (rc != TPM_RC_SUCCESS) {
27879       return rc;
27880     }
27881     if (parameter_section_size > buffer.size()) {
27882       return TPM_RC_INSUFFICIENT;
27883     }
27884     authorization_section_bytes = buffer.substr(parameter_section_size);
27885     // Keep the parameter section in |buffer|.
27886     buffer.erase(parameter_section_size);
27887   }
27888   std::unique_ptr<crypto::SecureHash> hash(
27889       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
27890   hash->Update(response_code_bytes.data(), response_code_bytes.size());
27891   hash->Update(command_code_bytes.data(), command_code_bytes.size());
27892   hash->Update(buffer.data(), buffer.size());
27893   std::string response_hash(32, 0);
27894   hash->Finish(std::data(response_hash), response_hash.size());
27895   if (tag == TPM_ST_SESSIONS) {
27896     if (!authorization_delegate)
27897       return TRUNKS_RC_AUTHORIZATION_FAILED;
27898     if (!authorization_delegate->CheckResponseAuthorization(
27899             response_hash, authorization_section_bytes)) {
27900       return TRUNKS_RC_AUTHORIZATION_FAILED;
27901     }
27902   }
27903   return TPM_RC_SUCCESS;
27904 }
27905 
SetAlgorithmSetErrorCallback(Tpm::SetAlgorithmSetResponse callback,TPM_RC response_code)27906 void SetAlgorithmSetErrorCallback(Tpm::SetAlgorithmSetResponse callback,
27907                                   TPM_RC response_code) {
27908   VLOG(1) << __func__;
27909   std::move(callback).Run(response_code);
27910 }
27911 
SetAlgorithmSetResponseParser(Tpm::SetAlgorithmSetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)27912 void SetAlgorithmSetResponseParser(
27913     Tpm::SetAlgorithmSetResponse callback,
27914     AuthorizationDelegate* authorization_delegate,
27915     const std::string& response) {
27916   VLOG(1) << __func__;
27917   TPM_RC rc =
27918       Tpm::ParseResponse_SetAlgorithmSet(response, authorization_delegate);
27919   if (rc != TPM_RC_SUCCESS) {
27920     base::OnceCallback<void(TPM_RC)> error_reporter =
27921         base::BindOnce(SetAlgorithmSetErrorCallback, std::move(callback));
27922     std::move(error_reporter).Run(rc);
27923     return;
27924   }
27925   std::move(callback).Run(rc);
27926 }
27927 
SetAlgorithmSet(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,AuthorizationDelegate * authorization_delegate,SetAlgorithmSetResponse callback)27928 void Tpm::SetAlgorithmSet(const TPMI_RH_PLATFORM& auth_handle,
27929                           const std::string& auth_handle_name,
27930                           const UINT32& algorithm_set,
27931                           AuthorizationDelegate* authorization_delegate,
27932                           SetAlgorithmSetResponse callback) {
27933   VLOG(1) << __func__;
27934   std::string command;
27935   TPM_RC rc = SerializeCommand_SetAlgorithmSet(auth_handle, auth_handle_name,
27936                                                algorithm_set, &command,
27937                                                authorization_delegate);
27938   if (rc != TPM_RC_SUCCESS) {
27939     base::OnceCallback<void(TPM_RC)> error_reporter =
27940         base::BindOnce(SetAlgorithmSetErrorCallback, std::move(callback));
27941     std::move(error_reporter).Run(rc);
27942     return;
27943   }
27944   base::OnceCallback<void(const std::string&)> parser =
27945       base::BindOnce(SetAlgorithmSetResponseParser, std::move(callback),
27946                      authorization_delegate);
27947   transceiver_->SendCommand(command, std::move(parser));
27948 }
27949 
SetAlgorithmSetSync(const TPMI_RH_PLATFORM & auth_handle,const std::string & auth_handle_name,const UINT32 & algorithm_set,AuthorizationDelegate * authorization_delegate)27950 TPM_RC Tpm::SetAlgorithmSetSync(const TPMI_RH_PLATFORM& auth_handle,
27951                                 const std::string& auth_handle_name,
27952                                 const UINT32& algorithm_set,
27953                                 AuthorizationDelegate* authorization_delegate) {
27954   VLOG(1) << __func__;
27955   std::string command;
27956   TPM_RC rc = SerializeCommand_SetAlgorithmSet(auth_handle, auth_handle_name,
27957                                                algorithm_set, &command,
27958                                                authorization_delegate);
27959   if (rc != TPM_RC_SUCCESS) {
27960     return rc;
27961   }
27962   std::string response = transceiver_->SendCommandAndWait(command);
27963   rc = ParseResponse_SetAlgorithmSet(response, authorization_delegate);
27964   return rc;
27965 }
27966 
SerializeCommand_FieldUpgradeStart(const TPMI_RH_PLATFORM & authorization,const std::string & authorization_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & fu_digest,const TPMT_SIGNATURE & manifest_signature,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)27967 TPM_RC Tpm::SerializeCommand_FieldUpgradeStart(
27968     const TPMI_RH_PLATFORM& authorization,
27969     const std::string& authorization_name,
27970     const TPMI_DH_OBJECT& key_handle,
27971     const std::string& key_handle_name,
27972     const TPM2B_DIGEST& fu_digest,
27973     const TPMT_SIGNATURE& manifest_signature,
27974     std::string* serialized_command,
27975     AuthorizationDelegate* authorization_delegate) {
27976   VLOG(3) << __func__;
27977   TPM_RC rc = TPM_RC_SUCCESS;
27978   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
27979   UINT32 command_size = 10;  // Header size.
27980   std::string handle_section_bytes;
27981   std::string parameter_section_bytes;
27982   TPM_CC command_code = TPM_CC_FieldUpgradeStart;
27983   bool is_command_parameter_encryption_possible = true;
27984   bool is_response_parameter_encryption_possible = false;
27985   std::string command_code_bytes;
27986   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
27987   if (rc != TPM_RC_SUCCESS) {
27988     return rc;
27989   }
27990   std::string authorization_bytes;
27991   rc = Serialize_TPMI_RH_PLATFORM(authorization, &authorization_bytes);
27992   if (rc != TPM_RC_SUCCESS) {
27993     return rc;
27994   }
27995   std::string key_handle_bytes;
27996   rc = Serialize_TPMI_DH_OBJECT(key_handle, &key_handle_bytes);
27997   if (rc != TPM_RC_SUCCESS) {
27998     return rc;
27999   }
28000   std::string fu_digest_bytes;
28001   rc = Serialize_TPM2B_DIGEST(fu_digest, &fu_digest_bytes);
28002   if (rc != TPM_RC_SUCCESS) {
28003     return rc;
28004   }
28005   std::string manifest_signature_bytes;
28006   rc = Serialize_TPMT_SIGNATURE(manifest_signature, &manifest_signature_bytes);
28007   if (rc != TPM_RC_SUCCESS) {
28008     return rc;
28009   }
28010   if (authorization_delegate) {
28011     // Encrypt just the parameter data, not the size.
28012     std::string tmp = fu_digest_bytes.substr(2);
28013     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
28014       return TRUNKS_RC_ENCRYPTION_FAILED;
28015     }
28016     fu_digest_bytes.replace(2, std::string::npos, tmp);
28017   }
28018   std::unique_ptr<crypto::SecureHash> hash(
28019       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28020   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28021   hash->Update(authorization_name.data(), authorization_name.size());
28022   handle_section_bytes += authorization_bytes;
28023   command_size += authorization_bytes.size();
28024   hash->Update(key_handle_name.data(), key_handle_name.size());
28025   handle_section_bytes += key_handle_bytes;
28026   command_size += key_handle_bytes.size();
28027   hash->Update(fu_digest_bytes.data(), fu_digest_bytes.size());
28028   parameter_section_bytes += fu_digest_bytes;
28029   command_size += fu_digest_bytes.size();
28030   hash->Update(manifest_signature_bytes.data(),
28031                manifest_signature_bytes.size());
28032   parameter_section_bytes += manifest_signature_bytes;
28033   command_size += manifest_signature_bytes.size();
28034   std::string command_hash(32, 0);
28035   hash->Finish(std::data(command_hash), command_hash.size());
28036   std::string authorization_section_bytes;
28037   std::string authorization_size_bytes;
28038   if (authorization_delegate) {
28039     if (!authorization_delegate->GetCommandAuthorization(
28040             command_hash, is_command_parameter_encryption_possible,
28041             is_response_parameter_encryption_possible,
28042             &authorization_section_bytes)) {
28043       return TRUNKS_RC_AUTHORIZATION_FAILED;
28044     }
28045     if (!authorization_section_bytes.empty()) {
28046       tag = TPM_ST_SESSIONS;
28047       std::string tmp;
28048       rc = Serialize_UINT32(authorization_section_bytes.size(),
28049                             &authorization_size_bytes);
28050       if (rc != TPM_RC_SUCCESS) {
28051         return rc;
28052       }
28053       command_size +=
28054           authorization_size_bytes.size() + authorization_section_bytes.size();
28055     }
28056   }
28057   std::string tag_bytes;
28058   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28059   if (rc != TPM_RC_SUCCESS) {
28060     return rc;
28061   }
28062   std::string command_size_bytes;
28063   rc = Serialize_UINT32(command_size, &command_size_bytes);
28064   if (rc != TPM_RC_SUCCESS) {
28065     return rc;
28066   }
28067   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28068                         handle_section_bytes + authorization_size_bytes +
28069                         authorization_section_bytes + parameter_section_bytes;
28070   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28071   VLOG(2) << "Command: "
28072           << base::HexEncode(serialized_command->data(),
28073                              serialized_command->size());
28074   return TPM_RC_SUCCESS;
28075 }
28076 
ParseResponse_FieldUpgradeStart(const std::string & response,AuthorizationDelegate * authorization_delegate)28077 TPM_RC Tpm::ParseResponse_FieldUpgradeStart(
28078     const std::string& response,
28079     AuthorizationDelegate* authorization_delegate) {
28080   VLOG(3) << __func__;
28081   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28082   TPM_RC rc = TPM_RC_SUCCESS;
28083   std::string buffer(response);
28084   TPM_ST tag;
28085   std::string tag_bytes;
28086   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28087   if (rc != TPM_RC_SUCCESS) {
28088     return rc;
28089   }
28090   UINT32 response_size;
28091   std::string response_size_bytes;
28092   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28093   if (rc != TPM_RC_SUCCESS) {
28094     return rc;
28095   }
28096   TPM_RC response_code;
28097   std::string response_code_bytes;
28098   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28099   if (rc != TPM_RC_SUCCESS) {
28100     return rc;
28101   }
28102   if (response_size != response.size()) {
28103     return TPM_RC_SIZE;
28104   }
28105   if (response_code != TPM_RC_SUCCESS) {
28106     return response_code;
28107   }
28108   TPM_CC command_code = TPM_CC_FieldUpgradeStart;
28109   std::string command_code_bytes;
28110   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28111   if (rc != TPM_RC_SUCCESS) {
28112     return rc;
28113   }
28114   std::string authorization_section_bytes;
28115   if (tag == TPM_ST_SESSIONS) {
28116     UINT32 parameter_section_size = buffer.size();
28117     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28118     if (rc != TPM_RC_SUCCESS) {
28119       return rc;
28120     }
28121     if (parameter_section_size > buffer.size()) {
28122       return TPM_RC_INSUFFICIENT;
28123     }
28124     authorization_section_bytes = buffer.substr(parameter_section_size);
28125     // Keep the parameter section in |buffer|.
28126     buffer.erase(parameter_section_size);
28127   }
28128   std::unique_ptr<crypto::SecureHash> hash(
28129       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28130   hash->Update(response_code_bytes.data(), response_code_bytes.size());
28131   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28132   hash->Update(buffer.data(), buffer.size());
28133   std::string response_hash(32, 0);
28134   hash->Finish(std::data(response_hash), response_hash.size());
28135   if (tag == TPM_ST_SESSIONS) {
28136     if (!authorization_delegate)
28137       return TRUNKS_RC_AUTHORIZATION_FAILED;
28138     if (!authorization_delegate->CheckResponseAuthorization(
28139             response_hash, authorization_section_bytes)) {
28140       return TRUNKS_RC_AUTHORIZATION_FAILED;
28141     }
28142   }
28143   return TPM_RC_SUCCESS;
28144 }
28145 
FieldUpgradeStartErrorCallback(Tpm::FieldUpgradeStartResponse callback,TPM_RC response_code)28146 void FieldUpgradeStartErrorCallback(Tpm::FieldUpgradeStartResponse callback,
28147                                     TPM_RC response_code) {
28148   VLOG(1) << __func__;
28149   std::move(callback).Run(response_code);
28150 }
28151 
FieldUpgradeStartResponseParser(Tpm::FieldUpgradeStartResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28152 void FieldUpgradeStartResponseParser(
28153     Tpm::FieldUpgradeStartResponse callback,
28154     AuthorizationDelegate* authorization_delegate,
28155     const std::string& response) {
28156   VLOG(1) << __func__;
28157   TPM_RC rc =
28158       Tpm::ParseResponse_FieldUpgradeStart(response, authorization_delegate);
28159   if (rc != TPM_RC_SUCCESS) {
28160     base::OnceCallback<void(TPM_RC)> error_reporter =
28161         base::BindOnce(FieldUpgradeStartErrorCallback, std::move(callback));
28162     std::move(error_reporter).Run(rc);
28163     return;
28164   }
28165   std::move(callback).Run(rc);
28166 }
28167 
FieldUpgradeStart(const TPMI_RH_PLATFORM & authorization,const std::string & authorization_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & fu_digest,const TPMT_SIGNATURE & manifest_signature,AuthorizationDelegate * authorization_delegate,FieldUpgradeStartResponse callback)28168 void Tpm::FieldUpgradeStart(const TPMI_RH_PLATFORM& authorization,
28169                             const std::string& authorization_name,
28170                             const TPMI_DH_OBJECT& key_handle,
28171                             const std::string& key_handle_name,
28172                             const TPM2B_DIGEST& fu_digest,
28173                             const TPMT_SIGNATURE& manifest_signature,
28174                             AuthorizationDelegate* authorization_delegate,
28175                             FieldUpgradeStartResponse callback) {
28176   VLOG(1) << __func__;
28177   std::string command;
28178   TPM_RC rc = SerializeCommand_FieldUpgradeStart(
28179       authorization, authorization_name, key_handle, key_handle_name, fu_digest,
28180       manifest_signature, &command, authorization_delegate);
28181   if (rc != TPM_RC_SUCCESS) {
28182     base::OnceCallback<void(TPM_RC)> error_reporter =
28183         base::BindOnce(FieldUpgradeStartErrorCallback, std::move(callback));
28184     std::move(error_reporter).Run(rc);
28185     return;
28186   }
28187   base::OnceCallback<void(const std::string&)> parser =
28188       base::BindOnce(FieldUpgradeStartResponseParser, std::move(callback),
28189                      authorization_delegate);
28190   transceiver_->SendCommand(command, std::move(parser));
28191 }
28192 
FieldUpgradeStartSync(const TPMI_RH_PLATFORM & authorization,const std::string & authorization_name,const TPMI_DH_OBJECT & key_handle,const std::string & key_handle_name,const TPM2B_DIGEST & fu_digest,const TPMT_SIGNATURE & manifest_signature,AuthorizationDelegate * authorization_delegate)28193 TPM_RC Tpm::FieldUpgradeStartSync(
28194     const TPMI_RH_PLATFORM& authorization,
28195     const std::string& authorization_name,
28196     const TPMI_DH_OBJECT& key_handle,
28197     const std::string& key_handle_name,
28198     const TPM2B_DIGEST& fu_digest,
28199     const TPMT_SIGNATURE& manifest_signature,
28200     AuthorizationDelegate* authorization_delegate) {
28201   VLOG(1) << __func__;
28202   std::string command;
28203   TPM_RC rc = SerializeCommand_FieldUpgradeStart(
28204       authorization, authorization_name, key_handle, key_handle_name, fu_digest,
28205       manifest_signature, &command, authorization_delegate);
28206   if (rc != TPM_RC_SUCCESS) {
28207     return rc;
28208   }
28209   std::string response = transceiver_->SendCommandAndWait(command);
28210   rc = ParseResponse_FieldUpgradeStart(response, authorization_delegate);
28211   return rc;
28212 }
28213 
SerializeCommand_FieldUpgradeData(const TPM2B_MAX_BUFFER & fu_data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28214 TPM_RC Tpm::SerializeCommand_FieldUpgradeData(
28215     const TPM2B_MAX_BUFFER& fu_data,
28216     std::string* serialized_command,
28217     AuthorizationDelegate* authorization_delegate) {
28218   VLOG(3) << __func__;
28219   TPM_RC rc = TPM_RC_SUCCESS;
28220   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28221   UINT32 command_size = 10;  // Header size.
28222   std::string handle_section_bytes;
28223   std::string parameter_section_bytes;
28224   TPM_CC command_code = TPM_CC_FieldUpgradeData;
28225   bool is_command_parameter_encryption_possible = true;
28226   bool is_response_parameter_encryption_possible = false;
28227   std::string command_code_bytes;
28228   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28229   if (rc != TPM_RC_SUCCESS) {
28230     return rc;
28231   }
28232   std::string fu_data_bytes;
28233   rc = Serialize_TPM2B_MAX_BUFFER(fu_data, &fu_data_bytes);
28234   if (rc != TPM_RC_SUCCESS) {
28235     return rc;
28236   }
28237   if (authorization_delegate) {
28238     // Encrypt just the parameter data, not the size.
28239     std::string tmp = fu_data_bytes.substr(2);
28240     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
28241       return TRUNKS_RC_ENCRYPTION_FAILED;
28242     }
28243     fu_data_bytes.replace(2, std::string::npos, tmp);
28244   }
28245   std::unique_ptr<crypto::SecureHash> hash(
28246       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28247   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28248   hash->Update(fu_data_bytes.data(), fu_data_bytes.size());
28249   parameter_section_bytes += fu_data_bytes;
28250   command_size += fu_data_bytes.size();
28251   std::string command_hash(32, 0);
28252   hash->Finish(std::data(command_hash), command_hash.size());
28253   std::string authorization_section_bytes;
28254   std::string authorization_size_bytes;
28255   if (authorization_delegate) {
28256     if (!authorization_delegate->GetCommandAuthorization(
28257             command_hash, is_command_parameter_encryption_possible,
28258             is_response_parameter_encryption_possible,
28259             &authorization_section_bytes)) {
28260       return TRUNKS_RC_AUTHORIZATION_FAILED;
28261     }
28262     if (!authorization_section_bytes.empty()) {
28263       tag = TPM_ST_SESSIONS;
28264       std::string tmp;
28265       rc = Serialize_UINT32(authorization_section_bytes.size(),
28266                             &authorization_size_bytes);
28267       if (rc != TPM_RC_SUCCESS) {
28268         return rc;
28269       }
28270       command_size +=
28271           authorization_size_bytes.size() + authorization_section_bytes.size();
28272     }
28273   }
28274   std::string tag_bytes;
28275   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28276   if (rc != TPM_RC_SUCCESS) {
28277     return rc;
28278   }
28279   std::string command_size_bytes;
28280   rc = Serialize_UINT32(command_size, &command_size_bytes);
28281   if (rc != TPM_RC_SUCCESS) {
28282     return rc;
28283   }
28284   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28285                         handle_section_bytes + authorization_size_bytes +
28286                         authorization_section_bytes + parameter_section_bytes;
28287   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28288   VLOG(2) << "Command: "
28289           << base::HexEncode(serialized_command->data(),
28290                              serialized_command->size());
28291   return TPM_RC_SUCCESS;
28292 }
28293 
ParseResponse_FieldUpgradeData(const std::string & response,TPMT_HA * next_digest,TPMT_HA * first_digest,AuthorizationDelegate * authorization_delegate)28294 TPM_RC Tpm::ParseResponse_FieldUpgradeData(
28295     const std::string& response,
28296     TPMT_HA* next_digest,
28297     TPMT_HA* first_digest,
28298     AuthorizationDelegate* authorization_delegate) {
28299   VLOG(3) << __func__;
28300   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28301   TPM_RC rc = TPM_RC_SUCCESS;
28302   std::string buffer(response);
28303   TPM_ST tag;
28304   std::string tag_bytes;
28305   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28306   if (rc != TPM_RC_SUCCESS) {
28307     return rc;
28308   }
28309   UINT32 response_size;
28310   std::string response_size_bytes;
28311   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28312   if (rc != TPM_RC_SUCCESS) {
28313     return rc;
28314   }
28315   TPM_RC response_code;
28316   std::string response_code_bytes;
28317   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28318   if (rc != TPM_RC_SUCCESS) {
28319     return rc;
28320   }
28321   if (response_size != response.size()) {
28322     return TPM_RC_SIZE;
28323   }
28324   if (response_code != TPM_RC_SUCCESS) {
28325     return response_code;
28326   }
28327   TPM_CC command_code = TPM_CC_FieldUpgradeData;
28328   std::string command_code_bytes;
28329   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28330   if (rc != TPM_RC_SUCCESS) {
28331     return rc;
28332   }
28333   std::string authorization_section_bytes;
28334   if (tag == TPM_ST_SESSIONS) {
28335     UINT32 parameter_section_size = buffer.size();
28336     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28337     if (rc != TPM_RC_SUCCESS) {
28338       return rc;
28339     }
28340     if (parameter_section_size > buffer.size()) {
28341       return TPM_RC_INSUFFICIENT;
28342     }
28343     authorization_section_bytes = buffer.substr(parameter_section_size);
28344     // Keep the parameter section in |buffer|.
28345     buffer.erase(parameter_section_size);
28346   }
28347   std::unique_ptr<crypto::SecureHash> hash(
28348       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28349   hash->Update(response_code_bytes.data(), response_code_bytes.size());
28350   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28351   hash->Update(buffer.data(), buffer.size());
28352   std::string response_hash(32, 0);
28353   hash->Finish(std::data(response_hash), response_hash.size());
28354   if (tag == TPM_ST_SESSIONS) {
28355     if (!authorization_delegate)
28356       return TRUNKS_RC_AUTHORIZATION_FAILED;
28357     if (!authorization_delegate->CheckResponseAuthorization(
28358             response_hash, authorization_section_bytes)) {
28359       return TRUNKS_RC_AUTHORIZATION_FAILED;
28360     }
28361   }
28362   std::string next_digest_bytes;
28363   rc = Parse_TPMT_HA(&buffer, next_digest, &next_digest_bytes);
28364   if (rc != TPM_RC_SUCCESS) {
28365     return rc;
28366   }
28367   std::string first_digest_bytes;
28368   rc = Parse_TPMT_HA(&buffer, first_digest, &first_digest_bytes);
28369   if (rc != TPM_RC_SUCCESS) {
28370     return rc;
28371   }
28372   return TPM_RC_SUCCESS;
28373 }
28374 
FieldUpgradeDataErrorCallback(Tpm::FieldUpgradeDataResponse callback,TPM_RC response_code)28375 void FieldUpgradeDataErrorCallback(Tpm::FieldUpgradeDataResponse callback,
28376                                    TPM_RC response_code) {
28377   VLOG(1) << __func__;
28378   std::move(callback).Run(response_code, TPMT_HA(), TPMT_HA());
28379 }
28380 
FieldUpgradeDataResponseParser(Tpm::FieldUpgradeDataResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28381 void FieldUpgradeDataResponseParser(
28382     Tpm::FieldUpgradeDataResponse callback,
28383     AuthorizationDelegate* authorization_delegate,
28384     const std::string& response) {
28385   VLOG(1) << __func__;
28386   TPMT_HA next_digest;
28387   TPMT_HA first_digest;
28388   TPM_RC rc = Tpm::ParseResponse_FieldUpgradeData(
28389       response, &next_digest, &first_digest, authorization_delegate);
28390   if (rc != TPM_RC_SUCCESS) {
28391     base::OnceCallback<void(TPM_RC)> error_reporter =
28392         base::BindOnce(FieldUpgradeDataErrorCallback, std::move(callback));
28393     std::move(error_reporter).Run(rc);
28394     return;
28395   }
28396   std::move(callback).Run(rc, next_digest, first_digest);
28397 }
28398 
FieldUpgradeData(const TPM2B_MAX_BUFFER & fu_data,AuthorizationDelegate * authorization_delegate,FieldUpgradeDataResponse callback)28399 void Tpm::FieldUpgradeData(const TPM2B_MAX_BUFFER& fu_data,
28400                            AuthorizationDelegate* authorization_delegate,
28401                            FieldUpgradeDataResponse callback) {
28402   VLOG(1) << __func__;
28403   std::string command;
28404   TPM_RC rc = SerializeCommand_FieldUpgradeData(fu_data, &command,
28405                                                 authorization_delegate);
28406   if (rc != TPM_RC_SUCCESS) {
28407     base::OnceCallback<void(TPM_RC)> error_reporter =
28408         base::BindOnce(FieldUpgradeDataErrorCallback, std::move(callback));
28409     std::move(error_reporter).Run(rc);
28410     return;
28411   }
28412   base::OnceCallback<void(const std::string&)> parser =
28413       base::BindOnce(FieldUpgradeDataResponseParser, std::move(callback),
28414                      authorization_delegate);
28415   transceiver_->SendCommand(command, std::move(parser));
28416 }
28417 
FieldUpgradeDataSync(const TPM2B_MAX_BUFFER & fu_data,TPMT_HA * next_digest,TPMT_HA * first_digest,AuthorizationDelegate * authorization_delegate)28418 TPM_RC Tpm::FieldUpgradeDataSync(
28419     const TPM2B_MAX_BUFFER& fu_data,
28420     TPMT_HA* next_digest,
28421     TPMT_HA* first_digest,
28422     AuthorizationDelegate* authorization_delegate) {
28423   VLOG(1) << __func__;
28424   std::string command;
28425   TPM_RC rc = SerializeCommand_FieldUpgradeData(fu_data, &command,
28426                                                 authorization_delegate);
28427   if (rc != TPM_RC_SUCCESS) {
28428     return rc;
28429   }
28430   std::string response = transceiver_->SendCommandAndWait(command);
28431   rc = ParseResponse_FieldUpgradeData(response, next_digest, first_digest,
28432                                       authorization_delegate);
28433   return rc;
28434 }
28435 
SerializeCommand_FirmwareRead(const UINT32 & sequence_number,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28436 TPM_RC Tpm::SerializeCommand_FirmwareRead(
28437     const UINT32& sequence_number,
28438     std::string* serialized_command,
28439     AuthorizationDelegate* authorization_delegate) {
28440   VLOG(3) << __func__;
28441   TPM_RC rc = TPM_RC_SUCCESS;
28442   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28443   UINT32 command_size = 10;  // Header size.
28444   std::string handle_section_bytes;
28445   std::string parameter_section_bytes;
28446   TPM_CC command_code = TPM_CC_FirmwareRead;
28447   bool is_command_parameter_encryption_possible = false;
28448   bool is_response_parameter_encryption_possible = true;
28449   std::string command_code_bytes;
28450   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28451   if (rc != TPM_RC_SUCCESS) {
28452     return rc;
28453   }
28454   std::string sequence_number_bytes;
28455   rc = Serialize_UINT32(sequence_number, &sequence_number_bytes);
28456   if (rc != TPM_RC_SUCCESS) {
28457     return rc;
28458   }
28459   std::unique_ptr<crypto::SecureHash> hash(
28460       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28461   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28462   hash->Update(sequence_number_bytes.data(), sequence_number_bytes.size());
28463   parameter_section_bytes += sequence_number_bytes;
28464   command_size += sequence_number_bytes.size();
28465   std::string command_hash(32, 0);
28466   hash->Finish(std::data(command_hash), command_hash.size());
28467   std::string authorization_section_bytes;
28468   std::string authorization_size_bytes;
28469   if (authorization_delegate) {
28470     if (!authorization_delegate->GetCommandAuthorization(
28471             command_hash, is_command_parameter_encryption_possible,
28472             is_response_parameter_encryption_possible,
28473             &authorization_section_bytes)) {
28474       return TRUNKS_RC_AUTHORIZATION_FAILED;
28475     }
28476     if (!authorization_section_bytes.empty()) {
28477       tag = TPM_ST_SESSIONS;
28478       std::string tmp;
28479       rc = Serialize_UINT32(authorization_section_bytes.size(),
28480                             &authorization_size_bytes);
28481       if (rc != TPM_RC_SUCCESS) {
28482         return rc;
28483       }
28484       command_size +=
28485           authorization_size_bytes.size() + authorization_section_bytes.size();
28486     }
28487   }
28488   std::string tag_bytes;
28489   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28490   if (rc != TPM_RC_SUCCESS) {
28491     return rc;
28492   }
28493   std::string command_size_bytes;
28494   rc = Serialize_UINT32(command_size, &command_size_bytes);
28495   if (rc != TPM_RC_SUCCESS) {
28496     return rc;
28497   }
28498   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28499                         handle_section_bytes + authorization_size_bytes +
28500                         authorization_section_bytes + parameter_section_bytes;
28501   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28502   VLOG(2) << "Command: "
28503           << base::HexEncode(serialized_command->data(),
28504                              serialized_command->size());
28505   return TPM_RC_SUCCESS;
28506 }
28507 
ParseResponse_FirmwareRead(const std::string & response,TPM2B_MAX_BUFFER * fu_data,AuthorizationDelegate * authorization_delegate)28508 TPM_RC Tpm::ParseResponse_FirmwareRead(
28509     const std::string& response,
28510     TPM2B_MAX_BUFFER* fu_data,
28511     AuthorizationDelegate* authorization_delegate) {
28512   VLOG(3) << __func__;
28513   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28514   TPM_RC rc = TPM_RC_SUCCESS;
28515   std::string buffer(response);
28516   TPM_ST tag;
28517   std::string tag_bytes;
28518   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28519   if (rc != TPM_RC_SUCCESS) {
28520     return rc;
28521   }
28522   UINT32 response_size;
28523   std::string response_size_bytes;
28524   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28525   if (rc != TPM_RC_SUCCESS) {
28526     return rc;
28527   }
28528   TPM_RC response_code;
28529   std::string response_code_bytes;
28530   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28531   if (rc != TPM_RC_SUCCESS) {
28532     return rc;
28533   }
28534   if (response_size != response.size()) {
28535     return TPM_RC_SIZE;
28536   }
28537   if (response_code != TPM_RC_SUCCESS) {
28538     return response_code;
28539   }
28540   TPM_CC command_code = TPM_CC_FirmwareRead;
28541   std::string command_code_bytes;
28542   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28543   if (rc != TPM_RC_SUCCESS) {
28544     return rc;
28545   }
28546   std::string authorization_section_bytes;
28547   if (tag == TPM_ST_SESSIONS) {
28548     UINT32 parameter_section_size = buffer.size();
28549     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28550     if (rc != TPM_RC_SUCCESS) {
28551       return rc;
28552     }
28553     if (parameter_section_size > buffer.size()) {
28554       return TPM_RC_INSUFFICIENT;
28555     }
28556     authorization_section_bytes = buffer.substr(parameter_section_size);
28557     // Keep the parameter section in |buffer|.
28558     buffer.erase(parameter_section_size);
28559   }
28560   std::unique_ptr<crypto::SecureHash> hash(
28561       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28562   hash->Update(response_code_bytes.data(), response_code_bytes.size());
28563   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28564   hash->Update(buffer.data(), buffer.size());
28565   std::string response_hash(32, 0);
28566   hash->Finish(std::data(response_hash), response_hash.size());
28567   if (tag == TPM_ST_SESSIONS) {
28568     if (!authorization_delegate)
28569       return TRUNKS_RC_AUTHORIZATION_FAILED;
28570     if (!authorization_delegate->CheckResponseAuthorization(
28571             response_hash, authorization_section_bytes)) {
28572       return TRUNKS_RC_AUTHORIZATION_FAILED;
28573     }
28574   }
28575   if (tag == TPM_ST_SESSIONS) {
28576     if (!authorization_delegate)
28577       return TRUNKS_RC_AUTHORIZATION_FAILED;
28578 
28579     // Parse the encrypted parameter size.
28580     UINT16 size;
28581     std::string size_buffer = buffer.substr(0, 2);
28582     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
28583       return result;
28584     }
28585     if (buffer.size() < 2 + size) {
28586       return TPM_RC_INSUFFICIENT;
28587     }
28588 
28589     // Decrypt just the parameter data, not the size.
28590     std::string decrypted_data = buffer.substr(2, size);
28591     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
28592       return TRUNKS_RC_ENCRYPTION_FAILED;
28593     }
28594     buffer.replace(2, size, decrypted_data);
28595   }
28596   std::string fu_data_bytes;
28597   rc = Parse_TPM2B_MAX_BUFFER(&buffer, fu_data, &fu_data_bytes);
28598   if (rc != TPM_RC_SUCCESS) {
28599     return rc;
28600   }
28601   return TPM_RC_SUCCESS;
28602 }
28603 
FirmwareReadErrorCallback(Tpm::FirmwareReadResponse callback,TPM_RC response_code)28604 void FirmwareReadErrorCallback(Tpm::FirmwareReadResponse callback,
28605                                TPM_RC response_code) {
28606   VLOG(1) << __func__;
28607   std::move(callback).Run(response_code, TPM2B_MAX_BUFFER());
28608 }
28609 
FirmwareReadResponseParser(Tpm::FirmwareReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28610 void FirmwareReadResponseParser(Tpm::FirmwareReadResponse callback,
28611                                 AuthorizationDelegate* authorization_delegate,
28612                                 const std::string& response) {
28613   VLOG(1) << __func__;
28614   TPM2B_MAX_BUFFER fu_data;
28615   TPM_RC rc = Tpm::ParseResponse_FirmwareRead(response, &fu_data,
28616                                               authorization_delegate);
28617   if (rc != TPM_RC_SUCCESS) {
28618     base::OnceCallback<void(TPM_RC)> error_reporter =
28619         base::BindOnce(FirmwareReadErrorCallback, std::move(callback));
28620     std::move(error_reporter).Run(rc);
28621     return;
28622   }
28623   std::move(callback).Run(rc, fu_data);
28624 }
28625 
FirmwareRead(const UINT32 & sequence_number,AuthorizationDelegate * authorization_delegate,FirmwareReadResponse callback)28626 void Tpm::FirmwareRead(const UINT32& sequence_number,
28627                        AuthorizationDelegate* authorization_delegate,
28628                        FirmwareReadResponse callback) {
28629   VLOG(1) << __func__;
28630   std::string command;
28631   TPM_RC rc = SerializeCommand_FirmwareRead(sequence_number, &command,
28632                                             authorization_delegate);
28633   if (rc != TPM_RC_SUCCESS) {
28634     base::OnceCallback<void(TPM_RC)> error_reporter =
28635         base::BindOnce(FirmwareReadErrorCallback, std::move(callback));
28636     std::move(error_reporter).Run(rc);
28637     return;
28638   }
28639   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
28640       FirmwareReadResponseParser, std::move(callback), authorization_delegate);
28641   transceiver_->SendCommand(command, std::move(parser));
28642 }
28643 
FirmwareReadSync(const UINT32 & sequence_number,TPM2B_MAX_BUFFER * fu_data,AuthorizationDelegate * authorization_delegate)28644 TPM_RC Tpm::FirmwareReadSync(const UINT32& sequence_number,
28645                              TPM2B_MAX_BUFFER* fu_data,
28646                              AuthorizationDelegate* authorization_delegate) {
28647   VLOG(1) << __func__;
28648   std::string command;
28649   TPM_RC rc = SerializeCommand_FirmwareRead(sequence_number, &command,
28650                                             authorization_delegate);
28651   if (rc != TPM_RC_SUCCESS) {
28652     return rc;
28653   }
28654   std::string response = transceiver_->SendCommandAndWait(command);
28655   rc = ParseResponse_FirmwareRead(response, fu_data, authorization_delegate);
28656   return rc;
28657 }
28658 
SerializeCommand_ContextSave(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28659 TPM_RC Tpm::SerializeCommand_ContextSave(
28660     const TPMI_DH_CONTEXT& save_handle,
28661     const std::string& save_handle_name,
28662     std::string* serialized_command,
28663     AuthorizationDelegate* authorization_delegate) {
28664   VLOG(3) << __func__;
28665   TPM_RC rc = TPM_RC_SUCCESS;
28666   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28667   UINT32 command_size = 10;  // Header size.
28668   std::string handle_section_bytes;
28669   std::string parameter_section_bytes;
28670   TPM_CC command_code = TPM_CC_ContextSave;
28671   bool is_command_parameter_encryption_possible = false;
28672   bool is_response_parameter_encryption_possible = false;
28673   std::string command_code_bytes;
28674   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28675   if (rc != TPM_RC_SUCCESS) {
28676     return rc;
28677   }
28678   std::string save_handle_bytes;
28679   rc = Serialize_TPMI_DH_CONTEXT(save_handle, &save_handle_bytes);
28680   if (rc != TPM_RC_SUCCESS) {
28681     return rc;
28682   }
28683   std::unique_ptr<crypto::SecureHash> hash(
28684       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28685   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28686   hash->Update(save_handle_name.data(), save_handle_name.size());
28687   handle_section_bytes += save_handle_bytes;
28688   command_size += save_handle_bytes.size();
28689   std::string command_hash(32, 0);
28690   hash->Finish(std::data(command_hash), command_hash.size());
28691   std::string authorization_section_bytes;
28692   std::string authorization_size_bytes;
28693   if (authorization_delegate) {
28694     if (!authorization_delegate->GetCommandAuthorization(
28695             command_hash, is_command_parameter_encryption_possible,
28696             is_response_parameter_encryption_possible,
28697             &authorization_section_bytes)) {
28698       return TRUNKS_RC_AUTHORIZATION_FAILED;
28699     }
28700     if (!authorization_section_bytes.empty()) {
28701       tag = TPM_ST_SESSIONS;
28702       std::string tmp;
28703       rc = Serialize_UINT32(authorization_section_bytes.size(),
28704                             &authorization_size_bytes);
28705       if (rc != TPM_RC_SUCCESS) {
28706         return rc;
28707       }
28708       command_size +=
28709           authorization_size_bytes.size() + authorization_section_bytes.size();
28710     }
28711   }
28712   std::string tag_bytes;
28713   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28714   if (rc != TPM_RC_SUCCESS) {
28715     return rc;
28716   }
28717   std::string command_size_bytes;
28718   rc = Serialize_UINT32(command_size, &command_size_bytes);
28719   if (rc != TPM_RC_SUCCESS) {
28720     return rc;
28721   }
28722   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28723                         handle_section_bytes + authorization_size_bytes +
28724                         authorization_section_bytes + parameter_section_bytes;
28725   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28726   VLOG(2) << "Command: "
28727           << base::HexEncode(serialized_command->data(),
28728                              serialized_command->size());
28729   return TPM_RC_SUCCESS;
28730 }
28731 
ParseResponse_ContextSave(const std::string & response,TPMS_CONTEXT * context,AuthorizationDelegate * authorization_delegate)28732 TPM_RC Tpm::ParseResponse_ContextSave(
28733     const std::string& response,
28734     TPMS_CONTEXT* context,
28735     AuthorizationDelegate* authorization_delegate) {
28736   VLOG(3) << __func__;
28737   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28738   TPM_RC rc = TPM_RC_SUCCESS;
28739   std::string buffer(response);
28740   TPM_ST tag;
28741   std::string tag_bytes;
28742   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28743   if (rc != TPM_RC_SUCCESS) {
28744     return rc;
28745   }
28746   UINT32 response_size;
28747   std::string response_size_bytes;
28748   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28749   if (rc != TPM_RC_SUCCESS) {
28750     return rc;
28751   }
28752   TPM_RC response_code;
28753   std::string response_code_bytes;
28754   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28755   if (rc != TPM_RC_SUCCESS) {
28756     return rc;
28757   }
28758   if (response_size != response.size()) {
28759     return TPM_RC_SIZE;
28760   }
28761   if (response_code != TPM_RC_SUCCESS) {
28762     return response_code;
28763   }
28764   TPM_CC command_code = TPM_CC_ContextSave;
28765   std::string command_code_bytes;
28766   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28767   if (rc != TPM_RC_SUCCESS) {
28768     return rc;
28769   }
28770   std::string authorization_section_bytes;
28771   if (tag == TPM_ST_SESSIONS) {
28772     UINT32 parameter_section_size = buffer.size();
28773     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28774     if (rc != TPM_RC_SUCCESS) {
28775       return rc;
28776     }
28777     if (parameter_section_size > buffer.size()) {
28778       return TPM_RC_INSUFFICIENT;
28779     }
28780     authorization_section_bytes = buffer.substr(parameter_section_size);
28781     // Keep the parameter section in |buffer|.
28782     buffer.erase(parameter_section_size);
28783   }
28784   std::unique_ptr<crypto::SecureHash> hash(
28785       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28786   hash->Update(response_code_bytes.data(), response_code_bytes.size());
28787   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28788   hash->Update(buffer.data(), buffer.size());
28789   std::string response_hash(32, 0);
28790   hash->Finish(std::data(response_hash), response_hash.size());
28791   if (tag == TPM_ST_SESSIONS) {
28792     if (!authorization_delegate)
28793       return TRUNKS_RC_AUTHORIZATION_FAILED;
28794     if (!authorization_delegate->CheckResponseAuthorization(
28795             response_hash, authorization_section_bytes)) {
28796       return TRUNKS_RC_AUTHORIZATION_FAILED;
28797     }
28798   }
28799   std::string context_bytes;
28800   rc = Parse_TPMS_CONTEXT(&buffer, context, &context_bytes);
28801   if (rc != TPM_RC_SUCCESS) {
28802     return rc;
28803   }
28804   return TPM_RC_SUCCESS;
28805 }
28806 
ContextSaveErrorCallback(Tpm::ContextSaveResponse callback,TPM_RC response_code)28807 void ContextSaveErrorCallback(Tpm::ContextSaveResponse callback,
28808                               TPM_RC response_code) {
28809   VLOG(1) << __func__;
28810   std::move(callback).Run(response_code, TPMS_CONTEXT());
28811 }
28812 
ContextSaveResponseParser(Tpm::ContextSaveResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)28813 void ContextSaveResponseParser(Tpm::ContextSaveResponse callback,
28814                                AuthorizationDelegate* authorization_delegate,
28815                                const std::string& response) {
28816   VLOG(1) << __func__;
28817   TPMS_CONTEXT context;
28818   TPM_RC rc = Tpm::ParseResponse_ContextSave(response, &context,
28819                                              authorization_delegate);
28820   if (rc != TPM_RC_SUCCESS) {
28821     base::OnceCallback<void(TPM_RC)> error_reporter =
28822         base::BindOnce(ContextSaveErrorCallback, std::move(callback));
28823     std::move(error_reporter).Run(rc);
28824     return;
28825   }
28826   std::move(callback).Run(rc, context);
28827 }
28828 
ContextSave(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,AuthorizationDelegate * authorization_delegate,ContextSaveResponse callback)28829 void Tpm::ContextSave(const TPMI_DH_CONTEXT& save_handle,
28830                       const std::string& save_handle_name,
28831                       AuthorizationDelegate* authorization_delegate,
28832                       ContextSaveResponse callback) {
28833   VLOG(1) << __func__;
28834   std::string command;
28835   TPM_RC rc = SerializeCommand_ContextSave(save_handle, save_handle_name,
28836                                            &command, authorization_delegate);
28837   if (rc != TPM_RC_SUCCESS) {
28838     base::OnceCallback<void(TPM_RC)> error_reporter =
28839         base::BindOnce(ContextSaveErrorCallback, std::move(callback));
28840     std::move(error_reporter).Run(rc);
28841     return;
28842   }
28843   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
28844       ContextSaveResponseParser, std::move(callback), authorization_delegate);
28845   transceiver_->SendCommand(command, std::move(parser));
28846 }
28847 
ContextSaveSync(const TPMI_DH_CONTEXT & save_handle,const std::string & save_handle_name,TPMS_CONTEXT * context,AuthorizationDelegate * authorization_delegate)28848 TPM_RC Tpm::ContextSaveSync(const TPMI_DH_CONTEXT& save_handle,
28849                             const std::string& save_handle_name,
28850                             TPMS_CONTEXT* context,
28851                             AuthorizationDelegate* authorization_delegate) {
28852   VLOG(1) << __func__;
28853   std::string command;
28854   TPM_RC rc = SerializeCommand_ContextSave(save_handle, save_handle_name,
28855                                            &command, authorization_delegate);
28856   if (rc != TPM_RC_SUCCESS) {
28857     return rc;
28858   }
28859   std::string response = transceiver_->SendCommandAndWait(command);
28860   rc = ParseResponse_ContextSave(response, context, authorization_delegate);
28861   return rc;
28862 }
28863 
SerializeCommand_ContextLoad(const TPMS_CONTEXT & context,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)28864 TPM_RC Tpm::SerializeCommand_ContextLoad(
28865     const TPMS_CONTEXT& context,
28866     std::string* serialized_command,
28867     AuthorizationDelegate* authorization_delegate) {
28868   VLOG(3) << __func__;
28869   TPM_RC rc = TPM_RC_SUCCESS;
28870   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
28871   UINT32 command_size = 10;  // Header size.
28872   std::string handle_section_bytes;
28873   std::string parameter_section_bytes;
28874   TPM_CC command_code = TPM_CC_ContextLoad;
28875   bool is_command_parameter_encryption_possible = false;
28876   bool is_response_parameter_encryption_possible = false;
28877   std::string command_code_bytes;
28878   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28879   if (rc != TPM_RC_SUCCESS) {
28880     return rc;
28881   }
28882   std::string context_bytes;
28883   rc = Serialize_TPMS_CONTEXT(context, &context_bytes);
28884   if (rc != TPM_RC_SUCCESS) {
28885     return rc;
28886   }
28887   std::unique_ptr<crypto::SecureHash> hash(
28888       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28889   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28890   hash->Update(context_bytes.data(), context_bytes.size());
28891   parameter_section_bytes += context_bytes;
28892   command_size += context_bytes.size();
28893   std::string command_hash(32, 0);
28894   hash->Finish(std::data(command_hash), command_hash.size());
28895   std::string authorization_section_bytes;
28896   std::string authorization_size_bytes;
28897   if (authorization_delegate) {
28898     if (!authorization_delegate->GetCommandAuthorization(
28899             command_hash, is_command_parameter_encryption_possible,
28900             is_response_parameter_encryption_possible,
28901             &authorization_section_bytes)) {
28902       return TRUNKS_RC_AUTHORIZATION_FAILED;
28903     }
28904     if (!authorization_section_bytes.empty()) {
28905       tag = TPM_ST_SESSIONS;
28906       std::string tmp;
28907       rc = Serialize_UINT32(authorization_section_bytes.size(),
28908                             &authorization_size_bytes);
28909       if (rc != TPM_RC_SUCCESS) {
28910         return rc;
28911       }
28912       command_size +=
28913           authorization_size_bytes.size() + authorization_section_bytes.size();
28914     }
28915   }
28916   std::string tag_bytes;
28917   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
28918   if (rc != TPM_RC_SUCCESS) {
28919     return rc;
28920   }
28921   std::string command_size_bytes;
28922   rc = Serialize_UINT32(command_size, &command_size_bytes);
28923   if (rc != TPM_RC_SUCCESS) {
28924     return rc;
28925   }
28926   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
28927                         handle_section_bytes + authorization_size_bytes +
28928                         authorization_section_bytes + parameter_section_bytes;
28929   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
28930   VLOG(2) << "Command: "
28931           << base::HexEncode(serialized_command->data(),
28932                              serialized_command->size());
28933   return TPM_RC_SUCCESS;
28934 }
28935 
ParseResponse_ContextLoad(const std::string & response,TPMI_DH_CONTEXT * loaded_handle,AuthorizationDelegate * authorization_delegate)28936 TPM_RC Tpm::ParseResponse_ContextLoad(
28937     const std::string& response,
28938     TPMI_DH_CONTEXT* loaded_handle,
28939     AuthorizationDelegate* authorization_delegate) {
28940   VLOG(3) << __func__;
28941   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
28942   TPM_RC rc = TPM_RC_SUCCESS;
28943   std::string buffer(response);
28944   TPM_ST tag;
28945   std::string tag_bytes;
28946   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
28947   if (rc != TPM_RC_SUCCESS) {
28948     return rc;
28949   }
28950   UINT32 response_size;
28951   std::string response_size_bytes;
28952   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
28953   if (rc != TPM_RC_SUCCESS) {
28954     return rc;
28955   }
28956   TPM_RC response_code;
28957   std::string response_code_bytes;
28958   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
28959   if (rc != TPM_RC_SUCCESS) {
28960     return rc;
28961   }
28962   if (response_size != response.size()) {
28963     return TPM_RC_SIZE;
28964   }
28965   if (response_code != TPM_RC_SUCCESS) {
28966     return response_code;
28967   }
28968   std::string loaded_handle_bytes;
28969   rc = Parse_TPMI_DH_CONTEXT(&buffer, loaded_handle, &loaded_handle_bytes);
28970   if (rc != TPM_RC_SUCCESS) {
28971     return rc;
28972   }
28973   TPM_CC command_code = TPM_CC_ContextLoad;
28974   std::string command_code_bytes;
28975   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
28976   if (rc != TPM_RC_SUCCESS) {
28977     return rc;
28978   }
28979   std::string authorization_section_bytes;
28980   if (tag == TPM_ST_SESSIONS) {
28981     UINT32 parameter_section_size = buffer.size();
28982     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
28983     if (rc != TPM_RC_SUCCESS) {
28984       return rc;
28985     }
28986     if (parameter_section_size > buffer.size()) {
28987       return TPM_RC_INSUFFICIENT;
28988     }
28989     authorization_section_bytes = buffer.substr(parameter_section_size);
28990     // Keep the parameter section in |buffer|.
28991     buffer.erase(parameter_section_size);
28992   }
28993   std::unique_ptr<crypto::SecureHash> hash(
28994       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
28995   hash->Update(response_code_bytes.data(), response_code_bytes.size());
28996   hash->Update(command_code_bytes.data(), command_code_bytes.size());
28997   hash->Update(buffer.data(), buffer.size());
28998   std::string response_hash(32, 0);
28999   hash->Finish(std::data(response_hash), response_hash.size());
29000   if (tag == TPM_ST_SESSIONS) {
29001     if (!authorization_delegate)
29002       return TRUNKS_RC_AUTHORIZATION_FAILED;
29003     if (!authorization_delegate->CheckResponseAuthorization(
29004             response_hash, authorization_section_bytes)) {
29005       return TRUNKS_RC_AUTHORIZATION_FAILED;
29006     }
29007   }
29008   return TPM_RC_SUCCESS;
29009 }
29010 
ContextLoadErrorCallback(Tpm::ContextLoadResponse callback,TPM_RC response_code)29011 void ContextLoadErrorCallback(Tpm::ContextLoadResponse callback,
29012                               TPM_RC response_code) {
29013   VLOG(1) << __func__;
29014   std::move(callback).Run(response_code, TPMI_DH_CONTEXT());
29015 }
29016 
ContextLoadResponseParser(Tpm::ContextLoadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29017 void ContextLoadResponseParser(Tpm::ContextLoadResponse callback,
29018                                AuthorizationDelegate* authorization_delegate,
29019                                const std::string& response) {
29020   VLOG(1) << __func__;
29021   TPMI_DH_CONTEXT loaded_handle;
29022   TPM_RC rc = Tpm::ParseResponse_ContextLoad(response, &loaded_handle,
29023                                              authorization_delegate);
29024   if (rc != TPM_RC_SUCCESS) {
29025     base::OnceCallback<void(TPM_RC)> error_reporter =
29026         base::BindOnce(ContextLoadErrorCallback, std::move(callback));
29027     std::move(error_reporter).Run(rc);
29028     return;
29029   }
29030   std::move(callback).Run(rc, loaded_handle);
29031 }
29032 
ContextLoad(const TPMS_CONTEXT & context,AuthorizationDelegate * authorization_delegate,ContextLoadResponse callback)29033 void Tpm::ContextLoad(const TPMS_CONTEXT& context,
29034                       AuthorizationDelegate* authorization_delegate,
29035                       ContextLoadResponse callback) {
29036   VLOG(1) << __func__;
29037   std::string command;
29038   TPM_RC rc =
29039       SerializeCommand_ContextLoad(context, &command, authorization_delegate);
29040   if (rc != TPM_RC_SUCCESS) {
29041     base::OnceCallback<void(TPM_RC)> error_reporter =
29042         base::BindOnce(ContextLoadErrorCallback, std::move(callback));
29043     std::move(error_reporter).Run(rc);
29044     return;
29045   }
29046   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29047       ContextLoadResponseParser, std::move(callback), authorization_delegate);
29048   transceiver_->SendCommand(command, std::move(parser));
29049 }
29050 
ContextLoadSync(const TPMS_CONTEXT & context,TPMI_DH_CONTEXT * loaded_handle,AuthorizationDelegate * authorization_delegate)29051 TPM_RC Tpm::ContextLoadSync(const TPMS_CONTEXT& context,
29052                             TPMI_DH_CONTEXT* loaded_handle,
29053                             AuthorizationDelegate* authorization_delegate) {
29054   VLOG(1) << __func__;
29055   std::string command;
29056   TPM_RC rc =
29057       SerializeCommand_ContextLoad(context, &command, authorization_delegate);
29058   if (rc != TPM_RC_SUCCESS) {
29059     return rc;
29060   }
29061   std::string response = transceiver_->SendCommandAndWait(command);
29062   rc = ParseResponse_ContextLoad(response, loaded_handle,
29063                                  authorization_delegate);
29064   return rc;
29065 }
29066 
SerializeCommand_FlushContext(const TPMI_DH_CONTEXT & flush_handle,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29067 TPM_RC Tpm::SerializeCommand_FlushContext(
29068     const TPMI_DH_CONTEXT& flush_handle,
29069     std::string* serialized_command,
29070     AuthorizationDelegate* authorization_delegate) {
29071   VLOG(3) << __func__;
29072   TPM_RC rc = TPM_RC_SUCCESS;
29073   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29074   UINT32 command_size = 10;  // Header size.
29075   std::string handle_section_bytes;
29076   std::string parameter_section_bytes;
29077   TPM_CC command_code = TPM_CC_FlushContext;
29078   bool is_command_parameter_encryption_possible = false;
29079   bool is_response_parameter_encryption_possible = false;
29080   std::string command_code_bytes;
29081   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29082   if (rc != TPM_RC_SUCCESS) {
29083     return rc;
29084   }
29085   std::string flush_handle_bytes;
29086   rc = Serialize_TPMI_DH_CONTEXT(flush_handle, &flush_handle_bytes);
29087   if (rc != TPM_RC_SUCCESS) {
29088     return rc;
29089   }
29090   std::unique_ptr<crypto::SecureHash> hash(
29091       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29092   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29093   hash->Update(flush_handle_bytes.data(), flush_handle_bytes.size());
29094   parameter_section_bytes += flush_handle_bytes;
29095   command_size += flush_handle_bytes.size();
29096   std::string command_hash(32, 0);
29097   hash->Finish(std::data(command_hash), command_hash.size());
29098   std::string authorization_section_bytes;
29099   std::string authorization_size_bytes;
29100   if (authorization_delegate) {
29101     if (!authorization_delegate->GetCommandAuthorization(
29102             command_hash, is_command_parameter_encryption_possible,
29103             is_response_parameter_encryption_possible,
29104             &authorization_section_bytes)) {
29105       return TRUNKS_RC_AUTHORIZATION_FAILED;
29106     }
29107     if (!authorization_section_bytes.empty()) {
29108       tag = TPM_ST_SESSIONS;
29109       std::string tmp;
29110       rc = Serialize_UINT32(authorization_section_bytes.size(),
29111                             &authorization_size_bytes);
29112       if (rc != TPM_RC_SUCCESS) {
29113         return rc;
29114       }
29115       command_size +=
29116           authorization_size_bytes.size() + authorization_section_bytes.size();
29117     }
29118   }
29119   std::string tag_bytes;
29120   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29121   if (rc != TPM_RC_SUCCESS) {
29122     return rc;
29123   }
29124   std::string command_size_bytes;
29125   rc = Serialize_UINT32(command_size, &command_size_bytes);
29126   if (rc != TPM_RC_SUCCESS) {
29127     return rc;
29128   }
29129   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29130                         handle_section_bytes + authorization_size_bytes +
29131                         authorization_section_bytes + parameter_section_bytes;
29132   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29133   VLOG(2) << "Command: "
29134           << base::HexEncode(serialized_command->data(),
29135                              serialized_command->size());
29136   return TPM_RC_SUCCESS;
29137 }
29138 
ParseResponse_FlushContext(const std::string & response,AuthorizationDelegate * authorization_delegate)29139 TPM_RC Tpm::ParseResponse_FlushContext(
29140     const std::string& response,
29141     AuthorizationDelegate* authorization_delegate) {
29142   VLOG(3) << __func__;
29143   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29144   TPM_RC rc = TPM_RC_SUCCESS;
29145   std::string buffer(response);
29146   TPM_ST tag;
29147   std::string tag_bytes;
29148   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29149   if (rc != TPM_RC_SUCCESS) {
29150     return rc;
29151   }
29152   UINT32 response_size;
29153   std::string response_size_bytes;
29154   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29155   if (rc != TPM_RC_SUCCESS) {
29156     return rc;
29157   }
29158   TPM_RC response_code;
29159   std::string response_code_bytes;
29160   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29161   if (rc != TPM_RC_SUCCESS) {
29162     return rc;
29163   }
29164   if (response_size != response.size()) {
29165     return TPM_RC_SIZE;
29166   }
29167   if (response_code != TPM_RC_SUCCESS) {
29168     return response_code;
29169   }
29170   TPM_CC command_code = TPM_CC_FlushContext;
29171   std::string command_code_bytes;
29172   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29173   if (rc != TPM_RC_SUCCESS) {
29174     return rc;
29175   }
29176   std::string authorization_section_bytes;
29177   if (tag == TPM_ST_SESSIONS) {
29178     UINT32 parameter_section_size = buffer.size();
29179     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29180     if (rc != TPM_RC_SUCCESS) {
29181       return rc;
29182     }
29183     if (parameter_section_size > buffer.size()) {
29184       return TPM_RC_INSUFFICIENT;
29185     }
29186     authorization_section_bytes = buffer.substr(parameter_section_size);
29187     // Keep the parameter section in |buffer|.
29188     buffer.erase(parameter_section_size);
29189   }
29190   std::unique_ptr<crypto::SecureHash> hash(
29191       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29192   hash->Update(response_code_bytes.data(), response_code_bytes.size());
29193   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29194   hash->Update(buffer.data(), buffer.size());
29195   std::string response_hash(32, 0);
29196   hash->Finish(std::data(response_hash), response_hash.size());
29197   if (tag == TPM_ST_SESSIONS) {
29198     if (!authorization_delegate)
29199       return TRUNKS_RC_AUTHORIZATION_FAILED;
29200     if (!authorization_delegate->CheckResponseAuthorization(
29201             response_hash, authorization_section_bytes)) {
29202       return TRUNKS_RC_AUTHORIZATION_FAILED;
29203     }
29204   }
29205   return TPM_RC_SUCCESS;
29206 }
29207 
FlushContextErrorCallback(Tpm::FlushContextResponse callback,TPM_RC response_code)29208 void FlushContextErrorCallback(Tpm::FlushContextResponse callback,
29209                                TPM_RC response_code) {
29210   VLOG(1) << __func__;
29211   std::move(callback).Run(response_code);
29212 }
29213 
FlushContextResponseParser(Tpm::FlushContextResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29214 void FlushContextResponseParser(Tpm::FlushContextResponse callback,
29215                                 AuthorizationDelegate* authorization_delegate,
29216                                 const std::string& response) {
29217   VLOG(1) << __func__;
29218   TPM_RC rc = Tpm::ParseResponse_FlushContext(response, authorization_delegate);
29219   if (rc != TPM_RC_SUCCESS) {
29220     base::OnceCallback<void(TPM_RC)> error_reporter =
29221         base::BindOnce(FlushContextErrorCallback, std::move(callback));
29222     std::move(error_reporter).Run(rc);
29223     return;
29224   }
29225   std::move(callback).Run(rc);
29226 }
29227 
FlushContext(const TPMI_DH_CONTEXT & flush_handle,AuthorizationDelegate * authorization_delegate,FlushContextResponse callback)29228 void Tpm::FlushContext(const TPMI_DH_CONTEXT& flush_handle,
29229                        AuthorizationDelegate* authorization_delegate,
29230                        FlushContextResponse callback) {
29231   VLOG(1) << __func__;
29232   std::string command;
29233   TPM_RC rc = SerializeCommand_FlushContext(flush_handle, &command,
29234                                             authorization_delegate);
29235   if (rc != TPM_RC_SUCCESS) {
29236     base::OnceCallback<void(TPM_RC)> error_reporter =
29237         base::BindOnce(FlushContextErrorCallback, std::move(callback));
29238     std::move(error_reporter).Run(rc);
29239     return;
29240   }
29241   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29242       FlushContextResponseParser, std::move(callback), authorization_delegate);
29243   transceiver_->SendCommand(command, std::move(parser));
29244 }
29245 
FlushContextSync(const TPMI_DH_CONTEXT & flush_handle,AuthorizationDelegate * authorization_delegate)29246 TPM_RC Tpm::FlushContextSync(const TPMI_DH_CONTEXT& flush_handle,
29247                              AuthorizationDelegate* authorization_delegate) {
29248   VLOG(1) << __func__;
29249   std::string command;
29250   TPM_RC rc = SerializeCommand_FlushContext(flush_handle, &command,
29251                                             authorization_delegate);
29252   if (rc != TPM_RC_SUCCESS) {
29253     return rc;
29254   }
29255   std::string response = transceiver_->SendCommandAndWait(command);
29256   rc = ParseResponse_FlushContext(response, authorization_delegate);
29257   return rc;
29258 }
29259 
SerializeCommand_EvictControl(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_PERSISTENT & persistent_handle,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29260 TPM_RC Tpm::SerializeCommand_EvictControl(
29261     const TPMI_RH_PROVISION& auth,
29262     const std::string& auth_name,
29263     const TPMI_DH_OBJECT& object_handle,
29264     const std::string& object_handle_name,
29265     const TPMI_DH_PERSISTENT& persistent_handle,
29266     std::string* serialized_command,
29267     AuthorizationDelegate* authorization_delegate) {
29268   VLOG(3) << __func__;
29269   TPM_RC rc = TPM_RC_SUCCESS;
29270   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29271   UINT32 command_size = 10;  // Header size.
29272   std::string handle_section_bytes;
29273   std::string parameter_section_bytes;
29274   TPM_CC command_code = TPM_CC_EvictControl;
29275   bool is_command_parameter_encryption_possible = false;
29276   bool is_response_parameter_encryption_possible = false;
29277   std::string command_code_bytes;
29278   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29279   if (rc != TPM_RC_SUCCESS) {
29280     return rc;
29281   }
29282   std::string auth_bytes;
29283   rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29284   if (rc != TPM_RC_SUCCESS) {
29285     return rc;
29286   }
29287   std::string object_handle_bytes;
29288   rc = Serialize_TPMI_DH_OBJECT(object_handle, &object_handle_bytes);
29289   if (rc != TPM_RC_SUCCESS) {
29290     return rc;
29291   }
29292   std::string persistent_handle_bytes;
29293   rc =
29294       Serialize_TPMI_DH_PERSISTENT(persistent_handle, &persistent_handle_bytes);
29295   if (rc != TPM_RC_SUCCESS) {
29296     return rc;
29297   }
29298   std::unique_ptr<crypto::SecureHash> hash(
29299       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29300   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29301   hash->Update(auth_name.data(), auth_name.size());
29302   handle_section_bytes += auth_bytes;
29303   command_size += auth_bytes.size();
29304   hash->Update(object_handle_name.data(), object_handle_name.size());
29305   handle_section_bytes += object_handle_bytes;
29306   command_size += object_handle_bytes.size();
29307   hash->Update(persistent_handle_bytes.data(), persistent_handle_bytes.size());
29308   parameter_section_bytes += persistent_handle_bytes;
29309   command_size += persistent_handle_bytes.size();
29310   std::string command_hash(32, 0);
29311   hash->Finish(std::data(command_hash), command_hash.size());
29312   std::string authorization_section_bytes;
29313   std::string authorization_size_bytes;
29314   if (authorization_delegate) {
29315     if (!authorization_delegate->GetCommandAuthorization(
29316             command_hash, is_command_parameter_encryption_possible,
29317             is_response_parameter_encryption_possible,
29318             &authorization_section_bytes)) {
29319       return TRUNKS_RC_AUTHORIZATION_FAILED;
29320     }
29321     if (!authorization_section_bytes.empty()) {
29322       tag = TPM_ST_SESSIONS;
29323       std::string tmp;
29324       rc = Serialize_UINT32(authorization_section_bytes.size(),
29325                             &authorization_size_bytes);
29326       if (rc != TPM_RC_SUCCESS) {
29327         return rc;
29328       }
29329       command_size +=
29330           authorization_size_bytes.size() + authorization_section_bytes.size();
29331     }
29332   }
29333   std::string tag_bytes;
29334   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29335   if (rc != TPM_RC_SUCCESS) {
29336     return rc;
29337   }
29338   std::string command_size_bytes;
29339   rc = Serialize_UINT32(command_size, &command_size_bytes);
29340   if (rc != TPM_RC_SUCCESS) {
29341     return rc;
29342   }
29343   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29344                         handle_section_bytes + authorization_size_bytes +
29345                         authorization_section_bytes + parameter_section_bytes;
29346   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29347   VLOG(2) << "Command: "
29348           << base::HexEncode(serialized_command->data(),
29349                              serialized_command->size());
29350   return TPM_RC_SUCCESS;
29351 }
29352 
ParseResponse_EvictControl(const std::string & response,AuthorizationDelegate * authorization_delegate)29353 TPM_RC Tpm::ParseResponse_EvictControl(
29354     const std::string& response,
29355     AuthorizationDelegate* authorization_delegate) {
29356   VLOG(3) << __func__;
29357   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29358   TPM_RC rc = TPM_RC_SUCCESS;
29359   std::string buffer(response);
29360   TPM_ST tag;
29361   std::string tag_bytes;
29362   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29363   if (rc != TPM_RC_SUCCESS) {
29364     return rc;
29365   }
29366   UINT32 response_size;
29367   std::string response_size_bytes;
29368   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29369   if (rc != TPM_RC_SUCCESS) {
29370     return rc;
29371   }
29372   TPM_RC response_code;
29373   std::string response_code_bytes;
29374   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29375   if (rc != TPM_RC_SUCCESS) {
29376     return rc;
29377   }
29378   if (response_size != response.size()) {
29379     return TPM_RC_SIZE;
29380   }
29381   if (response_code != TPM_RC_SUCCESS) {
29382     return response_code;
29383   }
29384   TPM_CC command_code = TPM_CC_EvictControl;
29385   std::string command_code_bytes;
29386   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29387   if (rc != TPM_RC_SUCCESS) {
29388     return rc;
29389   }
29390   std::string authorization_section_bytes;
29391   if (tag == TPM_ST_SESSIONS) {
29392     UINT32 parameter_section_size = buffer.size();
29393     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29394     if (rc != TPM_RC_SUCCESS) {
29395       return rc;
29396     }
29397     if (parameter_section_size > buffer.size()) {
29398       return TPM_RC_INSUFFICIENT;
29399     }
29400     authorization_section_bytes = buffer.substr(parameter_section_size);
29401     // Keep the parameter section in |buffer|.
29402     buffer.erase(parameter_section_size);
29403   }
29404   std::unique_ptr<crypto::SecureHash> hash(
29405       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29406   hash->Update(response_code_bytes.data(), response_code_bytes.size());
29407   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29408   hash->Update(buffer.data(), buffer.size());
29409   std::string response_hash(32, 0);
29410   hash->Finish(std::data(response_hash), response_hash.size());
29411   if (tag == TPM_ST_SESSIONS) {
29412     if (!authorization_delegate)
29413       return TRUNKS_RC_AUTHORIZATION_FAILED;
29414     if (!authorization_delegate->CheckResponseAuthorization(
29415             response_hash, authorization_section_bytes)) {
29416       return TRUNKS_RC_AUTHORIZATION_FAILED;
29417     }
29418   }
29419   return TPM_RC_SUCCESS;
29420 }
29421 
EvictControlErrorCallback(Tpm::EvictControlResponse callback,TPM_RC response_code)29422 void EvictControlErrorCallback(Tpm::EvictControlResponse callback,
29423                                TPM_RC response_code) {
29424   VLOG(1) << __func__;
29425   std::move(callback).Run(response_code);
29426 }
29427 
EvictControlResponseParser(Tpm::EvictControlResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29428 void EvictControlResponseParser(Tpm::EvictControlResponse callback,
29429                                 AuthorizationDelegate* authorization_delegate,
29430                                 const std::string& response) {
29431   VLOG(1) << __func__;
29432   TPM_RC rc = Tpm::ParseResponse_EvictControl(response, authorization_delegate);
29433   if (rc != TPM_RC_SUCCESS) {
29434     base::OnceCallback<void(TPM_RC)> error_reporter =
29435         base::BindOnce(EvictControlErrorCallback, std::move(callback));
29436     std::move(error_reporter).Run(rc);
29437     return;
29438   }
29439   std::move(callback).Run(rc);
29440 }
29441 
EvictControl(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_PERSISTENT & persistent_handle,AuthorizationDelegate * authorization_delegate,EvictControlResponse callback)29442 void Tpm::EvictControl(const TPMI_RH_PROVISION& auth,
29443                        const std::string& auth_name,
29444                        const TPMI_DH_OBJECT& object_handle,
29445                        const std::string& object_handle_name,
29446                        const TPMI_DH_PERSISTENT& persistent_handle,
29447                        AuthorizationDelegate* authorization_delegate,
29448                        EvictControlResponse callback) {
29449   VLOG(1) << __func__;
29450   std::string command;
29451   TPM_RC rc = SerializeCommand_EvictControl(
29452       auth, auth_name, object_handle, object_handle_name, persistent_handle,
29453       &command, authorization_delegate);
29454   if (rc != TPM_RC_SUCCESS) {
29455     base::OnceCallback<void(TPM_RC)> error_reporter =
29456         base::BindOnce(EvictControlErrorCallback, std::move(callback));
29457     std::move(error_reporter).Run(rc);
29458     return;
29459   }
29460   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29461       EvictControlResponseParser, std::move(callback), authorization_delegate);
29462   transceiver_->SendCommand(command, std::move(parser));
29463 }
29464 
EvictControlSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPMI_DH_OBJECT & object_handle,const std::string & object_handle_name,const TPMI_DH_PERSISTENT & persistent_handle,AuthorizationDelegate * authorization_delegate)29465 TPM_RC Tpm::EvictControlSync(const TPMI_RH_PROVISION& auth,
29466                              const std::string& auth_name,
29467                              const TPMI_DH_OBJECT& object_handle,
29468                              const std::string& object_handle_name,
29469                              const TPMI_DH_PERSISTENT& persistent_handle,
29470                              AuthorizationDelegate* authorization_delegate) {
29471   VLOG(1) << __func__;
29472   std::string command;
29473   TPM_RC rc = SerializeCommand_EvictControl(
29474       auth, auth_name, object_handle, object_handle_name, persistent_handle,
29475       &command, authorization_delegate);
29476   if (rc != TPM_RC_SUCCESS) {
29477     return rc;
29478   }
29479   std::string response = transceiver_->SendCommandAndWait(command);
29480   rc = ParseResponse_EvictControl(response, authorization_delegate);
29481   return rc;
29482 }
29483 
SerializeCommand_ReadClock(std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29484 TPM_RC Tpm::SerializeCommand_ReadClock(
29485     std::string* serialized_command,
29486     AuthorizationDelegate* authorization_delegate) {
29487   VLOG(3) << __func__;
29488   TPM_RC rc = TPM_RC_SUCCESS;
29489   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29490   UINT32 command_size = 10;  // Header size.
29491   std::string handle_section_bytes;
29492   std::string parameter_section_bytes;
29493   TPM_CC command_code = TPM_CC_ReadClock;
29494   bool is_command_parameter_encryption_possible = false;
29495   bool is_response_parameter_encryption_possible = false;
29496   std::string command_code_bytes;
29497   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29498   if (rc != TPM_RC_SUCCESS) {
29499     return rc;
29500   }
29501   std::unique_ptr<crypto::SecureHash> hash(
29502       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29503   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29504   std::string command_hash(32, 0);
29505   hash->Finish(std::data(command_hash), command_hash.size());
29506   std::string authorization_section_bytes;
29507   std::string authorization_size_bytes;
29508   if (authorization_delegate) {
29509     if (!authorization_delegate->GetCommandAuthorization(
29510             command_hash, is_command_parameter_encryption_possible,
29511             is_response_parameter_encryption_possible,
29512             &authorization_section_bytes)) {
29513       return TRUNKS_RC_AUTHORIZATION_FAILED;
29514     }
29515     if (!authorization_section_bytes.empty()) {
29516       tag = TPM_ST_SESSIONS;
29517       std::string tmp;
29518       rc = Serialize_UINT32(authorization_section_bytes.size(),
29519                             &authorization_size_bytes);
29520       if (rc != TPM_RC_SUCCESS) {
29521         return rc;
29522       }
29523       command_size +=
29524           authorization_size_bytes.size() + authorization_section_bytes.size();
29525     }
29526   }
29527   std::string tag_bytes;
29528   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29529   if (rc != TPM_RC_SUCCESS) {
29530     return rc;
29531   }
29532   std::string command_size_bytes;
29533   rc = Serialize_UINT32(command_size, &command_size_bytes);
29534   if (rc != TPM_RC_SUCCESS) {
29535     return rc;
29536   }
29537   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29538                         handle_section_bytes + authorization_size_bytes +
29539                         authorization_section_bytes + parameter_section_bytes;
29540   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29541   VLOG(2) << "Command: "
29542           << base::HexEncode(serialized_command->data(),
29543                              serialized_command->size());
29544   return TPM_RC_SUCCESS;
29545 }
29546 
ParseResponse_ReadClock(const std::string & response,TPMS_TIME_INFO * current_time,AuthorizationDelegate * authorization_delegate)29547 TPM_RC Tpm::ParseResponse_ReadClock(
29548     const std::string& response,
29549     TPMS_TIME_INFO* current_time,
29550     AuthorizationDelegate* authorization_delegate) {
29551   VLOG(3) << __func__;
29552   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29553   TPM_RC rc = TPM_RC_SUCCESS;
29554   std::string buffer(response);
29555   TPM_ST tag;
29556   std::string tag_bytes;
29557   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29558   if (rc != TPM_RC_SUCCESS) {
29559     return rc;
29560   }
29561   UINT32 response_size;
29562   std::string response_size_bytes;
29563   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29564   if (rc != TPM_RC_SUCCESS) {
29565     return rc;
29566   }
29567   TPM_RC response_code;
29568   std::string response_code_bytes;
29569   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29570   if (rc != TPM_RC_SUCCESS) {
29571     return rc;
29572   }
29573   if (response_size != response.size()) {
29574     return TPM_RC_SIZE;
29575   }
29576   if (response_code != TPM_RC_SUCCESS) {
29577     return response_code;
29578   }
29579   TPM_CC command_code = TPM_CC_ReadClock;
29580   std::string command_code_bytes;
29581   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29582   if (rc != TPM_RC_SUCCESS) {
29583     return rc;
29584   }
29585   std::string authorization_section_bytes;
29586   if (tag == TPM_ST_SESSIONS) {
29587     UINT32 parameter_section_size = buffer.size();
29588     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29589     if (rc != TPM_RC_SUCCESS) {
29590       return rc;
29591     }
29592     if (parameter_section_size > buffer.size()) {
29593       return TPM_RC_INSUFFICIENT;
29594     }
29595     authorization_section_bytes = buffer.substr(parameter_section_size);
29596     // Keep the parameter section in |buffer|.
29597     buffer.erase(parameter_section_size);
29598   }
29599   std::unique_ptr<crypto::SecureHash> hash(
29600       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29601   hash->Update(response_code_bytes.data(), response_code_bytes.size());
29602   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29603   hash->Update(buffer.data(), buffer.size());
29604   std::string response_hash(32, 0);
29605   hash->Finish(std::data(response_hash), response_hash.size());
29606   if (tag == TPM_ST_SESSIONS) {
29607     if (!authorization_delegate)
29608       return TRUNKS_RC_AUTHORIZATION_FAILED;
29609     if (!authorization_delegate->CheckResponseAuthorization(
29610             response_hash, authorization_section_bytes)) {
29611       return TRUNKS_RC_AUTHORIZATION_FAILED;
29612     }
29613   }
29614   std::string current_time_bytes;
29615   rc = Parse_TPMS_TIME_INFO(&buffer, current_time, &current_time_bytes);
29616   if (rc != TPM_RC_SUCCESS) {
29617     return rc;
29618   }
29619   return TPM_RC_SUCCESS;
29620 }
29621 
ReadClockErrorCallback(Tpm::ReadClockResponse callback,TPM_RC response_code)29622 void ReadClockErrorCallback(Tpm::ReadClockResponse callback,
29623                             TPM_RC response_code) {
29624   VLOG(1) << __func__;
29625   std::move(callback).Run(response_code, TPMS_TIME_INFO());
29626 }
29627 
ReadClockResponseParser(Tpm::ReadClockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29628 void ReadClockResponseParser(Tpm::ReadClockResponse callback,
29629                              AuthorizationDelegate* authorization_delegate,
29630                              const std::string& response) {
29631   VLOG(1) << __func__;
29632   TPMS_TIME_INFO current_time;
29633   TPM_RC rc = Tpm::ParseResponse_ReadClock(response, &current_time,
29634                                            authorization_delegate);
29635   if (rc != TPM_RC_SUCCESS) {
29636     base::OnceCallback<void(TPM_RC)> error_reporter =
29637         base::BindOnce(ReadClockErrorCallback, std::move(callback));
29638     std::move(error_reporter).Run(rc);
29639     return;
29640   }
29641   std::move(callback).Run(rc, current_time);
29642 }
29643 
ReadClock(AuthorizationDelegate * authorization_delegate,ReadClockResponse callback)29644 void Tpm::ReadClock(AuthorizationDelegate* authorization_delegate,
29645                     ReadClockResponse callback) {
29646   VLOG(1) << __func__;
29647   std::string command;
29648   TPM_RC rc = SerializeCommand_ReadClock(&command, authorization_delegate);
29649   if (rc != TPM_RC_SUCCESS) {
29650     base::OnceCallback<void(TPM_RC)> error_reporter =
29651         base::BindOnce(ReadClockErrorCallback, std::move(callback));
29652     std::move(error_reporter).Run(rc);
29653     return;
29654   }
29655   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29656       ReadClockResponseParser, std::move(callback), authorization_delegate);
29657   transceiver_->SendCommand(command, std::move(parser));
29658 }
29659 
ReadClockSync(TPMS_TIME_INFO * current_time,AuthorizationDelegate * authorization_delegate)29660 TPM_RC Tpm::ReadClockSync(TPMS_TIME_INFO* current_time,
29661                           AuthorizationDelegate* authorization_delegate) {
29662   VLOG(1) << __func__;
29663   std::string command;
29664   TPM_RC rc = SerializeCommand_ReadClock(&command, authorization_delegate);
29665   if (rc != TPM_RC_SUCCESS) {
29666     return rc;
29667   }
29668   std::string response = transceiver_->SendCommandAndWait(command);
29669   rc = ParseResponse_ReadClock(response, current_time, authorization_delegate);
29670   return rc;
29671 }
29672 
SerializeCommand_ClockSet(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29673 TPM_RC Tpm::SerializeCommand_ClockSet(
29674     const TPMI_RH_PROVISION& auth,
29675     const std::string& auth_name,
29676     const UINT64& new_time,
29677     std::string* serialized_command,
29678     AuthorizationDelegate* authorization_delegate) {
29679   VLOG(3) << __func__;
29680   TPM_RC rc = TPM_RC_SUCCESS;
29681   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29682   UINT32 command_size = 10;  // Header size.
29683   std::string handle_section_bytes;
29684   std::string parameter_section_bytes;
29685   TPM_CC command_code = TPM_CC_ClockSet;
29686   bool is_command_parameter_encryption_possible = false;
29687   bool is_response_parameter_encryption_possible = false;
29688   std::string command_code_bytes;
29689   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29690   if (rc != TPM_RC_SUCCESS) {
29691     return rc;
29692   }
29693   std::string auth_bytes;
29694   rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29695   if (rc != TPM_RC_SUCCESS) {
29696     return rc;
29697   }
29698   std::string new_time_bytes;
29699   rc = Serialize_UINT64(new_time, &new_time_bytes);
29700   if (rc != TPM_RC_SUCCESS) {
29701     return rc;
29702   }
29703   std::unique_ptr<crypto::SecureHash> hash(
29704       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29705   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29706   hash->Update(auth_name.data(), auth_name.size());
29707   handle_section_bytes += auth_bytes;
29708   command_size += auth_bytes.size();
29709   hash->Update(new_time_bytes.data(), new_time_bytes.size());
29710   parameter_section_bytes += new_time_bytes;
29711   command_size += new_time_bytes.size();
29712   std::string command_hash(32, 0);
29713   hash->Finish(std::data(command_hash), command_hash.size());
29714   std::string authorization_section_bytes;
29715   std::string authorization_size_bytes;
29716   if (authorization_delegate) {
29717     if (!authorization_delegate->GetCommandAuthorization(
29718             command_hash, is_command_parameter_encryption_possible,
29719             is_response_parameter_encryption_possible,
29720             &authorization_section_bytes)) {
29721       return TRUNKS_RC_AUTHORIZATION_FAILED;
29722     }
29723     if (!authorization_section_bytes.empty()) {
29724       tag = TPM_ST_SESSIONS;
29725       std::string tmp;
29726       rc = Serialize_UINT32(authorization_section_bytes.size(),
29727                             &authorization_size_bytes);
29728       if (rc != TPM_RC_SUCCESS) {
29729         return rc;
29730       }
29731       command_size +=
29732           authorization_size_bytes.size() + authorization_section_bytes.size();
29733     }
29734   }
29735   std::string tag_bytes;
29736   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29737   if (rc != TPM_RC_SUCCESS) {
29738     return rc;
29739   }
29740   std::string command_size_bytes;
29741   rc = Serialize_UINT32(command_size, &command_size_bytes);
29742   if (rc != TPM_RC_SUCCESS) {
29743     return rc;
29744   }
29745   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29746                         handle_section_bytes + authorization_size_bytes +
29747                         authorization_section_bytes + parameter_section_bytes;
29748   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29749   VLOG(2) << "Command: "
29750           << base::HexEncode(serialized_command->data(),
29751                              serialized_command->size());
29752   return TPM_RC_SUCCESS;
29753 }
29754 
ParseResponse_ClockSet(const std::string & response,AuthorizationDelegate * authorization_delegate)29755 TPM_RC Tpm::ParseResponse_ClockSet(
29756     const std::string& response,
29757     AuthorizationDelegate* authorization_delegate) {
29758   VLOG(3) << __func__;
29759   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29760   TPM_RC rc = TPM_RC_SUCCESS;
29761   std::string buffer(response);
29762   TPM_ST tag;
29763   std::string tag_bytes;
29764   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29765   if (rc != TPM_RC_SUCCESS) {
29766     return rc;
29767   }
29768   UINT32 response_size;
29769   std::string response_size_bytes;
29770   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29771   if (rc != TPM_RC_SUCCESS) {
29772     return rc;
29773   }
29774   TPM_RC response_code;
29775   std::string response_code_bytes;
29776   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29777   if (rc != TPM_RC_SUCCESS) {
29778     return rc;
29779   }
29780   if (response_size != response.size()) {
29781     return TPM_RC_SIZE;
29782   }
29783   if (response_code != TPM_RC_SUCCESS) {
29784     return response_code;
29785   }
29786   TPM_CC command_code = TPM_CC_ClockSet;
29787   std::string command_code_bytes;
29788   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29789   if (rc != TPM_RC_SUCCESS) {
29790     return rc;
29791   }
29792   std::string authorization_section_bytes;
29793   if (tag == TPM_ST_SESSIONS) {
29794     UINT32 parameter_section_size = buffer.size();
29795     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
29796     if (rc != TPM_RC_SUCCESS) {
29797       return rc;
29798     }
29799     if (parameter_section_size > buffer.size()) {
29800       return TPM_RC_INSUFFICIENT;
29801     }
29802     authorization_section_bytes = buffer.substr(parameter_section_size);
29803     // Keep the parameter section in |buffer|.
29804     buffer.erase(parameter_section_size);
29805   }
29806   std::unique_ptr<crypto::SecureHash> hash(
29807       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29808   hash->Update(response_code_bytes.data(), response_code_bytes.size());
29809   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29810   hash->Update(buffer.data(), buffer.size());
29811   std::string response_hash(32, 0);
29812   hash->Finish(std::data(response_hash), response_hash.size());
29813   if (tag == TPM_ST_SESSIONS) {
29814     if (!authorization_delegate)
29815       return TRUNKS_RC_AUTHORIZATION_FAILED;
29816     if (!authorization_delegate->CheckResponseAuthorization(
29817             response_hash, authorization_section_bytes)) {
29818       return TRUNKS_RC_AUTHORIZATION_FAILED;
29819     }
29820   }
29821   return TPM_RC_SUCCESS;
29822 }
29823 
ClockSetErrorCallback(Tpm::ClockSetResponse callback,TPM_RC response_code)29824 void ClockSetErrorCallback(Tpm::ClockSetResponse callback,
29825                            TPM_RC response_code) {
29826   VLOG(1) << __func__;
29827   std::move(callback).Run(response_code);
29828 }
29829 
ClockSetResponseParser(Tpm::ClockSetResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)29830 void ClockSetResponseParser(Tpm::ClockSetResponse callback,
29831                             AuthorizationDelegate* authorization_delegate,
29832                             const std::string& response) {
29833   VLOG(1) << __func__;
29834   TPM_RC rc = Tpm::ParseResponse_ClockSet(response, authorization_delegate);
29835   if (rc != TPM_RC_SUCCESS) {
29836     base::OnceCallback<void(TPM_RC)> error_reporter =
29837         base::BindOnce(ClockSetErrorCallback, std::move(callback));
29838     std::move(error_reporter).Run(rc);
29839     return;
29840   }
29841   std::move(callback).Run(rc);
29842 }
29843 
ClockSet(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,AuthorizationDelegate * authorization_delegate,ClockSetResponse callback)29844 void Tpm::ClockSet(const TPMI_RH_PROVISION& auth,
29845                    const std::string& auth_name,
29846                    const UINT64& new_time,
29847                    AuthorizationDelegate* authorization_delegate,
29848                    ClockSetResponse callback) {
29849   VLOG(1) << __func__;
29850   std::string command;
29851   TPM_RC rc = SerializeCommand_ClockSet(auth, auth_name, new_time, &command,
29852                                         authorization_delegate);
29853   if (rc != TPM_RC_SUCCESS) {
29854     base::OnceCallback<void(TPM_RC)> error_reporter =
29855         base::BindOnce(ClockSetErrorCallback, std::move(callback));
29856     std::move(error_reporter).Run(rc);
29857     return;
29858   }
29859   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
29860       ClockSetResponseParser, std::move(callback), authorization_delegate);
29861   transceiver_->SendCommand(command, std::move(parser));
29862 }
29863 
ClockSetSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const UINT64 & new_time,AuthorizationDelegate * authorization_delegate)29864 TPM_RC Tpm::ClockSetSync(const TPMI_RH_PROVISION& auth,
29865                          const std::string& auth_name,
29866                          const UINT64& new_time,
29867                          AuthorizationDelegate* authorization_delegate) {
29868   VLOG(1) << __func__;
29869   std::string command;
29870   TPM_RC rc = SerializeCommand_ClockSet(auth, auth_name, new_time, &command,
29871                                         authorization_delegate);
29872   if (rc != TPM_RC_SUCCESS) {
29873     return rc;
29874   }
29875   std::string response = transceiver_->SendCommandAndWait(command);
29876   rc = ParseResponse_ClockSet(response, authorization_delegate);
29877   return rc;
29878 }
29879 
SerializeCommand_ClockRateAdjust(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)29880 TPM_RC Tpm::SerializeCommand_ClockRateAdjust(
29881     const TPMI_RH_PROVISION& auth,
29882     const std::string& auth_name,
29883     const TPM_CLOCK_ADJUST& rate_adjust,
29884     std::string* serialized_command,
29885     AuthorizationDelegate* authorization_delegate) {
29886   VLOG(3) << __func__;
29887   TPM_RC rc = TPM_RC_SUCCESS;
29888   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
29889   UINT32 command_size = 10;  // Header size.
29890   std::string handle_section_bytes;
29891   std::string parameter_section_bytes;
29892   TPM_CC command_code = TPM_CC_ClockRateAdjust;
29893   bool is_command_parameter_encryption_possible = false;
29894   bool is_response_parameter_encryption_possible = false;
29895   std::string command_code_bytes;
29896   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29897   if (rc != TPM_RC_SUCCESS) {
29898     return rc;
29899   }
29900   std::string auth_bytes;
29901   rc = Serialize_TPMI_RH_PROVISION(auth, &auth_bytes);
29902   if (rc != TPM_RC_SUCCESS) {
29903     return rc;
29904   }
29905   std::string rate_adjust_bytes;
29906   rc = Serialize_TPM_CLOCK_ADJUST(rate_adjust, &rate_adjust_bytes);
29907   if (rc != TPM_RC_SUCCESS) {
29908     return rc;
29909   }
29910   std::unique_ptr<crypto::SecureHash> hash(
29911       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
29912   hash->Update(command_code_bytes.data(), command_code_bytes.size());
29913   hash->Update(auth_name.data(), auth_name.size());
29914   handle_section_bytes += auth_bytes;
29915   command_size += auth_bytes.size();
29916   hash->Update(rate_adjust_bytes.data(), rate_adjust_bytes.size());
29917   parameter_section_bytes += rate_adjust_bytes;
29918   command_size += rate_adjust_bytes.size();
29919   std::string command_hash(32, 0);
29920   hash->Finish(std::data(command_hash), command_hash.size());
29921   std::string authorization_section_bytes;
29922   std::string authorization_size_bytes;
29923   if (authorization_delegate) {
29924     if (!authorization_delegate->GetCommandAuthorization(
29925             command_hash, is_command_parameter_encryption_possible,
29926             is_response_parameter_encryption_possible,
29927             &authorization_section_bytes)) {
29928       return TRUNKS_RC_AUTHORIZATION_FAILED;
29929     }
29930     if (!authorization_section_bytes.empty()) {
29931       tag = TPM_ST_SESSIONS;
29932       std::string tmp;
29933       rc = Serialize_UINT32(authorization_section_bytes.size(),
29934                             &authorization_size_bytes);
29935       if (rc != TPM_RC_SUCCESS) {
29936         return rc;
29937       }
29938       command_size +=
29939           authorization_size_bytes.size() + authorization_section_bytes.size();
29940     }
29941   }
29942   std::string tag_bytes;
29943   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
29944   if (rc != TPM_RC_SUCCESS) {
29945     return rc;
29946   }
29947   std::string command_size_bytes;
29948   rc = Serialize_UINT32(command_size, &command_size_bytes);
29949   if (rc != TPM_RC_SUCCESS) {
29950     return rc;
29951   }
29952   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
29953                         handle_section_bytes + authorization_size_bytes +
29954                         authorization_section_bytes + parameter_section_bytes;
29955   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
29956   VLOG(2) << "Command: "
29957           << base::HexEncode(serialized_command->data(),
29958                              serialized_command->size());
29959   return TPM_RC_SUCCESS;
29960 }
29961 
ParseResponse_ClockRateAdjust(const std::string & response,AuthorizationDelegate * authorization_delegate)29962 TPM_RC Tpm::ParseResponse_ClockRateAdjust(
29963     const std::string& response,
29964     AuthorizationDelegate* authorization_delegate) {
29965   VLOG(3) << __func__;
29966   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
29967   TPM_RC rc = TPM_RC_SUCCESS;
29968   std::string buffer(response);
29969   TPM_ST tag;
29970   std::string tag_bytes;
29971   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
29972   if (rc != TPM_RC_SUCCESS) {
29973     return rc;
29974   }
29975   UINT32 response_size;
29976   std::string response_size_bytes;
29977   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
29978   if (rc != TPM_RC_SUCCESS) {
29979     return rc;
29980   }
29981   TPM_RC response_code;
29982   std::string response_code_bytes;
29983   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
29984   if (rc != TPM_RC_SUCCESS) {
29985     return rc;
29986   }
29987   if (response_size != response.size()) {
29988     return TPM_RC_SIZE;
29989   }
29990   if (response_code != TPM_RC_SUCCESS) {
29991     return response_code;
29992   }
29993   TPM_CC command_code = TPM_CC_ClockRateAdjust;
29994   std::string command_code_bytes;
29995   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
29996   if (rc != TPM_RC_SUCCESS) {
29997     return rc;
29998   }
29999   std::string authorization_section_bytes;
30000   if (tag == TPM_ST_SESSIONS) {
30001     UINT32 parameter_section_size = buffer.size();
30002     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30003     if (rc != TPM_RC_SUCCESS) {
30004       return rc;
30005     }
30006     if (parameter_section_size > buffer.size()) {
30007       return TPM_RC_INSUFFICIENT;
30008     }
30009     authorization_section_bytes = buffer.substr(parameter_section_size);
30010     // Keep the parameter section in |buffer|.
30011     buffer.erase(parameter_section_size);
30012   }
30013   std::unique_ptr<crypto::SecureHash> hash(
30014       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30015   hash->Update(response_code_bytes.data(), response_code_bytes.size());
30016   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30017   hash->Update(buffer.data(), buffer.size());
30018   std::string response_hash(32, 0);
30019   hash->Finish(std::data(response_hash), response_hash.size());
30020   if (tag == TPM_ST_SESSIONS) {
30021     if (!authorization_delegate)
30022       return TRUNKS_RC_AUTHORIZATION_FAILED;
30023     if (!authorization_delegate->CheckResponseAuthorization(
30024             response_hash, authorization_section_bytes)) {
30025       return TRUNKS_RC_AUTHORIZATION_FAILED;
30026     }
30027   }
30028   return TPM_RC_SUCCESS;
30029 }
30030 
ClockRateAdjustErrorCallback(Tpm::ClockRateAdjustResponse callback,TPM_RC response_code)30031 void ClockRateAdjustErrorCallback(Tpm::ClockRateAdjustResponse callback,
30032                                   TPM_RC response_code) {
30033   VLOG(1) << __func__;
30034   std::move(callback).Run(response_code);
30035 }
30036 
ClockRateAdjustResponseParser(Tpm::ClockRateAdjustResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30037 void ClockRateAdjustResponseParser(
30038     Tpm::ClockRateAdjustResponse callback,
30039     AuthorizationDelegate* authorization_delegate,
30040     const std::string& response) {
30041   VLOG(1) << __func__;
30042   TPM_RC rc =
30043       Tpm::ParseResponse_ClockRateAdjust(response, authorization_delegate);
30044   if (rc != TPM_RC_SUCCESS) {
30045     base::OnceCallback<void(TPM_RC)> error_reporter =
30046         base::BindOnce(ClockRateAdjustErrorCallback, std::move(callback));
30047     std::move(error_reporter).Run(rc);
30048     return;
30049   }
30050   std::move(callback).Run(rc);
30051 }
30052 
ClockRateAdjust(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,AuthorizationDelegate * authorization_delegate,ClockRateAdjustResponse callback)30053 void Tpm::ClockRateAdjust(const TPMI_RH_PROVISION& auth,
30054                           const std::string& auth_name,
30055                           const TPM_CLOCK_ADJUST& rate_adjust,
30056                           AuthorizationDelegate* authorization_delegate,
30057                           ClockRateAdjustResponse callback) {
30058   VLOG(1) << __func__;
30059   std::string command;
30060   TPM_RC rc = SerializeCommand_ClockRateAdjust(
30061       auth, auth_name, rate_adjust, &command, authorization_delegate);
30062   if (rc != TPM_RC_SUCCESS) {
30063     base::OnceCallback<void(TPM_RC)> error_reporter =
30064         base::BindOnce(ClockRateAdjustErrorCallback, std::move(callback));
30065     std::move(error_reporter).Run(rc);
30066     return;
30067   }
30068   base::OnceCallback<void(const std::string&)> parser =
30069       base::BindOnce(ClockRateAdjustResponseParser, std::move(callback),
30070                      authorization_delegate);
30071   transceiver_->SendCommand(command, std::move(parser));
30072 }
30073 
ClockRateAdjustSync(const TPMI_RH_PROVISION & auth,const std::string & auth_name,const TPM_CLOCK_ADJUST & rate_adjust,AuthorizationDelegate * authorization_delegate)30074 TPM_RC Tpm::ClockRateAdjustSync(const TPMI_RH_PROVISION& auth,
30075                                 const std::string& auth_name,
30076                                 const TPM_CLOCK_ADJUST& rate_adjust,
30077                                 AuthorizationDelegate* authorization_delegate) {
30078   VLOG(1) << __func__;
30079   std::string command;
30080   TPM_RC rc = SerializeCommand_ClockRateAdjust(
30081       auth, auth_name, rate_adjust, &command, authorization_delegate);
30082   if (rc != TPM_RC_SUCCESS) {
30083     return rc;
30084   }
30085   std::string response = transceiver_->SendCommandAndWait(command);
30086   rc = ParseResponse_ClockRateAdjust(response, authorization_delegate);
30087   return rc;
30088 }
30089 
SerializeCommand_GetCapability(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30090 TPM_RC Tpm::SerializeCommand_GetCapability(
30091     const TPM_CAP& capability,
30092     const UINT32& property,
30093     const UINT32& property_count,
30094     std::string* serialized_command,
30095     AuthorizationDelegate* authorization_delegate) {
30096   VLOG(3) << __func__;
30097   TPM_RC rc = TPM_RC_SUCCESS;
30098   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30099   UINT32 command_size = 10;  // Header size.
30100   std::string handle_section_bytes;
30101   std::string parameter_section_bytes;
30102   TPM_CC command_code = TPM_CC_GetCapability;
30103   bool is_command_parameter_encryption_possible = false;
30104   bool is_response_parameter_encryption_possible = false;
30105   std::string command_code_bytes;
30106   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30107   if (rc != TPM_RC_SUCCESS) {
30108     return rc;
30109   }
30110   std::string capability_bytes;
30111   rc = Serialize_TPM_CAP(capability, &capability_bytes);
30112   if (rc != TPM_RC_SUCCESS) {
30113     return rc;
30114   }
30115   std::string property_bytes;
30116   rc = Serialize_UINT32(property, &property_bytes);
30117   if (rc != TPM_RC_SUCCESS) {
30118     return rc;
30119   }
30120   std::string property_count_bytes;
30121   rc = Serialize_UINT32(property_count, &property_count_bytes);
30122   if (rc != TPM_RC_SUCCESS) {
30123     return rc;
30124   }
30125   std::unique_ptr<crypto::SecureHash> hash(
30126       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30127   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30128   hash->Update(capability_bytes.data(), capability_bytes.size());
30129   parameter_section_bytes += capability_bytes;
30130   command_size += capability_bytes.size();
30131   hash->Update(property_bytes.data(), property_bytes.size());
30132   parameter_section_bytes += property_bytes;
30133   command_size += property_bytes.size();
30134   hash->Update(property_count_bytes.data(), property_count_bytes.size());
30135   parameter_section_bytes += property_count_bytes;
30136   command_size += property_count_bytes.size();
30137   std::string command_hash(32, 0);
30138   hash->Finish(std::data(command_hash), command_hash.size());
30139   std::string authorization_section_bytes;
30140   std::string authorization_size_bytes;
30141   if (authorization_delegate) {
30142     if (!authorization_delegate->GetCommandAuthorization(
30143             command_hash, is_command_parameter_encryption_possible,
30144             is_response_parameter_encryption_possible,
30145             &authorization_section_bytes)) {
30146       return TRUNKS_RC_AUTHORIZATION_FAILED;
30147     }
30148     if (!authorization_section_bytes.empty()) {
30149       tag = TPM_ST_SESSIONS;
30150       std::string tmp;
30151       rc = Serialize_UINT32(authorization_section_bytes.size(),
30152                             &authorization_size_bytes);
30153       if (rc != TPM_RC_SUCCESS) {
30154         return rc;
30155       }
30156       command_size +=
30157           authorization_size_bytes.size() + authorization_section_bytes.size();
30158     }
30159   }
30160   std::string tag_bytes;
30161   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30162   if (rc != TPM_RC_SUCCESS) {
30163     return rc;
30164   }
30165   std::string command_size_bytes;
30166   rc = Serialize_UINT32(command_size, &command_size_bytes);
30167   if (rc != TPM_RC_SUCCESS) {
30168     return rc;
30169   }
30170   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30171                         handle_section_bytes + authorization_size_bytes +
30172                         authorization_section_bytes + parameter_section_bytes;
30173   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30174   VLOG(2) << "Command: "
30175           << base::HexEncode(serialized_command->data(),
30176                              serialized_command->size());
30177   return TPM_RC_SUCCESS;
30178 }
30179 
ParseResponse_GetCapability(const std::string & response,TPMI_YES_NO * more_data,TPMS_CAPABILITY_DATA * capability_data,AuthorizationDelegate * authorization_delegate)30180 TPM_RC Tpm::ParseResponse_GetCapability(
30181     const std::string& response,
30182     TPMI_YES_NO* more_data,
30183     TPMS_CAPABILITY_DATA* capability_data,
30184     AuthorizationDelegate* authorization_delegate) {
30185   VLOG(3) << __func__;
30186   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30187   TPM_RC rc = TPM_RC_SUCCESS;
30188   std::string buffer(response);
30189   TPM_ST tag;
30190   std::string tag_bytes;
30191   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30192   if (rc != TPM_RC_SUCCESS) {
30193     return rc;
30194   }
30195   UINT32 response_size;
30196   std::string response_size_bytes;
30197   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30198   if (rc != TPM_RC_SUCCESS) {
30199     return rc;
30200   }
30201   TPM_RC response_code;
30202   std::string response_code_bytes;
30203   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30204   if (rc != TPM_RC_SUCCESS) {
30205     return rc;
30206   }
30207   if (response_size != response.size()) {
30208     return TPM_RC_SIZE;
30209   }
30210   if (response_code != TPM_RC_SUCCESS) {
30211     return response_code;
30212   }
30213   TPM_CC command_code = TPM_CC_GetCapability;
30214   std::string command_code_bytes;
30215   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30216   if (rc != TPM_RC_SUCCESS) {
30217     return rc;
30218   }
30219   std::string authorization_section_bytes;
30220   if (tag == TPM_ST_SESSIONS) {
30221     UINT32 parameter_section_size = buffer.size();
30222     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30223     if (rc != TPM_RC_SUCCESS) {
30224       return rc;
30225     }
30226     if (parameter_section_size > buffer.size()) {
30227       return TPM_RC_INSUFFICIENT;
30228     }
30229     authorization_section_bytes = buffer.substr(parameter_section_size);
30230     // Keep the parameter section in |buffer|.
30231     buffer.erase(parameter_section_size);
30232   }
30233   std::unique_ptr<crypto::SecureHash> hash(
30234       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30235   hash->Update(response_code_bytes.data(), response_code_bytes.size());
30236   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30237   hash->Update(buffer.data(), buffer.size());
30238   std::string response_hash(32, 0);
30239   hash->Finish(std::data(response_hash), response_hash.size());
30240   if (tag == TPM_ST_SESSIONS) {
30241     if (!authorization_delegate)
30242       return TRUNKS_RC_AUTHORIZATION_FAILED;
30243     if (!authorization_delegate->CheckResponseAuthorization(
30244             response_hash, authorization_section_bytes)) {
30245       return TRUNKS_RC_AUTHORIZATION_FAILED;
30246     }
30247   }
30248   std::string more_data_bytes;
30249   rc = Parse_TPMI_YES_NO(&buffer, more_data, &more_data_bytes);
30250   if (rc != TPM_RC_SUCCESS) {
30251     return rc;
30252   }
30253   std::string capability_data_bytes;
30254   rc = Parse_TPMS_CAPABILITY_DATA(&buffer, capability_data,
30255                                   &capability_data_bytes);
30256   if (rc != TPM_RC_SUCCESS) {
30257     return rc;
30258   }
30259   return TPM_RC_SUCCESS;
30260 }
30261 
GetCapabilityErrorCallback(Tpm::GetCapabilityResponse callback,TPM_RC response_code)30262 void GetCapabilityErrorCallback(Tpm::GetCapabilityResponse callback,
30263                                 TPM_RC response_code) {
30264   VLOG(1) << __func__;
30265   std::move(callback).Run(response_code, TPMI_YES_NO(), TPMS_CAPABILITY_DATA());
30266 }
30267 
GetCapabilityResponseParser(Tpm::GetCapabilityResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30268 void GetCapabilityResponseParser(Tpm::GetCapabilityResponse callback,
30269                                  AuthorizationDelegate* authorization_delegate,
30270                                  const std::string& response) {
30271   VLOG(1) << __func__;
30272   TPMI_YES_NO more_data;
30273   TPMS_CAPABILITY_DATA capability_data;
30274   TPM_RC rc = Tpm::ParseResponse_GetCapability(
30275       response, &more_data, &capability_data, authorization_delegate);
30276   if (rc != TPM_RC_SUCCESS) {
30277     base::OnceCallback<void(TPM_RC)> error_reporter =
30278         base::BindOnce(GetCapabilityErrorCallback, std::move(callback));
30279     std::move(error_reporter).Run(rc);
30280     return;
30281   }
30282   std::move(callback).Run(rc, more_data, capability_data);
30283 }
30284 
GetCapability(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,AuthorizationDelegate * authorization_delegate,GetCapabilityResponse callback)30285 void Tpm::GetCapability(const TPM_CAP& capability,
30286                         const UINT32& property,
30287                         const UINT32& property_count,
30288                         AuthorizationDelegate* authorization_delegate,
30289                         GetCapabilityResponse callback) {
30290   VLOG(1) << __func__;
30291   std::string command;
30292   TPM_RC rc = SerializeCommand_GetCapability(
30293       capability, property, property_count, &command, authorization_delegate);
30294   if (rc != TPM_RC_SUCCESS) {
30295     base::OnceCallback<void(TPM_RC)> error_reporter =
30296         base::BindOnce(GetCapabilityErrorCallback, std::move(callback));
30297     std::move(error_reporter).Run(rc);
30298     return;
30299   }
30300   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
30301       GetCapabilityResponseParser, std::move(callback), authorization_delegate);
30302   transceiver_->SendCommand(command, std::move(parser));
30303 }
30304 
GetCapabilitySync(const TPM_CAP & capability,const UINT32 & property,const UINT32 & property_count,TPMI_YES_NO * more_data,TPMS_CAPABILITY_DATA * capability_data,AuthorizationDelegate * authorization_delegate)30305 TPM_RC Tpm::GetCapabilitySync(const TPM_CAP& capability,
30306                               const UINT32& property,
30307                               const UINT32& property_count,
30308                               TPMI_YES_NO* more_data,
30309                               TPMS_CAPABILITY_DATA* capability_data,
30310                               AuthorizationDelegate* authorization_delegate) {
30311   VLOG(1) << __func__;
30312   std::string command;
30313   TPM_RC rc = SerializeCommand_GetCapability(
30314       capability, property, property_count, &command, authorization_delegate);
30315   if (rc != TPM_RC_SUCCESS) {
30316     return rc;
30317   }
30318   std::string response = transceiver_->SendCommandAndWait(command);
30319   rc = ParseResponse_GetCapability(response, more_data, capability_data,
30320                                    authorization_delegate);
30321   return rc;
30322 }
30323 
SerializeCommand_TestParms(const TPMT_PUBLIC_PARMS & parameters,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30324 TPM_RC Tpm::SerializeCommand_TestParms(
30325     const TPMT_PUBLIC_PARMS& parameters,
30326     std::string* serialized_command,
30327     AuthorizationDelegate* authorization_delegate) {
30328   VLOG(3) << __func__;
30329   TPM_RC rc = TPM_RC_SUCCESS;
30330   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30331   UINT32 command_size = 10;  // Header size.
30332   std::string handle_section_bytes;
30333   std::string parameter_section_bytes;
30334   TPM_CC command_code = TPM_CC_TestParms;
30335   bool is_command_parameter_encryption_possible = false;
30336   bool is_response_parameter_encryption_possible = false;
30337   std::string command_code_bytes;
30338   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30339   if (rc != TPM_RC_SUCCESS) {
30340     return rc;
30341   }
30342   std::string parameters_bytes;
30343   rc = Serialize_TPMT_PUBLIC_PARMS(parameters, &parameters_bytes);
30344   if (rc != TPM_RC_SUCCESS) {
30345     return rc;
30346   }
30347   std::unique_ptr<crypto::SecureHash> hash(
30348       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30349   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30350   hash->Update(parameters_bytes.data(), parameters_bytes.size());
30351   parameter_section_bytes += parameters_bytes;
30352   command_size += parameters_bytes.size();
30353   std::string command_hash(32, 0);
30354   hash->Finish(std::data(command_hash), command_hash.size());
30355   std::string authorization_section_bytes;
30356   std::string authorization_size_bytes;
30357   if (authorization_delegate) {
30358     if (!authorization_delegate->GetCommandAuthorization(
30359             command_hash, is_command_parameter_encryption_possible,
30360             is_response_parameter_encryption_possible,
30361             &authorization_section_bytes)) {
30362       return TRUNKS_RC_AUTHORIZATION_FAILED;
30363     }
30364     if (!authorization_section_bytes.empty()) {
30365       tag = TPM_ST_SESSIONS;
30366       std::string tmp;
30367       rc = Serialize_UINT32(authorization_section_bytes.size(),
30368                             &authorization_size_bytes);
30369       if (rc != TPM_RC_SUCCESS) {
30370         return rc;
30371       }
30372       command_size +=
30373           authorization_size_bytes.size() + authorization_section_bytes.size();
30374     }
30375   }
30376   std::string tag_bytes;
30377   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30378   if (rc != TPM_RC_SUCCESS) {
30379     return rc;
30380   }
30381   std::string command_size_bytes;
30382   rc = Serialize_UINT32(command_size, &command_size_bytes);
30383   if (rc != TPM_RC_SUCCESS) {
30384     return rc;
30385   }
30386   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30387                         handle_section_bytes + authorization_size_bytes +
30388                         authorization_section_bytes + parameter_section_bytes;
30389   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30390   VLOG(2) << "Command: "
30391           << base::HexEncode(serialized_command->data(),
30392                              serialized_command->size());
30393   return TPM_RC_SUCCESS;
30394 }
30395 
ParseResponse_TestParms(const std::string & response,AuthorizationDelegate * authorization_delegate)30396 TPM_RC Tpm::ParseResponse_TestParms(
30397     const std::string& response,
30398     AuthorizationDelegate* authorization_delegate) {
30399   VLOG(3) << __func__;
30400   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30401   TPM_RC rc = TPM_RC_SUCCESS;
30402   std::string buffer(response);
30403   TPM_ST tag;
30404   std::string tag_bytes;
30405   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30406   if (rc != TPM_RC_SUCCESS) {
30407     return rc;
30408   }
30409   UINT32 response_size;
30410   std::string response_size_bytes;
30411   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30412   if (rc != TPM_RC_SUCCESS) {
30413     return rc;
30414   }
30415   TPM_RC response_code;
30416   std::string response_code_bytes;
30417   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30418   if (rc != TPM_RC_SUCCESS) {
30419     return rc;
30420   }
30421   if (response_size != response.size()) {
30422     return TPM_RC_SIZE;
30423   }
30424   if (response_code != TPM_RC_SUCCESS) {
30425     return response_code;
30426   }
30427   TPM_CC command_code = TPM_CC_TestParms;
30428   std::string command_code_bytes;
30429   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30430   if (rc != TPM_RC_SUCCESS) {
30431     return rc;
30432   }
30433   std::string authorization_section_bytes;
30434   if (tag == TPM_ST_SESSIONS) {
30435     UINT32 parameter_section_size = buffer.size();
30436     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30437     if (rc != TPM_RC_SUCCESS) {
30438       return rc;
30439     }
30440     if (parameter_section_size > buffer.size()) {
30441       return TPM_RC_INSUFFICIENT;
30442     }
30443     authorization_section_bytes = buffer.substr(parameter_section_size);
30444     // Keep the parameter section in |buffer|.
30445     buffer.erase(parameter_section_size);
30446   }
30447   std::unique_ptr<crypto::SecureHash> hash(
30448       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30449   hash->Update(response_code_bytes.data(), response_code_bytes.size());
30450   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30451   hash->Update(buffer.data(), buffer.size());
30452   std::string response_hash(32, 0);
30453   hash->Finish(std::data(response_hash), response_hash.size());
30454   if (tag == TPM_ST_SESSIONS) {
30455     if (!authorization_delegate)
30456       return TRUNKS_RC_AUTHORIZATION_FAILED;
30457     if (!authorization_delegate->CheckResponseAuthorization(
30458             response_hash, authorization_section_bytes)) {
30459       return TRUNKS_RC_AUTHORIZATION_FAILED;
30460     }
30461   }
30462   return TPM_RC_SUCCESS;
30463 }
30464 
TestParmsErrorCallback(Tpm::TestParmsResponse callback,TPM_RC response_code)30465 void TestParmsErrorCallback(Tpm::TestParmsResponse callback,
30466                             TPM_RC response_code) {
30467   VLOG(1) << __func__;
30468   std::move(callback).Run(response_code);
30469 }
30470 
TestParmsResponseParser(Tpm::TestParmsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30471 void TestParmsResponseParser(Tpm::TestParmsResponse callback,
30472                              AuthorizationDelegate* authorization_delegate,
30473                              const std::string& response) {
30474   VLOG(1) << __func__;
30475   TPM_RC rc = Tpm::ParseResponse_TestParms(response, authorization_delegate);
30476   if (rc != TPM_RC_SUCCESS) {
30477     base::OnceCallback<void(TPM_RC)> error_reporter =
30478         base::BindOnce(TestParmsErrorCallback, std::move(callback));
30479     std::move(error_reporter).Run(rc);
30480     return;
30481   }
30482   std::move(callback).Run(rc);
30483 }
30484 
TestParms(const TPMT_PUBLIC_PARMS & parameters,AuthorizationDelegate * authorization_delegate,TestParmsResponse callback)30485 void Tpm::TestParms(const TPMT_PUBLIC_PARMS& parameters,
30486                     AuthorizationDelegate* authorization_delegate,
30487                     TestParmsResponse callback) {
30488   VLOG(1) << __func__;
30489   std::string command;
30490   TPM_RC rc =
30491       SerializeCommand_TestParms(parameters, &command, authorization_delegate);
30492   if (rc != TPM_RC_SUCCESS) {
30493     base::OnceCallback<void(TPM_RC)> error_reporter =
30494         base::BindOnce(TestParmsErrorCallback, std::move(callback));
30495     std::move(error_reporter).Run(rc);
30496     return;
30497   }
30498   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
30499       TestParmsResponseParser, std::move(callback), authorization_delegate);
30500   transceiver_->SendCommand(command, std::move(parser));
30501 }
30502 
TestParmsSync(const TPMT_PUBLIC_PARMS & parameters,AuthorizationDelegate * authorization_delegate)30503 TPM_RC Tpm::TestParmsSync(const TPMT_PUBLIC_PARMS& parameters,
30504                           AuthorizationDelegate* authorization_delegate) {
30505   VLOG(1) << __func__;
30506   std::string command;
30507   TPM_RC rc =
30508       SerializeCommand_TestParms(parameters, &command, authorization_delegate);
30509   if (rc != TPM_RC_SUCCESS) {
30510     return rc;
30511   }
30512   std::string response = transceiver_->SendCommandAndWait(command);
30513   rc = ParseResponse_TestParms(response, authorization_delegate);
30514   return rc;
30515 }
30516 
SerializeCommand_NV_DefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & auth,const TPM2B_NV_PUBLIC & public_info,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30517 TPM_RC Tpm::SerializeCommand_NV_DefineSpace(
30518     const TPMI_RH_PROVISION& auth_handle,
30519     const std::string& auth_handle_name,
30520     const TPM2B_AUTH& auth,
30521     const TPM2B_NV_PUBLIC& public_info,
30522     std::string* serialized_command,
30523     AuthorizationDelegate* authorization_delegate) {
30524   VLOG(3) << __func__;
30525   TPM_RC rc = TPM_RC_SUCCESS;
30526   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30527   UINT32 command_size = 10;  // Header size.
30528   std::string handle_section_bytes;
30529   std::string parameter_section_bytes;
30530   TPM_CC command_code = TPM_CC_NV_DefineSpace;
30531   bool is_command_parameter_encryption_possible = true;
30532   bool is_response_parameter_encryption_possible = false;
30533   std::string command_code_bytes;
30534   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30535   if (rc != TPM_RC_SUCCESS) {
30536     return rc;
30537   }
30538   std::string auth_handle_bytes;
30539   rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
30540   if (rc != TPM_RC_SUCCESS) {
30541     return rc;
30542   }
30543   std::string auth_bytes;
30544   rc = Serialize_TPM2B_AUTH(auth, &auth_bytes);
30545   if (rc != TPM_RC_SUCCESS) {
30546     return rc;
30547   }
30548   std::string public_info_bytes;
30549   rc = Serialize_TPM2B_NV_PUBLIC(public_info, &public_info_bytes);
30550   if (rc != TPM_RC_SUCCESS) {
30551     return rc;
30552   }
30553   if (authorization_delegate) {
30554     // Encrypt just the parameter data, not the size.
30555     std::string tmp = auth_bytes.substr(2);
30556     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
30557       return TRUNKS_RC_ENCRYPTION_FAILED;
30558     }
30559     auth_bytes.replace(2, std::string::npos, tmp);
30560   }
30561   std::unique_ptr<crypto::SecureHash> hash(
30562       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30563   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30564   hash->Update(auth_handle_name.data(), auth_handle_name.size());
30565   handle_section_bytes += auth_handle_bytes;
30566   command_size += auth_handle_bytes.size();
30567   hash->Update(auth_bytes.data(), auth_bytes.size());
30568   parameter_section_bytes += auth_bytes;
30569   command_size += auth_bytes.size();
30570   hash->Update(public_info_bytes.data(), public_info_bytes.size());
30571   parameter_section_bytes += public_info_bytes;
30572   command_size += public_info_bytes.size();
30573   std::string command_hash(32, 0);
30574   hash->Finish(std::data(command_hash), command_hash.size());
30575   std::string authorization_section_bytes;
30576   std::string authorization_size_bytes;
30577   if (authorization_delegate) {
30578     if (!authorization_delegate->GetCommandAuthorization(
30579             command_hash, is_command_parameter_encryption_possible,
30580             is_response_parameter_encryption_possible,
30581             &authorization_section_bytes)) {
30582       return TRUNKS_RC_AUTHORIZATION_FAILED;
30583     }
30584     if (!authorization_section_bytes.empty()) {
30585       tag = TPM_ST_SESSIONS;
30586       std::string tmp;
30587       rc = Serialize_UINT32(authorization_section_bytes.size(),
30588                             &authorization_size_bytes);
30589       if (rc != TPM_RC_SUCCESS) {
30590         return rc;
30591       }
30592       command_size +=
30593           authorization_size_bytes.size() + authorization_section_bytes.size();
30594     }
30595   }
30596   std::string tag_bytes;
30597   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30598   if (rc != TPM_RC_SUCCESS) {
30599     return rc;
30600   }
30601   std::string command_size_bytes;
30602   rc = Serialize_UINT32(command_size, &command_size_bytes);
30603   if (rc != TPM_RC_SUCCESS) {
30604     return rc;
30605   }
30606   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30607                         handle_section_bytes + authorization_size_bytes +
30608                         authorization_section_bytes + parameter_section_bytes;
30609   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30610   VLOG(2) << "Command: "
30611           << base::HexEncode(serialized_command->data(),
30612                              serialized_command->size());
30613   return TPM_RC_SUCCESS;
30614 }
30615 
ParseResponse_NV_DefineSpace(const std::string & response,AuthorizationDelegate * authorization_delegate)30616 TPM_RC Tpm::ParseResponse_NV_DefineSpace(
30617     const std::string& response,
30618     AuthorizationDelegate* authorization_delegate) {
30619   VLOG(3) << __func__;
30620   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30621   TPM_RC rc = TPM_RC_SUCCESS;
30622   std::string buffer(response);
30623   TPM_ST tag;
30624   std::string tag_bytes;
30625   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30626   if (rc != TPM_RC_SUCCESS) {
30627     return rc;
30628   }
30629   UINT32 response_size;
30630   std::string response_size_bytes;
30631   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30632   if (rc != TPM_RC_SUCCESS) {
30633     return rc;
30634   }
30635   TPM_RC response_code;
30636   std::string response_code_bytes;
30637   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30638   if (rc != TPM_RC_SUCCESS) {
30639     return rc;
30640   }
30641   if (response_size != response.size()) {
30642     return TPM_RC_SIZE;
30643   }
30644   if (response_code != TPM_RC_SUCCESS) {
30645     return response_code;
30646   }
30647   TPM_CC command_code = TPM_CC_NV_DefineSpace;
30648   std::string command_code_bytes;
30649   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30650   if (rc != TPM_RC_SUCCESS) {
30651     return rc;
30652   }
30653   std::string authorization_section_bytes;
30654   if (tag == TPM_ST_SESSIONS) {
30655     UINT32 parameter_section_size = buffer.size();
30656     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30657     if (rc != TPM_RC_SUCCESS) {
30658       return rc;
30659     }
30660     if (parameter_section_size > buffer.size()) {
30661       return TPM_RC_INSUFFICIENT;
30662     }
30663     authorization_section_bytes = buffer.substr(parameter_section_size);
30664     // Keep the parameter section in |buffer|.
30665     buffer.erase(parameter_section_size);
30666   }
30667   std::unique_ptr<crypto::SecureHash> hash(
30668       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30669   hash->Update(response_code_bytes.data(), response_code_bytes.size());
30670   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30671   hash->Update(buffer.data(), buffer.size());
30672   std::string response_hash(32, 0);
30673   hash->Finish(std::data(response_hash), response_hash.size());
30674   if (tag == TPM_ST_SESSIONS) {
30675     if (!authorization_delegate)
30676       return TRUNKS_RC_AUTHORIZATION_FAILED;
30677     if (!authorization_delegate->CheckResponseAuthorization(
30678             response_hash, authorization_section_bytes)) {
30679       return TRUNKS_RC_AUTHORIZATION_FAILED;
30680     }
30681   }
30682   return TPM_RC_SUCCESS;
30683 }
30684 
NV_DefineSpaceErrorCallback(Tpm::NV_DefineSpaceResponse callback,TPM_RC response_code)30685 void NV_DefineSpaceErrorCallback(Tpm::NV_DefineSpaceResponse callback,
30686                                  TPM_RC response_code) {
30687   VLOG(1) << __func__;
30688   std::move(callback).Run(response_code);
30689 }
30690 
NV_DefineSpaceResponseParser(Tpm::NV_DefineSpaceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30691 void NV_DefineSpaceResponseParser(Tpm::NV_DefineSpaceResponse callback,
30692                                   AuthorizationDelegate* authorization_delegate,
30693                                   const std::string& response) {
30694   VLOG(1) << __func__;
30695   TPM_RC rc =
30696       Tpm::ParseResponse_NV_DefineSpace(response, authorization_delegate);
30697   if (rc != TPM_RC_SUCCESS) {
30698     base::OnceCallback<void(TPM_RC)> error_reporter =
30699         base::BindOnce(NV_DefineSpaceErrorCallback, std::move(callback));
30700     std::move(error_reporter).Run(rc);
30701     return;
30702   }
30703   std::move(callback).Run(rc);
30704 }
30705 
NV_DefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & auth,const TPM2B_NV_PUBLIC & public_info,AuthorizationDelegate * authorization_delegate,NV_DefineSpaceResponse callback)30706 void Tpm::NV_DefineSpace(const TPMI_RH_PROVISION& auth_handle,
30707                          const std::string& auth_handle_name,
30708                          const TPM2B_AUTH& auth,
30709                          const TPM2B_NV_PUBLIC& public_info,
30710                          AuthorizationDelegate* authorization_delegate,
30711                          NV_DefineSpaceResponse callback) {
30712   VLOG(1) << __func__;
30713   std::string command;
30714   TPM_RC rc = SerializeCommand_NV_DefineSpace(auth_handle, auth_handle_name,
30715                                               auth, public_info, &command,
30716                                               authorization_delegate);
30717   if (rc != TPM_RC_SUCCESS) {
30718     base::OnceCallback<void(TPM_RC)> error_reporter =
30719         base::BindOnce(NV_DefineSpaceErrorCallback, std::move(callback));
30720     std::move(error_reporter).Run(rc);
30721     return;
30722   }
30723   base::OnceCallback<void(const std::string&)> parser =
30724       base::BindOnce(NV_DefineSpaceResponseParser, std::move(callback),
30725                      authorization_delegate);
30726   transceiver_->SendCommand(command, std::move(parser));
30727 }
30728 
NV_DefineSpaceSync(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPM2B_AUTH & auth,const TPM2B_NV_PUBLIC & public_info,AuthorizationDelegate * authorization_delegate)30729 TPM_RC Tpm::NV_DefineSpaceSync(const TPMI_RH_PROVISION& auth_handle,
30730                                const std::string& auth_handle_name,
30731                                const TPM2B_AUTH& auth,
30732                                const TPM2B_NV_PUBLIC& public_info,
30733                                AuthorizationDelegate* authorization_delegate) {
30734   VLOG(1) << __func__;
30735   std::string command;
30736   TPM_RC rc = SerializeCommand_NV_DefineSpace(auth_handle, auth_handle_name,
30737                                               auth, public_info, &command,
30738                                               authorization_delegate);
30739   if (rc != TPM_RC_SUCCESS) {
30740     return rc;
30741   }
30742   std::string response = transceiver_->SendCommandAndWait(command);
30743   rc = ParseResponse_NV_DefineSpace(response, authorization_delegate);
30744   return rc;
30745 }
30746 
SerializeCommand_NV_UndefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30747 TPM_RC Tpm::SerializeCommand_NV_UndefineSpace(
30748     const TPMI_RH_PROVISION& auth_handle,
30749     const std::string& auth_handle_name,
30750     const TPMI_RH_NV_INDEX& nv_index,
30751     const std::string& nv_index_name,
30752     std::string* serialized_command,
30753     AuthorizationDelegate* authorization_delegate) {
30754   VLOG(3) << __func__;
30755   TPM_RC rc = TPM_RC_SUCCESS;
30756   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30757   UINT32 command_size = 10;  // Header size.
30758   std::string handle_section_bytes;
30759   std::string parameter_section_bytes;
30760   TPM_CC command_code = TPM_CC_NV_UndefineSpace;
30761   bool is_command_parameter_encryption_possible = false;
30762   bool is_response_parameter_encryption_possible = false;
30763   std::string command_code_bytes;
30764   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30765   if (rc != TPM_RC_SUCCESS) {
30766     return rc;
30767   }
30768   std::string auth_handle_bytes;
30769   rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
30770   if (rc != TPM_RC_SUCCESS) {
30771     return rc;
30772   }
30773   std::string nv_index_bytes;
30774   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30775   if (rc != TPM_RC_SUCCESS) {
30776     return rc;
30777   }
30778   std::unique_ptr<crypto::SecureHash> hash(
30779       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30780   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30781   hash->Update(auth_handle_name.data(), auth_handle_name.size());
30782   handle_section_bytes += auth_handle_bytes;
30783   command_size += auth_handle_bytes.size();
30784   hash->Update(nv_index_name.data(), nv_index_name.size());
30785   handle_section_bytes += nv_index_bytes;
30786   command_size += nv_index_bytes.size();
30787   std::string command_hash(32, 0);
30788   hash->Finish(std::data(command_hash), command_hash.size());
30789   std::string authorization_section_bytes;
30790   std::string authorization_size_bytes;
30791   if (authorization_delegate) {
30792     if (!authorization_delegate->GetCommandAuthorization(
30793             command_hash, is_command_parameter_encryption_possible,
30794             is_response_parameter_encryption_possible,
30795             &authorization_section_bytes)) {
30796       return TRUNKS_RC_AUTHORIZATION_FAILED;
30797     }
30798     if (!authorization_section_bytes.empty()) {
30799       tag = TPM_ST_SESSIONS;
30800       std::string tmp;
30801       rc = Serialize_UINT32(authorization_section_bytes.size(),
30802                             &authorization_size_bytes);
30803       if (rc != TPM_RC_SUCCESS) {
30804         return rc;
30805       }
30806       command_size +=
30807           authorization_size_bytes.size() + authorization_section_bytes.size();
30808     }
30809   }
30810   std::string tag_bytes;
30811   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
30812   if (rc != TPM_RC_SUCCESS) {
30813     return rc;
30814   }
30815   std::string command_size_bytes;
30816   rc = Serialize_UINT32(command_size, &command_size_bytes);
30817   if (rc != TPM_RC_SUCCESS) {
30818     return rc;
30819   }
30820   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
30821                         handle_section_bytes + authorization_size_bytes +
30822                         authorization_section_bytes + parameter_section_bytes;
30823   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
30824   VLOG(2) << "Command: "
30825           << base::HexEncode(serialized_command->data(),
30826                              serialized_command->size());
30827   return TPM_RC_SUCCESS;
30828 }
30829 
ParseResponse_NV_UndefineSpace(const std::string & response,AuthorizationDelegate * authorization_delegate)30830 TPM_RC Tpm::ParseResponse_NV_UndefineSpace(
30831     const std::string& response,
30832     AuthorizationDelegate* authorization_delegate) {
30833   VLOG(3) << __func__;
30834   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
30835   TPM_RC rc = TPM_RC_SUCCESS;
30836   std::string buffer(response);
30837   TPM_ST tag;
30838   std::string tag_bytes;
30839   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
30840   if (rc != TPM_RC_SUCCESS) {
30841     return rc;
30842   }
30843   UINT32 response_size;
30844   std::string response_size_bytes;
30845   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
30846   if (rc != TPM_RC_SUCCESS) {
30847     return rc;
30848   }
30849   TPM_RC response_code;
30850   std::string response_code_bytes;
30851   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
30852   if (rc != TPM_RC_SUCCESS) {
30853     return rc;
30854   }
30855   if (response_size != response.size()) {
30856     return TPM_RC_SIZE;
30857   }
30858   if (response_code != TPM_RC_SUCCESS) {
30859     return response_code;
30860   }
30861   TPM_CC command_code = TPM_CC_NV_UndefineSpace;
30862   std::string command_code_bytes;
30863   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30864   if (rc != TPM_RC_SUCCESS) {
30865     return rc;
30866   }
30867   std::string authorization_section_bytes;
30868   if (tag == TPM_ST_SESSIONS) {
30869     UINT32 parameter_section_size = buffer.size();
30870     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
30871     if (rc != TPM_RC_SUCCESS) {
30872       return rc;
30873     }
30874     if (parameter_section_size > buffer.size()) {
30875       return TPM_RC_INSUFFICIENT;
30876     }
30877     authorization_section_bytes = buffer.substr(parameter_section_size);
30878     // Keep the parameter section in |buffer|.
30879     buffer.erase(parameter_section_size);
30880   }
30881   std::unique_ptr<crypto::SecureHash> hash(
30882       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30883   hash->Update(response_code_bytes.data(), response_code_bytes.size());
30884   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30885   hash->Update(buffer.data(), buffer.size());
30886   std::string response_hash(32, 0);
30887   hash->Finish(std::data(response_hash), response_hash.size());
30888   if (tag == TPM_ST_SESSIONS) {
30889     if (!authorization_delegate)
30890       return TRUNKS_RC_AUTHORIZATION_FAILED;
30891     if (!authorization_delegate->CheckResponseAuthorization(
30892             response_hash, authorization_section_bytes)) {
30893       return TRUNKS_RC_AUTHORIZATION_FAILED;
30894     }
30895   }
30896   return TPM_RC_SUCCESS;
30897 }
30898 
NV_UndefineSpaceErrorCallback(Tpm::NV_UndefineSpaceResponse callback,TPM_RC response_code)30899 void NV_UndefineSpaceErrorCallback(Tpm::NV_UndefineSpaceResponse callback,
30900                                    TPM_RC response_code) {
30901   VLOG(1) << __func__;
30902   std::move(callback).Run(response_code);
30903 }
30904 
NV_UndefineSpaceResponseParser(Tpm::NV_UndefineSpaceResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)30905 void NV_UndefineSpaceResponseParser(
30906     Tpm::NV_UndefineSpaceResponse callback,
30907     AuthorizationDelegate* authorization_delegate,
30908     const std::string& response) {
30909   VLOG(1) << __func__;
30910   TPM_RC rc =
30911       Tpm::ParseResponse_NV_UndefineSpace(response, authorization_delegate);
30912   if (rc != TPM_RC_SUCCESS) {
30913     base::OnceCallback<void(TPM_RC)> error_reporter =
30914         base::BindOnce(NV_UndefineSpaceErrorCallback, std::move(callback));
30915     std::move(error_reporter).Run(rc);
30916     return;
30917   }
30918   std::move(callback).Run(rc);
30919 }
30920 
NV_UndefineSpace(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_UndefineSpaceResponse callback)30921 void Tpm::NV_UndefineSpace(const TPMI_RH_PROVISION& auth_handle,
30922                            const std::string& auth_handle_name,
30923                            const TPMI_RH_NV_INDEX& nv_index,
30924                            const std::string& nv_index_name,
30925                            AuthorizationDelegate* authorization_delegate,
30926                            NV_UndefineSpaceResponse callback) {
30927   VLOG(1) << __func__;
30928   std::string command;
30929   TPM_RC rc = SerializeCommand_NV_UndefineSpace(
30930       auth_handle, auth_handle_name, nv_index, nv_index_name, &command,
30931       authorization_delegate);
30932   if (rc != TPM_RC_SUCCESS) {
30933     base::OnceCallback<void(TPM_RC)> error_reporter =
30934         base::BindOnce(NV_UndefineSpaceErrorCallback, std::move(callback));
30935     std::move(error_reporter).Run(rc);
30936     return;
30937   }
30938   base::OnceCallback<void(const std::string&)> parser =
30939       base::BindOnce(NV_UndefineSpaceResponseParser, std::move(callback),
30940                      authorization_delegate);
30941   transceiver_->SendCommand(command, std::move(parser));
30942 }
30943 
NV_UndefineSpaceSync(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)30944 TPM_RC Tpm::NV_UndefineSpaceSync(
30945     const TPMI_RH_PROVISION& auth_handle,
30946     const std::string& auth_handle_name,
30947     const TPMI_RH_NV_INDEX& nv_index,
30948     const std::string& nv_index_name,
30949     AuthorizationDelegate* authorization_delegate) {
30950   VLOG(1) << __func__;
30951   std::string command;
30952   TPM_RC rc = SerializeCommand_NV_UndefineSpace(
30953       auth_handle, auth_handle_name, nv_index, nv_index_name, &command,
30954       authorization_delegate);
30955   if (rc != TPM_RC_SUCCESS) {
30956     return rc;
30957   }
30958   std::string response = transceiver_->SendCommandAndWait(command);
30959   rc = ParseResponse_NV_UndefineSpace(response, authorization_delegate);
30960   return rc;
30961 }
30962 
SerializeCommand_NV_UndefineSpaceSpecial(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_RH_PLATFORM & platform,const std::string & platform_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)30963 TPM_RC Tpm::SerializeCommand_NV_UndefineSpaceSpecial(
30964     const TPMI_RH_NV_INDEX& nv_index,
30965     const std::string& nv_index_name,
30966     const TPMI_RH_PLATFORM& platform,
30967     const std::string& platform_name,
30968     std::string* serialized_command,
30969     AuthorizationDelegate* authorization_delegate) {
30970   VLOG(3) << __func__;
30971   TPM_RC rc = TPM_RC_SUCCESS;
30972   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
30973   UINT32 command_size = 10;  // Header size.
30974   std::string handle_section_bytes;
30975   std::string parameter_section_bytes;
30976   TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial;
30977   bool is_command_parameter_encryption_possible = false;
30978   bool is_response_parameter_encryption_possible = false;
30979   std::string command_code_bytes;
30980   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
30981   if (rc != TPM_RC_SUCCESS) {
30982     return rc;
30983   }
30984   std::string nv_index_bytes;
30985   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
30986   if (rc != TPM_RC_SUCCESS) {
30987     return rc;
30988   }
30989   std::string platform_bytes;
30990   rc = Serialize_TPMI_RH_PLATFORM(platform, &platform_bytes);
30991   if (rc != TPM_RC_SUCCESS) {
30992     return rc;
30993   }
30994   std::unique_ptr<crypto::SecureHash> hash(
30995       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
30996   hash->Update(command_code_bytes.data(), command_code_bytes.size());
30997   hash->Update(nv_index_name.data(), nv_index_name.size());
30998   handle_section_bytes += nv_index_bytes;
30999   command_size += nv_index_bytes.size();
31000   hash->Update(platform_name.data(), platform_name.size());
31001   handle_section_bytes += platform_bytes;
31002   command_size += platform_bytes.size();
31003   std::string command_hash(32, 0);
31004   hash->Finish(std::data(command_hash), command_hash.size());
31005   std::string authorization_section_bytes;
31006   std::string authorization_size_bytes;
31007   if (authorization_delegate) {
31008     if (!authorization_delegate->GetCommandAuthorization(
31009             command_hash, is_command_parameter_encryption_possible,
31010             is_response_parameter_encryption_possible,
31011             &authorization_section_bytes)) {
31012       return TRUNKS_RC_AUTHORIZATION_FAILED;
31013     }
31014     if (!authorization_section_bytes.empty()) {
31015       tag = TPM_ST_SESSIONS;
31016       std::string tmp;
31017       rc = Serialize_UINT32(authorization_section_bytes.size(),
31018                             &authorization_size_bytes);
31019       if (rc != TPM_RC_SUCCESS) {
31020         return rc;
31021       }
31022       command_size +=
31023           authorization_size_bytes.size() + authorization_section_bytes.size();
31024     }
31025   }
31026   std::string tag_bytes;
31027   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31028   if (rc != TPM_RC_SUCCESS) {
31029     return rc;
31030   }
31031   std::string command_size_bytes;
31032   rc = Serialize_UINT32(command_size, &command_size_bytes);
31033   if (rc != TPM_RC_SUCCESS) {
31034     return rc;
31035   }
31036   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31037                         handle_section_bytes + authorization_size_bytes +
31038                         authorization_section_bytes + parameter_section_bytes;
31039   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31040   VLOG(2) << "Command: "
31041           << base::HexEncode(serialized_command->data(),
31042                              serialized_command->size());
31043   return TPM_RC_SUCCESS;
31044 }
31045 
ParseResponse_NV_UndefineSpaceSpecial(const std::string & response,AuthorizationDelegate * authorization_delegate)31046 TPM_RC Tpm::ParseResponse_NV_UndefineSpaceSpecial(
31047     const std::string& response,
31048     AuthorizationDelegate* authorization_delegate) {
31049   VLOG(3) << __func__;
31050   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31051   TPM_RC rc = TPM_RC_SUCCESS;
31052   std::string buffer(response);
31053   TPM_ST tag;
31054   std::string tag_bytes;
31055   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31056   if (rc != TPM_RC_SUCCESS) {
31057     return rc;
31058   }
31059   UINT32 response_size;
31060   std::string response_size_bytes;
31061   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31062   if (rc != TPM_RC_SUCCESS) {
31063     return rc;
31064   }
31065   TPM_RC response_code;
31066   std::string response_code_bytes;
31067   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31068   if (rc != TPM_RC_SUCCESS) {
31069     return rc;
31070   }
31071   if (response_size != response.size()) {
31072     return TPM_RC_SIZE;
31073   }
31074   if (response_code != TPM_RC_SUCCESS) {
31075     return response_code;
31076   }
31077   TPM_CC command_code = TPM_CC_NV_UndefineSpaceSpecial;
31078   std::string command_code_bytes;
31079   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31080   if (rc != TPM_RC_SUCCESS) {
31081     return rc;
31082   }
31083   std::string authorization_section_bytes;
31084   if (tag == TPM_ST_SESSIONS) {
31085     UINT32 parameter_section_size = buffer.size();
31086     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31087     if (rc != TPM_RC_SUCCESS) {
31088       return rc;
31089     }
31090     if (parameter_section_size > buffer.size()) {
31091       return TPM_RC_INSUFFICIENT;
31092     }
31093     authorization_section_bytes = buffer.substr(parameter_section_size);
31094     // Keep the parameter section in |buffer|.
31095     buffer.erase(parameter_section_size);
31096   }
31097   std::unique_ptr<crypto::SecureHash> hash(
31098       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31099   hash->Update(response_code_bytes.data(), response_code_bytes.size());
31100   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31101   hash->Update(buffer.data(), buffer.size());
31102   std::string response_hash(32, 0);
31103   hash->Finish(std::data(response_hash), response_hash.size());
31104   if (tag == TPM_ST_SESSIONS) {
31105     if (!authorization_delegate)
31106       return TRUNKS_RC_AUTHORIZATION_FAILED;
31107     if (!authorization_delegate->CheckResponseAuthorization(
31108             response_hash, authorization_section_bytes)) {
31109       return TRUNKS_RC_AUTHORIZATION_FAILED;
31110     }
31111   }
31112   return TPM_RC_SUCCESS;
31113 }
31114 
NV_UndefineSpaceSpecialErrorCallback(Tpm::NV_UndefineSpaceSpecialResponse callback,TPM_RC response_code)31115 void NV_UndefineSpaceSpecialErrorCallback(
31116     Tpm::NV_UndefineSpaceSpecialResponse callback, TPM_RC response_code) {
31117   VLOG(1) << __func__;
31118   std::move(callback).Run(response_code);
31119 }
31120 
NV_UndefineSpaceSpecialResponseParser(Tpm::NV_UndefineSpaceSpecialResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31121 void NV_UndefineSpaceSpecialResponseParser(
31122     Tpm::NV_UndefineSpaceSpecialResponse callback,
31123     AuthorizationDelegate* authorization_delegate,
31124     const std::string& response) {
31125   VLOG(1) << __func__;
31126   TPM_RC rc = Tpm::ParseResponse_NV_UndefineSpaceSpecial(
31127       response, authorization_delegate);
31128   if (rc != TPM_RC_SUCCESS) {
31129     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
31130         NV_UndefineSpaceSpecialErrorCallback, std::move(callback));
31131     std::move(error_reporter).Run(rc);
31132     return;
31133   }
31134   std::move(callback).Run(rc);
31135 }
31136 
NV_UndefineSpaceSpecial(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_RH_PLATFORM & platform,const std::string & platform_name,AuthorizationDelegate * authorization_delegate,NV_UndefineSpaceSpecialResponse callback)31137 void Tpm::NV_UndefineSpaceSpecial(const TPMI_RH_NV_INDEX& nv_index,
31138                                   const std::string& nv_index_name,
31139                                   const TPMI_RH_PLATFORM& platform,
31140                                   const std::string& platform_name,
31141                                   AuthorizationDelegate* authorization_delegate,
31142                                   NV_UndefineSpaceSpecialResponse callback) {
31143   VLOG(1) << __func__;
31144   std::string command;
31145   TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial(
31146       nv_index, nv_index_name, platform, platform_name, &command,
31147       authorization_delegate);
31148   if (rc != TPM_RC_SUCCESS) {
31149     base::OnceCallback<void(TPM_RC)> error_reporter = base::BindOnce(
31150         NV_UndefineSpaceSpecialErrorCallback, std::move(callback));
31151     std::move(error_reporter).Run(rc);
31152     return;
31153   }
31154   base::OnceCallback<void(const std::string&)> parser =
31155       base::BindOnce(NV_UndefineSpaceSpecialResponseParser, std::move(callback),
31156                      authorization_delegate);
31157   transceiver_->SendCommand(command, std::move(parser));
31158 }
31159 
NV_UndefineSpaceSpecialSync(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPMI_RH_PLATFORM & platform,const std::string & platform_name,AuthorizationDelegate * authorization_delegate)31160 TPM_RC Tpm::NV_UndefineSpaceSpecialSync(
31161     const TPMI_RH_NV_INDEX& nv_index,
31162     const std::string& nv_index_name,
31163     const TPMI_RH_PLATFORM& platform,
31164     const std::string& platform_name,
31165     AuthorizationDelegate* authorization_delegate) {
31166   VLOG(1) << __func__;
31167   std::string command;
31168   TPM_RC rc = SerializeCommand_NV_UndefineSpaceSpecial(
31169       nv_index, nv_index_name, platform, platform_name, &command,
31170       authorization_delegate);
31171   if (rc != TPM_RC_SUCCESS) {
31172     return rc;
31173   }
31174   std::string response = transceiver_->SendCommandAndWait(command);
31175   rc = ParseResponse_NV_UndefineSpaceSpecial(response, authorization_delegate);
31176   return rc;
31177 }
31178 
SerializeCommand_NV_ReadPublic(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31179 TPM_RC Tpm::SerializeCommand_NV_ReadPublic(
31180     const TPMI_RH_NV_INDEX& nv_index,
31181     const std::string& nv_index_name,
31182     std::string* serialized_command,
31183     AuthorizationDelegate* authorization_delegate) {
31184   VLOG(3) << __func__;
31185   TPM_RC rc = TPM_RC_SUCCESS;
31186   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31187   UINT32 command_size = 10;  // Header size.
31188   std::string handle_section_bytes;
31189   std::string parameter_section_bytes;
31190   TPM_CC command_code = TPM_CC_NV_ReadPublic;
31191   bool is_command_parameter_encryption_possible = false;
31192   bool is_response_parameter_encryption_possible = true;
31193   std::string command_code_bytes;
31194   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31195   if (rc != TPM_RC_SUCCESS) {
31196     return rc;
31197   }
31198   std::string nv_index_bytes;
31199   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31200   if (rc != TPM_RC_SUCCESS) {
31201     return rc;
31202   }
31203   std::unique_ptr<crypto::SecureHash> hash(
31204       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31205   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31206   hash->Update(nv_index_name.data(), nv_index_name.size());
31207   handle_section_bytes += nv_index_bytes;
31208   command_size += nv_index_bytes.size();
31209   std::string command_hash(32, 0);
31210   hash->Finish(std::data(command_hash), command_hash.size());
31211   std::string authorization_section_bytes;
31212   std::string authorization_size_bytes;
31213   if (authorization_delegate) {
31214     if (!authorization_delegate->GetCommandAuthorization(
31215             command_hash, is_command_parameter_encryption_possible,
31216             is_response_parameter_encryption_possible,
31217             &authorization_section_bytes)) {
31218       return TRUNKS_RC_AUTHORIZATION_FAILED;
31219     }
31220     if (!authorization_section_bytes.empty()) {
31221       tag = TPM_ST_SESSIONS;
31222       std::string tmp;
31223       rc = Serialize_UINT32(authorization_section_bytes.size(),
31224                             &authorization_size_bytes);
31225       if (rc != TPM_RC_SUCCESS) {
31226         return rc;
31227       }
31228       command_size +=
31229           authorization_size_bytes.size() + authorization_section_bytes.size();
31230     }
31231   }
31232   std::string tag_bytes;
31233   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31234   if (rc != TPM_RC_SUCCESS) {
31235     return rc;
31236   }
31237   std::string command_size_bytes;
31238   rc = Serialize_UINT32(command_size, &command_size_bytes);
31239   if (rc != TPM_RC_SUCCESS) {
31240     return rc;
31241   }
31242   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31243                         handle_section_bytes + authorization_size_bytes +
31244                         authorization_section_bytes + parameter_section_bytes;
31245   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31246   VLOG(2) << "Command: "
31247           << base::HexEncode(serialized_command->data(),
31248                              serialized_command->size());
31249   return TPM_RC_SUCCESS;
31250 }
31251 
ParseResponse_NV_ReadPublic(const std::string & response,TPM2B_NV_PUBLIC * nv_public,TPM2B_NAME * nv_name,AuthorizationDelegate * authorization_delegate)31252 TPM_RC Tpm::ParseResponse_NV_ReadPublic(
31253     const std::string& response,
31254     TPM2B_NV_PUBLIC* nv_public,
31255     TPM2B_NAME* nv_name,
31256     AuthorizationDelegate* authorization_delegate) {
31257   VLOG(3) << __func__;
31258   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31259   TPM_RC rc = TPM_RC_SUCCESS;
31260   std::string buffer(response);
31261   TPM_ST tag;
31262   std::string tag_bytes;
31263   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31264   if (rc != TPM_RC_SUCCESS) {
31265     return rc;
31266   }
31267   UINT32 response_size;
31268   std::string response_size_bytes;
31269   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31270   if (rc != TPM_RC_SUCCESS) {
31271     return rc;
31272   }
31273   TPM_RC response_code;
31274   std::string response_code_bytes;
31275   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31276   if (rc != TPM_RC_SUCCESS) {
31277     return rc;
31278   }
31279   if (response_size != response.size()) {
31280     return TPM_RC_SIZE;
31281   }
31282   if (response_code != TPM_RC_SUCCESS) {
31283     return response_code;
31284   }
31285   TPM_CC command_code = TPM_CC_NV_ReadPublic;
31286   std::string command_code_bytes;
31287   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31288   if (rc != TPM_RC_SUCCESS) {
31289     return rc;
31290   }
31291   std::string authorization_section_bytes;
31292   if (tag == TPM_ST_SESSIONS) {
31293     UINT32 parameter_section_size = buffer.size();
31294     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31295     if (rc != TPM_RC_SUCCESS) {
31296       return rc;
31297     }
31298     if (parameter_section_size > buffer.size()) {
31299       return TPM_RC_INSUFFICIENT;
31300     }
31301     authorization_section_bytes = buffer.substr(parameter_section_size);
31302     // Keep the parameter section in |buffer|.
31303     buffer.erase(parameter_section_size);
31304   }
31305   std::unique_ptr<crypto::SecureHash> hash(
31306       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31307   hash->Update(response_code_bytes.data(), response_code_bytes.size());
31308   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31309   hash->Update(buffer.data(), buffer.size());
31310   std::string response_hash(32, 0);
31311   hash->Finish(std::data(response_hash), response_hash.size());
31312   if (tag == TPM_ST_SESSIONS) {
31313     if (!authorization_delegate)
31314       return TRUNKS_RC_AUTHORIZATION_FAILED;
31315     if (!authorization_delegate->CheckResponseAuthorization(
31316             response_hash, authorization_section_bytes)) {
31317       return TRUNKS_RC_AUTHORIZATION_FAILED;
31318     }
31319   }
31320   if (tag == TPM_ST_SESSIONS) {
31321     if (!authorization_delegate)
31322       return TRUNKS_RC_AUTHORIZATION_FAILED;
31323 
31324     // Parse the encrypted parameter size.
31325     UINT16 size;
31326     std::string size_buffer = buffer.substr(0, 2);
31327     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
31328       return result;
31329     }
31330     if (buffer.size() < 2 + size) {
31331       return TPM_RC_INSUFFICIENT;
31332     }
31333 
31334     // Decrypt just the parameter data, not the size.
31335     std::string decrypted_data = buffer.substr(2, size);
31336     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
31337       return TRUNKS_RC_ENCRYPTION_FAILED;
31338     }
31339     buffer.replace(2, size, decrypted_data);
31340   }
31341   std::string nv_public_bytes;
31342   rc = Parse_TPM2B_NV_PUBLIC(&buffer, nv_public, &nv_public_bytes);
31343   if (rc != TPM_RC_SUCCESS) {
31344     return rc;
31345   }
31346   std::string nv_name_bytes;
31347   rc = Parse_TPM2B_NAME(&buffer, nv_name, &nv_name_bytes);
31348   if (rc != TPM_RC_SUCCESS) {
31349     return rc;
31350   }
31351   return TPM_RC_SUCCESS;
31352 }
31353 
NV_ReadPublicErrorCallback(Tpm::NV_ReadPublicResponse callback,TPM_RC response_code)31354 void NV_ReadPublicErrorCallback(Tpm::NV_ReadPublicResponse callback,
31355                                 TPM_RC response_code) {
31356   VLOG(1) << __func__;
31357   std::move(callback).Run(response_code, TPM2B_NV_PUBLIC(), TPM2B_NAME());
31358 }
31359 
NV_ReadPublicResponseParser(Tpm::NV_ReadPublicResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31360 void NV_ReadPublicResponseParser(Tpm::NV_ReadPublicResponse callback,
31361                                  AuthorizationDelegate* authorization_delegate,
31362                                  const std::string& response) {
31363   VLOG(1) << __func__;
31364   TPM2B_NV_PUBLIC nv_public;
31365   TPM2B_NAME nv_name;
31366   TPM_RC rc = Tpm::ParseResponse_NV_ReadPublic(response, &nv_public, &nv_name,
31367                                                authorization_delegate);
31368   if (rc != TPM_RC_SUCCESS) {
31369     base::OnceCallback<void(TPM_RC)> error_reporter =
31370         base::BindOnce(NV_ReadPublicErrorCallback, std::move(callback));
31371     std::move(error_reporter).Run(rc);
31372     return;
31373   }
31374   std::move(callback).Run(rc, nv_public, nv_name);
31375 }
31376 
NV_ReadPublic(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_ReadPublicResponse callback)31377 void Tpm::NV_ReadPublic(const TPMI_RH_NV_INDEX& nv_index,
31378                         const std::string& nv_index_name,
31379                         AuthorizationDelegate* authorization_delegate,
31380                         NV_ReadPublicResponse callback) {
31381   VLOG(1) << __func__;
31382   std::string command;
31383   TPM_RC rc = SerializeCommand_NV_ReadPublic(nv_index, nv_index_name, &command,
31384                                              authorization_delegate);
31385   if (rc != TPM_RC_SUCCESS) {
31386     base::OnceCallback<void(TPM_RC)> error_reporter =
31387         base::BindOnce(NV_ReadPublicErrorCallback, std::move(callback));
31388     std::move(error_reporter).Run(rc);
31389     return;
31390   }
31391   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31392       NV_ReadPublicResponseParser, std::move(callback), authorization_delegate);
31393   transceiver_->SendCommand(command, std::move(parser));
31394 }
31395 
NV_ReadPublicSync(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,TPM2B_NV_PUBLIC * nv_public,TPM2B_NAME * nv_name,AuthorizationDelegate * authorization_delegate)31396 TPM_RC Tpm::NV_ReadPublicSync(const TPMI_RH_NV_INDEX& nv_index,
31397                               const std::string& nv_index_name,
31398                               TPM2B_NV_PUBLIC* nv_public,
31399                               TPM2B_NAME* nv_name,
31400                               AuthorizationDelegate* authorization_delegate) {
31401   VLOG(1) << __func__;
31402   std::string command;
31403   TPM_RC rc = SerializeCommand_NV_ReadPublic(nv_index, nv_index_name, &command,
31404                                              authorization_delegate);
31405   if (rc != TPM_RC_SUCCESS) {
31406     return rc;
31407   }
31408   std::string response = transceiver_->SendCommandAndWait(command);
31409   rc = ParseResponse_NV_ReadPublic(response, nv_public, nv_name,
31410                                    authorization_delegate);
31411   return rc;
31412 }
31413 
SerializeCommand_NV_Write(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,const UINT16 & offset,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31414 TPM_RC Tpm::SerializeCommand_NV_Write(
31415     const TPMI_RH_NV_AUTH& auth_handle,
31416     const std::string& auth_handle_name,
31417     const TPMI_RH_NV_INDEX& nv_index,
31418     const std::string& nv_index_name,
31419     const TPM2B_MAX_NV_BUFFER& data,
31420     const UINT16& offset,
31421     std::string* serialized_command,
31422     AuthorizationDelegate* authorization_delegate) {
31423   VLOG(3) << __func__;
31424   TPM_RC rc = TPM_RC_SUCCESS;
31425   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31426   UINT32 command_size = 10;  // Header size.
31427   std::string handle_section_bytes;
31428   std::string parameter_section_bytes;
31429   TPM_CC command_code = TPM_CC_NV_Write;
31430   bool is_command_parameter_encryption_possible = true;
31431   bool is_response_parameter_encryption_possible = false;
31432   std::string command_code_bytes;
31433   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31434   if (rc != TPM_RC_SUCCESS) {
31435     return rc;
31436   }
31437   std::string auth_handle_bytes;
31438   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31439   if (rc != TPM_RC_SUCCESS) {
31440     return rc;
31441   }
31442   std::string nv_index_bytes;
31443   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31444   if (rc != TPM_RC_SUCCESS) {
31445     return rc;
31446   }
31447   std::string data_bytes;
31448   rc = Serialize_TPM2B_MAX_NV_BUFFER(data, &data_bytes);
31449   if (rc != TPM_RC_SUCCESS) {
31450     return rc;
31451   }
31452   std::string offset_bytes;
31453   rc = Serialize_UINT16(offset, &offset_bytes);
31454   if (rc != TPM_RC_SUCCESS) {
31455     return rc;
31456   }
31457   if (authorization_delegate) {
31458     // Encrypt just the parameter data, not the size.
31459     std::string tmp = data_bytes.substr(2);
31460     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
31461       return TRUNKS_RC_ENCRYPTION_FAILED;
31462     }
31463     data_bytes.replace(2, std::string::npos, tmp);
31464   }
31465   std::unique_ptr<crypto::SecureHash> hash(
31466       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31467   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31468   hash->Update(auth_handle_name.data(), auth_handle_name.size());
31469   handle_section_bytes += auth_handle_bytes;
31470   command_size += auth_handle_bytes.size();
31471   hash->Update(nv_index_name.data(), nv_index_name.size());
31472   handle_section_bytes += nv_index_bytes;
31473   command_size += nv_index_bytes.size();
31474   hash->Update(data_bytes.data(), data_bytes.size());
31475   parameter_section_bytes += data_bytes;
31476   command_size += data_bytes.size();
31477   hash->Update(offset_bytes.data(), offset_bytes.size());
31478   parameter_section_bytes += offset_bytes;
31479   command_size += offset_bytes.size();
31480   std::string command_hash(32, 0);
31481   hash->Finish(std::data(command_hash), command_hash.size());
31482   std::string authorization_section_bytes;
31483   std::string authorization_size_bytes;
31484   if (authorization_delegate) {
31485     if (!authorization_delegate->GetCommandAuthorization(
31486             command_hash, is_command_parameter_encryption_possible,
31487             is_response_parameter_encryption_possible,
31488             &authorization_section_bytes)) {
31489       return TRUNKS_RC_AUTHORIZATION_FAILED;
31490     }
31491     if (!authorization_section_bytes.empty()) {
31492       tag = TPM_ST_SESSIONS;
31493       std::string tmp;
31494       rc = Serialize_UINT32(authorization_section_bytes.size(),
31495                             &authorization_size_bytes);
31496       if (rc != TPM_RC_SUCCESS) {
31497         return rc;
31498       }
31499       command_size +=
31500           authorization_size_bytes.size() + authorization_section_bytes.size();
31501     }
31502   }
31503   std::string tag_bytes;
31504   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31505   if (rc != TPM_RC_SUCCESS) {
31506     return rc;
31507   }
31508   std::string command_size_bytes;
31509   rc = Serialize_UINT32(command_size, &command_size_bytes);
31510   if (rc != TPM_RC_SUCCESS) {
31511     return rc;
31512   }
31513   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31514                         handle_section_bytes + authorization_size_bytes +
31515                         authorization_section_bytes + parameter_section_bytes;
31516   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31517   VLOG(2) << "Command: "
31518           << base::HexEncode(serialized_command->data(),
31519                              serialized_command->size());
31520   return TPM_RC_SUCCESS;
31521 }
31522 
ParseResponse_NV_Write(const std::string & response,AuthorizationDelegate * authorization_delegate)31523 TPM_RC Tpm::ParseResponse_NV_Write(
31524     const std::string& response,
31525     AuthorizationDelegate* authorization_delegate) {
31526   VLOG(3) << __func__;
31527   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31528   TPM_RC rc = TPM_RC_SUCCESS;
31529   std::string buffer(response);
31530   TPM_ST tag;
31531   std::string tag_bytes;
31532   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31533   if (rc != TPM_RC_SUCCESS) {
31534     return rc;
31535   }
31536   UINT32 response_size;
31537   std::string response_size_bytes;
31538   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31539   if (rc != TPM_RC_SUCCESS) {
31540     return rc;
31541   }
31542   TPM_RC response_code;
31543   std::string response_code_bytes;
31544   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31545   if (rc != TPM_RC_SUCCESS) {
31546     return rc;
31547   }
31548   if (response_size != response.size()) {
31549     return TPM_RC_SIZE;
31550   }
31551   if (response_code != TPM_RC_SUCCESS) {
31552     return response_code;
31553   }
31554   TPM_CC command_code = TPM_CC_NV_Write;
31555   std::string command_code_bytes;
31556   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31557   if (rc != TPM_RC_SUCCESS) {
31558     return rc;
31559   }
31560   std::string authorization_section_bytes;
31561   if (tag == TPM_ST_SESSIONS) {
31562     UINT32 parameter_section_size = buffer.size();
31563     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31564     if (rc != TPM_RC_SUCCESS) {
31565       return rc;
31566     }
31567     if (parameter_section_size > buffer.size()) {
31568       return TPM_RC_INSUFFICIENT;
31569     }
31570     authorization_section_bytes = buffer.substr(parameter_section_size);
31571     // Keep the parameter section in |buffer|.
31572     buffer.erase(parameter_section_size);
31573   }
31574   std::unique_ptr<crypto::SecureHash> hash(
31575       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31576   hash->Update(response_code_bytes.data(), response_code_bytes.size());
31577   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31578   hash->Update(buffer.data(), buffer.size());
31579   std::string response_hash(32, 0);
31580   hash->Finish(std::data(response_hash), response_hash.size());
31581   if (tag == TPM_ST_SESSIONS) {
31582     if (!authorization_delegate)
31583       return TRUNKS_RC_AUTHORIZATION_FAILED;
31584     if (!authorization_delegate->CheckResponseAuthorization(
31585             response_hash, authorization_section_bytes)) {
31586       return TRUNKS_RC_AUTHORIZATION_FAILED;
31587     }
31588   }
31589   return TPM_RC_SUCCESS;
31590 }
31591 
NV_WriteErrorCallback(Tpm::NV_WriteResponse callback,TPM_RC response_code)31592 void NV_WriteErrorCallback(Tpm::NV_WriteResponse callback,
31593                            TPM_RC response_code) {
31594   VLOG(1) << __func__;
31595   std::move(callback).Run(response_code);
31596 }
31597 
NV_WriteResponseParser(Tpm::NV_WriteResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31598 void NV_WriteResponseParser(Tpm::NV_WriteResponse callback,
31599                             AuthorizationDelegate* authorization_delegate,
31600                             const std::string& response) {
31601   VLOG(1) << __func__;
31602   TPM_RC rc = Tpm::ParseResponse_NV_Write(response, authorization_delegate);
31603   if (rc != TPM_RC_SUCCESS) {
31604     base::OnceCallback<void(TPM_RC)> error_reporter =
31605         base::BindOnce(NV_WriteErrorCallback, std::move(callback));
31606     std::move(error_reporter).Run(rc);
31607     return;
31608   }
31609   std::move(callback).Run(rc);
31610 }
31611 
NV_Write(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,const UINT16 & offset,AuthorizationDelegate * authorization_delegate,NV_WriteResponse callback)31612 void Tpm::NV_Write(const TPMI_RH_NV_AUTH& auth_handle,
31613                    const std::string& auth_handle_name,
31614                    const TPMI_RH_NV_INDEX& nv_index,
31615                    const std::string& nv_index_name,
31616                    const TPM2B_MAX_NV_BUFFER& data,
31617                    const UINT16& offset,
31618                    AuthorizationDelegate* authorization_delegate,
31619                    NV_WriteResponse callback) {
31620   VLOG(1) << __func__;
31621   std::string command;
31622   TPM_RC rc = SerializeCommand_NV_Write(auth_handle, auth_handle_name, nv_index,
31623                                         nv_index_name, data, offset, &command,
31624                                         authorization_delegate);
31625   if (rc != TPM_RC_SUCCESS) {
31626     base::OnceCallback<void(TPM_RC)> error_reporter =
31627         base::BindOnce(NV_WriteErrorCallback, std::move(callback));
31628     std::move(error_reporter).Run(rc);
31629     return;
31630   }
31631   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31632       NV_WriteResponseParser, std::move(callback), authorization_delegate);
31633   transceiver_->SendCommand(command, std::move(parser));
31634 }
31635 
NV_WriteSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,const UINT16 & offset,AuthorizationDelegate * authorization_delegate)31636 TPM_RC Tpm::NV_WriteSync(const TPMI_RH_NV_AUTH& auth_handle,
31637                          const std::string& auth_handle_name,
31638                          const TPMI_RH_NV_INDEX& nv_index,
31639                          const std::string& nv_index_name,
31640                          const TPM2B_MAX_NV_BUFFER& data,
31641                          const UINT16& offset,
31642                          AuthorizationDelegate* authorization_delegate) {
31643   VLOG(1) << __func__;
31644   std::string command;
31645   TPM_RC rc = SerializeCommand_NV_Write(auth_handle, auth_handle_name, nv_index,
31646                                         nv_index_name, data, offset, &command,
31647                                         authorization_delegate);
31648   if (rc != TPM_RC_SUCCESS) {
31649     return rc;
31650   }
31651   std::string response = transceiver_->SendCommandAndWait(command);
31652   rc = ParseResponse_NV_Write(response, authorization_delegate);
31653   return rc;
31654 }
31655 
SerializeCommand_NV_Increment(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31656 TPM_RC Tpm::SerializeCommand_NV_Increment(
31657     const TPMI_RH_NV_AUTH& auth_handle,
31658     const std::string& auth_handle_name,
31659     const TPMI_RH_NV_INDEX& nv_index,
31660     const std::string& nv_index_name,
31661     std::string* serialized_command,
31662     AuthorizationDelegate* authorization_delegate) {
31663   VLOG(3) << __func__;
31664   TPM_RC rc = TPM_RC_SUCCESS;
31665   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31666   UINT32 command_size = 10;  // Header size.
31667   std::string handle_section_bytes;
31668   std::string parameter_section_bytes;
31669   TPM_CC command_code = TPM_CC_NV_Increment;
31670   bool is_command_parameter_encryption_possible = false;
31671   bool is_response_parameter_encryption_possible = false;
31672   std::string command_code_bytes;
31673   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31674   if (rc != TPM_RC_SUCCESS) {
31675     return rc;
31676   }
31677   std::string auth_handle_bytes;
31678   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31679   if (rc != TPM_RC_SUCCESS) {
31680     return rc;
31681   }
31682   std::string nv_index_bytes;
31683   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31684   if (rc != TPM_RC_SUCCESS) {
31685     return rc;
31686   }
31687   std::unique_ptr<crypto::SecureHash> hash(
31688       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31689   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31690   hash->Update(auth_handle_name.data(), auth_handle_name.size());
31691   handle_section_bytes += auth_handle_bytes;
31692   command_size += auth_handle_bytes.size();
31693   hash->Update(nv_index_name.data(), nv_index_name.size());
31694   handle_section_bytes += nv_index_bytes;
31695   command_size += nv_index_bytes.size();
31696   std::string command_hash(32, 0);
31697   hash->Finish(std::data(command_hash), command_hash.size());
31698   std::string authorization_section_bytes;
31699   std::string authorization_size_bytes;
31700   if (authorization_delegate) {
31701     if (!authorization_delegate->GetCommandAuthorization(
31702             command_hash, is_command_parameter_encryption_possible,
31703             is_response_parameter_encryption_possible,
31704             &authorization_section_bytes)) {
31705       return TRUNKS_RC_AUTHORIZATION_FAILED;
31706     }
31707     if (!authorization_section_bytes.empty()) {
31708       tag = TPM_ST_SESSIONS;
31709       std::string tmp;
31710       rc = Serialize_UINT32(authorization_section_bytes.size(),
31711                             &authorization_size_bytes);
31712       if (rc != TPM_RC_SUCCESS) {
31713         return rc;
31714       }
31715       command_size +=
31716           authorization_size_bytes.size() + authorization_section_bytes.size();
31717     }
31718   }
31719   std::string tag_bytes;
31720   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31721   if (rc != TPM_RC_SUCCESS) {
31722     return rc;
31723   }
31724   std::string command_size_bytes;
31725   rc = Serialize_UINT32(command_size, &command_size_bytes);
31726   if (rc != TPM_RC_SUCCESS) {
31727     return rc;
31728   }
31729   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31730                         handle_section_bytes + authorization_size_bytes +
31731                         authorization_section_bytes + parameter_section_bytes;
31732   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31733   VLOG(2) << "Command: "
31734           << base::HexEncode(serialized_command->data(),
31735                              serialized_command->size());
31736   return TPM_RC_SUCCESS;
31737 }
31738 
ParseResponse_NV_Increment(const std::string & response,AuthorizationDelegate * authorization_delegate)31739 TPM_RC Tpm::ParseResponse_NV_Increment(
31740     const std::string& response,
31741     AuthorizationDelegate* authorization_delegate) {
31742   VLOG(3) << __func__;
31743   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31744   TPM_RC rc = TPM_RC_SUCCESS;
31745   std::string buffer(response);
31746   TPM_ST tag;
31747   std::string tag_bytes;
31748   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31749   if (rc != TPM_RC_SUCCESS) {
31750     return rc;
31751   }
31752   UINT32 response_size;
31753   std::string response_size_bytes;
31754   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31755   if (rc != TPM_RC_SUCCESS) {
31756     return rc;
31757   }
31758   TPM_RC response_code;
31759   std::string response_code_bytes;
31760   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31761   if (rc != TPM_RC_SUCCESS) {
31762     return rc;
31763   }
31764   if (response_size != response.size()) {
31765     return TPM_RC_SIZE;
31766   }
31767   if (response_code != TPM_RC_SUCCESS) {
31768     return response_code;
31769   }
31770   TPM_CC command_code = TPM_CC_NV_Increment;
31771   std::string command_code_bytes;
31772   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31773   if (rc != TPM_RC_SUCCESS) {
31774     return rc;
31775   }
31776   std::string authorization_section_bytes;
31777   if (tag == TPM_ST_SESSIONS) {
31778     UINT32 parameter_section_size = buffer.size();
31779     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
31780     if (rc != TPM_RC_SUCCESS) {
31781       return rc;
31782     }
31783     if (parameter_section_size > buffer.size()) {
31784       return TPM_RC_INSUFFICIENT;
31785     }
31786     authorization_section_bytes = buffer.substr(parameter_section_size);
31787     // Keep the parameter section in |buffer|.
31788     buffer.erase(parameter_section_size);
31789   }
31790   std::unique_ptr<crypto::SecureHash> hash(
31791       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31792   hash->Update(response_code_bytes.data(), response_code_bytes.size());
31793   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31794   hash->Update(buffer.data(), buffer.size());
31795   std::string response_hash(32, 0);
31796   hash->Finish(std::data(response_hash), response_hash.size());
31797   if (tag == TPM_ST_SESSIONS) {
31798     if (!authorization_delegate)
31799       return TRUNKS_RC_AUTHORIZATION_FAILED;
31800     if (!authorization_delegate->CheckResponseAuthorization(
31801             response_hash, authorization_section_bytes)) {
31802       return TRUNKS_RC_AUTHORIZATION_FAILED;
31803     }
31804   }
31805   return TPM_RC_SUCCESS;
31806 }
31807 
NV_IncrementErrorCallback(Tpm::NV_IncrementResponse callback,TPM_RC response_code)31808 void NV_IncrementErrorCallback(Tpm::NV_IncrementResponse callback,
31809                                TPM_RC response_code) {
31810   VLOG(1) << __func__;
31811   std::move(callback).Run(response_code);
31812 }
31813 
NV_IncrementResponseParser(Tpm::NV_IncrementResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)31814 void NV_IncrementResponseParser(Tpm::NV_IncrementResponse callback,
31815                                 AuthorizationDelegate* authorization_delegate,
31816                                 const std::string& response) {
31817   VLOG(1) << __func__;
31818   TPM_RC rc = Tpm::ParseResponse_NV_Increment(response, authorization_delegate);
31819   if (rc != TPM_RC_SUCCESS) {
31820     base::OnceCallback<void(TPM_RC)> error_reporter =
31821         base::BindOnce(NV_IncrementErrorCallback, std::move(callback));
31822     std::move(error_reporter).Run(rc);
31823     return;
31824   }
31825   std::move(callback).Run(rc);
31826 }
31827 
NV_Increment(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_IncrementResponse callback)31828 void Tpm::NV_Increment(const TPMI_RH_NV_AUTH& auth_handle,
31829                        const std::string& auth_handle_name,
31830                        const TPMI_RH_NV_INDEX& nv_index,
31831                        const std::string& nv_index_name,
31832                        AuthorizationDelegate* authorization_delegate,
31833                        NV_IncrementResponse callback) {
31834   VLOG(1) << __func__;
31835   std::string command;
31836   TPM_RC rc = SerializeCommand_NV_Increment(auth_handle, auth_handle_name,
31837                                             nv_index, nv_index_name, &command,
31838                                             authorization_delegate);
31839   if (rc != TPM_RC_SUCCESS) {
31840     base::OnceCallback<void(TPM_RC)> error_reporter =
31841         base::BindOnce(NV_IncrementErrorCallback, std::move(callback));
31842     std::move(error_reporter).Run(rc);
31843     return;
31844   }
31845   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
31846       NV_IncrementResponseParser, std::move(callback), authorization_delegate);
31847   transceiver_->SendCommand(command, std::move(parser));
31848 }
31849 
NV_IncrementSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)31850 TPM_RC Tpm::NV_IncrementSync(const TPMI_RH_NV_AUTH& auth_handle,
31851                              const std::string& auth_handle_name,
31852                              const TPMI_RH_NV_INDEX& nv_index,
31853                              const std::string& nv_index_name,
31854                              AuthorizationDelegate* authorization_delegate) {
31855   VLOG(1) << __func__;
31856   std::string command;
31857   TPM_RC rc = SerializeCommand_NV_Increment(auth_handle, auth_handle_name,
31858                                             nv_index, nv_index_name, &command,
31859                                             authorization_delegate);
31860   if (rc != TPM_RC_SUCCESS) {
31861     return rc;
31862   }
31863   std::string response = transceiver_->SendCommandAndWait(command);
31864   rc = ParseResponse_NV_Increment(response, authorization_delegate);
31865   return rc;
31866 }
31867 
SerializeCommand_NV_Extend(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)31868 TPM_RC Tpm::SerializeCommand_NV_Extend(
31869     const TPMI_RH_NV_AUTH& auth_handle,
31870     const std::string& auth_handle_name,
31871     const TPMI_RH_NV_INDEX& nv_index,
31872     const std::string& nv_index_name,
31873     const TPM2B_MAX_NV_BUFFER& data,
31874     std::string* serialized_command,
31875     AuthorizationDelegate* authorization_delegate) {
31876   VLOG(3) << __func__;
31877   TPM_RC rc = TPM_RC_SUCCESS;
31878   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
31879   UINT32 command_size = 10;  // Header size.
31880   std::string handle_section_bytes;
31881   std::string parameter_section_bytes;
31882   TPM_CC command_code = TPM_CC_NV_Extend;
31883   bool is_command_parameter_encryption_possible = true;
31884   bool is_response_parameter_encryption_possible = false;
31885   std::string command_code_bytes;
31886   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
31887   if (rc != TPM_RC_SUCCESS) {
31888     return rc;
31889   }
31890   std::string auth_handle_bytes;
31891   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
31892   if (rc != TPM_RC_SUCCESS) {
31893     return rc;
31894   }
31895   std::string nv_index_bytes;
31896   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
31897   if (rc != TPM_RC_SUCCESS) {
31898     return rc;
31899   }
31900   std::string data_bytes;
31901   rc = Serialize_TPM2B_MAX_NV_BUFFER(data, &data_bytes);
31902   if (rc != TPM_RC_SUCCESS) {
31903     return rc;
31904   }
31905   if (authorization_delegate) {
31906     // Encrypt just the parameter data, not the size.
31907     std::string tmp = data_bytes.substr(2);
31908     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
31909       return TRUNKS_RC_ENCRYPTION_FAILED;
31910     }
31911     data_bytes.replace(2, std::string::npos, tmp);
31912   }
31913   std::unique_ptr<crypto::SecureHash> hash(
31914       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
31915   hash->Update(command_code_bytes.data(), command_code_bytes.size());
31916   hash->Update(auth_handle_name.data(), auth_handle_name.size());
31917   handle_section_bytes += auth_handle_bytes;
31918   command_size += auth_handle_bytes.size();
31919   hash->Update(nv_index_name.data(), nv_index_name.size());
31920   handle_section_bytes += nv_index_bytes;
31921   command_size += nv_index_bytes.size();
31922   hash->Update(data_bytes.data(), data_bytes.size());
31923   parameter_section_bytes += data_bytes;
31924   command_size += data_bytes.size();
31925   std::string command_hash(32, 0);
31926   hash->Finish(std::data(command_hash), command_hash.size());
31927   std::string authorization_section_bytes;
31928   std::string authorization_size_bytes;
31929   if (authorization_delegate) {
31930     if (!authorization_delegate->GetCommandAuthorization(
31931             command_hash, is_command_parameter_encryption_possible,
31932             is_response_parameter_encryption_possible,
31933             &authorization_section_bytes)) {
31934       return TRUNKS_RC_AUTHORIZATION_FAILED;
31935     }
31936     if (!authorization_section_bytes.empty()) {
31937       tag = TPM_ST_SESSIONS;
31938       std::string tmp;
31939       rc = Serialize_UINT32(authorization_section_bytes.size(),
31940                             &authorization_size_bytes);
31941       if (rc != TPM_RC_SUCCESS) {
31942         return rc;
31943       }
31944       command_size +=
31945           authorization_size_bytes.size() + authorization_section_bytes.size();
31946     }
31947   }
31948   std::string tag_bytes;
31949   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
31950   if (rc != TPM_RC_SUCCESS) {
31951     return rc;
31952   }
31953   std::string command_size_bytes;
31954   rc = Serialize_UINT32(command_size, &command_size_bytes);
31955   if (rc != TPM_RC_SUCCESS) {
31956     return rc;
31957   }
31958   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
31959                         handle_section_bytes + authorization_size_bytes +
31960                         authorization_section_bytes + parameter_section_bytes;
31961   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
31962   VLOG(2) << "Command: "
31963           << base::HexEncode(serialized_command->data(),
31964                              serialized_command->size());
31965   return TPM_RC_SUCCESS;
31966 }
31967 
ParseResponse_NV_Extend(const std::string & response,AuthorizationDelegate * authorization_delegate)31968 TPM_RC Tpm::ParseResponse_NV_Extend(
31969     const std::string& response,
31970     AuthorizationDelegate* authorization_delegate) {
31971   VLOG(3) << __func__;
31972   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
31973   TPM_RC rc = TPM_RC_SUCCESS;
31974   std::string buffer(response);
31975   TPM_ST tag;
31976   std::string tag_bytes;
31977   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
31978   if (rc != TPM_RC_SUCCESS) {
31979     return rc;
31980   }
31981   UINT32 response_size;
31982   std::string response_size_bytes;
31983   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
31984   if (rc != TPM_RC_SUCCESS) {
31985     return rc;
31986   }
31987   TPM_RC response_code;
31988   std::string response_code_bytes;
31989   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
31990   if (rc != TPM_RC_SUCCESS) {
31991     return rc;
31992   }
31993   if (response_size != response.size()) {
31994     return TPM_RC_SIZE;
31995   }
31996   if (response_code != TPM_RC_SUCCESS) {
31997     return response_code;
31998   }
31999   TPM_CC command_code = TPM_CC_NV_Extend;
32000   std::string command_code_bytes;
32001   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32002   if (rc != TPM_RC_SUCCESS) {
32003     return rc;
32004   }
32005   std::string authorization_section_bytes;
32006   if (tag == TPM_ST_SESSIONS) {
32007     UINT32 parameter_section_size = buffer.size();
32008     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32009     if (rc != TPM_RC_SUCCESS) {
32010       return rc;
32011     }
32012     if (parameter_section_size > buffer.size()) {
32013       return TPM_RC_INSUFFICIENT;
32014     }
32015     authorization_section_bytes = buffer.substr(parameter_section_size);
32016     // Keep the parameter section in |buffer|.
32017     buffer.erase(parameter_section_size);
32018   }
32019   std::unique_ptr<crypto::SecureHash> hash(
32020       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32021   hash->Update(response_code_bytes.data(), response_code_bytes.size());
32022   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32023   hash->Update(buffer.data(), buffer.size());
32024   std::string response_hash(32, 0);
32025   hash->Finish(std::data(response_hash), response_hash.size());
32026   if (tag == TPM_ST_SESSIONS) {
32027     if (!authorization_delegate)
32028       return TRUNKS_RC_AUTHORIZATION_FAILED;
32029     if (!authorization_delegate->CheckResponseAuthorization(
32030             response_hash, authorization_section_bytes)) {
32031       return TRUNKS_RC_AUTHORIZATION_FAILED;
32032     }
32033   }
32034   return TPM_RC_SUCCESS;
32035 }
32036 
NV_ExtendErrorCallback(Tpm::NV_ExtendResponse callback,TPM_RC response_code)32037 void NV_ExtendErrorCallback(Tpm::NV_ExtendResponse callback,
32038                             TPM_RC response_code) {
32039   VLOG(1) << __func__;
32040   std::move(callback).Run(response_code);
32041 }
32042 
NV_ExtendResponseParser(Tpm::NV_ExtendResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32043 void NV_ExtendResponseParser(Tpm::NV_ExtendResponse callback,
32044                              AuthorizationDelegate* authorization_delegate,
32045                              const std::string& response) {
32046   VLOG(1) << __func__;
32047   TPM_RC rc = Tpm::ParseResponse_NV_Extend(response, authorization_delegate);
32048   if (rc != TPM_RC_SUCCESS) {
32049     base::OnceCallback<void(TPM_RC)> error_reporter =
32050         base::BindOnce(NV_ExtendErrorCallback, std::move(callback));
32051     std::move(error_reporter).Run(rc);
32052     return;
32053   }
32054   std::move(callback).Run(rc);
32055 }
32056 
NV_Extend(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,AuthorizationDelegate * authorization_delegate,NV_ExtendResponse callback)32057 void Tpm::NV_Extend(const TPMI_RH_NV_AUTH& auth_handle,
32058                     const std::string& auth_handle_name,
32059                     const TPMI_RH_NV_INDEX& nv_index,
32060                     const std::string& nv_index_name,
32061                     const TPM2B_MAX_NV_BUFFER& data,
32062                     AuthorizationDelegate* authorization_delegate,
32063                     NV_ExtendResponse callback) {
32064   VLOG(1) << __func__;
32065   std::string command;
32066   TPM_RC rc = SerializeCommand_NV_Extend(auth_handle, auth_handle_name,
32067                                          nv_index, nv_index_name, data,
32068                                          &command, authorization_delegate);
32069   if (rc != TPM_RC_SUCCESS) {
32070     base::OnceCallback<void(TPM_RC)> error_reporter =
32071         base::BindOnce(NV_ExtendErrorCallback, std::move(callback));
32072     std::move(error_reporter).Run(rc);
32073     return;
32074   }
32075   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32076       NV_ExtendResponseParser, std::move(callback), authorization_delegate);
32077   transceiver_->SendCommand(command, std::move(parser));
32078 }
32079 
NV_ExtendSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_MAX_NV_BUFFER & data,AuthorizationDelegate * authorization_delegate)32080 TPM_RC Tpm::NV_ExtendSync(const TPMI_RH_NV_AUTH& auth_handle,
32081                           const std::string& auth_handle_name,
32082                           const TPMI_RH_NV_INDEX& nv_index,
32083                           const std::string& nv_index_name,
32084                           const TPM2B_MAX_NV_BUFFER& data,
32085                           AuthorizationDelegate* authorization_delegate) {
32086   VLOG(1) << __func__;
32087   std::string command;
32088   TPM_RC rc = SerializeCommand_NV_Extend(auth_handle, auth_handle_name,
32089                                          nv_index, nv_index_name, data,
32090                                          &command, authorization_delegate);
32091   if (rc != TPM_RC_SUCCESS) {
32092     return rc;
32093   }
32094   std::string response = transceiver_->SendCommandAndWait(command);
32095   rc = ParseResponse_NV_Extend(response, authorization_delegate);
32096   return rc;
32097 }
32098 
SerializeCommand_NV_SetBits(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT64 & bits,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32099 TPM_RC Tpm::SerializeCommand_NV_SetBits(
32100     const TPMI_RH_NV_AUTH& auth_handle,
32101     const std::string& auth_handle_name,
32102     const TPMI_RH_NV_INDEX& nv_index,
32103     const std::string& nv_index_name,
32104     const UINT64& bits,
32105     std::string* serialized_command,
32106     AuthorizationDelegate* authorization_delegate) {
32107   VLOG(3) << __func__;
32108   TPM_RC rc = TPM_RC_SUCCESS;
32109   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32110   UINT32 command_size = 10;  // Header size.
32111   std::string handle_section_bytes;
32112   std::string parameter_section_bytes;
32113   TPM_CC command_code = TPM_CC_NV_SetBits;
32114   bool is_command_parameter_encryption_possible = false;
32115   bool is_response_parameter_encryption_possible = false;
32116   std::string command_code_bytes;
32117   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32118   if (rc != TPM_RC_SUCCESS) {
32119     return rc;
32120   }
32121   std::string auth_handle_bytes;
32122   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32123   if (rc != TPM_RC_SUCCESS) {
32124     return rc;
32125   }
32126   std::string nv_index_bytes;
32127   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32128   if (rc != TPM_RC_SUCCESS) {
32129     return rc;
32130   }
32131   std::string bits_bytes;
32132   rc = Serialize_UINT64(bits, &bits_bytes);
32133   if (rc != TPM_RC_SUCCESS) {
32134     return rc;
32135   }
32136   std::unique_ptr<crypto::SecureHash> hash(
32137       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32138   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32139   hash->Update(auth_handle_name.data(), auth_handle_name.size());
32140   handle_section_bytes += auth_handle_bytes;
32141   command_size += auth_handle_bytes.size();
32142   hash->Update(nv_index_name.data(), nv_index_name.size());
32143   handle_section_bytes += nv_index_bytes;
32144   command_size += nv_index_bytes.size();
32145   hash->Update(bits_bytes.data(), bits_bytes.size());
32146   parameter_section_bytes += bits_bytes;
32147   command_size += bits_bytes.size();
32148   std::string command_hash(32, 0);
32149   hash->Finish(std::data(command_hash), command_hash.size());
32150   std::string authorization_section_bytes;
32151   std::string authorization_size_bytes;
32152   if (authorization_delegate) {
32153     if (!authorization_delegate->GetCommandAuthorization(
32154             command_hash, is_command_parameter_encryption_possible,
32155             is_response_parameter_encryption_possible,
32156             &authorization_section_bytes)) {
32157       return TRUNKS_RC_AUTHORIZATION_FAILED;
32158     }
32159     if (!authorization_section_bytes.empty()) {
32160       tag = TPM_ST_SESSIONS;
32161       std::string tmp;
32162       rc = Serialize_UINT32(authorization_section_bytes.size(),
32163                             &authorization_size_bytes);
32164       if (rc != TPM_RC_SUCCESS) {
32165         return rc;
32166       }
32167       command_size +=
32168           authorization_size_bytes.size() + authorization_section_bytes.size();
32169     }
32170   }
32171   std::string tag_bytes;
32172   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32173   if (rc != TPM_RC_SUCCESS) {
32174     return rc;
32175   }
32176   std::string command_size_bytes;
32177   rc = Serialize_UINT32(command_size, &command_size_bytes);
32178   if (rc != TPM_RC_SUCCESS) {
32179     return rc;
32180   }
32181   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32182                         handle_section_bytes + authorization_size_bytes +
32183                         authorization_section_bytes + parameter_section_bytes;
32184   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32185   VLOG(2) << "Command: "
32186           << base::HexEncode(serialized_command->data(),
32187                              serialized_command->size());
32188   return TPM_RC_SUCCESS;
32189 }
32190 
ParseResponse_NV_SetBits(const std::string & response,AuthorizationDelegate * authorization_delegate)32191 TPM_RC Tpm::ParseResponse_NV_SetBits(
32192     const std::string& response,
32193     AuthorizationDelegate* authorization_delegate) {
32194   VLOG(3) << __func__;
32195   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32196   TPM_RC rc = TPM_RC_SUCCESS;
32197   std::string buffer(response);
32198   TPM_ST tag;
32199   std::string tag_bytes;
32200   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32201   if (rc != TPM_RC_SUCCESS) {
32202     return rc;
32203   }
32204   UINT32 response_size;
32205   std::string response_size_bytes;
32206   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32207   if (rc != TPM_RC_SUCCESS) {
32208     return rc;
32209   }
32210   TPM_RC response_code;
32211   std::string response_code_bytes;
32212   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32213   if (rc != TPM_RC_SUCCESS) {
32214     return rc;
32215   }
32216   if (response_size != response.size()) {
32217     return TPM_RC_SIZE;
32218   }
32219   if (response_code != TPM_RC_SUCCESS) {
32220     return response_code;
32221   }
32222   TPM_CC command_code = TPM_CC_NV_SetBits;
32223   std::string command_code_bytes;
32224   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32225   if (rc != TPM_RC_SUCCESS) {
32226     return rc;
32227   }
32228   std::string authorization_section_bytes;
32229   if (tag == TPM_ST_SESSIONS) {
32230     UINT32 parameter_section_size = buffer.size();
32231     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32232     if (rc != TPM_RC_SUCCESS) {
32233       return rc;
32234     }
32235     if (parameter_section_size > buffer.size()) {
32236       return TPM_RC_INSUFFICIENT;
32237     }
32238     authorization_section_bytes = buffer.substr(parameter_section_size);
32239     // Keep the parameter section in |buffer|.
32240     buffer.erase(parameter_section_size);
32241   }
32242   std::unique_ptr<crypto::SecureHash> hash(
32243       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32244   hash->Update(response_code_bytes.data(), response_code_bytes.size());
32245   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32246   hash->Update(buffer.data(), buffer.size());
32247   std::string response_hash(32, 0);
32248   hash->Finish(std::data(response_hash), response_hash.size());
32249   if (tag == TPM_ST_SESSIONS) {
32250     if (!authorization_delegate)
32251       return TRUNKS_RC_AUTHORIZATION_FAILED;
32252     if (!authorization_delegate->CheckResponseAuthorization(
32253             response_hash, authorization_section_bytes)) {
32254       return TRUNKS_RC_AUTHORIZATION_FAILED;
32255     }
32256   }
32257   return TPM_RC_SUCCESS;
32258 }
32259 
NV_SetBitsErrorCallback(Tpm::NV_SetBitsResponse callback,TPM_RC response_code)32260 void NV_SetBitsErrorCallback(Tpm::NV_SetBitsResponse callback,
32261                              TPM_RC response_code) {
32262   VLOG(1) << __func__;
32263   std::move(callback).Run(response_code);
32264 }
32265 
NV_SetBitsResponseParser(Tpm::NV_SetBitsResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32266 void NV_SetBitsResponseParser(Tpm::NV_SetBitsResponse callback,
32267                               AuthorizationDelegate* authorization_delegate,
32268                               const std::string& response) {
32269   VLOG(1) << __func__;
32270   TPM_RC rc = Tpm::ParseResponse_NV_SetBits(response, authorization_delegate);
32271   if (rc != TPM_RC_SUCCESS) {
32272     base::OnceCallback<void(TPM_RC)> error_reporter =
32273         base::BindOnce(NV_SetBitsErrorCallback, std::move(callback));
32274     std::move(error_reporter).Run(rc);
32275     return;
32276   }
32277   std::move(callback).Run(rc);
32278 }
32279 
NV_SetBits(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT64 & bits,AuthorizationDelegate * authorization_delegate,NV_SetBitsResponse callback)32280 void Tpm::NV_SetBits(const TPMI_RH_NV_AUTH& auth_handle,
32281                      const std::string& auth_handle_name,
32282                      const TPMI_RH_NV_INDEX& nv_index,
32283                      const std::string& nv_index_name,
32284                      const UINT64& bits,
32285                      AuthorizationDelegate* authorization_delegate,
32286                      NV_SetBitsResponse callback) {
32287   VLOG(1) << __func__;
32288   std::string command;
32289   TPM_RC rc = SerializeCommand_NV_SetBits(auth_handle, auth_handle_name,
32290                                           nv_index, nv_index_name, bits,
32291                                           &command, authorization_delegate);
32292   if (rc != TPM_RC_SUCCESS) {
32293     base::OnceCallback<void(TPM_RC)> error_reporter =
32294         base::BindOnce(NV_SetBitsErrorCallback, std::move(callback));
32295     std::move(error_reporter).Run(rc);
32296     return;
32297   }
32298   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32299       NV_SetBitsResponseParser, std::move(callback), authorization_delegate);
32300   transceiver_->SendCommand(command, std::move(parser));
32301 }
32302 
NV_SetBitsSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT64 & bits,AuthorizationDelegate * authorization_delegate)32303 TPM_RC Tpm::NV_SetBitsSync(const TPMI_RH_NV_AUTH& auth_handle,
32304                            const std::string& auth_handle_name,
32305                            const TPMI_RH_NV_INDEX& nv_index,
32306                            const std::string& nv_index_name,
32307                            const UINT64& bits,
32308                            AuthorizationDelegate* authorization_delegate) {
32309   VLOG(1) << __func__;
32310   std::string command;
32311   TPM_RC rc = SerializeCommand_NV_SetBits(auth_handle, auth_handle_name,
32312                                           nv_index, nv_index_name, bits,
32313                                           &command, authorization_delegate);
32314   if (rc != TPM_RC_SUCCESS) {
32315     return rc;
32316   }
32317   std::string response = transceiver_->SendCommandAndWait(command);
32318   rc = ParseResponse_NV_SetBits(response, authorization_delegate);
32319   return rc;
32320 }
32321 
SerializeCommand_NV_WriteLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32322 TPM_RC Tpm::SerializeCommand_NV_WriteLock(
32323     const TPMI_RH_NV_AUTH& auth_handle,
32324     const std::string& auth_handle_name,
32325     const TPMI_RH_NV_INDEX& nv_index,
32326     const std::string& nv_index_name,
32327     std::string* serialized_command,
32328     AuthorizationDelegate* authorization_delegate) {
32329   VLOG(3) << __func__;
32330   TPM_RC rc = TPM_RC_SUCCESS;
32331   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32332   UINT32 command_size = 10;  // Header size.
32333   std::string handle_section_bytes;
32334   std::string parameter_section_bytes;
32335   TPM_CC command_code = TPM_CC_NV_WriteLock;
32336   bool is_command_parameter_encryption_possible = false;
32337   bool is_response_parameter_encryption_possible = false;
32338   std::string command_code_bytes;
32339   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32340   if (rc != TPM_RC_SUCCESS) {
32341     return rc;
32342   }
32343   std::string auth_handle_bytes;
32344   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32345   if (rc != TPM_RC_SUCCESS) {
32346     return rc;
32347   }
32348   std::string nv_index_bytes;
32349   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32350   if (rc != TPM_RC_SUCCESS) {
32351     return rc;
32352   }
32353   std::unique_ptr<crypto::SecureHash> hash(
32354       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32355   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32356   hash->Update(auth_handle_name.data(), auth_handle_name.size());
32357   handle_section_bytes += auth_handle_bytes;
32358   command_size += auth_handle_bytes.size();
32359   hash->Update(nv_index_name.data(), nv_index_name.size());
32360   handle_section_bytes += nv_index_bytes;
32361   command_size += nv_index_bytes.size();
32362   std::string command_hash(32, 0);
32363   hash->Finish(std::data(command_hash), command_hash.size());
32364   std::string authorization_section_bytes;
32365   std::string authorization_size_bytes;
32366   if (authorization_delegate) {
32367     if (!authorization_delegate->GetCommandAuthorization(
32368             command_hash, is_command_parameter_encryption_possible,
32369             is_response_parameter_encryption_possible,
32370             &authorization_section_bytes)) {
32371       return TRUNKS_RC_AUTHORIZATION_FAILED;
32372     }
32373     if (!authorization_section_bytes.empty()) {
32374       tag = TPM_ST_SESSIONS;
32375       std::string tmp;
32376       rc = Serialize_UINT32(authorization_section_bytes.size(),
32377                             &authorization_size_bytes);
32378       if (rc != TPM_RC_SUCCESS) {
32379         return rc;
32380       }
32381       command_size +=
32382           authorization_size_bytes.size() + authorization_section_bytes.size();
32383     }
32384   }
32385   std::string tag_bytes;
32386   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32387   if (rc != TPM_RC_SUCCESS) {
32388     return rc;
32389   }
32390   std::string command_size_bytes;
32391   rc = Serialize_UINT32(command_size, &command_size_bytes);
32392   if (rc != TPM_RC_SUCCESS) {
32393     return rc;
32394   }
32395   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32396                         handle_section_bytes + authorization_size_bytes +
32397                         authorization_section_bytes + parameter_section_bytes;
32398   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32399   VLOG(2) << "Command: "
32400           << base::HexEncode(serialized_command->data(),
32401                              serialized_command->size());
32402   return TPM_RC_SUCCESS;
32403 }
32404 
ParseResponse_NV_WriteLock(const std::string & response,AuthorizationDelegate * authorization_delegate)32405 TPM_RC Tpm::ParseResponse_NV_WriteLock(
32406     const std::string& response,
32407     AuthorizationDelegate* authorization_delegate) {
32408   VLOG(3) << __func__;
32409   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32410   TPM_RC rc = TPM_RC_SUCCESS;
32411   std::string buffer(response);
32412   TPM_ST tag;
32413   std::string tag_bytes;
32414   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32415   if (rc != TPM_RC_SUCCESS) {
32416     return rc;
32417   }
32418   UINT32 response_size;
32419   std::string response_size_bytes;
32420   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32421   if (rc != TPM_RC_SUCCESS) {
32422     return rc;
32423   }
32424   TPM_RC response_code;
32425   std::string response_code_bytes;
32426   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32427   if (rc != TPM_RC_SUCCESS) {
32428     return rc;
32429   }
32430   if (response_size != response.size()) {
32431     return TPM_RC_SIZE;
32432   }
32433   if (response_code != TPM_RC_SUCCESS) {
32434     return response_code;
32435   }
32436   TPM_CC command_code = TPM_CC_NV_WriteLock;
32437   std::string command_code_bytes;
32438   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32439   if (rc != TPM_RC_SUCCESS) {
32440     return rc;
32441   }
32442   std::string authorization_section_bytes;
32443   if (tag == TPM_ST_SESSIONS) {
32444     UINT32 parameter_section_size = buffer.size();
32445     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32446     if (rc != TPM_RC_SUCCESS) {
32447       return rc;
32448     }
32449     if (parameter_section_size > buffer.size()) {
32450       return TPM_RC_INSUFFICIENT;
32451     }
32452     authorization_section_bytes = buffer.substr(parameter_section_size);
32453     // Keep the parameter section in |buffer|.
32454     buffer.erase(parameter_section_size);
32455   }
32456   std::unique_ptr<crypto::SecureHash> hash(
32457       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32458   hash->Update(response_code_bytes.data(), response_code_bytes.size());
32459   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32460   hash->Update(buffer.data(), buffer.size());
32461   std::string response_hash(32, 0);
32462   hash->Finish(std::data(response_hash), response_hash.size());
32463   if (tag == TPM_ST_SESSIONS) {
32464     if (!authorization_delegate)
32465       return TRUNKS_RC_AUTHORIZATION_FAILED;
32466     if (!authorization_delegate->CheckResponseAuthorization(
32467             response_hash, authorization_section_bytes)) {
32468       return TRUNKS_RC_AUTHORIZATION_FAILED;
32469     }
32470   }
32471   return TPM_RC_SUCCESS;
32472 }
32473 
NV_WriteLockErrorCallback(Tpm::NV_WriteLockResponse callback,TPM_RC response_code)32474 void NV_WriteLockErrorCallback(Tpm::NV_WriteLockResponse callback,
32475                                TPM_RC response_code) {
32476   VLOG(1) << __func__;
32477   std::move(callback).Run(response_code);
32478 }
32479 
NV_WriteLockResponseParser(Tpm::NV_WriteLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32480 void NV_WriteLockResponseParser(Tpm::NV_WriteLockResponse callback,
32481                                 AuthorizationDelegate* authorization_delegate,
32482                                 const std::string& response) {
32483   VLOG(1) << __func__;
32484   TPM_RC rc = Tpm::ParseResponse_NV_WriteLock(response, authorization_delegate);
32485   if (rc != TPM_RC_SUCCESS) {
32486     base::OnceCallback<void(TPM_RC)> error_reporter =
32487         base::BindOnce(NV_WriteLockErrorCallback, std::move(callback));
32488     std::move(error_reporter).Run(rc);
32489     return;
32490   }
32491   std::move(callback).Run(rc);
32492 }
32493 
NV_WriteLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_WriteLockResponse callback)32494 void Tpm::NV_WriteLock(const TPMI_RH_NV_AUTH& auth_handle,
32495                        const std::string& auth_handle_name,
32496                        const TPMI_RH_NV_INDEX& nv_index,
32497                        const std::string& nv_index_name,
32498                        AuthorizationDelegate* authorization_delegate,
32499                        NV_WriteLockResponse callback) {
32500   VLOG(1) << __func__;
32501   std::string command;
32502   TPM_RC rc = SerializeCommand_NV_WriteLock(auth_handle, auth_handle_name,
32503                                             nv_index, nv_index_name, &command,
32504                                             authorization_delegate);
32505   if (rc != TPM_RC_SUCCESS) {
32506     base::OnceCallback<void(TPM_RC)> error_reporter =
32507         base::BindOnce(NV_WriteLockErrorCallback, std::move(callback));
32508     std::move(error_reporter).Run(rc);
32509     return;
32510   }
32511   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32512       NV_WriteLockResponseParser, std::move(callback), authorization_delegate);
32513   transceiver_->SendCommand(command, std::move(parser));
32514 }
32515 
NV_WriteLockSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)32516 TPM_RC Tpm::NV_WriteLockSync(const TPMI_RH_NV_AUTH& auth_handle,
32517                              const std::string& auth_handle_name,
32518                              const TPMI_RH_NV_INDEX& nv_index,
32519                              const std::string& nv_index_name,
32520                              AuthorizationDelegate* authorization_delegate) {
32521   VLOG(1) << __func__;
32522   std::string command;
32523   TPM_RC rc = SerializeCommand_NV_WriteLock(auth_handle, auth_handle_name,
32524                                             nv_index, nv_index_name, &command,
32525                                             authorization_delegate);
32526   if (rc != TPM_RC_SUCCESS) {
32527     return rc;
32528   }
32529   std::string response = transceiver_->SendCommandAndWait(command);
32530   rc = ParseResponse_NV_WriteLock(response, authorization_delegate);
32531   return rc;
32532 }
32533 
SerializeCommand_NV_GlobalWriteLock(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32534 TPM_RC Tpm::SerializeCommand_NV_GlobalWriteLock(
32535     const TPMI_RH_PROVISION& auth_handle,
32536     const std::string& auth_handle_name,
32537     std::string* serialized_command,
32538     AuthorizationDelegate* authorization_delegate) {
32539   VLOG(3) << __func__;
32540   TPM_RC rc = TPM_RC_SUCCESS;
32541   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32542   UINT32 command_size = 10;  // Header size.
32543   std::string handle_section_bytes;
32544   std::string parameter_section_bytes;
32545   TPM_CC command_code = TPM_CC_NV_GlobalWriteLock;
32546   bool is_command_parameter_encryption_possible = false;
32547   bool is_response_parameter_encryption_possible = false;
32548   std::string command_code_bytes;
32549   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32550   if (rc != TPM_RC_SUCCESS) {
32551     return rc;
32552   }
32553   std::string auth_handle_bytes;
32554   rc = Serialize_TPMI_RH_PROVISION(auth_handle, &auth_handle_bytes);
32555   if (rc != TPM_RC_SUCCESS) {
32556     return rc;
32557   }
32558   std::unique_ptr<crypto::SecureHash> hash(
32559       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32560   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32561   hash->Update(auth_handle_name.data(), auth_handle_name.size());
32562   handle_section_bytes += auth_handle_bytes;
32563   command_size += auth_handle_bytes.size();
32564   std::string command_hash(32, 0);
32565   hash->Finish(std::data(command_hash), command_hash.size());
32566   std::string authorization_section_bytes;
32567   std::string authorization_size_bytes;
32568   if (authorization_delegate) {
32569     if (!authorization_delegate->GetCommandAuthorization(
32570             command_hash, is_command_parameter_encryption_possible,
32571             is_response_parameter_encryption_possible,
32572             &authorization_section_bytes)) {
32573       return TRUNKS_RC_AUTHORIZATION_FAILED;
32574     }
32575     if (!authorization_section_bytes.empty()) {
32576       tag = TPM_ST_SESSIONS;
32577       std::string tmp;
32578       rc = Serialize_UINT32(authorization_section_bytes.size(),
32579                             &authorization_size_bytes);
32580       if (rc != TPM_RC_SUCCESS) {
32581         return rc;
32582       }
32583       command_size +=
32584           authorization_size_bytes.size() + authorization_section_bytes.size();
32585     }
32586   }
32587   std::string tag_bytes;
32588   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32589   if (rc != TPM_RC_SUCCESS) {
32590     return rc;
32591   }
32592   std::string command_size_bytes;
32593   rc = Serialize_UINT32(command_size, &command_size_bytes);
32594   if (rc != TPM_RC_SUCCESS) {
32595     return rc;
32596   }
32597   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32598                         handle_section_bytes + authorization_size_bytes +
32599                         authorization_section_bytes + parameter_section_bytes;
32600   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32601   VLOG(2) << "Command: "
32602           << base::HexEncode(serialized_command->data(),
32603                              serialized_command->size());
32604   return TPM_RC_SUCCESS;
32605 }
32606 
ParseResponse_NV_GlobalWriteLock(const std::string & response,AuthorizationDelegate * authorization_delegate)32607 TPM_RC Tpm::ParseResponse_NV_GlobalWriteLock(
32608     const std::string& response,
32609     AuthorizationDelegate* authorization_delegate) {
32610   VLOG(3) << __func__;
32611   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32612   TPM_RC rc = TPM_RC_SUCCESS;
32613   std::string buffer(response);
32614   TPM_ST tag;
32615   std::string tag_bytes;
32616   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32617   if (rc != TPM_RC_SUCCESS) {
32618     return rc;
32619   }
32620   UINT32 response_size;
32621   std::string response_size_bytes;
32622   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32623   if (rc != TPM_RC_SUCCESS) {
32624     return rc;
32625   }
32626   TPM_RC response_code;
32627   std::string response_code_bytes;
32628   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32629   if (rc != TPM_RC_SUCCESS) {
32630     return rc;
32631   }
32632   if (response_size != response.size()) {
32633     return TPM_RC_SIZE;
32634   }
32635   if (response_code != TPM_RC_SUCCESS) {
32636     return response_code;
32637   }
32638   TPM_CC command_code = TPM_CC_NV_GlobalWriteLock;
32639   std::string command_code_bytes;
32640   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32641   if (rc != TPM_RC_SUCCESS) {
32642     return rc;
32643   }
32644   std::string authorization_section_bytes;
32645   if (tag == TPM_ST_SESSIONS) {
32646     UINT32 parameter_section_size = buffer.size();
32647     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32648     if (rc != TPM_RC_SUCCESS) {
32649       return rc;
32650     }
32651     if (parameter_section_size > buffer.size()) {
32652       return TPM_RC_INSUFFICIENT;
32653     }
32654     authorization_section_bytes = buffer.substr(parameter_section_size);
32655     // Keep the parameter section in |buffer|.
32656     buffer.erase(parameter_section_size);
32657   }
32658   std::unique_ptr<crypto::SecureHash> hash(
32659       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32660   hash->Update(response_code_bytes.data(), response_code_bytes.size());
32661   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32662   hash->Update(buffer.data(), buffer.size());
32663   std::string response_hash(32, 0);
32664   hash->Finish(std::data(response_hash), response_hash.size());
32665   if (tag == TPM_ST_SESSIONS) {
32666     if (!authorization_delegate)
32667       return TRUNKS_RC_AUTHORIZATION_FAILED;
32668     if (!authorization_delegate->CheckResponseAuthorization(
32669             response_hash, authorization_section_bytes)) {
32670       return TRUNKS_RC_AUTHORIZATION_FAILED;
32671     }
32672   }
32673   return TPM_RC_SUCCESS;
32674 }
32675 
NV_GlobalWriteLockErrorCallback(Tpm::NV_GlobalWriteLockResponse callback,TPM_RC response_code)32676 void NV_GlobalWriteLockErrorCallback(Tpm::NV_GlobalWriteLockResponse callback,
32677                                      TPM_RC response_code) {
32678   VLOG(1) << __func__;
32679   std::move(callback).Run(response_code);
32680 }
32681 
NV_GlobalWriteLockResponseParser(Tpm::NV_GlobalWriteLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32682 void NV_GlobalWriteLockResponseParser(
32683     Tpm::NV_GlobalWriteLockResponse callback,
32684     AuthorizationDelegate* authorization_delegate,
32685     const std::string& response) {
32686   VLOG(1) << __func__;
32687   TPM_RC rc =
32688       Tpm::ParseResponse_NV_GlobalWriteLock(response, authorization_delegate);
32689   if (rc != TPM_RC_SUCCESS) {
32690     base::OnceCallback<void(TPM_RC)> error_reporter =
32691         base::BindOnce(NV_GlobalWriteLockErrorCallback, std::move(callback));
32692     std::move(error_reporter).Run(rc);
32693     return;
32694   }
32695   std::move(callback).Run(rc);
32696 }
32697 
NV_GlobalWriteLock(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate,NV_GlobalWriteLockResponse callback)32698 void Tpm::NV_GlobalWriteLock(const TPMI_RH_PROVISION& auth_handle,
32699                              const std::string& auth_handle_name,
32700                              AuthorizationDelegate* authorization_delegate,
32701                              NV_GlobalWriteLockResponse callback) {
32702   VLOG(1) << __func__;
32703   std::string command;
32704   TPM_RC rc = SerializeCommand_NV_GlobalWriteLock(
32705       auth_handle, auth_handle_name, &command, authorization_delegate);
32706   if (rc != TPM_RC_SUCCESS) {
32707     base::OnceCallback<void(TPM_RC)> error_reporter =
32708         base::BindOnce(NV_GlobalWriteLockErrorCallback, std::move(callback));
32709     std::move(error_reporter).Run(rc);
32710     return;
32711   }
32712   base::OnceCallback<void(const std::string&)> parser =
32713       base::BindOnce(NV_GlobalWriteLockResponseParser, std::move(callback),
32714                      authorization_delegate);
32715   transceiver_->SendCommand(command, std::move(parser));
32716 }
32717 
NV_GlobalWriteLockSync(const TPMI_RH_PROVISION & auth_handle,const std::string & auth_handle_name,AuthorizationDelegate * authorization_delegate)32718 TPM_RC Tpm::NV_GlobalWriteLockSync(
32719     const TPMI_RH_PROVISION& auth_handle,
32720     const std::string& auth_handle_name,
32721     AuthorizationDelegate* authorization_delegate) {
32722   VLOG(1) << __func__;
32723   std::string command;
32724   TPM_RC rc = SerializeCommand_NV_GlobalWriteLock(
32725       auth_handle, auth_handle_name, &command, authorization_delegate);
32726   if (rc != TPM_RC_SUCCESS) {
32727     return rc;
32728   }
32729   std::string response = transceiver_->SendCommandAndWait(command);
32730   rc = ParseResponse_NV_GlobalWriteLock(response, authorization_delegate);
32731   return rc;
32732 }
32733 
SerializeCommand_NV_Read(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT16 & size,const UINT16 & offset,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32734 TPM_RC Tpm::SerializeCommand_NV_Read(
32735     const TPMI_RH_NV_AUTH& auth_handle,
32736     const std::string& auth_handle_name,
32737     const TPMI_RH_NV_INDEX& nv_index,
32738     const std::string& nv_index_name,
32739     const UINT16& size,
32740     const UINT16& offset,
32741     std::string* serialized_command,
32742     AuthorizationDelegate* authorization_delegate) {
32743   VLOG(3) << __func__;
32744   TPM_RC rc = TPM_RC_SUCCESS;
32745   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
32746   UINT32 command_size = 10;  // Header size.
32747   std::string handle_section_bytes;
32748   std::string parameter_section_bytes;
32749   TPM_CC command_code = TPM_CC_NV_Read;
32750   bool is_command_parameter_encryption_possible = false;
32751   bool is_response_parameter_encryption_possible = true;
32752   std::string command_code_bytes;
32753   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32754   if (rc != TPM_RC_SUCCESS) {
32755     return rc;
32756   }
32757   std::string auth_handle_bytes;
32758   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
32759   if (rc != TPM_RC_SUCCESS) {
32760     return rc;
32761   }
32762   std::string nv_index_bytes;
32763   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
32764   if (rc != TPM_RC_SUCCESS) {
32765     return rc;
32766   }
32767   std::string size_bytes;
32768   rc = Serialize_UINT16(size, &size_bytes);
32769   if (rc != TPM_RC_SUCCESS) {
32770     return rc;
32771   }
32772   std::string offset_bytes;
32773   rc = Serialize_UINT16(offset, &offset_bytes);
32774   if (rc != TPM_RC_SUCCESS) {
32775     return rc;
32776   }
32777   std::unique_ptr<crypto::SecureHash> hash(
32778       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32779   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32780   hash->Update(auth_handle_name.data(), auth_handle_name.size());
32781   handle_section_bytes += auth_handle_bytes;
32782   command_size += auth_handle_bytes.size();
32783   hash->Update(nv_index_name.data(), nv_index_name.size());
32784   handle_section_bytes += nv_index_bytes;
32785   command_size += nv_index_bytes.size();
32786   hash->Update(size_bytes.data(), size_bytes.size());
32787   parameter_section_bytes += size_bytes;
32788   command_size += size_bytes.size();
32789   hash->Update(offset_bytes.data(), offset_bytes.size());
32790   parameter_section_bytes += offset_bytes;
32791   command_size += offset_bytes.size();
32792   std::string command_hash(32, 0);
32793   hash->Finish(std::data(command_hash), command_hash.size());
32794   std::string authorization_section_bytes;
32795   std::string authorization_size_bytes;
32796   if (authorization_delegate) {
32797     if (!authorization_delegate->GetCommandAuthorization(
32798             command_hash, is_command_parameter_encryption_possible,
32799             is_response_parameter_encryption_possible,
32800             &authorization_section_bytes)) {
32801       return TRUNKS_RC_AUTHORIZATION_FAILED;
32802     }
32803     if (!authorization_section_bytes.empty()) {
32804       tag = TPM_ST_SESSIONS;
32805       std::string tmp;
32806       rc = Serialize_UINT32(authorization_section_bytes.size(),
32807                             &authorization_size_bytes);
32808       if (rc != TPM_RC_SUCCESS) {
32809         return rc;
32810       }
32811       command_size +=
32812           authorization_size_bytes.size() + authorization_section_bytes.size();
32813     }
32814   }
32815   std::string tag_bytes;
32816   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
32817   if (rc != TPM_RC_SUCCESS) {
32818     return rc;
32819   }
32820   std::string command_size_bytes;
32821   rc = Serialize_UINT32(command_size, &command_size_bytes);
32822   if (rc != TPM_RC_SUCCESS) {
32823     return rc;
32824   }
32825   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
32826                         handle_section_bytes + authorization_size_bytes +
32827                         authorization_section_bytes + parameter_section_bytes;
32828   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
32829   VLOG(2) << "Command: "
32830           << base::HexEncode(serialized_command->data(),
32831                              serialized_command->size());
32832   return TPM_RC_SUCCESS;
32833 }
32834 
ParseResponse_NV_Read(const std::string & response,TPM2B_MAX_NV_BUFFER * data,AuthorizationDelegate * authorization_delegate)32835 TPM_RC Tpm::ParseResponse_NV_Read(
32836     const std::string& response,
32837     TPM2B_MAX_NV_BUFFER* data,
32838     AuthorizationDelegate* authorization_delegate) {
32839   VLOG(3) << __func__;
32840   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
32841   TPM_RC rc = TPM_RC_SUCCESS;
32842   std::string buffer(response);
32843   TPM_ST tag;
32844   std::string tag_bytes;
32845   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
32846   if (rc != TPM_RC_SUCCESS) {
32847     return rc;
32848   }
32849   UINT32 response_size;
32850   std::string response_size_bytes;
32851   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
32852   if (rc != TPM_RC_SUCCESS) {
32853     return rc;
32854   }
32855   TPM_RC response_code;
32856   std::string response_code_bytes;
32857   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
32858   if (rc != TPM_RC_SUCCESS) {
32859     return rc;
32860   }
32861   if (response_size != response.size()) {
32862     return TPM_RC_SIZE;
32863   }
32864   if (response_code != TPM_RC_SUCCESS) {
32865     return response_code;
32866   }
32867   TPM_CC command_code = TPM_CC_NV_Read;
32868   std::string command_code_bytes;
32869   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
32870   if (rc != TPM_RC_SUCCESS) {
32871     return rc;
32872   }
32873   std::string authorization_section_bytes;
32874   if (tag == TPM_ST_SESSIONS) {
32875     UINT32 parameter_section_size = buffer.size();
32876     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
32877     if (rc != TPM_RC_SUCCESS) {
32878       return rc;
32879     }
32880     if (parameter_section_size > buffer.size()) {
32881       return TPM_RC_INSUFFICIENT;
32882     }
32883     authorization_section_bytes = buffer.substr(parameter_section_size);
32884     // Keep the parameter section in |buffer|.
32885     buffer.erase(parameter_section_size);
32886   }
32887   std::unique_ptr<crypto::SecureHash> hash(
32888       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
32889   hash->Update(response_code_bytes.data(), response_code_bytes.size());
32890   hash->Update(command_code_bytes.data(), command_code_bytes.size());
32891   hash->Update(buffer.data(), buffer.size());
32892   std::string response_hash(32, 0);
32893   hash->Finish(std::data(response_hash), response_hash.size());
32894   if (tag == TPM_ST_SESSIONS) {
32895     if (!authorization_delegate)
32896       return TRUNKS_RC_AUTHORIZATION_FAILED;
32897     if (!authorization_delegate->CheckResponseAuthorization(
32898             response_hash, authorization_section_bytes)) {
32899       return TRUNKS_RC_AUTHORIZATION_FAILED;
32900     }
32901   }
32902   if (tag == TPM_ST_SESSIONS) {
32903     if (!authorization_delegate)
32904       return TRUNKS_RC_AUTHORIZATION_FAILED;
32905 
32906     // Parse the encrypted parameter size.
32907     UINT16 size;
32908     std::string size_buffer = buffer.substr(0, 2);
32909     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
32910       return result;
32911     }
32912     if (buffer.size() < 2 + size) {
32913       return TPM_RC_INSUFFICIENT;
32914     }
32915 
32916     // Decrypt just the parameter data, not the size.
32917     std::string decrypted_data = buffer.substr(2, size);
32918     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
32919       return TRUNKS_RC_ENCRYPTION_FAILED;
32920     }
32921     buffer.replace(2, size, decrypted_data);
32922   }
32923   std::string data_bytes;
32924   rc = Parse_TPM2B_MAX_NV_BUFFER(&buffer, data, &data_bytes);
32925   if (rc != TPM_RC_SUCCESS) {
32926     return rc;
32927   }
32928   return TPM_RC_SUCCESS;
32929 }
32930 
NV_ReadErrorCallback(Tpm::NV_ReadResponse callback,TPM_RC response_code)32931 void NV_ReadErrorCallback(Tpm::NV_ReadResponse callback, TPM_RC response_code) {
32932   VLOG(1) << __func__;
32933   std::move(callback).Run(response_code, TPM2B_MAX_NV_BUFFER());
32934 }
32935 
NV_ReadResponseParser(Tpm::NV_ReadResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)32936 void NV_ReadResponseParser(Tpm::NV_ReadResponse callback,
32937                            AuthorizationDelegate* authorization_delegate,
32938                            const std::string& response) {
32939   VLOG(1) << __func__;
32940   TPM2B_MAX_NV_BUFFER data;
32941   TPM_RC rc =
32942       Tpm::ParseResponse_NV_Read(response, &data, authorization_delegate);
32943   if (rc != TPM_RC_SUCCESS) {
32944     base::OnceCallback<void(TPM_RC)> error_reporter =
32945         base::BindOnce(NV_ReadErrorCallback, std::move(callback));
32946     std::move(error_reporter).Run(rc);
32947     return;
32948   }
32949   std::move(callback).Run(rc, data);
32950 }
32951 
NV_Read(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT16 & size,const UINT16 & offset,AuthorizationDelegate * authorization_delegate,NV_ReadResponse callback)32952 void Tpm::NV_Read(const TPMI_RH_NV_AUTH& auth_handle,
32953                   const std::string& auth_handle_name,
32954                   const TPMI_RH_NV_INDEX& nv_index,
32955                   const std::string& nv_index_name,
32956                   const UINT16& size,
32957                   const UINT16& offset,
32958                   AuthorizationDelegate* authorization_delegate,
32959                   NV_ReadResponse callback) {
32960   VLOG(1) << __func__;
32961   std::string command;
32962   TPM_RC rc = SerializeCommand_NV_Read(auth_handle, auth_handle_name, nv_index,
32963                                        nv_index_name, size, offset, &command,
32964                                        authorization_delegate);
32965   if (rc != TPM_RC_SUCCESS) {
32966     base::OnceCallback<void(TPM_RC)> error_reporter =
32967         base::BindOnce(NV_ReadErrorCallback, std::move(callback));
32968     std::move(error_reporter).Run(rc);
32969     return;
32970   }
32971   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
32972       NV_ReadResponseParser, std::move(callback), authorization_delegate);
32973   transceiver_->SendCommand(command, std::move(parser));
32974 }
32975 
NV_ReadSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const UINT16 & size,const UINT16 & offset,TPM2B_MAX_NV_BUFFER * data,AuthorizationDelegate * authorization_delegate)32976 TPM_RC Tpm::NV_ReadSync(const TPMI_RH_NV_AUTH& auth_handle,
32977                         const std::string& auth_handle_name,
32978                         const TPMI_RH_NV_INDEX& nv_index,
32979                         const std::string& nv_index_name,
32980                         const UINT16& size,
32981                         const UINT16& offset,
32982                         TPM2B_MAX_NV_BUFFER* data,
32983                         AuthorizationDelegate* authorization_delegate) {
32984   VLOG(1) << __func__;
32985   std::string command;
32986   TPM_RC rc = SerializeCommand_NV_Read(auth_handle, auth_handle_name, nv_index,
32987                                        nv_index_name, size, offset, &command,
32988                                        authorization_delegate);
32989   if (rc != TPM_RC_SUCCESS) {
32990     return rc;
32991   }
32992   std::string response = transceiver_->SendCommandAndWait(command);
32993   rc = ParseResponse_NV_Read(response, data, authorization_delegate);
32994   return rc;
32995 }
32996 
SerializeCommand_NV_ReadLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)32997 TPM_RC Tpm::SerializeCommand_NV_ReadLock(
32998     const TPMI_RH_NV_AUTH& auth_handle,
32999     const std::string& auth_handle_name,
33000     const TPMI_RH_NV_INDEX& nv_index,
33001     const std::string& nv_index_name,
33002     std::string* serialized_command,
33003     AuthorizationDelegate* authorization_delegate) {
33004   VLOG(3) << __func__;
33005   TPM_RC rc = TPM_RC_SUCCESS;
33006   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33007   UINT32 command_size = 10;  // Header size.
33008   std::string handle_section_bytes;
33009   std::string parameter_section_bytes;
33010   TPM_CC command_code = TPM_CC_NV_ReadLock;
33011   bool is_command_parameter_encryption_possible = false;
33012   bool is_response_parameter_encryption_possible = false;
33013   std::string command_code_bytes;
33014   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33015   if (rc != TPM_RC_SUCCESS) {
33016     return rc;
33017   }
33018   std::string auth_handle_bytes;
33019   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
33020   if (rc != TPM_RC_SUCCESS) {
33021     return rc;
33022   }
33023   std::string nv_index_bytes;
33024   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33025   if (rc != TPM_RC_SUCCESS) {
33026     return rc;
33027   }
33028   std::unique_ptr<crypto::SecureHash> hash(
33029       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33030   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33031   hash->Update(auth_handle_name.data(), auth_handle_name.size());
33032   handle_section_bytes += auth_handle_bytes;
33033   command_size += auth_handle_bytes.size();
33034   hash->Update(nv_index_name.data(), nv_index_name.size());
33035   handle_section_bytes += nv_index_bytes;
33036   command_size += nv_index_bytes.size();
33037   std::string command_hash(32, 0);
33038   hash->Finish(std::data(command_hash), command_hash.size());
33039   std::string authorization_section_bytes;
33040   std::string authorization_size_bytes;
33041   if (authorization_delegate) {
33042     if (!authorization_delegate->GetCommandAuthorization(
33043             command_hash, is_command_parameter_encryption_possible,
33044             is_response_parameter_encryption_possible,
33045             &authorization_section_bytes)) {
33046       return TRUNKS_RC_AUTHORIZATION_FAILED;
33047     }
33048     if (!authorization_section_bytes.empty()) {
33049       tag = TPM_ST_SESSIONS;
33050       std::string tmp;
33051       rc = Serialize_UINT32(authorization_section_bytes.size(),
33052                             &authorization_size_bytes);
33053       if (rc != TPM_RC_SUCCESS) {
33054         return rc;
33055       }
33056       command_size +=
33057           authorization_size_bytes.size() + authorization_section_bytes.size();
33058     }
33059   }
33060   std::string tag_bytes;
33061   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33062   if (rc != TPM_RC_SUCCESS) {
33063     return rc;
33064   }
33065   std::string command_size_bytes;
33066   rc = Serialize_UINT32(command_size, &command_size_bytes);
33067   if (rc != TPM_RC_SUCCESS) {
33068     return rc;
33069   }
33070   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33071                         handle_section_bytes + authorization_size_bytes +
33072                         authorization_section_bytes + parameter_section_bytes;
33073   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33074   VLOG(2) << "Command: "
33075           << base::HexEncode(serialized_command->data(),
33076                              serialized_command->size());
33077   return TPM_RC_SUCCESS;
33078 }
33079 
ParseResponse_NV_ReadLock(const std::string & response,AuthorizationDelegate * authorization_delegate)33080 TPM_RC Tpm::ParseResponse_NV_ReadLock(
33081     const std::string& response,
33082     AuthorizationDelegate* authorization_delegate) {
33083   VLOG(3) << __func__;
33084   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33085   TPM_RC rc = TPM_RC_SUCCESS;
33086   std::string buffer(response);
33087   TPM_ST tag;
33088   std::string tag_bytes;
33089   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33090   if (rc != TPM_RC_SUCCESS) {
33091     return rc;
33092   }
33093   UINT32 response_size;
33094   std::string response_size_bytes;
33095   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33096   if (rc != TPM_RC_SUCCESS) {
33097     return rc;
33098   }
33099   TPM_RC response_code;
33100   std::string response_code_bytes;
33101   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33102   if (rc != TPM_RC_SUCCESS) {
33103     return rc;
33104   }
33105   if (response_size != response.size()) {
33106     return TPM_RC_SIZE;
33107   }
33108   if (response_code != TPM_RC_SUCCESS) {
33109     return response_code;
33110   }
33111   TPM_CC command_code = TPM_CC_NV_ReadLock;
33112   std::string command_code_bytes;
33113   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33114   if (rc != TPM_RC_SUCCESS) {
33115     return rc;
33116   }
33117   std::string authorization_section_bytes;
33118   if (tag == TPM_ST_SESSIONS) {
33119     UINT32 parameter_section_size = buffer.size();
33120     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
33121     if (rc != TPM_RC_SUCCESS) {
33122       return rc;
33123     }
33124     if (parameter_section_size > buffer.size()) {
33125       return TPM_RC_INSUFFICIENT;
33126     }
33127     authorization_section_bytes = buffer.substr(parameter_section_size);
33128     // Keep the parameter section in |buffer|.
33129     buffer.erase(parameter_section_size);
33130   }
33131   std::unique_ptr<crypto::SecureHash> hash(
33132       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33133   hash->Update(response_code_bytes.data(), response_code_bytes.size());
33134   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33135   hash->Update(buffer.data(), buffer.size());
33136   std::string response_hash(32, 0);
33137   hash->Finish(std::data(response_hash), response_hash.size());
33138   if (tag == TPM_ST_SESSIONS) {
33139     if (!authorization_delegate)
33140       return TRUNKS_RC_AUTHORIZATION_FAILED;
33141     if (!authorization_delegate->CheckResponseAuthorization(
33142             response_hash, authorization_section_bytes)) {
33143       return TRUNKS_RC_AUTHORIZATION_FAILED;
33144     }
33145   }
33146   return TPM_RC_SUCCESS;
33147 }
33148 
NV_ReadLockErrorCallback(Tpm::NV_ReadLockResponse callback,TPM_RC response_code)33149 void NV_ReadLockErrorCallback(Tpm::NV_ReadLockResponse callback,
33150                               TPM_RC response_code) {
33151   VLOG(1) << __func__;
33152   std::move(callback).Run(response_code);
33153 }
33154 
NV_ReadLockResponseParser(Tpm::NV_ReadLockResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33155 void NV_ReadLockResponseParser(Tpm::NV_ReadLockResponse callback,
33156                                AuthorizationDelegate* authorization_delegate,
33157                                const std::string& response) {
33158   VLOG(1) << __func__;
33159   TPM_RC rc = Tpm::ParseResponse_NV_ReadLock(response, authorization_delegate);
33160   if (rc != TPM_RC_SUCCESS) {
33161     base::OnceCallback<void(TPM_RC)> error_reporter =
33162         base::BindOnce(NV_ReadLockErrorCallback, std::move(callback));
33163     std::move(error_reporter).Run(rc);
33164     return;
33165   }
33166   std::move(callback).Run(rc);
33167 }
33168 
NV_ReadLock(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate,NV_ReadLockResponse callback)33169 void Tpm::NV_ReadLock(const TPMI_RH_NV_AUTH& auth_handle,
33170                       const std::string& auth_handle_name,
33171                       const TPMI_RH_NV_INDEX& nv_index,
33172                       const std::string& nv_index_name,
33173                       AuthorizationDelegate* authorization_delegate,
33174                       NV_ReadLockResponse callback) {
33175   VLOG(1) << __func__;
33176   std::string command;
33177   TPM_RC rc = SerializeCommand_NV_ReadLock(auth_handle, auth_handle_name,
33178                                            nv_index, nv_index_name, &command,
33179                                            authorization_delegate);
33180   if (rc != TPM_RC_SUCCESS) {
33181     base::OnceCallback<void(TPM_RC)> error_reporter =
33182         base::BindOnce(NV_ReadLockErrorCallback, std::move(callback));
33183     std::move(error_reporter).Run(rc);
33184     return;
33185   }
33186   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33187       NV_ReadLockResponseParser, std::move(callback), authorization_delegate);
33188   transceiver_->SendCommand(command, std::move(parser));
33189 }
33190 
NV_ReadLockSync(const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,AuthorizationDelegate * authorization_delegate)33191 TPM_RC Tpm::NV_ReadLockSync(const TPMI_RH_NV_AUTH& auth_handle,
33192                             const std::string& auth_handle_name,
33193                             const TPMI_RH_NV_INDEX& nv_index,
33194                             const std::string& nv_index_name,
33195                             AuthorizationDelegate* authorization_delegate) {
33196   VLOG(1) << __func__;
33197   std::string command;
33198   TPM_RC rc = SerializeCommand_NV_ReadLock(auth_handle, auth_handle_name,
33199                                            nv_index, nv_index_name, &command,
33200                                            authorization_delegate);
33201   if (rc != TPM_RC_SUCCESS) {
33202     return rc;
33203   }
33204   std::string response = transceiver_->SendCommandAndWait(command);
33205   rc = ParseResponse_NV_ReadLock(response, authorization_delegate);
33206   return rc;
33207 }
33208 
SerializeCommand_NV_ChangeAuth(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_AUTH & new_auth,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)33209 TPM_RC Tpm::SerializeCommand_NV_ChangeAuth(
33210     const TPMI_RH_NV_INDEX& nv_index,
33211     const std::string& nv_index_name,
33212     const TPM2B_AUTH& new_auth,
33213     std::string* serialized_command,
33214     AuthorizationDelegate* authorization_delegate) {
33215   VLOG(3) << __func__;
33216   TPM_RC rc = TPM_RC_SUCCESS;
33217   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33218   UINT32 command_size = 10;  // Header size.
33219   std::string handle_section_bytes;
33220   std::string parameter_section_bytes;
33221   TPM_CC command_code = TPM_CC_NV_ChangeAuth;
33222   bool is_command_parameter_encryption_possible = true;
33223   bool is_response_parameter_encryption_possible = false;
33224   std::string command_code_bytes;
33225   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33226   if (rc != TPM_RC_SUCCESS) {
33227     return rc;
33228   }
33229   std::string nv_index_bytes;
33230   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33231   if (rc != TPM_RC_SUCCESS) {
33232     return rc;
33233   }
33234   std::string new_auth_bytes;
33235   rc = Serialize_TPM2B_AUTH(new_auth, &new_auth_bytes);
33236   if (rc != TPM_RC_SUCCESS) {
33237     return rc;
33238   }
33239   if (authorization_delegate) {
33240     // Encrypt just the parameter data, not the size.
33241     std::string tmp = new_auth_bytes.substr(2);
33242     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
33243       return TRUNKS_RC_ENCRYPTION_FAILED;
33244     }
33245     new_auth_bytes.replace(2, std::string::npos, tmp);
33246   }
33247   std::unique_ptr<crypto::SecureHash> hash(
33248       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33249   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33250   hash->Update(nv_index_name.data(), nv_index_name.size());
33251   handle_section_bytes += nv_index_bytes;
33252   command_size += nv_index_bytes.size();
33253   hash->Update(new_auth_bytes.data(), new_auth_bytes.size());
33254   parameter_section_bytes += new_auth_bytes;
33255   command_size += new_auth_bytes.size();
33256   std::string command_hash(32, 0);
33257   hash->Finish(std::data(command_hash), command_hash.size());
33258   std::string authorization_section_bytes;
33259   std::string authorization_size_bytes;
33260   if (authorization_delegate) {
33261     if (!authorization_delegate->GetCommandAuthorization(
33262             command_hash, is_command_parameter_encryption_possible,
33263             is_response_parameter_encryption_possible,
33264             &authorization_section_bytes)) {
33265       return TRUNKS_RC_AUTHORIZATION_FAILED;
33266     }
33267     if (!authorization_section_bytes.empty()) {
33268       tag = TPM_ST_SESSIONS;
33269       std::string tmp;
33270       rc = Serialize_UINT32(authorization_section_bytes.size(),
33271                             &authorization_size_bytes);
33272       if (rc != TPM_RC_SUCCESS) {
33273         return rc;
33274       }
33275       command_size +=
33276           authorization_size_bytes.size() + authorization_section_bytes.size();
33277     }
33278   }
33279   std::string tag_bytes;
33280   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33281   if (rc != TPM_RC_SUCCESS) {
33282     return rc;
33283   }
33284   std::string command_size_bytes;
33285   rc = Serialize_UINT32(command_size, &command_size_bytes);
33286   if (rc != TPM_RC_SUCCESS) {
33287     return rc;
33288   }
33289   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33290                         handle_section_bytes + authorization_size_bytes +
33291                         authorization_section_bytes + parameter_section_bytes;
33292   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33293   VLOG(2) << "Command: "
33294           << base::HexEncode(serialized_command->data(),
33295                              serialized_command->size());
33296   return TPM_RC_SUCCESS;
33297 }
33298 
ParseResponse_NV_ChangeAuth(const std::string & response,AuthorizationDelegate * authorization_delegate)33299 TPM_RC Tpm::ParseResponse_NV_ChangeAuth(
33300     const std::string& response,
33301     AuthorizationDelegate* authorization_delegate) {
33302   VLOG(3) << __func__;
33303   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33304   TPM_RC rc = TPM_RC_SUCCESS;
33305   std::string buffer(response);
33306   TPM_ST tag;
33307   std::string tag_bytes;
33308   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33309   if (rc != TPM_RC_SUCCESS) {
33310     return rc;
33311   }
33312   UINT32 response_size;
33313   std::string response_size_bytes;
33314   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33315   if (rc != TPM_RC_SUCCESS) {
33316     return rc;
33317   }
33318   TPM_RC response_code;
33319   std::string response_code_bytes;
33320   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33321   if (rc != TPM_RC_SUCCESS) {
33322     return rc;
33323   }
33324   if (response_size != response.size()) {
33325     return TPM_RC_SIZE;
33326   }
33327   if (response_code != TPM_RC_SUCCESS) {
33328     return response_code;
33329   }
33330   TPM_CC command_code = TPM_CC_NV_ChangeAuth;
33331   std::string command_code_bytes;
33332   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33333   if (rc != TPM_RC_SUCCESS) {
33334     return rc;
33335   }
33336   std::string authorization_section_bytes;
33337   if (tag == TPM_ST_SESSIONS) {
33338     UINT32 parameter_section_size = buffer.size();
33339     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
33340     if (rc != TPM_RC_SUCCESS) {
33341       return rc;
33342     }
33343     if (parameter_section_size > buffer.size()) {
33344       return TPM_RC_INSUFFICIENT;
33345     }
33346     authorization_section_bytes = buffer.substr(parameter_section_size);
33347     // Keep the parameter section in |buffer|.
33348     buffer.erase(parameter_section_size);
33349   }
33350   std::unique_ptr<crypto::SecureHash> hash(
33351       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33352   hash->Update(response_code_bytes.data(), response_code_bytes.size());
33353   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33354   hash->Update(buffer.data(), buffer.size());
33355   std::string response_hash(32, 0);
33356   hash->Finish(std::data(response_hash), response_hash.size());
33357   if (tag == TPM_ST_SESSIONS) {
33358     if (!authorization_delegate)
33359       return TRUNKS_RC_AUTHORIZATION_FAILED;
33360     if (!authorization_delegate->CheckResponseAuthorization(
33361             response_hash, authorization_section_bytes)) {
33362       return TRUNKS_RC_AUTHORIZATION_FAILED;
33363     }
33364   }
33365   return TPM_RC_SUCCESS;
33366 }
33367 
NV_ChangeAuthErrorCallback(Tpm::NV_ChangeAuthResponse callback,TPM_RC response_code)33368 void NV_ChangeAuthErrorCallback(Tpm::NV_ChangeAuthResponse callback,
33369                                 TPM_RC response_code) {
33370   VLOG(1) << __func__;
33371   std::move(callback).Run(response_code);
33372 }
33373 
NV_ChangeAuthResponseParser(Tpm::NV_ChangeAuthResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33374 void NV_ChangeAuthResponseParser(Tpm::NV_ChangeAuthResponse callback,
33375                                  AuthorizationDelegate* authorization_delegate,
33376                                  const std::string& response) {
33377   VLOG(1) << __func__;
33378   TPM_RC rc =
33379       Tpm::ParseResponse_NV_ChangeAuth(response, authorization_delegate);
33380   if (rc != TPM_RC_SUCCESS) {
33381     base::OnceCallback<void(TPM_RC)> error_reporter =
33382         base::BindOnce(NV_ChangeAuthErrorCallback, std::move(callback));
33383     std::move(error_reporter).Run(rc);
33384     return;
33385   }
33386   std::move(callback).Run(rc);
33387 }
33388 
NV_ChangeAuth(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate,NV_ChangeAuthResponse callback)33389 void Tpm::NV_ChangeAuth(const TPMI_RH_NV_INDEX& nv_index,
33390                         const std::string& nv_index_name,
33391                         const TPM2B_AUTH& new_auth,
33392                         AuthorizationDelegate* authorization_delegate,
33393                         NV_ChangeAuthResponse callback) {
33394   VLOG(1) << __func__;
33395   std::string command;
33396   TPM_RC rc = SerializeCommand_NV_ChangeAuth(nv_index, nv_index_name, new_auth,
33397                                              &command, authorization_delegate);
33398   if (rc != TPM_RC_SUCCESS) {
33399     base::OnceCallback<void(TPM_RC)> error_reporter =
33400         base::BindOnce(NV_ChangeAuthErrorCallback, std::move(callback));
33401     std::move(error_reporter).Run(rc);
33402     return;
33403   }
33404   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33405       NV_ChangeAuthResponseParser, std::move(callback), authorization_delegate);
33406   transceiver_->SendCommand(command, std::move(parser));
33407 }
33408 
NV_ChangeAuthSync(const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_AUTH & new_auth,AuthorizationDelegate * authorization_delegate)33409 TPM_RC Tpm::NV_ChangeAuthSync(const TPMI_RH_NV_INDEX& nv_index,
33410                               const std::string& nv_index_name,
33411                               const TPM2B_AUTH& new_auth,
33412                               AuthorizationDelegate* authorization_delegate) {
33413   VLOG(1) << __func__;
33414   std::string command;
33415   TPM_RC rc = SerializeCommand_NV_ChangeAuth(nv_index, nv_index_name, new_auth,
33416                                              &command, authorization_delegate);
33417   if (rc != TPM_RC_SUCCESS) {
33418     return rc;
33419   }
33420   std::string response = transceiver_->SendCommandAndWait(command);
33421   rc = ParseResponse_NV_ChangeAuth(response, authorization_delegate);
33422   return rc;
33423 }
33424 
SerializeCommand_NV_Certify(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const UINT16 & size,const UINT16 & offset,std::string * serialized_command,AuthorizationDelegate * authorization_delegate)33425 TPM_RC Tpm::SerializeCommand_NV_Certify(
33426     const TPMI_DH_OBJECT& sign_handle,
33427     const std::string& sign_handle_name,
33428     const TPMI_RH_NV_AUTH& auth_handle,
33429     const std::string& auth_handle_name,
33430     const TPMI_RH_NV_INDEX& nv_index,
33431     const std::string& nv_index_name,
33432     const TPM2B_DATA& qualifying_data,
33433     const TPMT_SIG_SCHEME& in_scheme,
33434     const UINT16& size,
33435     const UINT16& offset,
33436     std::string* serialized_command,
33437     AuthorizationDelegate* authorization_delegate) {
33438   VLOG(3) << __func__;
33439   TPM_RC rc = TPM_RC_SUCCESS;
33440   TPMI_ST_COMMAND_TAG tag = TPM_ST_NO_SESSIONS;
33441   UINT32 command_size = 10;  // Header size.
33442   std::string handle_section_bytes;
33443   std::string parameter_section_bytes;
33444   TPM_CC command_code = TPM_CC_NV_Certify;
33445   bool is_command_parameter_encryption_possible = true;
33446   bool is_response_parameter_encryption_possible = true;
33447   std::string command_code_bytes;
33448   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33449   if (rc != TPM_RC_SUCCESS) {
33450     return rc;
33451   }
33452   std::string sign_handle_bytes;
33453   rc = Serialize_TPMI_DH_OBJECT(sign_handle, &sign_handle_bytes);
33454   if (rc != TPM_RC_SUCCESS) {
33455     return rc;
33456   }
33457   std::string auth_handle_bytes;
33458   rc = Serialize_TPMI_RH_NV_AUTH(auth_handle, &auth_handle_bytes);
33459   if (rc != TPM_RC_SUCCESS) {
33460     return rc;
33461   }
33462   std::string nv_index_bytes;
33463   rc = Serialize_TPMI_RH_NV_INDEX(nv_index, &nv_index_bytes);
33464   if (rc != TPM_RC_SUCCESS) {
33465     return rc;
33466   }
33467   std::string qualifying_data_bytes;
33468   rc = Serialize_TPM2B_DATA(qualifying_data, &qualifying_data_bytes);
33469   if (rc != TPM_RC_SUCCESS) {
33470     return rc;
33471   }
33472   std::string in_scheme_bytes;
33473   rc = Serialize_TPMT_SIG_SCHEME(in_scheme, &in_scheme_bytes);
33474   if (rc != TPM_RC_SUCCESS) {
33475     return rc;
33476   }
33477   std::string size_bytes;
33478   rc = Serialize_UINT16(size, &size_bytes);
33479   if (rc != TPM_RC_SUCCESS) {
33480     return rc;
33481   }
33482   std::string offset_bytes;
33483   rc = Serialize_UINT16(offset, &offset_bytes);
33484   if (rc != TPM_RC_SUCCESS) {
33485     return rc;
33486   }
33487   if (authorization_delegate) {
33488     // Encrypt just the parameter data, not the size.
33489     std::string tmp = qualifying_data_bytes.substr(2);
33490     if (!authorization_delegate->EncryptCommandParameter(&tmp)) {
33491       return TRUNKS_RC_ENCRYPTION_FAILED;
33492     }
33493     qualifying_data_bytes.replace(2, std::string::npos, tmp);
33494   }
33495   std::unique_ptr<crypto::SecureHash> hash(
33496       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33497   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33498   hash->Update(sign_handle_name.data(), sign_handle_name.size());
33499   handle_section_bytes += sign_handle_bytes;
33500   command_size += sign_handle_bytes.size();
33501   hash->Update(auth_handle_name.data(), auth_handle_name.size());
33502   handle_section_bytes += auth_handle_bytes;
33503   command_size += auth_handle_bytes.size();
33504   hash->Update(nv_index_name.data(), nv_index_name.size());
33505   handle_section_bytes += nv_index_bytes;
33506   command_size += nv_index_bytes.size();
33507   hash->Update(qualifying_data_bytes.data(), qualifying_data_bytes.size());
33508   parameter_section_bytes += qualifying_data_bytes;
33509   command_size += qualifying_data_bytes.size();
33510   hash->Update(in_scheme_bytes.data(), in_scheme_bytes.size());
33511   parameter_section_bytes += in_scheme_bytes;
33512   command_size += in_scheme_bytes.size();
33513   hash->Update(size_bytes.data(), size_bytes.size());
33514   parameter_section_bytes += size_bytes;
33515   command_size += size_bytes.size();
33516   hash->Update(offset_bytes.data(), offset_bytes.size());
33517   parameter_section_bytes += offset_bytes;
33518   command_size += offset_bytes.size();
33519   std::string command_hash(32, 0);
33520   hash->Finish(std::data(command_hash), command_hash.size());
33521   std::string authorization_section_bytes;
33522   std::string authorization_size_bytes;
33523   if (authorization_delegate) {
33524     if (!authorization_delegate->GetCommandAuthorization(
33525             command_hash, is_command_parameter_encryption_possible,
33526             is_response_parameter_encryption_possible,
33527             &authorization_section_bytes)) {
33528       return TRUNKS_RC_AUTHORIZATION_FAILED;
33529     }
33530     if (!authorization_section_bytes.empty()) {
33531       tag = TPM_ST_SESSIONS;
33532       std::string tmp;
33533       rc = Serialize_UINT32(authorization_section_bytes.size(),
33534                             &authorization_size_bytes);
33535       if (rc != TPM_RC_SUCCESS) {
33536         return rc;
33537       }
33538       command_size +=
33539           authorization_size_bytes.size() + authorization_section_bytes.size();
33540     }
33541   }
33542   std::string tag_bytes;
33543   rc = Serialize_TPMI_ST_COMMAND_TAG(tag, &tag_bytes);
33544   if (rc != TPM_RC_SUCCESS) {
33545     return rc;
33546   }
33547   std::string command_size_bytes;
33548   rc = Serialize_UINT32(command_size, &command_size_bytes);
33549   if (rc != TPM_RC_SUCCESS) {
33550     return rc;
33551   }
33552   *serialized_command = tag_bytes + command_size_bytes + command_code_bytes +
33553                         handle_section_bytes + authorization_size_bytes +
33554                         authorization_section_bytes + parameter_section_bytes;
33555   CHECK(serialized_command->size() == command_size) << "Command size mismatch!";
33556   VLOG(2) << "Command: "
33557           << base::HexEncode(serialized_command->data(),
33558                              serialized_command->size());
33559   return TPM_RC_SUCCESS;
33560 }
33561 
ParseResponse_NV_Certify(const std::string & response,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)33562 TPM_RC Tpm::ParseResponse_NV_Certify(
33563     const std::string& response,
33564     TPM2B_ATTEST* certify_info,
33565     TPMT_SIGNATURE* signature,
33566     AuthorizationDelegate* authorization_delegate) {
33567   VLOG(3) << __func__;
33568   VLOG(2) << "Response: " << base::HexEncode(response.data(), response.size());
33569   TPM_RC rc = TPM_RC_SUCCESS;
33570   std::string buffer(response);
33571   TPM_ST tag;
33572   std::string tag_bytes;
33573   rc = Parse_TPM_ST(&buffer, &tag, &tag_bytes);
33574   if (rc != TPM_RC_SUCCESS) {
33575     return rc;
33576   }
33577   UINT32 response_size;
33578   std::string response_size_bytes;
33579   rc = Parse_UINT32(&buffer, &response_size, &response_size_bytes);
33580   if (rc != TPM_RC_SUCCESS) {
33581     return rc;
33582   }
33583   TPM_RC response_code;
33584   std::string response_code_bytes;
33585   rc = Parse_TPM_RC(&buffer, &response_code, &response_code_bytes);
33586   if (rc != TPM_RC_SUCCESS) {
33587     return rc;
33588   }
33589   if (response_size != response.size()) {
33590     return TPM_RC_SIZE;
33591   }
33592   if (response_code != TPM_RC_SUCCESS) {
33593     return response_code;
33594   }
33595   TPM_CC command_code = TPM_CC_NV_Certify;
33596   std::string command_code_bytes;
33597   rc = Serialize_TPM_CC(command_code, &command_code_bytes);
33598   if (rc != TPM_RC_SUCCESS) {
33599     return rc;
33600   }
33601   std::string authorization_section_bytes;
33602   if (tag == TPM_ST_SESSIONS) {
33603     UINT32 parameter_section_size = buffer.size();
33604     rc = Parse_UINT32(&buffer, &parameter_section_size, nullptr);
33605     if (rc != TPM_RC_SUCCESS) {
33606       return rc;
33607     }
33608     if (parameter_section_size > buffer.size()) {
33609       return TPM_RC_INSUFFICIENT;
33610     }
33611     authorization_section_bytes = buffer.substr(parameter_section_size);
33612     // Keep the parameter section in |buffer|.
33613     buffer.erase(parameter_section_size);
33614   }
33615   std::unique_ptr<crypto::SecureHash> hash(
33616       crypto::SecureHash::Create(crypto::SecureHash::SHA256));
33617   hash->Update(response_code_bytes.data(), response_code_bytes.size());
33618   hash->Update(command_code_bytes.data(), command_code_bytes.size());
33619   hash->Update(buffer.data(), buffer.size());
33620   std::string response_hash(32, 0);
33621   hash->Finish(std::data(response_hash), response_hash.size());
33622   if (tag == TPM_ST_SESSIONS) {
33623     if (!authorization_delegate)
33624       return TRUNKS_RC_AUTHORIZATION_FAILED;
33625     if (!authorization_delegate->CheckResponseAuthorization(
33626             response_hash, authorization_section_bytes)) {
33627       return TRUNKS_RC_AUTHORIZATION_FAILED;
33628     }
33629   }
33630   if (tag == TPM_ST_SESSIONS) {
33631     if (!authorization_delegate)
33632       return TRUNKS_RC_AUTHORIZATION_FAILED;
33633 
33634     // Parse the encrypted parameter size.
33635     UINT16 size;
33636     std::string size_buffer = buffer.substr(0, 2);
33637     if (TPM_RC result = Parse_UINT16(&size_buffer, &size, nullptr); result) {
33638       return result;
33639     }
33640     if (buffer.size() < 2 + size) {
33641       return TPM_RC_INSUFFICIENT;
33642     }
33643 
33644     // Decrypt just the parameter data, not the size.
33645     std::string decrypted_data = buffer.substr(2, size);
33646     if (!authorization_delegate->DecryptResponseParameter(&decrypted_data)) {
33647       return TRUNKS_RC_ENCRYPTION_FAILED;
33648     }
33649     buffer.replace(2, size, decrypted_data);
33650   }
33651   std::string certify_info_bytes;
33652   rc = Parse_TPM2B_ATTEST(&buffer, certify_info, &certify_info_bytes);
33653   if (rc != TPM_RC_SUCCESS) {
33654     return rc;
33655   }
33656   std::string signature_bytes;
33657   rc = Parse_TPMT_SIGNATURE(&buffer, signature, &signature_bytes);
33658   if (rc != TPM_RC_SUCCESS) {
33659     return rc;
33660   }
33661   return TPM_RC_SUCCESS;
33662 }
33663 
NV_CertifyErrorCallback(Tpm::NV_CertifyResponse callback,TPM_RC response_code)33664 void NV_CertifyErrorCallback(Tpm::NV_CertifyResponse callback,
33665                              TPM_RC response_code) {
33666   VLOG(1) << __func__;
33667   std::move(callback).Run(response_code, TPM2B_ATTEST(), TPMT_SIGNATURE());
33668 }
33669 
NV_CertifyResponseParser(Tpm::NV_CertifyResponse callback,AuthorizationDelegate * authorization_delegate,const std::string & response)33670 void NV_CertifyResponseParser(Tpm::NV_CertifyResponse callback,
33671                               AuthorizationDelegate* authorization_delegate,
33672                               const std::string& response) {
33673   VLOG(1) << __func__;
33674   TPM2B_ATTEST certify_info;
33675   TPMT_SIGNATURE signature;
33676   TPM_RC rc = Tpm::ParseResponse_NV_Certify(response, &certify_info, &signature,
33677                                             authorization_delegate);
33678   if (rc != TPM_RC_SUCCESS) {
33679     base::OnceCallback<void(TPM_RC)> error_reporter =
33680         base::BindOnce(NV_CertifyErrorCallback, std::move(callback));
33681     std::move(error_reporter).Run(rc);
33682     return;
33683   }
33684   std::move(callback).Run(rc, certify_info, signature);
33685 }
33686 
NV_Certify(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const UINT16 & size,const UINT16 & offset,AuthorizationDelegate * authorization_delegate,NV_CertifyResponse callback)33687 void Tpm::NV_Certify(const TPMI_DH_OBJECT& sign_handle,
33688                      const std::string& sign_handle_name,
33689                      const TPMI_RH_NV_AUTH& auth_handle,
33690                      const std::string& auth_handle_name,
33691                      const TPMI_RH_NV_INDEX& nv_index,
33692                      const std::string& nv_index_name,
33693                      const TPM2B_DATA& qualifying_data,
33694                      const TPMT_SIG_SCHEME& in_scheme,
33695                      const UINT16& size,
33696                      const UINT16& offset,
33697                      AuthorizationDelegate* authorization_delegate,
33698                      NV_CertifyResponse callback) {
33699   VLOG(1) << __func__;
33700   std::string command;
33701   TPM_RC rc = SerializeCommand_NV_Certify(
33702       sign_handle, sign_handle_name, auth_handle, auth_handle_name, nv_index,
33703       nv_index_name, qualifying_data, in_scheme, size, offset, &command,
33704       authorization_delegate);
33705   if (rc != TPM_RC_SUCCESS) {
33706     base::OnceCallback<void(TPM_RC)> error_reporter =
33707         base::BindOnce(NV_CertifyErrorCallback, std::move(callback));
33708     std::move(error_reporter).Run(rc);
33709     return;
33710   }
33711   base::OnceCallback<void(const std::string&)> parser = base::BindOnce(
33712       NV_CertifyResponseParser, std::move(callback), authorization_delegate);
33713   transceiver_->SendCommand(command, std::move(parser));
33714 }
33715 
NV_CertifySync(const TPMI_DH_OBJECT & sign_handle,const std::string & sign_handle_name,const TPMI_RH_NV_AUTH & auth_handle,const std::string & auth_handle_name,const TPMI_RH_NV_INDEX & nv_index,const std::string & nv_index_name,const TPM2B_DATA & qualifying_data,const TPMT_SIG_SCHEME & in_scheme,const UINT16 & size,const UINT16 & offset,TPM2B_ATTEST * certify_info,TPMT_SIGNATURE * signature,AuthorizationDelegate * authorization_delegate)33716 TPM_RC Tpm::NV_CertifySync(const TPMI_DH_OBJECT& sign_handle,
33717                            const std::string& sign_handle_name,
33718                            const TPMI_RH_NV_AUTH& auth_handle,
33719                            const std::string& auth_handle_name,
33720                            const TPMI_RH_NV_INDEX& nv_index,
33721                            const std::string& nv_index_name,
33722                            const TPM2B_DATA& qualifying_data,
33723                            const TPMT_SIG_SCHEME& in_scheme,
33724                            const UINT16& size,
33725                            const UINT16& offset,
33726                            TPM2B_ATTEST* certify_info,
33727                            TPMT_SIGNATURE* signature,
33728                            AuthorizationDelegate* authorization_delegate) {
33729   VLOG(1) << __func__;
33730   std::string command;
33731   TPM_RC rc = SerializeCommand_NV_Certify(
33732       sign_handle, sign_handle_name, auth_handle, auth_handle_name, nv_index,
33733       nv_index_name, qualifying_data, in_scheme, size, offset, &command,
33734       authorization_delegate);
33735   if (rc != TPM_RC_SUCCESS) {
33736     return rc;
33737   }
33738   std::string response = transceiver_->SendCommandAndWait(command);
33739   rc = ParseResponse_NV_Certify(response, certify_info, signature,
33740                                 authorization_delegate);
33741   return rc;
33742 }
33743 
33744 }  // namespace trunks
33745